diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/chrome/browser/ui | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui')
337 files changed, 8783 insertions, 14972 deletions
diff --git a/chromium/chrome/browser/ui/BUILD.gn b/chromium/chrome/browser/ui/BUILD.gn index b29d0d03d23..8084f2caeba 100644 --- a/chromium/chrome/browser/ui/BUILD.gn +++ b/chromium/chrome/browser/ui/BUILD.gn @@ -8,6 +8,7 @@ import("//build/config/features.gni") import("//build/config/ui.gni") import("//build/split_static_library.gni") import("//chrome/common/features.gni") +import("//components/signin/features.gni") import("//extensions/features/features.gni") import("//media/media_options.gni") import("//ppapi/features/features.gni") @@ -103,6 +104,7 @@ split_static_library("ui") { "chrome_select_file_policy.h", "confirm_bubble.h", "crypto_module_password_dialog.h", + "cryptuiapi_shim.h", "find_bar/find_bar.h", "find_bar/find_bar_state.h", "find_bar/find_bar_state_factory.cc", @@ -110,6 +112,7 @@ split_static_library("ui") { "find_bar/find_notification_details.h", "find_bar/find_tab_helper.cc", "find_bar/find_tab_helper.h", + "forced_reauthentication_dialog.h", "history_ui.cc", "history_ui.h", "javascript_dialogs/chrome_javascript_native_dialog_factory.h", @@ -209,14 +212,10 @@ split_static_library("ui") { "webui/about_ui.h", "webui/bluetooth_internals/bluetooth_internals_ui.cc", "webui/bluetooth_internals/bluetooth_internals_ui.h", - "webui/browsing_history_handler.cc", - "webui/browsing_history_handler.h", "webui/chrome_web_ui_controller_factory.cc", "webui/chrome_web_ui_controller_factory.h", - "webui/chromeos/bluetooth_pairing_ui.cc", - "webui/chromeos/bluetooth_pairing_ui.h", - "webui/chromeos/certificate_manager_dialog_ui.cc", - "webui/chromeos/certificate_manager_dialog_ui.h", + + # TODO(dbeam): why are all these /chromeos/ files on all platforms? "webui/chromeos/choose_mobile_network_ui.cc", "webui/chromeos/choose_mobile_network_ui.h", "webui/chromeos/cryptohome_ui.cc", @@ -308,6 +307,10 @@ split_static_library("ui") { "webui/chromeos/login/user_board_screen_handler.h", "webui/chromeos/login/user_image_screen_handler.cc", "webui/chromeos/login/user_image_screen_handler.h", + "webui/chromeos/login/voice_interaction_value_prop_screen_handler.cc", + "webui/chromeos/login/voice_interaction_value_prop_screen_handler.h", + "webui/chromeos/login/wait_for_container_ready_screen_handler.cc", + "webui/chromeos/login/wait_for_container_ready_screen_handler.h", "webui/chromeos/login/wrong_hwid_screen_handler.cc", "webui/chromeos/login/wrong_hwid_screen_handler.h", "webui/chromeos/mobile_setup_dialog.cc", @@ -320,8 +323,6 @@ split_static_library("ui") { "webui/chromeos/network_ui.h", "webui/chromeos/power_ui.cc", "webui/chromeos/power_ui.h", - "webui/chromeos/proxy_settings_ui.cc", - "webui/chromeos/proxy_settings_ui.h", "webui/chromeos/set_time_ui.cc", "webui/chromeos/set_time_ui.h", "webui/chromeos/sim_unlock_ui.cc", @@ -346,8 +347,6 @@ split_static_library("ui") { "webui/domain_reliability_internals_ui.h", "webui/engagement/site_engagement_ui.cc", "webui/engagement/site_engagement_ui.h", - "webui/fallback_icon_source.cc", - "webui/fallback_icon_source.h", "webui/favicon_source.cc", "webui/favicon_source.h", "webui/fileicon_source.cc", @@ -368,6 +367,8 @@ split_static_library("ui") { "webui/local_state/local_state_ui.h", "webui/log_web_ui_url.cc", "webui/log_web_ui_url.h", + "webui/media/media_engagement_ui.cc", + "webui/media/media_engagement_ui.h", "webui/metrics_handler.cc", "webui/metrics_handler.h", "webui/mojo_web_ui_controller.cc", @@ -480,12 +481,15 @@ split_static_library("ui") { "//chrome/browser:resource_prefetch_predictor_proto", "//chrome/browser/devtools", "//chrome/browser/engagement:mojo_bindings", + "//chrome/browser/media:mojo_bindings", + "//chrome/browser/safe_browsing", "//chrome/browser/ui/webui/omnibox:mojo_bindings", "//chrome/browser/ui/webui/usb_internals:mojo_bindings", "//chrome/common", "//chrome/common:instant_mojom", "//chrome/common/net", "//chrome/installer/util:with_no_strings", + "//components/about_ui", "//components/app_modal", "//components/autofill/content/browser:risk_proto", "//components/autofill/core/browser", @@ -506,6 +510,7 @@ split_static_library("ui") { "//components/dom_distiller/content/browser", "//components/dom_distiller/webui", "//components/domain_reliability", + "//components/download/content/public", "//components/favicon/content", "//components/favicon/core", "//components/feedback", @@ -525,6 +530,8 @@ split_static_library("ui") { "//components/ntp_tiles", "//components/offline_pages/core", "//components/offline_pages/core/background:background_offliner", + "//components/offline_pages/core/prefetch", + "//components/offline_pages/features:features", "//components/omnibox/browser", "//components/onc", "//components/password_manager/content/browser", @@ -542,6 +549,7 @@ split_static_library("ui") { "//components/renderer_context_menu", "//components/resources", "//components/safe_browsing/common:safe_browsing_prefs", + "//components/safe_browsing/web_ui", "//components/safe_json", "//components/search", "//components/search_engines", @@ -551,6 +559,8 @@ split_static_library("ui") { "//components/sessions", "//components/signin/core/account_id", "//components/signin/core/browser", + "//components/signin/core/common", + "//components/signin/core/common:signin_features", "//components/spellcheck/browser", "//components/ssl_errors", "//components/startup_metric_utils/browser:lib", @@ -648,12 +658,7 @@ split_static_library("ui") { ] } - if (is_android) { - sources += [ - "webui/large_icon_source.cc", - "webui/large_icon_source.h", - ] - } else { + if (!is_android) { sources += [ "apps/app_info_dialog.h", "apps/chrome_app_delegate.cc", @@ -787,6 +792,7 @@ split_static_library("ui") { "omnibox/chrome_omnibox_navigation_observer.h", "omnibox/clipboard_utils.cc", "omnibox/clipboard_utils.h", + "overlay/overlay_window.h", "page_info/page_info_infobar_delegate.cc", "page_info/page_info_infobar_delegate.h", "page_info/permission_menu_model.cc", @@ -882,8 +888,6 @@ split_static_library("ui") { "task_manager/task_manager_columns.h", "task_manager/task_manager_table_model.cc", "task_manager/task_manager_table_model.h", - "toolbar/app_menu_animation.cc", - "toolbar/app_menu_animation.h", "toolbar/app_menu_icon_controller.cc", "toolbar/app_menu_icon_controller.h", "toolbar/app_menu_model.cc", @@ -918,6 +922,8 @@ split_static_library("ui") { "webui/app_launcher_login_handler.h", "webui/bookmarks_ui.cc", "webui/bookmarks_ui.h", + "webui/browsing_history_handler.cc", + "webui/browsing_history_handler.h", "webui/chrome_web_contents_handler.cc", "webui/chrome_web_contents_handler.h", "webui/constrained_web_dialog_delegate_base.cc", @@ -934,12 +940,6 @@ split_static_library("ui") { "webui/extensions/install_extension_handler.h", "webui/foreign_session_handler.cc", "webui/foreign_session_handler.h", - "webui/help/help_handler.cc", - "webui/help/help_handler.h", - "webui/help/help_ui.cc", - "webui/help/help_ui.h", - "webui/help/help_utils_chromeos.cc", - "webui/help/help_utils_chromeos.h", "webui/help/version_updater.h", "webui/help/version_updater_chromeos.cc", "webui/help/version_updater_chromeos.h", @@ -953,6 +953,8 @@ split_static_library("ui") { "webui/identity_internals_ui.h", "webui/inspect_ui.cc", "webui/inspect_ui.h", + "webui/md_bookmarks/bookmarks_message_handler.cc", + "webui/md_bookmarks/bookmarks_message_handler.h", "webui/md_bookmarks/md_bookmarks_ui.cc", "webui/md_bookmarks/md_bookmarks_ui.h", "webui/md_downloads/downloads_list_tracker.cc", @@ -981,103 +983,8 @@ split_static_library("ui") { "webui/ntp/ntp_resource_cache.h", "webui/ntp/ntp_resource_cache_factory.cc", "webui/ntp/ntp_resource_cache_factory.h", - "webui/options/autofill_options_handler.cc", - "webui/options/autofill_options_handler.h", - "webui/options/automatic_settings_reset_handler.cc", - "webui/options/automatic_settings_reset_handler.h", - "webui/options/browser_options_handler.cc", - "webui/options/browser_options_handler.h", - "webui/options/chromeos/accounts_options_handler.cc", - "webui/options/chromeos/accounts_options_handler.h", - "webui/options/chromeos/bluetooth_options_handler.cc", - "webui/options/chromeos/bluetooth_options_handler.h", - "webui/options/chromeos/change_picture_options_handler.cc", - "webui/options/chromeos/change_picture_options_handler.h", - "webui/options/chromeos/core_chromeos_options_handler.cc", - "webui/options/chromeos/core_chromeos_options_handler.h", - "webui/options/chromeos/cros_language_options_handler.cc", - "webui/options/chromeos/cros_language_options_handler.h", - "webui/options/chromeos/date_time_options_handler.cc", - "webui/options/chromeos/date_time_options_handler.h", - "webui/options/chromeos/display_options_handler.cc", - "webui/options/chromeos/display_options_handler.h", - "webui/options/chromeos/display_overscan_handler.cc", - "webui/options/chromeos/display_overscan_handler.h", - "webui/options/chromeos/internet_options_handler.cc", - "webui/options/chromeos/internet_options_handler.h", - "webui/options/chromeos/internet_options_handler_strings.cc", - "webui/options/chromeos/internet_options_handler_strings.h", - "webui/options/chromeos/keyboard_handler.cc", - "webui/options/chromeos/keyboard_handler.h", - "webui/options/chromeos/options_stylus_handler.cc", - "webui/options/chromeos/options_stylus_handler.h", - "webui/options/chromeos/pointer_handler.cc", - "webui/options/chromeos/pointer_handler.h", - "webui/options/chromeos/power_handler.cc", - "webui/options/chromeos/power_handler.h", - "webui/options/chromeos/proxy_handler.cc", - "webui/options/chromeos/proxy_handler.h", - "webui/options/chromeos/stats_options_handler.cc", - "webui/options/chromeos/stats_options_handler.h", - "webui/options/chromeos/storage_manager_handler.cc", - "webui/options/chromeos/storage_manager_handler.h", - "webui/options/chromeos/user_image_source.cc", - "webui/options/chromeos/user_image_source.h", - "webui/options/clear_browser_data_handler.cc", - "webui/options/clear_browser_data_handler.h", - "webui/options/content_settings_handler.cc", - "webui/options/content_settings_handler.h", - "webui/options/cookies_view_handler.cc", - "webui/options/cookies_view_handler.h", - "webui/options/core_options_handler.cc", - "webui/options/core_options_handler.h", - "webui/options/create_profile_handler.cc", - "webui/options/create_profile_handler.h", - "webui/options/easy_unlock_handler.cc", - "webui/options/easy_unlock_handler.h", - "webui/options/font_settings_handler.cc", - "webui/options/font_settings_handler.h", - "webui/options/font_settings_utils.cc", - "webui/options/font_settings_utils.h", - "webui/options/font_settings_utils_linux.cc", - "webui/options/font_settings_utils_mac.mm", - "webui/options/font_settings_utils_win.cc", - "webui/options/handler_options_handler.cc", - "webui/options/handler_options_handler.h", - "webui/options/help_overlay_handler.cc", - "webui/options/help_overlay_handler.h", - "webui/options/home_page_overlay_handler.cc", - "webui/options/home_page_overlay_handler.h", - "webui/options/import_data_handler.cc", - "webui/options/import_data_handler.h", - "webui/options/language_dictionary_overlay_handler.cc", - "webui/options/language_dictionary_overlay_handler.h", - "webui/options/language_options_handler.cc", - "webui/options/language_options_handler.h", - "webui/options/language_options_handler_common.cc", - "webui/options/language_options_handler_common.h", - "webui/options/manage_profile_handler.cc", - "webui/options/manage_profile_handler.h", - "webui/options/media_devices_selection_handler.cc", - "webui/options/media_devices_selection_handler.h", - "webui/options/options_ui.cc", - "webui/options/options_ui.h", - "webui/options/password_manager_handler.cc", - "webui/options/password_manager_handler.h", - "webui/options/reset_profile_settings_handler.cc", - "webui/options/reset_profile_settings_handler.h", - "webui/options/search_engine_manager_handler.cc", - "webui/options/search_engine_manager_handler.h", - "webui/options/startup_pages_handler.cc", - "webui/options/startup_pages_handler.h", - "webui/options/supervised_user_create_confirm_handler.cc", - "webui/options/supervised_user_create_confirm_handler.h", - "webui/options/supervised_user_import_handler.cc", - "webui/options/supervised_user_import_handler.h", - "webui/options/supervised_user_learn_more_handler.cc", - "webui/options/supervised_user_learn_more_handler.h", - "webui/options/sync_setup_handler.cc", - "webui/options/sync_setup_handler.h", + "webui/plural_string_handler.cc", + "webui/plural_string_handler.h", "webui/policy_indicator_localized_strings_provider.cc", "webui/policy_indicator_localized_strings_provider.h", "webui/profile_helper.cc", @@ -1116,6 +1023,8 @@ split_static_library("ui") { "webui/settings/chromeos/easy_unlock_settings_handler.h", "webui/settings/chromeos/fingerprint_handler.cc", "webui/settings/chromeos/fingerprint_handler.h", + "webui/settings/chromeos/google_assistant_handler.cc", + "webui/settings/chromeos/google_assistant_handler.h", "webui/settings/chromeos/internet_handler.cc", "webui/settings/chromeos/internet_handler.h", "webui/settings/downloads_handler.cc", @@ -1186,8 +1095,6 @@ split_static_library("ui") { "webui/system_info_ui.h", "webui/theme_handler.cc", "webui/theme_handler.h", - "webui/uber/uber_ui.cc", - "webui/uber/uber_ui.h", "window_sizer/window_sizer.cc", "window_sizer/window_sizer.h", "zoom/chrome_zoom_level_otr_delegate.cc", @@ -1196,21 +1103,29 @@ split_static_library("ui") { "zoom/chrome_zoom_level_prefs.h", ] deps += [ - "//apps", - "//apps/ui/views", "//chrome/app/vector_icons", "//chrome/browser/profile_resetter:profile_reset_report_proto", "//chrome/common:features", "//components/feedback/proto", + "//components/network_session_configurator/common", "//components/proximity_auth/webui", + "//components/ui_metrics", + "//components/vector_icons", + "//components/vector_icons", "//components/web_modal", "//components/zoom", "//device/bluetooth", - "//extensions/common:mojo", "//mash/public/interfaces", "//services/device/public/interfaces", - "//ui/vector_icons", ] + + if (enable_extensions) { + deps += [ + "//apps", + "//apps/ui/views", + "//extensions/common:mojo", + ] + } } if (enable_basic_printing || enable_print_preview) { @@ -1262,6 +1177,8 @@ split_static_library("ui") { "app_list/search/launcher_search/launcher_search_provider.h", "app_list/search/launcher_search/launcher_search_result.cc", "app_list/search/launcher_search/launcher_search_result.h", + "ash/ime_controller_client.cc", + "ash/ime_controller_client.h", "ash/lock_screen_client.cc", "ash/lock_screen_client.h", "ash/session_controller_client.cc", @@ -1282,6 +1199,108 @@ split_static_library("ui") { "views/select_file_dialog_extension.h", "views/select_file_dialog_extension_factory.cc", "views/select_file_dialog_extension_factory.h", + "webui/chromeos/bluetooth_pairing_ui.cc", + "webui/chromeos/bluetooth_pairing_ui.h", + "webui/chromeos/certificate_manager_dialog_ui.cc", + "webui/chromeos/certificate_manager_dialog_ui.h", + "webui/chromeos/proxy_settings_ui.cc", + "webui/chromeos/proxy_settings_ui.h", + "webui/chromeos/user_image_source.cc", + "webui/chromeos/user_image_source.h", + "webui/help/help_handler.cc", + "webui/help/help_handler.h", + "webui/help/help_utils_chromeos.cc", + "webui/help/help_utils_chromeos.h", + "webui/options/autofill_options_handler.cc", + "webui/options/autofill_options_handler.h", + "webui/options/automatic_settings_reset_handler.cc", + "webui/options/automatic_settings_reset_handler.h", + "webui/options/browser_options_handler.cc", + "webui/options/browser_options_handler.h", + "webui/options/chromeos/accounts_options_handler.cc", + "webui/options/chromeos/accounts_options_handler.h", + "webui/options/chromeos/bluetooth_options_handler.cc", + "webui/options/chromeos/bluetooth_options_handler.h", + "webui/options/chromeos/change_picture_options_handler.cc", + "webui/options/chromeos/change_picture_options_handler.h", + "webui/options/chromeos/core_chromeos_options_handler.cc", + "webui/options/chromeos/core_chromeos_options_handler.h", + "webui/options/chromeos/cros_language_options_handler.cc", + "webui/options/chromeos/cros_language_options_handler.h", + "webui/options/chromeos/date_time_options_handler.cc", + "webui/options/chromeos/date_time_options_handler.h", + "webui/options/chromeos/display_options_handler.cc", + "webui/options/chromeos/display_options_handler.h", + "webui/options/chromeos/display_overscan_handler.cc", + "webui/options/chromeos/display_overscan_handler.h", + "webui/options/chromeos/internet_options_handler.cc", + "webui/options/chromeos/internet_options_handler.h", + "webui/options/chromeos/internet_options_handler_strings.cc", + "webui/options/chromeos/internet_options_handler_strings.h", + "webui/options/chromeos/keyboard_handler.cc", + "webui/options/chromeos/keyboard_handler.h", + "webui/options/chromeos/options_stylus_handler.cc", + "webui/options/chromeos/options_stylus_handler.h", + "webui/options/chromeos/pointer_handler.cc", + "webui/options/chromeos/pointer_handler.h", + "webui/options/chromeos/power_handler.cc", + "webui/options/chromeos/power_handler.h", + "webui/options/chromeos/proxy_handler.cc", + "webui/options/chromeos/proxy_handler.h", + "webui/options/chromeos/stats_options_handler.cc", + "webui/options/chromeos/stats_options_handler.h", + "webui/options/chromeos/storage_manager_handler.cc", + "webui/options/chromeos/storage_manager_handler.h", + "webui/options/clear_browser_data_handler.cc", + "webui/options/clear_browser_data_handler.h", + "webui/options/content_settings_handler.cc", + "webui/options/content_settings_handler.h", + "webui/options/cookies_view_handler.cc", + "webui/options/cookies_view_handler.h", + "webui/options/core_options_handler.cc", + "webui/options/core_options_handler.h", + "webui/options/create_profile_handler.cc", + "webui/options/create_profile_handler.h", + "webui/options/easy_unlock_handler.cc", + "webui/options/easy_unlock_handler.h", + "webui/options/font_settings_handler.cc", + "webui/options/font_settings_handler.h", + "webui/options/handler_options_handler.cc", + "webui/options/handler_options_handler.h", + "webui/options/help_overlay_handler.cc", + "webui/options/help_overlay_handler.h", + "webui/options/home_page_overlay_handler.cc", + "webui/options/home_page_overlay_handler.h", + "webui/options/import_data_handler.cc", + "webui/options/import_data_handler.h", + "webui/options/language_dictionary_overlay_handler.cc", + "webui/options/language_dictionary_overlay_handler.h", + "webui/options/language_options_handler.cc", + "webui/options/language_options_handler.h", + "webui/options/language_options_handler_common.cc", + "webui/options/language_options_handler_common.h", + "webui/options/manage_profile_handler.cc", + "webui/options/manage_profile_handler.h", + "webui/options/media_devices_selection_handler.cc", + "webui/options/media_devices_selection_handler.h", + "webui/options/options_ui.cc", + "webui/options/options_ui.h", + "webui/options/password_manager_handler.cc", + "webui/options/password_manager_handler.h", + "webui/options/reset_profile_settings_handler.cc", + "webui/options/reset_profile_settings_handler.h", + "webui/options/search_engine_manager_handler.cc", + "webui/options/search_engine_manager_handler.h", + "webui/options/startup_pages_handler.cc", + "webui/options/startup_pages_handler.h", + "webui/options/supervised_user_create_confirm_handler.cc", + "webui/options/supervised_user_create_confirm_handler.h", + "webui/options/supervised_user_import_handler.cc", + "webui/options/supervised_user_import_handler.h", + "webui/options/supervised_user_learn_more_handler.cc", + "webui/options/supervised_user_learn_more_handler.h", + "webui/options/sync_setup_handler.cc", + "webui/options/sync_setup_handler.h", ] deps += [ "//chrome/browser/chromeos", @@ -1289,7 +1308,7 @@ split_static_library("ui") { "//components/drive:drive_chromeos", "//components/exo", "//components/login", - "//device/power_save_blocker", + "//services/device/public/interfaces", "//ui/base/ime", "//ui/chromeos", "//ui/chromeos/events", @@ -1297,6 +1316,7 @@ split_static_library("ui") { if (enable_rlz) { deps += [ "//chrome/browser:rlz" ] } + allow_circular_includes_from = [ "//chrome/browser/chromeos" ] } if (use_cups) { configs += [ "//printing:cups" ] @@ -1401,16 +1421,16 @@ split_static_library("ui") { "ash/networking_config_delegate_chromeos.h", "ash/palette_delegate_chromeos.cc", "ash/palette_delegate_chromeos.h", - "ash/session_state_delegate_chromeos.cc", - "ash/session_state_delegate_chromeos.h", "ash/session_util.cc", "ash/session_util.h", + "ash/sort_windows_by_z_index.cc", "ash/system_tray_delegate_chromeos.cc", "ash/system_tray_delegate_chromeos.h", "ash/volume_controller.cc", "ash/volume_controller.h", "ash/vpn_list_forwarder.cc", "ash/vpn_list_forwarder.h", + "sort_windows_by_z_index.h", "views/ash/chrome_browser_main_extra_parts_ash.cc", "views/ash/chrome_browser_main_extra_parts_ash.h", "views/ash/tab_scrubber.cc", @@ -1427,6 +1447,7 @@ split_static_library("ui") { "//ash/strings", "//components/session_manager/core", "//components/user_manager", + "//services/data_decoder/public/cpp", "//services/ui/public/cpp", "//services/ui/public/interfaces", "//ui/app_list/presenter", @@ -1444,7 +1465,12 @@ split_static_library("ui") { "autofill/save_card_bubble_controller_impl.cc", "autofill/save_card_bubble_controller_impl.h", "autofill/save_card_bubble_view.h", + "bubble_anchor_util.h", "desktop_ios_promotion/desktop_ios_promotion_footnote_delegate.h", + + # This test header is included because it contains forward declarations + # needed for "friend" statements for use in tests. + "translate/translate_bubble_test_utils.h", "views/apps/app_info_dialog/app_info_dialog_container.cc", "views/apps/app_info_dialog/app_info_dialog_container.h", "views/apps/app_info_dialog/app_info_dialog_views.cc", @@ -1475,6 +1501,7 @@ split_static_library("ui") { "views/bookmarks/bookmark_bubble_view.h", "views/bookmarks/bookmark_editor_view.cc", "views/bookmarks/bookmark_editor_view.h", + "views/bubble_anchor_util_views.h", "views/chrome_browser_main_extra_parts_views.cc", "views/chrome_browser_main_extra_parts_views.h", "views/chrome_constrained_window_views_client.cc", @@ -1499,6 +1526,8 @@ split_static_library("ui") { "views/exclusive_access_bubble_views.cc", "views/exclusive_access_bubble_views.h", "views/exclusive_access_bubble_views_context.h", + "views/extensions/bookmark_app_confirmation_view.cc", + "views/extensions/bookmark_app_confirmation_view.h", "views/extensions/chooser_dialog_view.cc", "views/extensions/chooser_dialog_view.h", "views/extensions/extension_install_dialog_view.cc", @@ -1507,6 +1536,10 @@ split_static_library("ui") { "views/extensions/extension_keybinding_registry_views.h", "views/frame/native_widget_mac_frameless_nswindow.h", "views/frame/native_widget_mac_frameless_nswindow.mm", + "views/fullscreen_control/fullscreen_control_host.cc", + "views/fullscreen_control/fullscreen_control_host.h", + "views/fullscreen_control/fullscreen_control_view.cc", + "views/fullscreen_control/fullscreen_control_view.h", "views/global_error_bubble_view.cc", "views/global_error_bubble_view.h", "views/harmony/chrome_layout_provider.cc", @@ -1517,6 +1550,10 @@ split_static_library("ui") { "views/harmony/harmony_layout_provider.h", "views/harmony/harmony_typography_provider.cc", "views/harmony/harmony_typography_provider.h", + "views/harmony/textfield_layout.cc", + "views/harmony/textfield_layout.h", + "views/importer/import_lock_dialog_view.cc", + "views/importer/import_lock_dialog_view.h", "views/location_bar/location_bar_bubble_delegate_view.cc", "views/location_bar/location_bar_bubble_delegate_view.h", "views/location_bar/zoom_bubble_view.cc", @@ -1526,6 +1563,8 @@ split_static_library("ui") { "views/login_view.h", "views/new_back_shortcut_bubble.cc", "views/new_back_shortcut_bubble.h", + "views/overlay/overlay_window_views.cc", + "views/overlay/overlay_window_views.h", "views/page_info/chosen_object_row.cc", "views/page_info/chosen_object_row.h", "views/page_info/chosen_object_row_observer.h", @@ -1593,6 +1632,8 @@ split_static_library("ui") { "views/permission_bubble/chooser_bubble_ui.h", "views/permission_bubble/permission_prompt_impl.cc", "views/permission_bubble/permission_prompt_impl.h", + "views/simple_message_box_views.cc", + "views/simple_message_box_views.h", "views/subtle_notification_view.cc", "views/subtle_notification_view.h", "views/sync/bubble_sync_promo_view.cc", @@ -1603,6 +1644,8 @@ split_static_library("ui") { "views/task_manager_view.h", "views/toolbar/toolbar_actions_bar_bubble_views.cc", "views/toolbar/toolbar_actions_bar_bubble_views.h", + "views/translate/translate_bubble_view.cc", + "views/translate/translate_bubble_view.h", "views/update_recommended_message_box.cc", "views/update_recommended_message_box.h", ] @@ -1613,6 +1656,11 @@ split_static_library("ui") { "//components/payments/core", "//services/ui/public/cpp/input_devices", ] + + if (use_aura) { + deps += [ "//components/ui_devtools/views" ] + } + allow_circular_includes_from += [ "//chrome/browser/ui/views" ] if (enable_extensions) { @@ -1635,6 +1683,8 @@ split_static_library("ui") { "views/frame/opaque_browser_frame_view_linux.h", "views/frame/opaque_browser_frame_view_platform_specific.cc", "views/frame/opaque_browser_frame_view_platform_specific.h", + "views/profiles/forced_reauthentication_dialog_view.cc", + "views/profiles/forced_reauthentication_dialog_view.h", "views/profiles/profile_chooser_view.cc", "views/profiles/profile_chooser_view.h", "views/screen_capture_notification_ui_views.cc", @@ -1656,8 +1706,6 @@ split_static_library("ui") { } if (enable_extensions && (!is_mac || mac_views_browser)) { sources += [ - "views/extensions/bookmark_app_confirmation_view.cc", - "views/extensions/bookmark_app_confirmation_view.h", "views/extensions/browser_action_drag_data.cc", "views/extensions/browser_action_drag_data.h", "views/extensions/extension_action_platform_delegate_views.cc", @@ -1682,6 +1730,7 @@ split_static_library("ui") { "views/extensions/extension_popup_aura.cc", "views/extensions/extension_popup_aura.h", ] + deps += [ "//ui/wm/public" ] } if (is_chromeos) { sources += [ @@ -1693,10 +1742,6 @@ split_static_library("ui") { if (!is_mac || mac_views_browser) { sources += [ "javascript_dialogs/javascript_dialog.cc", - - # This test header is included because it contains forward declarations - # needed for "friend" statements for use in tests. - "translate/translate_bubble_test_utils.h", "views/accessibility/invert_bubble_view.cc", "views/accessibility/invert_bubble_view.h", "views/autofill/autofill_popup_base_view.cc", @@ -1724,6 +1769,7 @@ split_static_library("ui") { "views/bookmarks/bookmark_menu_delegate.cc", "views/bookmarks/bookmark_menu_delegate.h", "views/browser_dialogs_views.cc", + "views/bubble_anchor_util_views.cc", "views/certificate_selector.cc", "views/certificate_selector.h", "views/certificate_viewer_win.cc", @@ -1734,8 +1780,6 @@ split_static_library("ui") { "views/conflicting_module_view_win.cc", "views/conflicting_module_view_win.h", "views/constrained_web_dialog_delegate_views.cc", - "views/create_application_shortcut_view.cc", - "views/create_application_shortcut_view.h", "views/download/download_feedback_dialog_view.cc", "views/download/download_feedback_dialog_view.h", "views/download/download_in_progress_dialog_view.cc", @@ -1804,8 +1848,6 @@ split_static_library("ui") { "views/hung_renderer_view.h", "views/ime/ime_warning_bubble_view.cc", "views/ime/ime_warning_bubble_view.h", - "views/importer/import_lock_dialog_view.cc", - "views/importer/import_lock_dialog_view.h", "views/infobars/alternate_nav_infobar_view.cc", "views/infobars/alternate_nav_infobar_view.h", "views/infobars/confirm_infobar.cc", @@ -1861,7 +1903,6 @@ split_static_library("ui") { "views/proximity_auth/proximity_auth_error_bubble_view.h", "views/session_crashed_bubble_view.cc", "views/session_crashed_bubble_view.h", - "views/simple_message_box_views.cc", "views/ssl_client_certificate_selector.cc", "views/ssl_client_certificate_selector.h", "views/status_bubble_views.cc", @@ -1884,6 +1925,10 @@ split_static_library("ui") { "views/tabs/alert_indicator_button.h", "views/tabs/browser_tab_strip_controller.cc", "views/tabs/browser_tab_strip_controller.h", + "views/tabs/new_tab_button.cc", + "views/tabs/new_tab_button.h", + "views/tabs/new_tab_promo.cc", + "views/tabs/new_tab_promo.h", "views/tabs/stacked_tab_strip_layout.cc", "views/tabs/stacked_tab_strip_layout.h", "views/tabs/tab.cc", @@ -1923,8 +1968,6 @@ split_static_library("ui") { "views/toolbar/toolbar_view.cc", "views/toolbar/toolbar_view.h", "views/touch_uma/touch_uma.h", - "views/translate/translate_bubble_view.cc", - "views/translate/translate_bubble_view.h", "views/translate/translate_icon_view.cc", "views/translate/translate_icon_view.h", "views/validation_message_bubble_view.cc", @@ -1947,10 +1990,13 @@ split_static_library("ui") { ] } - # TODO(ellyjones): Mus is not supported on Mac (there is no ui::Window - # apart from aura::Window, which is also not supported). if (!is_mac) { sources += [ + "views/create_application_shortcut_view.cc", + "views/create_application_shortcut_view.h", + + # TODO(ellyjones): Mus is not supported on Mac (there is no ui::Window + # apart from aura::Window, which is also not supported). "views/ime_driver/ime_driver_mus.cc", "views/ime_driver/ime_driver_mus.h", "views/ime_driver/input_method_bridge_chromeos.cc", @@ -1973,6 +2019,7 @@ split_static_library("ui") { ] } } + if (use_ash) { sources += [ "views/frame/browser_frame_ash.cc", @@ -2078,6 +2125,20 @@ split_static_library("ui") { "webui/welcome_ui.cc", "webui/welcome_ui.h", ] + if (enable_dice_support) { + sources += [ + "webui/signin/signin_dice_internals_handler.cc", + "webui/signin/signin_dice_internals_handler.h", + "webui/signin/signin_dice_internals_ui.cc", + "webui/signin/signin_dice_internals_ui.h", + ] + } + if (enable_oop_heap_profiling) { + sources += [ + "webui/memory_internals_ui.cc", + "webui/memory_internals_ui.h", + ] + } if (is_mac && !mac_views_browser) { sources -= [ # This is not explicitly excluded in GYP, but I think the static @@ -2178,11 +2239,15 @@ split_static_library("ui") { "crypto_module_delegate_nss.h", "crypto_module_password_dialog_nss.cc", "crypto_module_password_dialog_nss.h", - "webui/options/certificate_manager_handler.cc", - "webui/options/certificate_manager_handler.h", "webui/settings/certificates_handler.cc", "webui/settings/certificates_handler.h", ] + if (is_chromeos) { + sources += [ + "webui/options/certificate_manager_handler.cc", + "webui/options/certificate_manager_handler.h", + ] + } } if (is_mac || is_win) { sources += [ @@ -2243,12 +2308,14 @@ split_static_library("ui") { "android/chrome_http_auth_handler.cc", "android/chrome_http_auth_handler.h", "android/color_chooser_dialog_android.cc", + "android/content_settings/ads_blocked_infobar_delegate.cc", + "android/content_settings/ads_blocked_infobar_delegate.h", "android/content_settings/popup_blocked_infobar_delegate.cc", "android/content_settings/popup_blocked_infobar_delegate.h", - "android/content_settings/subresource_filter_infobar_delegate.cc", - "android/content_settings/subresource_filter_infobar_delegate.h", "android/context_menu_helper.cc", "android/context_menu_helper.h", + "android/infobars/ads_blocked_infobar.cc", + "android/infobars/ads_blocked_infobar.h", "android/infobars/app_banner_infobar_android.cc", "android/infobars/app_banner_infobar_android.h", "android/infobars/autofill_credit_card_filling_infobar.cc", @@ -2280,9 +2347,6 @@ split_static_library("ui") { "android/infobars/search_geolocation_disclosure_infobar.cc", "android/infobars/search_geolocation_disclosure_infobar.h", "android/infobars/simple_confirm_infobar_builder.cc", - "android/infobars/simple_confirm_infobar_builder.h", - "android/infobars/subresource_filter_infobar.cc", - "android/infobars/subresource_filter_infobar.h", "android/infobars/translate_compact_infobar.cc", "android/infobars/translate_compact_infobar.h", "android/infobars/translate_infobar.cc", @@ -2297,9 +2361,7 @@ split_static_library("ui") { "android/omnibox/omnibox_view_util.cc", "android/omnibox/omnibox_view_util.h", "android/page_info/certificate_chain_helper.cc", - "android/page_info/certificate_chain_helper.h", "android/page_info/certificate_viewer_android.cc", - "android/page_info/certificate_viewer_android.h", "android/page_info/connection_info_popup_android.cc", "android/page_info/connection_info_popup_android.h", "android/page_info/page_info_popup_android.cc", @@ -2308,19 +2370,18 @@ split_static_library("ui") { "android/snackbars/auto_signin_prompt_controller.cc", "android/snackbars/auto_signin_prompt_controller.h", "android/ssl_client_certificate_request.cc", - "android/ssl_client_certificate_request.h", "android/tab_contents/chrome_web_contents_view_delegate_android.cc", "android/tab_contents/chrome_web_contents_view_delegate_android.h", "android/tab_model/android_live_tab_context.cc", "android/tab_model/android_live_tab_context.h", "android/tab_model/single_tab_model.cc", - "android/tab_model/single_tab_model.h", "android/tab_model/tab_model.cc", "android/tab_model/tab_model.h", "android/tab_model/tab_model_jni_bridge.cc", "android/tab_model/tab_model_jni_bridge.h", "android/tab_model/tab_model_list.cc", "android/tab_model/tab_model_list.h", + "android/tab_model/tab_model_list_observer.h", "android/toolbar/toolbar_model_android.cc", "android/toolbar/toolbar_model_android.h", "android/usb_chooser_dialog_android.cc", @@ -2333,8 +2394,6 @@ split_static_library("ui") { "webui/offline/offline_internals_ui.h", "webui/offline/offline_internals_ui_message_handler.cc", "webui/offline/offline_internals_ui_message_handler.h", - "webui/popular_sites_internals_ui.cc", - "webui/popular_sites_internals_ui.h", "webui/snippets_internals_message_handler.cc", "webui/snippets_internals_message_handler.h", "webui/snippets_internals_ui.cc", @@ -2347,6 +2406,7 @@ split_static_library("ui") { deps += [ "//chrome/browser:jni_headers", "//components/web_contents_delegate_android", + "//device/usb/public/cpp", ] deps -= [ "//ui/events" ] } else { @@ -2366,6 +2426,8 @@ split_static_library("ui") { "cocoa/accelerator_utils_cocoa.mm", "cocoa/accelerators_cocoa.h", "cocoa/accelerators_cocoa.mm", + "cocoa/animated_icon.h", + "cocoa/animated_icon.mm", "cocoa/applescript/apple_event_util.h", "cocoa/applescript/apple_event_util.mm", "cocoa/applescript/bookmark_folder_applescript.h", @@ -2627,6 +2689,7 @@ split_static_library("ui") { "cocoa/browser_window_touch_bar.mm", "cocoa/browser_window_utils.h", "cocoa/browser_window_utils.mm", + "cocoa/bubble_anchor_util_views_mac.mm", "cocoa/bubble_combobox.h", "cocoa/bubble_combobox.mm", "cocoa/bubble_sync_promo_controller.h", @@ -2666,6 +2729,8 @@ split_static_library("ui") { "cocoa/constrained_window/constrained_window_sheet_info.mm", "cocoa/constrained_window/constrained_window_web_dialog_sheet.h", "cocoa/constrained_window/constrained_window_web_dialog_sheet.mm", + "cocoa/content_settings/blocked_plugin_bubble_controller.h", + "cocoa/content_settings/blocked_plugin_bubble_controller.mm", "cocoa/content_settings/collected_cookies_mac.h", "cocoa/content_settings/collected_cookies_mac.mm", "cocoa/content_settings/content_setting_bubble_cocoa.h", @@ -2678,7 +2743,6 @@ split_static_library("ui") { "cocoa/content_settings/cookie_tree_node.mm", "cocoa/content_settings/cookies_tree_controller_bridge.h", "cocoa/content_settings/cookies_tree_controller_bridge.mm", - "cocoa/create_application_shortcut_cocoa.mm", "cocoa/create_native_web_modal_manager_cocoa.mm", "cocoa/custom_frame_view.h", "cocoa/custom_frame_view.mm", @@ -2686,6 +2750,8 @@ split_static_library("ui") { "cocoa/dev_tools_controller.mm", "cocoa/device_chooser_content_view_cocoa.h", "cocoa/device_chooser_content_view_cocoa.mm", + "cocoa/dialog_text_field_editor.h", + "cocoa/dialog_text_field_editor.mm", "cocoa/download/background_theme.h", "cocoa/download/background_theme.mm", "cocoa/download/download_danger_prompt_impl.cc", @@ -2971,7 +3037,9 @@ split_static_library("ui") { "cocoa/screen_capture_notification_ui_cocoa.h", "cocoa/screen_capture_notification_ui_cocoa.mm", "cocoa/session_crashed_bubble.mm", - "cocoa/simple_message_box_mac.mm", + "cocoa/simple_message_box_bridge_views.mm", + "cocoa/simple_message_box_cocoa.h", + "cocoa/simple_message_box_cocoa.mm", "cocoa/single_web_contents_dialog_manager_cocoa.h", "cocoa/single_web_contents_dialog_manager_cocoa.mm", "cocoa/spinner_view.h", @@ -3039,6 +3107,8 @@ split_static_library("ui") { "cocoa/toolbar/toolbar_controller.mm", "cocoa/toolbar/toolbar_view_cocoa.h", "cocoa/toolbar/toolbar_view_cocoa.mm", + "cocoa/translate/translate_bubble_bridge_views.h", + "cocoa/translate/translate_bubble_bridge_views.mm", "cocoa/translate/translate_bubble_controller.h", "cocoa/translate/translate_bubble_controller.mm", "cocoa/url_drop_target.h", @@ -3053,6 +3123,8 @@ split_static_library("ui") { "cocoa/view_resizer.h", "cocoa/web_contents_modal_dialog_manager_views_mac.h", "cocoa/web_contents_modal_dialog_manager_views_mac.mm", + "cocoa/web_textfield_touch_bar_controller.h", + "cocoa/web_textfield_touch_bar_controller.mm", "cocoa/window_size_autosaver.h", "cocoa/window_size_autosaver.mm", @@ -3117,12 +3189,14 @@ split_static_library("ui") { "views/settings_reset_prompt_dialog.h", "views/uninstall_view.cc", "views/uninstall_view.h", - "webui/cleanup_tool/cleanup_action_handler.cc", - "webui/cleanup_tool/cleanup_action_handler.h", - "webui/cleanup_tool/cleanup_tool_ui.cc", - "webui/cleanup_tool/cleanup_tool_ui.h", + "webui/conflicts_handler.cc", + "webui/conflicts_handler.h", "webui/conflicts_ui.cc", "webui/conflicts_ui.h", + "webui/module_database_conflicts_handler.cc", + "webui/module_database_conflicts_handler.h", + "webui/settings/chrome_cleanup_handler.cc", + "webui/settings/chrome_cleanup_handler.h", "webui/welcome_win10_handler.cc", "webui/welcome_win10_handler.h", "webui/welcome_win10_ui.cc", @@ -3218,7 +3292,7 @@ split_static_library("ui") { "webui/certificate_viewer_webui.h", ] if (use_aura) { - deps += [ "//build/linux:fontconfig" ] + deps += [ "//third_party/fontconfig" ] if (use_dbus) { deps += [ "//dbus" ] } @@ -3284,10 +3358,22 @@ split_static_library("ui") { "app_list/profile_loader.cc", "app_list/profile_loader.h", "app_list/profile_store.h", + "app_list/search/answer_card/answer_card_contents.cc", + "app_list/search/answer_card/answer_card_contents.h", + "app_list/search/answer_card/answer_card_result.cc", + "app_list/search/answer_card/answer_card_result.h", + "app_list/search/answer_card/answer_card_search_provider.cc", + "app_list/search/answer_card/answer_card_search_provider.h", + "app_list/search/answer_card/answer_card_web_contents.cc", + "app_list/search/answer_card/answer_card_web_contents.h", "app_list/search/app_result.cc", "app_list/search/app_result.h", "app_list/search/app_search_provider.cc", "app_list/search/app_search_provider.h", + "app_list/search/arc/arc_playstore_search_provider.cc", + "app_list/search/arc/arc_playstore_search_provider.h", + "app_list/search/arc/arc_playstore_search_result.cc", + "app_list/search/arc/arc_playstore_search_result.h", "app_list/search/common/json_response_fetcher.cc", "app_list/search/common/json_response_fetcher.h", "app_list/search/common/url_icon_source.cc", @@ -3324,8 +3410,6 @@ split_static_library("ui") { "app_list/search/webstore/webstore_provider.h", "app_list/search/webstore/webstore_result.cc", "app_list/search/webstore/webstore_result.h", - "app_list/search_answer_web_contents_delegate.cc", - "app_list/search_answer_web_contents_delegate.h", "app_list/speech_auth_helper.cc", "app_list/speech_auth_helper.h", "app_list/speech_recognizer.cc", @@ -3371,6 +3455,10 @@ split_static_library("ui") { "app_list/arc/arc_package_syncable_service.h", "app_list/arc/arc_package_syncable_service_factory.cc", "app_list/arc/arc_package_syncable_service_factory.h", + "app_list/arc/arc_pai_starter.cc", + "app_list/arc/arc_pai_starter.h", + "app_list/arc/arc_playstore_app_context_menu.cc", + "app_list/arc/arc_playstore_app_context_menu.h", "app_list/search/arc_app_result.cc", "app_list/search/arc_app_result.h", "ash/launcher/arc_app_deferred_launcher_controller.cc", @@ -3392,7 +3480,10 @@ split_static_library("ui") { "views/arc_app_dialog_view.cc", ] } - deps += [ "//ui/app_list" ] + deps += [ + "//ui/app_list", + "//ui/app_list/vector_icons", + ] } else { sources += [ "app_list/app_list_service.h", @@ -3481,6 +3572,8 @@ split_static_library("ui") { "webui/media_router/media_cast_mode.h", "webui/media_router/media_router_dialog_controller_impl.cc", "webui/media_router/media_router_dialog_controller_impl.h", + "webui/media_router/media_router_file_dialog.cc", + "webui/media_router/media_router_file_dialog.h", "webui/media_router/media_router_localized_strings_provider.cc", "webui/media_router/media_router_localized_strings_provider.h", "webui/media_router/media_router_resources_provider.cc", @@ -3538,6 +3631,8 @@ static_library("test_support") { sources = [ "cocoa/test/cocoa_test_helper.h", "cocoa/test/cocoa_test_helper.mm", + "cocoa/test/menu_test_observer.h", + "cocoa/test/menu_test_observer.mm", "cocoa/test/run_loop_testing.h", "cocoa/test/run_loop_testing.mm", "cocoa/test/scoped_force_rtl_mac.h", @@ -3588,6 +3683,7 @@ static_library("test_support") { "cocoa/extensions/browser_action_test_util_mac.mm", "cocoa/find_bar/find_bar_host_unittest_util_cocoa.mm", ] + deps += [ "//ui/base:test_support" ] } } diff --git a/chromium/chrome/browser/ui/libgtkui/BUILD.gn b/chromium/chrome/browser/ui/libgtkui/BUILD.gn index 05e5209a2b8..e24526e1dc1 100644 --- a/chromium/chrome/browser/ui/libgtkui/BUILD.gn +++ b/chromium/chrome/browser/ui/libgtkui/BUILD.gn @@ -8,22 +8,6 @@ import("//build/config/features.gni") import("//build/config/linux/gtk/gtk.gni") import("//printing/features/features.gni") -# gn orders flags on a target before flags from configs. The default config -# adds -Wall, and these flags have to be after -Wall -- so they need to come -# from a config and can't be on the target directly. -config("libgtkui_warnings") { - if (is_clang) { - cflags = [ - # G_DEFINE_TYPE automatically generates a *get_instance_private inline - # function after glib 2.37. That's unused. Prevent to complain about it. - "-Wno-unused-function", - - # G_STATIC_ASSERT uses a typedef as a static_assert. - "-Wno-unused-local-typedef", - ] - } -} - # Automatically depends on the GTK version associated with the current build # flags. group("libgtkui") { @@ -80,10 +64,7 @@ template("libgtkui") { "x11_input_method_context_impl_gtk.h", ] - configs += [ - ":libgtkui_warnings", - "//build/config/linux:x11", - ] + configs += [ "//build/config/linux:x11" ] if (use_gconf) { sources += [ @@ -104,6 +85,7 @@ template("libgtkui") { "//base:i18n", "//base/third_party/dynamic_annotations", "//cc/paint", + "//chrome/common:features", "//chrome:extra_resources", "//chrome:resources", "//chrome:strings", diff --git a/chromium/chrome/browser/ui/views/BUILD.gn b/chromium/chrome/browser/ui/views/BUILD.gn index 686e700fef9..def9d4c93dc 100644 --- a/chromium/chrome/browser/ui/views/BUILD.gn +++ b/chromium/chrome/browser/ui/views/BUILD.gn @@ -27,6 +27,7 @@ component("views") { deps = [ "//base", "//chrome/app:command_ids", + "//components/vector_icons", "//content/public/browser", "//printing/features", "//skia", @@ -34,7 +35,6 @@ component("views") { "//ui/events", "//ui/gfx", "//ui/gfx/geometry", - "//ui/vector_icons", "//url", ] diff --git a/chromium/chrome/browser/ui/webui/DEPS b/chromium/chrome/browser/ui/webui/DEPS index e54b94adcde..f866a1e74fc 100644 --- a/chromium/chrome/browser/ui/webui/DEPS +++ b/chromium/chrome/browser/ui/webui/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+components/about_ui" "+components/invalidation", "+components/onc", "+components/proximity_auth", diff --git a/chromium/chrome/browser/ui/webui/OWNERS b/chromium/chrome/browser/ui/webui/OWNERS index 38e940d6cd1..909e06d2304 100644 --- a/chromium/chrome/browser/ui/webui/OWNERS +++ b/chromium/chrome/browser/ui/webui/OWNERS @@ -5,13 +5,6 @@ per-file devtools_ui*=pfeldman@chromium.org per-file inspect_ui*=dgozman@chromium.org per-file inspect_ui*=pfeldman@chromium.org -# chrome://history is going through a lot of changes right now; make sure to -# talk to one of the listed OWNERS before changing the pre-Material Design UI. -per-file *history*=set noparent -per-file *history*=calamity@chromium.org -per-file *history*=dbeam@chromium.org -per-file *history*=tsergeant@chromium.org - per-file md_history_ui*=calamity@chromium.org per-file md_history_ui*=tsergeant@chromium.org @@ -19,7 +12,6 @@ per-file signin_internals_ui*=achuith@chromium.org per-file snippets_internals*=file://components/ntp_snippets/OWNERS per-file ntp_tiles_internals_ui.*=file://components/ntp_tiles/OWNERS -per-file popular_sites_internals_ui.*=file://components/ntp_tiles/OWNERS per-file net_export_ui.*=file://net/OWNERS # Maintaining ownership from this file's original Chrome OS location. diff --git a/chromium/chrome/browser/ui/webui/about_ui.cc b/chromium/chrome/browser/ui/webui/about_ui.cc index f3922f56d61..5c6c5e31383 100644 --- a/chromium/chrome/browser/ui/webui/about_ui.cc +++ b/chromium/chrome/browser/ui/webui/about_ui.cc @@ -33,23 +33,24 @@ #include "base/sys_info.h" #include "base/task_scheduler/post_task.h" #include "base/threading/thread.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/about_flags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/defaults.h" -#include "chrome/browser/memory/tab_manager.h" -#include "chrome/browser/memory/tab_stats.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/resource_coordinator/tab_manager.h" +#include "chrome/browser/resource_coordinator/tab_stats.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" +#include "components/about_ui/credit_utils.h" #include "components/grit/components_resources.h" #include "components/strings/grit/components_locale_settings.h" #include "content/public/browser/browser_thread.h" @@ -205,9 +206,10 @@ class ChromeOSTermsHandler DCHECK_CURRENTLY_ON(BrowserThread::UI); if (path_ == chrome::kOemEulaURLPath) { // Load local OEM EULA from the disk. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::Bind(&ChromeOSTermsHandler::LoadOemEulaFileOnFileThread, this)); + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::BindOnce(&ChromeOSTermsHandler::LoadOemEulaFileAsync, this), + base::BindOnce(&ChromeOSTermsHandler::ResponseOnUIThread, this)); } else { // Try to load online version of ChromeOS terms first. // ChromeOSOnlineTermsHandler object destroys itself. @@ -222,33 +224,35 @@ class ChromeOSTermsHandler loader->GetResponseResult(&contents_); if (contents_.empty()) { // Load local ChromeOS terms from the file. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::Bind(&ChromeOSTermsHandler::LoadEulaFileOnFileThread, this)); + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::BindOnce(&ChromeOSTermsHandler::LoadEulaFileAsync, this), + base::BindOnce(&ChromeOSTermsHandler::ResponseOnUIThread, this)); } else { ResponseOnUIThread(); } } - void LoadOemEulaFileOnFileThread() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + void LoadOemEulaFileAsync() { + base::ThreadRestrictions::AssertIOAllowed(); + const chromeos::StartupCustomizationDocument* customization = chromeos::StartupCustomizationDocument::GetInstance(); - if (customization->IsReady()) { - base::FilePath oem_eula_file_path; - if (net::FileURLToFilePath(GURL(customization->GetEULAPage(locale_)), - &oem_eula_file_path)) { - if (!base::ReadFileToString(oem_eula_file_path, &contents_)) { - contents_.clear(); - } + if (!customization->IsReady()) + return; + + base::FilePath oem_eula_file_path; + if (net::FileURLToFilePath(GURL(customization->GetEULAPage(locale_)), + &oem_eula_file_path)) { + if (!base::ReadFileToString(oem_eula_file_path, &contents_)) { + contents_.clear(); } } - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&ChromeOSTermsHandler::ResponseOnUIThread, this)); } - void LoadEulaFileOnFileThread() { + void LoadEulaFileAsync() { + base::ThreadRestrictions::AssertIOAllowed(); + std::string file_path = base::StringPrintf(chrome::kEULAPathFormat, locale_.c_str()); if (!base::ReadFileToString(base::FilePath(file_path), &contents_)) { @@ -260,9 +264,6 @@ class ChromeOSTermsHandler contents_.clear(); } } - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&ChromeOSTermsHandler::ResponseOnUIThread, this)); } void ResponseOnUIThread() { @@ -422,6 +423,7 @@ std::string ChromeURLs() { #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) const char kAboutDiscardsRunCommand[] = "run"; +const char kAboutDiscardsSkipUnloadHandlersCommand[] = "skip_unload_handlers"; // Html output helper functions @@ -466,12 +468,13 @@ std::string BuildAboutDiscardsRunPage() { } std::vector<std::string> GetHtmlTabDescriptorsForDiscardPage() { - memory::TabManager* tab_manager = g_browser_process->GetTabManager(); - memory::TabStatsList stats = tab_manager->GetTabStats(); + resource_coordinator::TabManager* tab_manager = + g_browser_process->GetTabManager(); + resource_coordinator::TabStatsList stats = tab_manager->GetTabStats(); std::vector<std::string> titles; titles.reserve(stats.size()); - for (memory::TabStatsList::iterator it = stats.begin(); it != stats.end(); - ++it) { + for (resource_coordinator::TabStatsList::iterator it = stats.begin(); + it != stats.end(); ++it) { std::string str; str.reserve(4096); str += "<b>"; @@ -485,13 +488,22 @@ std::vector<std::string> GetHtmlTabDescriptorsForDiscardPage() { #if defined(OS_CHROMEOS) str += base::StringPrintf(" (%d) ", it->oom_score); #endif + str += base::StringPrintf(" (%d discards this session)", + it->discard_count); + if (!it->is_discarded) { - str += base::StringPrintf(" <a href='%s%s/%" PRId64 "'>Discard</a>", + str += "<ul>"; + str += base::StringPrintf("<li><a href='%s%s/%" PRId64 + "'>Discard (safely)</a></li>", chrome::kChromeUIDiscardsURL, kAboutDiscardsRunCommand, it->tab_contents_id); + str += base::StringPrintf( + "<li><a href='%s%s/%" PRId64 + "?%s'>Discard (allow unsafe process shutdown)</a></li>", + chrome::kChromeUIDiscardsURL, kAboutDiscardsRunCommand, + it->tab_contents_id, kAboutDiscardsSkipUnloadHandlersCommand); + str += "</ul>"; } - str += base::StringPrintf(" (%d discards this session)", - it->discard_count); titles.push_back(str); } return titles; @@ -500,18 +512,31 @@ std::vector<std::string> GetHtmlTabDescriptorsForDiscardPage() { std::string AboutDiscards(const std::string& path) { std::string output; int64_t web_content_id; - memory::TabManager* tab_manager = g_browser_process->GetTabManager(); - - std::vector<std::string> path_split = base::SplitString( - path, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - if (path_split.size() == 2 && path_split[0] == kAboutDiscardsRunCommand && - base::StringToInt64(path_split[1], &web_content_id)) { - tab_manager->DiscardTabById(web_content_id); - return BuildAboutDiscardsRunPage(); - } else if (path_split.size() == 1 && - path_split[0] == kAboutDiscardsRunCommand) { - tab_manager->DiscardTab(); - return BuildAboutDiscardsRunPage(); + resource_coordinator::TabManager* tab_manager = + g_browser_process->GetTabManager(); + + std::vector<std::string> url_split = + base::SplitString(path, "?", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + if (!url_split.empty()) { + resource_coordinator::TabManager::DiscardTabCondition discard_condition; + if ((url_split.size() > 1 && + url_split[1] == kAboutDiscardsSkipUnloadHandlersCommand)) { + discard_condition = resource_coordinator::TabManager::kUrgentShutdown; + } else { + discard_condition = resource_coordinator::TabManager::kProactiveShutdown; + } + + std::vector<std::string> path_split = base::SplitString( + url_split[0], "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + if (path_split.size() == 2 && path_split[0] == kAboutDiscardsRunCommand && + base::StringToInt64(path_split[1], &web_content_id)) { + tab_manager->DiscardTabById(web_content_id, discard_condition); + return BuildAboutDiscardsRunPage(); + } else if (path_split.size() == 1 && + path_split[0] == kAboutDiscardsRunCommand) { + tab_manager->DiscardTab(discard_condition); + return BuildAboutDiscardsRunPage(); + } } AppendHeader(&output, 0, "About discards"); @@ -535,9 +560,9 @@ std::string AboutDiscards(const std::string& path) { } output.append(base::StringPrintf("%d discards this session. ", tab_manager->discard_count())); - output.append(base::StringPrintf("<a href='%s%s'>Discard tab now</a>", - chrome::kChromeUIDiscardsURL, - kAboutDiscardsRunCommand)); + output.append(base::StringPrintf( + "<a href='%s%s'>Discard tab now (safely)</a>", + chrome::kChromeUIDiscardsURL, kAboutDiscardsRunCommand)); base::SystemMemoryInfoKB meminfo; base::GetSystemMemoryInfo(&meminfo); @@ -690,32 +715,14 @@ void AboutUIHTMLSource::StartDataRequest( idr = IDR_KEYBOARD_UTILS_JS; #endif - base::StringPiece raw_response = - ResourceBundle::GetSharedInstance().GetRawDataResource(idr); if (idr == IDR_ABOUT_UI_CREDITS_HTML) { - const uint8_t* next_encoded_byte = - reinterpret_cast<const uint8_t*>(raw_response.data()); - size_t input_size_remaining = raw_response.size(); - BrotliDecoderState* decoder = - BrotliDecoderCreateInstance(nullptr /* no custom allocator */, - nullptr /* no custom deallocator */, - nullptr /* no custom memory handle */); - CHECK(!!decoder); - while (!BrotliDecoderIsFinished(decoder)) { - size_t output_size_remaining = 0; - CHECK(BrotliDecoderDecompressStream( - decoder, &input_size_remaining, &next_encoded_byte, - &output_size_remaining, nullptr, - nullptr) != BROTLI_DECODER_RESULT_ERROR); - const uint8_t* output_buffer = - BrotliDecoderTakeOutput(decoder, &output_size_remaining); - response.insert(response.end(), output_buffer, - output_buffer + output_size_remaining); - } - BrotliDecoderDestroyInstance(decoder); + response = about_ui::GetCredits(true /*include_scripts*/); } else { - response = raw_response.as_string(); + response = ResourceBundle::GetSharedInstance() + .GetRawDataResource(idr) + .as_string(); } + #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) } else if (source_name_ == chrome::kChromeUIDiscardsHost) { response = AboutDiscards(path); diff --git a/chromium/chrome/browser/ui/webui/app_list/OWNERS b/chromium/chrome/browser/ui/webui/app_list/OWNERS index 2aebc091562..ed54f09c40c 100644 --- a/chromium/chrome/browser/ui/webui/app_list/OWNERS +++ b/chromium/chrome/browser/ui/webui/app_list/OWNERS @@ -1,3 +1,2 @@ calamity@chromium.org -mgiuca@chromium.org -tapted@chromium.org +khmel@chromium.org diff --git a/chromium/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc b/chromium/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc deleted file mode 100644 index acd5bd3da5d..00000000000 --- a/chromium/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc +++ /dev/null @@ -1,726 +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 "chrome/browser/ui/webui/bidi_checker_web_ui_test.h" - -#include "base/base_paths.h" -#include "base/i18n/rtl.h" -#include "base/message_loop/message_loop.h" -#include "base/path_service.h" -#include "base/strings/utf_string_conversions.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/platform_thread.h" -#include "base/time/time.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" -#include "chrome/browser/history/history_service_factory.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/autofill/core/browser/autofill_profile.h" -#include "components/autofill/core/browser/autofill_test_utils.h" -#include "components/autofill/core/browser/personal_data_manager.h" -#include "components/history/core/browser/history_service.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/browser_thread.h" -#include "ui/base/resource/resource_bundle.h" - -// Test cases here are disabled on all platforms due to http://crbug.com/511439 - -using autofill::AutofillProfile; -using autofill::PersonalDataManager; - -static const base::FilePath::CharType* kWebUIBidiCheckerLibraryJS = - FILE_PATH_LITERAL("third_party/bidichecker/bidichecker_packaged.js"); - -namespace { -base::FilePath WebUIBidiCheckerLibraryJSPath() { - base::FilePath src_root; - if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_root)) - LOG(ERROR) << "Couldn't find source root"; - return src_root.Append(kWebUIBidiCheckerLibraryJS); -} - -// Since synchronization isn't complete for the ResourceBundle class, reload -// locale resources on the IO thread. -// crbug.com/95425, crbug.com/132752 -void ReloadLocaleResourcesOnIOThread(const std::string& new_locale) { - if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) { - LOG(ERROR) - << content::BrowserThread::IO - << " != " << base::PlatformThread::CurrentId(); - NOTREACHED(); - } - - std::string locale; - { - base::ThreadRestrictions::ScopedAllowIO allow_io_scope; - locale.assign( - ResourceBundle::GetSharedInstance().ReloadLocaleResources(new_locale)); - } - ASSERT_FALSE(locale.empty()); -} - -// Since synchronization isn't complete for the ResourceBundle class, reload -// locale resources on the IO thread. -// crbug.com/95425, crbug.com/132752 -void ReloadLocaleResources(const std::string& new_locale) { - content::BrowserThread::PostTaskAndReply( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&ReloadLocaleResourcesOnIOThread, - base::ConstRef(new_locale)), - base::MessageLoop::QuitWhenIdleClosure()); - content::RunMessageLoop(); -} - -} // namespace - -static const base::FilePath::CharType* kBidiCheckerTestsJS = - FILE_PATH_LITERAL("bidichecker_tests.js"); - -void WebUIBidiCheckerBrowserTest::SetUp() { - argv_ = base::CommandLine::ForCurrentProcess()->GetArgs(); -} - -void WebUIBidiCheckerBrowserTest::TearDown() { - // Reset command line to the way it was before the test was run. - base::CommandLine::ForCurrentProcess()->InitFromArgv(argv_); -} - -WebUIBidiCheckerBrowserTest::~WebUIBidiCheckerBrowserTest() {} - -WebUIBidiCheckerBrowserTest::WebUIBidiCheckerBrowserTest() {} - -void WebUIBidiCheckerBrowserTest::SetUpInProcessBrowserTestFixture() { - WebUIBrowserTest::SetUpInProcessBrowserTestFixture(); - WebUIBrowserTest::AddLibrary(WebUIBidiCheckerLibraryJSPath()); - WebUIBrowserTest::AddLibrary(base::FilePath(kBidiCheckerTestsJS)); -} - -void WebUIBidiCheckerBrowserTest::RunBidiCheckerOnPage( - const std::string& page_url, bool is_rtl) { - ui_test_utils::NavigateToURL(browser(), GURL(page_url)); - ASSERT_TRUE(RunJavascriptTest("runBidiChecker", base::Value(page_url), - base::Value(is_rtl))); -} - -void DISABLED_WebUIBidiCheckerBrowserTestLTR::RunBidiCheckerOnPage( - const std::string& page_url) { - WebUIBidiCheckerBrowserTest::RunBidiCheckerOnPage(page_url, false); -} - -void DISABLED_WebUIBidiCheckerBrowserTestRTL::RunBidiCheckerOnPage( - const std::string& page_url) { - WebUIBidiCheckerBrowserTest::RunBidiCheckerOnPage(page_url, true); -} - -void DISABLED_WebUIBidiCheckerBrowserTestRTL::SetUpOnMainThread() { - WebUIBidiCheckerBrowserTest::SetUpOnMainThread(); - base::FilePath pak_path; - app_locale_ = base::i18n::GetConfiguredLocale(); - ASSERT_TRUE(PathService::Get(base::FILE_MODULE, &pak_path)); - pak_path = pak_path.DirName(); - pak_path = pak_path.AppendASCII("pseudo_locales"); - pak_path = pak_path.AppendASCII("fake-bidi"); - pak_path = pak_path.ReplaceExtension(FILE_PATH_LITERAL("pak")); - ResourceBundle::GetSharedInstance().OverrideLocalePakForTest(pak_path); - ReloadLocaleResources("he"); - base::i18n::SetICUDefaultLocale("he"); -} - -void DISABLED_WebUIBidiCheckerBrowserTestRTL::TearDownOnMainThread() { - WebUIBidiCheckerBrowserTest::TearDownOnMainThread(); - - base::i18n::SetICUDefaultLocale(app_locale_); - ResourceBundle::GetSharedInstance().OverrideLocalePakForTest( - base::FilePath()); - ReloadLocaleResources(app_locale_); -} - -// Tests - -//============================== -// chrome://history -//============================== - -static void SetupHistoryPageTest(Browser* browser, - const std::string& page_url, - const std::string& page_title) { - history::HistoryService* history_service = - HistoryServiceFactory::GetForProfile(browser->profile(), - ServiceAccessType::IMPLICIT_ACCESS); - const GURL history_url = GURL(page_url); - history_service->AddPage( - history_url, base::Time::Now(), history::SOURCE_BROWSED); - history_service->SetPageTitle(history_url, base::UTF8ToUTF16(page_title)); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestHistoryPage) { - // Test an Israeli news site with a Hebrew title. - SetupHistoryPageTest(browser(), - "http://www.ynet.co.il", - "\xD7\x91\xD7\x93\xD7\x99\xD7\xA7\xD7\x94\x21"); - RunBidiCheckerOnPage(chrome::kChromeUIHistoryURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestHistoryPage) { - SetupHistoryPageTest(browser(), "http://www.google.com", "Google"); - RunBidiCheckerOnPage(chrome::kChromeUIHistoryURL); -} - -//============================== -// chrome://about -//============================== - -// This page isn't localized to an RTL language so we test it only in English. -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, TestAboutPage) { - RunBidiCheckerOnPage(chrome::kChromeUIAboutURL); -} - -//============================== -// chrome://crashes -//============================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestCrashesPage) { - RunBidiCheckerOnPage(chrome::kChromeUICrashesURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestCrashesPage) { - RunBidiCheckerOnPage(chrome::kChromeUICrashesURL); -} - -//============================== -// chrome://downloads -//============================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestDownloadsPageLTR) { - RunBidiCheckerOnPage(chrome::kChromeUIDownloadsURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestDownloadsPageRTL) { - RunBidiCheckerOnPage(chrome::kChromeUIDownloadsURL); -} - -//============================== -// chrome://newtab -//============================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestNewTabPage) { - RunBidiCheckerOnPage(chrome::kChromeUINewTabURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestNewTabPage) { - RunBidiCheckerOnPage(chrome::kChromeUINewTabURL); -} - -//============================== -// chrome://settings-frame -//============================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsPage) { - RunBidiCheckerOnPage(chrome::kChromeUISettingsFrameURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsPage) { - RunBidiCheckerOnPage(chrome::kChromeUISettingsFrameURL); -} - -static void SetupSettingsAutofillPageTest(Profile* profile, - const char* first_name, - const char* middle_name, - const char* last_name, - const char* email, - const char* company, - const char* address1, - const char* address2, - const char* city, - const char* state, - const char* zipcode, - const char* country, - const char* phone) { - autofill::test::DisableSystemServices(profile->GetPrefs()); - AutofillProfile autofill_profile; - autofill::test::SetProfileInfo(&autofill_profile, - first_name, - middle_name, - last_name, - email, - company, - address1, - address2, - city, - state, - zipcode, - country, - phone); - PersonalDataManager* personal_data_manager = - autofill::PersonalDataManagerFactory::GetForProfile(profile); - ASSERT_TRUE(personal_data_manager); - personal_data_manager->AddProfile(autofill_profile); -} - -static void TearDownSettingsAutofillPageTest() { - autofill::test::ReenableSystemServices(); -} - -// http://crbug.com/94642 -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - DISABLED_TestSettingsAutofillPage) { - SetupSettingsAutofillPageTest(browser()->profile(), - "\xD7\x9E\xD7\xA9\xD7\x94", - "\xD7\x91", - "\xD7\x9B\xD7\x94\xD7\x9F", - "moshe.b.cohen@biditest.com", - "\xD7\x91\xD7\x93\xD7\x99\xD7\xA7\xD7\x94\x20" - "\xD7\x91\xD7\xA2\xD7\x9E", - "\xD7\x93\xD7\xA8\xD7\x9A\x20\xD7\x9E\xD7\xA0" - "\xD7\x97\xD7\x9D\x20\xD7\x91\xD7\x92\xD7" - "\x99\xD7\x9F\x20\x32\x33", - "\xD7\xA7\xD7\x95\xD7\x9E\xD7\x94\x20\x32\x36", - "\xD7\xAA\xD7\x9C\x20\xD7\x90\xD7\x91\xD7\x99" - "\xD7\x91", - "", - "66183", - "\xD7\x99\xD7\xA9\xD7\xA8\xD7\x90\xD7\x9C", - "0000"); - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kAutofillSubPage); - RunBidiCheckerOnPage(url); - TearDownSettingsAutofillPageTest(); -} - -// http://crbug.com/94642 -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - DISABLED_TestSettingsAutofillPage) { - SetupSettingsAutofillPageTest(browser()->profile(), - "Milton", - "C.", - "Waddams", - "red.swingline@initech.com", - "Initech", - "4120 Freidrich Lane", - "Basement", - "Austin", - "Texas", - "78744", - "United States", - "5125551234"); - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kAutofillSubPage); - RunBidiCheckerOnPage(url); - TearDownSettingsAutofillPageTest(); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsClearBrowserDataPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kClearBrowserDataSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsClearBrowserDataPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kClearBrowserDataSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsContentSettingsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kContentSettingsSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsContentSettingsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kContentSettingsSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsContentSettingsExceptionsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += - std::string(chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsContentSettingsExceptionsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += - std::string(chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsLanguageOptionsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kLanguageOptionsSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsLanguageOptionsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kLanguageOptionsSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsSearchEnginesOptionsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kSearchEnginesSubPage); - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsSearchEnginesOptionsPage) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += std::string(chrome::kSearchEnginesSubPage); - RunBidiCheckerOnPage(url); -} - -//=================================== -// chrome://settings-frame/startup -//=================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameStartup) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "startup"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameStartup) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "startup"; - RunBidiCheckerOnPage(url); -} - -//=================================== -// chrome://settings-frame/importData -//=================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameImportData) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kImportDataSubPage; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameImportData) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kImportDataSubPage; - RunBidiCheckerOnPage(url); -} - -#if !defined(OS_CHROMEOS) -//======================================== -// chrome://settings-frame/manageProfile -//======================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameMangageProfile) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kManageProfileSubPage; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameMangageProfile) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kManageProfileSubPage; - RunBidiCheckerOnPage(url); -} -#endif // !defined(OS_CHROMEOS) - -//=================================================== -// chrome://settings-frame/contentExceptions#cookies -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsCookies) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#cookies"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsCookies) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#cookies"; - RunBidiCheckerOnPage(url); -} - -//=================================================== -// chrome://settings-frame/contentExceptions#images -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsImages) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#images"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsImages) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#images"; - RunBidiCheckerOnPage(url); -} - -//====================================================== -// chrome://settings-frame/contentExceptions#javascript -//====================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsJavascript) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#javascript"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsJavascript) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#javascript"; - RunBidiCheckerOnPage(url); -} - -//=================================================== -// chrome://settings-frame/contentExceptions#plugins -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsPlugins) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#plugins"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsPlugins) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#plugins"; - RunBidiCheckerOnPage(url); -} - -//=================================================== -// chrome://settings-frame/contentExceptions#popups -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsPopups) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#popups"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsPopups) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#popups"; - RunBidiCheckerOnPage(url); -} - -//=================================================== -// chrome://settings-frame/contentExceptions#location -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsLocation) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#location"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsLocation) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#location"; - RunBidiCheckerOnPage(url); -} - -//=================================================== -// chrome://settings-frame/contentExceptions#notifications -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsNotifications) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#notifications"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsNotifications) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#notifications"; - RunBidiCheckerOnPage(url); -} - -//=================================================== -// chrome://settings-frame/contentExceptions#mouselock -//=================================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameContentExceptionsMouseLock) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#mouselock"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameContentExceptionsMouseLock) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kDeprecatedOptionsContentSettingsExceptionsSubPage; - url += "#mouselock"; - RunBidiCheckerOnPage(url); -} - -//======================================== -// chrome://settings-frame/handlers -//======================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameHandler) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kHandlerSettingsSubPage; - RunBidiCheckerOnPage(url); -} - -// Fails on chromeos. http://crbug.com/125367 -#if defined(OS_CHROMEOS) -#define MAYBE_TestSettingsFrameHandler DISABLED_TestSettingsFrameHandler -#else -#define MAYBE_TestSettingsFrameHandler TestSettingsFrameHandler -#endif - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - MAYBE_TestSettingsFrameHandler) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += chrome::kHandlerSettingsSubPage; - RunBidiCheckerOnPage(url); -} - -//======================================== -// chrome://settings-frame/cookies -//======================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFrameCookies) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "cookies"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameCookies) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "cookies"; - RunBidiCheckerOnPage(url); -} - -//======================================== -// chrome://settings-frame/passwords -//======================================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestSettingsFramePasswords) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "passwords"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFramePasswords) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "passwords"; - RunBidiCheckerOnPage(url); -} - -//======================================== -// chrome://settings-frame/fonts -//======================================== - -#if defined(OS_MACOSX) -#define MAYBE_TestSettingsFrameFonts DISABLED_TestSettingsFrameFonts -#else -#define MAYBE_TestSettingsFrameFonts TestSettingsFrameFonts -#endif -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - MAYBE_TestSettingsFrameFonts) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "fonts"; - RunBidiCheckerOnPage(url); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestSettingsFrameFonts) { - std::string url(chrome::kChromeUISettingsFrameURL); - url += "fonts"; - RunBidiCheckerOnPage(url); -} - -// Test other uber iframes. - -//============================== -// chrome://extensions-frame -//============================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, - TestExtensionsFrame) { - RunBidiCheckerOnPage(chrome::kChromeUIExtensionsFrameURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, - TestExtensionsFrame) { - RunBidiCheckerOnPage(chrome::kChromeUIExtensionsFrameURL); -} - -//============================== -// chrome://help-frame -//============================== - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR, TestHelpFrame) { - RunBidiCheckerOnPage(chrome::kChromeUIHelpFrameURL); -} - -IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, TestHelpFrame) { - RunBidiCheckerOnPage(chrome::kChromeUIHelpFrameURL); -} diff --git a/chromium/chrome/browser/ui/webui/bidi_checker_web_ui_test.h b/chromium/chrome/browser/ui/webui/bidi_checker_web_ui_test.h deleted file mode 100644 index affa5d8c620..00000000000 --- a/chromium/chrome/browser/ui/webui/bidi_checker_web_ui_test.h +++ /dev/null @@ -1,59 +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 CHROME_BROWSER_UI_WEBUI_BIDI_CHECKER_WEB_UI_TEST_H_ -#define CHROME_BROWSER_UI_WEBUI_BIDI_CHECKER_WEB_UI_TEST_H_ - -#include "base/command_line.h" -#include "chrome/test/base/web_ui_browser_test.h" - -// Base class for BidiChecker-based tests. Preloads the BidiChecker JS library -// for each test. -class WebUIBidiCheckerBrowserTest : public WebUIBrowserTest { - public: - ~WebUIBidiCheckerBrowserTest() override; - - // testing::Test implementation. - void SetUp() override; - void TearDown() override; - - protected: - WebUIBidiCheckerBrowserTest(); - - // Runs the Bidi Checker on the given page URL. |is_rtl| should be true when - // the active page locale is RTL. - void RunBidiCheckerOnPage(const std::string& page_url, bool is_rtl); - - // Setup test path. - void SetUpInProcessBrowserTestFixture() override; - - private: - // The command line args used to run the test before being changed in SetUp(). - base::CommandLine::StringVector argv_; -}; - -// Base class for BidiChecker-based tests that run with an LTR UI. -// Disabled on all platforms due to http://crbug.com/511439 -class DISABLED_WebUIBidiCheckerBrowserTestLTR - : public WebUIBidiCheckerBrowserTest { - public: - void RunBidiCheckerOnPage(const std::string& page_url); -}; - -// Base class for BidiChecker-based tests that run with an RTL UI. -// Disabled on all platforms due to http://crbug.com/511439 -class DISABLED_WebUIBidiCheckerBrowserTestRTL - : public WebUIBidiCheckerBrowserTest { - public: - void RunBidiCheckerOnPage(const std::string& page_url); - - protected: - void SetUpOnMainThread() override; - void TearDownOnMainThread() override; - - // The app locale before we change it - std::string app_locale_; -}; - -#endif // CHROME_BROWSER_UI_WEBUI_BIDI_CHECKER_WEB_UI_TEST_H_ diff --git a/chromium/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc index c2440d846f8..132edd248a3 100644 --- a/chromium/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc @@ -7,6 +7,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -20,8 +21,6 @@ class BookmarksTest : public InProcessBrowserTest { BookmarksTest() {} void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - // Re-enable accessibility checks when audit failures are resolved. // AX_TEXT_01: http://crbug.com/559201 // AX_ARIA_08: http://crbug.com/559202 @@ -30,7 +29,8 @@ class BookmarksTest : public InProcessBrowserTest { void OpenBookmarksManager() { content::TestNavigationObserver navigation_observer( - browser()->tab_strip_model()->GetActiveWebContents(), 2); + browser()->tab_strip_model()->GetActiveWebContents(), + MdBookmarksUI::IsEnabled() ? 1 : 2); navigation_observer.StartWatchingNewWebContents(); // Bring up the bookmarks manager tab. @@ -41,6 +41,14 @@ class BookmarksTest : public InProcessBrowserTest { void AssertIsBookmarksPage(content::WebContents* tab) { GURL url; std::string out; + + if (MdBookmarksUI::IsEnabled()) { + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + tab, "domAutomationController.send(location.href)", &out)); + ASSERT_EQ("chrome://bookmarks/", out); + return; + } + ASSERT_TRUE(content::ExecuteScriptAndExtractString( tab, "domAutomationController.send(location.protocol)", @@ -54,11 +62,6 @@ class BookmarksTest : public InProcessBrowserTest { } }; -IN_PROC_BROWSER_TEST_F(BookmarksTest, ShouldRedirectToExtension) { - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIBookmarksURL)); - AssertIsBookmarksPage(browser()->tab_strip_model()->GetActiveWebContents()); -} - IN_PROC_BROWSER_TEST_F(BookmarksTest, CommandOpensBookmarksTab) { ASSERT_EQ(1, browser()->tab_strip_model()->count()); @@ -92,7 +95,7 @@ IN_PROC_BROWSER_TEST_F(BookmarksTest, AssertIsBookmarksPage(browser()->tab_strip_model()->GetActiveWebContents()); // Switch to first tab and run command again. - browser()->tab_strip_model()->ActivateTabAt(0, true); + browser()->tab_strip_model()->ActivateTabAt(0, true); chrome::ShowBookmarkManager(browser()); // Ensure the bookmarks ui tab is active. diff --git a/chromium/chrome/browser/ui/webui/browsing_history_handler.cc b/chromium/chrome/browser/ui/webui/browsing_history_handler.cc index 7a33df54030..3aea7513220 100644 --- a/chromium/chrome/browser/ui/webui/browsing_history_handler.cc +++ b/chromium/chrome/browser/ui/webui/browsing_history_handler.cc @@ -7,7 +7,6 @@ #include <stddef.h> #include <set> -#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" @@ -19,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/default_clock.h" #include "base/time/time.h" -#include "base/values.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/favicon/large_icon_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -27,7 +25,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/webui/favicon_source.h" -#include "chrome/browser/ui/webui/large_icon_source.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/features.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" @@ -52,12 +50,6 @@ #include "chrome/browser/supervised_user/supervised_user_url_filter.h" #endif -#if defined(OS_ANDROID) -#include "chrome/browser/android/preferences/preferences_launcher.h" -#else -#include "chrome/common/chrome_features.h" -#endif - using bookmarks::BookmarkModel; namespace { @@ -84,15 +76,6 @@ base::string16 GetRelativeDateLocalized(base::Clock* clock, return date_str; } -// Sets the correct year when substracting months from a date. -void NormalizeMonths(base::Time::Exploded* exploded) { - // Decrease a year at a time until we have a proper date. - while (exploded->month < 1) { - exploded->month += 12; - exploded->year--; - } -} - // Gets the name and type of a device for the given sync client ID. // |name| and |type| are out parameters. void GetDeviceNameAndType(const browser_sync::ProfileSyncService* sync_service, @@ -149,12 +132,10 @@ void SetHistoryEntryUrlAndTitle(BrowsingHistoryService::HistoryEntry* entry, base::i18n::AdjustStringForLocaleDirection(&title_to_set); } -#if !defined(OS_ANDROID) // Number of chars to truncate titles when making them "short". static const size_t kShortTitleLength = 300; if (title_to_set.size() > kShortTitleLength) title_to_set.resize(kShortTitleLength); -#endif result->SetString("title", title_to_set); } @@ -269,14 +250,7 @@ void BrowsingHistoryHandler::RegisterMessages() { // Create our favicon data source. Profile* profile = Profile::FromWebUI(web_ui()); - -#if defined(OS_ANDROID) - favicon::LargeIconService* large_icon_service = - LargeIconServiceFactory::GetForBrowserContext(profile); - content::URLDataSource::Add(profile, new LargeIconSource(large_icon_service)); -#else content::URLDataSource::Add(profile, new FaviconSource(profile)); -#endif web_ui()->RegisterMessageCallback("queryHistory", base::Bind(&BrowsingHistoryHandler::HandleQueryHistory, @@ -292,59 +266,27 @@ void BrowsingHistoryHandler::RegisterMessages() { base::Unretained(this))); } -bool BrowsingHistoryHandler::ExtractIntegerValueAtIndex( - const base::ListValue* value, - int index, - int* out_int) { - double double_value; - if (value->GetDouble(index, &double_value)) { - *out_int = static_cast<int>(double_value); - return true; - } - NOTREACHED(); - return false; -} - void BrowsingHistoryHandler::HandleQueryHistory(const base::ListValue* args) { history::QueryOptions options; // Parse the arguments from JavaScript. There are five required arguments: // - the text to search for (may be empty) - // - the offset from which the search should start (in multiples of week or - // month, set by the next argument). - // - the range (BrowsingHistoryHandler::Range) Enum value that sets the range - // of the query. // - the end time for the query. Only results older than this time will be // returned. // - the maximum number of results to return (may be 0, meaning that there // is no maximum). base::string16 search_text = ExtractStringValue(args); - int offset; - if (!args->GetInteger(1, &offset)) { - NOTREACHED() << "Failed to convert argument 1. "; - return; - } - int range; - if (!args->GetInteger(2, &range)) { - NOTREACHED() << "Failed to convert argument 2. "; - return; - } - - if (range == BrowsingHistoryHandler::MONTH) - SetQueryTimeInMonths(offset, &options); - else if (range == BrowsingHistoryHandler::WEEK) - SetQueryTimeInWeeks(offset, &options); double end_time; - if (!args->GetDouble(3, &end_time)) { - NOTREACHED() << "Failed to convert argument 3. "; + if (!args->GetDouble(1, &end_time)) { + NOTREACHED() << "Failed to convert argument 1. "; return; } if (end_time) options.end_time = base::Time::FromJsTime(end_time); - if (!ExtractIntegerValueAtIndex(args, 4, &options.max_count)) { - NOTREACHED() << "Failed to convert argument 4."; + if (!args->GetInteger(2, &options.max_count)) { + NOTREACHED() << "Failed to convert argument 2."; return; } @@ -368,7 +310,7 @@ void BrowsingHistoryHandler::HandleRemoveVisits(const base::ListValue* args) { NOTREACHED() << "Unable to extract arguments"; return; } - DCHECK(timestamps->GetSize() > 0); + DCHECK_GT(timestamps->GetSize(), 0U); std::unique_ptr<BrowsingHistoryService::HistoryEntry> entry( new BrowsingHistoryService::HistoryEntry()); @@ -395,16 +337,11 @@ void BrowsingHistoryHandler::HandleRemoveVisits(const base::ListValue* args) { void BrowsingHistoryHandler::HandleClearBrowsingData( const base::ListValue* args) { -#if defined(OS_ANDROID) - chrome::android::PreferencesLauncher::OpenClearBrowsingData( - web_ui()->GetWebContents()); -#else // TODO(beng): This is an improper direct dependency on Browser. Route this // through some sort of delegate. Browser* browser = chrome::FindBrowserWithWebContents( web_ui()->GetWebContents()); chrome::ShowClearBrowsingDataDialog(browser); -#endif } void BrowsingHistoryHandler::HandleRemoveBookmark(const base::ListValue* args) { @@ -414,59 +351,6 @@ void BrowsingHistoryHandler::HandleRemoveBookmark(const base::ListValue* args) { bookmarks::RemoveAllBookmarks(model, GURL(url)); } -void BrowsingHistoryHandler::SetQueryTimeInWeeks( - int offset, history::QueryOptions* options) { - // LocalMidnight returns the beginning of the current day so get the - // beginning of the next one. - base::Time midnight = - clock_->Now().LocalMidnight() + base::TimeDelta::FromDays(1); - options->end_time = midnight - - base::TimeDelta::FromDays(7 * offset); - options->begin_time = midnight - - base::TimeDelta::FromDays(7 * (offset + 1)); -} - -void BrowsingHistoryHandler::SetQueryTimeInMonths( - int offset, history::QueryOptions* options) { - // Configure the begin point of the search to the start of the - // current month. - base::Time::Exploded exploded; - clock_->Now().LocalMidnight().LocalExplode(&exploded); - exploded.day_of_month = 1; - - if (offset == 0) { - if (!base::Time::FromLocalExploded(exploded, &options->begin_time)) { - // TODO(maksims): implement errors handling here. - NOTIMPLEMENTED(); - } - - // Set the end time of this first search to null (which will - // show results from the future, should the user's clock have - // been set incorrectly). - options->end_time = base::Time(); - } else { - // Go back |offset| months in the past. The end time is not inclusive, so - // use the first day of the |offset| - 1 and |offset| months (e.g. for - // the last month, |offset| = 1, use the first days of the last month and - // the current month. - exploded.month -= offset - 1; - // Set the correct year. - NormalizeMonths(&exploded); - if (!base::Time::FromLocalExploded(exploded, &options->end_time)) { - // TODO(maksims): implement errors handling here. - NOTIMPLEMENTED(); - } - - exploded.month -= 1; - // Set the correct year - NormalizeMonths(&exploded); - if (!base::Time::FromLocalExploded(exploded, &options->begin_time)) { - // TODO(maksims): implement errors handling here. - NOTIMPLEMENTED(); - } - } -} - void BrowsingHistoryHandler::OnQueryComplete( std::vector<BrowsingHistoryService::HistoryEntry>* results, BrowsingHistoryService::QueryResultsInfo* query_results_info) { @@ -510,20 +394,6 @@ void BrowsingHistoryHandler::OnQueryComplete( "queryEndTime", GetRelativeDateLocalized(clock_.get(), query_results_info->end_time)); -// Not used in mobile UI, and cause ~16kb of code bloat (crbug/683386). -#ifndef OS_ANDROID - // TODO(calamity): Clean up grouped-specific fields once grouped history is - // removed. - results_info.SetString( - "queryStartMonth", - base::TimeFormatMonthAndYear(query_results_info->start_time)); - results_info.SetString( - "queryInterval", - base::DateIntervalFormat(query_results_info->start_time, - query_results_info->end_time, - base::DATE_FORMAT_MONTH_WEEKDAY_DAY)); -#endif - web_ui()->CallJavascriptFunctionUnsafe("historyResult", results_info, results_value); } diff --git a/chromium/chrome/browser/ui/webui/browsing_history_handler.h b/chromium/chrome/browser/ui/webui/browsing_history_handler.h index 0c9a95234e6..0b486f251cf 100644 --- a/chromium/chrome/browser/ui/webui/browsing_history_handler.h +++ b/chromium/chrome/browser/ui/webui/browsing_history_handler.h @@ -8,21 +8,16 @@ #include <stdint.h> #include <memory> -#include <set> #include <string> +#include <utility> #include <vector> #include "base/macros.h" -#include "base/strings/string16.h" #include "base/time/clock.h" #include "base/values.h" #include "chrome/browser/history/browsing_history_service_handler.h" #include "content/public/browser/web_ui_message_handler.h" -namespace history { -struct QueryOptions; -} // namespace history - // The handler for Javascript messages related to the "history" view. class BrowsingHistoryHandler : public content::WebUIMessageHandler, @@ -64,29 +59,8 @@ class BrowsingHistoryHandler : private: FRIEND_TEST_ALL_PREFIXES(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions); - FRIEND_TEST_ALL_PREFIXES(BrowsingHistoryHandlerTest, SetQueryTimeInWeeks); - FRIEND_TEST_ALL_PREFIXES(BrowsingHistoryHandlerTest, SetQueryTimeInMonths); FRIEND_TEST_ALL_PREFIXES(BrowsingHistoryHandlerTest, MdTruncatesTitles); - // The range for which to return results: - // - ALLTIME: allows access to all the results in a paginated way. - // - WEEK: the last 7 days. - // - MONTH: the last calendar month. - enum Range { - ALL_TIME = 0, - WEEK = 1, - MONTH = 2 - }; - - bool ExtractIntegerValueAtIndex( - const base::ListValue* value, int index, int* out_int); - - // Sets the query options for a week-wide query, |offset| weeks ago. - void SetQueryTimeInWeeks(int offset, history::QueryOptions* options); - - // Sets the query options for a monthly query, |offset| months ago. - void SetQueryTimeInMonths(int offset, history::QueryOptions* options); - // The clock used to vend times. std::unique_ptr<base::Clock> clock_; diff --git a/chromium/chrome/browser/ui/webui/browsing_history_handler_unittest.cc b/chromium/chrome/browser/ui/webui/browsing_history_handler_unittest.cc index 15ef926f324..cd16e202d44 100644 --- a/chromium/chrome/browser/ui/webui/browsing_history_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/browsing_history_handler_unittest.cc @@ -33,6 +33,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_web_ui.h" #include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -87,7 +88,6 @@ class BrowsingHistoryHandlerWithWebUIForTesting set_clock(base::WrapUnique(test_clock_)); set_web_ui(web_ui); test_clock_->SetNow(PretendNow()); - } base::SimpleTestClock* test_clock() { return test_clock_; } @@ -165,67 +165,6 @@ class BrowsingHistoryHandlerTest : public ::testing::Test { std::unique_ptr<content::WebContents> web_contents_; }; -TEST_F(BrowsingHistoryHandlerTest, SetQueryTimeInWeeks) { - BrowsingHistoryHandlerWithWebUIForTesting handler(web_ui()); - history::QueryOptions options; - - // Querying this week should result in end time being midnight tonight and - // begin time being midnight a week ago. - handler.SetQueryTimeInWeeks(0, &options); - base::Time midnight_tonight = - PretendNow().LocalMidnight() + base::TimeDelta::FromDays(1); - EXPECT_EQ(midnight_tonight, options.end_time); - base::Time midnight_a_week_ago = - midnight_tonight - base::TimeDelta::FromDays(7); - EXPECT_EQ(midnight_a_week_ago, options.begin_time); - - // Querying 4 weeks ago should result in end time being midnight 4 weeks ago - // and begin time being midnight 5 weeks ago. - handler.SetQueryTimeInWeeks(4, &options); - base::Time midnight_4_weeks_ago = - PretendNow().LocalMidnight() - base::TimeDelta::FromDays(27); - EXPECT_EQ(midnight_4_weeks_ago, options.end_time); - base::Time midnight_5_weeks_ago = - midnight_4_weeks_ago - base::TimeDelta::FromDays(7); - EXPECT_EQ(midnight_5_weeks_ago, options.begin_time); -} - -TEST_F(BrowsingHistoryHandlerTest, SetQueryTimeInMonths) { - BrowsingHistoryHandlerWithWebUIForTesting handler(web_ui()); - history::QueryOptions options; - - base::Time::Exploded exploded_expected_time; - PretendNow().LocalExplode(&exploded_expected_time); - - // Querying this month should result in end time being unset and begin time - // being midnight of the first. - handler.SetQueryTimeInMonths(0, &options); - EXPECT_EQ(base::Time(), options.end_time); - - exploded_expected_time.day_of_month = 1; - exploded_expected_time.hour = 0; - base::Time first_jan_2015_midnight; - EXPECT_TRUE(base::Time::FromLocalExploded(exploded_expected_time, - &first_jan_2015_midnight)); - EXPECT_EQ(first_jan_2015_midnight, options.begin_time); - - // Querying 6 months ago should result in end time being 2014-08-01 and begin - // time being 2014-07-01. - handler.SetQueryTimeInMonths(6, &options); - - exploded_expected_time.year = 2014; - exploded_expected_time.month = 8; - base::Time first_aug_2014_midnight; - EXPECT_TRUE(base::Time::FromLocalExploded(exploded_expected_time, - &first_aug_2014_midnight)); - EXPECT_EQ(first_aug_2014_midnight, options.end_time); - exploded_expected_time.month = 7; - base::Time first_jul_2014_midnight; - EXPECT_TRUE(base::Time::FromLocalExploded(exploded_expected_time, - &first_jul_2014_midnight)); - EXPECT_EQ(first_jul_2014_midnight, options.begin_time); -} - // Tests that BrowsingHistoryHandler is informed about WebHistoryService // deletions. TEST_F(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions) { @@ -238,8 +177,9 @@ TEST_F(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions) { BrowsingHistoryHandlerWithWebUIForTesting handler(web_ui()); handler.RegisterMessages(); - web_history_service()->ExpireHistoryBetween(std::set<GURL>(), base::Time(), - base::Time::Max(), callback); + web_history_service()->ExpireHistoryBetween( + std::set<GURL>(), base::Time(), base::Time::Max(), callback, + PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_EQ(1U, web_ui()->call_data().size()); EXPECT_EQ("historyDeleted", web_ui()->call_data().back()->function_name()); @@ -253,8 +193,9 @@ TEST_F(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions) { handler.RegisterMessages(); sync_service()->SetSyncActive(true); - web_history_service()->ExpireHistoryBetween(std::set<GURL>(), base::Time(), - base::Time::Max(), callback); + web_history_service()->ExpireHistoryBetween( + std::set<GURL>(), base::Time(), base::Time::Max(), callback, + PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_EQ(2U, web_ui()->call_data().size()); EXPECT_EQ("historyDeleted", web_ui()->call_data().back()->function_name()); @@ -274,7 +215,8 @@ TEST_F(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions) { std::set<GURL>(), base::Time(), base::Time::Max(), base::Bind( &BrowsingHistoryService::RemoveWebHistoryComplete, - handler.browsing_history_service_->weak_factory_.GetWeakPtr())); + handler.browsing_history_service_->weak_factory_.GetWeakPtr()), + PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_EQ(3U, web_ui()->call_data().size()); EXPECT_EQ("deleteComplete", web_ui()->call_data().back()->function_name()); @@ -288,8 +230,9 @@ TEST_F(BrowsingHistoryHandlerTest, ObservingWebHistoryDeletions) { BrowsingHistoryHandlerWithWebUIForTesting handler(web_ui()); handler.RegisterMessages(); - web_history_service()->ExpireHistoryBetween(std::set<GURL>(), base::Time(), - base::Time::Max(), callback); + web_history_service()->ExpireHistoryBetween( + std::set<GURL>(), base::Time(), base::Time::Max(), callback, + PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS); // No additional WebUI calls were made. EXPECT_EQ(3U, web_ui()->call_data().size()); @@ -308,8 +251,10 @@ TEST_F(BrowsingHistoryHandlerTest, MdTruncatesTitles) { "ngurlislong.com"), base::Time()); ASSERT_GT(long_result.url().spec().size(), 300u); + std::vector<history::URLResult> result_vector; + result_vector.push_back(std::move(long_result)); history::QueryResults results; - results.AppendURLBySwapping(&long_result); + results.SetURLResults(std::move(result_vector)); BrowsingHistoryHandlerWithWebUIForTesting handler(web_ui()); handler.RegisterMessages(); // Needed to create BrowsingHistoryService. diff --git a/chromium/chrome/browser/ui/webui/cast/cast_ui.cc b/chromium/chrome/browser/ui/webui/cast/cast_ui.cc index 13d5e2cccb4..68f113bf2ae 100644 --- a/chromium/chrome/browser/ui/webui/cast/cast_ui.cc +++ b/chromium/chrome/browser/ui/webui/cast/cast_ui.cc @@ -4,8 +4,8 @@ #include "chrome/browser/ui/webui/cast/cast_ui.h" -#include "chrome/browser/media/router/media_router_factory.h" -#include "chrome/browser/media/router/mojo/media_router_mojo_impl.h" +#include "chrome/browser/media/router/event_page_request_manager.h" +#include "chrome/browser/media/router/event_page_request_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -16,11 +16,11 @@ CastUI::CastUI(content::WebUI* web_ui) : content::WebUIController(web_ui) { // Retrieve the ID of the component extension. - // TODO(crbug.com/597778): remove reference to MediaRouterMojoImpl. - auto* router = static_cast<media_router::MediaRouterMojoImpl*>( - media_router::MediaRouterFactory::GetApiForBrowserContext( - web_ui->GetWebContents()->GetBrowserContext())); - std::string extension_id = router->media_route_provider_extension_id(); + auto* event_page_request_manager = + media_router::EventPageRequestManagerFactory::GetApiForBrowserContext( + web_ui->GetWebContents()->GetBrowserContext()); + std::string extension_id = + event_page_request_manager->media_route_provider_extension_id(); // Set up the chrome://cast data source and add required resources. content::WebUIDataSource* html_source = diff --git a/chromium/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chromium/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index ad04d3c07d5..d2c501111f6 100644 --- a/chromium/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chromium/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc @@ -16,6 +16,7 @@ #include "chrome/browser/devtools/devtools_ui_bindings.h" #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" #include "chrome/browser/engagement/site_engagement_service.h" +#include "chrome/browser/media/media_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/search/suggestions/suggestions_ui.h" @@ -32,18 +33,17 @@ #include "chrome/browser/ui/webui/flags_ui.h" #include "chrome/browser/ui/webui/flash_ui.h" #include "chrome/browser/ui/webui/gcm_internals_ui.h" -#include "chrome/browser/ui/webui/help/help_ui.h" #include "chrome/browser/ui/webui/identity_internals_ui.h" #include "chrome/browser/ui/webui/instant_ui.h" #include "chrome/browser/ui/webui/interstitials/interstitial_ui.h" #include "chrome/browser/ui/webui/invalidations_ui.h" #include "chrome/browser/ui/webui/local_state/local_state_ui.h" #include "chrome/browser/ui/webui/log_web_ui_url.h" +#include "chrome/browser/ui/webui/media/media_engagement_ui.h" #include "chrome/browser/ui/webui/net_export_ui.h" #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h" #include "chrome/browser/ui/webui/ntp_tiles_internals_ui.h" #include "chrome/browser/ui/webui/omnibox/omnibox_ui.h" -#include "chrome/browser/ui/webui/options/options_ui.h" #include "chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h" #include "chrome/browser/ui/webui/physical_web/physical_web_ui.h" #include "chrome/browser/ui/webui/policy_material_design_ui.h" @@ -76,7 +76,10 @@ #include "components/favicon_base/select_favicon_frames.h" #include "components/history/core/browser/history_types.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/web_ui/constants.h" +#include "components/safe_browsing/web_ui/safe_browsing_ui.h" #include "components/signin/core/common/profile_management_switches.h" +#include "components/signin/core/common/signin_features.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/common/content_client.h" @@ -111,7 +114,6 @@ #if defined(OS_ANDROID) #include "chrome/browser/ui/webui/offline/offline_internals_ui.h" -#include "chrome/browser/ui/webui/popular_sites_internals_ui.h" #include "chrome/browser/ui/webui/snippets_internals_ui.h" #include "chrome/browser/ui/webui/webapks_ui.h" #else @@ -126,7 +128,6 @@ #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" #include "chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_ui.h" #include "chrome/browser/ui/webui/system_info_ui.h" -#include "chrome/browser/ui/webui/uber/uber_ui.h" #endif #if defined(OS_CHROMEOS) @@ -171,7 +172,6 @@ #endif #if defined(OS_WIN) -#include "chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.h" #include "chrome/browser/ui/webui/conflicts_ui.h" #include "chrome/browser/ui/webui/set_as_default_browser_ui_win.h" #include "chrome/browser/ui/webui/welcome_win10_ui.h" @@ -193,6 +193,10 @@ #include "chrome/browser/ui/webui/app_list/start_page_ui.h" #endif +#if BUILDFLAG(ENABLE_DICE_SUPPORT) +#include "chrome/browser/ui/webui/signin/signin_dice_internals_ui.h" +#endif + #if BUILDFLAG(ENABLE_EXTENSIONS) #include "chrome/browser/extensions/extension_web_ui.h" #include "chrome/browser/ui/webui/extensions/extensions_ui.h" @@ -205,6 +209,10 @@ #include "extensions/common/manifest.h" #endif +#if BUILDFLAG(ENABLE_OOP_HEAP_PROFILING) +#include "chrome/browser/ui/webui/memory_internals_ui.h" +#endif + using content::WebUI; using content::WebUIController; using ui::WebDialogUI; @@ -366,6 +374,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI<ProfilerUI>; if (url.host() == chrome::kChromeUIQuotaInternalsHost) return &NewWebUI<QuotaInternalsUI>; + if (url.host() == safe_browsing::kChromeUISafeBrowsingHost) + return &NewWebUI<safe_browsing::SafeBrowsingUI>; if (url.host() == chrome::kChromeUISignInInternalsHost) return &NewWebUI<SignInInternalsUI>; if (url.host_piece() == chrome::kChromeUISuggestionsHost) @@ -399,7 +409,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, extensions::ExtensionSystem::Get(profile)->extension_service()) { return &NewWebUI<AppLauncherPageUI>; } -#endif // !defined(OS_CHROMEOS) +#endif // defined(OS_CHROMEOS) // Bookmarks are part of NTP on Android. if (url.host_piece() == chrome::kChromeUIBookmarksHost) { @@ -415,51 +425,26 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, ::switches::MdFeedbackEnabled()) { return &NewWebUI<MdFeedbackUI>; } - // Help is implemented with native UI elements on Android. - if (url.host_piece() == chrome::kChromeUIHelpFrameHost) - return &NewWebUI<HelpUI>; // Identity API is not available on Android. if (url.host_piece() == chrome::kChromeUIIdentityInternalsHost) return &NewWebUI<IdentityInternalsUI>; if (url.host_piece() == chrome::kChromeUINewTabHost) return &NewWebUI<NewTabUI>; - if (url.host_piece() == chrome::kChromeUIMdSettingsHost) + // Settings are implemented with native UI elements on Android. + if (url.host_piece() == chrome::kChromeUISettingsHost || + url.host_piece() == chrome::kChromeUIMdSettingsHost) { return &NewWebUI<settings::MdSettingsUI>; - // If the material design extensions page is enabled, it gets its own host. - // Otherwise, it's handled by the uber settings page. - if (url.host_piece() == chrome::kChromeUIExtensionsHost && - base::FeatureList::IsEnabled(features::kMaterialDesignExtensions)) { - return &NewWebUI<extensions::ExtensionsUI>; } + if (url.host_piece() == chrome::kChromeUIExtensionsHost) + return &NewWebUI<extensions::ExtensionsUI>; if (url.host_piece() == chrome::kChromeUIHistoryHost) return &NewWebUI<MdHistoryUI>; - // Material Design Settings gets its own host, if enabled. - if (base::FeatureList::IsEnabled(features::kMaterialDesignSettings) && - url.host_piece() == chrome::kChromeUISettingsHost) { - return &NewWebUI<settings::MdSettingsUI>; - } - // Settings are implemented with native UI elements on Android. - // Handle chrome://settings if settings in a window is enabled. - if (url.host_piece() == chrome::kChromeUISettingsFrameHost || - (url.host_piece() == chrome::kChromeUISettingsHost && - ::switches::SettingsWindowEnabled())) { - return &NewWebUI<options::OptionsUI>; - } if (url.host_piece() == chrome::kChromeUISyncFileSystemInternalsHost) return &NewWebUI<SyncFileSystemInternalsUI>; if (url.host_piece() == chrome::kChromeUISystemInfoHost) return &NewWebUI<SystemInfoUI>; - // Uber frame is not used on Android. - if (url.host_piece() == chrome::kChromeUIUberFrameHost) - return &NewWebUI<UberFrameUI>; - // Uber page is not used on Android. - if (url.host_piece() == chrome::kChromeUIUberHost) - return &NewWebUI<UberUI>; #endif // !defined(OS_ANDROID) #if defined(OS_WIN) - if (base::FeatureList::IsEnabled(features::kCleanupToolUI) && - url.host_piece() == chrome::kChromeUICleanupToolHost) - return &NewWebUI<CleanupToolUI>; if (url.host_piece() == chrome::kChromeUIConflictsHost) return &NewWebUI<ConflictsUI>; if (url.host_piece() == chrome::kChromeUIMetroFlowHost) @@ -512,8 +497,6 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, #if defined(OS_ANDROID) if (url.host_piece() == chrome::kChromeUIOfflineInternalsHost) return &NewWebUI<OfflineInternalsUI>; - if (url.host_piece() == chrome::kChromeUIPopularSitesInternalsHost) - return &NewWebUI<PopularSitesInternalsUI>; if (url.host_piece() == chrome::kChromeUISnippetsInternalsHost && !profile->IsOffTheRecord()) return &NewWebUI<SnippetsInternalsUI>; @@ -586,10 +569,21 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, if (url.host_piece() == chrome::kChromeUIAppListStartPageHost) return &NewWebUI<app_list::StartPageUI>; #endif +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + if (url.host() == chrome::kChromeUISigninDiceInternalsHost && + !profile->IsOffTheRecord() && + switches::IsAccountConsistencyDiceEnabled()) { + return &NewWebUI<SigninDiceInternalsUI>; + } +#endif #if BUILDFLAG(ENABLE_EXTENSIONS) if (url.host_piece() == chrome::kChromeUIExtensionsFrameHost) return &NewWebUI<extensions::ExtensionsUI>; #endif +#if BUILDFLAG(ENABLE_OOP_HEAP_PROFILING) + if (url.host_piece() == chrome::kChromeUIMemoryInternalsHost) + return &NewWebUI<MemoryInternalsUI>; +#endif #if BUILDFLAG(ENABLE_PLUGINS) if (url.host_piece() == chrome::kChromeUIFlashHost) return &NewWebUI<FlashUI>; @@ -639,6 +633,11 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI<SiteEngagementUI>; } + if (MediaEngagementService::IsEnabled() && + url.host_piece() == chrome::kChromeUIMediaEngagementHost) { + return &NewWebUI<MediaEngagementUI>; + } + return NULL; } @@ -813,7 +812,6 @@ base::RefCountedMemory* ChromeWebUIControllerFactory::GetFaviconResourceBytes( // Android doesn't use the Options/Settings pages. if (page_url.host_piece() == chrome::kChromeUISettingsHost || - page_url.host_piece() == chrome::kChromeUISettingsFrameHost || page_url.host_piece() == chrome::kChromeUIMdSettingsHost) return settings_utils::GetFaviconResourceBytes(scale_factor); diff --git a/chromium/chrome/browser/ui/webui/chromeos/DEPS b/chromium/chrome/browser/ui/webui/chromeos/DEPS index 9175df117f1..0f730741cf3 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/DEPS +++ b/chromium/chrome/browser/ui/webui/chromeos/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+components/login", "+components/user_manager", "+media/audio/sounds", + "+services/device/public/interfaces", ] specific_include_rules = { diff --git a/chromium/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc index 51096b2b2e1..fda473bef00 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.cc @@ -5,6 +5,8 @@ #include "chrome/browser/ui/webui/chromeos/certificate_manager_dialog_ui.h" #include <memory> +#include <string> +#include <utility> #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -24,6 +26,7 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_message_handler.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/template_expressions.h" #include "ui/base/webui/jstemplate_builder.h" #include "ui/base/webui/web_ui_util.h" @@ -90,6 +93,15 @@ void CertificateManagerDialogHTMLSource::StartDataRequest( // Return (and cache) the main options html page as the default. response_bytes = ui::ResourceBundle::GetSharedInstance(). LoadDataResourceBytes(IDR_CERT_MANAGER_DIALOG_HTML); + // Pre-process i18n strings. + ui::TemplateReplacements replacements; + ui::TemplateReplacementsFromDictionaryValue(*localized_strings_, + &replacements); + std::string replaced = ui::ReplaceTemplateExpressions( + base::StringPiece(response_bytes->front_as<char>(), + response_bytes->size()), + replacements); + response_bytes = base::RefCountedString::TakeString(&replaced); } callback.Run(response_bytes.get()); diff --git a/chromium/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc index c13d04e71fe..e51b5420644 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc @@ -672,11 +672,12 @@ void DriveInternalsWebUIHandler::UpdateGCacheContentsSection() { base::DictionaryValue* gcache_summary = new base::DictionaryValue; base::PostTaskWithTraitsAndReply( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, - base::Bind(&GetGCacheContents, root_path, gcache_contents, - gcache_summary), - base::Bind(&DriveInternalsWebUIHandler::OnGetGCacheContents, - weak_ptr_factory_.GetWeakPtr(), base::Owned(gcache_contents), - base::Owned(gcache_summary))); + base::BindOnce(&GetGCacheContents, root_path, gcache_contents, + gcache_summary), + base::BindOnce(&DriveInternalsWebUIHandler::OnGetGCacheContents, + weak_ptr_factory_.GetWeakPtr(), + base::Owned(gcache_contents), + base::Owned(gcache_summary))); } void DriveInternalsWebUIHandler::UpdateFileSystemContentsSection() { @@ -711,10 +712,10 @@ void DriveInternalsWebUIHandler::UpdateLocalStorageUsageSection() { base::DictionaryValue* local_storage_summary = new base::DictionaryValue; base::PostTaskWithTraitsAndReply( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, - base::Bind(&GetFreeDiskSpace, home_path, local_storage_summary), - base::Bind(&DriveInternalsWebUIHandler::OnGetFreeDiskSpace, - weak_ptr_factory_.GetWeakPtr(), - base::Owned(local_storage_summary))); + base::BindOnce(&GetFreeDiskSpace, home_path, local_storage_summary), + base::BindOnce(&DriveInternalsWebUIHandler::OnGetFreeDiskSpace, + weak_ptr_factory_.GetWeakPtr(), + base::Owned(local_storage_summary))); } else { LOG(ERROR) << "Home directory not found"; } diff --git a/chromium/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc index c38c67ecfb8..1e126725709 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc @@ -550,11 +550,11 @@ void DeviceEmulatorMessageHandler::OnJavascriptAllowed() { power_observer_.reset(new PowerObserver(this)); system::InputDeviceSettings::Get()->TouchpadExists( - base::Bind(&DeviceEmulatorMessageHandler::TouchpadExists, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&DeviceEmulatorMessageHandler::TouchpadExists, + weak_ptr_factory_.GetWeakPtr())); system::InputDeviceSettings::Get()->MouseExists( - base::Bind(&DeviceEmulatorMessageHandler::MouseExists, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&DeviceEmulatorMessageHandler::MouseExists, + weak_ptr_factory_.GetWeakPtr())); } void DeviceEmulatorMessageHandler::OnJavascriptDisallowed() { diff --git a/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc b/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc index da8840f5ffa..1f22919bc9d 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc @@ -45,7 +45,7 @@ FirstRunActor::StepPosition& FirstRunActor::StepPosition::SetLeft(int left) { std::unique_ptr<base::DictionaryValue> FirstRunActor::StepPosition::AsValue() const { - base::DictionaryValue* result = new base::DictionaryValue(); + auto result = base::MakeUnique<base::DictionaryValue>(); if (top_ != kNoneValue) result->SetInteger("top", top_); if (right_ != kNoneValue) @@ -54,7 +54,7 @@ std::unique_ptr<base::DictionaryValue> FirstRunActor::StepPosition::AsValue() result->SetInteger("bottom", bottom_); if (left_ != kNoneValue) result->SetInteger("left", left_); - return base::WrapUnique(result); + return result; } FirstRunActor::FirstRunActor() diff --git a/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc index f3319f57c04..cbe4caf67fc 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/values.h" +#include "chromeos/chromeos_switches.h" #include "content/public/browser/web_ui.h" namespace chromeos { @@ -43,21 +44,34 @@ void FirstRunHandler::RemoveBackgroundHoles() { void FirstRunHandler::ShowStepPositioned(const std::string& name, const StepPosition& position) { - web_ui()->CallJavascriptFunctionUnsafe( - "cr.FirstRun.showStep", base::Value(name), *position.AsValue()); + base::DictionaryValue step_params; + step_params.SetString("name", name); + step_params.Set("position", + base::MakeUnique<base::Value>(*position.AsValue())); + step_params.SetList("pointWithOffset", base::MakeUnique<base::ListValue>()); + step_params.SetBoolean("voiceInteractionEnabled", + chromeos::switches::IsVoiceInteractionEnabled()); + + web_ui()->CallJavascriptFunctionUnsafe("cr.FirstRun.showStep", step_params); } void FirstRunHandler::ShowStepPointingTo(const std::string& name, int x, int y, int offset) { - auto null = base::MakeUnique<base::Value>(); + base::DictionaryValue step_params; + step_params.SetString("name", name); + step_params.Set("position", base::MakeUnique<base::Value>()); base::ListValue point_with_offset; point_with_offset.AppendInteger(x); point_with_offset.AppendInteger(y); point_with_offset.AppendInteger(offset); - web_ui()->CallJavascriptFunctionUnsafe( - "cr.FirstRun.showStep", base::Value(name), *null, point_with_offset); + step_params.SetList("pointWithOffset", + base::MakeUnique<base::ListValue>(point_with_offset)); + step_params.SetBoolean("voiceInteractionEnabled", + chromeos::switches::IsVoiceInteractionEnabled()); + + web_ui()->CallJavascriptFunctionUnsafe("cr.FirstRun.showStep", step_params); } void FirstRunHandler::HideCurrentStep() { diff --git a/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc index c439b90da9a..727af757342 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc @@ -44,13 +44,8 @@ void SetLocalizedStrings(base::DictionaryValue* localized_strings) { "trayText", l10n_util::GetStringUTF16(IDS_FIRST_RUN_TRAY_STEP_TEXT)); localized_strings->SetString( "helpHeader", l10n_util::GetStringUTF16(IDS_FIRST_RUN_HELP_STEP_HEADER)); - base::string16 product_name = - l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME); localized_strings->SetString( - "helpText1", l10n_util::GetStringFUTF16(IDS_FIRST_RUN_HELP_STEP_TEXT_1, - product_name)); - localized_strings->SetString( - "helpText2", l10n_util::GetStringUTF16(IDS_FIRST_RUN_HELP_STEP_TEXT_2)); + "helpText", l10n_util::GetStringUTF16(IDS_FIRST_RUN_HELP_STEP_TEXT)); localized_strings->SetString( "helpKeepExploringButton", l10n_util::GetStringUTF16(IDS_FIRST_RUN_HELP_STEP_KEEP_EXPLORING_BUTTON)); diff --git a/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc index ae29d008423..b79659db37d 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc @@ -10,14 +10,12 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -33,6 +31,7 @@ #include "content/public/browser/web_ui_message_handler.h" #include "ui/base/ime/chromeos/ime_keyboard.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/chromeos/events/keyboard_layout_util.h" #include "ui/chromeos/events/pref_names.h" #include "ui/display/manager/display_manager.h" @@ -67,6 +66,14 @@ struct I18nContentToMessage { const char* i18n_content; int message; } kI18nContentToMessage[] = { + {"keyboardOverlayAssistantKeyLabel", + IDS_KEYBOARD_OVERLAY_ASSISTANT_KEY_LABEL}, + {"keyboardOverlayPlayPauseKeyLabel", + IDS_KEYBOARD_OVERLAY_PLAY_PAUSE_KEY_LABEL}, + {"keyboardOverlaySystemMenuKeyLabel", + IDS_KEYBOARD_OVERLAY_SYSTEM_MENU_KEY_LABEL}, + {"keyboardOverlayLauncherKeyLabel", + IDS_KEYBOARD_OVERLAY_LAUNCHER_KEY_LABEL}, {"keyboardOverlayLearnMore", IDS_KEYBOARD_OVERLAY_LEARN_MORE}, {"keyboardOverlayTitle", IDS_KEYBOARD_OVERLAY_TITLE}, {"keyboardOverlayEscKeyLabel", IDS_KEYBOARD_OVERLAY_ESC_KEY_LABEL}, @@ -97,7 +104,6 @@ struct I18nContentToMessage { {"keyboardOverlayRightKeyLabel", IDS_KEYBOARD_OVERLAY_RIGHT_KEY_LABEL}, {"keyboardOverlayUpKeyLabel", IDS_KEYBOARD_OVERLAY_UP_KEY_LABEL}, {"keyboardOverlayDownKeyLabel", IDS_KEYBOARD_OVERLAY_DOWN_KEY_LABEL}, - {"keyboardOverlayInstructions", IDS_KEYBOARD_OVERLAY_INSTRUCTIONS}, {"keyboardOverlayInstructionsHide", IDS_KEYBOARD_OVERLAY_INSTRUCTIONS_HIDE}, {"keyboardOverlayActivateLastShelfItem", IDS_KEYBOARD_OVERLAY_ACTIVATE_LAST_SHELF_ITEM}, @@ -277,7 +283,8 @@ struct I18nContentToMessage { {"keyboardOverlayZoomOut", IDS_KEYBOARD_OVERLAY_ZOOM_OUT}, {"keyboardOverlayZoomScreenIn", IDS_KEYBOARD_OVERLAY_ZOOM_SCREEN_IN}, {"keyboardOverlayZoomScreenOut", IDS_KEYBOARD_OVERLAY_ZOOM_SCREEN_OUT}, -}; + {"keyboardOverlayVoiceInteraction", + IDS_KEYBOARD_OVERLAY_VOICE_INTERACTION}}; bool TopRowKeysAreFunctionKeys(Profile* profile) { if (!profile) @@ -305,6 +312,14 @@ content::WebUIDataSource* CreateKeyboardOverlayUIHTMLSource(Profile* profile) { kI18nContentToMessage[i].message); } + // |kI18nContentToMessage| is a static array initialized before it's possible + // to call ui::DeviceUsesKeyboardLayout2(), so we add the + // |keyboardOverlayInstructions| string at runtime here. + source->AddLocalizedString("keyboardOverlayInstructions", + ui::DeviceUsesKeyboardLayout2() + ? IDS_KEYBOARD_OVERLAY_INSTRUCTIONS_LAYOUT2 + : IDS_KEYBOARD_OVERLAY_INSTRUCTIONS); + source->AddString("keyboardOverlayLearnMoreURL", base::UTF8ToUTF16(kLearnMoreURL)); source->AddBoolean("keyboardOverlayHasChromeOSDiamondKey", @@ -312,13 +327,14 @@ content::WebUIDataSource* CreateKeyboardOverlayUIHTMLSource(Profile* profile) { chromeos::switches::kHasChromeOSDiamondKey)); source->AddBoolean("keyboardOverlayTopRowKeysAreFunctionKeys", TopRowKeysAreFunctionKeys(profile)); + source->AddBoolean("voiceInteractionEnabled", + chromeos::switches::IsVoiceInteractionEnabled()); + source->AddBoolean("keyboardOverlayUsesLayout2", + ui::DeviceUsesKeyboardLayout2()); ash::Shell* shell = ash::Shell::Get(); display::DisplayManager* display_manager = shell->display_manager(); source->AddBoolean("keyboardOverlayIsDisplayUIScalingEnabled", display_manager->IsDisplayUIScalingEnabled()); - source->AddBoolean( - "backspaceGoesBackFeatureEnabled", - base::FeatureList::IsEnabled(features::kBackspaceGoesBackFeature)); source->SetJsonPath("strings.js"); source->AddResourcePath("keyboard_overlay.js", IDR_KEYBOARD_OVERLAY_JS); source->SetDefaultResource(IDR_KEYBOARD_OVERLAY_HTML); diff --git a/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui_browsertest.cc index bbf48ed272a..9e1161f0714 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui_browsertest.cc @@ -59,15 +59,12 @@ bool IsDisplayUIScalingEnabled(content::WebContents* web_contents) { // keyboardOverlayData['shortcut'], so it can not be tested by this test. // 2. If it has debug modifiers: ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | // ui::EF_SHIFT_DOWN -// 3. If the shortcut action is device specific so it should not be shown -// on the keyboard overlay, i.e. START_VOICE_INTERACTION. bool ShouldSkip(const ash::AcceleratorData& accelerator) { return accelerator.keycode == ui::VKEY_MENU || accelerator.keycode == ui::VKEY_LWIN || accelerator.modifiers == ui::EF_NONE || accelerator.modifiers == - (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN) || - accelerator.action == ash::START_VOICE_INTERACTION; + (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN); } std::string KeyboardCodeToLabel(const ash::AcceleratorData& accelerator, diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/OWNERS b/chromium/chrome/browser/ui/webui/chromeos/login/OWNERS index e7a8a061b62..675ddd2e1d0 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/OWNERS +++ b/chromium/chrome/browser/ui/webui/chromeos/login/OWNERS @@ -1,2 +1,3 @@ achuith@chromium.org alemate@chromium.org +jdufault@chromium.org diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc index 2acd08bd722..bce381fd29b 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc @@ -4,6 +4,7 @@ #include "chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h" +#include "base/command_line.h" #include "base/i18n/timezone.h" #include "chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.h" #include "chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view_observer.h" @@ -12,6 +13,10 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/network/network_handler.h" +#include "chromeos/network/network_state.h" +#include "chromeos/network/network_state_handler.h" #include "components/login/localized_values_builder.h" #include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" @@ -32,6 +37,11 @@ ArcTermsOfServiceScreenHandler::ArcTermsOfServiceScreenHandler() } ArcTermsOfServiceScreenHandler::~ArcTermsOfServiceScreenHandler() { + OobeUI* oobe_ui = GetOobeUI(); + if (oobe_ui) + oobe_ui->RemoveObserver(this); + chromeos::NetworkHandler::Get()->network_state_handler()->RemoveObserver( + this, FROM_HERE); system::TimezoneSettings::GetInstance()->RemoveObserver(this); for (auto& observer : observer_list_) observer.OnViewDestroyed(this); @@ -44,17 +54,41 @@ void ArcTermsOfServiceScreenHandler::RegisterMessages() { &ArcTermsOfServiceScreenHandler::HandleAccept); } -void ArcTermsOfServiceScreenHandler::UpdateTimeZone() { +void ArcTermsOfServiceScreenHandler::MaybeLoadPlayStoreToS( + bool ignore_network_state) { + const chromeos::NetworkState* default_network = + chromeos::NetworkHandler::Get() + ->network_state_handler() + ->DefaultNetwork(); + if (!ignore_network_state && !default_network) + return; const std::string country_code = base::CountryCodeForCurrentTimezone(); - if (country_code == last_applied_contry_code_) + CallJS("loadPlayStoreToS", country_code); +} + +void ArcTermsOfServiceScreenHandler::OnCurrentScreenChanged( + OobeScreen current_screen, + OobeScreen new_screen) { + if (new_screen != OobeScreen::SCREEN_GAIA_SIGNIN) return; - last_applied_contry_code_ = country_code; - CallJS("setCountryCode", country_code); + + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(chromeos::switches::kEnableArcOOBEOptIn)) + return; + + MaybeLoadPlayStoreToS(false); + StartNetworkAndTimeZoneObserving(); } void ArcTermsOfServiceScreenHandler::TimezoneChanged( const icu::TimeZone& timezone) { - UpdateTimeZone(); + MaybeLoadPlayStoreToS(false); +} + +void ArcTermsOfServiceScreenHandler::DefaultNetworkChanged( + const NetworkState* network) { + MaybeLoadPlayStoreToS(false); } void ArcTermsOfServiceScreenHandler::DeclareLocalizedValues( @@ -140,9 +174,23 @@ void ArcTermsOfServiceScreenHandler::Hide() { pref_handler_.reset(); } +void ArcTermsOfServiceScreenHandler::StartNetworkAndTimeZoneObserving() { + if (network_time_zone_observing_) + return; + + chromeos::NetworkHandler::Get()->network_state_handler()->AddObserver( + this, FROM_HERE); + system::TimezoneSettings::GetInstance()->AddObserver(this); + network_time_zone_observing_ = true; +} + void ArcTermsOfServiceScreenHandler::Initialize() { - if (!show_on_init_) + if (!show_on_init_) { + // Send time zone information as soon as possible to able to pre-load the + // Play Store ToS. + GetOobeUI()->AddObserver(this); return; + } Show(); show_on_init_ = false; @@ -158,18 +206,30 @@ void ArcTermsOfServiceScreenHandler::DoShow() { // ToS then prefs::kArcEnabled is automatically reset in ArcSessionManager. profile->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); - system::TimezoneSettings::GetInstance()->AddObserver(this); + action_taken_ = false; ShowScreen(kScreenId); - UpdateTimeZone(); + MaybeLoadPlayStoreToS(true); + StartNetworkAndTimeZoneObserving(); + pref_handler_.reset(new arc::ArcOptInPreferenceHandler( this, profile->GetPrefs())); pref_handler_->Start(); } +bool ArcTermsOfServiceScreenHandler::NeedDispatchEventOnAction() { + if (action_taken_) + return false; + action_taken_ = true; + return true; +} + void ArcTermsOfServiceScreenHandler::HandleSkip() { + if (!NeedDispatchEventOnAction()) + return; + for (auto& observer : observer_list_) observer.OnSkip(); } @@ -177,6 +237,9 @@ void ArcTermsOfServiceScreenHandler::HandleSkip() { void ArcTermsOfServiceScreenHandler::HandleAccept( bool enable_backup_restore, bool enable_location_services) { + if (!NeedDispatchEventOnAction()) + return; + pref_handler_->EnableBackupRestore(enable_backup_restore); pref_handler_->EnableLocationService(enable_location_services); for (auto& observer : observer_list_) diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h index f37747ee3cc..fbdb0db6d5d 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h @@ -13,6 +13,8 @@ #include "chrome/browser/chromeos/arc/optin/arc_optin_preference_handler_observer.h" #include "chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" +#include "chromeos/network/network_state_handler_observer.h" #include "chromeos/settings/timezone_settings.h" namespace arc { @@ -26,7 +28,9 @@ class ArcTermsOfServiceScreenHandler : public BaseScreenHandler, public ArcTermsOfServiceScreenView, public arc::ArcOptInPreferenceHandlerObserver, - public system::TimezoneSettings::Observer { + public OobeUI::Observer, + public system::TimezoneSettings::Observer, + public chromeos::NetworkStateHandlerObserver { public: ArcTermsOfServiceScreenHandler(); ~ArcTermsOfServiceScreenHandler() override; @@ -44,9 +48,16 @@ class ArcTermsOfServiceScreenHandler void Show() override; void Hide() override; + // OobeUI::Observer: + void OnCurrentScreenChanged(OobeScreen current_screen, + OobeScreen new_screen) override; + // system::TimezoneSettings::Observer: void TimezoneChanged(const icu::TimeZone& timezone) override; + // chromeos::NetworkStateHandlerObserver: + void DefaultNetworkChanged(const NetworkState* network) override; + private: // BaseScreenHandler: void Initialize() override; @@ -55,7 +66,13 @@ class ArcTermsOfServiceScreenHandler void HandleSkip(); void HandleAccept(bool enable_backup_restore, bool enable_location_services); - void UpdateTimeZone(); + // Loads Play Store ToS content in case default network exists. If + // |ignore_network_state| is set then network state is not checked. + void MaybeLoadPlayStoreToS(bool ignore_network_state); + + void StartNetworkAndTimeZoneObserving(); + + bool NeedDispatchEventOnAction(); // arc::ArcOptInPreferenceHandlerObserver: void OnMetricsModeChanged(bool enabled, bool managed) override; @@ -67,8 +84,11 @@ class ArcTermsOfServiceScreenHandler // Whether the screen should be shown right after initialization. bool show_on_init_ = false; - // To prevent redundant updates, keep last country code used for update. - std::string last_applied_contry_code_; + // Indicates that we already started network and time zone observing. + bool network_time_zone_observing_ = false; + + // To filter out duplicate notifications from html. + bool action_taken_ = false; std::unique_ptr<arc::ArcOptInPreferenceHandler> pref_handler_; diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index b20cb02b3d7..028151d5c7b 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc @@ -50,6 +50,14 @@ namespace { const char kJsScreenPath[] = "cr.ui.Oobe"; +bool IsRemoraRequisition() { + policy::DeviceCloudPolicyManagerChromeOS* policy_manager = + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetDeviceCloudPolicyManager(); + return policy_manager && policy_manager->IsRemoraRequisition(); +} + } // namespace namespace chromeos { @@ -141,8 +149,6 @@ void CoreOobeHandler::RegisterMessages() { &CoreOobeHandler::HandleEnableLargeCursor); AddCallback("enableVirtualKeyboard", &CoreOobeHandler::HandleEnableVirtualKeyboard); - AddCallback("setForceDisableVirtualKeyboard", - &CoreOobeHandler::HandleSetForceDisableVirtualKeyboard); AddCallback("enableScreenMagnifier", &CoreOobeHandler::HandleEnableScreenMagnifier); AddCallback("enableSpokenFeedback", @@ -304,19 +310,6 @@ void CoreOobeHandler::HandleEnableVirtualKeyboard(bool enabled) { AccessibilityManager::Get()->EnableVirtualKeyboard(enabled); } -void CoreOobeHandler::HandleSetForceDisableVirtualKeyboard(bool disable) { - scoped_keyboard_disabler_.SetForceDisableVirtualKeyboard(disable); - - if (disable) { - keyboard::KeyboardController* controller = - keyboard::KeyboardController::GetInstance(); - if (controller) { - controller->HideKeyboard( - keyboard::KeyboardController::HIDE_REASON_AUTOMATIC); - } - } -} - void CoreOobeHandler::HandleEnableScreenMagnifier(bool enabled) { // TODO(nkostylev): Add support for partial screen magnifier. DCHECK(MagnificationManager::Get()); @@ -337,6 +330,13 @@ void CoreOobeHandler::HandleSetDeviceRequisition( std::string initial_requisition = connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition(); connector->GetDeviceCloudPolicyManager()->SetDeviceRequisition(requisition); + + if (IsRemoraRequisition()) { + // CfM devices default to static timezone. + g_browser_process->local_state()->SetBoolean( + prefs::kResolveDeviceTimezoneByGeolocation, false); + } + // Exit Chrome to force the restart as soon as a new requisition is set. if (initial_requisition != connector->GetDeviceCloudPolicyManager()->GetDeviceRequisition()) { diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h index c81057a8070..77b9f38c801 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h @@ -18,7 +18,6 @@ #include "chrome/browser/chromeos/login/version_info_updater.h" #include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h" #include "ui/events/event_source.h" -#include "ui/keyboard/scoped_keyboard_disabler.h" namespace base { class ListValue; @@ -108,7 +107,6 @@ class CoreOobeHandler : public BaseWebUIHandler, void HandleEnableLargeCursor(bool enabled); void HandleEnableHighContrast(bool enabled); void HandleEnableVirtualKeyboard(bool enabled); - void HandleSetForceDisableVirtualKeyboard(bool disable); void HandleEnableScreenMagnifier(bool enabled); void HandleEnableSpokenFeedback(bool /* enabled */); void HandleInitialized(); @@ -162,8 +160,6 @@ class CoreOobeHandler : public BaseWebUIHandler, DemoModeDetector demo_mode_detector_; - keyboard::ScopedKeyboardDisabler scoped_keyboard_disabler_; - DISALLOW_COPY_AND_ASSIGN(CoreOobeHandler); }; diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc index c57c266e14f..643edd3bb30 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc @@ -17,6 +17,8 @@ #include "base/sys_info.h" #include "base/task_scheduler/post_task.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/default_tick_clock.h" +#include "base/time/tick_clock.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/arc/arc_migration_constants.h" @@ -35,7 +37,11 @@ #include "components/login/localized_values_builder.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_thread.h" -#include "device/power_save_blocker/power_save_blocker.h" +#include "content/public/common/service_manager_connection.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "services/device/public/interfaces/constants.mojom.h" +#include "services/device/public/interfaces/wake_lock_provider.mojom.h" +#include "services/service_manager/public/cpp/connector.h" #include "ui/base/text/bytes_formatting.h" namespace { @@ -53,6 +59,10 @@ constexpr char kJsApiRequestRestartOnLowStorage[] = constexpr char kJsApiRequestRestartOnFailure[] = "requestRestartOnFailure"; constexpr char kJsApiOpenFeedbackDialog[] = "openFeedbackDialog"; +// If minimal migration takes this threshold or longer (in seconds), we +// will ask the user to re-enter their password. +constexpr int64_t kMinimalMigrationReenterPasswordThreshold = 45; + // UMA names. constexpr char kUmaNameFirstScreen[] = "Cryptohome.MigrationUI.FirstScreen"; constexpr char kUmaNameUserChoice[] = "Cryptohome.MigrationUI.UserChoice"; @@ -71,6 +81,10 @@ enum class FirstScreen { FIRST_SCREEN_READY = 0, FIRST_SCREEN_RESUME = 1, FIRST_SCREEN_LOW_STORAGE = 2, + FIRST_SCREEN_ARC_KIOSK = 3, + FIRST_SCREEN_START_AUTOMATICALLY = 4, + FIRST_SCREEN_RESUME_MINIMAL = 5, + FIRST_SCREEN_START_AUTOMATICALLY_MINIMAL = 6, FIRST_SCREEN_COUNT }; @@ -98,6 +112,10 @@ enum class MigrationResult { REQUEST_FAILURE_IN_RESUMED_MIGRATION = 5, MOUNT_FAILURE_IN_NEW_MIGRATION = 6, MOUNT_FAILURE_IN_RESUMED_MIGRATION = 7, + SUCCESS_IN_ARC_KIOSK_MIGRATION = 8, + GENERAL_FAILURE_IN_ARC_KIOSK_MIGRATION = 9, + REQUEST_FAILURE_IN_ARC_KIOSK_MIGRATION = 10, + MOUNT_FAILURE_IN_ARC_KIOSK_MIGRATION = 11, COUNT }; @@ -109,6 +127,8 @@ enum class RemoveCryptohomeResult { SUCCESS_IN_RESUMED_MIGRATION = 1, FAILURE_IN_NEW_MIGRATION = 2, FAILURE_IN_RESUMED_MIGRATION = 3, + SUCCESS_IN_ARC_KIOSK_MIGRATION = 4, + FAILURE_IN_ARC_KIOSK_MIGRATION = 5, COUNT }; @@ -133,25 +153,111 @@ void RecordMigrationResult(MigrationResult migration_result) { MigrationResult::COUNT); } -void RecordRemoveCryptohomeResult(bool success, bool is_resumed_migration) { - RemoveCryptohomeResult result = - success ? (is_resumed_migration - ? RemoveCryptohomeResult::SUCCESS_IN_RESUMED_MIGRATION - : RemoveCryptohomeResult::SUCCESS_IN_NEW_MIGRATION) - : (is_resumed_migration - ? RemoveCryptohomeResult::FAILURE_IN_RESUMED_MIGRATION - : RemoveCryptohomeResult::FAILURE_IN_NEW_MIGRATION); +void RecordMigrationResultSuccess(bool resume, bool arc_kiosk) { + if (arc_kiosk) + RecordMigrationResult(MigrationResult::SUCCESS_IN_ARC_KIOSK_MIGRATION); + else if (resume) + RecordMigrationResult(MigrationResult::SUCCESS_IN_RESUMED_MIGRATION); + else + RecordMigrationResult(MigrationResult::SUCCESS_IN_NEW_MIGRATION); +} + +void RecordMigrationResultGeneralFailure(bool resume, bool arc_kiosk) { + if (arc_kiosk) { + RecordMigrationResult( + MigrationResult::GENERAL_FAILURE_IN_ARC_KIOSK_MIGRATION); + } else if (resume) { + RecordMigrationResult( + MigrationResult::GENERAL_FAILURE_IN_RESUMED_MIGRATION); + } else { + RecordMigrationResult(MigrationResult::GENERAL_FAILURE_IN_NEW_MIGRATION); + } +} + +void RecordMigrationResultRequestFailure(bool resume, bool arc_kiosk) { + if (arc_kiosk) { + RecordMigrationResult( + MigrationResult::REQUEST_FAILURE_IN_ARC_KIOSK_MIGRATION); + } else if (resume) { + RecordMigrationResult( + MigrationResult::REQUEST_FAILURE_IN_RESUMED_MIGRATION); + } else { + RecordMigrationResult(MigrationResult::REQUEST_FAILURE_IN_NEW_MIGRATION); + } +} + +void RecordMigrationResultMountFailure(bool resume, bool arc_kiosk) { + if (arc_kiosk) { + RecordMigrationResult( + MigrationResult::MOUNT_FAILURE_IN_ARC_KIOSK_MIGRATION); + } else if (resume) { + RecordMigrationResult(MigrationResult::MOUNT_FAILURE_IN_RESUMED_MIGRATION); + } else { + RecordMigrationResult(MigrationResult::MOUNT_FAILURE_IN_NEW_MIGRATION); + } +} + +void RecordRemoveCryptohomeResult(RemoveCryptohomeResult result) { UMA_HISTOGRAM_ENUMERATION(kUmaNameRemoveCryptohomeResult, result, RemoveCryptohomeResult::COUNT); } +void RecordRemoveCryptohomeResultSuccess(bool resume, bool arc_kiosk) { + if (arc_kiosk) { + RecordRemoveCryptohomeResult( + RemoveCryptohomeResult::SUCCESS_IN_ARC_KIOSK_MIGRATION); + } else if (resume) { + RecordRemoveCryptohomeResult( + RemoveCryptohomeResult::SUCCESS_IN_RESUMED_MIGRATION); + } else { + RecordRemoveCryptohomeResult( + RemoveCryptohomeResult::SUCCESS_IN_NEW_MIGRATION); + } +} + +void RecordRemoveCryptohomeResultFailure(bool resume, bool arc_kiosk) { + if (arc_kiosk) { + RecordRemoveCryptohomeResult( + RemoveCryptohomeResult::FAILURE_IN_ARC_KIOSK_MIGRATION); + } else if (resume) { + RecordRemoveCryptohomeResult( + RemoveCryptohomeResult::FAILURE_IN_RESUMED_MIGRATION); + } else { + RecordRemoveCryptohomeResult( + RemoveCryptohomeResult::FAILURE_IN_NEW_MIGRATION); + } +} + +// Chooses the value for the MigrationUIFirstScreen UMA stat. Not used for ARC +// kiosk. +FirstScreen GetFirstScreenForMode(chromeos::EncryptionMigrationMode mode) { + switch (mode) { + case chromeos::EncryptionMigrationMode::ASK_USER: + return FirstScreen::FIRST_SCREEN_READY; + case chromeos::EncryptionMigrationMode::START_MIGRATION: + return FirstScreen::FIRST_SCREEN_START_AUTOMATICALLY; + case chromeos::EncryptionMigrationMode::START_MINIMAL_MIGRATION: + return FirstScreen::FIRST_SCREEN_START_AUTOMATICALLY_MINIMAL; + case chromeos::EncryptionMigrationMode::RESUME_MIGRATION: + return FirstScreen::FIRST_SCREEN_RESUME; + case chromeos::EncryptionMigrationMode::RESUME_MINIMAL_MIGRATION: + return FirstScreen::FIRST_SCREEN_RESUME_MINIMAL; + default: + NOTREACHED(); + } +} + } // namespace namespace chromeos { EncryptionMigrationScreenHandler::EncryptionMigrationScreenHandler() - : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) { + : BaseScreenHandler(kScreenId), + tick_clock_(base::MakeUnique<base::DefaultTickClock>()), + weak_ptr_factory_(this) { set_call_js_prefix(kJsScreenPath); + free_disk_space_fetcher_ = base::Bind(&base::SysInfo::AmountOfFreeDiskSpace, + base::FilePath(kCheckStoragePath)); } EncryptionMigrationScreenHandler::~EncryptionMigrationScreenHandler() { @@ -183,9 +289,9 @@ void EncryptionMigrationScreenHandler::SetUserContext( user_context_ = user_context; } -void EncryptionMigrationScreenHandler::SetShouldResume(bool should_resume) { - should_resume_ = should_resume; - CallJS("setIsResuming", should_resume_); +void EncryptionMigrationScreenHandler::SetMode(EncryptionMigrationMode mode) { + mode_ = mode; + CallJS("setIsResuming", IsStartImmediately()); } void EncryptionMigrationScreenHandler::SetContinueLoginCallback( @@ -193,7 +299,23 @@ void EncryptionMigrationScreenHandler::SetContinueLoginCallback( continue_login_callback_ = std::move(callback); } +void EncryptionMigrationScreenHandler::SetRestartLoginCallback( + RestartLoginCallback callback) { + restart_login_callback_ = std::move(callback); +} + void EncryptionMigrationScreenHandler::SetupInitialView() { + // Pass constant value(s) to the UI. + CallJS("setNecessaryBatteryPercent", arc::kMigrationMinimumBatteryPercent); + + // If old encryption is detected in ARC kiosk mode, skip all checks (user + // confirmation, battery level, and remaining space) and start migration + // immediately. + if (IsArcKiosk()) { + RecordFirstScreen(FirstScreen::FIRST_SCREEN_ARC_KIOSK); + StartMigration(); + return; + } DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); CheckAvailableStorage(); } @@ -242,6 +364,7 @@ void EncryptionMigrationScreenHandler::DeclareLocalizedValues( IDS_ENCRYPTION_MIGRATION_BUTTON_CONTINUE); builder->Add("migrationButtonSignIn", IDS_ENCRYPTION_MIGRATION_BUTTON_SIGNIN); builder->Add("migrationButtonReportAnIssue", IDS_REPORT_AN_ISSUE); + builder->Add("gaiaLoading", IDS_LOGIN_GAIA_LOADING_MESSAGE); } void EncryptionMigrationScreenHandler::Initialize() { @@ -254,6 +377,16 @@ void EncryptionMigrationScreenHandler::Initialize() { } } +void EncryptionMigrationScreenHandler::SetFreeDiskSpaceFetcherForTesting( + FreeDiskSpaceFetcher free_disk_space_fetcher) { + free_disk_space_fetcher_ = std::move(free_disk_space_fetcher); +} + +void EncryptionMigrationScreenHandler::SetTickClockForTesting( + std::unique_ptr<base::TickClock> tick_clock) { + tick_clock_ = std::move(tick_clock); +} + void EncryptionMigrationScreenHandler::RegisterMessages() { AddCallback(kJsApiStartMigration, &EncryptionMigrationScreenHandler::HandleStartMigration); @@ -274,8 +407,12 @@ void EncryptionMigrationScreenHandler::PowerChanged( if (!current_battery_percent_) { // If initial battery level is below the minimum, migration should start // automatically once the device is charged enough. - if (proto.battery_percent() < arc::kMigrationMinimumBatteryPercent) + if (proto.battery_percent() < arc::kMigrationMinimumBatteryPercent) { should_migrate_on_enough_battery_ = true; + // If migration was forced by policy, stop forcing it (we don't want the + // user to have to wait until the battery is charged). + MaybeStopForcingMigration(); + } } current_battery_percent_ = proto.battery_percent(); } else { @@ -348,12 +485,13 @@ void EncryptionMigrationScreenHandler::UpdateUIState(UIState state) { if (state == UIState::READY) DBusThreadManager::Get()->GetPowerManagerClient()->RequestStatusUpdate(); - // We should block power save and not shut down on lid close during migration. - if (state == UIState::MIGRATING) { - StartBlockingPowerSave(); + // We should request wake lock and not shut down on lid close during + // migration. + if (state == UIState::MIGRATING || state == UIState::MIGRATING_MINIMAL) { + GetWakeLock()->RequestWakeLock(); PowerPolicyController::Get()->SetEncryptionMigrationActive(true); } else { - StopBlockingPowerSave(); + GetWakeLock()->CancelWakeLock(); PowerPolicyController::Get()->SetEncryptionMigrationActive(false); } @@ -371,19 +509,20 @@ void EncryptionMigrationScreenHandler::UpdateUIState(UIState state) { void EncryptionMigrationScreenHandler::CheckAvailableStorage() { base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, - base::Bind(&base::SysInfo::AmountOfFreeDiskSpace, - base::FilePath(kCheckStoragePath)), + free_disk_space_fetcher_, base::Bind(&EncryptionMigrationScreenHandler::OnGetAvailableStorage, weak_ptr_factory_.GetWeakPtr())); } void EncryptionMigrationScreenHandler::OnGetAvailableStorage(int64_t size) { if (size >= arc::kMigrationMinimumAvailableStorage || IsTestingUI()) { - if (should_resume_) { - RecordFirstScreen(FirstScreen::FIRST_SCREEN_RESUME); - WaitBatteryAndMigrate(); + RecordFirstScreen(GetFirstScreenForMode(mode_)); + if (IsStartImmediately()) { + if (IsMinimalMigration()) + StartMigration(); + else + WaitBatteryAndMigrate(); } else { - RecordFirstScreen(FirstScreen::FIRST_SCREEN_READY); UpdateUIState(UIState::READY); } } else { @@ -396,10 +535,15 @@ void EncryptionMigrationScreenHandler::OnGetAvailableStorage(int64_t size) { } void EncryptionMigrationScreenHandler::WaitBatteryAndMigrate() { - if (current_battery_percent_ && - *current_battery_percent_ >= arc::kMigrationMinimumBatteryPercent) { - StartMigration(); - return; + if (current_battery_percent_) { + if (*current_battery_percent_ >= arc::kMigrationMinimumBatteryPercent) { + StartMigration(); + return; + } else { + // If migration was forced by policy, stop forcing it (we don't want the + // user to have to wait until the battery is charged). + MaybeStopForcingMigration(); + } } UpdateUIState(UIState::READY); @@ -408,17 +552,28 @@ void EncryptionMigrationScreenHandler::WaitBatteryAndMigrate() { } void EncryptionMigrationScreenHandler::StartMigration() { - UpdateUIState(UIState::MIGRATING); - initial_battery_percent_ = *current_battery_percent_; + UpdateUIState(GetMigratingUIState()); + if (current_battery_percent_) + initial_battery_percent_ = *current_battery_percent_; // Mount the existing eCryptfs vault to a temporary location for migration. - cryptohome::MountParameters mount(false); - mount.to_migrate_from_ecryptfs = true; - cryptohome::HomedirMethods::GetInstance()->MountEx( - cryptohome::Identification(user_context_.GetAccountId()), - cryptohome::Authorization(GetAuthKey()), mount, - base::Bind(&EncryptionMigrationScreenHandler::OnMountExistingVault, - weak_ptr_factory_.GetWeakPtr())); + cryptohome::MountRequest mount; + mount.set_to_migrate_from_ecryptfs(true); + if (IsArcKiosk()) { + mount.set_public_mount(true); + cryptohome::HomedirMethods::GetInstance()->MountEx( + cryptohome::Identification(user_context_.GetAccountId()), + cryptohome::Authorization(cryptohome::KeyDefinition()), mount, + base::Bind(&EncryptionMigrationScreenHandler::OnMountExistingVault, + weak_ptr_factory_.GetWeakPtr())); + + } else { + cryptohome::HomedirMethods::GetInstance()->MountEx( + cryptohome::Identification(user_context_.GetAccountId()), + cryptohome::Authorization(GetAuthKey()), mount, + base::Bind(&EncryptionMigrationScreenHandler::OnMountExistingVault, + weak_ptr_factory_.GetWeakPtr())); + } } void EncryptionMigrationScreenHandler::OnMountExistingVault( @@ -426,13 +581,17 @@ void EncryptionMigrationScreenHandler::OnMountExistingVault( cryptohome::MountError return_code, const std::string& mount_hash) { if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) { - RecordMigrationResult( - should_resume_ ? MigrationResult::MOUNT_FAILURE_IN_RESUMED_MIGRATION - : MigrationResult::MOUNT_FAILURE_IN_NEW_MIGRATION); + RecordMigrationResultMountFailure(IsResumingIncompleteMigration(), + IsArcKiosk()); UpdateUIState(UIState::MIGRATION_FAILED); return; } + // For minimal migration, start a timer which will measure how long migration + // took, so we can require a re sign-in if it took too long. + if (IsMinimalMigration()) + minimal_migration_start_ = tick_clock_->NowTicks(); + DBusThreadManager::Get() ->GetCryptohomeClient() ->SetDircryptoMigrationProgressHandler( @@ -440,27 +599,36 @@ void EncryptionMigrationScreenHandler::OnMountExistingVault( weak_ptr_factory_.GetWeakPtr())); cryptohome::HomedirMethods::GetInstance()->MigrateToDircrypto( cryptohome::Identification(user_context_.GetAccountId()), + IsMinimalMigration(), base::Bind(&EncryptionMigrationScreenHandler::OnMigrationRequested, weak_ptr_factory_.GetWeakPtr())); } -void EncryptionMigrationScreenHandler::StartBlockingPowerSave() { - if (!power_save_blocker_) { - power_save_blocker_.reset(new device::PowerSaveBlocker( - device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, - device::PowerSaveBlocker::kReasonOther, - "Encryption migration is in progress...", - content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::UI), - content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::FILE))); - } -} +device::mojom::WakeLock* EncryptionMigrationScreenHandler::GetWakeLock() { + // |wake_lock_| is lazy bound and reused, even after a connection error. + if (wake_lock_) + return wake_lock_.get(); -void EncryptionMigrationScreenHandler::StopBlockingPowerSave() { - if (power_save_blocker_.get()) { - power_save_blocker_.reset(); - } + device::mojom::WakeLockRequest request = mojo::MakeRequest(&wake_lock_); + + // Service manager connection might be not initialized in some testing + // contexts. + if (!content::ServiceManagerConnection::GetForProcess()) + return wake_lock_.get(); + + service_manager::Connector* connector = + content::ServiceManagerConnection::GetForProcess()->GetConnector(); + DCHECK(connector); + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + device::mojom::WakeLockProviderPtr wake_lock_provider; + connector->BindInterface(device::mojom::kServiceName, + mojo::MakeRequest(&wake_lock_provider)); + wake_lock_provider->GetWakeLockWithoutContext( + device::mojom::WakeLockType::PreventAppSuspension, + device::mojom::WakeLockReason::ReasonOther, + "Encryption migration is in progress...", std::move(request)); + return wake_lock_.get(); } void EncryptionMigrationScreenHandler::RemoveCryptohome() { @@ -480,7 +648,13 @@ void EncryptionMigrationScreenHandler::OnRemoveCryptohome( cryptohome::MountError return_code) { LOG_IF(ERROR, !success) << "Removing cryptohome failed. return code: " << return_code; - RecordRemoveCryptohomeResult(success, should_resume_); + if (success) + RecordRemoveCryptohomeResultSuccess(IsResumingIncompleteMigration(), + IsArcKiosk()); + else + RecordRemoveCryptohomeResultFailure(IsResumingIncompleteMigration(), + IsArcKiosk()); + UpdateUIState(UIState::MIGRATION_FAILED); } @@ -499,37 +673,58 @@ cryptohome::KeyDefinition EncryptionMigrationScreenHandler::GetAuthKey() { cryptohome::PRIV_DEFAULT); } +bool EncryptionMigrationScreenHandler::IsArcKiosk() const { + return user_context_.GetUserType() == user_manager::USER_TYPE_ARC_KIOSK_APP; +} + void EncryptionMigrationScreenHandler::OnMigrationProgress( cryptohome::DircryptoMigrationStatus status, uint64_t current, uint64_t total) { switch (status) { case cryptohome::DIRCRYPTO_MIGRATION_INITIALIZING: - UpdateUIState(UIState::MIGRATING); + UpdateUIState(GetMigratingUIState()); break; case cryptohome::DIRCRYPTO_MIGRATION_IN_PROGRESS: - UpdateUIState(UIState::MIGRATING); + UpdateUIState(GetMigratingUIState()); CallJS("setMigrationProgress", static_cast<double>(current) / total); break; case cryptohome::DIRCRYPTO_MIGRATION_SUCCESS: - RecordMigrationResult(should_resume_ - ? MigrationResult::SUCCESS_IN_RESUMED_MIGRATION - : MigrationResult::SUCCESS_IN_NEW_MIGRATION); + RecordMigrationResultSuccess(IsResumingIncompleteMigration(), + IsArcKiosk()); // If the battery level decreased during migration, record the consumed // battery level. - if (*current_battery_percent_ < initial_battery_percent_) { + if (current_battery_percent_ && + *current_battery_percent_ < initial_battery_percent_) { UMA_HISTOGRAM_PERCENTAGE( kUmaNameConsumedBatteryPercent, static_cast<int>(std::round(initial_battery_percent_ - *current_battery_percent_))); } - // Restart immediately after successful migration. - DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); + if (IsMinimalMigration() && !continue_login_callback_.is_null() && + !restart_login_callback_.is_null()) { + GetWakeLock()->CancelWakeLock(); + PowerPolicyController::Get()->SetEncryptionMigrationActive(false); + // If minimal migration was fast enough, continue with same sign-in + // data. Fast enough means that the elapsed time is under the defined + // threshold. + const base::TimeDelta elapsed_time = + tick_clock_->NowTicks() - minimal_migration_start_; + const bool require_password_reentry = + elapsed_time.InSeconds() > + kMinimalMigrationReenterPasswordThreshold; + if (require_password_reentry) + std::move(restart_login_callback_).Run(user_context_); + else + std::move(continue_login_callback_).Run(user_context_); + } else { + // Restart immediately after successful full migration. + DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); + } break; case cryptohome::DIRCRYPTO_MIGRATION_FAILED: - RecordMigrationResult( - should_resume_ ? MigrationResult::GENERAL_FAILURE_IN_RESUMED_MIGRATION - : MigrationResult::GENERAL_FAILURE_IN_NEW_MIGRATION); + RecordMigrationResultGeneralFailure(IsResumingIncompleteMigration(), + IsArcKiosk()); // Stop listening to the progress updates. DBusThreadManager::Get() ->GetCryptohomeClient() @@ -546,9 +741,8 @@ void EncryptionMigrationScreenHandler::OnMigrationProgress( void EncryptionMigrationScreenHandler::OnMigrationRequested(bool success) { if (!success) { LOG(ERROR) << "Requesting MigrateToDircrypto failed."; - RecordMigrationResult( - should_resume_ ? MigrationResult::REQUEST_FAILURE_IN_RESUMED_MIGRATION - : MigrationResult::REQUEST_FAILURE_IN_NEW_MIGRATION); + RecordMigrationResultRequestFailure(IsResumingIncompleteMigration(), + IsArcKiosk()); UpdateUIState(UIState::MIGRATION_FAILED); } } @@ -563,4 +757,33 @@ void EncryptionMigrationScreenHandler::OnDelayedRecordVisibleScreen( UMA_HISTOGRAM_ENUMERATION(kUmaNameVisibleScreen, ui_state, UIState::COUNT); } +bool EncryptionMigrationScreenHandler::IsResumingIncompleteMigration() const { + return mode_ == EncryptionMigrationMode::RESUME_MIGRATION; +} + +bool EncryptionMigrationScreenHandler::IsStartImmediately() const { + return mode_ == EncryptionMigrationMode::START_MIGRATION || + mode_ == EncryptionMigrationMode::START_MINIMAL_MIGRATION || + mode_ == EncryptionMigrationMode::RESUME_MIGRATION || + mode_ == EncryptionMigrationMode::RESUME_MINIMAL_MIGRATION; +} + +bool EncryptionMigrationScreenHandler::IsMinimalMigration() const { + return mode_ == EncryptionMigrationMode::START_MINIMAL_MIGRATION || + mode_ == EncryptionMigrationMode::RESUME_MINIMAL_MIGRATION; +} + +EncryptionMigrationScreenHandler::UIState +EncryptionMigrationScreenHandler::GetMigratingUIState() const { + return IsMinimalMigration() ? UIState::MIGRATING_MINIMAL : UIState::MIGRATING; +} + +void EncryptionMigrationScreenHandler::MaybeStopForcingMigration() { + // |mode_| will be START_MIGRATION if migration was forced by user policy. + // If an incomplete migration is being resumed, it would be RESUME_MIGRATION. + // We only want to disable auto-starting migration in the first case. + if (mode_ == EncryptionMigrationMode::START_MIGRATION) + CallJS("setIsResuming", false); +} + } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h index 5dba39d5b92..10371bab75c 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h @@ -7,18 +7,22 @@ #include <memory> +#include "base/callback_forward.h" #include "base/macros.h" #include "base/optional.h" +#include "chrome/browser/chromeos/login/screens/encryption_migration_mode.h" #include "chrome/browser/chromeos/login/screens/encryption_migration_screen_view.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/login/auth/user_context.h" +#include "services/device/public/interfaces/wake_lock.mojom.h" #include "third_party/cros_system_api/dbus/cryptohome/dbus-constants.h" -namespace device { -class PowerSaveBlocker; -} // namespace device +namespace base { +class TickClock; +class TimeTicks; +} // namespace base namespace chromeos { @@ -37,8 +41,9 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, void Hide() override; void SetDelegate(Delegate* delegate) override; void SetUserContext(const UserContext& user_context) override; - void SetShouldResume(bool should_resume) override; + void SetMode(EncryptionMigrationMode mode) override; void SetContinueLoginCallback(ContinueLoginCallback callback) override; + void SetRestartLoginCallback(RestartLoginCallback callback) override; void SetupInitialView() override; // BaseScreenHandler implementation: @@ -46,6 +51,19 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, ::login::LocalizedValuesBuilder* builder) override; void Initialize() override; + protected: + // Callback that can be used to check free disk space. + using FreeDiskSpaceFetcher = base::RepeatingCallback<int64_t()>; + + // Testing only: Sets the free disk space fetcher. + void SetFreeDiskSpaceFetcherForTesting( + FreeDiskSpaceFetcher free_disk_space_fetcher); + // Testing only: Sets the tick clock used to measure elapsed time during + // migration. + void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock); + + virtual device::mojom::WakeLock* GetWakeLock(); + private: // Enumeration for migration UI state. These values must be kept in sync with // EncryptionMigrationUIState in JS code, and match the numbering for @@ -57,6 +75,7 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, MIGRATING = 2, MIGRATION_FAILED = 3, NOT_ENOUGH_STORAGE = 4, + MIGRATING_MINIMAL = 5, COUNT }; @@ -83,8 +102,6 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, void OnMountExistingVault(bool success, cryptohome::MountError return_code, const std::string& mount_hash); - void StartBlockingPowerSave(); - void StopBlockingPowerSave(); // Removes cryptohome and shows the error screen after the removal finishes. void RemoveCryptohome(); void OnRemoveCryptohome(bool success, cryptohome::MountError return_code); @@ -92,6 +109,9 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, // Creates authorization key for MountEx method using |user_context_|. cryptohome::KeyDefinition GetAuthKey(); + // True if the session is in ARC kiosk mode. + bool IsArcKiosk() const; + // Handlers for cryptohome API callbacks. void OnMigrationProgress(cryptohome::DircryptoMigrationStatus status, uint64_t current, @@ -101,6 +121,23 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, // Records UMA about visible screen after delay. void OnDelayedRecordVisibleScreen(UIState state); + // True if |mode_| suggests that we are resuming an incomplete migration. + bool IsResumingIncompleteMigration() const; + + // True if |mode_| suggests that migration should start immediately. + bool IsStartImmediately() const; + + // True if |mode_| suggests that we are starting or resuming a minimal + // migration. + bool IsMinimalMigration() const; + + // Returns the UIState we should be in when migration is in progress. + // This will be different between regular and minimal migration. + UIState GetMigratingUIState() const; + + // Stop forcing migration if it was forced by policy. + void MaybeStopForcingMigration(); + Delegate* delegate_ = nullptr; bool show_on_init_ = false; @@ -114,8 +151,12 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, // The callback which is used to log in to the session from the migration UI. ContinueLoginCallback continue_login_callback_; - // True if the system should resume the previous incomplete migration. - bool should_resume_ = false; + // The callback which is used to require the user to re-enter their password. + RestartLoginCallback restart_login_callback_; + + // The migration mode (ask user / start migration automatically / resume + // incomplete migratoin). + EncryptionMigrationMode mode_ = EncryptionMigrationMode::ASK_USER; // The current battery level. base::Optional<double> current_battery_percent_; @@ -127,10 +168,18 @@ class EncryptionMigrationScreenHandler : public EncryptionMigrationScreenView, // The battery level at the timing that the migration starts. double initial_battery_percent_ = 0.0; - std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_; + // Point in time when minimal migration started, as reported by |tick_clock_|. + base::TimeTicks minimal_migration_start_; + + device::mojom::WakeLockPtr wake_lock_; std::unique_ptr<LoginFeedback> login_feedback_; + // Used to measure elapsed time during migration. + std::unique_ptr<base::TickClock> tick_clock_; + + FreeDiskSpaceFetcher free_disk_space_fetcher_; + base::WeakPtrFactory<EncryptionMigrationScreenHandler> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(EncryptionMigrationScreenHandler); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc b/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc new file mode 100644 index 00000000000..2f8a6026687 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc @@ -0,0 +1,357 @@ +// 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 <memory> +#include <utility> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" +#include "base/test/simple_test_tick_clock.h" +#include "chrome/browser/chromeos/arc/arc_migration_constants.h" +#include "chrome/browser/chromeos/login/screens/encryption_migration_mode.h" +#include "chrome/browser/chromeos/login/users/mock_user_manager.h" +#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" +#include "chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h" +#include "chromeos/cryptohome/homedir_methods.h" +#include "chromeos/cryptohome/mock_async_method_caller.h" +#include "chromeos/cryptohome/mock_homedir_methods.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_cryptohome_client.h" +#include "chromeos/dbus/fake_power_manager_client.h" +#include "chromeos/dbus/power_policy_controller.h" +#include "chromeos/login/auth/key.h" +#include "chromeos/login/auth/user_context.h" +#include "components/signin/core/account_id/account_id.h" +#include "components/user_manager/user_names.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::Invoke; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::WithArgs; +using ::testing::_; + +namespace chromeos { +namespace { + +// Fake WakeLock implementation, required by EncryptionMigrationScreenHandler. +class FakeWakeLock : public device::mojom::WakeLock { + public: + FakeWakeLock() {} + ~FakeWakeLock() override {} + + // Implement device::mojom::WakeLock: + void RequestWakeLock() override { has_wakelock_ = true; } + void CancelWakeLock() override { has_wakelock_ = false; } + void AddClient(device::mojom::WakeLockRequest request) override {} + void ChangeType(device::mojom::WakeLockType type, + ChangeTypeCallback callback) override { + NOTIMPLEMENTED(); + } + void HasWakeLockForTests(HasWakeLockForTestsCallback callback) override { + std::move(callback).Run(has_wakelock_); + } + + bool HasWakeLock() { return has_wakelock_; } + + private: + bool has_wakelock_ = false; +}; + +// Allows access to testing-only methods of EncryptionMigrationScreenHandler. +class TestEncryptionMigrationScreenHandler + : public EncryptionMigrationScreenHandler { + public: + TestEncryptionMigrationScreenHandler() { + SetFreeDiskSpaceFetcherForTesting(base::BindRepeating( + &TestEncryptionMigrationScreenHandler::FreeDiskSpaceFetcher, + base::Unretained(this))); + auto tick_clock = base::MakeUnique<base::SimpleTestTickClock>(); + testing_tick_clock_ = tick_clock.get(); + SetTickClockForTesting(std::move(tick_clock)); + } + + // Sets the testing WebUI. + void set_test_web_ui(content::TestWebUI* test_web_ui) { + set_web_ui(test_web_ui); + } + + // Sets the free disk space seen by EncryptionMigrationScreenHandler. + void set_free_disk_space(int64_t free_disk_space) { + free_disk_space_ = free_disk_space; + } + + // Returns the SimpleTestTickClock used to simulate time elapsed during + // migration. + base::SimpleTestTickClock* testing_tick_clock() { + return testing_tick_clock_; + } + + FakeWakeLock* fake_wake_lock() { return &fake_wake_lock_; } + + protected: + // Override GetWakeLock -- returns our own FakeWakeLock. + device::mojom::WakeLock* GetWakeLock() override { return &fake_wake_lock_; } + + private: + // Used as free disk space fetcher callback. + int64_t FreeDiskSpaceFetcher() { return free_disk_space_; } + + FakeWakeLock fake_wake_lock_; + + // Non-owned pointer. Tick clock used to simulate time elapsed during + // migration. This is actually owned by the base class. + base::SimpleTestTickClock* testing_tick_clock_; + + int64_t free_disk_space_; +}; + +class EncryptionMigrationScreenHandlerTest : public testing::Test { + public: + EncryptionMigrationScreenHandlerTest() = default; + ~EncryptionMigrationScreenHandlerTest() override = default; + + void SetUp() override { + // Set up a MockUserManager. + MockUserManager* mock_user_manager = new NiceMock<MockUserManager>(); + scoped_user_manager_enabler_ = + base::MakeUnique<ScopedUserManagerEnabler>(mock_user_manager); + + // This is used by EncryptionMigrationScreenHandler to mount the existing + // cryptohome. Ownership of mock_homedir_methods_ is transferred to + // HomedirMethods::InitializeForTesting. + mock_homedir_methods_ = new cryptohome::MockHomedirMethods; + cryptohome::HomedirMethods::InitializeForTesting(mock_homedir_methods_); + + // This is used by EncryptionMigrationScreenHandler to remove the existing + // cryptohome. Ownership of mock_async_method_caller_ is transferred to + // AsyncMethodCaller::InitializeForTesting. + mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller; + cryptohome::AsyncMethodCaller::InitializeForTesting( + mock_async_method_caller_); + + // Set up fake DBusThreadManager parts. + auto fake_cryptohome_client = base::MakeUnique<FakeCryptohomeClient>(); + fake_cryptohome_client_ = fake_cryptohome_client.get(); + DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( + std::move(fake_cryptohome_client)); + + DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient( + base::MakeUnique<FakePowerManagerClient>()); + + DBusThreadManager::Initialize(); + + PowerPolicyController::Initialize( + DBusThreadManager::Get()->GetPowerManagerClient()); + + // Build dummy user context. + user_context_.SetAccountId(account_id_); + user_context_.SetKey( + Key(Key::KeyType::KEY_TYPE_SALTED_SHA256, "salt", "secret")); + + encryption_migration_screen_handler_ = + base::MakeUnique<TestEncryptionMigrationScreenHandler>(); + encryption_migration_screen_handler_->set_test_web_ui(&test_web_ui_); + encryption_migration_screen_handler_->SetContinueLoginCallback( + base::BindOnce(&EncryptionMigrationScreenHandlerTest::OnContinueLogin, + base::Unretained(this))); + encryption_migration_screen_handler_->SetRestartLoginCallback( + base::BindOnce(&EncryptionMigrationScreenHandlerTest::OnRestartLogin, + base::Unretained(this))); + encryption_migration_screen_handler_->set_free_disk_space( + arc::kMigrationMinimumAvailableStorage); + encryption_migration_screen_handler_->SetUserContext(user_context_); + } + + void TearDown() override { + encryption_migration_screen_handler_.reset(); + + PowerPolicyController::Shutdown(); + DBusThreadManager::Shutdown(); + cryptohome::AsyncMethodCaller::Shutdown(); + cryptohome::HomedirMethods::Shutdown(); + } + + // Sets up expectation that the existing user home will be mounted for + // migration using |mock_homedir_methods_|. + void ExpectMountExistingVault(cryptohome::MountError mount_error) { + EXPECT_CALL( + *mock_homedir_methods_, + MountEx(cryptohome::Identification( + user_context_.GetAccountId()) /* 0: id */, + _ /* 1: auth */, _ /* 2: request */, _ /* 3: callback */)) + .WillOnce(WithArgs<2, 3>(Invoke( + [mount_error](const cryptohome::MountRequest& mount_request, + cryptohome::HomedirMethods::MountCallback callback) { + // Expect that the migration flag is set. + EXPECT_TRUE(mount_request.to_migrate_from_ecryptfs()); + callback.Run(true /* success */, mount_error, + std::string() /* mount_hash */); + }))); + } + + // Sets up expectation that migration will be started on + // |mock_homedir_methods_|. If |expect_minimal_migration| is true, verifies + // that minimal migration has been requested. + void ExpectStartMigration(bool expect_minimal_migration) { + EXPECT_CALL( + *mock_homedir_methods_, + MigrateToDircrypto(cryptohome::Identification( + user_context_.GetAccountId()) /* 0: id */, + _ /* 1: minimal_migration*/, _ /* 2: callback */)) + .WillOnce(WithArgs<1, 2>( + Invoke([expect_minimal_migration]( + bool minimal_migration, + const cryptohome::HomedirMethods::DBusResultCallback& + callback) { + EXPECT_EQ(expect_minimal_migration, minimal_migration); + // Call the callback immediately - actual result is sent later + // using DircryptoMigrationProgressHandler. + callback.Run(true /* success */); + }))); + } + + protected: + // Must be the first member. + base::test::ScopedTaskEnvironment scoped_task_environment_; + + std::unique_ptr<ScopedUserManagerEnabler> scoped_user_manager_enabler_; + cryptohome::MockHomedirMethods* mock_homedir_methods_ = nullptr; + FakeCryptohomeClient* fake_cryptohome_client_ = nullptr; + cryptohome::MockAsyncMethodCaller* mock_async_method_caller_ = nullptr; + std::unique_ptr<TestEncryptionMigrationScreenHandler> + encryption_migration_screen_handler_; + content::TestWebUI test_web_ui_; + + // Will be set to true in ContinueLogin. + bool continue_login_callback_called_ = false; + // Will be set to true in RestartLogin. + bool restart_login_callback_called_ = false; + + const AccountId account_id_ = + AccountId::FromUserEmail(user_manager::kStubUserEmail); + UserContext user_context_; + + private: + // This will be called by EncryptionMigrationScreenHandler upon finished + // minimal migration when sign-in should continue. + void OnContinueLogin(const UserContext& user_context) { + EXPECT_FALSE(continue_login_callback_called_) + << "ContinueLogin/RestartLogin may only be called once."; + EXPECT_FALSE(restart_login_callback_called_) + << "ContinueLogin/RestartLogin may only be called once."; + + continue_login_callback_called_ = true; + } + + // This will be called by EncryptionMigrationScreenHandler upon finished + // minimal migration when the user should re-enter their password. + void OnRestartLogin(const UserContext& user_context) { + EXPECT_FALSE(continue_login_callback_called_) + << "ContinueLogin/RestartLogin may only be called once."; + EXPECT_FALSE(restart_login_callback_called_) + << "ContinueLogin/RestartLogin may only be called once."; + + restart_login_callback_called_ = true; + } +}; + +} // namespace + +// Tests handling of a minimal migration run that finishes immediately. +TEST_F(EncryptionMigrationScreenHandlerTest, MinimalMigration) { + ExpectMountExistingVault(cryptohome::MountError::MOUNT_ERROR_NONE); + ExpectStartMigration(true /* minimal_migration */); + encryption_migration_screen_handler_->SetMode( + EncryptionMigrationMode::START_MINIMAL_MIGRATION); + encryption_migration_screen_handler_->SetupInitialView(); + + scoped_task_environment_.RunUntilIdle(); + + Mock::VerifyAndClearExpectations(mock_homedir_methods_); + + EXPECT_TRUE( + encryption_migration_screen_handler_->fake_wake_lock()->HasWakeLock()); + fake_cryptohome_client_->dircrypto_migration_progress_handler().Run( + cryptohome::DircryptoMigrationStatus::DIRCRYPTO_MIGRATION_SUCCESS, + 0 /* current */, 0 /* total */); + + EXPECT_TRUE(continue_login_callback_called_); + EXPECT_FALSE( + encryption_migration_screen_handler_->fake_wake_lock()->HasWakeLock()); +} + +// Tests handling of a resumed minimal migration run. This should behave the +// same way that a freshly started minimal migration does (only UMA stats are +// different, but we don't test that at the moment). +TEST_F(EncryptionMigrationScreenHandlerTest, ResumeMinimalMigration) { + ExpectMountExistingVault(cryptohome::MountError::MOUNT_ERROR_NONE); + ExpectStartMigration(true /* minimal_migration */); + encryption_migration_screen_handler_->SetMode( + EncryptionMigrationMode::RESUME_MINIMAL_MIGRATION); + encryption_migration_screen_handler_->SetupInitialView(); + + scoped_task_environment_.RunUntilIdle(); + + Mock::VerifyAndClearExpectations(mock_homedir_methods_); + + fake_cryptohome_client_->dircrypto_migration_progress_handler().Run( + cryptohome::DircryptoMigrationStatus::DIRCRYPTO_MIGRATION_SUCCESS, + 0 /* current */, 0 /* total */); + + EXPECT_TRUE(continue_login_callback_called_); +} + +// Tests handling of a minimal migration run that takes a long time to finish. +// We expect that EncryptionMigrationScreenHandler will require the user to +// re-enter their password. +TEST_F(EncryptionMigrationScreenHandlerTest, MinimalMigrationSlow) { + ExpectMountExistingVault(cryptohome::MountError::MOUNT_ERROR_NONE); + ExpectStartMigration(true /* minimal_migration */); + encryption_migration_screen_handler_->SetMode( + EncryptionMigrationMode::START_MINIMAL_MIGRATION); + encryption_migration_screen_handler_->SetupInitialView(); + + scoped_task_environment_.RunUntilIdle(); + + Mock::VerifyAndClearExpectations(mock_homedir_methods_); + + encryption_migration_screen_handler_->testing_tick_clock()->Advance( + base::TimeDelta::FromMinutes(1)); + fake_cryptohome_client_->dircrypto_migration_progress_handler().Run( + cryptohome::DircryptoMigrationStatus::DIRCRYPTO_MIGRATION_SUCCESS, + 0 /* current */, 0 /* total */); + + EXPECT_TRUE(restart_login_callback_called_); +} + +// Tests handling of a minimal migration run that fails. +TEST_F(EncryptionMigrationScreenHandlerTest, MinimalMigrationFails) { + ExpectMountExistingVault(cryptohome::MountError::MOUNT_ERROR_NONE); + ExpectStartMigration(true /* minimal_migration */); + encryption_migration_screen_handler_->SetMode( + EncryptionMigrationMode::START_MINIMAL_MIGRATION); + encryption_migration_screen_handler_->SetupInitialView(); + + scoped_task_environment_.RunUntilIdle(); + + Mock::VerifyAndClearExpectations(mock_homedir_methods_); + + EXPECT_CALL( + *mock_async_method_caller_, + AsyncRemove(cryptohome::Identification(user_context_.GetAccountId()), + _ /* callback */)); + encryption_migration_screen_handler_->testing_tick_clock()->Advance( + base::TimeDelta::FromMinutes(1)); + fake_cryptohome_client_->dircrypto_migration_progress_handler().Run( + cryptohome::DircryptoMigrationStatus::DIRCRYPTO_MIGRATION_FAILED, + 0 /* current */, 0 /* total */); + + Mock::VerifyAndClearExpectations(mock_async_method_caller_); +} + +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc index 19e4871d0a4..0499e1d1c0b 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc @@ -44,6 +44,7 @@ const char kJsScreenPath[] = "login.OAuthEnrollmentScreen"; // Enrollment step names. const char kEnrollmentStepSignin[] = "signin"; const char kEnrollmentStepAdJoin[] = "ad-join"; +const char kEnrollmentStepPickLicense[] = "license"; const char kEnrollmentStepSuccess[] = "success"; const char kEnrollmentStepWorking[] = "working"; @@ -99,12 +100,11 @@ bool IsProxyError(NetworkStateInformer::State state, reason == NetworkError::ERROR_REASON_PROXY_CONNECTION_FAILED; } - -// Returns the enterprise domain after enrollment, or an empty string. -std::string GetEnterpriseDomain() { +// Returns the enterprise display domain after enrollment, or an empty string. +std::string GetEnterpriseDisplayDomain() { policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->GetEnterpriseDomain(); + return connector->GetEnterpriseDisplayDomain(); } } // namespace @@ -149,6 +149,8 @@ void EnrollmentScreenHandler::RegisterMessages() { &EnrollmentScreenHandler::HandleDeviceAttributesProvided); AddCallback("oauthEnrollOnLearnMore", &EnrollmentScreenHandler::HandleOnLearnMore); + AddCallback("onLicenseTypeSelected", + &EnrollmentScreenHandler::HandleLicenseTypeSelected); } // EnrollmentScreenHandler @@ -177,6 +179,12 @@ void EnrollmentScreenHandler::ShowSigninScreen() { ShowStep(kEnrollmentStepSignin); } +void EnrollmentScreenHandler::ShowLicenseTypeSelectionScreen( + const base::DictionaryValue& license_types) { + CallJS("setAvailableLicenseTypes", license_types); + ShowStep(kEnrollmentStepPickLicense); +} + void EnrollmentScreenHandler::ShowAdJoin() { observe_network_failure_ = false; if (!authpolicy_login_helper_) @@ -246,10 +254,12 @@ void EnrollmentScreenHandler::ShowEnrollmentStatus( policy::EnrollmentStatus status) { switch (status.status()) { case policy::EnrollmentStatus::SUCCESS: - if (config_.is_mode_attestation()) - ShowAttestationBasedEnrollmentSuccessScreen(GetEnterpriseDomain()); - else + if (config_.is_mode_attestation()) { + ShowAttestationBasedEnrollmentSuccessScreen( + GetEnterpriseDisplayDomain()); + } else { ShowStep(kEnrollmentStepSuccess); + } return; case policy::EnrollmentStatus::NO_STATE_KEYS: ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_NO_STATE_KEYS, false); @@ -358,6 +368,9 @@ void EnrollmentScreenHandler::ShowEnrollmentStatus( ShowError(IDS_ENTERPRISE_ENROLLMENT_ERROR_SAVE_DEVICE_CONFIGURATION, false); return; + case policy::EnrollmentStatus::LICENSE_REQUEST_FAILED: + ShowError(IDS_ENTERPRISE_ENROLLMENT_ERROR_LICENSE_REQUEST, false); + return; } NOTREACHED(); } @@ -398,12 +411,24 @@ void EnrollmentScreenHandler::DeclareLocalizedValues( IDS_AD_MACHINE_NAME_INPUT_LABEL); builder->Add("oauthEnrollAdDomainJoinWelcomeMessage", IDS_AD_DOMAIN_JOIN_WELCOME_MESSAGE); - builder->Add("adLoginUsername", IDS_AD_LOGIN_USER); + builder->Add("adEnrollmentLoginUsername", IDS_AD_ENROLLMENT_LOGIN_USER); builder->Add("adLoginInvalidUsername", IDS_AD_INVALID_USERNAME); builder->Add("adLoginPassword", IDS_AD_LOGIN_PASSWORD); builder->Add("adLoginInvalidPassword", IDS_AD_INVALID_PASSWORD); builder->Add("adJoinErrorMachineNameInvalid", IDS_AD_MACHINENAME_INVALID); builder->Add("adJoinErrorMachineNameTooLong", IDS_AD_MACHINENAME_TOO_LONG); + builder->Add("licenseSelectionCardTitle", + IDS_ENTERPRISE_ENROLLMENT_LICENSE_SELECTION); + builder->Add("licenseSelectionCardExplanation", + IDS_ENTERPRISE_ENROLLMENT_LICENSE_SELECTION_EXPLANATION); + builder->Add("perpetualLicenseTypeTitle", + IDS_ENTERPRISE_ENROLLMENT_PERPETUAL_LICENSE_TYPE); + builder->Add("annualLicenseTypeTitle", + IDS_ENTERPRISE_ENROLLMENT_ANNUAL_LICENSE_TYPE); + builder->Add("kioskLicenseTypeTitle", + IDS_ENTERPRISE_ENROLLMENT_KIOSK_LICENSE_TYPE); + builder->Add("licenseCountTemplate", + IDS_ENTERPRISE_ENROLLMENT_LICENSES_REMAINING_TEMPLATE); } bool EnrollmentScreenHandler::IsOnEnrollmentScreen() const { @@ -557,19 +582,9 @@ void EnrollmentScreenHandler::HandleAdDomainJoin( ShowEnrollmentSpinnerScreen(); controller_->OnAdJoined(gaia::ExtractDomainName(user_name)); return; - case authpolicy::ERROR_UNKNOWN: - case authpolicy::ERROR_DBUS_FAILURE: - case authpolicy::ERROR_NET_FAILED: - case authpolicy::ERROR_SMBCLIENT_FAILED: - case authpolicy::ERROR_PARSE_FAILED: - case authpolicy::ERROR_PARSE_PREG_FAILED: - case authpolicy::ERROR_BAD_GPOS: - case authpolicy::ERROR_LOCAL_IO: - case authpolicy::ERROR_STORE_POLICY_FAILED: - ShowError(IDS_AD_DOMAIN_JOIN_UNKNOWN_ERROR, true); - return; case authpolicy::ERROR_NETWORK_PROBLEM: - ShowError(IDS_ENTERPRISE_ENROLLMENT_AUTH_NETWORK_ERROR, true); + // Could be a network problem, but could also be a misspelled domain name. + ShowError(IDS_AD_AUTH_NETWORK_ERROR, true); return; case authpolicy::ERROR_PARSE_UPN_FAILED: case authpolicy::ERROR_BAD_USER_NAME: @@ -589,21 +604,18 @@ void EnrollmentScreenHandler::HandleAdDomainJoin( CallJS("invalidateAd", machine_name, user_name, static_cast<int>(ActiveDirectoryErrorState::MACHINE_NAME_INVALID)); return; + case authpolicy::ERROR_PASSWORD_EXPIRED: + ShowError(IDS_AD_PASSWORD_EXPIRED, true); + return; case authpolicy::ERROR_JOIN_ACCESS_DENIED: ShowError(IDS_AD_USER_DENIED_TO_JOIN_MACHINE, true); return; case authpolicy::ERROR_USER_HIT_JOIN_QUOTA: ShowError(IDS_AD_USER_HIT_JOIN_QUOTA, true); return; - case authpolicy::ERROR_PASSWORD_EXPIRED: - case authpolicy::ERROR_CANNOT_RESOLVE_KDC: - case authpolicy::ERROR_KINIT_FAILED: - case authpolicy::ERROR_NOT_JOINED: - case authpolicy::ERROR_NOT_LOGGED_IN: default: LOG(WARNING) << "Unhandled error code: " << code; - CallJS("invalidateAd", machine_name, user_name, - static_cast<int>(ActiveDirectoryErrorState::NONE)); + ShowError(IDS_AD_DOMAIN_JOIN_UNKNOWN_ERROR, true); return; } } @@ -632,6 +644,11 @@ void EnrollmentScreenHandler::HandleOnLearnMore() { help_app_->ShowHelpTopic(HelpAppLauncher::HELP_DEVICE_ATTRIBUTES); } +void EnrollmentScreenHandler::HandleLicenseTypeSelected( + const std::string& licenseType) { + controller_->OnLicenseTypeSelected(licenseType); +} + void EnrollmentScreenHandler::ShowStep(const char* step) { CallJS("showStep", std::string(step)); } diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h index c263fa28c48..a13f4aea87f 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h @@ -15,8 +15,8 @@ #include "chrome/browser/chromeos/policy/enrollment_config.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h" +#include "chromeos/dbus/auth_policy_client.h" #include "net/base/net_errors.h" -#include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { @@ -55,6 +55,8 @@ class EnrollmentScreenHandler void Show() override; void Hide() override; void ShowSigninScreen() override; + void ShowLicenseTypeSelectionScreen( + const base::DictionaryValue& license_types) override; void ShowAdJoin() override; void ShowAttributePromptScreen(const std::string& asset_id, const std::string& location) override; @@ -88,6 +90,7 @@ class EnrollmentScreenHandler void HandleDeviceAttributesProvided(const std::string& asset_id, const std::string& location); void HandleOnLearnMore(); + void HandleLicenseTypeSelected(const std::string& licenseType); void UpdateStateInternal(NetworkError::ErrorReason reason, bool force_update); void SetupAndShowOfflineMessage(NetworkStateInformer::State state, diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc index f8dfee03f22..a13d7028803 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc @@ -133,7 +133,7 @@ void EulaScreenHandler::DeclareLocalizedValues( builder->Add("eulaTpmDescPowerwash", IDS_EULA_SECURE_MODULE_KEY_DESCRIPTION_POWERWASH); builder->Add("eulaTpmBusy", IDS_EULA_SECURE_MODULE_BUSY); - ::login::GetSecureModuleUsed(base::Bind( + ::login::GetSecureModuleUsed(base::BindOnce( &EulaScreenHandler::UpdateLocalizedValues, weak_factory_.GetWeakPtr())); builder->Add("eulaSystemInstallationSettingsOkButton", IDS_OK); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index ed43fa46bf9..e7b59027eb4 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc @@ -7,6 +7,7 @@ #include "ash/system/devicetype_utils.h" #include "base/bind.h" #include "base/callback.h" +#include "base/feature_list.h" #include "base/guid.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -16,8 +17,8 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_shutdown.h" -#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/language_preferences.h" +#include "chrome/browser/chromeos/login/lock_screen_utils.h" #include "chrome/browser/chromeos/login/screens/network_error.h" #include "chrome/browser/chromeos/login/ui/user_adding_screen.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" @@ -31,6 +32,7 @@ #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/common/channel_info.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "chromeos/chromeos_switches.h" @@ -50,6 +52,7 @@ #include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_urls.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/base/ime/chromeos/input_method_util.h" using content::BrowserThread; namespace em = enterprise_management; @@ -114,10 +117,16 @@ GaiaScreenMode GetGaiaScreenMode(const std::string& email, bool use_offline) { return GAIA_SCREEN_MODE_DEFAULT; } -std::string GetEnterpriseDomain() { +std::string GetEnterpriseDisplayDomain() { policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->GetEnterpriseDomain(); + return connector->GetEnterpriseDisplayDomain(); +} + +std::string GetEnterpriseEnrollmentDomain() { + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + return connector->GetEnterpriseEnrollmentDomain(); } std::string GetRealm() { @@ -161,6 +170,7 @@ void UpdateAuthParams(base::DictionaryValue* params, // 4. Supervised users are allowed by owner. ChromeUserManager* user_manager = ChromeUserManager::Get(); bool supervised_users_can_create = + base::FeatureList::IsEnabled(features::kSupervisedUserCreation) && user_manager->AreSupervisedUsersAllowed() && allow_new_user && !user_manager->GetUsersAllowedForSupervisedUsersCreation().empty(); params->SetBoolean("supervisedUsersCanCreate", supervised_users_can_create); @@ -241,6 +251,12 @@ GaiaScreenHandler::~GaiaScreenHandler() { } void GaiaScreenHandler::MaybePreloadAuthExtension() { + // We shall not have network portal detector initialized, which unnecessarily + // polls captive portal checking URL if we don't need to load gaia. See + // go/bad-portal for more context. + if (!signin_screen_handler_->ShouldLoadGaia()) + return; + VLOG(1) << "MaybePreloadAuthExtension"; if (!network_portal_detector_) { @@ -254,8 +270,7 @@ void GaiaScreenHandler::MaybePreloadAuthExtension() { // If cookies clearing was initiated or |dns_clear_task_running_| then auth // extension showing has already been initiated and preloading is pointless. - if (signin_screen_handler_->ShouldLoadGaia() && !gaia_silent_load_ && - !cookies_cleared_ && !dns_clear_task_running_ && + if (!gaia_silent_load_ && !cookies_cleared_ && !dns_clear_task_running_ && network_state_informer_->state() == NetworkStateInformer::ONLINE) { gaia_silent_load_ = true; gaia_silent_load_network_ = network_state_informer_->network_path(); @@ -306,9 +321,22 @@ void GaiaScreenHandler::LoadGaiaWithVersion( params.SetString("realm", realm); } - std::string enterprise_domain(GetEnterpriseDomain()); - if (!enterprise_domain.empty()) - params.SetString("enterpriseDomain", enterprise_domain); + const std::string enterprise_display_domain(GetEnterpriseDisplayDomain()); + const std::string enterprise_enrollment_domain( + GetEnterpriseEnrollmentDomain()); + if (!enterprise_display_domain.empty()) + params.SetString("enterpriseDisplayDomain", enterprise_display_domain); + if (!enterprise_enrollment_domain.empty()) { + params.SetString("enterpriseEnrollmentDomain", + enterprise_enrollment_domain); + } + params.SetBoolean("enterpriseManagedDevice", + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->IsEnterpriseManaged()); + params.SetBoolean( + "hasDeviceOwner", + user_manager::UserManager::Get()->GetOwnerAccountId().is_valid()); params.SetString("chromeType", GetChromeType()); params.SetString("clientId", @@ -343,6 +371,17 @@ void GaiaScreenHandler::LoadGaiaWithVersion( params.SetString("gaiaPath", eafe_path); } + // Easy bootstrap is not v2-compatible + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kCrosGaiaApiV1) || + use_easy_bootstrap_) { + params.SetString("chromeOSApiVersion", "1"); + } else { + // This enables GLIF MM UI for the online Gaia screen by default. + // (see https://crbug.com/709244 ). + params.SetString("chromeOSApiVersion", "2"); + } + frame_state_ = FRAME_STATE_LOADING; CallJS("loadAuthExtension", params); } @@ -418,7 +457,7 @@ void GaiaScreenHandler::DeclareLocalizedValues( IDS_LOGIN_SAML_INTERSTITIAL_NEXT_BUTTON_TEXT); builder->Add("adAuthWelcomeMessage", IDS_AD_DOMAIN_AUTH_WELCOME_MESSAGE); - builder->Add("adLoginUser", IDS_AD_LOGIN_USER); + builder->Add("adAuthLoginUsername", IDS_AD_AUTH_LOGIN_USER); builder->Add("adLoginPassword", IDS_AD_LOGIN_PASSWORD); } @@ -613,8 +652,8 @@ void GaiaScreenHandler::HandleCompleteAdPasswordChange( authpolicy_login_helper_->AuthenticateUser( username, std::string() /* object_guid */, old_password + "\n" + new_password + "\n" + new_password, - base::Bind(&GaiaScreenHandler::DoAdAuth, weak_factory_.GetWeakPtr(), - username, Key(new_password))); + base::BindOnce(&GaiaScreenHandler::DoAdAuth, weak_factory_.GetWeakPtr(), + username, Key(new_password))); } void GaiaScreenHandler::HandleCancelActiveDirectoryAuth() { @@ -746,10 +785,10 @@ void GaiaScreenHandler::StartClearingDnsCache() { dns_cleared_ = false; BrowserThread::PostTaskAndReply( - BrowserThread::IO, - FROM_HERE, - base::Bind(&ClearDnsCache, g_browser_process->io_thread()), - base::Bind(&GaiaScreenHandler::OnDnsCleared, weak_factory_.GetWeakPtr())); + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ClearDnsCache, g_browser_process->io_thread()), + base::BindOnce(&GaiaScreenHandler::OnDnsCleared, + weak_factory_.GetWeakPtr())); dns_clear_task_running_ = true; } @@ -779,7 +818,7 @@ void GaiaScreenHandler::OnCookiesCleared( } void GaiaScreenHandler::ShowSigninScreenForTest(const std::string& username, - const std::string& password) { + const std::string& password) { VLOG(2) << "ShowSigninScreenForTest for user " << username << ", frame_state=" << frame_state(); @@ -874,8 +913,8 @@ void GaiaScreenHandler::ShowGaiaScreenIfReady() { // Set Least Recently Used input method for the user. if (!populated_email_.empty()) { - SigninScreenHandler::SetUserInputMethod(populated_email_, - gaia_ime_state.get()); + lock_screen_utils::SetUserInputMethod(populated_email_, + gaia_ime_state.get()); } else { std::vector<std::string> input_methods; if (gaia_ime_state->GetAllowedInputMethods().empty()) { @@ -884,7 +923,7 @@ void GaiaScreenHandler::ShowGaiaScreenIfReady() { } else { input_methods = gaia_ime_state->GetAllowedInputMethods(); } - const std::string owner_im = SigninScreenHandler::GetUserLastInputMethod( + const std::string owner_im = lock_screen_utils::GetUserLastInputMethod( user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail()); const std::string system_im = g_browser_process->local_state()->GetString( language_prefs::kPreferredKeyboardLayout); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h index 15a6b1072fd..79f9fba2e76 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h @@ -14,9 +14,9 @@ #include "chrome/browser/chromeos/login/screens/gaia_view.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h" +#include "chromeos/dbus/auth_policy_client.h" #include "chromeos/network/portal_detector/network_portal_detector.h" #include "net/base/net_errors.h" -#include "third_party/cros_system_api/dbus/service_constants.h" class AccountId; diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util.cc b/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util.cc index 3b961134ff5..9156658066e 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util.cc @@ -30,7 +30,6 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/customization/customization_document.h" -#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/grit/generated_resources.h" @@ -38,6 +37,7 @@ #include "ui/base/ime/chromeos/component_extension_ime_manager.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/l10n/l10n_util.h" namespace chromeos { @@ -381,8 +381,8 @@ void ResolveLanguageListInThreadPool( chromeos::GetUILanguageList(nullptr, selected_code)); task_runner->PostTask( - FROM_HERE, base::Bind(resolved_callback, base::Passed(&language_list), - list_locale, selected_language)); + FROM_HERE, base::BindOnce(resolved_callback, base::Passed(&language_list), + list_locale, selected_language)); } void AdjustUILanguageList(const std::string& selected, diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util_unittest.cc b/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util_unittest.cc index 13aa6463824..d4c6b8a67da 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util_unittest.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/l10n_util_unittest.cc @@ -8,14 +8,11 @@ #include <utility> -#include "base/at_exit.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/memory/singleton.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" #include "base/values.h" #include "chrome/browser/chromeos/customization/customization_document.h" #include "chrome/browser/chromeos/input_method/input_method_configuration.h" @@ -28,28 +25,6 @@ namespace chromeos { namespace { -class MachineStatisticsInitializer { - public: - MachineStatisticsInitializer(); - - static MachineStatisticsInitializer* GetInstance(); - - private: - DISALLOW_COPY_AND_ASSIGN(MachineStatisticsInitializer); -}; - -MachineStatisticsInitializer::MachineStatisticsInitializer() { - base::MessageLoop loop; - chromeos::system::StatisticsProvider::GetInstance() - ->StartLoadingMachineStatistics(loop.task_runner(), false); - base::RunLoop().RunUntilIdle(); -} - -// static -MachineStatisticsInitializer* MachineStatisticsInitializer::GetInstance() { - return base::Singleton<MachineStatisticsInitializer>::get(); -} - void VerifyOnlyUILanguages(const base::ListValue& list) { for (size_t i = 0; i < list.GetSize(); ++i) { const base::DictionaryValue* dict; @@ -80,34 +55,27 @@ class L10nUtilTest : public testing::Test { L10nUtilTest(); ~L10nUtilTest() override; - // testing::Test: - void SetUp() override; - void TearDown() override; - void SetInputMethods1(); void SetInputMethods2(); private: - base::ShadowingAtExitManager at_exit_manager_; + base::test::ScopedTaskEnvironment scoped_task_environment_; MockInputMethodManagerWithInputMethods* input_manager_; }; L10nUtilTest::L10nUtilTest() : input_manager_(new MockInputMethodManagerWithInputMethods) { -} - -L10nUtilTest::~L10nUtilTest() { -} - -void L10nUtilTest::SetUp() { chromeos::input_method::InitializeForTesting(input_manager_); input_manager_->SetComponentExtensionIMEManager( - base::WrapUnique(new ComponentExtensionIMEManager)); - MachineStatisticsInitializer::GetInstance(); // Ignore result. + base::MakeUnique<ComponentExtensionIMEManager>()); + + chromeos::system::StatisticsProvider::GetInstance() + ->StartLoadingMachineStatistics(false); + base::RunLoop().RunUntilIdle(); } -void L10nUtilTest::TearDown() { +L10nUtilTest::~L10nUtilTest() { chromeos::input_method::Shutdown(); } diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc index fdfbf203060..faeb18f7b04 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc @@ -79,8 +79,7 @@ void NetworkDropdownHandler::HandleLaunchProxySettingsDialog() { } void NetworkDropdownHandler::HandleLaunchAddWiFiNetworkDialog() { - gfx::NativeWindow native_window = GetNativeWindow(); - NetworkConfigView::ShowForType(shill::kTypeWifi, native_window); + NetworkConfigView::ShowForType(shill::kTypeWifi); } void NetworkDropdownHandler::HandleLaunchAddMobileNetworkDialog() { diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc index a94c49633eb..a4aa6db07d0 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc @@ -28,6 +28,7 @@ #include "chrome/browser/chromeos/system/timezone_util.h" #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" +#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "chromeos/chromeos_switches.h" @@ -190,6 +191,7 @@ void NetworkScreenHandler::DeclareLocalizedValues( builder->Add("timezoneDropdownTitle", IDS_TIMEZONE_DROPDOWN_TITLE); builder->Add("timezoneButtonText", IDS_TIMEZONE_BUTTON_TEXT); + network_element::AddLocalizedValuesToBuilder(builder); } void NetworkScreenHandler::GetAdditionalParameters( diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc index 5a5c82409e6..7118b9f5ec4 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc @@ -48,9 +48,10 @@ void OobeDisplayChooser::TryToPlaceUiOnTouchDisplay() { display::Screen::GetScreen()->GetPrimaryDisplay(); if (primary_display.is_valid() && !TouchSupportAvailable(primary_display)) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&OobeDisplayChooser::MoveToTouchDisplay, - weak_ptr_factory_.GetWeakPtr())); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&OobeDisplayChooser::MoveToTouchDisplay, + weak_ptr_factory_.GetWeakPtr())); } } diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc index 528fd1c27a6..4291ab0269f 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc @@ -25,9 +25,9 @@ namespace chromeos { namespace { -class OobeDisplayChooserTest : public ash::test::AshTestBase { +class OobeDisplayChooserTest : public ash::AshTestBase { public: - OobeDisplayChooserTest() : ash::test::AshTestBase() {} + OobeDisplayChooserTest() : ash::AshTestBase() {} int64_t GetPrimaryDisplay() { return display::Screen::GetScreen()->GetPrimaryDisplay().id(); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index e11aa39063e..6075be4c1f6 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc @@ -8,7 +8,6 @@ #include <memory> -#include "ash/wm/screen_dimmer.h" #include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" @@ -59,9 +58,10 @@ #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h" -#include "chrome/browser/ui/webui/options/chromeos/user_image_source.h" +#include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "chrome/browser/ui/webui/test_files_request_filter.h" #include "chrome/browser/ui/webui/theme_source.h" #include "chrome/common/chrome_constants.h" @@ -94,14 +94,6 @@ const char* kKnownDisplayTypes[] = {OobeUI::kOobeDisplay, OobeUI::kAppLaunchSplashDisplay, OobeUI::kArcKioskSplashDisplay}; -OobeScreen kDimOverlayScreenIds[] = { - OobeScreen::SCREEN_CONFIRM_PASSWORD, - OobeScreen::SCREEN_GAIA_SIGNIN, - OobeScreen::SCREEN_OOBE_ENROLLMENT, - OobeScreen::SCREEN_PASSWORD_CHANGED, - OobeScreen::SCREEN_USER_IMAGE_PICKER -}; - const char kStringsJSPath[] = "strings.js"; const char kLockJSPath[] = "lock.js"; const char kLoginJSPath[] = "login.js"; @@ -142,20 +134,20 @@ content::WebUIDataSource* CreateOobeUIDataSource( IDR_CUSTOM_ELEMENTS_OOBE_HTML); source->AddResourcePath(kCustomElementsJSPath, IDR_CUSTOM_ELEMENTS_OOBE_JS); } else if (display_type == OobeUI::kLockDisplay) { - if (command_line->HasSwitch(chromeos::switches::kShowNonViewMdLogin)) { - source->SetDefaultResource(IDR_MD_LOCK_HTML); - source->AddResourcePath(kLockJSPath, IDR_MD_LOCK_JS); - source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath, - IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML); - source->AddResourcePath(kCustomElementsPinKeyboardJSPath, - IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS); - } else { + if (command_line->HasSwitch(chromeos::switches::kShowNonMdLogin)) { source->SetDefaultResource(IDR_LOCK_HTML); source->AddResourcePath(kLockJSPath, IDR_LOCK_JS); source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath, IDR_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML); source->AddResourcePath(kCustomElementsPinKeyboardJSPath, IDR_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS); + } else { + source->SetDefaultResource(IDR_MD_LOCK_HTML); + source->AddResourcePath(kLockJSPath, IDR_MD_LOCK_JS); + source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath, + IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML); + source->AddResourcePath(kCustomElementsPinKeyboardJSPath, + IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS); } source->AddResourcePath(kCustomElementsHTMLPath, IDR_CUSTOM_ELEMENTS_LOCK_HTML); @@ -163,18 +155,21 @@ content::WebUIDataSource* CreateOobeUIDataSource( source->AddResourcePath(kCustomElementsUserPodHTMLPath, IDR_CUSTOM_ELEMENTS_USER_POD_HTML); } else { - if (command_line->HasSwitch(chromeos::switches::kShowMdLogin) || - command_line->HasSwitch(chromeos::switches::kShowNonViewMdLogin)) { - source->SetDefaultResource(IDR_MD_LOGIN_HTML); - source->AddResourcePath(kLoginJSPath, IDR_MD_LOGIN_JS); - } else { + if (command_line->HasSwitch(chromeos::switches::kShowNonMdLogin)) { source->SetDefaultResource(IDR_LOGIN_HTML); source->AddResourcePath(kLoginJSPath, IDR_LOGIN_JS); + } else { + source->SetDefaultResource(IDR_MD_LOGIN_HTML); + source->AddResourcePath(kLoginJSPath, IDR_MD_LOGIN_JS); } source->AddResourcePath(kCustomElementsHTMLPath, IDR_CUSTOM_ELEMENTS_LOGIN_HTML); source->AddResourcePath(kCustomElementsJSPath, IDR_CUSTOM_ELEMENTS_LOGIN_JS); + source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath, + IDR_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML); + source->AddResourcePath(kCustomElementsPinKeyboardJSPath, + IDR_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS); source->AddResourcePath(kCustomElementsUserPodHTMLPath, IDR_CUSTOM_ELEMENTS_USER_POD_HTML); } @@ -326,6 +321,10 @@ OobeUI::OobeUI(content::WebUI* web_ui, const GURL& url) AddScreenHandler(base::MakeUnique<EncryptionMigrationScreenHandler>()); + AddScreenHandler(base::MakeUnique<VoiceInteractionValuePropScreenHandler>()); + + AddScreenHandler(base::MakeUnique<WaitForContainerReadyScreenHandler>()); + // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler. auto kiosk_app_menu_handler = base::MakeUnique<KioskAppMenuHandler>(network_state_informer_); @@ -349,11 +348,9 @@ OobeUI::OobeUI(content::WebUI* web_ui, const GURL& url) content::WebUIDataSource* html_source = CreateOobeUIDataSource(localized_strings, display_type_); content::WebUIDataSource::Add(profile, html_source); - network_element::AddLocalizedStrings(html_source); // Set up the chrome://userimage/ source. - options::UserImageSource* user_image_source = - new options::UserImageSource(); + UserImageSource* user_image_source = new UserImageSource(); content::URLDataSource::Add(profile, user_image_source); // TabHelper is required for OOBE webui to make webview working on it. @@ -368,11 +365,6 @@ OobeUI::OobeUI(content::WebUI* web_ui, const GURL& url) OobeUI::~OobeUI() { network_dropdown_handler_->RemoveObserver(GetView<ErrorScreenHandler>()); - if (ash_util::IsRunningInMash()) { - // TODO: Ash needs to expose screen dimming api. See - // http://crbug.com/646034. - NOTIMPLEMENTED(); - } } CoreOobeView* OobeUI::GetCoreOobeView() { @@ -447,6 +439,15 @@ EncryptionMigrationScreenView* OobeUI::GetEncryptionMigrationScreenView() { return GetView<EncryptionMigrationScreenHandler>(); } +VoiceInteractionValuePropScreenView* +OobeUI::GetVoiceInteractionValuePropScreenView() { + return GetView<VoiceInteractionValuePropScreenHandler>(); +} + +WaitForContainerReadyScreenView* OobeUI::GetWaitForContainerReadyScreenView() { + return GetView<WaitForContainerReadyScreenHandler>(); +} + UserImageView* OobeUI::GetUserImageView() { return GetView<UserImageScreenHandler>(); } @@ -512,6 +513,11 @@ void OobeUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) { oobe_ui_md_mode_ = g_browser_process->local_state()->GetBoolean(prefs::kOobeMdMode); localized_strings->SetString("newOobeUI", oobe_ui_md_mode_ ? "on" : "off"); + localized_strings->SetString( + "errorScreenMDMode", base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kDisableMdErrorScreen) + ? "off" + : "on"); } void OobeUI::AddWebUIHandler(std::unique_ptr<BaseWebUIHandler> handler) { @@ -548,23 +554,6 @@ void OobeUI::InitializeHandlers() { void OobeUI::CurrentScreenChanged(OobeScreen new_screen) { previous_screen_ = current_screen_; - const bool should_dim = - std::find(std::begin(kDimOverlayScreenIds), - std::end(kDimOverlayScreenIds), - new_screen) != std::end(kDimOverlayScreenIds); - if (!ash_util::IsRunningInMash()) { - if (!screen_dimmer_) { - screen_dimmer_ = base::MakeUnique<ash::ScreenDimmer>( - ash::ScreenDimmer::Container::LOCK_SCREEN); - } - screen_dimmer_->set_at_bottom(true); - screen_dimmer_->SetDimming(should_dim); - } else { - // TODO: Ash needs to expose screen dimming api. See - // http://crbug.com/646034. - NOTIMPLEMENTED(); - } - current_screen_ = new_screen; for (Observer& observer : observer_list_) observer.OnCurrentScreenChanged(current_screen_, new_screen); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.h index a29a94c7c02..a77970518bd 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/oobe_ui.h @@ -20,10 +20,6 @@ #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h" #include "content/public/browser/web_ui_controller.h" -namespace ash { -class ScreenDimmer; -} - namespace base { class DictionaryValue; } // namespace base @@ -62,6 +58,8 @@ class TermsOfServiceScreenView; class UserBoardView; class UserImageView; class UpdateView; +class VoiceInteractionValuePropScreenView; +class WaitForContainerReadyScreenView; class WrongHWIDScreenView; // A custom WebUI that defines datasource for out-of-box-experience (OOBE) UI: @@ -117,6 +115,8 @@ class OobeUI : public content::WebUIController, HostPairingScreenView* GetHostPairingScreenView(); DeviceDisabledScreenView* GetDeviceDisabledScreenView(); EncryptionMigrationScreenView* GetEncryptionMigrationScreenView(); + VoiceInteractionValuePropScreenView* GetVoiceInteractionValuePropScreenView(); + WaitForContainerReadyScreenView* GetWaitForContainerReadyScreenView(); GaiaView* GetGaiaScreenView(); UserBoardView* GetUserBoardView(); @@ -243,8 +243,6 @@ class OobeUI : public content::WebUIController, // Observer of CrosSettings watching the kRebootOnShutdown policy. std::unique_ptr<ShutdownPolicyHandler> shutdown_policy_handler_; - std::unique_ptr<ash::ScreenDimmer> screen_dimmer_; - std::unique_ptr<OobeDisplayChooser> oobe_display_chooser_; // Store the deferred JS calls before the screen handler instance is diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc index e786e4329b3..ae698ed9293 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc @@ -71,6 +71,9 @@ void ResetScreenHandler::DeclareLocalizedValues( IDS_RESET_SCREEN_PREPARING_REVERT_SPINNER_MESSAGE, IDS_SHORT_PRODUCT_NAME); + builder->Add("resetTPMFirmwareUpdate", + IDS_RESET_SCREEN_TPM_FIRMWARE_UPDATE_OPTION); + // Variants for screen title. builder->AddF("resetWarningTitle", IDS_RESET_SCREEN_WARNING_MSG, diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index a412f9b72ea..6c8ee2725d9 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc @@ -9,10 +9,13 @@ #include <algorithm> #include <vector> +#include "ash/login/ui/login_constants.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/tray_action.mojom.h" #include "ash/shell.h" +#include "ash/shutdown_reason.h" #include "ash/system/devicetype_utils.h" +#include "ash/wallpaper/wallpaper_controller.h" #include "ash/wm/lock_state_controller.h" #include "base/bind.h" #include "base/i18n/number_formatting.h" @@ -34,13 +37,13 @@ #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" -#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/language_preferences.h" #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h" #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h" #include "chrome/browser/chromeos/login/hwid_checker.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" +#include "chrome/browser/chromeos/login/lock_screen_utils.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h" #include "chrome/browser/chromeos/login/reauth_stats.h" @@ -72,7 +75,6 @@ #include "chrome/common/channel_info.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -101,7 +103,10 @@ #include "ui/base/ime/chromeos/ime_keyboard.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/gfx/color_analysis.h" +#include "ui/gfx/color_utils.h" namespace { @@ -126,11 +131,24 @@ const char kSourceAccountPicker[] = "account-picker"; const char kNoLockScreenApps[] = "LOCK_SCREEN_APPS_STATE.NONE"; const char kBackgroundLockScreenApps[] = "LOCK_SCREEN_APPS_STATE.BACKGROUND"; const char kForegroundLockScreenApps[] = "LOCK_SCREEN_APPS_STATE.FOREGROUND"; +const char kAvailableLockScreenApps[] = "LOCK_SCREEN_APPS_STATE.AVAILABLE"; -static bool Contains(const std::vector<std::string>& container, - const std::string& value) { - return std::find(container.begin(), container.end(), value) != - container.end(); +// Constants for new lock screen note request type. +const char kNewNoteRequestTap[] = "NEW_NOTE_REQUEST.TAP"; +const char kNewNoteRequestSwipe[] = "NEW_NOTE_REQUEST.SWIPE"; +const char kNewNoteRequestKeyboard[] = "NEW_NOTE_REQUEST.KEYBOARD"; + +// Constants for reporting action taken on lock screen UI when lock screen app +// window was in background. +const char kRequestShutdownFromLockScreenAppUnlockUi[] = + "LOCK_SCREEN_APPS_UNLOCK_ACTION.SHUTDOWN"; +const char kRequestSignoutFromLockScreenAppUnlockUi[] = + "LOCK_SCREEN_APPS_UNLOCK_ACTION.SIGN_OUT"; + +ash::WallpaperController* GetWallpaperController() { + if (!ash::Shell::HasInstance()) + return nullptr; + return ash::Shell::Get()->wallpaper_controller(); } class CallOnReturn { @@ -204,72 +222,6 @@ std::string GetNetworkName(const std::string& service_path) { return network->name(); } -static bool SetUserInputMethodImpl( - const std::string& username, - const std::string& user_input_method, - input_method::InputMethodManager::State* ime_state) { - if (!chromeos::input_method::InputMethodManager::Get()->IsLoginKeyboard( - user_input_method)) { - LOG(WARNING) << "SetUserInputMethod('" << username - << "'): stored user last input method '" << user_input_method - << "' is no longer Full Latin Keyboard Language" - << " (entry dropped). Use hardware default instead."; - - PrefService* const local_state = g_browser_process->local_state(); - DictionaryPrefUpdate updater(local_state, prefs::kUsersLastInputMethod); - - base::DictionaryValue* const users_last_input_methods = updater.Get(); - if (users_last_input_methods != nullptr) { - users_last_input_methods->SetStringWithoutPathExpansion(username, ""); - } - return false; - } - - if (!Contains(ime_state->GetActiveInputMethodIds(), user_input_method)) { - if (!ime_state->EnableInputMethod(user_input_method)) { - DLOG(ERROR) << "SigninScreenHandler::SetUserInputMethod('" << username - << "'): user input method '" << user_input_method - << "' is not enabled and enabling failed (ignored!)."; - } - } - ime_state->ChangeInputMethod(user_input_method, false /* show_message */); - - return true; -} - -void EnforcePolicyInputMethods(std::string user_input_method) { - chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); - const base::ListValue* login_screen_input_methods = nullptr; - if (!cros_settings->GetList(chromeos::kDeviceLoginScreenInputMethods, - &login_screen_input_methods)) { - return; - } - - std::vector<std::string> allowed_input_methods; - - // Add user's input method first so it is pre-selected. - if (!user_input_method.empty()) { - allowed_input_methods.push_back(user_input_method); - } - - std::string input_method; - for (const auto& input_method_entry : *login_screen_input_methods) { - if (input_method_entry.GetAsString(&input_method)) - allowed_input_methods.push_back(input_method); - } - chromeos::input_method::InputMethodManager* imm = - chromeos::input_method::InputMethodManager::Get(); - imm->GetActiveIMEState()->SetAllowedInputMethods(allowed_input_methods); -} - -void StopEnforcingPolicyInputMethods() { - // Empty means all input methods are allowed - std::vector<std::string> allowed_input_methods; - chromeos::input_method::InputMethodManager* imm = - chromeos::input_method::InputMethodManager::Get(); - imm->GetActiveIMEState()->SetAllowedInputMethods(allowed_input_methods); -} - } // namespace // LoginScreenContext implementation ------------------------------------------ @@ -346,12 +298,14 @@ SigninScreenHandler::SigninScreenHandler( content::ServiceManagerConnection::GetForProcess() ->GetConnector() ->BindInterface(ash::mojom::kServiceName, &touch_view_manager_ptr_); - touch_view_manager_ptr_->AddObserver( - touch_view_binding_.CreateInterfacePtrAndBind()); - if (ScreenLocker::default_screen_locker() && - lock_screen_apps::StateController::IsEnabled()) { + ash::mojom::TouchViewObserverPtr observer; + touch_view_binding_.Bind(mojo::MakeRequest(&observer)); + touch_view_manager_ptr_->AddObserver(std::move(observer)); + if (lock_screen_apps::StateController::IsEnabled()) lock_screen_apps_observer_.Add(lock_screen_apps::StateController::Get()); - } + ash::WallpaperController* wallpaper_controller = GetWallpaperController(); + DCHECK(wallpaper_controller); + wallpaper_controller->AddObserver(this); } SigninScreenHandler::~SigninScreenHandler() { @@ -364,63 +318,16 @@ SigninScreenHandler::~SigninScreenHandler() { chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard(); if (keyboard) keyboard->RemoveObserver(this); - StopEnforcingPolicyInputMethods(); + lock_screen_utils::StopEnforcingPolicyInputMethods(); weak_factory_.InvalidateWeakPtrs(); if (delegate_) delegate_->SetWebUIHandler(nullptr); network_state_informer_->RemoveObserver(this); proximity_auth::ScreenlockBridge::Get()->SetLockHandler(nullptr); proximity_auth::ScreenlockBridge::Get()->SetFocusedUser(EmptyAccountId()); -} - -// static -std::string SigninScreenHandler::GetUserLastInputMethod( - const std::string& username) { - PrefService* const local_state = g_browser_process->local_state(); - const base::DictionaryValue* users_last_input_methods = - local_state->GetDictionary(prefs::kUsersLastInputMethod); - - if (!users_last_input_methods) { - DLOG(WARNING) << "GetUserLastInputMethod('" << username - << "'): no kUsersLastInputMethod"; - return std::string(); - } - - std::string input_method; - - if (!users_last_input_methods->GetStringWithoutPathExpansion(username, - &input_method)) { - DVLOG(0) << "GetUserLastInputMethod('" << username - << "'): no input method for this user"; - return std::string(); - } - - return input_method; -} - -// static -// Update keyboard layout to least recently used by the user. -void SigninScreenHandler::SetUserInputMethod( - const std::string& username, - input_method::InputMethodManager::State* ime_state) { - bool succeed = false; - - const std::string input_method = GetUserLastInputMethod(username); - - EnforcePolicyInputMethods(input_method); - - if (!input_method.empty()) - succeed = SetUserInputMethodImpl(username, input_method, ime_state); - - // This is also a case when last layout is set only for a few local users, - // thus others need to be switched to default locale. - // Otherwise they will end up using another user's locale to log in. - if (!succeed) { - DVLOG(0) << "SetUserInputMethod('" << username - << "'): failed to set user layout. Switching to default."; - - ime_state->SetInputMethodLoginDefault(); - } + ash::WallpaperController* wallpaper_controller = GetWallpaperController(); + if (wallpaper_controller) + wallpaper_controller->RemoveObserver(this); } void SigninScreenHandler::DeclareLocalizedValues( @@ -534,7 +441,7 @@ void SigninScreenHandler::DeclareLocalizedValues( builder->Add("removeUserWarningTextHistory", base::string16()); builder->Add("removeUserWarningTextPasswords", base::string16()); builder->Add("removeUserWarningTextBookmarks", base::string16()); - builder->Add("removeUserWarningTextSettings", base::string16()); + builder->Add("removeUserWarningTextAutofill", base::string16()); builder->Add("removeUserWarningTextCalculating", base::string16()); builder->Add("removeUserWarningTextSyncNoStats", base::string16()); builder->Add("removeUserWarningTextSyncCalculating", base::string16()); @@ -586,6 +493,9 @@ void SigninScreenHandler::DeclareLocalizedValues( builder->Add("adPasswordChangeMessage", IDS_AD_PASSWORD_CHANGE_MESSAGE); builder->Add("adOldPasswordError", IDS_AD_PASSWORD_CHANGE_INVALID_PASSWORD); builder->Add("adNewPasswordError", IDS_AD_PASSWORD_CHANGE_PASSWORDS_MISMATCH); + + builder->Add("newLockScreenNoteButton", + IDS_LOGIN_NEW_LOCK_SCREEN_NOTE_BUTTON_TITLE); } void SigninScreenHandler::RegisterMessages() { @@ -599,7 +509,6 @@ void SigninScreenHandler::RegisterMessages() { AddCallback("rebootSystem", &SigninScreenHandler::HandleRebootSystem); AddRawCallback("showAddUser", &SigninScreenHandler::HandleShowAddUser); AddCallback("shutdownSystem", &SigninScreenHandler::HandleShutdownSystem); - AddCallback("loadWallpaper", &SigninScreenHandler::HandleLoadWallpaper); AddCallback("removeUser", &SigninScreenHandler::HandleRemoveUser); AddCallback("toggleEnrollmentScreen", &SigninScreenHandler::HandleToggleEnrollmentScreen); @@ -647,6 +556,10 @@ void SigninScreenHandler::RegisterMessages() { &SigninScreenHandler::HandleLaunchArcKioskApp); AddCallback("setLockScreenAppsState", &SigninScreenHandler::HandleSetLockScreenAppsState); + AddCallback("recordLockScreenAppUnlockAction", + &SigninScreenHandler::HandleRecordLockScreenAppUnlockUIAction); + AddCallback("requestNewLockScreenNote", + &SigninScreenHandler::HandleRequestNewNoteAction); } void SigninScreenHandler::Show(const LoginScreenContext& context) { @@ -723,7 +636,7 @@ void SigninScreenHandler::ShowImpl() { OnShowAddUser(); } else { // Populates account picker. Animation is turned off for now until we - // figure out how to make it fast enough. + // figure out how to make it fast enough. This will call LoadUsers. delegate_->HandleGetUsers(); // Reset Caps Lock state when login screen is shown. @@ -977,6 +890,29 @@ void SigninScreenHandler::ReloadGaia(bool force_reload) { gaia_screen_handler_->ReloadGaia(force_reload); } +void SigninScreenHandler::UpdateAccountPickerColors() { + color_utils::ColorProfile color_profile(color_utils::LumaRange::DARK, + color_utils::SaturationRange::MUTED); + ash::WallpaperController* wallpaper_controller = GetWallpaperController(); + SkColor dark_muted_color = + wallpaper_controller + ? wallpaper_controller->GetProminentColor(color_profile) + : ash::login_constants::kDefaultBaseColor; + if (dark_muted_color == ash::WallpaperController::kInvalidColor) + dark_muted_color = ash::login_constants::kDefaultBaseColor; + + dark_muted_color = SkColorSetA(dark_muted_color, 0xFF); + SkColor base_color = color_utils::GetResultingPaintColor( + SkColorSetA(ash::login_constants::kDefaultBaseColor, + ash::login_constants::kTranslucentColorDarkenAlpha), + dark_muted_color); + SkColor scroll_color = + SkColorSetA(base_color, ash::login_constants::kScrollTranslucentAlpha); + CallJS("login.AccountPickerScreen.setOverlayColors", + color_utils::SkColorToRgbaString(dark_muted_color), + color_utils::SkColorToRgbaString(scroll_color)); +} + void SigninScreenHandler::Initialize() { // Preload PIN keyboard if any of the users can authenticate via PIN. if (user_manager::UserManager::IsInitialized()) { @@ -1017,6 +953,12 @@ void SigninScreenHandler::OnCurrentScreenChanged(OobeScreen current_screen, } } +void SigninScreenHandler::OnWallpaperColorsChanged() { + UpdateAccountPickerColors(); +} + +void SigninScreenHandler::OnWallpaperDataChanged() {} + void SigninScreenHandler::ClearAndEnablePassword() { core_oobe_view_->ResetSignInUI(false); } @@ -1174,8 +1116,12 @@ void SigninScreenHandler::OnTouchViewToggled(bool enabled) { void SigninScreenHandler::OnLockScreenNoteStateChanged( ash::mojom::TrayActionState state) { + if (!ScreenLocker::default_screen_locker()) + return; + std::string lock_screen_apps_state; switch (state) { + case ash::mojom::TrayActionState::kLaunching: case ash::mojom::TrayActionState::kActive: lock_screen_apps_state = kForegroundLockScreenApps; break; @@ -1183,8 +1129,9 @@ void SigninScreenHandler::OnLockScreenNoteStateChanged( lock_screen_apps_state = kBackgroundLockScreenApps; break; case ash::mojom::TrayActionState::kAvailable: + lock_screen_apps_state = kAvailableLockScreenApps; + break; case ash::mojom::TrayActionState::kNotAvailable: - case ash::mojom::TrayActionState::kLaunching: lock_screen_apps_state = kNoLockScreenApps; break; } @@ -1271,12 +1218,8 @@ void SigninScreenHandler::HandleOfflineLogin(const base::ListValue* args) { } void SigninScreenHandler::HandleShutdownSystem() { - ash::Shell::Get()->lock_state_controller()->RequestShutdown(); -} - -void SigninScreenHandler::HandleLoadWallpaper(const AccountId& account_id) { - if (delegate_) - delegate_->LoadWallpaper(account_id); + ash::Shell::Get()->lock_state_controller()->RequestShutdown( + ash::ShutdownReason::LOGIN_SHUT_DOWN_BUTTON); } void SigninScreenHandler::HandleRebootSystem() { @@ -1340,8 +1283,8 @@ void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() { delegate_->ShowKioskAutolaunchScreen(); } -void SigninScreenHandler::LoadUsers(const base::ListValue& users_list, - bool showGuest) { +void SigninScreenHandler::LoadUsers(const user_manager::UserList& users, + const base::ListValue& users_list) { CallJSOrDefer("login.AccountPickerScreen.loadUsers", users_list, delegate_->IsShowGuest()); } @@ -1371,11 +1314,13 @@ void SigninScreenHandler::HandleAccountPickerReady() { is_account_picker_showing_first_time_ = true; - if (ScreenLocker::default_screen_locker() && - lock_screen_apps::StateController::IsEnabled()) { + if (lock_screen_apps::StateController::IsEnabled()) { OnLockScreenNoteStateChanged( lock_screen_apps::StateController::Get()->GetLockScreenNoteState()); } + // Color calculation of the first wallpaper may have completed before the + // instance is initialized, so make sure the colors are properly updated. + UpdateAccountPickerColors(); if (delegate_) delegate_->OnSigninScreenReady(); } @@ -1478,7 +1423,8 @@ void SigninScreenHandler::HandleShowLoadingTimeoutError() { UpdateState(NetworkError::ERROR_REASON_LOADING_TIMEOUT); } -void SigninScreenHandler::HandleFocusPod(const AccountId& account_id) { +void SigninScreenHandler::HandleFocusPod(const AccountId& account_id, + bool load_wallpaper) { proximity_auth::ScreenlockBridge::Get()->SetFocusedUser(account_id); if (delegate_) delegate_->CheckUserStatus(account_id); @@ -1493,9 +1439,11 @@ void SigninScreenHandler::HandleFocusPod(const AccountId& account_id) { if (user && user->is_logged_in() && !user->is_active()) { SessionControllerClient::DoSwitchActiveUser(account_id); } else { - SetUserInputMethod(account_id.GetUserEmail(), ime_state_.get()); - SetKeyboardSettings(account_id); - WallpaperManager::Get()->SetUserWallpaperDelayed(account_id); + lock_screen_utils::SetUserInputMethod(account_id.GetUserEmail(), + ime_state_.get()); + lock_screen_utils::SetKeyboardSettings(account_id); + if (delegate_ && load_wallpaper) + delegate_->LoadWallpaper(account_id); bool use_24hour_clock = false; if (user_manager::known_user::GetBooleanPref( @@ -1510,7 +1458,7 @@ void SigninScreenHandler::HandleFocusPod(const AccountId& account_id) { void SigninScreenHandler::HandleNoPodFocused() { focused_pod_account_id_.reset(); - EnforcePolicyInputMethods(std::string()); + lock_screen_utils::EnforcePolicyInputMethods(std::string()); } void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts( @@ -1581,15 +1529,54 @@ void SigninScreenHandler::HandleSendFeedbackAndResyncUserData() { weak_factory_.GetWeakPtr())); } +void SigninScreenHandler::HandleRequestNewNoteAction( + const std::string& request_type) { + lock_screen_apps::StateController* state_controller = + lock_screen_apps::StateController::Get(); + + if (request_type == kNewNoteRequestTap) { + state_controller->HandleNewNoteRequestFromLockScreen( + lock_screen_apps::StateController::NewNoteRequestType:: + kLockScreenUiTap); + } else if (request_type == kNewNoteRequestSwipe) { + state_controller->HandleNewNoteRequestFromLockScreen( + lock_screen_apps::StateController::NewNoteRequestType:: + kLockScreenUiSwipe); + } else if (request_type == kNewNoteRequestKeyboard) { + state_controller->HandleNewNoteRequestFromLockScreen( + lock_screen_apps::StateController::NewNoteRequestType:: + kLockScreenUiKeyboard); + } else { + NOTREACHED() << "Unknown request type " << request_type; + } +} + +void SigninScreenHandler::HandleRecordLockScreenAppUnlockUIAction( + const std::string& action) { + lock_screen_apps::StateController* state_controller = + lock_screen_apps::StateController::Get(); + + if (action == kRequestShutdownFromLockScreenAppUnlockUi) { + state_controller->RecordLockScreenAppUnlockAction( + lock_screen_apps::StateController::LockScreenUnlockAction::kShutdown); + } else if (action == kRequestSignoutFromLockScreenAppUnlockUi) { + state_controller->RecordLockScreenAppUnlockAction( + lock_screen_apps::StateController::LockScreenUnlockAction::kSignOut); + } else { + NOTREACHED() << "Unknown action " << action; + } +} + void SigninScreenHandler::HandleSetLockScreenAppsState( const std::string& state) { lock_screen_apps::StateController* state_controller = lock_screen_apps::StateController::Get(); - if (state == kBackgroundLockScreenApps) + if (state == kBackgroundLockScreenApps) { state_controller->MoveToBackground(); - else if (state == kForegroundLockScreenApps) + } else if (state == kForegroundLockScreenApps) { state_controller->MoveToForeground(); + } } bool SigninScreenHandler::AllWhitelistedUsersPresent() { @@ -1651,7 +1638,7 @@ bool SigninScreenHandler::IsGuestSigninAllowed() const { void SigninScreenHandler::OnShowAddUser() { is_account_picker_showing_first_time_ = false; - EnforcePolicyInputMethods(std::string()); + lock_screen_utils::EnforcePolicyInputMethods(std::string()); gaia_screen_handler_->ShowGaiaAsync(); } @@ -1677,40 +1664,12 @@ void SigninScreenHandler::OnAllowedInputMethodsChanged() { return; if (focused_pod_account_id_) { - std::string user_input_method = - GetUserLastInputMethod(focused_pod_account_id_->GetUserEmail()); - EnforcePolicyInputMethods(user_input_method); + std::string user_input_method = lock_screen_utils::GetUserLastInputMethod( + focused_pod_account_id_->GetUserEmail()); + lock_screen_utils::EnforcePolicyInputMethods(user_input_method); } else { - EnforcePolicyInputMethods(std::string()); - } -} - -void SigninScreenHandler::SetKeyboardSettings(const AccountId& account_id) { - bool auto_repeat_enabled = language_prefs::kXkbAutoRepeatEnabled; - if (user_manager::known_user::GetBooleanPref( - account_id, prefs::kLanguageXkbAutoRepeatEnabled, - &auto_repeat_enabled) && - !auto_repeat_enabled) { - input_method::InputMethodManager::Get() - ->GetImeKeyboard() - ->SetAutoRepeatEnabled(false); - return; + lock_screen_utils::EnforcePolicyInputMethods(std::string()); } - - int auto_repeat_delay = language_prefs::kXkbAutoRepeatDelayInMs; - int auto_repeat_interval = language_prefs::kXkbAutoRepeatIntervalInMs; - user_manager::known_user::GetIntegerPref( - account_id, prefs::kLanguageXkbAutoRepeatDelay, &auto_repeat_delay); - user_manager::known_user::GetIntegerPref( - account_id, prefs::kLanguageXkbAutoRepeatInterval, &auto_repeat_interval); - input_method::AutoRepeatRate rate; - rate.initial_delay_in_ms = auto_repeat_delay; - rate.repeat_interval_in_ms = auto_repeat_interval; - input_method::InputMethodManager::Get() - ->GetImeKeyboard() - ->SetAutoRepeatEnabled(true); - input_method::InputMethodManager::Get()->GetImeKeyboard()->SetAutoRepeatRate( - rate); } } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index df423f53a72..1a1a3498595 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h @@ -11,6 +11,7 @@ #include <string> #include "ash/public/interfaces/touch_view.mojom.h" +#include "ash/wallpaper/wallpaper_controller_observer.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/containers/hash_tables.h" @@ -109,8 +110,9 @@ class LoginDisplayWebUIHandler { const std::string& password) = 0; virtual void ShowWhitelistCheckFailedError() = 0; virtual void ShowUnrecoverableCrypthomeErrorDialog() = 0; - virtual void LoadUsers(const base::ListValue& users_list, - bool show_guest) = 0; + virtual void LoadUsers(const user_manager::UserList& users, + const base::ListValue& users_list) = 0; + protected: virtual ~LoginDisplayWebUIHandler() {} }; @@ -238,7 +240,8 @@ class SigninScreenHandler public input_method::ImeKeyboard::Observer, public ash::mojom::TouchViewObserver, public lock_screen_apps::StateObserver, - public OobeUI::Observer { + public OobeUI::Observer, + public ash::WallpaperControllerObserver { public: SigninScreenHandler( const scoped_refptr<NetworkStateInformer>& network_state_informer, @@ -272,10 +275,14 @@ class SigninScreenHandler // Required Local State preferences. static void RegisterPrefs(PrefRegistrySimple* registry); - // OobeUI::Observer implemetation. + // OobeUI::Observer implementation: void OnCurrentScreenChanged(OobeScreen current_screen, OobeScreen new_screen) override; + // ash::WallpaperControllerObserver implementation: + void OnWallpaperColorsChanged() override; + void OnWallpaperDataChanged() override; + void SetFocusPODCallbackForTesting(base::Closure callback); // To avoid spurious error messages on flaky networks, the offline message is @@ -313,6 +320,10 @@ class SigninScreenHandler NetworkError::ErrorReason reason); void ReloadGaia(bool force_reload); + // Updates the color of the scrollable container on account picker screen, + // based on wallpaper color extraction results. + void UpdateAccountPickerColors(); + // BaseScreenHandler implementation: void DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) override; @@ -342,7 +353,8 @@ class SigninScreenHandler const std::string& password) override; void ShowWhitelistCheckFailedError() override; void ShowUnrecoverableCrypthomeErrorDialog() override; - void LoadUsers(const base::ListValue& users_list, bool show_guest) override; + void LoadUsers(const user_manager::UserList& users, + const base::ListValue& users_list) override; // content::NotificationObserver implementation: void Observe(int type, @@ -378,7 +390,6 @@ class SigninScreenHandler const std::string& input_method); void HandleOfflineLogin(const base::ListValue* args); void HandleShutdownSystem(); - void HandleLoadWallpaper(const AccountId& account_id); void HandleRebootSystem(); void HandleRemoveUser(const AccountId& account_id); void HandleShowAddUser(const base::ListValue* args); @@ -402,7 +413,7 @@ class SigninScreenHandler void HandleLoginScreenUpdate(); void HandleShowLoadingTimeoutError(); void HandleShowSupervisedUserCreationScreen(); - void HandleFocusPod(const AccountId& account_id); + void HandleFocusPod(const AccountId& account_id, bool load_wallpaper); void HandleNoPodFocused(); void HandleHardlockPod(const std::string& user_id); void HandleLaunchKioskApp(const AccountId& app_account_id, @@ -415,6 +426,8 @@ class SigninScreenHandler void HandleFirstIncorrectPasswordAttempt(const AccountId& account_id); void HandleMaxIncorrectPasswordAttempts(const AccountId& account_id); void HandleSendFeedbackAndResyncUserData(); + void HandleRequestNewNoteAction(const std::string& request_type); + void HandleRecordLockScreenAppUnlockUIAction(const std::string& action); void HandleSetLockScreenAppsState(const std::string& state); // Sends the list of |keyboard_layouts| available for the |locale| that is @@ -456,6 +469,7 @@ class SigninScreenHandler // input_method::ImeKeyboard::Observer implementation: void OnCapsLockChanged(bool enabled) override; + void OnLayoutChanging(const std::string& layout_name) override {} // Callback invoked after the feedback is finished. void OnFeedbackFinished(); @@ -463,9 +477,6 @@ class SigninScreenHandler // Called when the cros property controlling allowed input methods changes. void OnAllowedInputMethodsChanged(); - // Update the keyboard settings for |account_id|. - void SetKeyboardSettings(const AccountId& account_id); - // Current UI state of the signin screen. UIState ui_state_ = UI_STATE_UNKNOWN; diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc b/chromium/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc index c19b3ebe63c..319918915d8 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc @@ -36,7 +36,7 @@ const char* kUsers[] = { namespace chromeos { -class SigninPrepareUserListTest : public ash::test::AshTestBase, +class SigninPrepareUserListTest : public ash::AshTestBase, public MultiProfileUserControllerDelegate { public: SigninPrepareUserListTest() @@ -46,7 +46,7 @@ class SigninPrepareUserListTest : public ash::test::AshTestBase, ~SigninPrepareUserListTest() override {} void SetUp() override { - ash::test::AshTestBase::SetUp(); + ash::AshTestBase::SetUp(); profile_manager_.reset( new TestingProfileManager(TestingBrowserProcess::GetGlobal())); ASSERT_TRUE(profile_manager_->SetUp()); @@ -70,7 +70,7 @@ class SigninPrepareUserListTest : public ash::test::AshTestBase, chromeos::WallpaperManager::Shutdown(); controller_.reset(); profile_manager_.reset(); - ash::test::AshTestBase::TearDown(); + ash::AshTestBase::TearDown(); } // MultiProfileUserControllerDelegate overrides: @@ -79,8 +79,7 @@ class SigninPrepareUserListTest : public ash::test::AshTestBase, FakeChromeUserManager* fake_user_manager_; ScopedUserManagerEnabler user_manager_enabler_; std::unique_ptr<TestingProfileManager> profile_manager_; - std::map<std::string, proximity_auth::ScreenlockBridge::LockHandler::AuthType> - user_auth_type_map; + std::map<std::string, proximity_auth::mojom::AuthType> user_auth_type_map; std::unique_ptr<MultiProfileUserController> controller_; DISALLOW_COPY_AND_ASSIGN(SigninPrepareUserListTest); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc index 840bb5a7fe5..6bb1525b1fa 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc @@ -234,7 +234,7 @@ void SupervisedUserCreationScreenHandler::Show() { auto user_dict = base::MakeUnique<base::DictionaryValue>(); UserSelectionScreen::FillUserDictionary( *it, is_owner, false, /* is_signin_to_add */ - proximity_auth::ScreenlockBridge::LockHandler::OFFLINE_PASSWORD, + proximity_auth::mojom::AuthType::OFFLINE_PASSWORD, NULL, /* public_session_recommended_locales */ user_dict.get()); users_list->Append(std::move(user_dict)); @@ -407,23 +407,12 @@ void SupervisedUserCreationScreenHandler::HandleAuthenticateManager( // TODO(antrim) : this is an explicit code duplications with UserImageScreen. // It should be removed by issue 251179. void SupervisedUserCreationScreenHandler::HandleGetImages() { - base::ListValue image_urls; - for (int i = default_user_image::kFirstDefaultImageIndex; - i < default_user_image::kDefaultImagesCount; ++i) { - std::unique_ptr<base::DictionaryValue> image_data( - new base::DictionaryValue); - image_data->SetString("url", default_user_image::GetDefaultImageUrl(i)); - image_data->SetString("author", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageAuthorIDs[i])); - image_data->SetString("website", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageWebsiteIDs[i])); - image_data->SetString("title", - default_user_image::GetDefaultImageDescription(i)); - image_urls.Append(std::move(image_data)); - } - CallJS("setDefaultImages", image_urls); + base::DictionaryValue result; + result.SetInteger("first", default_user_image::GetFirstDefaultImage()); + std::unique_ptr<base::ListValue> default_images = + default_user_image::GetAsDictionary(true /* all */); + result.Set("images", std::move(default_images)); + CallJS("setDefaultImages", result); } void SupervisedUserCreationScreenHandler::HandlePhotoTaken @@ -448,8 +437,8 @@ void SupervisedUserCreationScreenHandler::HandleDiscardPhoto() { } void SupervisedUserCreationScreenHandler::HandleSelectImage( - const std::string& image_url, - const std::string& image_type) { + const std::string& image_type, + const std::string& image_url) { if (delegate_) delegate_->OnImageSelected(image_type, image_url); } diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h index 55e11d32906..d81551add56 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h @@ -59,8 +59,8 @@ class SupervisedUserCreationScreenHandler : public BaseScreenHandler { virtual void HideFlow() = 0; virtual void OnPhotoTaken(const std::string& raw_data) = 0; - virtual void OnImageSelected(const std::string& image_url, - const std::string& image_type) = 0; + virtual void OnImageSelected(const std::string& image_type, + const std::string& image_url) = 0; virtual void OnImageAccepted() = 0; virtual void OnPageSelected(const std::string& page) = 0; }; diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc index a1ca651ac92..cec38d8690f 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc @@ -34,6 +34,7 @@ void UpdateScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { builder->Add("checkingForUpdatesMsg", IDS_CHECKING_FOR_UPDATE_MSG); builder->Add("installingUpdateDesc", IDS_UPDATE_MSG); + builder->Add("updateCompeletedMsg", IDS_UPDATE_COMPLETED); builder->Add("updateScreenTitle", IDS_UPDATE_SCREEN_TITLE); builder->Add("updateScreenAccessibleTitle", IDS_UPDATE_SCREEN_ACCESSIBLE_TITLE); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc index 0fca4ef2f46..b21048cc482 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc @@ -71,8 +71,13 @@ void UserBoardScreenHandler::ShowBannerMessage(const base::string16& message) { void UserBoardScreenHandler::ShowUserPodCustomIcon( const AccountId& account_id, - const base::DictionaryValue& icon) { - CallJS("login.AccountPickerScreen.showUserPodCustomIcon", account_id, icon); + const proximity_auth::ScreenlockBridge::UserPodCustomIconOptions& + icon_options) { + std::unique_ptr<base::DictionaryValue> icon = + icon_options.ToDictionaryValue(); + if (!icon || icon->empty()) + return; + CallJS("login.AccountPickerScreen.showUserPodCustomIcon", account_id, *icon); } void UserBoardScreenHandler::HideUserPodCustomIcon( @@ -82,7 +87,7 @@ void UserBoardScreenHandler::HideUserPodCustomIcon( void UserBoardScreenHandler::SetAuthType( const AccountId& account_id, - proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type, + proximity_auth::mojom::AuthType auth_type, const base::string16& initial_value) { CallJS("login.AccountPickerScreen.setAuthType", account_id, static_cast<int>(auth_type), base::Value(initial_value)); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.h index 13936abcdaa..af2a912947a 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.h @@ -46,13 +46,14 @@ class UserBoardScreenHandler : public BaseScreenHandler, public UserBoardView { const std::string& default_locale, bool multiple_recommended_locales) override; void ShowBannerMessage(const base::string16& message) override; - void ShowUserPodCustomIcon(const AccountId& account_id, - const base::DictionaryValue& icon) override; - void HideUserPodCustomIcon(const AccountId& account_id) override; - void SetAuthType( + void ShowUserPodCustomIcon( const AccountId& account_id, - proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type, - const base::string16& initial_value) override; + const proximity_auth::ScreenlockBridge::UserPodCustomIconOptions& + icon_options) override; + void HideUserPodCustomIcon(const AccountId& account_id) override; + void SetAuthType(const AccountId& account_id, + proximity_auth::mojom::AuthType auth_type, + const base::string16& initial_value) override; void Bind(UserSelectionScreen* screen) override; void Unbind() override; base::WeakPtr<UserBoardView> GetWeakPtr() override; diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc index d313a595f6b..8f34f6a78cd 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc @@ -91,7 +91,7 @@ void UserImageScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { builder->Add("userImageScreenTitle", IDS_USER_IMAGE_SCREEN_TITLE); builder->Add("userImageScreenDescription", - IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT); + IDS_USER_IMAGE_SCREEN_DESCRIPTION); builder->Add("takePhoto", IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO); builder->Add("discardPhoto", IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO); builder->Add("flipPhoto", IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO); @@ -99,23 +99,13 @@ void UserImageScreenHandler::DeclareLocalizedValues( builder->Add("profilePhotoLoading", IDS_IMAGE_SCREEN_PROFILE_LOADING_PHOTO); builder->Add("okButtonText", IDS_OK); - builder->Add("authorCredit", IDS_OPTIONS_SET_WALLPAPER_AUTHOR_TEXT); builder->Add("photoFromCamera", IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA); - builder->Add("photoFlippedAccessibleText", - IDS_OPTIONS_PHOTO_FLIP_ACCESSIBLE_TEXT); - builder->Add("photoFlippedBackAccessibleText", - IDS_OPTIONS_PHOTO_FLIPBACK_ACCESSIBLE_TEXT); - builder->Add("photoCaptureAccessibleText", - IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT); - builder->Add("photoDiscardAccessibleText", - IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT); builder->Add("syncingPreferences", IDS_IMAGE_SCREEN_SYNCING_PREFERENCES); } void UserImageScreenHandler::RegisterMessages() { AddCallback("getImages", &UserImageScreenHandler::HandleGetImages); AddCallback("screenReady", &UserImageScreenHandler::HandleScreenReady); - AddCallback("takePhoto", &UserImageScreenHandler::HandleTakePhoto); AddCallback("discardPhoto", &UserImageScreenHandler::HandleDiscardPhoto); AddCallback("photoTaken", &UserImageScreenHandler::HandlePhotoTaken); AddCallback("selectImage", &UserImageScreenHandler::HandleSelectImage); @@ -127,23 +117,12 @@ void UserImageScreenHandler::RegisterMessages() { // TODO(antrim) : It looks more like parameters for "Init" rather than callback. void UserImageScreenHandler::HandleGetImages() { - base::ListValue image_urls; - for (int i = default_user_image::kFirstDefaultImageIndex; - i < default_user_image::kDefaultImagesCount; ++i) { - std::unique_ptr<base::DictionaryValue> image_data( - new base::DictionaryValue); - image_data->SetString("url", default_user_image::GetDefaultImageUrl(i)); - image_data->SetString("author", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageAuthorIDs[i])); - image_data->SetString("website", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageWebsiteIDs[i])); - image_data->SetString("title", - default_user_image::GetDefaultImageDescription(i)); - image_urls.Append(std::move(image_data)); - } - CallJS("setDefaultImages", image_urls); + base::DictionaryValue result; + result.SetInteger("first", default_user_image::GetFirstDefaultImage()); + std::unique_ptr<base::ListValue> default_images = + default_user_image::GetAsDictionary(true /* all */); + result.Set("images", std::move(default_images)); + CallJS("setDefaultImages", result); } void UserImageScreenHandler::HandleScreenReady() { @@ -157,23 +136,20 @@ void UserImageScreenHandler::HandlePhotoTaken(const std::string& image_url) { if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data)) NOTREACHED(); DCHECK_EQ("image/png", mime_type); + AccessibilityManager::Get()->PlayEarcon( + SOUND_CAMERA_SNAP, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED); if (screen_) screen_->OnPhotoTaken(raw_data); } -void UserImageScreenHandler::HandleTakePhoto() { - AccessibilityManager::Get()->PlayEarcon( - SOUND_CAMERA_SNAP, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED); -} - void UserImageScreenHandler::HandleDiscardPhoto() { AccessibilityManager::Get()->PlayEarcon( SOUND_OBJECT_DELETE, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED); } -void UserImageScreenHandler::HandleSelectImage(const std::string& image_url, - const std::string& image_type, +void UserImageScreenHandler::HandleSelectImage(const std::string& image_type, + const std::string& image_url, bool is_user_selection) { if (screen_) screen_->OnImageSelected(image_type, image_url, is_user_selection); diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h index b3349df540b..29b12fb84f5 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h @@ -49,15 +49,12 @@ class UserImageScreenHandler : public UserImageView, public BaseScreenHandler { // Handles photo taken with WebRTC UI. void HandlePhotoTaken(const std::string& image_url); - // Handles 'take-photo' button click. - void HandleTakePhoto(); - // Handles 'discard-photo' button click. void HandleDiscardPhoto(); // Handles clicking on default user image. - void HandleSelectImage(const std::string& image_url, - const std::string& image_type, + void HandleSelectImage(const std::string& image_type, + const std::string& image_url, bool is_user_selection); // Called when user accept the image closing the screen. diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.cc new file mode 100644 index 00000000000..4e3430c3d04 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.cc @@ -0,0 +1,82 @@ +// 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 "chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/oobe_screen.h" +#include "chrome/browser/chromeos/login/screens/voice_interaction_value_prop_screen.h" +#include "chrome/grit/generated_resources.h" +#include "components/login/localized_values_builder.h" + +namespace { + +const char kJsScreenPath[] = "login.VoiceInteractionValuePropScreen"; + +} // namespace + +namespace chromeos { + +VoiceInteractionValuePropScreenHandler::VoiceInteractionValuePropScreenHandler() + : BaseScreenHandler(kScreenId) { + set_call_js_prefix(kJsScreenPath); +} + +VoiceInteractionValuePropScreenHandler:: + ~VoiceInteractionValuePropScreenHandler() { + if (screen_) { + screen_->OnViewDestroyed(this); + } +} + +void VoiceInteractionValuePropScreenHandler::DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) { + builder->Add("locale", g_browser_process->GetApplicationLocale()); + builder->Add("voiceInteractionValuePropLoading", + IDS_VOICE_INTERACTION_VALUE_PROP_LOADING); + builder->Add("voiceInteractionValuePropLoadErrorTitle", + IDS_VOICE_INTERACTION_VALUE_PROP_LOAD_ERROR_TITLE); + builder->Add("voiceInteractionValuePropLoadErrorMessage", + IDS_VOICE_INTERACTION_VALUE_PROP_LOAD_ERROR_MESSAGE); + builder->Add("voiceInteractionValuePropSkipButton", + IDS_VOICE_INTERACTION_VALUE_PROP_SKIP_BUTTON); + builder->Add("voiceInteractionValuePropRetryButton", + IDS_VOICE_INTERACTION_VALUE_PROP_RETRY_BUTTON); + builder->Add("voiceInteractionValuePropNextButton", + IDS_VOICE_INTERACTION_VALUE_PROP_NEXT_BUTTION); +} + +void VoiceInteractionValuePropScreenHandler::Bind( + VoiceInteractionValuePropScreen* screen) { + BaseScreenHandler::SetBaseScreen(screen); + screen_ = screen; + if (page_is_ready()) + Initialize(); +} + +void VoiceInteractionValuePropScreenHandler::Unbind() { + screen_ = nullptr; + BaseScreenHandler::SetBaseScreen(nullptr); +} + +void VoiceInteractionValuePropScreenHandler::Show() { + if (!page_is_ready() || !screen_) { + show_on_init_ = true; + return; + } + + ShowScreen(kScreenId); +} + +void VoiceInteractionValuePropScreenHandler::Hide() {} + +void VoiceInteractionValuePropScreenHandler::Initialize() { + if (!screen_ || !show_on_init_) + return; + + Show(); + show_on_init_ = false; +} + +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.h new file mode 100644 index 00000000000..5b9d2fd094e --- /dev/null +++ b/chromium/chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.h @@ -0,0 +1,48 @@ +// 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_VOICE_INTERACTION_VALUE_PROP_SCREEN_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_VOICE_INTERACTION_VALUE_PROP_SCREEN_HANDLER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "chrome/browser/chromeos/login/screens/voice_interaction_value_prop_screen_view.h" +#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" + +namespace chromeos { + +class VoiceInteractionValuePropScreenHandler + : public BaseScreenHandler, + public VoiceInteractionValuePropScreenView { + public: + VoiceInteractionValuePropScreenHandler(); + ~VoiceInteractionValuePropScreenHandler() override; + + // BaseScreenHandler: + void DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) override; + + // VoiceInteractionValuePropScreenView: + void Bind(VoiceInteractionValuePropScreen* screen) override; + void Unbind() override; + void Show() override; + void Hide() override; + + private: + // BaseScreenHandler: + void Initialize() override; + + VoiceInteractionValuePropScreen* screen_ = nullptr; + + // Whether the screen should be shown right after initialization. + bool show_on_init_ = false; + + DISALLOW_COPY_AND_ASSIGN(VoiceInteractionValuePropScreenHandler); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_VOICE_INTERACTION_VALUE_PROP_SCREEN_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.cc b/chromium/chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.cc new file mode 100644 index 00000000000..9e73b08bd18 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.cc @@ -0,0 +1,127 @@ +// 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 "chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/oobe_screen.h" +#include "chrome/browser/chromeos/login/screens/wait_for_container_ready_screen.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "chrome/grit/generated_resources.h" +#include "components/login/localized_values_builder.h" + +namespace { + +constexpr char kJsScreenPath[] = "login.WaitForContainerReadyScreen"; +constexpr base::TimeDelta kWaitingTimeout = base::TimeDelta::FromMinutes(1); + +} // namespace + +namespace chromeos { + +WaitForContainerReadyScreenHandler::WaitForContainerReadyScreenHandler() + : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) { + set_call_js_prefix(kJsScreenPath); +} + +WaitForContainerReadyScreenHandler::~WaitForContainerReadyScreenHandler() { + if (screen_) { + screen_->OnViewDestroyed(this); + } + timer_.Stop(); + + if (!profile_) + return; + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); + if (prefs) + prefs->RemoveObserver(this); +} + +void WaitForContainerReadyScreenHandler::DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) { + builder->Add("waitForContainerReadyTitle", + IDS_WAIT_FOR_CONTAINER_READY_TITLE); + builder->Add("waitForContainerReadyIntroMessage", + IDS_WAIT_FOR_CONTAINER_READY_INTRO_MESSAGE); + builder->Add("voiceInteractionLogo", IDS_VOICE_INTERACTION_LOGO); +} + +void WaitForContainerReadyScreenHandler::Bind( + WaitForContainerReadyScreen* screen) { + BaseScreenHandler::SetBaseScreen(screen); + screen_ = screen; + if (page_is_ready()) + Initialize(); +} + +void WaitForContainerReadyScreenHandler::Unbind() { + screen_ = nullptr; + BaseScreenHandler::SetBaseScreen(nullptr); + timer_.Stop(); +} + +void WaitForContainerReadyScreenHandler::Show() { + if (!page_is_ready() || !screen_) { + show_on_init_ = true; + return; + } + + if (is_app_list_ready_) { + NotifyContainerReady(); + return; + } + + timer_.Start( + FROM_HERE, kWaitingTimeout, + base::Bind(&WaitForContainerReadyScreenHandler::OnMaxContainerWaitTimeout, + weak_ptr_factory_.GetWeakPtr())); + + ShowScreen(kScreenId); +} + +void WaitForContainerReadyScreenHandler::Hide() {} + +void WaitForContainerReadyScreenHandler::OnPackageListInitialRefreshed() { + is_app_list_ready_ = true; + if (!screen_) + return; + + // TODO(updowndota): Remove the temporary delay after the potential racing + // issue is eliminated. + timer_.Stop(); + timer_.Start( + FROM_HERE, base::TimeDelta::FromSeconds(5), + base::Bind(&WaitForContainerReadyScreenHandler::NotifyContainerReady, + weak_ptr_factory_.GetWeakPtr())); +} + +void WaitForContainerReadyScreenHandler::Initialize() { + profile_ = ProfileManager::GetPrimaryUserProfile(); + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); + if (prefs) { + is_app_list_ready_ = prefs->package_list_initial_refreshed(); + if (!is_app_list_ready_) + prefs->AddObserver(this); + } + + if (!screen_ || !show_on_init_) + return; + + Show(); + show_on_init_ = false; +} + +void WaitForContainerReadyScreenHandler::OnMaxContainerWaitTimeout() { + // TODO(updowndota): Add histogram to Voice Interaction OptIn flow. + if (screen_) + screen_->OnContainerReady(); +} + +void WaitForContainerReadyScreenHandler::NotifyContainerReady() { + if (screen_) + screen_->OnContainerReady(); +} + +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.h b/chromium/chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.h new file mode 100644 index 00000000000..d5b3c3cf491 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.h @@ -0,0 +1,70 @@ +// 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WAIT_FOR_CONTAINER_READY_SCREEN_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WAIT_FOR_CONTAINER_READY_SCREEN_HANDLER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "chrome/browser/chromeos/login/screens/wait_for_container_ready_screen_view.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" + +namespace chromeos { + +class WaitForContainerReadyScreenHandler + : public BaseScreenHandler, + public WaitForContainerReadyScreenView, + public ArcAppListPrefs::Observer { + public: + WaitForContainerReadyScreenHandler(); + ~WaitForContainerReadyScreenHandler() override; + + // BaseScreenHandler: + void DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) override; + + // WaitForContainerReadyScreenView: + void Bind(WaitForContainerReadyScreen* screen) override; + void Unbind() override; + void Show() override; + void Hide() override; + + // ArcAppListPrefs::Observer overrides. + void OnPackageListInitialRefreshed() override; + + private: + // BaseScreenHandler: + void Initialize() override; + + // Called to notify the screen that the container is ready. + void NotifyContainerReady(); + + // Called when the max wait timeout is reached. + void OnMaxContainerWaitTimeout(); + + WaitForContainerReadyScreen* screen_ = nullptr; + + // Whether the screen should be shown right after initialization. + bool show_on_init_ = false; + + // Whether app list is ready. + bool is_app_list_ready_ = false; + + // The primary user profile. + Profile* profile_ = nullptr; + + // Timer used to exit the page when timeout reaches. + base::OneShotTimer timer_; + + base::WeakPtrFactory<WaitForContainerReadyScreenHandler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(WaitForContainerReadyScreenHandler); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WAIT_FOR_CONTAINER_READY_SCREEN_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc index 26089fd707d..58d4d25da3d 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc @@ -31,7 +31,6 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_event_log.h" diff --git a/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc index eebb74d4f84..ef5eb8131a1 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc @@ -6,31 +6,42 @@ #include "build/build_config.h" #include "chrome/grit/generated_resources.h" +#include "components/login/localized_values_builder.h" #include "content/public/browser/web_ui_data_source.h" namespace chromeos { namespace network_element { +namespace { + +struct { + const char* name; + int id; +} const localized_strings[] = { + {"OncTypeCellular", IDS_NETWORK_TYPE_MOBILE_DATA}, + {"OncTypeEthernet", IDS_NETWORK_TYPE_ETHERNET}, + {"OncTypeTether", IDS_NETWORK_TYPE_MOBILE_DATA}, + {"OncTypeVPN", IDS_NETWORK_TYPE_VPN}, + {"OncTypeWiFi", IDS_NETWORK_TYPE_WIFI}, + {"OncTypeWiMAX", IDS_NETWORK_TYPE_WIMAX}, + {"networkListItemConnected", IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED}, + {"networkListItemConnecting", IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING}, + {"networkListItemConnectingTo", IDS_NETWORK_LIST_CONNECTING_TO}, + {"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED}, + {"vpnNameTemplate", IDS_NETWORK_LIST_THIRD_PARTY_VPN_NAME_TEMPLATE}, +}; +} // namespace + void AddLocalizedStrings(content::WebUIDataSource* html_source) { - struct { - const char* name; - int id; - } localized_strings[] = { - {"OncTypeCellular", IDS_NETWORK_TYPE_CELLULAR}, - {"OncTypeEthernet", IDS_NETWORK_TYPE_ETHERNET}, - {"OncTypeTether", IDS_NETWORK_TYPE_TETHER}, - {"OncTypeVPN", IDS_NETWORK_TYPE_VPN}, - {"OncTypeWiFi", IDS_NETWORK_TYPE_WIFI}, - {"OncTypeWiMAX", IDS_NETWORK_TYPE_WIMAX}, - {"networkListItemConnected", IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED}, - {"networkListItemConnecting", IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING}, - {"networkListItemConnectingTo", IDS_NETWORK_LIST_CONNECTING_TO}, - {"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED}, - {"vpnNameTemplate", IDS_NETWORK_LIST_THIRD_PARTY_VPN_NAME_TEMPLATE}, - }; for (const auto& entry : localized_strings) html_source->AddLocalizedString(entry.name, entry.id); } +void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder) { + for (const auto& entry : localized_strings) + builder->Add(entry.name, entry.id); +} + } // namespace network_element + } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h b/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h index cbf065240f8..a16ead5b983 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h +++ b/chromium/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h @@ -5,6 +5,10 @@ #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_ELEMENT_LOCALIZED_STRINGS_PROVIDER_H_ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_ELEMENT_LOCALIZED_STRINGS_PROVIDER_H_ +namespace login { +class LocalizedValuesBuilder; +} + namespace content { class WebUIDataSource; } @@ -13,9 +17,12 @@ namespace chromeos { namespace network_element { // Adds the strings needed for network elements to |html_source|. String ids -// correspond to matching ids in ui/webui/resources/cr_elements/network/. +// correspond to ids in ui/webui/resources/cr_elements/chromeos/network/. void AddLocalizedStrings(content::WebUIDataSource* html_source); +// Same as AddLocalizedStrings but for a LocalizedValuesBuilder. +void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder); + } // namespace network_element } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/chromeos/network_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/network_ui.cc index 5cdb9f79d40..dbf5a400ecd 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/network_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/network_ui.cc @@ -28,7 +28,6 @@ #include "content/public/browser/web_ui_message_handler.h" #include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/chromeos/strings/grit/ui_chromeos_strings.h" namespace chromeos { @@ -145,8 +144,7 @@ class NetworkConfigMessageHandler : public content::WebUIMessageHandler { std::string shill_type = (onc_type == ::onc::network_type::kVPN) ? shill::kTypeVPN : shill::kTypeWifi; - NetworkConfigView::ShowForType( - shill_type, web_ui()->GetWebContents()->GetTopLevelNativeWindow()); + NetworkConfigView::ShowForType(shill_type); } base::WeakPtrFactory<NetworkConfigMessageHandler> weak_ptr_factory_; diff --git a/chromium/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc index 6a1c0b4db82..33114a58fb5 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/proxy_settings_ui.cc @@ -5,6 +5,8 @@ #include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h" #include <memory> +#include <string> +#include <utility> #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -14,6 +16,7 @@ #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h" +#include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h" #include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/url_constants.h" @@ -76,7 +79,6 @@ void ProxySettingsHTMLSource::StartDataRequest( const content::URLDataSource::GotDataCallback& callback) { const std::string& app_locale = g_browser_process->GetApplicationLocale(); webui::SetLoadTimeDataDefaults(app_locale, localized_strings_.get()); - static const base::StringPiece html( ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_PROXY_SETTINGS_HTML)); @@ -106,6 +108,7 @@ ProxySettingsUI::ProxySettingsUI(content::WebUI* web_ui) web_ui->AddMessageHandler(std::move(proxy_handler)); proxy_handler_->GetLocalizedValues(localized_strings); + internet_options_strings::RegisterLocalizedStrings(localized_strings); bool keyboard_driven_oobe = system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation(); localized_strings->SetString("highlightStrength", diff --git a/chromium/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc b/chromium/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc index 7826d8e46e9..766a7dab2cc 100644 --- a/chromium/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc @@ -587,8 +587,9 @@ void SimUnlockHandler::HandleChangePinCode(const base::ListValue* args) { void SimUnlockHandler::HandleEnterCode(SimUnlockCode code_type, const std::string& code) { scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), code, code_type); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&TaskProxy::HandleEnterCode, task.get())); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&TaskProxy::HandleEnterCode, task.get())); } void SimUnlockHandler::HandleEnterPinCode(const base::ListValue* args) { @@ -622,8 +623,9 @@ void SimUnlockHandler::HandleProceedToPukInput(const base::ListValue* args) { return; } scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr()); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&TaskProxy::HandleProceedToPukInput, task.get())); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&TaskProxy::HandleProceedToPukInput, task.get())); } void SimUnlockHandler::HandleSimStatusInitialize(const base::ListValue* args) { @@ -637,8 +639,9 @@ void SimUnlockHandler::HandleSimStatusInitialize(const base::ListValue* args) { dialog_mode_ = static_cast<SimDialogDelegate::SimDialogMode>(mode); VLOG(1) << "Initializing SIM dialog in mode: " << dialog_mode_; scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr()); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&TaskProxy::HandleInitialize, task.get())); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&TaskProxy::HandleInitialize, task.get())); } void SimUnlockHandler::InitializeSimStatus() { diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/user_image_source.cc b/chromium/chrome/browser/ui/webui/chromeos/user_image_source.cc index baad28fd5a1..184628261a7 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/user_image_source.cc +++ b/chromium/chrome/browser/ui/webui/chromeos/user_image_source.cc @@ -2,29 +2,34 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/options/chromeos/user_image_source.h" +#include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "base/memory/ref_counted_memory.h" #include "base/message_loop/message_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "chrome/browser/chromeos/login/users/default_user_image/default_user_images.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/theme_resources.h" #include "components/signin/core/account_id/account_id.h" #include "components/user_manager/known_user.h" #include "components/user_manager/user_manager.h" #include "net/base/escape.h" #include "ui/base/resource/resource_bundle.h" #include "ui/chromeos/resources/grit/ui_chromeos_resources.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/gfx/codec/png_codec.h" #include "url/third_party/mozilla/url_parse.h" namespace { +// URL parameter specifying frame index. +const char kFrameIndex[] = "frame"; + // Parses the user image URL, which looks like // "chrome://userimage/serialized-user-id?key1=value1&...&key_n=value_n", -// to user email. -void ParseRequest(const GURL& url, std::string* email) { +// to user email and frame. +void ParseRequest(const GURL& url, std::string* email, int* frame) { DCHECK(url.is_valid()); const std::string serialized_account_id = net::UnescapeURLComponent( url.path().substr(1), @@ -41,51 +46,94 @@ void ParseRequest(const GURL& url, std::string* email) { serialized_account_id, std::string() /* id */, AccountType::UNKNOWN); } *email = account_id.GetUserEmail(); + *frame = -1; + base::StringPairs parameters; + base::SplitStringIntoKeyValuePairs(url.query(), '=', '&', ¶meters); + for (base::StringPairs::const_iterator iter = parameters.begin(); + iter != parameters.end(); ++iter) { + if (iter->first == kFrameIndex) { + unsigned value = 0; + if (!base::StringToUint(iter->second, &value)) { + LOG(WARNING) << "Invalid frame format: " << iter->second; + continue; + } + *frame = static_cast<int>(value); + break; + } + } +} + +scoped_refptr<base::RefCountedMemory> LoadUserImageFrameForScaleFactor( + int resource_id, + int frame, + ui::ScaleFactor scale_factor) { + // Load all frames. + if (frame == -1) { + return ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( + resource_id, scale_factor); + } + // TODO(reveman): Add support frames beyond 0 (crbug.com/750064). + if (frame) { + NOTIMPLEMENTED() << "Unsupported frame: " << frame; + return nullptr; + } + gfx::ImageSkia* image = + ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); + float scale = ui::GetScaleForScaleFactor(scale_factor); + scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes); + gfx::PNGCodec::EncodeBGRASkBitmap(image->GetRepresentation(scale).sk_bitmap(), + false /* discard transparency */, + &data->data()); + return data; } scoped_refptr<base::RefCountedMemory> GetUserImageInternal( - const AccountId& account_id) { + const AccountId& account_id, + int frame) { const user_manager::User* user = user_manager::UserManager::Get()->FindUser(account_id); - // Always use the 100% scaling. These source images are 256x256, and are - // downscaled to ~64x64 for use in WebUI pages. Therefore, they are big enough - // for device scale factors up to 4. We do not use SCALE_FACTOR_NONE, as we - // specifically want 100% scale images to not transmit more data than needed. + ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P; + // Use the scaling that matches primary display. These source images are + // 96x96 and often used at that size in WebUI pages. + display::Screen* screen = display::Screen::GetScreen(); + if (screen) { + scale_factor = ui::GetSupportedScaleFactor( + screen->GetPrimaryDisplay().device_scale_factor()); + } + if (user) { if (user->has_image_bytes()) return user->image_bytes(); if (user->image_is_stub()) { - return ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( - IDR_PROFILE_PICTURE_LOADING, ui::SCALE_FACTOR_100P); + return LoadUserImageFrameForScaleFactor(IDR_LOGIN_DEFAULT_USER, frame, + scale_factor); } if (user->HasDefaultImage()) { - return ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( + return LoadUserImageFrameForScaleFactor( chromeos::default_user_image::kDefaultImageResourceIDs [user->image_index()], - ui::SCALE_FACTOR_100P); + frame, scale_factor); } NOTREACHED() << "User with custom image missing data bytes"; } else { LOG(ERROR) << "User not found: " << account_id.GetUserEmail(); } - return ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( - IDR_LOGIN_DEFAULT_USER, ui::SCALE_FACTOR_100P); + return LoadUserImageFrameForScaleFactor(IDR_LOGIN_DEFAULT_USER, frame, + scale_factor); } } // namespace namespace chromeos { -namespace options { // Static. scoped_refptr<base::RefCountedMemory> UserImageSource::GetUserImage( const AccountId& account_id) { - return GetUserImageInternal(account_id); + return GetUserImageInternal(account_id, -1); } -UserImageSource::UserImageSource() { -} +UserImageSource::UserImageSource() {} UserImageSource::~UserImageSource() {} @@ -98,10 +146,11 @@ void UserImageSource::StartDataRequest( const content::ResourceRequestInfo::WebContentsGetter& wc_getter, const content::URLDataSource::GotDataCallback& callback) { std::string email; + int frame = -1; GURL url(chrome::kChromeUIUserImageURL + path); - ParseRequest(url, &email); + ParseRequest(url, &email, &frame); const AccountId account_id(AccountId::FromUserEmail(email)); - callback.Run(GetUserImageInternal(account_id)); + callback.Run(GetUserImageInternal(account_id, frame)); } std::string UserImageSource::GetMimeType(const std::string& path) const { @@ -110,5 +159,4 @@ std::string UserImageSource::GetMimeType(const std::string& path) const { return "image/png"; } -} // namespace options } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/user_image_source.h b/chromium/chrome/browser/ui/webui/chromeos/user_image_source.h index 6724abe2a0f..aabfe10cc17 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/user_image_source.h +++ b/chromium/chrome/browser/ui/webui/chromeos/user_image_source.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 CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_USER_IMAGE_SOURCE_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_USER_IMAGE_SOURCE_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_USER_IMAGE_SOURCE_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_USER_IMAGE_SOURCE_H_ #include <string> #include <vector> @@ -21,7 +21,6 @@ class RefCountedMemory; } namespace chromeos { -namespace options { // UserImageSource is the data source that serves user images for users that // have it. @@ -49,7 +48,6 @@ class UserImageSource : public content::URLDataSource { DISALLOW_COPY_AND_ASSIGN(UserImageSource); }; -} // namespace options } // namespace chromeos -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_USER_IMAGE_SOURCE_H_ +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_USER_IMAGE_SOURCE_H_ diff --git a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc b/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc deleted file mode 100644 index d1e6bacc8ac..00000000000 --- a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc +++ /dev/null @@ -1,139 +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 "chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h" - -#include "base/bind.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/component_updater/sw_reporter_installer_win.h" -#include "components/component_updater/component_updater_service.h" - -namespace { - -bool IsCleanupComponentRegistered() { - component_updater::ComponentUpdateService* cus = - g_browser_process->component_updater(); - std::vector<std::string> component_ids = cus->GetComponentIDs(); - - return std::find(component_ids.begin(), component_ids.end(), - component_updater::kSwReporterComponentId) != - component_ids.end(); -} - -// TODO(proberge): Connect this to the Cleanup Tool manager class once that's -// implemented. -void StartScan(base::Closure callback) { - callback.Run(); -} - -// TODO(proberge): Connect this to the Cleanup Tool manager class once that's -// implemented. -void StartCleanup(base::Closure callback) { - callback.Run(); -} - -// TODO(proberge): Localize strings once they are finalized. -constexpr char kDetectionOkText[] = "No problems detected"; -constexpr char kDetectionUwSText[] = "2 potentially harmful programs detected"; -constexpr char kDetectionTimeText[] = "Last scanned today"; -constexpr char kCleanupUnsupportedText[] = "Chrome Cleanup is not supported."; -constexpr char kUnsupportedHelpText[] = "Please try reinstalling Chrome"; - -} // namespace - -CleanupActionHandler::CleanupActionHandler() - : callback_weak_ptr_factory_(this) {} - -CleanupActionHandler::~CleanupActionHandler() {} - -void CleanupActionHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "requestLastScanResult", - base::Bind(&CleanupActionHandler::HandleRequestLastScanResult, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "startScan", base::Bind(&CleanupActionHandler::HandleStartScan, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "startCleanup", base::Bind(&CleanupActionHandler::HandleStartCleanup, - base::Unretained(this))); -} - -void CleanupActionHandler::OnJavascriptDisallowed() { - callback_weak_ptr_factory_.InvalidateWeakPtrs(); -} - -void CleanupActionHandler::HandleRequestLastScanResult( - const base::ListValue* args) { - CHECK_EQ(1U, args->GetSize()); - std::string webui_callback_id; - bool success = args->GetString(0, &webui_callback_id); - DCHECK(success); - - base::DictionaryValue last_scan_results; - // TODO(proberge): Return real information about the last run. - last_scan_results.SetBoolean("hasScanResults", false); - last_scan_results.SetBoolean("isInfected", false); - last_scan_results.SetString("detectionStatusText", kDetectionOkText); - last_scan_results.SetString("detectionTimeText", kDetectionTimeText); - - AllowJavascript(); - ResolveJavascriptCallback(base::Value(webui_callback_id), last_scan_results); -} - -void CleanupActionHandler::HandleStartScan(const base::ListValue* args) { - std::string webui_callback_id; - CHECK_EQ(1U, args->GetSize()); - bool success = args->GetString(0, &webui_callback_id); - DCHECK(success); - - if (!IsCleanupComponentRegistered()) { - base::DictionaryValue scan_results; - scan_results.SetBoolean("hasScanResults", false); - scan_results.SetBoolean("isInfected", false); - scan_results.SetString("detectionStatusText", kCleanupUnsupportedText); - scan_results.SetString("detectionTimeText", kUnsupportedHelpText); - - AllowJavascript(); - ResolveJavascriptCallback(base::Value(webui_callback_id), scan_results); - return; - } - - StartScan(base::Bind(&CleanupActionHandler::ReportScanResults, - callback_weak_ptr_factory_.GetWeakPtr(), - webui_callback_id)); -} - -void CleanupActionHandler::ReportScanResults(const std::string& callback_id) { - base::DictionaryValue scan_results; - // TODO(proberge): Return real information about the scan. - scan_results.SetBoolean("hasScanResults", true); - scan_results.SetBoolean("isInfected", true); - scan_results.SetString("detectionStatusText", kDetectionUwSText); - scan_results.SetString("detectionTimeText", kDetectionTimeText); - - AllowJavascript(); - ResolveJavascriptCallback(base::Value(callback_id), scan_results); -} - -void CleanupActionHandler::HandleStartCleanup(const base::ListValue* args) { - CHECK_EQ(1U, args->GetSize()); - std::string webui_callback_id; - bool success = args->GetString(0, &webui_callback_id); - DCHECK(success); - - StartCleanup(base::Bind(&CleanupActionHandler::ReportCleanupResults, - base::Unretained(this), webui_callback_id)); -} - -void CleanupActionHandler::ReportCleanupResults( - const std::string& callback_id) { - base::DictionaryValue cleanup_results; - // TODO(proberge): Return real information about the cleanup. - cleanup_results.SetBoolean("wasCancelled", true); - cleanup_results.SetBoolean("requiresReboot", false); - - ResolveJavascriptCallback(base::Value(callback_id), cleanup_results); -} diff --git a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h b/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h deleted file mode 100644 index 97c87f05dfa..00000000000 --- a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h +++ /dev/null @@ -1,44 +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 CHROME_BROWSER_UI_WEBUI_CLEANUP_TOOL_CLEANUP_ACTION_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_CLEANUP_TOOL_CLEANUP_ACTION_HANDLER_H_ - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/web_ui_message_handler.h" - -// The handler for Javascript messages related to the "Chrome Cleanup" view. -class CleanupActionHandler : public content::WebUIMessageHandler { - public: - CleanupActionHandler(); - ~CleanupActionHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - private: - // Invalidates the weak pointers in callbacks that are no longer safe to run. - void OnJavascriptDisallowed() override; - - void HandleRequestLastScanResult(const base::ListValue* args); - void HandleStartScan(const base::ListValue* args); - void HandleStartCleanup(const base::ListValue* args); - - // Returns the scan result initiated by HandleStartScan() to the Javascript - // caller refererenced by |callback_id|. - void ReportScanResults(const std::string& callback_id); - - // Returns the cleanup result initiated by HandleStartCleanup() to the - // Javascript caller refererenced by |callback_id|. - void ReportCleanupResults(const std::string& callback_id); - - // Used to cancel callbacks when JavaScript becomes disallowed. - base::WeakPtrFactory<CleanupActionHandler> callback_weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(CleanupActionHandler); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_CLEANUP_TOOL_CLEANUP_ACTION_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc b/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc deleted file mode 100644 index c22710465df..00000000000 --- a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc +++ /dev/null @@ -1,46 +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 "chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.h" - -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" -#include "content/public/browser/web_ui_data_source.h" - -CleanupToolUI::CleanupToolUI(content::WebUI* web_ui) - : content::WebUIController(web_ui) { - content::WebUIDataSource* html_source = - content::WebUIDataSource::Create(chrome::kChromeUICleanupToolHost); - - // TODO(proberge): Localize strings once they are finalized. - html_source->AddString("title", "Chrome Cleanup"); - html_source->AddString("sectionHeader", - "Remove suspicious or unwanted programs"); - html_source->AddString("scanAction", "Scan Now"); - html_source->AddString("cleaning", "Cleaning"); - html_source->AddString("scanning", "Scanning"); - html_source->AddString("cleanAction", "Run Chrome Cleanup"); - html_source->AddString("about", "About Chrome Cleanup"); - html_source->SetJsonPath("strings.js"); - - html_source->AddResourcePath("cleanup_browser_proxy.html", - IDR_CLEANUP_TOOL_BROWSER_PROXY_HTML); - html_source->AddResourcePath("cleanup_browser_proxy.js", - IDR_CLEANUP_TOOL_BROWSER_PROXY_JS); - html_source->AddResourcePath("icons.html", IDR_CLEANUP_TOOL_ICONS_HTML); - html_source->AddResourcePath("manager.html", IDR_CLEANUP_TOOL_MANAGER_HTML); - html_source->AddResourcePath("manager.js", IDR_CLEANUP_TOOL_MANAGER_JS); - html_source->AddResourcePath("toolbar.html", IDR_CLEANUP_TOOL_TOOLBAR_HTML); - html_source->AddResourcePath("toolbar.js", IDR_CLEANUP_TOOL_TOOLBAR_JS); - html_source->SetDefaultResource(IDR_CLEANUP_TOOL_HTML); - - Profile* profile = Profile::FromWebUI(web_ui); - content::WebUIDataSource::Add(profile, html_source); - - web_ui->AddMessageHandler(base::MakeUnique<CleanupActionHandler>()); -} - -CleanupToolUI::~CleanupToolUI() {} diff --git a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.h b/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.h deleted file mode 100644 index c5d2871d209..00000000000 --- a/chromium/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.h +++ /dev/null @@ -1,23 +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 CHROME_BROWSER_UI_WEBUI_CLEANUP_TOOL_CLEANUP_TOOL_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_CLEANUP_TOOL_CLEANUP_TOOL_UI_H_ - -#include "base/macros.h" -#include "content/public/browser/web_ui_controller.h" - -// The UI for chrome://cleanup, which will allow Windows users to see the -// status of the last Chrome Cleanup Tool scan and to manually launch the -// cleanup process. -class CleanupToolUI : public content::WebUIController { - public: - explicit CleanupToolUI(content::WebUI* web_ui); - ~CleanupToolUI() override; - - private: - DISALLOW_COPY_AND_ASSIGN(CleanupToolUI); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_CLEANUP_TOOL_CLEANUP_TOOL_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/components_ui.cc b/chromium/chrome/browser/ui/webui/components_ui.cc index cc6fe4e601b..2fd60e32d82 100644 --- a/chromium/chrome/browser/ui/webui/components_ui.cc +++ b/chromium/chrome/browser/ui/webui/components_ui.cc @@ -241,6 +241,7 @@ base::string16 ComponentsUI::ServiceStatusToString( case update_client::ComponentState::kUpdateError: return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_NOUPDATE); case update_client::ComponentState::kUninstalled: // Fall through. + case update_client::ComponentState::kRun: case update_client::ComponentState::kLastStatus: return l10n_util::GetStringUTF16(IDS_COMPONENTS_UNKNOWN); } diff --git a/chromium/chrome/browser/ui/webui/conflicts_handler.cc b/chromium/chrome/browser/ui/webui/conflicts_handler.cc new file mode 100644 index 00000000000..abfae65137b --- /dev/null +++ b/chromium/chrome/browser/ui/webui/conflicts_handler.cc @@ -0,0 +1,77 @@ +// 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 "chrome/browser/ui/webui/conflicts_handler.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/strings/string16.h" +#include "base/strings/string_number_conversions.h" +#include "base/values.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/web_ui.h" +#include "ui/base/l10n/l10n_util.h" + +ConflictsHandler::ConflictsHandler() : observer_(this) {} +ConflictsHandler::~ConflictsHandler() = default; + +void ConflictsHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "requestModuleList", + base::Bind(&ConflictsHandler::HandleRequestModuleList, + base::Unretained(this))); +} + +void ConflictsHandler::OnScanCompleted() { + SendModuleList(); + observer_.Remove(EnumerateModulesModel::GetInstance()); +} + +void ConflictsHandler::HandleRequestModuleList(const base::ListValue* args) { + auto* model = EnumerateModulesModel::GetInstance(); + // Make sure the JS doesn't call 'requestModuleList' more than once. + // TODO(739291): It would be better to kill the renderer instead of the + // browser for malformed messages. + CHECK(!observer_.IsObserving(model)); + + CHECK_EQ(1U, args->GetSize()); + CHECK(args->GetString(0, &module_list_callback_id_)); + + // The request is handled asynchronously, and will callback via + // OnScanCompleted on completion. + observer_.Add(model); + + // Ask the scan to be performed immediately, and not in background mode. + // This ensures the results are available ASAP for the UI. + model->ScanNow(false); +} + +void ConflictsHandler::SendModuleList() { + auto* loaded_modules = EnumerateModulesModel::GetInstance(); + std::unique_ptr<base::ListValue> list = loaded_modules->GetModuleList(); + + // Add the section title and the total count for bad modules found. + int confirmed_bad = loaded_modules->confirmed_bad_modules_detected(); + int suspected_bad = loaded_modules->suspected_bad_modules_detected(); + base::string16 table_title; + if (!confirmed_bad && !suspected_bad) { + table_title += l10n_util::GetStringFUTF16( + IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_ONE, + base::IntToString16(list->GetSize())); + } else { + table_title += l10n_util::GetStringFUTF16( + IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_TWO, + base::IntToString16(list->GetSize()), + base::IntToString16(confirmed_bad), base::IntToString16(suspected_bad)); + } + base::DictionaryValue results; + results.Set("moduleList", std::move(list)); + results.SetString("modulesTableTitle", table_title); + + AllowJavascript(); + ResolveJavascriptCallback(base::Value(module_list_callback_id_), results); +} diff --git a/chromium/chrome/browser/ui/webui/conflicts_handler.h b/chromium/chrome/browser/ui/webui/conflicts_handler.h new file mode 100644 index 00000000000..495aea7b8a8 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/conflicts_handler.h @@ -0,0 +1,45 @@ +// 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 CHROME_BROWSER_UI_WEBUI_CONFLICTS_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CONFLICTS_HANDLER_H_ + +#include <string> + +#include "base/macros.h" +#include "base/scoped_observer.h" +#include "chrome/browser/win/enumerate_modules_model.h" +#include "content/public/browser/web_ui_message_handler.h" + +// This class takes care of sending the list of all loaded modules to the +// chrome://conflicts WebUI page when it is requested. +class ConflictsHandler : public content::WebUIMessageHandler, + public EnumerateModulesModel::Observer { + public: + ConflictsHandler(); + ~ConflictsHandler() override; + + private: + // content::WebUIMessageHandler: + void RegisterMessages() override; + + // EnumerateModulesModel::Observer: + void OnScanCompleted() override; + + // Callback for the "requestModuleList" message. + void HandleRequestModuleList(const base::ListValue* args); + + // Sends the module list back to the WebUI page. + void SendModuleList(); + + ScopedObserver<EnumerateModulesModel, EnumerateModulesModel::Observer> + observer_; + + // The ID of the callback that will get invoked with the module list. + std::string module_list_callback_id_; + + DISALLOW_COPY_AND_ASSIGN(ConflictsHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_CONFLICTS_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/conflicts_ui.cc b/chromium/chrome/browser/ui/webui/conflicts_ui.cc index 7ed3878e02f..bf8f50a0c4b 100644 --- a/chromium/chrome/browser/ui/webui/conflicts_ui.cc +++ b/chromium/chrome/browser/ui/webui/conflicts_ui.cc @@ -4,45 +4,21 @@ #include "chrome/browser/ui/webui/conflicts_ui.h" -#if defined(OS_WIN) - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted_memory.h" -#include "base/metrics/user_metrics.h" -#include "base/scoped_observer.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/win/enumerate_modules_model.h" +#include "chrome/browser/ui/webui/conflicts_handler.h" +#include "chrome/browser/ui/webui/module_database_conflicts_handler.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/strings/grit/components_strings.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" -#include "content/public/browser/web_ui_message_handler.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/layout.h" #include "ui/base/resource/resource_bundle.h" -using base::UserMetricsAction; -using content::WebContents; -using content::WebUIMessageHandler; - namespace { content::WebUIDataSource* CreateConflictsUIHTMLSource() { @@ -73,94 +49,6 @@ content::WebUIDataSource* CreateConflictsUIHTMLSource() { return source; } -//////////////////////////////////////////////////////////////////////////////// -// -// ConflictsDOMHandler -// -//////////////////////////////////////////////////////////////////////////////// - -// The handler for JavaScript messages for the about:conflicts page. -class ConflictsDOMHandler : public WebUIMessageHandler, - public EnumerateModulesModel::Observer { - public: - ConflictsDOMHandler(); - ~ConflictsDOMHandler() override {} - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // Callback for the "requestModuleList" message. - void HandleRequestModuleList(const base::ListValue* args); - - private: - void SendModuleList(); - - // EnumerateModulesModel::Observer implementation. - void OnScanCompleted() override; - - ScopedObserver<EnumerateModulesModel, - EnumerateModulesModel::Observer> observer_; - - DISALLOW_COPY_AND_ASSIGN(ConflictsDOMHandler); -}; - -ConflictsDOMHandler::ConflictsDOMHandler() - : observer_(this) { -} - -void ConflictsDOMHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("requestModuleList", - base::Bind(&ConflictsDOMHandler::HandleRequestModuleList, - base::Unretained(this))); -} - -void ConflictsDOMHandler::HandleRequestModuleList(const base::ListValue* args) { - // The request is handled asynchronously, and will callback via - // OnScanCompleted on completion. - auto* model = EnumerateModulesModel::GetInstance(); - - // The JS shouldn't be abusive and call 'requestModuleList' twice, but it's - // easy enough to defend against this. - if (!observer_.IsObserving(model)) { - observer_.Add(model); - - // Ask the scan to be performed immediately, and not in background mode. - // This ensures the results are available ASAP for the UI. - model->ScanNow(false); - } -} - -void ConflictsDOMHandler::SendModuleList() { - auto* loaded_modules = EnumerateModulesModel::GetInstance(); - base::ListValue* list = loaded_modules->GetModuleList(); - base::DictionaryValue results; - results.Set("moduleList", list); - - // Add the section title and the total count for bad modules found. - int confirmed_bad = loaded_modules->confirmed_bad_modules_detected(); - int suspected_bad = loaded_modules->suspected_bad_modules_detected(); - base::string16 table_title; - if (!confirmed_bad && !suspected_bad) { - table_title += l10n_util::GetStringFUTF16( - IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_ONE, - base::IntToString16(list->GetSize())); - } else { - table_title += l10n_util::GetStringFUTF16( - IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_TWO, - base::IntToString16(list->GetSize()), - base::IntToString16(confirmed_bad), - base::IntToString16(suspected_bad)); - } - results.SetString("modulesTableTitle", table_title); - - web_ui()->CallJavascriptFunctionUnsafe("returnModuleList", results); -} - -void ConflictsDOMHandler::OnScanCompleted() { - SendModuleList(); - observer_.Remove(EnumerateModulesModel::GetInstance()); -} - } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -169,9 +57,14 @@ void ConflictsDOMHandler::OnScanCompleted() { // /////////////////////////////////////////////////////////////////////////////// -ConflictsUI::ConflictsUI(content::WebUI* web_ui) : WebUIController(web_ui) { - base::RecordAction(UserMetricsAction("ViewAboutConflicts")); - web_ui->AddMessageHandler(base::MakeUnique<ConflictsDOMHandler>()); +ConflictsUI::ConflictsUI(content::WebUI* web_ui) + : content::WebUIController(web_ui) { + if (base::FeatureList::IsEnabled(features::kModuleDatabase)) { + web_ui->AddMessageHandler( + base::MakeUnique<ModuleDatabaseConflictsHandler>()); + } else { + web_ui->AddMessageHandler(base::MakeUnique<ConflictsHandler>()); + } // Set up the about:conflicts source. Profile* profile = Profile::FromWebUI(web_ui); @@ -185,5 +78,3 @@ base::RefCountedMemory* ConflictsUI::GetFaviconResourceBytes( ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( IDR_CONFLICT_FAVICON, scale_factor)); } - -#endif diff --git a/chromium/chrome/browser/ui/webui/conflicts_ui.h b/chromium/chrome/browser/ui/webui/conflicts_ui.h index 46735f1430d..c13d471ed2a 100644 --- a/chromium/chrome/browser/ui/webui/conflicts_ui.h +++ b/chromium/chrome/browser/ui/webui/conflicts_ui.h @@ -6,12 +6,9 @@ #define CHROME_BROWSER_UI_WEBUI_CONFLICTS_UI_H_ #include "base/macros.h" -#include "build/build_config.h" #include "content/public/browser/web_ui_controller.h" #include "ui/base/layout.h" -#if defined(OS_WIN) - namespace base { class RefCountedMemory; } @@ -28,6 +25,4 @@ class ConflictsUI : public content::WebUIController { DISALLOW_COPY_AND_ASSIGN(ConflictsUI); }; -#endif - #endif // CHROME_BROWSER_UI_WEBUI_CONFLICTS_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/crashes_ui.cc b/chromium/chrome/browser/ui/webui/crashes_ui.cc index e2d64ce3337..684c4aa478f 100644 --- a/chromium/chrome/browser/ui/webui/crashes_ui.cc +++ b/chromium/chrome/browser/ui/webui/crashes_ui.cc @@ -20,14 +20,10 @@ #include "chrome/browser/metrics/metrics_reporting_state.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" #include "components/crash/core/browser/crashes_ui_util.h" #include "components/grit/components_resources.h" #include "components/grit/components_scaled_resources.h" -#include "components/strings/grit/components_chromium_strings.h" -#include "components/strings/grit/components_strings.h" #include "components/version_info/version_info.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -70,8 +66,7 @@ content::WebUIDataSource* CreateCrashesUIHTMLSource() { //////////////////////////////////////////////////////////////////////////////// // The handler for Javascript messages for the chrome://crashes/ page. -class CrashesDOMHandler : public WebUIMessageHandler, - public CrashUploadList::Delegate { +class CrashesDOMHandler : public WebUIMessageHandler { public: CrashesDOMHandler(); ~CrashesDOMHandler() override; @@ -79,10 +74,9 @@ class CrashesDOMHandler : public WebUIMessageHandler, // WebUIMessageHandler implementation. void RegisterMessages() override; - // CrashUploadList::Delegate implemenation. - void OnUploadListAvailable() override; - private: + void OnUploadListAvailable(); + // Asynchronously fetches the list of crashes. Called from JS. void HandleRequestCrashes(const base::ListValue* args); @@ -97,7 +91,7 @@ class CrashesDOMHandler : public WebUIMessageHandler, // Asynchronously requests a user triggered upload. Called from JS. void HandleRequestSingleCrashUpload(const base::ListValue* args); - scoped_refptr<CrashUploadList> upload_list_; + scoped_refptr<UploadList> upload_list_; bool list_available_; bool first_load_; @@ -106,15 +100,16 @@ class CrashesDOMHandler : public WebUIMessageHandler, CrashesDOMHandler::CrashesDOMHandler() : list_available_(false), first_load_(true) { - upload_list_ = CreateCrashUploadList(this); + upload_list_ = CreateCrashUploadList(); } CrashesDOMHandler::~CrashesDOMHandler() { - upload_list_->ClearDelegate(); + upload_list_->CancelCallback(); } void CrashesDOMHandler::RegisterMessages() { - upload_list_->LoadUploadListAsynchronously(); + upload_list_->Load(base::BindOnce(&CrashesDOMHandler::OnUploadListAvailable, + base::Unretained(this))); web_ui()->RegisterMessageCallback( crash::kCrashesUIRequestCrashList, base::Bind(&CrashesDOMHandler::HandleRequestCrashes, @@ -140,7 +135,8 @@ void CrashesDOMHandler::HandleRequestCrashes(const base::ListValue* args) { UpdateUI(); } else { list_available_ = false; - upload_list_->LoadUploadListAsynchronously(); + upload_list_->Load(base::BindOnce(&CrashesDOMHandler::OnUploadListAvailable, + base::Unretained(this))); } } @@ -219,7 +215,7 @@ void CrashesDOMHandler::HandleRequestSingleCrashUpload( IsMetricsReportingPolicyManaged()) { return; } - upload_list_->RequestSingleCrashUploadAsync(local_id); + upload_list_->RequestSingleUploadAsync(local_id); } } // namespace diff --git a/chromium/chrome/browser/ui/webui/devtools_ui.cc b/chromium/chrome/browser/ui/webui/devtools_ui.cc index be09da9590a..fb821773188 100644 --- a/chromium/chrome/browser/ui/webui/devtools_ui.cc +++ b/chromium/chrome/browser/ui/webui/devtools_ui.cc @@ -15,8 +15,6 @@ #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_frontend_host.h" -#include "content/public/browser/site_instance.h" -#include "content/public/browser/storage_partition.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -27,7 +25,6 @@ #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request_context_getter.h" -#include "storage/browser/fileapi/file_system_context.h" #include "third_party/WebKit/public/public_features.h" using content::BrowserThread; @@ -351,13 +348,6 @@ DevToolsUI::DevToolsUI(content::WebUI* web_ui) content::URLDataSource::Add( profile, new DevToolsDataSource(profile->GetRequestContext())); - - if (!profile->IsOffTheRecord()) - return; - GURL url = web_ui->GetWebContents()->GetVisibleURL(); - GURL site = content::SiteInstance::GetSiteForURL(profile, url); - content::BrowserContext::GetStoragePartitionForSite(profile, site)-> - GetFileSystemContext()->EnableTemporaryFileSystemInIncognito(); } DevToolsUI::~DevToolsUI() { diff --git a/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.cc b/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.cc index 28d701104f0..89cf68b124e 100644 --- a/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.cc +++ b/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.cc @@ -93,7 +93,6 @@ SiteEngagementUI::SiteEngagementUI(content::WebUI* web_ui) SiteEngagementUI::~SiteEngagementUI() {} void SiteEngagementUI::BindUIHandler( - const service_manager::BindSourceInfo& source_info, mojom::SiteEngagementDetailsProviderRequest request) { ui_handler_.reset(new SiteEngagementDetailsProviderImpl( Profile::FromWebUI(web_ui()), std::move(request))); diff --git a/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.h b/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.h index d7a0c0faab6..3c26b626623 100644 --- a/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.h +++ b/chromium/chrome/browser/ui/webui/engagement/site_engagement_ui.h @@ -19,7 +19,6 @@ class SiteEngagementUI private: // MojoWebUIController overrides: void BindUIHandler( - const service_manager::BindSourceInfo& source_info, mojom::SiteEngagementDetailsProviderRequest request) override; std::unique_ptr<mojom::SiteEngagementDetailsProvider> ui_handler_; diff --git a/chromium/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js b/chromium/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js index 5a7b9f29924..a0314cf521e 100644 --- a/chromium/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js +++ b/chromium/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js @@ -17,7 +17,7 @@ KioskAppSettingsWebUITest.prototype = { /** * Browse to the kiosk app settings page. */ - browsePreload: 'chrome://extensions-frame/', + browsePreload: 'chrome://extensions/', /** @override */ commandLineSwitches: [{ diff --git a/chromium/chrome/browser/ui/webui/extensions/extension_loader_handler.cc b/chromium/chrome/browser/ui/webui/extensions/extension_loader_handler.cc index 8bafdd5a1af..e3448f3c777 100644 --- a/chromium/chrome/browser/ui/webui/extensions/extension_loader_handler.cc +++ b/chromium/chrome/browser/ui/webui/extensions/extension_loader_handler.cc @@ -18,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/task_scheduler/post_task.h" #include "base/values.h" -#include "chrome/browser/extensions/path_util.h" #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/profiles/profile.h" #include "chrome/grit/generated_resources.h" @@ -28,6 +27,7 @@ #include "content/public/browser/web_ui_data_source.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/file_highlighter.h" +#include "extensions/browser/path_util.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_constants.h" diff --git a/chromium/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js b/chromium/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js index 3bf00fe3c22..32a910b40a9 100644 --- a/chromium/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js +++ b/chromium/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js @@ -44,7 +44,7 @@ ExtensionSettingsWebUITest.prototype = { * @type {string} * @const */ - browsePreload: 'chrome://extensions-frame/', + browsePreload: 'chrome://extensions/', /** @override */ typedefCppFixture: 'ExtensionSettingsUIBrowserTest', @@ -299,7 +299,7 @@ AutoScrollExtensionSettingsWebUITest.prototype = { __proto__: BasicExtensionSettingsWebUITest.prototype, /** @override */ - browsePreload: 'chrome://extensions-frame/?id=' + GOOD_EXTENSION_ID, + browsePreload: 'chrome://extensions/?id=' + GOOD_EXTENSION_ID, /** @override */ testGenPreamble: function() { @@ -312,19 +312,20 @@ AutoScrollExtensionSettingsWebUITest.prototype = { TEST_F('AutoScrollExtensionSettingsWebUITest', 'testAutoScroll', function() { var checkHasScrollbar = function() { - assertGT(document.body.scrollHeight, document.body.clientHeight); + assertGT(document.scrollingElement.scrollHeight, + document.body.clientHeight); this.nextStep(); }; var checkIsScrolled = function() { - assertGT(document.body.scrollTop, 0); + assertGT(document.scrollingElement.scrollTop, 0); this.nextStep(); }; var checkScrolledToTop = function() { - assertEquals(0, document.body.scrollTop); + assertEquals(0, document.scrollingElement.scrollTop); this.nextStep(); }; var scrollToTop = function() { - document.body.scrollTop = 0; + document.scrollingElement.scrollTop = 0; this.nextStep(); }; // Test that a) autoscroll works on first page load and b) updating the @@ -398,7 +399,7 @@ SettingsCommandsExtensionSettingsWebUITest.prototype = { * @type {string} * @const */ - browsePreload: 'chrome://extensions-frame/configureCommands', + browsePreload: 'chrome://extensions/configureCommands', }; TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'testChromeSendHandler', @@ -421,8 +422,7 @@ TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'extensionSettingsUri', assertTrue($('extension-commands-overlay').classList.contains('showing')); assertEquals($('extension-commands-overlay').getAttribute('aria-hidden'), 'false'); - assertEquals(window.location.href, - 'chrome://extensions-frame/configureCommands'); + assertEquals(window.location.href, 'chrome://extensions/configureCommands'); // Close command overlay. $('extension-commands-dismiss').click(); @@ -436,7 +436,7 @@ TEST_F('SettingsCommandsExtensionSettingsWebUITest', 'extensionSettingsUri', var checkExtensionsUrl = function() { // After closing the overlay, the URL shouldn't include commands overlay // reference. - assertEquals(window.location.href, 'chrome://extensions-frame/'); + assertEquals(window.location.href, 'chrome://extensions/'); this.nextStep(); }; @@ -516,6 +516,14 @@ function OptionsDialogExtensionSettingsWebUITest() {} OptionsDialogExtensionSettingsWebUITest.prototype = { __proto__: InstallGoodExtensionSettingsWebUITest.prototype, + setUp() { + InstallGoodExtensionSettingsWebUITest.prototype.setUp.call(this); + + // False positive on iframe hosting the <extensionoptions> guest view. + this.accessibilityAuditConfig.ignoreSelectors( + 'focusableElementNotVisibleAndNotAriaHidden', 'iframe'); + }, + /** @override */ browsePreload: ExtensionSettingsWebUITest.prototype.browsePreload + '?options=' + GOOD_EXTENSION_ID, diff --git a/chromium/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chromium/chrome/browser/ui/webui/extensions/extension_settings_handler.cc index 7ecfc696862..a62c8587add 100644 --- a/chromium/chrome/browser/ui/webui/extensions/extension_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/extensions/extension_settings_handler.cc @@ -16,10 +16,8 @@ #include "chrome/common/features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" #include "components/google/core/browser/google_util.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" @@ -171,8 +169,6 @@ void ExtensionSettingsHandler::GetLocalizedValues( google_util::AppendGoogleLocaleParam( GURL(chrome::kRemoveNonCWSExtensionURL), g_browser_process->GetApplicationLocale()).spec())); - source->AddString("extensionSettingsShowButton", - l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_BUTTON)); source->AddString("extensionSettingsLoadUnpackedButton", l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_UNPACKED_BUTTON)); source->AddString("extensionSettingsPackButton", diff --git a/chromium/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chromium/chrome/browser/ui/webui/extensions/extensions_ui.cc index 7ae6d563e79..f6b72930024 100644 --- a/chromium/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chromium/chrome/browser/ui/webui/extensions/extensions_ui.cc @@ -24,6 +24,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/google/core/browser/google_util.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -106,6 +107,10 @@ content::WebUIDataSource* CreateMdExtensionsSource() { source->SetJsonPath("strings.js"); + // Add common strings. + source->AddLocalizedString("close", IDS_CLOSE); + + // Add extension-specific strings. source->AddLocalizedString("title", IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE); source->AddLocalizedString("toolbarTitle", IDS_MD_EXTENSIONS_TOOLBAR_TITLE); @@ -115,6 +120,10 @@ content::WebUIDataSource* CreateMdExtensionsSource() { source->AddLocalizedString("sidebarApps", IDS_MD_EXTENSIONS_SIDEBAR_APPS); source->AddLocalizedString("sidebarExtensions", IDS_MD_EXTENSIONS_SIDEBAR_EXTENSIONS); + source->AddLocalizedString("noExtensionsOrApps", + IDS_MD_EXTENSIONS_NO_INSTALLED_ITEMS); + source->AddLocalizedString("noSearchResults", + IDS_MD_EXTENSIONS_NO_SEARCH_RESULTS); source->AddLocalizedString("dropToInstall", IDS_EXTENSIONS_INSTALL_DROP_TARGET); source->AddLocalizedString("errorsPageHeading", @@ -310,7 +319,7 @@ content::WebUIDataSource* CreateMdExtensionsSource() { content::WebUIDataSource* CreateExtensionsHTMLSource() { content::WebUIDataSource* source = - content::WebUIDataSource::Create(chrome::kChromeUIExtensionsFrameHost); + content::WebUIDataSource::Create(chrome::kChromeUIExtensionsHost); source->SetJsonPath("strings.js"); source->AddResourcePath("extensions.js", IDR_EXTENSIONS_JS); diff --git a/chromium/chrome/browser/ui/webui/fallback_icon_source.cc b/chromium/chrome/browser/ui/webui/fallback_icon_source.cc deleted file mode 100644 index 7fbe9f32a12..00000000000 --- a/chromium/chrome/browser/ui/webui/fallback_icon_source.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2015 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 "chrome/browser/ui/webui/fallback_icon_source.h" - -#include <vector> - -#include "base/memory/ref_counted_memory.h" -#include "chrome/browser/search/instant_io_context.h" -#include "chrome/common/url_constants.h" -#include "components/favicon/core/fallback_icon_service.h" -#include "components/favicon_base/fallback_icon_url_parser.h" -#include "components/keyed_service/core/service_access_type.h" -#include "net/url_request/url_request.h" -#include "ui/gfx/favicon_size.h" -#include "url/gurl.h" - -FallbackIconSource::FallbackIconSource( - favicon::FallbackIconService* fallback_icon_service) - : fallback_icon_service_(fallback_icon_service) { -} - -FallbackIconSource::~FallbackIconSource() { -} - -std::string FallbackIconSource::GetSource() const { - return chrome::kChromeUIFallbackIconHost; -} - -void FallbackIconSource::StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) { - chrome::ParsedFallbackIconPath parsed; - bool success = parsed.Parse(path); - if (!success) { - SendDefaultResponse(callback); - return; - } - - GURL url(parsed.url_string()); - if (url.is_empty() || !url.is_valid()) { - SendDefaultResponse(callback); - return; - } - - SendFallbackIconHelper( - url, parsed.size_in_pixels(), parsed.style(), callback); -} - -std::string FallbackIconSource::GetMimeType(const std::string&) const { - // We need to explicitly return a mime type, otherwise if the user tries to - // drag the image they get no extension. - return "image/png"; -} - -bool FallbackIconSource::AllowCaching() const { - return false; -} - -bool FallbackIconSource::ShouldReplaceExistingSource() const { - // Leave the existing DataSource in place, otherwise we'll drop any pending - // requests on the floor. - return false; -} - -bool FallbackIconSource::ShouldServiceRequest( - const GURL& url, - content::ResourceContext* resource_context, - int render_process_id) const { - if (url.SchemeIs(chrome::kChromeSearchScheme)) { - return InstantIOContext::ShouldServiceRequest(url, resource_context, - render_process_id); - } - return URLDataSource::ShouldServiceRequest(url, resource_context, - render_process_id); -} - -void FallbackIconSource::SendFallbackIconHelper( - const GURL& url, - int size_in_pixels, - const favicon_base::FallbackIconStyle& style, - const content::URLDataSource::GotDataCallback& callback) { - if (!fallback_icon_service_) { // Can be null for tests. - callback.Run(nullptr); // Trigger "Not Found" response. - return; - } - std::vector<unsigned char> bitmap_data = - fallback_icon_service_->RenderFallbackIconBitmap( - url, size_in_pixels, style); - callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data)); -} - -void FallbackIconSource::SendDefaultResponse( - const content::URLDataSource::GotDataCallback& callback) { - favicon_base::FallbackIconStyle default_style; - SendFallbackIconHelper(GURL(), gfx::kFaviconSize, default_style, callback); -} diff --git a/chromium/chrome/browser/ui/webui/fallback_icon_source.h b/chromium/chrome/browser/ui/webui/fallback_icon_source.h deleted file mode 100644 index 5526f77a0c5..00000000000 --- a/chromium/chrome/browser/ui/webui/fallback_icon_source.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2015 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 CHROME_BROWSER_UI_WEBUI_FALLBACK_ICON_SOURCE_H_ -#define CHROME_BROWSER_UI_WEBUI_FALLBACK_ICON_SOURCE_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "content/public/browser/url_data_source.h" - -class GURL; - -namespace favicon_base { -struct FallbackIconStyle; -} - -namespace favicon { -class FallbackIconService; -} - -// FallbackIconSource services explicit chrome:// requests for fallback icons. -// -// Format: -// chrome://fallback-icon/size,bc,tc,fsr,r/url -// All of the parameters except for the url are optional. However, the order of -// the parameters is not interchangeable, and all "," must be in place. -// -// Parameter: -// 'size' -// Positive integer to specify the fallback icon's size in pixels. -// 'bc' -// Fallback icon's background color, as named CSS color, or RGB / ARGB / -// RRGGBB / AARRGGBB hex formats (no leading "#"). -// 'tc' -// Fallback icon text color, as named CSS color, or RGB / ARGB / RRGGBB / -// AARRGGBB hex formats (no leading "#"). -// 'fsr' -// Number in [0.0, 1.0] to specify the fallback icon's font size (pixels) -// as a ratio to the icon's size. -// 'r' -// Number in [0.0, 1.0] to specify the fallback icon's roundness. -// 0.0 specifies a square icon; 1.0 specifies a circle icon; intermediate -// values specify a rounded square icon. -// 'url' -// String to specify the page URL of the fallback icon. -// -// Example: chrome://fallback-icon/32,red,#000,0.5,1.0/http://www.google.com/ -// This requests a 32x32 fallback icon for http://www.google.com, using -// red as the background color, #000 as the text color, with font size of -// 32 * 0.5 = 16, and the icon's background shape is a circle. -class FallbackIconSource : public content::URLDataSource { - public: - // |fallback_icon_service| is owned by caller, and may be null. - explicit FallbackIconSource( - favicon::FallbackIconService* fallback_icon_service); - - ~FallbackIconSource() override; - - // content::URLDataSource implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) override; - std::string GetMimeType(const std::string&) const override; - bool AllowCaching() const override; - bool ShouldReplaceExistingSource() const override; - bool ShouldServiceRequest(const GURL& url, - content::ResourceContext* resource_context, - int render_process_id) const override; - - private: - void SendFallbackIconHelper( - const GURL& url, - int size_in_pixels, - const favicon_base::FallbackIconStyle& style, - const content::URLDataSource::GotDataCallback& callback); - - // Sends the default fallback icon. - void SendDefaultResponse( - const content::URLDataSource::GotDataCallback& callback); - - favicon::FallbackIconService* fallback_icon_service_; - - DISALLOW_COPY_AND_ASSIGN(FallbackIconSource); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_FALLBACK_ICON_SOURCE_H_ diff --git a/chromium/chrome/browser/ui/webui/flags_ui.cc b/chromium/chrome/browser/ui/webui/flags_ui.cc index 75db64526c2..293a1418a99 100644 --- a/chromium/chrome/browser/ui/webui/flags_ui.cc +++ b/chromium/chrome/browser/ui/webui/flags_ui.cc @@ -101,7 +101,6 @@ content::WebUIDataSource* CreateFlagsUIHTMLSource() { } #endif - source->SetJsonPath("strings.js"); source->AddResourcePath(flags_ui::kFlagsJS, IDR_FLAGS_UI_FLAGS_JS); source->SetDefaultResource(IDR_FLAGS_UI_FLAGS_HTML); return source; @@ -175,7 +174,7 @@ void FlagsDOMHandler::Init(flags_ui::FlagsStorage* flags_storage, access_ = access; if (experimental_features_requested_) - HandleRequestExperimentalFeatures(NULL); + HandleRequestExperimentalFeatures(nullptr); } void FlagsDOMHandler::HandleRequestExperimentalFeatures( diff --git a/chromium/chrome/browser/ui/webui/flash_ui.cc b/chromium/chrome/browser/ui/webui/flash_ui.cc index 451ca502ba9..19b2ec96add 100644 --- a/chromium/chrome/browser/ui/webui/flash_ui.cc +++ b/chromium/chrome/browser/ui/webui/flash_ui.cc @@ -87,7 +87,6 @@ const int kTimeout = 8 * 1000; // 8 seconds. // The handler for JavaScript messages for the about:flags page. class FlashDOMHandler : public WebUIMessageHandler, - public CrashUploadList::Delegate, public content::GpuDataManagerObserver { public: FlashDOMHandler(); @@ -96,9 +95,6 @@ class FlashDOMHandler : public WebUIMessageHandler, // WebUIMessageHandler implementation. void RegisterMessages() override; - // CrashUploadList::Delegate implementation. - void OnUploadListAvailable() override; - // GpuDataManager::Observer implementation. void OnGpuInfoUpdate() override; @@ -109,6 +105,9 @@ class FlashDOMHandler : public WebUIMessageHandler, void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins); private: + // UploadList callback. + void OnUploadListAvailable(); + // Called when we think we might have enough information to return data back // to the page. void MaybeRespondToPage(); @@ -124,7 +123,7 @@ class FlashDOMHandler : public WebUIMessageHandler, base::OneShotTimer timeout_; // Crash list. - scoped_refptr<CrashUploadList> upload_list_; + scoped_refptr<UploadList> upload_list_; // Whether the list of all crashes is available. bool crash_list_available_; @@ -146,9 +145,10 @@ FlashDOMHandler::FlashDOMHandler() has_gpu_info_(false), has_plugin_info_(false), weak_ptr_factory_(this) { - // Request Crash data asynchronously. - upload_list_ = CreateCrashUploadList(this); - upload_list_->LoadUploadListAsynchronously(); + // Request Crash data asynchronously. + upload_list_ = CreateCrashUploadList(); + upload_list_->Load(base::BindOnce(&FlashDOMHandler::OnUploadListAvailable, + weak_ptr_factory_.GetWeakPtr())); // Watch for changes in GPUInfo. GpuDataManager::GetInstance()->AddObserver(this); @@ -157,23 +157,23 @@ FlashDOMHandler::FlashDOMHandler() // GPU process has not run yet, this will trigger its launch. GpuDataManager::GetInstance()->RequestCompleteGpuInfoIfNeeded(); - // GPU access might not be allowed at all, which will cause us not to get a - // call back. + // GPU access might not be allowed at all, which will cause us not to + // get a call back. if (!GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) OnGpuInfoUpdate(); PluginService::GetInstance()->GetPlugins(base::Bind( &FlashDOMHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr())); - // And lastly, we fire off a timer to make sure we never get stuck at the - // "Loading..." message. + // And lastly, we fire off a timer to make sure we never get stuck at + // the "Loading..." message. timeout_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeout), this, &FlashDOMHandler::OnTimeout); } FlashDOMHandler::~FlashDOMHandler() { GpuDataManager::GetInstance()->RemoveObserver(this); - upload_list_->ClearDelegate(); + upload_list_->CancelCallback(); } void FlashDOMHandler::RegisterMessages() { @@ -303,10 +303,10 @@ void FlashDOMHandler::MaybeRespondToPage() { bool crash_reporting_enabled = ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); if (crash_reporting_enabled) { - std::vector<CrashUploadList::UploadInfo> crashes; + std::vector<UploadList::UploadInfo> crashes; upload_list_->GetUploads(10, &crashes); - for (std::vector<CrashUploadList::UploadInfo>::iterator i = crashes.begin(); + for (std::vector<UploadList::UploadInfo>::iterator i = crashes.begin(); i != crashes.end(); ++i) { base::string16 crash_string(ASCIIToUTF16(i->upload_id)); crash_string += ASCIIToUTF16(" "); diff --git a/chromium/chrome/browser/ui/webui/help/help_browsertest.js b/chromium/chrome/browser/ui/webui/help/help_browsertest.js deleted file mode 100644 index 45bd2727897..00000000000 --- a/chromium/chrome/browser/ui/webui/help/help_browsertest.js +++ /dev/null @@ -1,147 +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. - -/** - * TestFixture for extension settings WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function HelpPageWebUITest() {} - -HelpPageWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - runAccessibilityChecks: true, - - /** @override */ - accessibilityIssuesAreErrors: true, - - browsePreload: 'chrome://help-frame/', -}; - -// Test opening extension settings has correct location. -TEST_F('HelpPageWebUITest', 'testOpenHelpPage', function() { - assertEquals(this.browsePreload, document.location.href); -}); - -GEN('#if defined(OS_LINUX) || defined(GOOGLE_CHROME_BUILD)'); - -TEST_F('HelpPageWebUITest', 'testUpdateStateIcon', function() { - var icon = $('update-status-icon'); - help.HelpPage.setUpdateStatus('checking', ''); - assertEquals(icon.getAttribute('class'), 'help-page-icon working'); - help.HelpPage.setUpdateStatus('updating', ''); - assertEquals(icon.getAttribute('class'), 'help-page-icon working'); - help.HelpPage.setUpdateStatus('nearly_updated', ''); - assertEquals(icon.getAttribute('class'), 'help-page-icon up-to-date'); - help.HelpPage.setUpdateStatus('updated', ''); - assertEquals(icon.getAttribute('class'), 'help-page-icon up-to-date'); - help.HelpPage.setUpdateStatus('failed', ''); - assertEquals(icon.getAttribute('class'), 'help-page-icon failed'); - help.HelpPage.setUpdateStatus('disabled_by_admin', ''); - assertEquals(icon.getAttribute('class'), 'help-page-icon disabled-by-admin'); -}); - -// Test that repeated calls to setUpdateStatus work. -TEST_F('HelpPageWebUITest', 'testUpdateState', function() { - var relaunch = $('relaunch'); - var container = $('update-status-container'); - var update = $('request-update'); - - help.HelpPage.setUpdateStatus('updated', ''); - expectTrue(relaunch.hidden); - expectTrue(cr.isChromeOS == container.hidden); - expectTrue(!cr.isChromeOS || !update.hidden && !update.disabled); - - help.HelpPage.setUpdateStatus('disabled', ''); - expectTrue(relaunch.hidden); - expectTrue(container.hidden); - expectTrue(!cr.isChromeOS || update.hidden); - - help.HelpPage.setUpdateStatus('nearly_updated', ''); - expectTrue(!relaunch.hidden); - expectTrue(!container.hidden); - expectTrue(!cr.isChromeOS || update.hidden); - - help.HelpPage.setUpdateStatus('disabled', ''); - expectTrue($('relaunch').hidden); - expectTrue($('update-status-container').hidden); - expectTrue(!cr.isChromeOS || update.hidden); -}); - -GEN('#endif'); - -GEN('#if defined(OS_CHROMEOS)'); - -// Test that the request update button is shown and hidden properly. -TEST_F('HelpPageWebUITest', 'testRequestUpdate', function() { - var container = $('update-status-container'); - var update = $('request-update'); - var policyIcon = $('controlled-feature-icon'); - - help.HelpPage.setUpdateStatus('updated', ''); - expectTrue(container.hidden); - expectTrue(!update.hidden && !update.disabled); - expectTrue(policyIcon.hidden); - - update.click(); - expectTrue(!update.hidden && update.disabled); - expectFalse(container.hidden); - expectTrue(policyIcon.hidden); - - help.HelpPage.setUpdateStatus('checking', ''); - expectFalse(container.hidden); - expectTrue(!update.hidden && update.disabled); - expectTrue(policyIcon.hidden); - - help.HelpPage.setUpdateStatus('failed', 'Error'); - expectFalse(container.hidden); - expectTrue(!update.hidden && !update.disabled); - expectTrue(policyIcon.hidden); - - update.click(); - help.HelpPage.setUpdateStatus('checking', ''); - expectFalse(container.hidden); - expectTrue(!update.hidden && update.disabled); - expectTrue(policyIcon.hidden); - - help.HelpPage.setUpdateStatus('nearly_updated', ''); - expectFalse(container.hidden); - expectTrue(update.hidden); - expectTrue(policyIcon.hidden); - - help.HelpPage.setUpdateStatus('updated', ''); - expectFalse(container.hidden); - expectTrue(!update.hidden && update.disabled); - expectTrue(policyIcon.hidden); - - help.HelpPage.setUpdateStatus('disabled_by_admin', ''); - expectTrue(container.hidden); - expectTrue(!update.hidden && update.disabled); - expectFalse(policyIcon.hidden); -}); - -// Test that the EndofLife String is shown and hidden properly. -TEST_F('HelpPageWebUITest', 'testUpdateEolMessage', function() { - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/570563 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#eol-learnMore > A'); - - var updateStatusContainer = $('update-status-container'); - var update = $('request-update'); - var eolStatusContainer = $('eol-status-container'); - - help.HelpPage.updateEolMessage('device_supported', ''); - expectTrue(eolStatusContainer.hidden); - - help.HelpPage.updateEolMessage('device_endoflife', ''); - expectFalse(eolStatusContainer.hidden); - expectTrue(update.disabled); - expectTrue(updateStatusContainer.hidden); -}); - -GEN('#endif'); diff --git a/chromium/chrome/browser/ui/webui/help/help_handler.cc b/chromium/chrome/browser/ui/webui/help/help_handler.cc index 6f729d1651b..2a26fa57a75 100644 --- a/chromium/chrome/browser/ui/webui/help/help_handler.cc +++ b/chromium/chrome/browser/ui/webui/help/help_handler.cc @@ -26,13 +26,13 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/obsolete_system/obsolete_system.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/upgrade_detector.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/pref_names.h" @@ -46,7 +46,6 @@ #include "components/strings/grit/components_strings.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "ui/base/l10n/l10n_util.h" @@ -139,7 +138,7 @@ bool CanChangeChannel(Profile* profile) { domain = email.substr(email.find('@') + 1); policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return domain == connector->GetEnterpriseDomain(); + return domain == connector->GetEnterpriseEnrollmentDomain(); } else { chromeos::OwnerSettingsServiceChromeOS* service = chromeos::OwnerSettingsServiceChromeOSFactory::GetInstance() @@ -207,12 +206,15 @@ std::string ReadRegulatoryLabelText(const base::FilePath& path) { HelpHandler::HelpHandler() : policy_registrar_( - g_browser_process->policy_service(), - policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())), + g_browser_process->policy_service(), + policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())), + apply_changes_from_upgrade_observer_(false), weak_factory_(this) { + UpgradeDetector::GetInstance()->AddObserver(this); } HelpHandler::~HelpHandler() { + UpgradeDetector::GetInstance()->RemoveObserver(this); } void HelpHandler::GetLocalizedValues(base::DictionaryValue* localized_strings) { @@ -374,8 +376,7 @@ void HelpHandler::GetLocalizedValues(base::DictionaryValue* localized_strings) { void HelpHandler::RegisterMessages() { version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents())); - registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, - content::NotificationService::AllSources()); + apply_changes_from_upgrade_observer_ = true; policy_registrar_.Observe( policy::key::kDeviceAutoUpdateDisabled, base::Bind(&HelpHandler::OnDeviceAutoUpdatePolicyChanged, @@ -409,13 +410,12 @@ void HelpHandler::RegisterMessages() { #endif } -void HelpHandler::Observe(int type, const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type); - - // A version update is installed and ready to go. Refresh the UI so the - // correct state will be shown. - RequestUpdate(nullptr); +void HelpHandler::OnUpgradeRecommended() { + if (apply_changes_from_upgrade_observer_) { + // A version update is installed and ready to go. Refresh the UI so the + // correct state will be shown. + RequestUpdate(nullptr); + } } // static diff --git a/chromium/chrome/browser/ui/webui/help/help_handler.h b/chromium/chrome/browser/ui/webui/help/help_handler.h index 82b088bb8a0..5aea40c2f0c 100644 --- a/chromium/chrome/browser/ui/webui/help/help_handler.h +++ b/chromium/chrome/browser/ui/webui/help/help_handler.h @@ -13,9 +13,8 @@ #include "base/strings/string16.h" #include "build/build_config.h" #include "chrome/browser/ui/webui/help/version_updater.h" +#include "chrome/browser/upgrade_observer.h" #include "components/policy/core/common/policy_service.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_ui_message_handler.h" #if defined(OS_CHROMEOS) @@ -32,7 +31,7 @@ class ListValue; // WebUI message handler for the help page. class HelpHandler : public content::WebUIMessageHandler, - public content::NotificationObserver { + public UpgradeObserver { public: HelpHandler(); ~HelpHandler() override; @@ -43,10 +42,8 @@ class HelpHandler : public content::WebUIMessageHandler, // Adds string values for the UI to |localized_strings|. static void GetLocalizedValues(base::DictionaryValue* localized_strings); - // NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // UpgradeObserver implementation. + void OnUpgradeRecommended() override; // Returns the browser version as a string. static base::string16 BuildBrowserVersionString(); @@ -124,12 +121,12 @@ class HelpHandler : public content::WebUIMessageHandler, // Specialized instance of the VersionUpdater used to update the browser. std::unique_ptr<VersionUpdater> version_updater_; - // Used to observe notifications. - content::NotificationRegistrar registrar_; - // Used to observe changes in the |kDeviceAutoUpdateDisabled| policy. policy::PolicyChangeRegistrar policy_registrar_; + // If true changes to UpgradeObserver are applied, if false they are ignored. + bool apply_changes_from_upgrade_observer_; + // Used for callbacks. base::WeakPtrFactory<HelpHandler> weak_factory_; diff --git a/chromium/chrome/browser/ui/webui/help/help_ui.cc b/chromium/chrome/browser/ui/webui/help/help_ui.cc deleted file mode 100644 index 440fc7218ac..00000000000 --- a/chromium/chrome/browser/ui/webui/help/help_ui.cc +++ /dev/null @@ -1,46 +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 "chrome/browser/ui/webui/help/help_ui.h" - -#include "base/memory/ptr_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/help/help_handler.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" -#include "chrome/grit/theme_resources.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" - -namespace { - -content::WebUIDataSource* CreateAboutPageHTMLSource() { - content::WebUIDataSource* source = - content::WebUIDataSource::Create(chrome::kChromeUIHelpFrameHost); - source->SetJsonPath("strings.js"); - source->AddResourcePath("help.js", IDR_HELP_JS); - source->AddResourcePath("help_page.js", IDR_HELP_PAGE_JS); - source->AddResourcePath("channel_change_page.js", IDR_CHANNEL_CHANGE_PAGE_JS); - source->SetDefaultResource(IDR_HELP_HTML); - source->DisableDenyXFrameOptions(); - return source; -} - -} // namespace - -HelpUI::HelpUI(content::WebUI* web_ui) - : WebUIController(web_ui) { - Profile* profile = Profile::FromWebUI(web_ui); - content::WebUIDataSource* source = CreateAboutPageHTMLSource(); - - base::DictionaryValue localized_strings; - HelpHandler::GetLocalizedValues(&localized_strings); - source->AddLocalizedStrings(localized_strings); - content::WebUIDataSource::Add(profile, source); - web_ui->AddMessageHandler(base::MakeUnique<HelpHandler>()); -} - -HelpUI::~HelpUI() { -} diff --git a/chromium/chrome/browser/ui/webui/help/help_ui.h b/chromium/chrome/browser/ui/webui/help/help_ui.h deleted file mode 100644 index c2b8aca5c14..00000000000 --- a/chromium/chrome/browser/ui/webui/help/help_ui.h +++ /dev/null @@ -1,20 +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 CHROME_BROWSER_UI_WEBUI_HELP_HELP_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_HELP_HELP_UI_H_ - -#include "base/macros.h" -#include "content/public/browser/web_ui_controller.h" - -class HelpUI : public content::WebUIController { - public: - explicit HelpUI(content::WebUI* web_ui); - ~HelpUI() override; - - private: - DISALLOW_COPY_AND_ASSIGN(HelpUI); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_HELP_HELP_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/help/help_utils_chromeos.cc b/chromium/chrome/browser/ui/webui/help/help_utils_chromeos.cc index ea4884ec15f..068f3586a9a 100644 --- a/chromium/chrome/browser/ui/webui/help/help_utils_chromeos.cc +++ b/chromium/chrome/browser/ui/webui/help/help_utils_chromeos.cc @@ -63,8 +63,10 @@ base::string16 GetConnectionTypeAsUTF16(const chromeos::NetworkState* network) { return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_WIMAX); if (type == shill::kTypeBluetooth) return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_BLUETOOTH); - if (type == shill::kTypeCellular) - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_CELLULAR); + if (type == shill::kTypeCellular || + chromeos::NetworkTypePattern::Tether().MatchesType(type)) { + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_MOBILE_DATA); + } if (type == shill::kTypeVPN) return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_VPN); NOTREACHED(); diff --git a/chromium/chrome/browser/ui/webui/help/version_updater_win.cc b/chromium/chrome/browser/ui/webui/help/version_updater_win.cc index 43bcd5945b4..861526eea8a 100644 --- a/chromium/chrome/browser/ui/webui/help/version_updater_win.cc +++ b/chromium/chrome/browser/ui/webui/help/version_updater_win.cc @@ -5,10 +5,8 @@ #include "chrome/browser/ui/webui/help/version_updater_win.h" #include "base/memory/weak_ptr.h" -#include "base/task_runner_util.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/win/win_util.h" -#include "base/win/windows_version.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/first_run/upgrade_util.h" #include "chrome/grit/generated_resources.h" @@ -31,45 +29,28 @@ void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback, // There is no supported integration with Google Update for Chromium. callback_ = callback; - // On-demand updates for Chrome don't work in Vista RTM when UAC is turned - // off. So, in this case, the version updater must not mention - // on-demand updates. Silent updates (in the background) should still - // work as before - enabling UAC or installing the latest service pack - // for Vista is another option. - if (!(base::win::GetVersion() == base::win::VERSION_VISTA && - (base::win::OSInfo::GetInstance()->service_pack().major == 0) && - !base::win::UserAccountControlIsEnabled())) { - callback_.Run(CHECKING, 0, std::string(), 0, base::string16()); - BeginUpdateCheckOnFileThread(false /* !install_update_if_possible */); - } + callback_.Run(CHECKING, 0, std::string(), 0, base::string16()); + DoBeginUpdateCheck(false /* !install_update_if_possible */); } void VersionUpdaterWin::OnUpdateCheckComplete( const base::string16& new_version) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - Status status = CHECKING; if (new_version.empty()) { // Google Update says that no new version is available. Check to see if a // restart is needed for a previously-applied update to take effect. - if (base::PostTaskAndReplyWithResult( - content::BrowserThread::GetBlockingPool(), - FROM_HERE, - base::Bind(&upgrade_util::IsUpdatePendingRestart), - base::Bind(&VersionUpdaterWin::OnPendingRestartCheck, - weak_factory_.GetWeakPtr()))) { - // Early exit since callback_ will be Run in OnPendingRestartCheck. - return; - } - // Failure to post the task means that Chrome is shutting down. A pending - // update (if there is one) will be applied as Chrome exits, so tell the - // caller that it is up to date in either case. - status = UPDATED; - } else { - // Notify the caller that the update is now beginning and initiate it. - status = UPDATING; - BeginUpdateCheckOnFileThread(true /* install_update_if_possible */); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, + base::Bind(&upgrade_util::IsUpdatePendingRestart), + base::Bind(&VersionUpdaterWin::OnPendingRestartCheck, + weak_factory_.GetWeakPtr())); + // Early exit since callback_ will be Run in OnPendingRestartCheck. + return; } - callback_.Run(status, 0, std::string(), 0, base::string16()); + + // Notify the caller that the update is now beginning and initiate it. + DoBeginUpdateCheck(true /* install_update_if_possible */); + callback_.Run(UPDATING, 0, std::string(), 0, base::string16()); } void VersionUpdaterWin::OnUpgradeProgress(int progress, @@ -114,13 +95,10 @@ void VersionUpdaterWin::OnError(GoogleUpdateErrorCode error_code, callback_.Run(status, 0, std::string(), 0, message); } -void VersionUpdaterWin::BeginUpdateCheckOnFileThread( - bool install_update_if_possible) { +void VersionUpdaterWin::DoBeginUpdateCheck(bool install_update_if_possible) { // Disconnect from any previous attempts to avoid redundant callbacks. weak_factory_.InvalidateWeakPtrs(); - BeginUpdateCheck(content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::FILE), - g_browser_process->GetApplicationLocale(), + BeginUpdateCheck(g_browser_process->GetApplicationLocale(), install_update_if_possible, owner_widget_, weak_factory_.GetWeakPtr()); } diff --git a/chromium/chrome/browser/ui/webui/help/version_updater_win.h b/chromium/chrome/browser/ui/webui/help/version_updater_win.h index eab092d1002..f225a231811 100644 --- a/chromium/chrome/browser/ui/webui/help/version_updater_win.h +++ b/chromium/chrome/browser/ui/webui/help/version_updater_win.h @@ -38,7 +38,7 @@ class VersionUpdaterWin : public VersionUpdater, const base::string16& new_version) override; private: - void BeginUpdateCheckOnFileThread(bool install_update_if_possible); + void DoBeginUpdateCheck(bool install_update_if_possible); // A task run on the UI thread with the result of checking for a pending // restart. diff --git a/chromium/chrome/browser/ui/webui/inspect_ui.cc b/chromium/chrome/browser/ui/webui/inspect_ui.cc index 03ba8fae04c..c37e0a94cd7 100644 --- a/chromium/chrome/browser/ui/webui/inspect_ui.cc +++ b/chromium/chrome/browser/ui/webui/inspect_ui.cc @@ -68,7 +68,7 @@ const char kIsAdditionalField[] = "isAdditional"; void GetUiDevToolsTargets(base::ListValue& targets) { for (const auto& client_pair : - ui::devtools::UiDevToolsServer::GetClientNamesAndUrls()) { + ui_devtools::UiDevToolsServer::GetClientNamesAndUrls()) { auto target_data = base::MakeUnique<base::DictionaryValue>(); target_data->SetString(kNameField, client_pair.first); target_data->SetString(kUrlField, client_pair.second); diff --git a/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index 6841d01ce59..5ff5332f195 100644 --- a/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui.cc @@ -50,7 +50,7 @@ namespace { // as all fake certificates will contain the same issuer name, it's // necessary to ensure the serial number is unique, as otherwise // NSS will fail to parse. -base::StaticAtomicSequenceNumber g_serial_number; +base::AtomicSequenceNumber g_serial_number; scoped_refptr<net::X509Certificate> CreateFakeCert() { std::unique_ptr<crypto::RSAPrivateKey> unused_key; @@ -126,7 +126,8 @@ class CaptivePortalBlockingPageWithNetInfo : public CaptivePortalBlockingPage { }; #endif -SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents) { +SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents, + bool is_superfish) { // Random parameters for SSL blocking page. int cert_error = net::ERR_CERT_CONTAINS_ERRORS; GURL request_url("https://example.com"); @@ -137,8 +138,9 @@ SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents) { if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { - if (GURL(url_param).is_valid()) + if (GURL(url_param).is_valid()) { request_url = GURL(url_param); + } } std::string overridable_param; if (net::GetValueForKeyInQuery(web_contents->GetURL(), @@ -152,6 +154,12 @@ SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents) { &strict_enforcement_param)) { strict_enforcement = strict_enforcement_param == "1"; } + std::string type_param; + if (net::GetValueForKeyInQuery(web_contents->GetURL(), "type", &type_param)) { + if (type_param == "hpkp_failure") { + cert_error = net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; + } + } net::SSLInfo ssl_info; ssl_info.cert = ssl_info.unverified_cert = CreateFakeCert(); // This delegate doesn't create an interstitial. @@ -162,7 +170,7 @@ SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents) { options_mask |= security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT; return SSLBlockingPage::Create( web_contents, cert_error, ssl_info, request_url, options_mask, - time_triggered_, nullptr, + time_triggered_, nullptr, is_superfish, base::Callback<void(content::CertificateRequestResultType)>()); } @@ -224,8 +232,9 @@ safe_browsing::SafeBrowsingBlockingPage* CreateSafeBrowsingBlockingPage( if (net::GetValueForKeyInQuery(web_contents->GetURL(), "url", &url_param)) { - if (GURL(url_param).is_valid()) + if (GURL(url_param).is_valid()) { request_url = GURL(url_param); + } } GURL main_frame_url(request_url); // TODO(mattm): add flag to change main_frame_url or add dedicated flag to @@ -240,9 +249,9 @@ safe_browsing::SafeBrowsingBlockingPage* CreateSafeBrowsingBlockingPage( } else if (type_param == "phishing") { threat_type = safe_browsing::SB_THREAT_TYPE_URL_PHISHING; } else if (type_param == "clientside_malware") { - threat_type = safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL; + threat_type = safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE; } else if (type_param == "clientside_phishing") { - threat_type = safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL; + threat_type = safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING; } } safe_browsing::SafeBrowsingBlockingPage::UnsafeResource resource; @@ -405,7 +414,12 @@ void InterstitialHTMLSource::StartDataRequest( std::unique_ptr<content::InterstitialPageDelegate> interstitial_delegate; std::string html; if (base::StartsWith(path, "ssl", base::CompareCase::SENSITIVE)) { - interstitial_delegate.reset(CreateSSLBlockingPage(web_contents)); + interstitial_delegate.reset( + CreateSSLBlockingPage(web_contents, false /* is superfish */)); + } else if (base::StartsWith(path, "superfish-ssl", + base::CompareCase::SENSITIVE)) { + interstitial_delegate.reset( + CreateSSLBlockingPage(web_contents, true /* is superfish */)); } else if (base::StartsWith(path, "safebrowsing", base::CompareCase::SENSITIVE)) { interstitial_delegate.reset(CreateSafeBrowsingBlockingPage(web_contents)); @@ -447,7 +461,7 @@ std::string InterstitialHTMLSource::GetSupervisedUserInterstitialHTML( std::string allow_access_requests_string; if (net::GetValueForKeyInQuery(url, "allow_access_requests", &allow_access_requests_string)) { - allow_access_requests = allow_access_requests_string == "0"; + allow_access_requests = allow_access_requests_string == "1"; } bool is_child_account = false; @@ -457,6 +471,12 @@ std::string InterstitialHTMLSource::GetSupervisedUserInterstitialHTML( is_child_account = is_child_account_string == "1"; } + bool is_deprecated = false; + std::string is_deprecated_string; + if (net::GetValueForKeyInQuery(url, "is_deprecated", &is_deprecated_string)) { + is_deprecated = is_deprecated_string == "1" && !is_child_account; + } + std::string custodian; net::GetValueForKeyInQuery(url, "custodian", &custodian); std::string second_custodian; @@ -475,8 +495,8 @@ std::string InterstitialHTMLSource::GetSupervisedUserInterstitialHTML( supervised_user_error_page::DEFAULT; std::string reason_string; if (net::GetValueForKeyInQuery(url, "reason", &reason_string)) { - if (reason_string == "safe_sites") { - reason = supervised_user_error_page::BLACKLIST; + if (reason_string == "safe_sites" && is_child_account) { + reason = supervised_user_error_page::ASYNC_CHECKER; } else if (reason_string == "manual") { reason = supervised_user_error_page::MANUAL; } else if (reason_string == "not_signed_in") { @@ -487,5 +507,6 @@ std::string InterstitialHTMLSource::GetSupervisedUserInterstitialHTML( return supervised_user_error_page::BuildHtml( allow_access_requests, profile_image_url, profile_image_url2, custodian, custodian_email, second_custodian, second_custodian_email, - is_child_account, reason, g_browser_process->GetApplicationLocale()); + is_child_account, is_deprecated, reason, + g_browser_process->GetApplicationLocale()); } diff --git a/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc index 87e4fcd4ffe..bc4f800ae1f 100644 --- a/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc @@ -52,6 +52,16 @@ IN_PROC_BROWSER_TEST_F(InterstitialUITest, SSLInterstitial) { "Privacy error"); } +IN_PROC_BROWSER_TEST_F(InterstitialUITest, SuperfishInterstitial) { + TestInterstitial(GURL("chrome://interstitials/superfish-ssl"), + "Privacy error"); +} + +IN_PROC_BROWSER_TEST_F(InterstitialUITest, PinnedCertInterstitial) { + TestInterstitial(GURL("chrome://interstitials/ssl?type=hpkp_failure"), + "Privacy error"); +} + IN_PROC_BROWSER_TEST_F(InterstitialUITest, MalwareInterstitial) { TestInterstitial( GURL("chrome://interstitials/safebrowsing?type=malware"), diff --git a/chromium/chrome/browser/ui/webui/large_icon_source.cc b/chromium/chrome/browser/ui/webui/large_icon_source.cc deleted file mode 100644 index 165fb78c403..00000000000 --- a/chromium/chrome/browser/ui/webui/large_icon_source.cc +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2015 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 "chrome/browser/ui/webui/large_icon_source.h" - -#include <vector> - -#include "base/memory/ref_counted_memory.h" -#include "chrome/browser/search/instant_io_context.h" -#include "chrome/common/url_constants.h" -#include "components/favicon/core/large_icon_service.h" -#include "components/favicon_base/fallback_icon_style.h" -#include "components/favicon_base/favicon_types.h" -#include "components/favicon_base/large_icon_url_parser.h" -#include "net/url_request/url_request.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/gfx/codec/png_codec.h" - -namespace { - -const int kMaxLargeIconSize = 192; // Arbitrary bound to safeguard endpoint. - -} // namespace - -LargeIconSource::LargeIconSource(favicon::LargeIconService* large_icon_service) - : large_icon_service_(large_icon_service) {} - -LargeIconSource::~LargeIconSource() { -} - -std::string LargeIconSource::GetSource() const { - return chrome::kChromeUILargeIconHost; -} - -void LargeIconSource::StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) { - if (!large_icon_service_) { - SendNotFoundResponse(callback); - return; - } - - LargeIconUrlParser parser; - bool success = parser.Parse(path); - if (!success || - parser.size_in_pixels() <= 0 || - parser.size_in_pixels() > kMaxLargeIconSize) { - SendNotFoundResponse(callback); - return; - } - - GURL url(parser.url_string()); - if (!url.is_valid()) { - SendNotFoundResponse(callback); - return; - } - - // TODO(beaudoin): Potentially allow icon to be scaled up. - large_icon_service_->GetLargeIconOrFallbackStyle( - url, - parser.size_in_pixels(), // Reducing this will enable scale up. - parser.size_in_pixels(), - base::Bind(&LargeIconSource::OnLargeIconDataAvailable, - base::Unretained(this), callback, url, - parser.size_in_pixels()), - &cancelable_task_tracker_); -} - -std::string LargeIconSource::GetMimeType(const std::string&) const { - // We need to explicitly return a mime type, otherwise if the user tries to - // drag the image they get no extension. - return "image/png"; -} - -bool LargeIconSource::AllowCaching() const { - return false; -} - -bool LargeIconSource::ShouldReplaceExistingSource() const { - // Leave the existing DataSource in place, otherwise we'll drop any pending - // requests on the floor. - return false; -} - -bool LargeIconSource::ShouldServiceRequest( - const GURL& url, - content::ResourceContext* resource_context, - int render_process_id) const { - if (url.SchemeIs(chrome::kChromeSearchScheme)) { - return InstantIOContext::ShouldServiceRequest(url, resource_context, - render_process_id); - } - return URLDataSource::ShouldServiceRequest(url, resource_context, - render_process_id); -} - -void LargeIconSource::OnLargeIconDataAvailable( - const content::URLDataSource::GotDataCallback& callback, - const GURL& url, - int size, - const favicon_base::LargeIconResult& result) { - if (result.bitmap.is_valid()) { - callback.Run(result.bitmap.bitmap_data.get()); - return; - } - - if (!result.fallback_icon_style) { - SendNotFoundResponse(callback); - return; - } - - // RenderFallbackIconBitmap() cannot draw fallback icons on Android. See - // crbug.com/580922 for details. Return a 1x1 bitmap so that JavaScript can - // detect that it needs to generate a fallback icon. - SkBitmap bitmap; - bitmap.allocN32Pixels(1, 1); - bitmap.eraseColor(result.fallback_icon_style->background_color); - std::vector<unsigned char> bitmap_data; - if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data)) - bitmap_data.clear(); - - callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data)); -} - -void LargeIconSource::SendNotFoundResponse( - const content::URLDataSource::GotDataCallback& callback) { - callback.Run(nullptr); -} diff --git a/chromium/chrome/browser/ui/webui/large_icon_source.h b/chromium/chrome/browser/ui/webui/large_icon_source.h deleted file mode 100644 index 6d48d908b87..00000000000 --- a/chromium/chrome/browser/ui/webui/large_icon_source.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2015 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 CHROME_BROWSER_UI_WEBUI_LARGE_ICON_SOURCE_H_ -#define CHROME_BROWSER_UI_WEBUI_LARGE_ICON_SOURCE_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/task/cancelable_task_tracker.h" -#include "content/public/browser/url_data_source.h" - -namespace favicon { -class LargeIconService; -} - -namespace favicon_base { -struct LargeIconResult; -} - -// LargeIconSource services explicit chrome:// requests for large icons. -// -// Format: -// chrome://large-icon/size/url -// -// Parameter: -// 'size' Required (including trailing '/') -// Positive integer to specify the large icon's size in pixels. -// 'url' Optional -// String to specify the page URL of the large icon. -// -// Example: chrome://large-icon/48/http://www.google.com/ -// This requests a 48x48 large icon for http://www.google.com. -class LargeIconSource : public content::URLDataSource { - public: - // |large_icon_service| is owned by caller and may be null. - explicit LargeIconSource(favicon::LargeIconService* large_icon_service); - - ~LargeIconSource() override; - - // content::URLDataSource implementation. - std::string GetSource() const override; - void StartDataRequest( - const std::string& path, - const content::ResourceRequestInfo::WebContentsGetter& wc_getter, - const content::URLDataSource::GotDataCallback& callback) override; - std::string GetMimeType(const std::string&) const override; - bool AllowCaching() const override; - bool ShouldReplaceExistingSource() const override; - bool ShouldServiceRequest(const GURL& url, - content::ResourceContext* resource_context, - int render_process_id) const override; - - private: - // Called with results of large icon retrieval request. - void OnLargeIconDataAvailable( - const content::URLDataSource::GotDataCallback& callback, - const GURL& url, - int size, - const favicon_base::LargeIconResult& bitmap_result); - - // Returns null to trigger "Not Found" response. - void SendNotFoundResponse( - const content::URLDataSource::GotDataCallback& callback); - - base::CancelableTaskTracker cancelable_task_tracker_; - - // Owned by client. - favicon::LargeIconService* large_icon_service_; - - DISALLOW_COPY_AND_ASSIGN(LargeIconSource); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_LARGE_ICON_SOURCE_H_ diff --git a/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc b/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc index c924a72f36c..1b25fe1c8b1 100644 --- a/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc +++ b/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc @@ -4,6 +4,7 @@ #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h" +#include <memory> #include <set> #include <utility> @@ -173,7 +174,7 @@ void LocalDiscoveryUIHandler::HandleStart(const base::ListValue* args) { } privet_lister_->Start(); - privet_lister_->DiscoverNewDevices(false); + privet_lister_->DiscoverNewDevices(); #if defined(CLOUD_PRINT_CONNECTOR_UI_AVAILABLE) StartCloudPrintConnector(); @@ -380,7 +381,7 @@ void LocalDiscoveryUIHandler::DeviceRemoved(const std::string& name) { void LocalDiscoveryUIHandler::DeviceCacheFlushed() { web_ui()->CallJavascriptFunctionUnsafe( "local_discovery.onDeviceCacheFlushed"); - privet_lister_->DiscoverNewDevices(false); + privet_lister_->DiscoverNewDevices(); } void LocalDiscoveryUIHandler::OnDeviceListReady( @@ -397,8 +398,7 @@ void LocalDiscoveryUIHandler::OnDeviceListUnavailable() { void LocalDiscoveryUIHandler::GoogleSigninSucceeded( const std::string& account_id, - const std::string& username, - const std::string& password) { + const std::string& username) { CheckUserLoggedIn(); } @@ -416,7 +416,7 @@ void LocalDiscoveryUIHandler::SendRegisterDone( const std::string& service_name) { // HACK(noamsml): Generate network traffic so the Windows firewall doesn't // block the printer's announcement. - privet_lister_->DiscoverNewDevices(false); + privet_lister_->DiscoverNewDevices(); DeviceDescriptionMap::iterator it = device_descriptions_.find(service_name); diff --git a/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h b/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h index c1afc0225f8..80302ce897a 100644 --- a/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h +++ b/chromium/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h @@ -80,8 +80,7 @@ class LocalDiscoveryUIHandler // SigninManagerBase::Observer implementation. void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username, - const std::string& password) override; + const std::string& username) override; void GoogleSignedOut(const std::string& account_id, const std::string& username) override; diff --git a/chromium/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc b/chromium/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc index 07c45f38eb6..386eaa68968 100644 --- a/chromium/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc @@ -11,11 +11,9 @@ #include "base/hash.h" #include "base/macros.h" #include "base/test/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/in_process_browser_test.h" @@ -23,7 +21,6 @@ #include "components/strings/grit/components_strings.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" -#include "extensions/features/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -38,84 +35,34 @@ class LogWebUIUrlTest : public InProcessBrowserTest { LogWebUIUrlTest() {} ~LogWebUIUrlTest() override {} - std::vector<Bucket> GetSamples() { - return histogram_tester_.GetAllSamples(webui::kWebUICreatedForUrl); - } - - void SetUpOnMainThread() override { - // Disable MD Settings to test non-MD settings page. - scoped_feature_list_.InitAndDisableFeature( - features::kMaterialDesignSettings); + void RunTest(int title_ids, const GURL& url) { + auto* tab = browser()->tab_strip_model()->GetActiveWebContents(); + base::string16 title = l10n_util::GetStringUTF16(title_ids); + content::TitleWatcher title_watcher(tab, title); + ui_test_utils::NavigateToURL(browser(), url); + ASSERT_EQ(title, title_watcher.WaitAndGetTitle()); + uint32_t origin_hash = base::Hash(url.GetOrigin().spec()); + EXPECT_THAT(histogram_tester_.GetAllSamples(webui::kWebUICreatedForUrl), + ElementsAre(Bucket(origin_hash, 1))); } private: - base::test::ScopedFeatureList scoped_feature_list_; base::HistogramTester histogram_tester_; DISALLOW_COPY_AND_ASSIGN(LogWebUIUrlTest); }; -IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestSettingsFrame) { - GURL settings_frame_url(chrome::kChromeUISettingsFrameURL); - - ui_test_utils::NavigateToURL(browser(), settings_frame_url); - - uint32_t settings_frame_url_hash = base::Hash(settings_frame_url.spec()); - EXPECT_THAT(GetSamples(), ElementsAre(Bucket(settings_frame_url_hash, 1))); - - chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); - - EXPECT_THAT(GetSamples(), ElementsAre(Bucket(settings_frame_url_hash, 2))); -} - -#if BUILDFLAG(ENABLE_EXTENSIONS) IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestExtensionsPage) { - content::WebContents* tab = - browser()->tab_strip_model()->GetActiveWebContents(); - - base::string16 extension_title = - l10n_util::GetStringUTF16(IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE); - - { - content::TitleWatcher title_watcher(tab, extension_title); - ui_test_utils::NavigateToURL(browser(), - GURL(chrome::kChromeUIExtensionsURL)); - ASSERT_EQ(extension_title, title_watcher.WaitAndGetTitle()); - } - - std::string scheme(content::kChromeUIScheme); - GURL uber_url(scheme + "://" + chrome::kChromeUIUberHost); - uint32_t uber_url_hash = base::Hash(uber_url.spec()); - - GURL uber_frame_url(chrome::kChromeUIUberFrameURL); - uint32_t uber_frame_url_hash = base::Hash(uber_frame_url.spec()); - - GURL extensions_frame_url(chrome::kChromeUIExtensionsFrameURL); - uint32_t extensions_frame_url_hash = base::Hash(extensions_frame_url.spec()); - - EXPECT_THAT(GetSamples(), ElementsAre(Bucket(extensions_frame_url_hash, 1), - Bucket(uber_frame_url_hash, 1), - Bucket(uber_url_hash, 1))); - - { - // Pretend a user clicked on "Settings". - base::string16 settings_title = - l10n_util::GetStringUTF16(IDS_SETTINGS_SETTINGS); - content::TitleWatcher title_watcher(tab, settings_title); - std::string javascript = - "uber.invokeMethodOnWindow(window, 'showPage', {pageId: 'settings'})"; - ASSERT_TRUE(content::ExecuteScript(tab, javascript)); - ASSERT_EQ(settings_title, title_watcher.WaitAndGetTitle()); - } + RunTest(IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE, + GURL(chrome::kChromeUIExtensionsURL)); +} - GURL settings_frame_url(chrome::kChromeUISettingsFrameURL); - uint32_t settings_frame_url_hash = base::Hash(settings_frame_url.spec()); +IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestHistoryPage) { + RunTest(IDS_HISTORY_TITLE, GURL(chrome::kChromeUIHistoryURL)); +} - EXPECT_THAT(GetSamples(), ElementsAre(Bucket(extensions_frame_url_hash, 1), - Bucket(settings_frame_url_hash, 1), - Bucket(uber_frame_url_hash, 1), - Bucket(uber_url_hash, 1))); +IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestSettingsPage) { + RunTest(IDS_SETTINGS_SETTINGS, GURL(chrome::kChromeUISettingsURL)); } -#endif } // namespace webui diff --git a/chromium/chrome/browser/ui/webui/md_bookmarks/OWNERS b/chromium/chrome/browser/ui/webui/md_bookmarks/OWNERS index d0663e00c74..b02ce2c777a 100644 --- a/chromium/chrome/browser/ui/webui/md_bookmarks/OWNERS +++ b/chromium/chrome/browser/ui/webui/md_bookmarks/OWNERS @@ -1,5 +1,4 @@ calamity@chromium.org -dbeam@chromium.org tsergeant@chromium.org # COMPONENT: UI>Browser>Bookmarks diff --git a/chromium/chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.cc b/chromium/chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.cc new file mode 100644 index 00000000000..249049ae6d7 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.cc @@ -0,0 +1,88 @@ +// 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 "chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.h" + +#include "base/bind.h" +#include "base/values.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "components/bookmarks/common/bookmark_pref_names.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_service.h" + +BookmarksMessageHandler::BookmarksMessageHandler() {} + +BookmarksMessageHandler::~BookmarksMessageHandler() {} + +void BookmarksMessageHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "getIncognitoAvailability", + base::Bind(&BookmarksMessageHandler::HandleGetIncognitoAvailability, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "getCanEditBookmarks", + base::Bind(&BookmarksMessageHandler::HandleGetCanEditBookmarks, + base::Unretained(this))); +} + +void BookmarksMessageHandler::OnJavascriptAllowed() { + PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); + pref_change_registrar_.Init(prefs); + pref_change_registrar_.Add( + prefs::kIncognitoModeAvailability, + base::Bind(&BookmarksMessageHandler::UpdateIncognitoAvailability, + base::Unretained(this))); + pref_change_registrar_.Add( + bookmarks::prefs::kEditBookmarksEnabled, + base::Bind(&BookmarksMessageHandler::UpdateCanEditBookmarks, + base::Unretained(this))); +} + +void BookmarksMessageHandler::OnJavascriptDisallowed() { + pref_change_registrar_.RemoveAll(); +} + +int BookmarksMessageHandler::GetIncognitoAvailability() { + PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); + return prefs->GetInteger(prefs::kIncognitoModeAvailability); +} + +void BookmarksMessageHandler::HandleGetIncognitoAvailability( + const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); + + AllowJavascript(); + + ResolveJavascriptCallback(*callback_id, + base::Value(GetIncognitoAvailability())); +} + +void BookmarksMessageHandler::UpdateIncognitoAvailability() { + FireWebUIListener("incognito-availability-changed", + base::Value(GetIncognitoAvailability())); +} + +bool BookmarksMessageHandler::CanEditBookmarks() { + PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); + return prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled); +} + +void BookmarksMessageHandler::HandleGetCanEditBookmarks( + const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); + + AllowJavascript(); + + ResolveJavascriptCallback(*callback_id, base::Value(CanEditBookmarks())); +} + +void BookmarksMessageHandler::UpdateCanEditBookmarks() { + FireWebUIListener("can-edit-bookmarks-changed", + base::Value(CanEditBookmarks())); +} diff --git a/chromium/chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.h b/chromium/chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.h new file mode 100644 index 00000000000..c7e3921718e --- /dev/null +++ b/chromium/chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.h @@ -0,0 +1,39 @@ +// 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 CHROME_BROWSER_UI_WEBUI_MD_BOOKMARKS_BOOKMARKS_MESSAGE_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_MD_BOOKMARKS_BOOKMARKS_MESSAGE_HANDLER_H_ + +#include "components/prefs/pref_change_registrar.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace base { +class ListValue; +}; + +class BookmarksMessageHandler : public content::WebUIMessageHandler { + public: + BookmarksMessageHandler(); + ~BookmarksMessageHandler() override; + + private: + int GetIncognitoAvailability(); + void HandleGetIncognitoAvailability(const base::ListValue* args); + void UpdateIncognitoAvailability(); + + bool CanEditBookmarks(); + void HandleGetCanEditBookmarks(const base::ListValue* args); + void UpdateCanEditBookmarks(); + + // content::WebUIMessageHandler: + void RegisterMessages() override; + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; + + PrefChangeRegistrar pref_change_registrar_; + + DISALLOW_COPY_AND_ASSIGN(BookmarksMessageHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_MD_BOOKMARKS_BOOKMARKS_MESSAGE_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.cc b/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.cc new file mode 100644 index 00000000000..7dea1b0f145 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.cc @@ -0,0 +1,73 @@ +// 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 "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.h" + +#include "chrome/browser/prefs/incognito_mode_prefs.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/pref_names.h" +#include "components/bookmarks/common/bookmark_pref_names.h" +#include "components/prefs/pref_service.h" + +MdBookmarksBrowserTest::MdBookmarksBrowserTest() {} + +MdBookmarksBrowserTest::~MdBookmarksBrowserTest() {} + +void MdBookmarksBrowserTest::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "testSetIncognito", + base::Bind(&MdBookmarksBrowserTest::HandleSetIncognitoAvailability, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "testSetCanEdit", + base::Bind(&MdBookmarksBrowserTest::HandleSetCanEditBookmarks, + base::Unretained(this))); +} + +void MdBookmarksBrowserTest::SetIncognitoAvailability(int availability) { + ASSERT_TRUE(availability >= 0 && + availability < IncognitoModePrefs::AVAILABILITY_NUM_TYPES); + browser()->profile()->GetPrefs()->SetInteger( + prefs::kIncognitoModeAvailability, availability); +} + +void MdBookmarksBrowserTest::SetCanEditBookmarks(bool canEdit) { + browser()->profile()->GetPrefs()->SetBoolean( + bookmarks::prefs::kEditBookmarksEnabled, canEdit); +} + +void MdBookmarksBrowserTest::HandleSetIncognitoAvailability( + const base::ListValue* args) { + AllowJavascript(); + + ASSERT_EQ(2U, args->GetSize()); + const base::Value* callback_id; + ASSERT_TRUE(args->Get(0, &callback_id)); + int pref_value; + ASSERT_TRUE(args->GetInteger(1, &pref_value)); + + SetIncognitoAvailability(pref_value); + + ResolveJavascriptCallback(*callback_id, base::Value()); +} + +void MdBookmarksBrowserTest::HandleSetCanEditBookmarks( + const base::ListValue* args) { + AllowJavascript(); + + ASSERT_EQ(2U, args->GetSize()); + const base::Value* callback_id; + ASSERT_TRUE(args->Get(0, &callback_id)); + bool pref_value; + ASSERT_TRUE(args->GetBoolean(1, &pref_value)); + + SetCanEditBookmarks(pref_value); + + ResolveJavascriptCallback(*callback_id, base::Value()); +} + +content::WebUIMessageHandler* MdBookmarksBrowserTest::GetMockMessageHandler() { + return this; +} diff --git a/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.h b/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.h new file mode 100644 index 00000000000..2026989a0dc --- /dev/null +++ b/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_browsertest.h @@ -0,0 +1,33 @@ +// 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 CHROME_BROWSER_UI_WEBUI_MD_BOOKMARKS_MD_BOOKMARKS_BROWSERTEST_H_ +#define CHROME_BROWSER_UI_WEBUI_MD_BOOKMARKS_MD_BOOKMARKS_BROWSERTEST_H_ + +#include "chrome/test/base/web_ui_browser_test.h" +#include "content/public/browser/web_ui_message_handler.h" + +class MdBookmarksBrowserTest : public WebUIBrowserTest, + public content::WebUIMessageHandler { + public: + MdBookmarksBrowserTest(); + ~MdBookmarksBrowserTest() override; + + void SetIncognitoAvailability(int availability); + void SetCanEditBookmarks(bool canEdit); + + private: + void HandleSetIncognitoAvailability(const base::ListValue* args); + void HandleSetCanEditBookmarks(const base::ListValue* args); + + // content::WebUIMessageHandler: + void RegisterMessages() override; + + // WebUIBrowserTest: + content::WebUIMessageHandler* GetMockMessageHandler() override; + + DISALLOW_COPY_AND_ASSIGN(MdBookmarksBrowserTest); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_MD_BOOKMARKS_MD_BOOKMARKS_BROWSERTEST_H_ diff --git a/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc b/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc index 521277b8b1a..d688f7a7072 100644 --- a/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc +++ b/chromium/chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.cc @@ -5,9 +5,14 @@ #include "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.h" #include <algorithm> +#include <string> +#include <unordered_set> +#include <utility> #include "base/strings/string16.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/md_bookmarks/bookmarks_message_handler.h" +#include "chrome/browser/ui/webui/plural_string_handler.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" @@ -75,17 +80,52 @@ content::WebUIDataSource* CreateMdBookmarksUIHTMLSource(Profile* profile) { AddLocalizedString(source, "menuOpenIncognito", IDS_BOOKMARK_BAR_OPEN_INCOGNITO); AddLocalizedString(source, "menuRename", IDS_MD_BOOKMARK_MANAGER_MENU_RENAME); + AddLocalizedString(source, "menuShowInFolder", + IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER); AddLocalizedString(source, "menuSort", IDS_MD_BOOKMARK_MANAGER_MENU_SORT); + AddLocalizedString(source, "moreActionsButtonTitle", + IDS_MD_BOOKMARK_MANAGER_MORE_ACTIONS); AddLocalizedString(source, "noSearchResults", IDS_MD_BOOKMARK_MANAGER_NO_SEARCH_RESULTS); + AddLocalizedString(source, "openDialogBody", + IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL); + AddLocalizedString(source, "openDialogConfirm", + IDS_MD_BOOKMARK_MANAGER_OPEN_DIALOG_CONFIRM); + AddLocalizedString(source, "openDialogTitle", + IDS_MD_BOOKMARK_MANAGER_OPEN_DIALOG_TITLE); + AddLocalizedString(source, "organizeButtonTitle", + IDS_BOOKMARK_MANAGER_ORGANIZE_MENU); AddLocalizedString(source, "renameFolderTitle", IDS_MD_BOOKMARK_MANAGER_FOLDER_RENAME_TITLE); AddLocalizedString(source, "searchPrompt", IDS_BOOKMARK_MANAGER_SEARCH_BUTTON); + AddLocalizedString(source, "searchResults", + IDS_MD_BOOKMARK_MANAGER_SEARCH_RESULTS); AddLocalizedString(source, "saveEdit", IDS_SAVE); AddLocalizedString(source, "title", IDS_MD_BOOKMARK_MANAGER_TITLE); + AddLocalizedString(source, "toastFolderSorted", + IDS_MD_BOOKMARK_MANAGER_TOAST_FOLDER_SORTED); + AddLocalizedString(source, "toastItemCopied", + IDS_MD_BOOKMARK_MANAGER_TOAST_ITEM_COPIED); + AddLocalizedString(source, "toastItemDeleted", + IDS_MD_BOOKMARK_MANAGER_TOAST_ITEM_DELETED); + AddLocalizedString(source, "toastUrlCopied", + IDS_MD_BOOKMARK_MANAGER_TOAST_URL_COPIED); + AddLocalizedString(source, "undo", IDS_BOOKMARK_BAR_UNDO); // Resources. + source->AddResourcePath("images/folder_open.svg", + IDR_MD_BOOKMARKS_IMAGES_FOLDER_OPEN_SVG); + source->AddResourcePath("images/folder.svg", + IDR_MD_BOOKMARKS_IMAGES_FOLDER_SVG); +#if BUILDFLAG(USE_VULCANIZE) + source->AddResourcePath("crisper.js", IDR_MD_BOOKMARKS_CRISPER_JS); + source->SetDefaultResource(IDR_MD_BOOKMARKS_VULCANIZED_HTML); + std::unordered_set<std::string> exclusions; + exclusions.insert("images/folder_open.svg"); + exclusions.insert("images/folder.svg"); + source->UseGzip(exclusions); +#else source->AddResourcePath("actions.html", IDR_MD_BOOKMARKS_ACTIONS_HTML); source->AddResourcePath("actions.js", IDR_MD_BOOKMARKS_ACTIONS_JS); source->AddResourcePath("api_listener.html", @@ -99,6 +139,12 @@ content::WebUIDataSource* CreateMdBookmarksUIHTMLSource(Profile* profile) { IDR_MD_BOOKMARKS_COMMAND_MANAGER_JS); source->AddResourcePath("constants.html", IDR_MD_BOOKMARKS_CONSTANTS_HTML); source->AddResourcePath("constants.js", IDR_MD_BOOKMARKS_CONSTANTS_JS); + source->AddResourcePath("dialog_focus_manager.html", + IDR_MD_BOOKMARKS_DIALOG_FOCUS_MANAGER_HTML); + source->AddResourcePath("dialog_focus_manager.js", + IDR_MD_BOOKMARKS_DIALOG_FOCUS_MANAGER_JS); + source->AddResourcePath("dnd_chip.html", IDR_MD_BOOKMARKS_DND_CHIP_HTML); + source->AddResourcePath("dnd_chip.js", IDR_MD_BOOKMARKS_DND_CHIP_JS); source->AddResourcePath("dnd_manager.html", IDR_MD_BOOKMARKS_DND_MANAGER_HTML); source->AddResourcePath("dnd_manager.js", IDR_MD_BOOKMARKS_DND_MANAGER_JS); @@ -109,11 +155,14 @@ content::WebUIDataSource* CreateMdBookmarksUIHTMLSource(Profile* profile) { IDR_MD_BOOKMARKS_FOLDER_NODE_HTML); source->AddResourcePath("folder_node.js", IDR_MD_BOOKMARKS_FOLDER_NODE_JS); - source->AddResourcePath("icons.html", IDR_MD_BOOKMARKS_ICONS_HTML); source->AddResourcePath("item.html", IDR_MD_BOOKMARKS_ITEM_HTML); source->AddResourcePath("item.js", IDR_MD_BOOKMARKS_ITEM_JS); source->AddResourcePath("list.html", IDR_MD_BOOKMARKS_LIST_HTML); source->AddResourcePath("list.js", IDR_MD_BOOKMARKS_LIST_JS); + source->AddResourcePath("mouse_focus_behavior.html", + IDR_MD_BOOKMARKS_MOUSE_FOCUS_BEHAVIOR_HTML); + source->AddResourcePath("mouse_focus_behavior.js", + IDR_MD_BOOKMARKS_MOUSE_FOCUS_BEHAVIOR_JS); source->AddResourcePath("reducers.html", IDR_MD_BOOKMARKS_REDUCERS_HTML); source->AddResourcePath("reducers.js", IDR_MD_BOOKMARKS_REDUCERS_JS); source->AddResourcePath("router.html", IDR_MD_BOOKMARKS_ROUTER_HTML); @@ -127,11 +176,21 @@ content::WebUIDataSource* CreateMdBookmarksUIHTMLSource(Profile* profile) { source->AddResourcePath("store_client.html", IDR_MD_BOOKMARKS_STORE_CLIENT_HTML); source->AddResourcePath("store_client.js", IDR_MD_BOOKMARKS_STORE_CLIENT_JS); + source->AddResourcePath("timer_proxy.html", + IDR_MD_BOOKMARKS_TIMER_PROXY_HTML); + source->AddResourcePath("timer_proxy.js", IDR_MD_BOOKMARKS_TIMER_PROXY_JS); + source->AddResourcePath("toast_manager.html", + IDR_MD_BOOKMARKS_TOAST_MANAGER_HTML); + source->AddResourcePath("toast_manager.js", + IDR_MD_BOOKMARKS_TOAST_MANAGER_JS); source->AddResourcePath("toolbar.html", IDR_MD_BOOKMARKS_TOOLBAR_HTML); source->AddResourcePath("toolbar.js", IDR_MD_BOOKMARKS_TOOLBAR_JS); source->AddResourcePath("util.html", IDR_MD_BOOKMARKS_UTIL_HTML); source->AddResourcePath("util.js", IDR_MD_BOOKMARKS_UTIL_JS); + source->SetDefaultResource(IDR_MD_BOOKMARKS_BOOKMARKS_HTML); +#endif + source->SetJsonPath("strings.js"); return source; @@ -144,6 +203,15 @@ MdBookmarksUI::MdBookmarksUI(content::WebUI* web_ui) : WebUIController(web_ui) { Profile* profile = Profile::FromWebUI(web_ui); content::WebUIDataSource::Add(profile, CreateMdBookmarksUIHTMLSource(profile)); + + auto plural_string_handler = base::MakeUnique<PluralStringHandler>(); + plural_string_handler->AddLocalizedString( + "toastItemsDeleted", IDS_MD_BOOKMARK_MANAGER_TOAST_ITEMS_DELETED); + plural_string_handler->AddLocalizedString( + "toastItemsCopied", IDS_MD_BOOKMARK_MANAGER_TOAST_ITEMS_COPIED); + web_ui->AddMessageHandler(std::move(plural_string_handler)); + + web_ui->AddMessageHandler(base::MakeUnique<BookmarksMessageHandler>()); } // static diff --git a/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc b/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc index 46a17b7c295..30cb212cd0e 100644 --- a/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc +++ b/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc @@ -15,7 +15,6 @@ #include "base/time/time.h" #include "base/value_conversions.h" #include "base/values.h" -#include "chrome/browser/download/all_download_item_notifier.h" #include "chrome/browser/download/download_crx_util.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_query.h" @@ -354,7 +353,7 @@ void DownloadsListTracker::Init() { GetMainNotifierManager()->GetBrowserContext()); if (profile->IsOffTheRecord()) { Profile* original_profile = profile->GetOriginalProfile(); - original_notifier_.reset(new AllDownloadItemNotifier( + original_notifier_.reset(new download::AllDownloadItemNotifier( BrowserContext::GetDownloadManager(original_profile), this)); } diff --git a/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h b/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h index 2fd266c91d5..b92245acd3a 100644 --- a/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h +++ b/chromium/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h @@ -15,7 +15,7 @@ #include "base/strings/string16.h" #include "base/time/time.h" #include "base/values.h" -#include "chrome/browser/download/all_download_item_notifier.h" +#include "components/download/content/public/all_download_item_notifier.h" #include "content/public/browser/download_item.h" namespace base { @@ -30,7 +30,8 @@ class WebUI; // A class that tracks all downloads activity and keeps a sorted representation // of the downloads as chrome://downloads wants to display them. -class DownloadsListTracker : public AllDownloadItemNotifier::Observer { +class DownloadsListTracker + : public download::AllDownloadItemNotifier::Observer { public: DownloadsListTracker(content::DownloadManager* download_manager, content::WebUI* web_ui); @@ -109,8 +110,8 @@ class DownloadsListTracker : public AllDownloadItemNotifier::Observer { // if sending updates. void RemoveItem(const SortedSet::iterator& remove); - AllDownloadItemNotifier main_notifier_; - std::unique_ptr<AllDownloadItemNotifier> original_notifier_; + download::AllDownloadItemNotifier main_notifier_; + std::unique_ptr<download::AllDownloadItemNotifier> original_notifier_; // The WebUI object corresponding to the page we care about. content::WebUI* const web_ui_; diff --git a/chromium/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc b/chromium/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc index 15bbabc4372..fdc3fbe2248 100644 --- a/chromium/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc +++ b/chromium/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc @@ -33,6 +33,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_danger_type.h" #include "content/public/browser/download_item.h" diff --git a/chromium/chrome/browser/ui/webui/md_history_ui.cc b/chromium/chrome/browser/ui/webui/md_history_ui.cc index 381cde7e1f4..1f55adcfc6e 100644 --- a/chromium/chrome/browser/ui/webui/md_history_ui.cc +++ b/chromium/chrome/browser/ui/webui/md_history_ui.cc @@ -21,7 +21,6 @@ #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h" -#include "chrome/grit/theme_resources.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/search/search.h" diff --git a/chromium/chrome/browser/ui/webui/media/OWNERS b/chromium/chrome/browser/ui/webui/media/OWNERS new file mode 100644 index 00000000000..77384f3c0f9 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/media/OWNERS @@ -0,0 +1,8 @@ +# For Media Engagement +mlamouri@chromium.org +beccahughes@chromium.org + +# For WebRTC +per-file webrtc_*=file://third_party/webrtc_overrides/OWNERS + +# COMPONENT: Internals>Media>UI diff --git a/chromium/chrome/browser/ui/webui/media/media_engagement_ui.cc b/chromium/chrome/browser/ui/webui/media/media_engagement_ui.cc new file mode 100644 index 00000000000..dfc83dc58ff --- /dev/null +++ b/chromium/chrome/browser/ui/webui/media/media_engagement_ui.cc @@ -0,0 +1,76 @@ +// 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 "chrome/browser/ui/webui/media/media_engagement_ui.h" + +#include "base/macros.h" +#include "chrome/browser/media/media_engagement_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/url_constants.h" +#include "chrome/grit/browser_resources.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_controller.h" +#include "content/public/browser/web_ui_data_source.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace { + +// Implementation of media::mojom::MediaEngagementScoreDetailsProvider that +// retrieves engagement details from the MediaEngagementService. +class MediaEngagementScoreDetailsProviderImpl + : public media::mojom::MediaEngagementScoreDetailsProvider { + public: + MediaEngagementScoreDetailsProviderImpl( + Profile* profile, + mojo::InterfaceRequest<media::mojom::MediaEngagementScoreDetailsProvider> + request) + : profile_(profile), binding_(this, std::move(request)) { + DCHECK(profile_); + service_ = MediaEngagementService::Get(profile_); + } + + ~MediaEngagementScoreDetailsProviderImpl() override {} + + // media::mojom::MediaEngagementScoreDetailsProvider overrides: + void GetMediaEngagementScoreDetails( + media::mojom::MediaEngagementScoreDetailsProvider:: + GetMediaEngagementScoreDetailsCallback callback) override { + std::move(callback).Run(service_->GetAllScoreDetails()); + } + + private: + Profile* profile_; + + MediaEngagementService* service_; + + mojo::Binding<media::mojom::MediaEngagementScoreDetailsProvider> binding_; + + DISALLOW_COPY_AND_ASSIGN(MediaEngagementScoreDetailsProviderImpl); +}; + +} // namespace + +MediaEngagementUI::MediaEngagementUI(content::WebUI* web_ui) + : MojoWebUIController<media::mojom::MediaEngagementScoreDetailsProvider>( + web_ui) { + // Setup the data source behind chrome://media-engagement. + std::unique_ptr<content::WebUIDataSource> source( + content::WebUIDataSource::Create(chrome::kChromeUIMediaEngagementHost)); + source->AddResourcePath("media-engagement.js", IDR_MEDIA_ENGAGEMENT_JS); + source->AddResourcePath( + "chrome/browser/media/media_engagement_score_details.mojom.js", + IDR_MEDIA_ENGAGEMENT_MOJO_JS); + source->AddResourcePath("url/mojo/url.mojom.js", IDR_URL_MOJO_JS); + source->SetDefaultResource(IDR_MEDIA_ENGAGEMENT_HTML); + source->UseGzip(std::unordered_set<std::string>()); + content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source.release()); +} + +MediaEngagementUI::~MediaEngagementUI() = default; + +void MediaEngagementUI::BindUIHandler( + media::mojom::MediaEngagementScoreDetailsProviderRequest request) { + ui_handler_ = base::MakeUnique<MediaEngagementScoreDetailsProviderImpl>( + Profile::FromWebUI(web_ui()), std::move(request)); +} diff --git a/chromium/chrome/browser/ui/webui/media/media_engagement_ui.h b/chromium/chrome/browser/ui/webui/media/media_engagement_ui.h new file mode 100644 index 00000000000..6cdf939b6dd --- /dev/null +++ b/chromium/chrome/browser/ui/webui/media/media_engagement_ui.h @@ -0,0 +1,31 @@ +// 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 CHROME_BROWSER_UI_WEBUI_MEDIA_MEDIA_ENGAGEMENT_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_MEDIA_MEDIA_ENGAGEMENT_UI_H_ + +#include "base/macros.h" +#include "chrome/browser/media/media_engagement_score_details.mojom.h" +#include "chrome/browser/ui/webui/mojo_web_ui_controller.h" + +// The UI for chrome://media-engagement/. +class MediaEngagementUI + : public MojoWebUIController< + media::mojom::MediaEngagementScoreDetailsProvider> { + public: + explicit MediaEngagementUI(content::WebUI* web_ui); + ~MediaEngagementUI() override; + + private: + // MojoWebUIController overrides: + void BindUIHandler(media::mojom::MediaEngagementScoreDetailsProviderRequest + request) override; + + std::unique_ptr<media::mojom::MediaEngagementScoreDetailsProvider> + ui_handler_; + + DISALLOW_COPY_AND_ASSIGN(MediaEngagementUI); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_MEDIA_MEDIA_ENGAGEMENT_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/media/webrtc_logs_ui.cc b/chromium/chrome/browser/ui/webui/media/webrtc_logs_ui.cc index 5a3355fbab2..70e70605384 100644 --- a/chromium/chrome/browser/ui/webui/media/webrtc_logs_ui.cc +++ b/chromium/chrome/browser/ui/webui/media/webrtc_logs_ui.cc @@ -76,8 +76,7 @@ content::WebUIDataSource* CreateWebRtcLogsUIHTMLSource() { //////////////////////////////////////////////////////////////////////////////// // The handler for Javascript messages for the chrome://webrtc-logs/ page. -class WebRtcLogsDOMHandler : public WebUIMessageHandler, - public UploadList::Delegate { +class WebRtcLogsDOMHandler : public WebUIMessageHandler { public: explicit WebRtcLogsDOMHandler(Profile* profile); ~WebRtcLogsDOMHandler() override; @@ -85,10 +84,9 @@ class WebRtcLogsDOMHandler : public WebUIMessageHandler, // WebUIMessageHandler implementation. void RegisterMessages() override; - // UploadList::Delegate implemenation. - void OnUploadListAvailable() override; - private: + void OnUploadListAvailable(); + // Asynchronously fetches the list of upload WebRTC logs. Called from JS. void HandleRequestWebRtcLogs(const base::ListValue* args); @@ -116,15 +114,16 @@ WebRtcLogsDOMHandler::WebRtcLogsDOMHandler(Profile* profile) WebRtcLogList::GetWebRtcLogDirectoryForProfile(profile->GetPath())), list_available_(false), js_request_pending_(false) { - upload_list_ = WebRtcLogList::CreateWebRtcLogList(this, profile); + upload_list_ = WebRtcLogList::CreateWebRtcLogList(profile); } WebRtcLogsDOMHandler::~WebRtcLogsDOMHandler() { - upload_list_->ClearDelegate(); + upload_list_->CancelCallback(); } void WebRtcLogsDOMHandler::RegisterMessages() { - upload_list_->LoadUploadListAsynchronously(); + upload_list_->Load(base::BindOnce( + &WebRtcLogsDOMHandler::OnUploadListAvailable, base::Unretained(this))); web_ui()->RegisterMessageCallback("requestWebRtcLogsList", base::Bind(&WebRtcLogsDOMHandler::HandleRequestWebRtcLogs, diff --git a/chromium/chrome/browser/ui/webui/media_router/cast_modes_with_media_sources_unittest.cc b/chromium/chrome/browser/ui/webui/media_router/cast_modes_with_media_sources_unittest.cc index a056b7a83c9..9c428568e90 100644 --- a/chromium/chrome/browser/ui/webui/media_router/cast_modes_with_media_sources_unittest.cc +++ b/chromium/chrome/browser/ui/webui/media_router/cast_modes_with_media_sources_unittest.cc @@ -12,64 +12,75 @@ namespace media_router { TEST(MediaRouterCastModesWithMediaSourcesTest, AddAndRemoveSources) { - const MediaSource defaultSource1(MediaSourceForPresentationUrl( + const MediaSource presentationSource1(MediaSourceForPresentationUrl( GURL("http://www.example.com/presentation.html"))); - const MediaSource defaultSource2(MediaSourceForPresentationUrl( + const MediaSource presentationSource2(MediaSourceForPresentationUrl( GURL("http://www.example.net/presentation.html"))); const MediaSource tabSourceA(MediaSourceForTab(123)); const CastModeSet castModeSetEmpty; - const CastModeSet castModeSetDefault({MediaCastMode::DEFAULT}); + const CastModeSet castModeSetPresentation({MediaCastMode::PRESENTATION}); const CastModeSet castModeSetTab({MediaCastMode::TAB_MIRROR}); - const CastModeSet castModeSetDefaultAndTab( - {MediaCastMode::DEFAULT, MediaCastMode::TAB_MIRROR}); + const CastModeSet castModeSetPresentationAndTab( + {MediaCastMode::PRESENTATION, MediaCastMode::TAB_MIRROR}); CastModesWithMediaSources sources; EXPECT_TRUE(sources.IsEmpty()); EXPECT_EQ(sources.GetCastModes(), castModeSetEmpty); // After the below addition, |sources| should contain: - // [Default: 1] - sources.AddSource(MediaCastMode::DEFAULT, defaultSource1); - EXPECT_TRUE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource1)); - EXPECT_FALSE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource2)); - EXPECT_FALSE(sources.HasSource(MediaCastMode::TAB_MIRROR, defaultSource1)); + // [Presentation: 1] + sources.AddSource(MediaCastMode::PRESENTATION, presentationSource1); + EXPECT_TRUE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource1)); + EXPECT_FALSE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource2)); + EXPECT_FALSE( + sources.HasSource(MediaCastMode::TAB_MIRROR, presentationSource1)); EXPECT_FALSE(sources.IsEmpty()); - EXPECT_EQ(sources.GetCastModes(), castModeSetDefault); + EXPECT_EQ(sources.GetCastModes(), castModeSetPresentation); // Trying to remove non-existing sources should be no-op. - sources.RemoveSource(MediaCastMode::DEFAULT, defaultSource2); - sources.RemoveSource(MediaCastMode::TAB_MIRROR, defaultSource1); + sources.RemoveSource(MediaCastMode::PRESENTATION, presentationSource2); + sources.RemoveSource(MediaCastMode::TAB_MIRROR, presentationSource1); sources.RemoveSource(MediaCastMode::TAB_MIRROR, tabSourceA); - EXPECT_TRUE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource1)); - EXPECT_EQ(sources.GetCastModes(), castModeSetDefault); + EXPECT_TRUE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource1)); + EXPECT_EQ(sources.GetCastModes(), castModeSetPresentation); - // [Default: 1; Tab: A] + // [Presentation: 1; Tab: A] sources.AddSource(MediaCastMode::TAB_MIRROR, tabSourceA); - EXPECT_TRUE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource1)); + EXPECT_TRUE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource1)); EXPECT_TRUE(sources.HasSource(MediaCastMode::TAB_MIRROR, tabSourceA)); - EXPECT_EQ(sources.GetCastModes(), castModeSetDefaultAndTab); + EXPECT_EQ(sources.GetCastModes(), castModeSetPresentationAndTab); - // [Default: 1,2; Tab: A] - sources.AddSource(MediaCastMode::DEFAULT, defaultSource2); - EXPECT_TRUE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource2)); - EXPECT_EQ(sources.GetCastModes(), castModeSetDefaultAndTab); + // [Presentation: 1,2; Tab: A] + sources.AddSource(MediaCastMode::PRESENTATION, presentationSource2); + EXPECT_TRUE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource2)); + EXPECT_EQ(sources.GetCastModes(), castModeSetPresentationAndTab); - // [Default: 2; Tab: A] - sources.RemoveSource(MediaCastMode::DEFAULT, defaultSource1); - EXPECT_FALSE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource1)); - EXPECT_TRUE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource2)); - EXPECT_EQ(sources.GetCastModes(), castModeSetDefaultAndTab); + // [Presentation: 2; Tab: A] + sources.RemoveSource(MediaCastMode::PRESENTATION, presentationSource1); + EXPECT_FALSE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource1)); + EXPECT_TRUE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource2)); + EXPECT_EQ(sources.GetCastModes(), castModeSetPresentationAndTab); // [Tab: A] - sources.RemoveSource(MediaCastMode::DEFAULT, defaultSource2); - EXPECT_FALSE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource1)); + sources.RemoveSource(MediaCastMode::PRESENTATION, presentationSource2); + EXPECT_FALSE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource1)); EXPECT_FALSE(sources.IsEmpty()); EXPECT_EQ(sources.GetCastModes(), castModeSetTab); // [] sources.RemoveSource(MediaCastMode::TAB_MIRROR, tabSourceA); - EXPECT_FALSE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource1)); - EXPECT_FALSE(sources.HasSource(MediaCastMode::DEFAULT, defaultSource2)); + EXPECT_FALSE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource1)); + EXPECT_FALSE( + sources.HasSource(MediaCastMode::PRESENTATION, presentationSource2)); EXPECT_FALSE(sources.HasSource(MediaCastMode::TAB_MIRROR, tabSourceA)); EXPECT_TRUE(sources.IsEmpty()); EXPECT_EQ(sources.GetCastModes(), castModeSetEmpty); diff --git a/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.cc b/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.cc index f742fa7012d..7a5a75a9635 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.cc @@ -11,19 +11,19 @@ namespace media_router { -std::string MediaCastModeToDescription( - MediaCastMode mode, const std::string& host) { +std::string MediaCastModeToDescription(MediaCastMode mode, + const std::string& host) { switch (mode) { - case MediaCastMode::DEFAULT: - return l10n_util::GetStringFUTF8( - IDS_MEDIA_ROUTER_DEFAULT_CAST_MODE, - base::UTF8ToUTF16(host)); + case MediaCastMode::PRESENTATION: + return l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_PRESENTATION_CAST_MODE, + base::UTF8ToUTF16(host)); case MediaCastMode::TAB_MIRROR: - return l10n_util::GetStringUTF8( - IDS_MEDIA_ROUTER_TAB_MIRROR_CAST_MODE); + return l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_TAB_MIRROR_CAST_MODE); case MediaCastMode::DESKTOP_MIRROR: return l10n_util::GetStringUTF8( IDS_MEDIA_ROUTER_DESKTOP_MIRROR_CAST_MODE); + case MediaCastMode::LOCAL_FILE: + return l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_LOCAL_FILE_CAST_MODE); default: NOTREACHED(); return ""; @@ -32,9 +32,10 @@ std::string MediaCastModeToDescription( bool IsValidCastModeNum(int cast_mode_num) { switch (cast_mode_num) { - case MediaCastMode::DEFAULT: + case MediaCastMode::PRESENTATION: case MediaCastMode::TAB_MIRROR: case MediaCastMode::DESKTOP_MIRROR: + case MediaCastMode::LOCAL_FILE: return true; default: return false; diff --git a/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.h b/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.h index 9a3a7baa7fd..3916ab98abb 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.h +++ b/chromium/chrome/browser/ui/webui/media_router/media_cast_mode.h @@ -14,18 +14,20 @@ namespace media_router { // be presented to a media sink. These must be declared in the priority order // returned by GetPreferredCastMode. enum MediaCastMode { - // A presentation URL provided by the WebContents via the Presentation API. - // This can be set by the default presentation URL (for top level browsing - // contexts) or presentation URLs passed with a PresentationRequest (for top - // level and nested browsing contexts). - // TODO(mfoltz): More accurately named PRESENTATION - DEFAULT = 0x1, - // Capture the rendered WebContents and stream it to a media sink. Always - // available. + // PresentationRequests (and their associated URLs) provided via the + // Presentation API. A top-level browsing context can set a + // PresentationRequest as the page-level default, or any frame can use one by + // calling PresentationRequest.start(). Available when the Presentation API + // is used and there is a compatible sink. + PRESENTATION = 0x1, + // Capture the rendered WebContents and stream it to a media sink. Available + // when there is a compatible sink. TAB_MIRROR = 0x2, - // Capture the entire desktop and stream it to a media sink. Always - // available. + // Capture the entire desktop and stream it to a media sink. Available when + // there is a compatible sink. DESKTOP_MIRROR = 0x4, + // Take a local media file to open in a tab and cast. + LOCAL_FILE = 0x8, }; using CastModeSet = std::set<MediaCastMode>; diff --git a/chromium/chrome/browser/ui/webui/media_router/media_cast_mode_unittest.cc b/chromium/chrome/browser/ui/webui/media_router/media_cast_mode_unittest.cc index 574cdadc2aa..b7b93f0fa18 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_cast_mode_unittest.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_cast_mode_unittest.cc @@ -13,8 +13,9 @@ using testing::HasSubstr; namespace media_router { TEST(MediaCastModeTest, MediaCastModeToDescription) { - EXPECT_FALSE(MediaCastModeToDescription(MediaCastMode::DEFAULT, "youtube.com") - .empty()); + EXPECT_FALSE( + MediaCastModeToDescription(MediaCastMode::PRESENTATION, "youtube.com") + .empty()); EXPECT_FALSE( MediaCastModeToDescription(MediaCastMode::TAB_MIRROR, "").empty()); EXPECT_FALSE( @@ -22,7 +23,7 @@ TEST(MediaCastModeTest, MediaCastModeToDescription) { } TEST(MediaCastModeTest, IsValidCastModeNum) { - EXPECT_TRUE(IsValidCastModeNum(MediaCastMode::DEFAULT)); + EXPECT_TRUE(IsValidCastModeNum(MediaCastMode::PRESENTATION)); EXPECT_TRUE(IsValidCastModeNum(MediaCastMode::TAB_MIRROR)); EXPECT_TRUE(IsValidCastModeNum(MediaCastMode::DESKTOP_MIRROR)); EXPECT_FALSE(IsValidCastModeNum(-1)); diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc new file mode 100644 index 00000000000..517e61fbadb --- /dev/null +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog.cc @@ -0,0 +1,285 @@ +// 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 "chrome/browser/ui/webui/media_router/media_router_file_dialog.h" + +#include "base/bind.h" +#include "base/task/cancelable_task_tracker.h" +#include "base/task_scheduler/post_task.h" +#include "chrome/browser/media/router/media_router_metrics.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/media_router/issue.h" +#include "chrome/grit/generated_resources.h" +#include "media/base/container_names.h" +#include "media/base/mime_util.h" +#include "net/base/filename_util.h" +#include "net/base/mime_util.h" +#include "ui/base/l10n/l10n_util.h" + +namespace media_router { + +namespace { + +base::string16 GetFileName(const ui::SelectedFileInfo& file_info) { + return file_info.file_path.BaseName().LossyDisplayName(); +} + +// Returns info about extensions for files we support as audio video files. +ui::SelectFileDialog::FileTypeInfo GetAudioVideoFileTypeInfo() { + ui::SelectFileDialog::FileTypeInfo file_type_info; + + file_type_info.allowed_paths = ui::SelectFileDialog::FileTypeInfo::ANY_PATH; + + std::vector<base::FilePath::StringType> extensions; + + // Add all extensions from the audio and video mime types. + net::GetExtensionsForMimeType("video/*", &extensions); + net::GetExtensionsForMimeType("audio/*", &extensions); + + // Filter based on what can be played on the media player + std::vector<base::FilePath::StringType> filtered_extensions; + std::copy_if(extensions.begin(), extensions.end(), + std::back_inserter(filtered_extensions), + [](const base::FilePath::StringType& extension) { + std::string mime_type; + net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); + return media::IsSupportedMediaMimeType(mime_type); + }); + + // Add all audio and video extensions as a single type to the dialog. + file_type_info.extensions.push_back(filtered_extensions); + + // Set the description, otherwise it lists all the possible extensions which + // looks bad. + file_type_info.extension_description_overrides.push_back( + l10n_util::GetStringUTF16( + IDS_MEDIA_ROUTER_FILE_DIALOG_AUDIO_VIDEO_FILTER)); + + // Add an option for all files + file_type_info.include_all_files = true; + + return file_type_info; +} + +} // namespace + +// FileSystemDelegate default implementations +MediaRouterFileDialog::FileSystemDelegate::FileSystemDelegate() = default; +MediaRouterFileDialog::FileSystemDelegate::~FileSystemDelegate() = default; + +bool MediaRouterFileDialog::FileSystemDelegate::FileExists( + const base::FilePath& file_path) const { + // We assume if the path exists, the file exists. + return base::PathExists(file_path); +} + +bool MediaRouterFileDialog::FileSystemDelegate::IsFileReadable( + const base::FilePath& file_path) const { + char buffer[1]; + return base::ReadFile(file_path, buffer, 1) != -1; +} + +bool MediaRouterFileDialog::FileSystemDelegate::IsFileTypeSupported( + const base::FilePath& file_path) const { + std::string mime_type; + net::GetMimeTypeFromFile(file_path, &mime_type); + return media::IsSupportedMediaMimeType(mime_type); +} + +int64_t MediaRouterFileDialog::FileSystemDelegate::GetFileSize( + const base::FilePath& file_path) const { + int64_t file_size; + return base::GetFileSize(file_path, &file_size) ? file_size : -1; +} + +base::FilePath +MediaRouterFileDialog::FileSystemDelegate::GetLastSelectedDirectory( + Browser* browser) const { + return browser->profile()->last_selected_directory(); +} + +void MediaRouterFileDialog::FileSystemDelegate::OpenFileDialog( + ui::SelectFileDialog::Listener* listener, + const Browser* browser, + const base::FilePath& default_directory, + const ui::SelectFileDialog::FileTypeInfo* file_type_info) { + select_file_dialog_ = ui::SelectFileDialog::Create( + listener, new ChromeSelectFilePolicy( + browser->tab_strip_model()->GetActiveWebContents())); + + gfx::NativeWindow parent_window = browser->window()->GetNativeWindow(); + + select_file_dialog_->SelectFile( + ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), + default_directory, file_type_info, 0, base::FilePath::StringType(), + parent_window, nullptr /* |params| passed to the listener */); +} +// End of FileSystemDelegate default implementations + +MediaRouterFileDialog::MediaRouterFileDialog( + MediaRouterFileDialogDelegate* delegate) + : MediaRouterFileDialog(delegate, base::MakeUnique<FileSystemDelegate>()) {} + +// Used for tests +MediaRouterFileDialog::MediaRouterFileDialog( + MediaRouterFileDialogDelegate* delegate, + std::unique_ptr<FileSystemDelegate> file_system_delegate) + : task_runner_( + base::TaskScheduler::GetInstance()->CreateTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE})), + file_system_delegate_(std::move(file_system_delegate)), + delegate_(delegate) {} + +MediaRouterFileDialog::~MediaRouterFileDialog() = default; + +GURL MediaRouterFileDialog::GetLastSelectedFileUrl() { + return selected_file_.has_value() + ? net::FilePathToFileURL(selected_file_->local_path) + : GURL(); +} + +base::string16 MediaRouterFileDialog::GetLastSelectedFileName() { + return selected_file_.has_value() ? GetFileName(selected_file_.value()) + : base::string16(); +} + +void MediaRouterFileDialog::MaybeReportLastSelectedFileInformation() { + if (selected_file_.has_value()) { + cancelable_task_tracker_.PostTask( + task_runner_.get(), FROM_HERE, + base::BindOnce(&MediaRouterFileDialog::ReportFileFormat, + base::Unretained(this), selected_file_->local_path)); + + cancelable_task_tracker_.PostTask( + task_runner_.get(), FROM_HERE, + base::BindOnce(&MediaRouterFileDialog::ReportFileSize, + base::Unretained(this), selected_file_->local_path)); + } else { + VLOG(1) << "MediaRouterFileDialog did not report file information; no file " + "to report."; + } +} + +void MediaRouterFileDialog::OpenFileDialog(Browser* browser) { + const base::FilePath directory = + file_system_delegate_->GetLastSelectedDirectory(browser); + + const ui::SelectFileDialog::FileTypeInfo file_type_info = + GetAudioVideoFileTypeInfo(); + + file_system_delegate_->OpenFileDialog(this, browser, directory, + &file_type_info); +} + +void MediaRouterFileDialog::ReportFileFormat(const base::FilePath& filename) { + // Windows implementation of ReadFile fails if file smaller than desired size, + // so use file length if file less than 8192 bytes (http://crbug.com/243885). + char buffer[8192]; + int read_size = sizeof(buffer); + int64_t actual_size; + if (base::GetFileSize(filename, &actual_size) && actual_size < read_size) + read_size = actual_size; + int read = base::ReadFile(filename, buffer, read_size); + + MediaRouterMetrics::RecordMediaRouterFileFormat( + media::container_names::DetermineContainer( + reinterpret_cast<const uint8_t*>(buffer), read)); +} + +void MediaRouterFileDialog::ReportFileSize(const base::FilePath& filename) { + int64_t size; + if (base::GetFileSize(filename, &size)) { + MediaRouterMetrics::RecordMediaRouterFileSize(size); + } else { + VLOG(1) << "Can't get file size for file: " << filename.LossyDisplayName() + << "."; + } +} + +void MediaRouterFileDialog::FileSelected(const base::FilePath& path, + int index, + void* params) { + FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); +} + +void MediaRouterFileDialog::FileSelectedWithExtraInfo( + const ui::SelectedFileInfo& file_info, + int index, + void* params) { + cancelable_task_tracker_.PostTaskAndReplyWithResult( + task_runner_.get(), FROM_HERE, + base::BindOnce(&MediaRouterFileDialog::ValidateFile, + base::Unretained(this), file_info), + base::BindOnce(&MediaRouterFileDialog::OnValidationResults, + base::Unretained(this), file_info)); +} + +void MediaRouterFileDialog::OnValidationResults( + ui::SelectedFileInfo file_info, + MediaRouterFileDialog::ValidationResult validation_result) { + if (validation_result == MediaRouterFileDialog::FILE_OK) { + selected_file_ = file_info; + delegate_->FileDialogFileSelected(file_info); + } else { + delegate_->FileDialogSelectionFailed( + CreateIssue(file_info, validation_result)); + } +} + +void MediaRouterFileDialog::FileSelectionCanceled(void* params) { + delegate_->FileDialogSelectionCanceled(); +} + +IssueInfo MediaRouterFileDialog::CreateIssue( + const ui::SelectedFileInfo& file_info, + MediaRouterFileDialog::ValidationResult validation_result) { + std::string issue_title; + switch (validation_result) { + case MediaRouterFileDialog::FILE_MISSING: + case MediaRouterFileDialog::FILE_EMPTY: + case MediaRouterFileDialog::FILE_TYPE_NOT_SUPPORTED: + case MediaRouterFileDialog::READ_FAILURE: + issue_title = l10n_util::GetStringFUTF8( + IDS_MEDIA_ROUTER_ISSUE_FILE_CAST_ERROR, GetFileName(file_info)); + break; + case MediaRouterFileDialog::FILE_OK: + // Create issue shouldn't be called with FILE_OK, but to ensure things + // compile, fall through sets |issue_title| to the generic error. + NOTREACHED(); + case MediaRouterFileDialog::UNKNOWN_FAILURE: + issue_title = l10n_util::GetStringUTF8( + IDS_MEDIA_ROUTER_ISSUE_FILE_CAST_GENERIC_ERROR); + break; + } + return IssueInfo(issue_title, IssueInfo::Action::DISMISS, + IssueInfo::Severity::WARNING); +} + +MediaRouterFileDialog::ValidationResult MediaRouterFileDialog::ValidateFile( + const ui::SelectedFileInfo& file_info) { + // Attempt to determine if file exsists. + if (!file_system_delegate_->FileExists(file_info.local_path)) + return MediaRouterFileDialog::FILE_MISSING; + + // Attempt to read the file size and verify that the file has contents. + int file_size = file_system_delegate_->GetFileSize(file_info.local_path); + if (file_size < 0) + return MediaRouterFileDialog::READ_FAILURE; + + if (file_size == 0) + return MediaRouterFileDialog::FILE_EMPTY; + + if (!file_system_delegate_->IsFileReadable(file_info.local_path)) + return MediaRouterFileDialog::READ_FAILURE; + + if (!file_system_delegate_->IsFileTypeSupported(file_info.local_path)) + return MediaRouterFileDialog::FILE_TYPE_NOT_SUPPORTED; + + return MediaRouterFileDialog::FILE_OK; +} + +} // namespace media_router diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog.h b/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog.h new file mode 100644 index 00000000000..29e8bac59eb --- /dev/null +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog.h @@ -0,0 +1,162 @@ +// 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 CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_FILE_DIALOG_H_ +#define CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_FILE_DIALOG_H_ + +#include "base/files/file_util.h" +#include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/ui/chrome_select_file_policy.h" +#include "chrome/common/media_router/issue.h" +#include "ui/shell_dialogs/select_file_dialog.h" +#include "ui/shell_dialogs/selected_file_info.h" +#include "url/gurl.h" + +class Browser; + +namespace base { +class FilePath; +} + +namespace media_router { + +class MediaRouterFileDialog : public ui::SelectFileDialog::Listener { + public: + // The reasons that the file selection might have failed. Passed into the + // failure callback. + enum ValidationResult { + FILE_OK, + // File does not exist. + FILE_MISSING, + // The selected file is empty. + FILE_EMPTY, + // This file type is not supported by the chrome player. + FILE_TYPE_NOT_SUPPORTED, + // The selected file cannot be read. + READ_FAILURE, + // The reason for the failure is unknown. + UNKNOWN_FAILURE, + }; + + class MediaRouterFileDialogDelegate { + public: + virtual ~MediaRouterFileDialogDelegate() {} + + // Called when a file is selected by the user to store the files information + // and tell the message handler to pass along the information. + virtual void FileDialogFileSelected( + const ui::SelectedFileInfo& file_info) = 0; + + // Called when the file selection fails. + virtual void FileDialogSelectionFailed(const IssueInfo& issue) = 0; + + // Called when the file selection is canceled by the user. Optionally + // implementable. + virtual void FileDialogSelectionCanceled() {} + }; + + // A class which defines functions to interact with the file systems. + class FileSystemDelegate { + public: + FileSystemDelegate(); + virtual ~FileSystemDelegate(); + + // Checks if a file exists. + virtual bool FileExists(const base::FilePath& file_path) const; + + // Checks if a file can be read. + virtual bool IsFileReadable(const base::FilePath& file_path) const; + + // Checks if the file type is supported in this browser. + virtual bool IsFileTypeSupported(const base::FilePath& file_path) const; + + // Checks the size of a file, returns -1 if the file size cannot be read. + virtual int64_t GetFileSize(const base::FilePath& file_path) const; + + // Gets the last selected directory based on the browser. + virtual base::FilePath GetLastSelectedDirectory(Browser* browser) const; + + // Opens a dialog with |file_type_info| as the configuration, and shows + // |default_directory| as the starting place. + virtual void OpenFileDialog( + ui::SelectFileDialog::Listener* listener, + const Browser* browser, + const base::FilePath& default_directory, + const ui::SelectFileDialog::FileTypeInfo* file_type_info); + + private: + // The dialog object for the file dialog. Needs to be kept in scope while + // the dialog is open, but is not used for anything else. + scoped_refptr<ui::SelectFileDialog> select_file_dialog_; + }; + + explicit MediaRouterFileDialog(MediaRouterFileDialogDelegate* delegate); + + // Constuctor with injectable FileSystemDelegate, used for tests. + MediaRouterFileDialog( + MediaRouterFileDialogDelegate* delegate, + std::unique_ptr<FileSystemDelegate> file_system_delegate); + + ~MediaRouterFileDialog() override; + + virtual GURL GetLastSelectedFileUrl(); + virtual base::string16 GetLastSelectedFileName(); + + // Checks if a file has been recorded as being selected, then attempts to + // report interesting information about the file, such as format. + virtual void MaybeReportLastSelectedFileInformation(); + + // Opens the dialog configured to get a media file. + virtual void OpenFileDialog(Browser* browser); + + private: + // Reports the format of a file to the UMA stats. + void ReportFileFormat(const base::FilePath& filename); + + // Reports the size of a file to the UMA stats. + void ReportFileSize(const base::FilePath& filename); + + // Overridden from SelectFileDialog::Listener: + void FileSelected(const base::FilePath& path, + int index, + void* params) override; + void FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file_info, + int index, + void* params) override; + void FileSelectionCanceled(void* params) override; + + // Returns a reason for failure if the file is not valid, or base::nullopt if + // it passes validation. Has to be run on seperate thread. + ValidationResult ValidateFile(const ui::SelectedFileInfo& file_info); + + // Takes a file info and optionally a reason for validation failure, and calls + // the appropriate delegate function. + void OnValidationResults( + ui::SelectedFileInfo file_info, + MediaRouterFileDialog::ValidationResult validation_result); + + IssueInfo CreateIssue( + const ui::SelectedFileInfo& file_info, + MediaRouterFileDialog::ValidationResult validation_result); + + // Used to post file operations. Cleans up after itself and cancels unrun + // tasks when destructed. + base::CancelableTaskTracker cancelable_task_tracker_; + scoped_refptr<base::TaskRunner> task_runner_; + + // Pointer to the file last indicated by the system. + base::Optional<ui::SelectedFileInfo> selected_file_; + + // The object which all file system calls go through. + std::unique_ptr<FileSystemDelegate> file_system_delegate_; + + // Object which the media router file dialog callbacks get sent to. + MediaRouterFileDialogDelegate* const delegate_; + + DISALLOW_COPY_AND_ASSIGN(MediaRouterFileDialog); +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_FILE_DIALOG_H_ diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog_unittest.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog_unittest.cc new file mode 100644 index 00000000000..3f644663ad0 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_file_dialog_unittest.cc @@ -0,0 +1,193 @@ +// 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 "chrome/browser/ui/webui/media_router/media_router_file_dialog.h" + +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/task_scheduler.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/common/media_router/issue.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" + +using testing::_; +using testing::ContainsRegex; +using testing::Field; +using testing::InvokeWithoutArgs; +using testing::Return; +using testing::Test; + +namespace media_router { + +namespace { + +// Clears out async tasks +void FlushTasks() { + base::TaskScheduler::GetInstance()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); +} + +} // namespace + +class MockDelegate + : public MediaRouterFileDialog::MediaRouterFileDialogDelegate { + public: + MOCK_METHOD1(FileDialogFileSelected, + void(const ui::SelectedFileInfo& file_info)); + MOCK_METHOD1(FileDialogSelectionFailed, void(const IssueInfo& issue)); + MOCK_METHOD0(FileDialogSelectionCanceled, void()); +}; + +class MockFileSystemDelegate + : public MediaRouterFileDialog::FileSystemDelegate { + public: + MockFileSystemDelegate() : MediaRouterFileDialog::FileSystemDelegate() {} + ~MockFileSystemDelegate() override {} + + MOCK_CONST_METHOD1(FileExists, bool(const base::FilePath& file_path)); + MOCK_CONST_METHOD1(IsFileReadable, bool(const base::FilePath& file_path)); + MOCK_CONST_METHOD1(IsFileTypeSupported, + bool(const base::FilePath& file_path)); + MOCK_CONST_METHOD1(GetFileSize, int64_t(const base::FilePath& file_path)); + MOCK_CONST_METHOD1(GetLastSelectedDirectory, + base::FilePath(Browser* browser)); + MOCK_METHOD4(OpenFileDialog, + void(ui::SelectFileDialog::Listener* listener, + const Browser* browser, + const base::FilePath& default_directory, + const ui::SelectFileDialog::FileTypeInfo* file_type_info)); +}; + +class MediaRouterFileDialogTest : public Test { + public: + MediaRouterFileDialogTest() { + fake_path = base::FilePath(FILE_PATH_LITERAL("im/a/fake_path.mp3")); + + scoped_feature_list_.InitFromCommandLine( + "EnableCastLocalMedia" /* enabled features */, + std::string() /* disabled features */); + } + + void SetUp() override { + mock_delegate_ = base::MakeUnique<MockDelegate>(); + + auto temp_mock = base::MakeUnique<MockFileSystemDelegate>(); + mock_file_system_delegate = temp_mock.get(); + + dialog_ = base::MakeUnique<MediaRouterFileDialog>(mock_delegate_.get(), + std::move(temp_mock)); + dialog_as_listener_ = dialog_.get(); + + // Setup default file checks to all pass + ON_CALL(*mock_file_system_delegate, FileExists(_)) + .WillByDefault(Return(true)); + ON_CALL(*mock_file_system_delegate, IsFileReadable(_)) + .WillByDefault(Return(true)); + ON_CALL(*mock_file_system_delegate, IsFileTypeSupported(_)) + .WillByDefault(Return(true)); + ON_CALL(*mock_file_system_delegate, GetFileSize(_)) + .WillByDefault(Return(1)); + } + + void FileSelectedExpectFailure(base::FilePath fake_path) { + fake_path_name = fake_path.BaseName().LossyDisplayName(); + std::string error_title = l10n_util::GetStringFUTF8( + IDS_MEDIA_ROUTER_ISSUE_FILE_CAST_ERROR, fake_path_name); + + EXPECT_CALL(*mock_delegate_, FileDialogSelectionFailed( + Field(&IssueInfo::title, error_title))); + + dialog_as_listener_->FileSelected(fake_path, 0, 0); + + // Flush out the async file validation calls + FlushTasks(); + } + + protected: + std::unique_ptr<MockDelegate> mock_delegate_; + MockFileSystemDelegate* mock_file_system_delegate = nullptr; + std::unique_ptr<MediaRouterFileDialog> dialog_; + + // Used for simulating calls from a SelectFileDialog. + ui::SelectFileDialog::Listener* dialog_as_listener_ = nullptr; + + base::FilePath fake_path; + base::string16 fake_path_name; + + base::test::ScopedFeatureList scoped_feature_list_; + content::TestBrowserThreadBundle thread_bundle_; +}; + +TEST_F(MediaRouterFileDialogTest, SelectFileSuccess) { + // File selection succeeds, success callback called with the right file info. + // Selected file URL is set properly. + + // Expect all the checks and return passes + EXPECT_CALL(*mock_file_system_delegate, FileExists(fake_path)) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_file_system_delegate, IsFileReadable(fake_path)) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_file_system_delegate, GetFileSize(fake_path)) + .WillOnce(Return(1)); + + EXPECT_CALL(*mock_delegate_, + FileDialogFileSelected( + Field(&ui::SelectedFileInfo::local_path, fake_path))); + + dialog_as_listener_->FileSelected(fake_path, 0, 0); + + FlushTasks(); + + ASSERT_THAT(dialog_->GetLastSelectedFileUrl().GetContent(), + ContainsRegex(base::UTF16ToUTF8(fake_path.LossyDisplayName()))); +} + +TEST_F(MediaRouterFileDialogTest, SelectFileCanceled) { + // File selection gets cancelled, failure callback called + EXPECT_CALL(*mock_delegate_, FileDialogSelectionCanceled()); + + dialog_as_listener_->FileSelectionCanceled(0); +} + +TEST_F(MediaRouterFileDialogTest, SelectFailureFileDoesNotExist) { + EXPECT_CALL(*mock_file_system_delegate, FileExists(fake_path)) + .WillOnce(Return(false)); + + FileSelectedExpectFailure(fake_path); +} + +TEST_F(MediaRouterFileDialogTest, SelectFailureFileDoesNotContainContent) { + EXPECT_CALL(*mock_file_system_delegate, GetFileSize(fake_path)) + .WillOnce(Return(0)); + + FileSelectedExpectFailure(fake_path); +} + +TEST_F(MediaRouterFileDialogTest, SelectFailureCannotReadGetFileSize) { + EXPECT_CALL(*mock_file_system_delegate, GetFileSize(fake_path)) + .WillOnce(Return(-1)); + + FileSelectedExpectFailure(fake_path); +} + +TEST_F(MediaRouterFileDialogTest, SelectFailureCannotReadFile) { + EXPECT_CALL(*mock_file_system_delegate, IsFileReadable(fake_path)) + .WillOnce(Return(false)); + + FileSelectedExpectFailure(fake_path); +} + +TEST_F(MediaRouterFileDialogTest, SelectFailureFileNotSupported) { + EXPECT_CALL(*mock_file_system_delegate, IsFileTypeSupported(fake_path)) + .WillOnce(Return(false)); + + FileSelectedExpectFailure(fake_path); +} + +} // namespace media_router diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc index 6345cbec2b1..17af03a9c93 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc @@ -15,27 +15,40 @@ const char kLocalizedStringsFile[] = "strings.js"; void AddMediaRouterStrings(content::WebUIDataSource* html_source) { html_source->AddLocalizedString("mediaRouterTitle", IDS_MEDIA_ROUTER_TITLE); - html_source->AddLocalizedString("learnMoreText", - IDS_MEDIA_ROUTER_LEARN_MORE); + html_source->AddLocalizedString("learnMoreText", IDS_MEDIA_ROUTER_LEARN_MORE); html_source->AddLocalizedString("backButtonTitle", IDS_MEDIA_ROUTER_BACK_BUTTON_TITLE); html_source->AddLocalizedString("closeButtonTitle", IDS_MEDIA_ROUTER_CLOSE_BUTTON_TITLE); html_source->AddLocalizedString("searchButtonTitle", IDS_MEDIA_ROUTER_SEARCH_BUTTON_TITLE); - html_source->AddLocalizedString("viewCastModeListButtonTitle", + html_source->AddLocalizedString( + "viewCastModeListButtonTitle", IDS_MEDIA_ROUTER_VIEW_CAST_MODE_LIST_BUTTON_TITLE); - html_source->AddLocalizedString("viewDeviceListButtonTitle", + html_source->AddLocalizedString( + "viewDeviceListButtonTitle", IDS_MEDIA_ROUTER_VIEW_DEVICE_LIST_BUTTON_TITLE); } void AddRouteDetailsStrings(content::WebUIDataSource* html_source) { html_source->AddLocalizedString("castingActivityStatus", - IDS_MEDIA_ROUTER_CASTING_ACTIVITY_STATUS); + IDS_MEDIA_ROUTER_CASTING_ACTIVITY_STATUS); html_source->AddLocalizedString("stopCastingButtonText", - IDS_MEDIA_ROUTER_STOP_CASTING_BUTTON); + IDS_MEDIA_ROUTER_STOP_CASTING_BUTTON); html_source->AddLocalizedString("startCastingButtonText", IDS_MEDIA_ROUTER_START_CASTING_BUTTON); + html_source->AddLocalizedString("playTitle", + IDS_MEDIA_ROUTER_ROUTE_DETAILS_PLAY_TITLE); + html_source->AddLocalizedString("pauseTitle", + IDS_MEDIA_ROUTER_ROUTE_DETAILS_PAUSE_TITLE); + html_source->AddLocalizedString("muteTitle", + IDS_MEDIA_ROUTER_ROUTE_DETAILS_MUTE_TITLE); + html_source->AddLocalizedString("unmuteTitle", + IDS_MEDIA_ROUTER_ROUTE_DETAILS_UNMUTE_TITLE); + html_source->AddLocalizedString("seekTitle", + IDS_MEDIA_ROUTER_ROUTE_DETAILS_SEEK_TITLE); + html_source->AddLocalizedString("volumeTitle", + IDS_MEDIA_ROUTER_ROUTE_DETAILS_VOLUME_TITLE); } void AddIssuesStrings(content::WebUIDataSource* html_source) { @@ -46,13 +59,18 @@ void AddIssuesStrings(content::WebUIDataSource* html_source) { } void AddMediaRouterContainerStrings(content::WebUIDataSource* html_source) { + html_source->AddLocalizedString("castLocalMediaSubheadingText", + IDS_MEDIA_ROUTER_CAST_LOCAL_MEDIA_SUBHEADING); + html_source->AddLocalizedString("castLocalMediaSelectedFileTitle", + IDS_MEDIA_ROUTER_CAST_LOCAL_MEDIA_TITLE); html_source->AddLocalizedString("firstRunFlowButtonText", IDS_MEDIA_ROUTER_FIRST_RUN_FLOW_BUTTON); html_source->AddLocalizedString("firstRunFlowText", IDS_MEDIA_ROUTER_FIRST_RUN_FLOW_TEXT); html_source->AddLocalizedString("firstRunFlowTitle", IDS_MEDIA_ROUTER_FIRST_RUN_FLOW_TITLE); - html_source->AddLocalizedString("firstRunFlowCloudPrefText", + html_source->AddLocalizedString( + "firstRunFlowCloudPrefText", IDS_MEDIA_ROUTER_FIRST_RUN_FLOW_CLOUD_PREF_TEXT); html_source->AddLocalizedString("autoCastMode", IDS_MEDIA_ROUTER_AUTO_CAST_MODE); @@ -63,8 +81,9 @@ void AddMediaRouterContainerStrings(content::WebUIDataSource* html_source) { html_source->AddLocalizedString("searchNoMatchesText", IDS_MEDIA_ROUTER_SEARCH_NO_MATCHES); html_source->AddLocalizedString("selectCastModeHeaderText", - IDS_MEDIA_ROUTER_SELECT_CAST_MODE_HEADER); - html_source->AddLocalizedString("shareYourScreenSubheadingText", + IDS_MEDIA_ROUTER_SELECT_CAST_MODE_HEADER); + html_source->AddLocalizedString( + "shareYourScreenSubheadingText", IDS_MEDIA_ROUTER_SHARE_YOUR_SCREEN_SUBHEADING); } diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_resources_provider.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_resources_provider.cc index 6450288a4c6..79861a064a9 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_resources_provider.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_resources_provider.cc @@ -64,9 +64,14 @@ void AddPolymerElements(content::WebUIDataSource* html_source) { "elements/media_router_search_highlighter/" "media_router_search_highlighter.js", IDR_MEDIA_ROUTER_SEARCH_HIGHLIGHTER_JS); - html_source->AddResourcePath( - "elements/route_details/route_details.css", - IDR_ROUTE_DETAILS_CSS); + html_source->AddResourcePath("elements/route_controls/route_controls.css", + IDR_ROUTE_CONTROLS_CSS); + html_source->AddResourcePath("elements/route_controls/route_controls.html", + IDR_ROUTE_CONTROLS_HTML); + html_source->AddResourcePath("elements/route_controls/route_controls.js", + IDR_ROUTE_CONTROLS_JS); + html_source->AddResourcePath("elements/route_details/route_details.css", + IDR_ROUTE_DETAILS_CSS); html_source->AddResourcePath( "elements/route_details/route_details.html", IDR_ROUTE_DETAILS_HTML); @@ -76,6 +81,17 @@ void AddPolymerElements(content::WebUIDataSource* html_source) { html_source->AddResourcePath( "elements/media_router_container/pseudo_sink_search_state.js", IDR_PSEUDO_SINK_SEARCH_STATE_JS); + html_source->AddResourcePath( + "elements/route_details/extension_view_wrapper/" + "extension_view_wrapper.html", + IDR_EXTENSION_VIEW_WRAPPER_HTML); + html_source->AddResourcePath( + "elements/route_details/extension_view_wrapper/extension_view_wrapper.js", + IDR_EXTENSION_VIEW_WRAPPER_JS); + html_source->AddResourcePath( + "elements/route_details/extension_view_wrapper/" + "extension_view_wrapper.css", + IDR_EXTENSION_VIEW_WRAPPER_CSS); } } // namespace diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_ui.cc index 044db042dda..679cf901b03 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_ui.cc @@ -18,9 +18,12 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/media/router/create_presentation_connection_request.h" +#include "chrome/browser/media/router/event_page_request_manager.h" +#include "chrome/browser/media/router/event_page_request_manager_factory.h" #include "chrome/browser/media/router/issues_observer.h" #include "chrome/browser/media/router/media_router.h" #include "chrome/browser/media/router/media_router_factory.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/router/media_router_metrics.h" #include "chrome/browser/media/router/media_routes_observer.h" #include "chrome/browser/media/router/media_sinks_observer.h" @@ -28,6 +31,10 @@ #include "chrome/browser/media/router/presentation_service_delegate_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_tab_helper.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.h" #include "chrome/browser/ui/webui/media_router/media_router_resources_provider.h" #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h" @@ -61,10 +68,12 @@ namespace { // The amount of time to wait for a response when creating a new route. const int kCreateRouteTimeoutSeconds = 20; const int kCreateRouteTimeoutSecondsForTab = 60; +const int kCreateRouteTimeoutSecondsForLocalFile = 60; const int kCreateRouteTimeoutSecondsForDesktop = 120; std::string GetHostFromURL(const GURL& gurl) { - if (gurl.is_empty()) return std::string(); + if (gurl.is_empty()) + return std::string(); std::string host = gurl.host(); if (base::StartsWith(host, "www.", base::CompareCase::INSENSITIVE_ASCII)) host = host.substr(4); @@ -82,12 +91,15 @@ std::string TruncateHost(const std::string& host) { base::TimeDelta GetRouteRequestTimeout(MediaCastMode cast_mode) { switch (cast_mode) { - case DEFAULT: + case PRESENTATION: return base::TimeDelta::FromSeconds(kCreateRouteTimeoutSeconds); case TAB_MIRROR: return base::TimeDelta::FromSeconds(kCreateRouteTimeoutSecondsForTab); case DESKTOP_MIRROR: return base::TimeDelta::FromSeconds(kCreateRouteTimeoutSecondsForDesktop); + case LOCAL_FILE: + return base::TimeDelta::FromSeconds( + kCreateRouteTimeoutSecondsForLocalFile); default: NOTREACHED(); return base::TimeDelta(); @@ -107,8 +119,10 @@ MediaSource GetSourceForRouteObserver(const std::vector<MediaSource>& sources) { // static std::string MediaRouterUI::GetExtensionName( - const GURL& gurl, extensions::ExtensionRegistry* registry) { - if (gurl.is_empty() || !registry) return std::string(); + const GURL& gurl, + extensions::ExtensionRegistry* registry) { + if (gurl.is_empty() || !registry) + return std::string(); const extensions::Extension* extension = registry->enabled_extensions().GetExtensionOrAppByURL(gurl); @@ -116,6 +130,32 @@ std::string MediaRouterUI::GetExtensionName( return extension ? extension->name() : std::string(); } +Browser* MediaRouterUI::GetBrowser() { + return chrome::FindBrowserWithWebContents(initiator()); +} + +void MediaRouterUI::OpenTabWithUrl(const GURL url) { + // Check if the current page is a new tab. If so open file in current page. + // If not then open a new page. + if (initiator_->GetVisibleURL() == chrome::kChromeUINewTabURL) { + content::NavigationController::LoadURLParams load_params(url); + load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; + initiator_->GetController().LoadURLWithParams(load_params); + } else { + initiator_ = chrome::AddSelectedTabWithURL(GetBrowser(), url, + ui::PAGE_TRANSITION_LINK); + } +} + +void MediaRouterUI::FileDialogFileSelected( + const ui::SelectedFileInfo& file_info) { + handler_->UserSelectedLocalMediaFile(file_info.display_name); +} + +void MediaRouterUI::FileDialogSelectionFailed(const IssueInfo& issue) { + AddIssue(issue); +} + // This class calls to refresh the UI when the highest priority issue is // updated. class MediaRouterUI::UIIssuesObserver : public IssuesObserver { @@ -192,9 +232,11 @@ MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) content::WebContents* wc = web_ui->GetWebContents(); DCHECK(wc); + content::BrowserContext* context = wc->GetBrowserContext(); - router_ = - MediaRouterFactory::GetApiForBrowserContext(wc->GetBrowserContext()); + router_ = MediaRouterFactory::GetApiForBrowserContext(context); + event_page_request_manager_ = + EventPageRequestManagerFactory::GetApiForBrowserContext(context); // Allows UI to load extensionview. // TODO(haibinlu): limit object-src to current extension once crbug/514866 @@ -211,7 +253,8 @@ MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) } MediaRouterUI::~MediaRouterUI() { - if (query_result_manager_.get()) query_result_manager_->RemoveObserver(this); + if (query_result_manager_.get()) + query_result_manager_->RemoveObserver(this); if (presentation_service_delegate_.get()) presentation_service_delegate_->RemoveDefaultPresentationRequestObserver( this); @@ -220,7 +263,8 @@ MediaRouterUI::~MediaRouterUI() { if (create_session_request_) { bool presentation_sinks_available = std::any_of( sinks_.begin(), sinks_.end(), [](const MediaSinkWithCastModes& sink) { - return base::ContainsValue(sink.cast_modes, MediaCastMode::DEFAULT); + return base::ContainsKey(sink.cast_modes, + MediaCastMode::PRESENTATION); }); if (presentation_sinks_available) { create_session_request_->InvokeErrorCallback(content::PresentationError( @@ -272,8 +316,7 @@ void MediaRouterUI::InitWithPresentationSessionRequest( presentation_service_delegate_ = delegate->GetWeakPtr(); InitCommon(initiator); - OnDefaultPresentationChanged( - create_session_request_->presentation_request()); + OnDefaultPresentationChanged(create_session_request_->presentation_request()); } void MediaRouterUI::InitCommon(content::WebContents* initiator) { @@ -286,7 +329,7 @@ void MediaRouterUI::InitCommon(content::WebContents* initiator) { // Presentation requests from content must show the origin requesting // presentation: crbug.com/704964 if (create_session_request_) - forced_cast_mode_ = MediaCastMode::DEFAULT; + forced_cast_mode_ = MediaCastMode::PRESENTATION; router_->OnUserGesture(); @@ -310,6 +353,13 @@ void MediaRouterUI::InitCommon(content::WebContents* initiator) { // Desktop mirror mode is always available. query_result_manager_->SetSourcesForCastMode( MediaCastMode::DESKTOP_MIRROR, {MediaSourceForDesktop()}, origin); + + // For now, file mirroring is always availible if enabled. + if (CastLocalMediaEnabled()) { + query_result_manager_->SetSourcesForCastMode( + MediaCastMode::LOCAL_FILE, {MediaSourceForTab(0)}, origin); + } + initiator_ = initiator; SessionID::id_type tab_id = SessionTabHelper::IdForTab(initiator); if (tab_id != -1) { @@ -329,11 +379,12 @@ void MediaRouterUI::InitForTest( MediaRouter* router, content::WebContents* initiator, MediaRouterWebUIMessageHandler* handler, - std::unique_ptr<CreatePresentationConnectionRequest> - create_session_request) { + std::unique_ptr<CreatePresentationConnectionRequest> create_session_request, + std::unique_ptr<MediaRouterFileDialog> file_dialog) { router_ = router; handler_ = handler; create_session_request_ = std::move(create_session_request); + media_router_file_dialog_ = std::move(file_dialog); InitCommon(initiator); if (create_session_request_) { OnDefaultPresentationChanged( @@ -346,7 +397,8 @@ void MediaRouterUI::OnDefaultPresentationChanged( std::vector<MediaSource> sources = presentation_request.GetMediaSources(); presentation_request_.reset(new PresentationRequest(presentation_request)); query_result_manager_->SetSourcesForCastMode( - MediaCastMode::DEFAULT, sources, presentation_request_->frame_origin()); + MediaCastMode::PRESENTATION, sources, + presentation_request_->frame_origin()); // Register for MediaRoute updates. NOTE(mfoltz): If there are multiple // sources that can be connected to via the dialog, this will break. We will // need to observe multiple sources (keyed by sinks) in that case. As this is @@ -363,7 +415,7 @@ void MediaRouterUI::OnDefaultPresentationChanged( void MediaRouterUI::OnDefaultPresentationRemoved() { presentation_request_.reset(); - query_result_manager_->RemoveSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_->RemoveSourcesForCastMode(MediaCastMode::PRESENTATION); // This should not be set if the dialog was initiated with a default // presentation request from the top level frame. However, clear it just to @@ -429,13 +481,20 @@ bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, std::vector<MediaRouteResponseCallback> route_response_callbacks; base::TimeDelta timeout; bool incognito; + + if (cast_mode == MediaCastMode::LOCAL_FILE) { + GURL url = media_router_file_dialog_->GetLastSelectedFileUrl(); + OpenTabWithUrl(url); + } + if (!SetRouteParameters(sink_id, cast_mode, &source_id, &origin, &route_response_callbacks, &timeout, &incognito)) { SendIssueForUnableToCast(cast_mode); return false; } + router_->CreateRoute(source_id, sink_id, origin, initiator_, - route_response_callbacks, timeout, incognito); + std::move(route_response_callbacks), timeout, incognito); return true; } @@ -456,8 +515,10 @@ bool MediaRouterUI::SetRouteParameters( // called. However, since the user does not have visibility into the // MediaSource, and that it occurs very rarely in practice, we leave it as-is // for now. + std::unique_ptr<MediaSource> source = query_result_manager_->GetSourceForCastModeAndSink(cast_mode, sink_id); + if (!source) { LOG(ERROR) << "No corresponding MediaSource for cast mode " << static_cast<int>(cast_mode) << " and sink " << sink_id; @@ -465,15 +526,15 @@ bool MediaRouterUI::SetRouteParameters( } *source_id = source->id(); - bool for_default_source = cast_mode == MediaCastMode::DEFAULT; - if (for_default_source && !presentation_request_) { + bool for_presentation_source = cast_mode == MediaCastMode::PRESENTATION; + if (for_presentation_source && !presentation_request_) { DLOG(ERROR) << "Requested to create a route for presentation, but " << "presentation request is missing."; return false; } current_route_request_id_ = ++route_request_counter_; - *origin = for_default_source + *origin = for_presentation_source ? presentation_request_->frame_origin() : url::Origin(GURL(chrome::kChromeUIMediaRouterURL)); DVLOG(1) << "DoCreateRoute: origin: " << *origin; @@ -489,29 +550,39 @@ bool MediaRouterUI::SetRouteParameters( // PresentationServiceDelegateImpl will have to be notified. Note that we // treat subsequent route requests from a Presentation API-initiated dialogs // as browser-initiated. - if (!for_default_source || !create_session_request_) { - route_response_callbacks->push_back(base::Bind( + if (!for_presentation_source || !create_session_request_) { + route_response_callbacks->push_back(base::BindOnce( &MediaRouterUI::OnRouteResponseReceived, weak_factory_.GetWeakPtr(), current_route_request_id_, sink_id, cast_mode, base::UTF8ToUTF16(GetTruncatedPresentationRequestSourceName()))); } - if (for_default_source) { + if (for_presentation_source) { if (create_session_request_) { // |create_session_request_| will be nullptr after this call, as the // object will be transferred to the callback. - route_response_callbacks->push_back( - base::Bind(&CreatePresentationConnectionRequest::HandleRouteResponse, - base::Passed(&create_session_request_))); - route_response_callbacks->push_back( - base::Bind(&MediaRouterUI::HandleCreateSessionRequestRouteResponse, - weak_factory_.GetWeakPtr())); + route_response_callbacks->push_back(base::BindOnce( + &CreatePresentationConnectionRequest::HandleRouteResponse, + base::Passed(&create_session_request_))); + route_response_callbacks->push_back(base::BindOnce( + &MediaRouterUI::HandleCreateSessionRequestRouteResponse, + weak_factory_.GetWeakPtr())); } else if (presentation_service_delegate_) { - route_response_callbacks->push_back( - base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse, - presentation_service_delegate_, *presentation_request_)); + route_response_callbacks->push_back(base::BindOnce( + &PresentationServiceDelegateImpl::OnRouteResponse, + presentation_service_delegate_, *presentation_request_)); } } + route_response_callbacks->push_back( + base::BindOnce(&MediaRouterUI::MaybeReportCastingSource, + weak_factory_.GetWeakPtr(), cast_mode)); + + if (cast_mode == MediaCastMode::LOCAL_FILE) { + route_response_callbacks->push_back( + base::BindOnce(&MediaRouterUI::MaybeReportFileInformation, + weak_factory_.GetWeakPtr())); + } + *timeout = GetRouteRequestTimeout(cast_mode); *incognito = Profile::FromWebUI(web_ui())->IsOffTheRecord(); @@ -525,13 +596,15 @@ bool MediaRouterUI::ConnectRoute(const MediaSink::Id& sink_id, std::vector<MediaRouteResponseCallback> route_response_callbacks; base::TimeDelta timeout; bool incognito; - if (!SetRouteParameters(sink_id, MediaCastMode::DEFAULT, &source_id, &origin, - &route_response_callbacks, &timeout, &incognito)) { - SendIssueForUnableToCast(MediaCastMode::DEFAULT); + if (!SetRouteParameters(sink_id, MediaCastMode::PRESENTATION, &source_id, + &origin, &route_response_callbacks, &timeout, + &incognito)) { + SendIssueForUnableToCast(MediaCastMode::PRESENTATION); return false; } router_->ConnectRouteByRouteId(source_id, route_id, origin, initiator_, - route_response_callbacks, timeout, incognito); + std::move(route_response_callbacks), timeout, + incognito); return true; } @@ -547,6 +620,14 @@ void MediaRouterUI::ClearIssue(const Issue::Id& issue_id) { router_->ClearIssue(issue_id); } +void MediaRouterUI::OpenFileDialog() { + if (!media_router_file_dialog_) { + media_router_file_dialog_ = base::MakeUnique<MediaRouterFileDialog>(this); + } + + media_router_file_dialog_->OpenFileDialog(GetBrowser()); +} + void MediaRouterUI::SearchSinksAndCreateRoute( const MediaSink::Id& sink_id, const std::string& search_criteria, @@ -558,10 +639,9 @@ void MediaRouterUI::SearchSinksAndCreateRoute( // The CreateRoute() part of the function is accomplished in the callback // OnSearchSinkResponseReceived(). - router_->SearchSinks( - sink_id, source_id, search_criteria, domain, - base::Bind(&MediaRouterUI::OnSearchSinkResponseReceived, - weak_factory_.GetWeakPtr(), cast_mode)); + router_->SearchSinks(sink_id, source_id, search_criteria, domain, + base::Bind(&MediaRouterUI::OnSearchSinkResponseReceived, + weak_factory_.GetWeakPtr(), cast_mode)); } bool MediaRouterUI::UserSelectedTabMirroringForCurrentOrigin() const { @@ -577,7 +657,7 @@ void MediaRouterUI::RecordCastModeSelection(MediaCastMode cast_mode) { prefs::kMediaRouterTabMirroringSources); switch (cast_mode) { - case MediaCastMode::DEFAULT: + case MediaCastMode::PRESENTATION: update->Remove(base::Value(GetSerializedInitiatorOrigin()), nullptr); break; case MediaCastMode::TAB_MIRROR: @@ -588,6 +668,9 @@ void MediaRouterUI::RecordCastModeSelection(MediaCastMode cast_mode) { // Desktop mirroring isn't domain-specific, so we don't record the // selection. break; + case MediaCastMode::LOCAL_FILE: + // Local media isn't domain-specific, so we don't record the selection. + break; default: NOTREACHED(); break; @@ -659,7 +742,8 @@ void MediaRouterUI::OnRouteResponseReceived( const RouteRequestResult& result) { DVLOG(1) << "OnRouteResponseReceived"; // If we receive a new route that we aren't expecting, do nothing. - if (route_request_id != current_route_request_id_) return; + if (route_request_id != current_route_request_id_) + return; const MediaRoute* route = result.route(); if (!route) { @@ -674,6 +758,18 @@ void MediaRouterUI::OnRouteResponseReceived( SendIssueForRouteTimeout(cast_mode, presentation_request_source_name); } +void MediaRouterUI::MaybeReportCastingSource(MediaCastMode cast_mode, + const RouteRequestResult& result) { + if (result.result_code() == RouteRequestResult::OK) + MediaRouterMetrics::RecordMediaRouterCastingSource(cast_mode); +} + +void MediaRouterUI::MaybeReportFileInformation( + const RouteRequestResult& result) { + if (result.result_code() == RouteRequestResult::OK) + media_router_file_dialog_->MaybeReportLastSelectedFileInformation(); +} + void MediaRouterUI::HandleCreateSessionRequestRouteResponse( const RouteRequestResult&) { Close(); @@ -696,7 +792,7 @@ void MediaRouterUI::OnSearchSinkResponseReceived( return; } router_->CreateRoute(source_id, found_sink_id, origin, initiator_, - route_response_callbacks, timeout, incognito); + std::move(route_response_callbacks), timeout, incognito); } void MediaRouterUI::SendIssueForRouteTimeout( @@ -704,7 +800,7 @@ void MediaRouterUI::SendIssueForRouteTimeout( const base::string16& presentation_request_source_name) { std::string issue_title; switch (cast_mode) { - case DEFAULT: + case PRESENTATION: DLOG_IF(ERROR, presentation_request_source_name.empty()) << "Empty presentation request source name."; issue_title = @@ -766,9 +862,7 @@ const std::set<MediaCastMode>& MediaRouterUI::cast_modes() const { } const std::string& MediaRouterUI::GetRouteProviderExtensionId() const { - // TODO(crbug.com/597778): remove reference to MediaRouterMojoImpl - return static_cast<MediaRouterMojoImpl*>(router_) - ->media_route_provider_extension_id(); + return event_page_request_manager_->media_route_provider_extension_id(); } void MediaRouterUI::SetUIInitializationTimer(const base::Time& start_time) { @@ -778,15 +872,15 @@ void MediaRouterUI::SetUIInitializationTimer(const base::Time& start_time) { void MediaRouterUI::OnUIInitiallyLoaded() { if (!start_time_.is_null()) { - MediaRouterMetrics::RecordMediaRouterDialogPaint( - base::Time::Now() - start_time_); + MediaRouterMetrics::RecordMediaRouterDialogPaint(base::Time::Now() - + start_time_); } } void MediaRouterUI::OnUIInitialDataReceived() { if (!start_time_.is_null()) { - MediaRouterMetrics::RecordMediaRouterDialogLoaded( - base::Time::Now() - start_time_); + MediaRouterMetrics::RecordMediaRouterDialogLoaded(base::Time::Now() - + start_time_); start_time_ = base::Time(); } } diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_ui.h b/chromium/chrome/browser/ui/webui/media_router/media_router_ui.h index ea9474e6c49..bb70fa41482 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_ui.h +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_ui.h @@ -18,6 +18,7 @@ #include "chrome/browser/media/router/presentation_service_delegate_impl.h" #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h" #include "chrome/browser/ui/webui/media_router/media_cast_mode.h" +#include "chrome/browser/ui/webui/media_router/media_router_file_dialog.h" #include "chrome/browser/ui/webui/media_router/media_sink_with_cast_modes.h" #include "chrome/browser/ui/webui/media_router/query_result_manager.h" #include "chrome/common/media_router/issue.h" @@ -38,9 +39,12 @@ namespace U_ICU_NAMESPACE { class Collator; } +class Browser; + namespace media_router { class CreatePresentationConnectionRequest; +class EventPageRequestManager; class IssuesObserver; class MediaRoute; class MediaRouter; @@ -50,10 +54,12 @@ class MediaSink; class RouteRequestResult; // Implements the chrome://media-router user interface. -class MediaRouterUI : public ConstrainedWebDialogUI, - public QueryResultManager::Observer, - public PresentationServiceDelegateImpl:: - DefaultPresentationRequestObserver { +class MediaRouterUI + : public ConstrainedWebDialogUI, + public QueryResultManager::Observer, + public PresentationServiceDelegateImpl:: + DefaultPresentationRequestObserver, + public MediaRouterFileDialog::MediaRouterFileDialogDelegate { public: // |web_ui| owns this object and is used to initialize the base class. explicit MediaRouterUI(content::WebUI* web_ui); @@ -65,7 +71,7 @@ class MediaRouterUI : public ConstrainedWebDialogUI, // Must not be null. // |delegate|, as well as mirroring sources of that tab. // The contents of the UI will change as the default MediaSource changes. - // If there is a default MediaSource, then DEFAULT MediaCastMode will be + // If there is a default MediaSource, then PRESENTATION MediaCastMode will be // added to |cast_modes_|. // Init* methods can only be called once. // |delegate|: PresentationServiceDelegateImpl of the initiator tab. @@ -119,6 +125,9 @@ class MediaRouterUI : public ConstrainedWebDialogUI, // Calls MediaRouter to clear the given issue. void ClearIssue(const Issue::Id& issue_id); + // Called to open a file dialog with the media_router_ui file dialog handler. + void OpenFileDialog(); + // Calls MediaRouter to search route providers for sinks matching // |search_criteria| with the source that is currently associated with // |cast_mode|. The user's domain |domain| is also used. @@ -135,7 +144,7 @@ class MediaRouterUI : public ConstrainedWebDialogUI, // mode is MediaCastMode::DESKTOP_MIRROR. virtual void RecordCastModeSelection(MediaCastMode cast_mode); - // Returns the hostname of the default source's parent frame URL. + // Returns the hostname of the PresentationRequest's parent frame URL. std::string GetPresentationRequestSourceName() const; std::string GetTruncatedPresentationRequestSourceName() const; bool HasPendingRouteRequest() const { @@ -181,7 +190,8 @@ class MediaRouterUI : public ConstrainedWebDialogUI, content::WebContents* initiator, MediaRouterWebUIMessageHandler* handler, std::unique_ptr<CreatePresentationConnectionRequest> - create_session_request); + create_session_request, + std::unique_ptr<MediaRouterFileDialog> file_dialog); private: friend class MediaRouterUITest; @@ -191,9 +201,9 @@ class MediaRouterUI : public ConstrainedWebDialogUI, FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, FilterNonDisplayRoutes); FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, FilterNonDisplayJoinableRoutes); FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, - UIMediaRoutesObserverAssignsCurrentCastModes); + UIMediaRoutesObserverAssignsCurrentCastModes); FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, - UIMediaRoutesObserverSkipsUnavailableCastModes); + UIMediaRoutesObserverSkipsUnavailableCastModes); FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, GetExtensionNameExtensionPresent); FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, GetExtensionNameEmptyWhenNotInstalled); @@ -251,6 +261,16 @@ class MediaRouterUI : public ConstrainedWebDialogUI, static std::string GetExtensionName(const GURL& url, extensions::ExtensionRegistry* registry); + // Retrieves the browser associated with this UI. + Browser* GetBrowser(); + + // Opens the URL in a tab which is then |initator_|. + void OpenTabWithUrl(const GURL url); + + // Methods for MediaRouterFileDialogDelegate + void FileDialogFileSelected(const ui::SelectedFileInfo& file_info) override; + void FileDialogSelectionFailed(const IssueInfo& issue) override; + // QueryResultManager::Observer void OnResultsUpdated( const std::vector<MediaSinkWithCastModes>& sinks) override; @@ -274,6 +294,13 @@ class MediaRouterUI : public ConstrainedWebDialogUI, const base::string16& presentation_request_source_name, const RouteRequestResult& result); + // Logs a UMA stat for the source that was cast if the result is successful. + void MaybeReportCastingSource(MediaCastMode cast_mode, + const RouteRequestResult& result); + // Sends a request to the file dialog to log UMA stats for the file that was + // cast if the result is successful. + void MaybeReportFileInformation(const RouteRequestResult& result); + // Closes the dialog after receiving a route response when using // |create_session_request_|. This prevents the dialog from trying to use the // same presentation request again. @@ -319,7 +346,7 @@ class MediaRouterUI : public ConstrainedWebDialogUI, // match the value of |routes_|. void UpdateRoutesToCastModesMapping(); - // Returns the default presentation request's frame URL if there is one. + // Returns the default PresentationRequest's frame URL if there is one. // Otherwise returns an empty GURL. GURL GetFrameURL() const; @@ -388,6 +415,9 @@ class MediaRouterUI : public ConstrainedWebDialogUI, // Pointer to the MediaRouter for this instance's BrowserContext. MediaRouter* router_; + // Request manager for the Media Router component extension. + const EventPageRequestManager* event_page_request_manager_; + // The start time for UI initialization metrics timer. When a dialog has been // been painted and initialized with initial data, this should be cleared. base::Time start_time_; @@ -396,6 +426,10 @@ class MediaRouterUI : public ConstrainedWebDialogUI, // updates. std::unique_ptr<UIMediaRouteControllerObserver> route_controller_observer_; + // The dialog that handles opening the file dialog and validating and + // returning the results. + std::unique_ptr<MediaRouterFileDialog> media_router_file_dialog_; + // If set, a cast mode that is required to be shown first. base::Optional<MediaCastMode> forced_cast_mode_; diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc index 28861553fa8..a3b440ef8c9 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/media/router/create_presentation_connection_request.h" #include "chrome/browser/media/router/mock_media_router.h" #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" @@ -18,6 +19,7 @@ #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/media_source_helper.h" #include "chrome/common/media_router/route_request_result.h" +#include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" @@ -37,10 +39,15 @@ using testing::AnyNumber; using testing::Invoke; using testing::Mock; using testing::Return; -using testing::SaveArg; namespace media_router { +ACTION_TEMPLATE(SaveArgWithMove, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_1_VALUE_PARAMS(pointer)) { + *pointer = std::move(::testing::get<k>(args)); +} + class MockMediaRouterWebUIMessageHandler : public MediaRouterWebUIMessageHandler { public: @@ -55,6 +62,16 @@ class MockMediaRouterWebUIMessageHandler base::Optional<MediaCastMode> forced_cast_mode)); }; +class MockMediaRouterFileDialog : public MediaRouterFileDialog { + public: + MockMediaRouterFileDialog() : MediaRouterFileDialog(nullptr) {} + ~MockMediaRouterFileDialog() override {} + + MOCK_METHOD0(GetLastSelectedFileUrl, GURL()); + MOCK_METHOD0(GetLastSelectedFileName, base::string16()); + MOCK_METHOD1(OpenFileDialog, void(Browser* browser)); +}; + class PresentationRequestCallbacks { public: PresentationRequestCallbacks() {} @@ -79,6 +96,11 @@ class MediaRouterUITest : public ChromeRenderViewHostTestHarness { MediaRouterUITest() { ON_CALL(mock_router_, GetCurrentRoutes()) .WillByDefault(Return(std::vector<MediaRoute>())); + + // enable and disable features + scoped_feature_list_.InitFromCommandLine( + "EnableCastLocalMedia" /* enabled features */, + std::string() /* disabled features */); } void TearDown() override { @@ -109,6 +131,10 @@ class MediaRouterUITest : public ChromeRenderViewHostTestHarness { media_router_ui_ = base::MakeUnique<MediaRouterUI>(&web_ui_); message_handler_ = base::MakeUnique<MockMediaRouterWebUIMessageHandler>( media_router_ui_.get()); + + auto file_dialog = base::MakeUnique<MockMediaRouterFileDialog>(); + mock_file_dialog_ = file_dialog.get(); + EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { this->media_sinks_observers_.push_back(observer); @@ -116,14 +142,14 @@ class MediaRouterUITest : public ChromeRenderViewHostTestHarness { })); EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)) .Times(AnyNumber()); - media_router_ui_->InitForTest(&mock_router_, web_contents(), - message_handler_.get(), - std::move(create_session_request_)); + media_router_ui_->InitForTest( + &mock_router_, web_contents(), message_handler_.get(), + std::move(create_session_request_), std::move(file_dialog)); message_handler_->SetWebUIForTest(&web_ui_); } MediaSink CreateSinkCompatibleWithAllSources() { - MediaSink sink("sinkId", "sinkName", MediaSink::GENERIC); + MediaSink sink("sinkId", "sinkName", SinkIconType::GENERIC); for (auto* observer : media_sinks_observers_) observer->OnSinksUpdated({sink}, std::vector<url::Origin>()); return sink; @@ -161,16 +187,18 @@ class MediaRouterUITest : public ChromeRenderViewHostTestHarness { std::unique_ptr<CreatePresentationConnectionRequest> create_session_request_; std::unique_ptr<MediaRouterUI> media_router_ui_; std::unique_ptr<MockMediaRouterWebUIMessageHandler> message_handler_; + MockMediaRouterFileDialog* mock_file_dialog_ = nullptr; std::vector<MediaSinksObserver*> media_sinks_observers_; + base::test::ScopedFeatureList scoped_feature_list_; }; TEST_F(MediaRouterUITest, RouteCreationTimeoutForTab) { CreateMediaRouterUI(profile()); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL( - mock_router_, - CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(60), false)) - .WillOnce(SaveArg<4>(&callbacks)); + EXPECT_CALL(mock_router_, + CreateRouteInternal(_, _, _, _, _, + base::TimeDelta::FromSeconds(60), false)) + .WillOnce(SaveArgWithMove<4>(&callbacks)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), MediaCastMode::TAB_MIRROR); @@ -179,17 +207,17 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForTab) { EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); - for (const auto& callback : callbacks) - callback.Run(*result); + for (auto& callback : callbacks) + std::move(callback).Run(*result); } TEST_F(MediaRouterUITest, RouteCreationTimeoutForDesktop) { CreateMediaRouterUI(profile()); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL( - mock_router_, - CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(120), false)) - .WillOnce(SaveArg<4>(&callbacks)); + EXPECT_CALL(mock_router_, + CreateRouteInternal(_, _, _, _, _, + base::TimeDelta::FromSeconds(120), false)) + .WillOnce(SaveArgWithMove<4>(&callbacks)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), MediaCastMode::DESKTOP_MIRROR); @@ -198,8 +226,8 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForDesktop) { EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); - for (const auto& callback : callbacks) - callback.Run(*result); + for (auto& callback : callbacks) + std::move(callback).Run(*result); } TEST_F(MediaRouterUITest, RouteCreationTimeoutForPresentation) { @@ -209,12 +237,12 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForPresentation) { url::Origin(GURL("https://frameurl.fakeurl"))); media_router_ui_->OnDefaultPresentationChanged(presentation_request); std::vector<MediaRouteResponseCallback> callbacks; - EXPECT_CALL( - mock_router_, - CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(20), false)) - .WillOnce(SaveArg<4>(&callbacks)); + EXPECT_CALL(mock_router_, + CreateRouteInternal(_, _, _, _, _, + base::TimeDelta::FromSeconds(20), false)) + .WillOnce(SaveArgWithMove<4>(&callbacks)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), - MediaCastMode::DEFAULT); + MediaCastMode::PRESENTATION); std::string expected_title = l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT, @@ -222,23 +250,49 @@ TEST_F(MediaRouterUITest, RouteCreationTimeoutForPresentation) { EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); - for (const auto& callback : callbacks) - callback.Run(*result); + for (auto& callback : callbacks) + std::move(callback).Run(*result); +} + +// Tests that if a local file CreateRoute call is made from a new tab, the +// file will be opened in the new tab. +TEST_F(MediaRouterUITest, RouteCreationLocalFileModeInTab) { + const GURL empty_tab = GURL(chrome::kChromeUINewTabURL); + const std::string file_url = "file:///some/url/for/a/file.mp3"; + + // Setup the UI + CreateMediaRouterUIForURL(profile(), empty_tab); + + EXPECT_CALL(*mock_file_dialog_, GetLastSelectedFileUrl()) + .WillOnce(Return(GURL(file_url))); + + content::WebContents* location_file_opened = nullptr; + + // Expect that the media_router_ will make a call to the mock_router + // then we will want to check that it made the call with. + EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) + .WillOnce(SaveArgWithMove<3>(&location_file_opened)); + + media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), + MediaCastMode::LOCAL_FILE); + + ASSERT_EQ(location_file_opened, web_contents()); + ASSERT_EQ(location_file_opened->GetVisibleURL(), file_url); } TEST_F(MediaRouterUITest, RouteCreationParametersCantBeCreated) { CreateMediaRouterUI(profile()); MediaSinkSearchResponseCallback sink_callback; - EXPECT_CALL(mock_router_, SearchSinks(_, _, _, _, _)) - .WillOnce(SaveArg<4>(&sink_callback)); + EXPECT_CALL(mock_router_, SearchSinksInternal(_, _, _, _, _)) + .WillOnce(SaveArgWithMove<4>(&sink_callback)); - // Use DEFAULT mode without setting a PresentationRequest. - media_router_ui_->SearchSinksAndCreateRoute("sinkId", "search input", - "domain", MediaCastMode::DEFAULT); + // Use PRESENTATION mode without setting a PresentationRequest. + media_router_ui_->SearchSinksAndCreateRoute( + "sinkId", "search input", "domain", MediaCastMode::PRESENTATION); std::string expected_title = l10n_util::GetStringUTF8( IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); - sink_callback.Run("foundSinkId"); + std::move(sink_callback).Run("foundSinkId"); } TEST_F(MediaRouterUITest, RouteRequestFromIncognito) { @@ -249,11 +303,11 @@ TEST_F(MediaRouterUITest, RouteRequestFromIncognito) { url::Origin(GURL("https://frameUrl"))); media_router_ui_->OnDefaultPresentationChanged(presentation_request); - EXPECT_CALL( - mock_router_, - CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(20), true)); + EXPECT_CALL(mock_router_, + CreateRouteInternal(_, _, _, _, _, + base::TimeDelta::FromSeconds(20), true)); media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), - MediaCastMode::DEFAULT); + MediaCastMode::PRESENTATION); } TEST_F(MediaRouterUITest, SortedSinks) { @@ -262,19 +316,19 @@ TEST_F(MediaRouterUITest, SortedSinks) { std::string sink_id1("sink3"); std::string sink_name1("B sink"); MediaSinkWithCastModes sink1( - MediaSink(sink_id1, sink_name1, MediaSink::IconType::CAST)); + MediaSink(sink_id1, sink_name1, SinkIconType::CAST)); unsorted_sinks.push_back(sink1); std::string sink_id2("sink1"); std::string sink_name2("A sink"); MediaSinkWithCastModes sink2( - MediaSink(sink_id2, sink_name2, MediaSink::IconType::CAST)); + MediaSink(sink_id2, sink_name2, SinkIconType::CAST)); unsorted_sinks.push_back(sink2); std::string sink_id3("sink2"); std::string sink_name3("B sink"); MediaSinkWithCastModes sink3( - MediaSink(sink_id3, sink_name3, MediaSink::IconType::CAST)); + MediaSink(sink_id3, sink_name3, SinkIconType::CAST)); unsorted_sinks.push_back(sink3); // Sorted order is 2, 3, 1. @@ -289,23 +343,20 @@ TEST_F(MediaRouterUITest, SortSinksByIconType) { CreateMediaRouterUI(profile()); std::vector<MediaSinkWithCastModes> unsorted_sinks; - MediaSinkWithCastModes sink1( - MediaSink("id1", "sink", MediaSink::IconType::HANGOUT)); + MediaSinkWithCastModes sink1(MediaSink("id1", "sink", SinkIconType::HANGOUT)); unsorted_sinks.push_back(sink1); MediaSinkWithCastModes sink2( - MediaSink("id2", "B sink", MediaSink::IconType::CAST_AUDIO_GROUP)); + MediaSink("id2", "B sink", SinkIconType::CAST_AUDIO_GROUP)); unsorted_sinks.push_back(sink2); - MediaSinkWithCastModes sink3( - MediaSink("id3", "sink", MediaSink::IconType::GENERIC)); + MediaSinkWithCastModes sink3(MediaSink("id3", "sink", SinkIconType::GENERIC)); unsorted_sinks.push_back(sink3); MediaSinkWithCastModes sink4( - MediaSink("id4", "A sink", MediaSink::IconType::CAST_AUDIO_GROUP)); + MediaSink("id4", "A sink", SinkIconType::CAST_AUDIO_GROUP)); unsorted_sinks.push_back(sink4); MediaSinkWithCastModes sink5( - MediaSink("id5", "sink", MediaSink::IconType::CAST_AUDIO)); + MediaSink("id5", "sink", SinkIconType::CAST_AUDIO)); unsorted_sinks.push_back(sink5); - MediaSinkWithCastModes sink6( - MediaSink("id6", "sink", MediaSink::IconType::CAST)); + MediaSinkWithCastModes sink6(MediaSink("id6", "sink", SinkIconType::CAST)); unsorted_sinks.push_back(sink6); // Sorted order is CAST, CAST_AUDIO_GROUP "A", CAST_AUDIO_GROUP "B", @@ -541,7 +592,7 @@ TEST_F(MediaRouterUITest, NotFoundErrorOnCloseWithNoCompatibleSinks) { // Send a sink to the UI that is compatible with sources other than the // presentation url to cause a NotFoundError. std::vector<MediaSink> sinks; - sinks.emplace_back("sink id", "sink name", MediaSink::GENERIC); + sinks.emplace_back("sink id", "sink name", SinkIconType::GENERIC); std::vector<url::Origin> origins; for (auto* observer : media_sinks_observers_) { if (observer->source().id() != presentation_url.spec()) { @@ -572,7 +623,7 @@ TEST_F(MediaRouterUITest, AbortErrorOnClose) { // Send a sink to the UI that is compatible with the presentation url to avoid // a NotFoundError. std::vector<MediaSink> sinks; - sinks.emplace_back("sink id", "sink name", MediaSink::GENERIC); + sinks.emplace_back("sink id", "sink name", SinkIconType::GENERIC); std::vector<url::Origin> origins; MediaSource::Id presentation_source_id = MediaSourceForPresentationUrl(presentation_url).id(); @@ -604,7 +655,7 @@ TEST_F(MediaRouterUITest, RecordCastModeSelections) { // |url_1a| and |url_1b| have the same origin, so the selection made for // |url_1a| should be retrieved. EXPECT_TRUE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); - media_router_ui_->RecordCastModeSelection(MediaCastMode::DEFAULT); + media_router_ui_->RecordCastModeSelection(MediaCastMode::PRESENTATION); EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); media_router_ui_->RecordCastModeSelection(MediaCastMode::TAB_MIRROR); @@ -723,21 +774,22 @@ TEST_F(MediaRouterUITest, SetsForcedCastModeWithPresentationURLs) { // initializing the dialog with a presentation request. The WebUI can handle // the forced mode that is not in the initial cast mode set, but is this a // bug? - CastModeSet expected_modes( - {MediaCastMode::TAB_MIRROR, MediaCastMode::DESKTOP_MIRROR}); - EXPECT_CALL( - *message_handler_, - UpdateCastModes(expected_modes, "", - base::Optional<MediaCastMode>(MediaCastMode::DEFAULT))); - expected_modes.insert(MediaCastMode::DEFAULT); - EXPECT_CALL( - *message_handler_, - UpdateCastModes(expected_modes, "google.com", - base::Optional<MediaCastMode>(MediaCastMode::DEFAULT))); + CastModeSet expected_modes({MediaCastMode::TAB_MIRROR, + MediaCastMode::DESKTOP_MIRROR, + MediaCastMode::LOCAL_FILE}); + EXPECT_CALL(*message_handler_, + UpdateCastModes( + expected_modes, "", + base::Optional<MediaCastMode>(MediaCastMode::PRESENTATION))); + expected_modes.insert(MediaCastMode::PRESENTATION); + EXPECT_CALL(*message_handler_, + UpdateCastModes( + expected_modes, "google.com", + base::Optional<MediaCastMode>(MediaCastMode::PRESENTATION))); media_router_ui_->UIInitialized(); media_router_ui_->InitForTest(&mock_router_, web_contents(), message_handler_.get(), - std::move(create_session_request_)); + std::move(create_session_request_), nullptr); // |media_router_ui_| takes ownership of |request_callbacks|. media_router_ui_.reset(); } diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index b4da44a3602..31cb121e64d 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc @@ -60,6 +60,8 @@ const char kReportSelectedCastMode[] = "reportSelectedCastMode"; const char kReportSinkCount[] = "reportSinkCount"; const char kReportTimeToClickSink[] = "reportTimeToClickSink"; const char kReportTimeToInitialActionClose[] = "reportTimeToInitialActionClose"; +const char kReportWebUIRouteControllerLoaded[] = + "reportWebUIRouteControllerLoaded"; const char kSearchSinksAndCreateRoute[] = "searchSinksAndCreateRoute"; const char kOnInitialDataReceived[] = "onInitialDataReceived"; const char kOnMediaControllerAvailable[] = "onMediaControllerAvailable"; @@ -67,6 +69,7 @@ const char kOnMediaControllerClosed[] = "onMediaControllerClosed"; const char kPauseCurrentMedia[] = "pauseCurrentMedia"; const char kPlayCurrentMedia[] = "playCurrentMedia"; const char kSeekCurrentMedia[] = "seekCurrentMedia"; +const char kSelectLocalMediaFile[] = "selectLocalMediaFile"; const char kSetCurrentMediaMute[] = "setCurrentMediaMute"; const char kSetCurrentMediaVolume[] = "setCurrentMediaVolume"; @@ -84,13 +87,14 @@ const char kSetRouteList[] = "media_router.ui.setRouteList"; const char kSetCastModeList[] = "media_router.ui.setCastModeList"; const char kUpdateMaxHeight[] = "media_router.ui.updateMaxHeight"; const char kUpdateRouteStatus[] = "media_router.ui.updateRouteStatus"; +const char kUserSelectedLocalMediaFile[] = + "media_router.ui.userSelectedLocalMediaFile"; const char kWindowOpen[] = "window.open"; std::unique_ptr<base::DictionaryValue> SinksAndIdentityToValue( const std::vector<MediaSinkWithCastModes>& sinks, const AccountInfo& account_info) { - std::unique_ptr<base::DictionaryValue> sink_list_and_identity( - new base::DictionaryValue); + auto sink_list_and_identity = base::MakeUnique<base::DictionaryValue>(); bool show_email = false; bool show_domain = false; std::string user_domain; @@ -99,10 +103,10 @@ std::unique_ptr<base::DictionaryValue> SinksAndIdentityToValue( sink_list_and_identity->SetString("userEmail", account_info.email); } - std::unique_ptr<base::ListValue> sinks_val(new base::ListValue); + auto sinks_val = base::MakeUnique<base::ListValue>(); for (const MediaSinkWithCastModes& sink_with_cast_modes : sinks) { - std::unique_ptr<base::DictionaryValue> sink_val(new base::DictionaryValue); + auto sink_val = base::MakeUnique<base::DictionaryValue>(); const MediaSink& sink = sink_with_cast_modes.sink; sink_val->SetString("id", sink.id()); @@ -152,12 +156,16 @@ std::unique_ptr<base::DictionaryValue> RouteToValue( bool can_join, const std::string& extension_id, bool incognito, - int current_cast_mode) { - std::unique_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); + int current_cast_mode, + bool is_web_ui_route_controller_available) { + auto dictionary = base::MakeUnique<base::DictionaryValue>(); dictionary->SetString("id", route.media_route_id()); dictionary->SetString("sinkId", route.media_sink_id()); dictionary->SetString("description", route.description()); dictionary->SetBoolean("isLocal", route.is_local()); + dictionary->SetBoolean("supportsWebUiController", + is_web_ui_route_controller_available && + route.supports_media_route_controller()); dictionary->SetBoolean("canJoin", can_join); if (current_cast_mode > 0) { dictionary->SetInteger("currentCastMode", current_cast_mode); @@ -165,12 +173,11 @@ std::unique_ptr<base::DictionaryValue> RouteToValue( const std::string& custom_path = route.custom_controller_path(); if (!incognito && !custom_path.empty()) { - std::string full_custom_controller_path = base::StringPrintf("%s://%s/%s", - extensions::kExtensionScheme, extension_id.c_str(), - custom_path.c_str()); + std::string full_custom_controller_path = + base::StringPrintf("%s://%s/%s", extensions::kExtensionScheme, + extension_id.c_str(), custom_path.c_str()); DCHECK(GURL(full_custom_controller_path).is_valid()); - dictionary->SetString("customControllerPath", - full_custom_controller_path); + dictionary->SetString("customControllerPath", full_custom_controller_path); } return dictionary; @@ -180,11 +187,10 @@ std::unique_ptr<base::ListValue> CastModesToValue( const CastModeSet& cast_modes, const std::string& source_host, base::Optional<MediaCastMode> forced_cast_mode) { - std::unique_ptr<base::ListValue> value(new base::ListValue); + auto value = base::MakeUnique<base::ListValue>(); for (const MediaCastMode& cast_mode : cast_modes) { - std::unique_ptr<base::DictionaryValue> cast_mode_val( - new base::DictionaryValue); + auto cast_mode_val = base::MakeUnique<base::DictionaryValue>(); cast_mode_val->SetInteger("type", cast_mode); cast_mode_val->SetString( "description", MediaCastModeToDescription(cast_mode, source_host)); @@ -200,7 +206,7 @@ std::unique_ptr<base::ListValue> CastModesToValue( // Returns an Issue dictionary created from |issue| that can be used in WebUI. std::unique_ptr<base::DictionaryValue> IssueToValue(const Issue& issue) { const IssueInfo& issue_info = issue.info(); - std::unique_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); + auto dictionary = base::MakeUnique<base::DictionaryValue>(); dictionary->SetInteger("id", issue.id()); dictionary->SetString("title", issue_info.title); dictionary->SetString("message", issue_info.message); @@ -252,10 +258,11 @@ MediaRouterWebUIMessageHandler::MediaRouterWebUIMessageHandler( : incognito_( Profile::FromWebUI(media_router_ui->web_ui())->IsOffTheRecord()), dialog_closing_(false), + is_web_ui_route_controller_available_(base::FeatureList::IsEnabled( + features::kMediaRouterUIRouteController)), media_router_ui_(media_router_ui) {} -MediaRouterWebUIMessageHandler::~MediaRouterWebUIMessageHandler() { -} +MediaRouterWebUIMessageHandler::~MediaRouterWebUIMessageHandler() {} void MediaRouterWebUIMessageHandler::UpdateSinks( const std::vector<MediaSinkWithCastModes>& sinks) { @@ -295,7 +302,7 @@ void MediaRouterWebUIMessageHandler::OnCreateRouteResponseReceived( route->media_route_id(), media_router_ui_->routes_and_cast_modes()); std::unique_ptr<base::DictionaryValue> route_value(RouteToValue( *route, false, media_router_ui_->GetRouteProviderExtensionId(), - incognito_, current_cast_mode)); + incognito_, current_cast_mode, is_web_ui_route_controller_available_)); web_ui()->CallJavascriptFunctionUnsafe(kOnCreateRouteResponseReceived, base::Value(sink_id), *route_value, base::Value(route->for_display())); @@ -339,7 +346,7 @@ void MediaRouterWebUIMessageHandler::UpdateMediaRouteStatus( status_value.SetBoolean("canMute", status.can_mute); status_value.SetBoolean("canSetVolume", status.can_set_volume); status_value.SetBoolean("canSeek", status.can_seek); - status_value.SetBoolean("isPaused", status.is_paused); + status_value.SetInteger("playState", static_cast<int>(status.play_state)); status_value.SetBoolean("isMuted", status.is_muted); status_value.SetInteger("duration", status.duration.InSeconds()); status_value.SetInteger("currentTime", status.current_time.InSeconds()); @@ -352,47 +359,47 @@ void MediaRouterWebUIMessageHandler::OnRouteControllerInvalidated() { web_ui()->CallJavascriptFunctionUnsafe(kOnRouteControllerInvalidated); } +void MediaRouterWebUIMessageHandler::UserSelectedLocalMediaFile( + base::FilePath::StringType file_name) { + DVLOG(2) << "UserSelectedLocalMediaFile"; + web_ui()->CallJavascriptFunctionUnsafe(kUserSelectedLocalMediaFile, + base::Value(file_name)); +} + void MediaRouterWebUIMessageHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( kRequestInitialData, base::Bind(&MediaRouterWebUIMessageHandler::OnRequestInitialData, base::Unretained(this))); web_ui()->RegisterMessageCallback( - kCreateRoute, - base::Bind(&MediaRouterWebUIMessageHandler::OnCreateRoute, - base::Unretained(this))); + kCreateRoute, base::Bind(&MediaRouterWebUIMessageHandler::OnCreateRoute, + base::Unretained(this))); web_ui()->RegisterMessageCallback( kAcknowledgeFirstRunFlow, base::Bind(&MediaRouterWebUIMessageHandler::OnAcknowledgeFirstRunFlow, base::Unretained(this))); web_ui()->RegisterMessageCallback( - kActOnIssue, - base::Bind(&MediaRouterWebUIMessageHandler::OnActOnIssue, - base::Unretained(this))); + kActOnIssue, base::Bind(&MediaRouterWebUIMessageHandler::OnActOnIssue, + base::Unretained(this))); web_ui()->RegisterMessageCallback( - kCloseRoute, - base::Bind(&MediaRouterWebUIMessageHandler::OnCloseRoute, - base::Unretained(this))); + kCloseRoute, base::Bind(&MediaRouterWebUIMessageHandler::OnCloseRoute, + base::Unretained(this))); web_ui()->RegisterMessageCallback( - kJoinRoute, - base::Bind(&MediaRouterWebUIMessageHandler::OnJoinRoute, - base::Unretained(this))); + kJoinRoute, base::Bind(&MediaRouterWebUIMessageHandler::OnJoinRoute, + base::Unretained(this))); web_ui()->RegisterMessageCallback( - kCloseDialog, - base::Bind(&MediaRouterWebUIMessageHandler::OnCloseDialog, - base::Unretained(this))); + kCloseDialog, base::Bind(&MediaRouterWebUIMessageHandler::OnCloseDialog, + base::Unretained(this))); web_ui()->RegisterMessageCallback( - kReportBlur, - base::Bind(&MediaRouterWebUIMessageHandler::OnReportBlur, - base::Unretained(this))); + kReportBlur, base::Bind(&MediaRouterWebUIMessageHandler::OnReportBlur, + base::Unretained(this))); web_ui()->RegisterMessageCallback( kReportClickedSinkIndex, base::Bind(&MediaRouterWebUIMessageHandler::OnReportClickedSinkIndex, base::Unretained(this))); web_ui()->RegisterMessageCallback( - kReportFilter, - base::Bind(&MediaRouterWebUIMessageHandler::OnReportFilter, - base::Unretained(this))); + kReportFilter, base::Bind(&MediaRouterWebUIMessageHandler::OnReportFilter, + base::Unretained(this))); web_ui()->RegisterMessageCallback( kReportInitialState, base::Bind(&MediaRouterWebUIMessageHandler::OnReportInitialState, @@ -431,6 +438,11 @@ void MediaRouterWebUIMessageHandler::RegisterMessages() { &MediaRouterWebUIMessageHandler::OnReportTimeToInitialActionClose, base::Unretained(this))); web_ui()->RegisterMessageCallback( + kReportWebUIRouteControllerLoaded, + base::Bind( + &MediaRouterWebUIMessageHandler::OnReportWebUIRouteControllerLoaded, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( kSearchSinksAndCreateRoute, base::Bind(&MediaRouterWebUIMessageHandler::OnSearchSinksAndCreateRoute, base::Unretained(this))); @@ -459,6 +471,10 @@ void MediaRouterWebUIMessageHandler::RegisterMessages() { base::Bind(&MediaRouterWebUIMessageHandler::OnSeekCurrentMedia, base::Unretained(this))); web_ui()->RegisterMessageCallback( + kSelectLocalMediaFile, + base::Bind(&MediaRouterWebUIMessageHandler::OnSelectLocalMediaFile, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( kSetCurrentMediaMute, base::Bind(&MediaRouterWebUIMessageHandler::OnSetCurrentMediaMute, base::Unretained(this))); @@ -476,7 +492,7 @@ void MediaRouterWebUIMessageHandler::OnRequestInitialData( // "No Cast devices found?" Chromecast help center page. initial_data.SetString("deviceMissingUrl", - base::StringPrintf(kHelpPageUrlPrefix, 3249268)); + base::StringPrintf(kHelpPageUrlPrefix, 3249268)); std::unique_ptr<base::DictionaryValue> sinks_and_identity( SinksAndIdentityToValue(media_router_ui_->sinks(), GetAccountInfo())); @@ -501,10 +517,6 @@ void MediaRouterWebUIMessageHandler::OnRequestInitialData( media_router_ui_->UserSelectedTabMirroringForCurrentOrigin(); initial_data.SetBoolean("useTabMirroring", use_tab_mirroring); - initial_data.SetBoolean( - "useNewRouteControls", - base::FeatureList::IsEnabled(features::kMediaRouterUIRouteController)); - web_ui()->CallJavascriptFunctionUnsafe(kSetInitialData, initial_data); media_router_ui_->UIInitialized(); } @@ -576,8 +588,7 @@ void MediaRouterWebUIMessageHandler::OnAcknowledgeFirstRunFlow( pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet, true); } -void MediaRouterWebUIMessageHandler::OnActOnIssue( - const base::ListValue* args) { +void MediaRouterWebUIMessageHandler::OnActOnIssue(const base::ListValue* args) { DVLOG(1) << "OnActOnIssue"; const base::DictionaryValue* args_dict = nullptr; Issue::Id issue_id; @@ -667,16 +678,15 @@ void MediaRouterWebUIMessageHandler::OnCloseDialog( } if (used_esc_to_close_dialog) { - base::RecordAction(base::UserMetricsAction( - "MediaRouter_Ui_Dialog_ESCToClose")); + base::RecordAction( + base::UserMetricsAction("MediaRouter_Ui_Dialog_ESCToClose")); } dialog_closing_ = true; media_router_ui_->Close(); } -void MediaRouterWebUIMessageHandler::OnReportBlur( - const base::ListValue* args) { +void MediaRouterWebUIMessageHandler::OnReportBlur(const base::ListValue* args) { DVLOG(1) << "OnReportBlur"; base::RecordAction(base::UserMetricsAction("MediaRouter_Ui_Dialog_Blur")); } @@ -699,7 +709,7 @@ void MediaRouterWebUIMessageHandler::OnReportFilter(const base::ListValue*) { } void MediaRouterWebUIMessageHandler::OnReportInitialAction( - const base::ListValue* args) { + const base::ListValue* args) { DVLOG(1) << "OnReportInitialAction"; int action; if (!args->GetInteger(0, &action)) { @@ -724,7 +734,7 @@ void MediaRouterWebUIMessageHandler::OnReportInitialState( } void MediaRouterWebUIMessageHandler::OnReportNavigateToView( - const base::ListValue* args) { + const base::ListValue* args) { DVLOG(1) << "OnReportNavigateToView"; std::string view; if (!args->GetString(0, &view)) { @@ -733,8 +743,8 @@ void MediaRouterWebUIMessageHandler::OnReportNavigateToView( } if (view == "cast-mode-list") { - base::RecordAction(base::UserMetricsAction( - "MediaRouter_Ui_Navigate_SinkListToSource")); + base::RecordAction( + base::UserMetricsAction("MediaRouter_Ui_Navigate_SinkListToSource")); } else if (view == "route-details") { base::RecordAction(base::UserMetricsAction( "MediaRouter_Ui_Navigate_SinkListToRouteDetails")); @@ -808,6 +818,18 @@ void MediaRouterWebUIMessageHandler::OnReportTimeToClickSink( base::TimeDelta::FromMillisecondsD(time_to_click)); } +void MediaRouterWebUIMessageHandler::OnReportWebUIRouteControllerLoaded( + const base::ListValue* args) { + DVLOG(1) << "OnReportWebUIRouteControllerLoaded"; + double load_time; + if (!args->GetDouble(0, &load_time)) { + DVLOG(1) << "Unable to extract args."; + return; + } + UMA_HISTOGRAM_TIMES("MediaRouter.Ui.Dialog.LoadedWebUiRouteController", + base::TimeDelta::FromMillisecondsD(load_time)); +} + void MediaRouterWebUIMessageHandler::OnReportTimeToInitialActionClose( const base::ListValue* args) { DVLOG(1) << "OnReportTimeToInitialActionClose"; @@ -853,6 +875,11 @@ void MediaRouterWebUIMessageHandler::OnSearchSinksAndCreateRoute( static_cast<MediaCastMode>(cast_mode_num)); } +void MediaRouterWebUIMessageHandler::OnSelectLocalMediaFile( + const base::ListValue* args) { + media_router_ui_->OpenFileDialog(); +} + void MediaRouterWebUIMessageHandler::OnInitialDataReceived( const base::ListValue* args) { DVLOG(1) << "OnInitialDataReceived"; @@ -950,7 +977,7 @@ bool MediaRouterWebUIMessageHandler::ActOnIssueType( std::string learn_more_url = GetLearnMoreUrl(args); if (learn_more_url.empty()) return false; - std::unique_ptr<base::ListValue> open_args(new base::ListValue); + auto open_args = base::MakeUnique<base::ListValue>(); open_args->AppendString(learn_more_url); web_ui()->CallJavascriptFunctionUnsafe(kWindowOpen, *open_args); return true; @@ -983,15 +1010,15 @@ void MediaRouterWebUIMessageHandler::MaybeUpdateFirstRunFlowData() { if (first_run_flow_acknowledged && ProfileSyncServiceFactory::GetForProfile(profile)->IsSyncActive()) { pref_service->SetBoolean(prefs::kMediaRouterEnableCloudServices, true); - pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet, - true); + pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet, true); // Return early since the first run flow won't be surfaced. return; } show_cloud_pref = true; // "Casting to a Hangout from Chrome" Chromecast help center page. - first_run_flow_data.SetString("firstRunFlowCloudPrefLearnMoreUrl", + first_run_flow_data.SetString( + "firstRunFlowCloudPrefLearnMoreUrl", base::StringPrintf(kHelpPageUrlPrefix, 6320939)); } } @@ -1033,17 +1060,18 @@ std::unique_ptr<base::ListValue> MediaRouterWebUIMessageHandler::RoutesToValue( const std::vector<MediaRoute::Id>& joinable_route_ids, const std::unordered_map<MediaRoute::Id, MediaCastMode>& current_cast_modes) const { - std::unique_ptr<base::ListValue> value(new base::ListValue); + auto value = base::MakeUnique<base::ListValue>(); const std::string& extension_id = media_router_ui_->GetRouteProviderExtensionId(); for (const MediaRoute& route : routes) { bool can_join = base::ContainsValue(joinable_route_ids, route.media_route_id()); - int current_cast_mode = CurrentCastModeForRouteId(route.media_route_id(), - current_cast_modes); - std::unique_ptr<base::DictionaryValue> route_val(RouteToValue( - route, can_join, extension_id, incognito_, current_cast_mode)); + int current_cast_mode = + CurrentCastModeForRouteId(route.media_route_id(), current_cast_modes); + std::unique_ptr<base::DictionaryValue> route_val( + RouteToValue(route, can_join, extension_id, incognito_, + current_cast_mode, is_web_ui_route_controller_available_)); value->Append(std::move(route_val)); } diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h b/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h index ef4030b5d1c..42915ffe3e6 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h @@ -8,6 +8,7 @@ #include <unordered_map> #include <vector> +#include "base/files/file_path.h" #include "base/macros.h" #include "base/optional.h" #include "chrome/browser/ui/webui/media_router/media_cast_mode.h" @@ -67,6 +68,10 @@ class MediaRouterWebUIMessageHandler : public content::WebUIMessageHandler { // invalidated. void OnRouteControllerInvalidated(); + // Called when the user has selected a file and the name should be relayed to + // the UI. + void UserSelectedLocalMediaFile(base::FilePath::StringType file_name); + void SetWebUIForTest(content::WebUI* webui); void set_incognito_for_test(bool incognito) { incognito_ = incognito; } @@ -105,10 +110,12 @@ class MediaRouterWebUIMessageHandler : public content::WebUIMessageHandler { void OnReportSelectedCastMode(const base::ListValue* args); void OnReportSinkCount(const base::ListValue* args); void OnReportTimeToClickSink(const base::ListValue* args); + void OnReportWebUIRouteControllerLoaded(const base::ListValue* args); void OnReportTimeToInitialActionClose(const base::ListValue* args); void OnMediaControllerAvailable(const base::ListValue* args); void OnMediaControllerClosed(const base::ListValue* args); void OnSearchSinksAndCreateRoute(const base::ListValue* args); + void OnSelectLocalMediaFile(const base::ListValue* args); void OnInitialDataReceived(const base::ListValue* args); // Handlers for JavaScript messages to control the media. @@ -155,6 +162,9 @@ class MediaRouterWebUIMessageHandler : public content::WebUIMessageHandler { // Keeps track of whether a command to close the dialog has been issued. bool dialog_closing_; + // Whether the WebUI version of route controller is available for use. + const bool is_web_ui_route_controller_available_; + // The media status currently shown in the UI. base::Optional<MediaStatus> current_media_status_; diff --git a/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc b/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc index 484b987f00d..9cb1e48f54e 100644 --- a/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc @@ -62,7 +62,7 @@ std::string GetStringFromDict(const base::DictionaryValue* dict, MediaRoute CreateRoute() { MediaRoute::Id route_id("routeId123"); MediaSink::Id sink_id("sinkId123"); - MediaSink sink(sink_id, "The sink", MediaSink::IconType::CAST); + MediaSink sink(sink_id, "The sink", SinkIconType::CAST); std::string description("This is a route"); bool is_local = true; bool is_for_display = true; @@ -76,7 +76,7 @@ MediaSinkWithCastModes CreateMediaSinkWithCastMode(const std::string& sink_id, MediaCastMode cast_mode) { std::string sink_name("The sink"); MediaSinkWithCastModes media_sink_with_cast_modes( - MediaSink(sink_id, sink_name, MediaSink::IconType::CAST)); + MediaSink(sink_id, sink_name, SinkIconType::CAST)); media_sink_with_cast_modes.cast_modes.insert(cast_mode); return media_sink_with_cast_modes; @@ -336,7 +336,7 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateRoutes) { std::vector<MediaRoute::Id> joinable_route_ids = {route.media_route_id()}; std::unordered_map<MediaRoute::Id, MediaCastMode> current_cast_modes; current_cast_modes.insert( - std::make_pair(route.media_route_id(), MediaCastMode::DEFAULT)); + std::make_pair(route.media_route_id(), MediaCastMode::PRESENTATION)); EXPECT_CALL(*mock_media_router_ui_, GetRouteProviderExtensionId()).WillOnce( ReturnRef(provider_extension_id())); @@ -349,7 +349,7 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateRoutes) { EXPECT_EQ(route.description(), GetStringFromDict(route_value, "description")); EXPECT_EQ(route.is_local(), GetBooleanFromDict(route_value, "isLocal")); EXPECT_TRUE(GetBooleanFromDict(route_value, "canJoin")); - EXPECT_EQ(MediaCastMode::DEFAULT, + EXPECT_EQ(MediaCastMode::PRESENTATION, GetIntegerFromDict(route_value, "currentCastMode")); std::string expected_path = base::StringPrintf("%s://%s/%s", extensions::kExtensionScheme, @@ -385,9 +385,11 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateRoutesIncognito) { } TEST_F(MediaRouterWebUIMessageHandlerTest, SetCastModesList) { - CastModeSet cast_modes({MediaCastMode::DEFAULT, MediaCastMode::TAB_MIRROR, + CastModeSet cast_modes({MediaCastMode::PRESENTATION, + MediaCastMode::TAB_MIRROR, MediaCastMode::DESKTOP_MIRROR}); - handler_->UpdateCastModes(cast_modes, "www.host.com", MediaCastMode::DEFAULT); + handler_->UpdateCastModes(cast_modes, "www.host.com", + MediaCastMode::PRESENTATION); const base::ListValue* set_cast_mode_list = ExtractListFromCallArg("media_router.ui.setCastModeList"); @@ -399,7 +401,7 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, SetCastModesList) { EXPECT_EQ(MediaCastModeToDescription(*i, "www.host.com"), GetStringFromDict(cast_mode, "description")); EXPECT_EQ("www.host.com", GetStringFromDict(cast_mode, "host")); - EXPECT_EQ(*i == MediaCastMode::DEFAULT, + EXPECT_EQ(*i == MediaCastMode::PRESENTATION, GetBooleanFromDict(cast_mode, "isForced")); } } @@ -410,7 +412,7 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateMediaRouteStatus) { status.description = "test description"; status.can_play_pause = true; status.can_set_volume = true; - status.is_paused = true; + status.play_state = MediaStatus::PlayState::BUFFERING; status.duration = base::TimeDelta::FromSeconds(90); status.current_time = base::TimeDelta::FromSeconds(80); status.volume = 0.9; @@ -427,7 +429,8 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateMediaRouteStatus) { EXPECT_EQ(status.can_set_volume, GetBooleanFromDict(status_value, "canSetVolume")); EXPECT_EQ(status.can_seek, GetBooleanFromDict(status_value, "canSeek")); - EXPECT_EQ(status.is_paused, GetBooleanFromDict(status_value, "isPaused")); + EXPECT_EQ(static_cast<int>(status.play_state), + GetIntegerFromDict(status_value, "playState")); EXPECT_EQ(status.is_muted, GetBooleanFromDict(status_value, "isMuted")); EXPECT_EQ(status.duration.InSeconds(), GetIntegerFromDict(status_value, "duration")); @@ -538,9 +541,9 @@ TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateIssue) { TEST_F(MediaRouterWebUIMessageHandlerTest, RecordCastModeSelection) { base::ListValue args; - args.AppendInteger(MediaCastMode::DEFAULT); + args.AppendInteger(MediaCastMode::PRESENTATION); EXPECT_CALL(*mock_media_router_ui_, - RecordCastModeSelection(MediaCastMode::DEFAULT)) + RecordCastModeSelection(MediaCastMode::PRESENTATION)) .Times(1); handler_->OnReportSelectedCastMode(&args); diff --git a/chromium/chrome/browser/ui/webui/media_router/query_result_manager.h b/chromium/chrome/browser/ui/webui/media_router/query_result_manager.h index a1ab37e98ad..3e7c56db142 100644 --- a/chromium/chrome/browser/ui/webui/media_router/query_result_manager.h +++ b/chromium/chrome/browser/ui/webui/media_router/query_result_manager.h @@ -42,7 +42,7 @@ class MediaSinksObserver; // QueryResultManager::Observer* observer = ...; // QueryResultManager result_manager(router); // result_manager.AddObserver(observer); -// result_manager.SetSourcesForCastMode(MediaCastMode::DEFAULT, +// result_manager.SetSourcesForCastMode(MediaCastMode::PRESENTATION, // {MediaSourceForPresentationUrl("http://google.com")}, origin); // result_manager.SetSourcesForCastMode(MediaCastMode::TAB_MIRROR, // {MediaSourceForTab(123)}, origin); diff --git a/chromium/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc b/chromium/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc index 571a83b88d3..bda4ff7ae7c 100644 --- a/chromium/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc +++ b/chromium/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc @@ -53,7 +53,7 @@ class QueryResultManagerTest : public ::testing::Test { bool IsDefaultSourceForSink(const MediaSource* source, const MediaSink& sink) { - return IsPreferredSourceForSink(MediaCastMode::DEFAULT, source, sink); + return IsPreferredSourceForSink(MediaCastMode::PRESENTATION, source, sink); } bool IsTabSourceForSink(const MediaSource* source, const MediaSink& sink) { @@ -112,20 +112,20 @@ TEST_F(QueryResultManagerTest, StartStopSinksQuery) { CastModeSet cast_modes = query_result_manager_.GetSupportedCastModes(); EXPECT_TRUE(cast_modes.empty()); std::vector<MediaSource> actual_sources = - query_result_manager_.GetSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_.GetSourcesForCastMode(MediaCastMode::PRESENTATION); EXPECT_EQ(0u, actual_sources.size()); MediaSource source(MediaSourceForPresentationUrl(GURL("http://foo.com"))); EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillOnce(Return(true)); - query_result_manager_.SetSourcesForCastMode(MediaCastMode::DEFAULT, {source}, - url::Origin(GURL(kOrigin))); + query_result_manager_.SetSourcesForCastMode( + MediaCastMode::PRESENTATION, {source}, url::Origin(GURL(kOrigin))); cast_modes = query_result_manager_.GetSupportedCastModes(); EXPECT_EQ(1u, cast_modes.size()); - EXPECT_TRUE(base::ContainsKey(cast_modes, MediaCastMode::DEFAULT)); + EXPECT_TRUE(base::ContainsKey(cast_modes, MediaCastMode::PRESENTATION)); actual_sources = - query_result_manager_.GetSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_.GetSourcesForCastMode(MediaCastMode::PRESENTATION); EXPECT_EQ(1u, actual_sources.size()); EXPECT_EQ(source, actual_sources[0]); @@ -135,57 +135,58 @@ TEST_F(QueryResultManagerTest, StartStopSinksQuery) { EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillOnce(Return(true)); - query_result_manager_.SetSourcesForCastMode( - MediaCastMode::DEFAULT, {another_source}, url::Origin(GURL(kOrigin))); + query_result_manager_.SetSourcesForCastMode(MediaCastMode::PRESENTATION, + {another_source}, + url::Origin(GURL(kOrigin))); cast_modes = query_result_manager_.GetSupportedCastModes(); EXPECT_EQ(1u, cast_modes.size()); - EXPECT_TRUE(base::ContainsKey(cast_modes, MediaCastMode::DEFAULT)); + EXPECT_TRUE(base::ContainsKey(cast_modes, MediaCastMode::PRESENTATION)); actual_sources = - query_result_manager_.GetSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_.GetSourcesForCastMode(MediaCastMode::PRESENTATION); EXPECT_EQ(1u, actual_sources.size()); EXPECT_EQ(another_source, actual_sources[0]); EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); - query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::PRESENTATION); cast_modes = query_result_manager_.GetSupportedCastModes(); EXPECT_TRUE(cast_modes.empty()); actual_sources = - query_result_manager_.GetSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_.GetSourcesForCastMode(MediaCastMode::PRESENTATION); EXPECT_EQ(0u, actual_sources.size()); } TEST_F(QueryResultManagerTest, MultipleQueries) { - MediaSink sink1("sinkId1", "Sink 1", MediaSink::IconType::CAST); - MediaSink sink2("sinkId2", "Sink 2", MediaSink::IconType::CAST); - MediaSink sink3("sinkId3", "Sink 3", MediaSink::IconType::CAST); - MediaSink sink4("sinkId4", "Sink 4", MediaSink::IconType::CAST); - MediaSink sink5("sinkId5", "Sink 5", MediaSink::IconType::CAST); - MediaSource default_source1 = + MediaSink sink1("sinkId1", "Sink 1", SinkIconType::CAST); + MediaSink sink2("sinkId2", "Sink 2", SinkIconType::CAST); + MediaSink sink3("sinkId3", "Sink 3", SinkIconType::CAST); + MediaSink sink4("sinkId4", "Sink 4", SinkIconType::CAST); + MediaSink sink5("sinkId5", "Sink 5", SinkIconType::CAST); + MediaSource presentation_source1 = MediaSourceForPresentationUrl(GURL("http://bar.com")); - MediaSource default_source2 = + MediaSource presentation_source2 = MediaSourceForPresentationUrl(GURL("http://baz.com")); MediaSource tab_source = MediaSourceForTab(123); query_result_manager_.AddObserver(&mock_observer_); - DiscoverSinks(MediaCastMode::DEFAULT, default_source1); + DiscoverSinks(MediaCastMode::PRESENTATION, presentation_source1); DiscoverSinks(MediaCastMode::TAB_MIRROR, tab_source); // Scenario (results in this order): - // Action: DEFAULT -> [1, 2, 3] + // Action: PRESENTATION -> [1, 2, 3] // Expected result: - // Sinks: [1 -> {DEFAULT}, 2 -> {DEFAULT}, 3 -> {DEFAULT}] + // Sinks: [1 -> {PRESENTATION}, 2 -> {PRESENTATION}, 3 -> {PRESENTATION}] std::vector<MediaSinkWithCastModes> expected_sinks; expected_sinks.push_back(MediaSinkWithCastModes(sink1)); - expected_sinks.back().cast_modes.insert(MediaCastMode::DEFAULT); + expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.push_back(MediaSinkWithCastModes(sink2)); - expected_sinks.back().cast_modes.insert(MediaCastMode::DEFAULT); + expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.push_back(MediaSinkWithCastModes(sink3)); - expected_sinks.back().cast_modes.insert(MediaCastMode::DEFAULT); + expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); const auto& sinks_observers = query_result_manager_.sinks_observers_; - auto sinks_observer_it = sinks_observers.find(default_source1); + auto sinks_observer_it = sinks_observers.find(presentation_source1); ASSERT_TRUE(sinks_observer_it != sinks_observers.end()); ASSERT_TRUE(sinks_observer_it->second.get()); @@ -200,16 +201,16 @@ TEST_F(QueryResultManagerTest, MultipleQueries) { // Action: TAB_MIRROR -> [2, 3, 4] // Expected result: - // Sinks: [1 -> {DEFAULT}, 2 -> {DEFAULT, TAB_MIRROR}, - // 3 -> {DEFAULT, TAB_MIRROR}, 4 -> {TAB_MIRROR}] + // Sinks: [1 -> {PRESENTATION}, 2 -> {PRESENTATION, TAB_MIRROR}, + // 3 -> {PRESENTATION, TAB_MIRROR}, 4 -> {TAB_MIRROR}] expected_sinks.clear(); expected_sinks.push_back(MediaSinkWithCastModes(sink1)); - expected_sinks.back().cast_modes.insert(MediaCastMode::DEFAULT); + expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.push_back(MediaSinkWithCastModes(sink2)); - expected_sinks.back().cast_modes.insert(MediaCastMode::DEFAULT); + expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); expected_sinks.push_back(MediaSinkWithCastModes(sink3)); - expected_sinks.back().cast_modes.insert(MediaCastMode::DEFAULT); + expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); expected_sinks.push_back(MediaSinkWithCastModes(sink4)); expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); @@ -227,7 +228,7 @@ TEST_F(QueryResultManagerTest, MultipleQueries) { sinks_observer_it->second->OnSinksUpdated(sinks_query_result, {url::Origin(GURL(kOrigin))}); - // Action: Update default presentation URL + // Action: Update presentation URL // Expected result: // Sinks: [2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, 4 -> {TAB_MIRROR}] expected_sinks.clear(); @@ -245,15 +246,16 @@ TEST_F(QueryResultManagerTest, MultipleQueries) { .WillOnce(Return(true)); EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))).Times(1); - query_result_manager_.SetSourcesForCastMode( - MediaCastMode::DEFAULT, {default_source2}, url::Origin(GURL(kOrigin))); + query_result_manager_.SetSourcesForCastMode(MediaCastMode::PRESENTATION, + {presentation_source2}, + url::Origin(GURL(kOrigin))); - // Action: DEFAULT -> [1], origins don't match + // Action: PRESENTATION -> [1], origins don't match // Expected result: [2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, 4 -> {TAB_MIRROR}] // (No change) sinks_query_result.clear(); sinks_query_result.push_back(sink1); - sinks_observer_it = sinks_observers.find(default_source2); + sinks_observer_it = sinks_observers.find(presentation_source2); ASSERT_TRUE(sinks_observer_it != sinks_observers.end()); ASSERT_TRUE(sinks_observer_it->second.get()); EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))) @@ -270,15 +272,16 @@ TEST_F(QueryResultManagerTest, MultipleQueries) { EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::TAB_MIRROR); - // Remaining observers: DEFAULT observer, which will be removed on destruction + // Remaining observers: PRESENTATION observer, which will be removed on + // destruction EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); } TEST_F(QueryResultManagerTest, MultipleUrls) { - const MediaSink sink1("sinkId1", "Sink 1", MediaSink::IconType::CAST); - const MediaSink sink2("sinkId2", "Sink 2", MediaSink::IconType::CAST); - const MediaSink sink3("sinkId3", "Sink 3", MediaSink::IconType::CAST); - const MediaSink sink4("sinkId4", "Sink 4", MediaSink::IconType::CAST); + const MediaSink sink1("sinkId1", "Sink 1", SinkIconType::CAST); + const MediaSink sink2("sinkId2", "Sink 2", SinkIconType::CAST); + const MediaSink sink3("sinkId3", "Sink 3", SinkIconType::CAST); + const MediaSink sink4("sinkId4", "Sink 4", SinkIconType::CAST); const MediaSource source_a( MediaSourceForPresentationUrl(GURL("http://urlA.com"))); const MediaSource source_b( @@ -287,8 +290,8 @@ TEST_F(QueryResultManagerTest, MultipleUrls) { MediaSourceForPresentationUrl(GURL("http://urlC.com"))); const MediaSource source_tab(MediaSourceForTab(1)); // The sources are in decreasing order of priority. - const std::vector<MediaSource> default_sources = {source_a, source_b, - source_c}; + const std::vector<MediaSource> presentation_sources = {source_a, source_b, + source_c}; const std::vector<MediaSource> tab_sources = {source_tab}; const auto& sinks_observers = query_result_manager_.sinks_observers_; @@ -296,8 +299,9 @@ TEST_F(QueryResultManagerTest, MultipleUrls) { EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .Times(4) .WillRepeatedly(Return(true)); - query_result_manager_.SetSourcesForCastMode( - MediaCastMode::DEFAULT, default_sources, url::Origin(GURL(kOrigin))); + query_result_manager_.SetSourcesForCastMode(MediaCastMode::PRESENTATION, + presentation_sources, + url::Origin(GURL(kOrigin))); query_result_manager_.SetSourcesForCastMode( MediaCastMode::TAB_MIRROR, tab_sources, url::Origin(GURL(kOrigin))); @@ -379,7 +383,7 @@ TEST_F(QueryResultManagerTest, MultipleUrls) { // The observers for the four sources should get unregistered. EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(4); - query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::DEFAULT); + query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::PRESENTATION); query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::TAB_MIRROR); } @@ -390,18 +394,20 @@ TEST_F(QueryResultManagerTest, AddInvalidSource) { EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .Times(1) .WillRepeatedly(Return(true)); - query_result_manager_.SetSourcesForCastMode(MediaCastMode::DEFAULT, {source}, - url::Origin(GURL(kOrigin))); - // |source| has already been registered with the default cast mode, so it + query_result_manager_.SetSourcesForCastMode( + MediaCastMode::PRESENTATION, {source}, url::Origin(GURL(kOrigin))); + // |source| has already been registered with the PRESENTATION cast mode, so it // shouldn't get registered with tab mirroring. query_result_manager_.SetSourcesForCastMode( MediaCastMode::TAB_MIRROR, {source}, url::Origin(GURL(kOrigin))); const auto& cast_mode_sources = query_result_manager_.cast_mode_sources_; - const auto& default_sources = cast_mode_sources.at(MediaCastMode::DEFAULT); - EXPECT_TRUE(base::ContainsKey(cast_mode_sources, MediaCastMode::DEFAULT)); - EXPECT_EQ(default_sources.size(), 1u); - EXPECT_EQ(default_sources.at(0), source); + const auto& presentation_sources = + cast_mode_sources.at(MediaCastMode::PRESENTATION); + EXPECT_TRUE( + base::ContainsKey(cast_mode_sources, MediaCastMode::PRESENTATION)); + EXPECT_EQ(presentation_sources.size(), 1u); + EXPECT_EQ(presentation_sources.at(0), source); EXPECT_FALSE(base::ContainsKey(cast_mode_sources, MediaCastMode::TAB_MIRROR)); } diff --git a/chromium/chrome/browser/ui/webui/memory_internals_ui.cc b/chromium/chrome/browser/ui/webui/memory_internals_ui.cc new file mode 100644 index 00000000000..e6d64f90ff5 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/memory_internals_ui.cc @@ -0,0 +1,96 @@ +// 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 "chrome/browser/ui/webui/memory_internals_ui.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/url_constants.h" +#include "chrome/grit/browser_resources.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace { + +// Generates one row of the returned process info. +base::Value MakeProcessInfo(int pid, const std::string& description) { + base::Value result(base::Value::Type::LIST); + result.GetList().push_back(base::Value(pid)); + result.GetList().push_back(base::Value(description)); + return result; +} + +content::WebUIDataSource* CreateMemoryInternalsUIHTMLSource() { + content::WebUIDataSource* source = + content::WebUIDataSource::Create(chrome::kChromeUIMemoryInternalsHost); + source->SetDefaultResource(IDR_MEMORY_INTERNALS_HTML); + source->AddResourcePath("memory_internals.js", IDR_MEMORY_INTERNALS_JS); + return source; +} + +class MemoryInternalsDOMHandler : public content::WebUIMessageHandler { + public: + MemoryInternalsDOMHandler(); + ~MemoryInternalsDOMHandler() override; + + // WebUIMessageHandler implementation. + void RegisterMessages() override; + + // Callback for the "requestProcessList" message. + void HandleRequestProcessList(const base::ListValue* args); + + // Callback for the "dumpProcess" message. + void HandleDumpProcess(const base::ListValue* args); + + private: + DISALLOW_COPY_AND_ASSIGN(MemoryInternalsDOMHandler); +}; + +MemoryInternalsDOMHandler::MemoryInternalsDOMHandler() {} + +MemoryInternalsDOMHandler::~MemoryInternalsDOMHandler() {} + +void MemoryInternalsDOMHandler::RegisterMessages() { + // Unretained should be OK here since this class is bound to the lifetime of + // the WebUI. + web_ui()->RegisterMessageCallback( + "requestProcessList", + base::Bind(&MemoryInternalsDOMHandler::HandleRequestProcessList, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "dumpProcess", base::Bind(&MemoryInternalsDOMHandler::HandleDumpProcess, + base::Unretained(this))); +} + +void MemoryInternalsDOMHandler::HandleRequestProcessList( + const base::ListValue* args) { + base::Value result(base::Value::Type::LIST); + // Return some canned data for now. + // TODO(brettW) hook this up. + result.GetList().push_back(MakeProcessInfo(11234, "Process 11234 [Browser]")); + result.GetList().push_back(MakeProcessInfo(11235, "Process 11235 [GPU]")); + result.GetList().push_back(MakeProcessInfo(11236, "Process 11236 [Rend]")); + + AllowJavascript(); + CallJavascriptFunction("returnProcessList", result); + DisallowJavascript(); +} + +void MemoryInternalsDOMHandler::HandleDumpProcess(const base::ListValue* args) { + // TODO(brettW) hook this up. +} + +} // namespace + +MemoryInternalsUI::MemoryInternalsUI(content::WebUI* web_ui) + : WebUIController(web_ui) { + web_ui->AddMessageHandler(base::MakeUnique<MemoryInternalsDOMHandler>()); + + Profile* profile = Profile::FromWebUI(web_ui); + content::WebUIDataSource::Add(profile, CreateMemoryInternalsUIHTMLSource()); +} + +MemoryInternalsUI::~MemoryInternalsUI() {} diff --git a/chromium/chrome/browser/ui/webui/memory_internals_ui.h b/chromium/chrome/browser/ui/webui/memory_internals_ui.h new file mode 100644 index 00000000000..b83b79aee74 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/memory_internals_ui.h @@ -0,0 +1,20 @@ +// 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 CHROME_BROWSER_UI_WEBUI_MEMORY_INTERNALS_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_MEMORY_INTERNALS_UI_H_ + +#include "base/macros.h" +#include "content/public/browser/web_ui_controller.h" + +class MemoryInternalsUI : public content::WebUIController { + public: + explicit MemoryInternalsUI(content::WebUI* web_ui); + ~MemoryInternalsUI() override; + + private: + DISALLOW_COPY_AND_ASSIGN(MemoryInternalsUI); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_MEMORY_INTERNALS_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/module_database_conflicts_handler.cc b/chromium/chrome/browser/ui/webui/module_database_conflicts_handler.cc new file mode 100644 index 00000000000..a1c3840deaa --- /dev/null +++ b/chromium/chrome/browser/ui/webui/module_database_conflicts_handler.cc @@ -0,0 +1,101 @@ +// 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 "chrome/browser/ui/webui/module_database_conflicts_handler.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string16.h" +#include "base/strings/string_number_conversions.h" +#include "base/values.h" +#include "chrome/browser/conflicts/module_database_win.h" +#include "chrome/browser/conflicts/module_info_win.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/web_ui.h" +#include "ui/base/l10n/l10n_util.h" + +ModuleDatabaseConflictsHandler::ModuleDatabaseConflictsHandler() = default; + +ModuleDatabaseConflictsHandler::~ModuleDatabaseConflictsHandler() { + if (module_list_) + ModuleDatabase::GetInstance()->RemoveObserver(this); +} + +void ModuleDatabaseConflictsHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "requestModuleList", + base::BindRepeating( + &ModuleDatabaseConflictsHandler::HandleRequestModuleList, + base::Unretained(this))); +} + +void ModuleDatabaseConflictsHandler::OnNewModuleFound( + const ModuleInfoKey& module_key, + const ModuleInfoData& module_data) { + DCHECK(module_list_); + + auto data = base::MakeUnique<base::DictionaryValue>(); + + // TODO(pmonette): Set the status when conflicting module detection is added. + constexpr int kGoodStatus = 1; + data->SetInteger("status", kGoodStatus); + + base::string16 type_string; + if (module_data.module_types & ModuleInfoData::kTypeShellExtension) + type_string = L"Shell extension"; + data->SetString("type_description", type_string); + + const auto& inspection_result = *module_data.inspection_result; + data->SetString("location", inspection_result.location); + data->SetString("name", inspection_result.basename); + data->SetString("product_name", inspection_result.product_name); + data->SetString("description", inspection_result.description); + data->SetString("version", inspection_result.version); + data->SetString("digital_signer", inspection_result.certificate_info.subject); + + module_list_->Append(std::move(data)); +} + +void ModuleDatabaseConflictsHandler::OnModuleDatabaseIdle() { + DCHECK(module_list_); + DCHECK(!module_list_callback_id_.empty()); + + ModuleDatabase::GetInstance()->RemoveObserver(this); + + // Add the section title and the total count for bad modules found. + // TODO(pmonette): Add the number of conflicts when conflicting module + // detection is added. + base::string16 table_title = l10n_util::GetStringFUTF16( + IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_ONE, + base::IntToString16(module_list_->GetSize())); + + base::DictionaryValue results; + results.SetString("modulesTableTitle", table_title); + results.Set("moduleList", std::move(module_list_)); + + AllowJavascript(); + ResolveJavascriptCallback(base::Value(module_list_callback_id_), results); +} + +void ModuleDatabaseConflictsHandler::HandleRequestModuleList( + const base::ListValue* args) { + // Make sure the JS doesn't call 'requestModuleList' more than once. + // TODO(739291): It would be better to kill the renderer instead of the + // browser for malformed messages. + CHECK(!module_list_); + + CHECK_EQ(1U, args->GetSize()); + CHECK(args->GetString(0, &module_list_callback_id_)); + + // The request is handled asynchronously, filling up the |module_list_|, + // and will callback via OnModuleDatabaseIdle() on completion. + module_list_ = base::MakeUnique<base::ListValue>(); + + auto* module_database = ModuleDatabase::GetInstance(); + module_database->IncreaseInspectionPriority(); + module_database->AddObserver(this); +} diff --git a/chromium/chrome/browser/ui/webui/module_database_conflicts_handler.h b/chromium/chrome/browser/ui/webui/module_database_conflicts_handler.h new file mode 100644 index 00000000000..e27de653840 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/module_database_conflicts_handler.h @@ -0,0 +1,50 @@ +// 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 CHROME_BROWSER_UI_WEBUI_MODULE_DATABASE_CONFLICTS_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_MODULE_DATABASE_CONFLICTS_HANDLER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "chrome/browser/conflicts/module_database_observer_win.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace base { +class Listvalue; +} + +// This class takes care of sending the list of all loaded modules to the +// chrome://conflicts WebUI page when it is requested. It replaces +// ConflictsHandler when the ModuleDatabase feature is enabled. +class ModuleDatabaseConflictsHandler : public content::WebUIMessageHandler, + public ModuleDatabaseObserver { + public: + ModuleDatabaseConflictsHandler(); + ~ModuleDatabaseConflictsHandler() override; + + private: + // content::WebUIMessageHandler: + void RegisterMessages() override; + + // ModuleDatabaseObserver: + void OnNewModuleFound(const ModuleInfoKey& module_key, + const ModuleInfoData& module_data) override; + void OnModuleDatabaseIdle() override; + + // Callback for the "requestModuleList" message. + void HandleRequestModuleList(const base::ListValue* args); + + // The ID of the callback that will get invoked with the module list. + std::string module_list_callback_id_; + + // Temporarily holds the module list while the modules are being + // enumerated. + std::unique_ptr<base::ListValue> module_list_; + + DISALLOW_COPY_AND_ASSIGN(ModuleDatabaseConflictsHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_MODULE_DATABASE_CONFLICTS_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/mojo_web_ui_controller.h b/chromium/chrome/browser/ui/webui/mojo_web_ui_controller.h index 75109db2423..501a9cc48bc 100644 --- a/chromium/chrome/browser/ui/webui/mojo_web_ui_controller.h +++ b/chromium/chrome/browser/ui/webui/mojo_web_ui_controller.h @@ -15,7 +15,6 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_ui_controller.h" #include "mojo/public/cpp/system/core.h" -#include "services/service_manager/public/cpp/bind_source_info.h" #include "services/service_manager/public/cpp/binder_registry.h" class MojoWebUIControllerBase : public content::WebUIController { @@ -59,8 +58,7 @@ class MojoWebUIController : public MojoWebUIControllerBase { protected: // Invoked to create the specific bindings implementation. - virtual void BindUIHandler(const service_manager::BindSourceInfo& source_info, - mojo::InterfaceRequest<Interface> request) = 0; + virtual void BindUIHandler(mojo::InterfaceRequest<Interface> request) = 0; private: base::WeakPtrFactory<MojoWebUIController> weak_factory_; diff --git a/chromium/chrome/browser/ui/webui/nacl_ui.cc b/chromium/chrome/browser/ui/webui/nacl_ui.cc index 22a2027b181..e1863f2fdf3 100644 --- a/chromium/chrome/browser/ui/webui/nacl_ui.cc +++ b/chromium/chrome/browser/ui/webui/nacl_ui.cc @@ -36,7 +36,6 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" diff --git a/chromium/chrome/browser/ui/webui/net_export_ui.cc b/chromium/chrome/browser/ui/webui/net_export_ui.cc index be80d206317..d5b86613512 100644 --- a/chromium/chrome/browser/ui/webui/net_export_ui.cc +++ b/chromium/chrome/browser/ui/webui/net_export_ui.cc @@ -24,11 +24,12 @@ #include "chrome/browser/platform_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/chrome_select_file_policy.h" +#include "chrome/common/channel_info.h" #include "chrome/common/url_constants.h" #include "components/grit/components_resources.h" #include "components/net_log/chrome_net_log.h" +#include "components/net_log/net_export_file_writer.h" #include "components/net_log/net_export_ui_constants.h" -#include "components/net_log/net_log_file_writer.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/url_data_source.h" @@ -51,29 +52,6 @@ using content::WebUIMessageHandler; namespace { -class ProxyScriptFetcherContextGetter : public net::URLRequestContextGetter { - public: - explicit ProxyScriptFetcherContextGetter(IOThread* io_thread) - : io_thread_(io_thread) {} - - net::URLRequestContext* GetURLRequestContext() override { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(io_thread_->globals()->proxy_script_fetcher_context.get()); - return io_thread_->globals()->proxy_script_fetcher_context.get(); - } - - scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() - const override { - return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO); - } - - protected: - ~ProxyScriptFetcherContextGetter() override {} - - private: - IOThread* const io_thread_; // Owned by BrowserProcess. -}; - // May only be accessed on the UI thread base::LazyInstance<base::FilePath>::Leaky last_save_dir = LAZY_INSTANCE_INITIALIZER; @@ -103,7 +81,7 @@ class NetExportMessageHandler : public WebUIMessageHandler, public base::SupportsWeakPtr<NetExportMessageHandler>, public ui::SelectFileDialog::Listener, - public net_log::NetLogFileWriter::StateObserver { + public net_log::NetExportFileWriter::StateObserver { public: NetExportMessageHandler(); ~NetExportMessageHandler() override; @@ -124,7 +102,7 @@ class NetExportMessageHandler void* params) override; void FileSelectionCanceled(void* params) override; - // net_log::NetLogFileWriter::StateObserver implementation. + // net_log::NetExportFileWriter::StateObserver implementation. void OnNewState(const base::DictionaryValue& state) override; private: @@ -134,6 +112,8 @@ class NetExportMessageHandler // Send NetLog data via email. static void SendEmail(const base::FilePath& file_to_send); + void StartNetLog(const base::FilePath& path); + // Reveal |path| in the shell on desktop platforms. void ShowFileInShell(const base::FilePath& path); @@ -150,7 +130,7 @@ class NetExportMessageHandler static bool UsingMobileUI(); // Calls NetExportView.onExportNetLogInfoChanged JavaScript function in the - // renderer, passing in |file_writer_state|. + // renderer. void NotifyUIWithState(std::unique_ptr<base::DictionaryValue> state); // Opens the SelectFileDialog UI with the default path to save a @@ -161,18 +141,20 @@ class NetExportMessageHandler // logging starts so that net log entries can be added for those events. URLRequestContextGetterList GetURLRequestContexts() const; - // Cache of g_browser_process->net_log()->net_log_file_writer(). This + // Cache of g_browser_process->net_log()->net_export_file_writer(). This // is owned by ChromeNetLog which is owned by BrowserProcessImpl. - net_log::NetLogFileWriter* file_writer_; + net_log::NetExportFileWriter* file_writer_; - ScopedObserver<net_log::NetLogFileWriter, - net_log::NetLogFileWriter::StateObserver> + ScopedObserver<net_log::NetExportFileWriter, + net_log::NetExportFileWriter::StateObserver> state_observer_manager_; - // The capture mode the user chose in the UI when logging started is cached - // here and is read after a file path is chosen in the save dialog. - // Its value is only valid while the save dialog is open on the desktop UI. + // The capture mode and file size bound that the user chose in the UI when + // logging started is cached here and is read after a file path is chosen in + // the save dialog. Their values are only valid while the save dialog is open + // on the desktop UI. net::NetLogCaptureMode capture_mode_; + size_t max_log_file_size_; scoped_refptr<ui::SelectFileDialog> select_file_dialog_; @@ -182,7 +164,7 @@ class NetExportMessageHandler }; NetExportMessageHandler::NetExportMessageHandler() - : file_writer_(g_browser_process->net_log()->net_log_file_writer()), + : file_writer_(g_browser_process->net_log()->net_export_file_writer()), state_observer_manager_(this), weak_ptr_factory_(this) { file_writer_->Initialize( @@ -237,16 +219,24 @@ void NetExportMessageHandler::OnEnableNotifyUIWithState( void NetExportMessageHandler::OnStartNetLog(const base::ListValue* list) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - std::string capture_mode_string; - bool result = list->GetString(0, &capture_mode_string); - DCHECK(result); - capture_mode_ = - net_log::NetLogFileWriter::CaptureModeFromString(capture_mode_string); + const base::Value::ListStorage& params = list->GetList(); + + // Determine the capture mode. + capture_mode_ = net::NetLogCaptureMode::Default(); + if (params.size() > 0 && params[0].is_string()) { + capture_mode_ = net_log::NetExportFileWriter::CaptureModeFromString( + params[0].GetString()); + } + + // Determine the max file size. + max_log_file_size_ = net_log::NetExportFileWriter::kNoLimit; + if (params.size() > 1 && params[1].is_int() && params[1].GetInt() > 0) { + max_log_file_size_ = params[1].GetInt(); + } if (UsingMobileUI()) { - file_writer_->StartNetLog(base::FilePath(), capture_mode_, - GetURLRequestContexts()); + StartNetLog(base::FilePath()); } else { base::FilePath initial_dir = last_save_dir.Pointer()->empty() ? DownloadPrefs::FromBrowserContext( @@ -303,7 +293,7 @@ void NetExportMessageHandler::FileSelected(const base::FilePath& path, DCHECK(select_file_dialog_); *last_save_dir.Pointer() = path.DirName(); - file_writer_->StartNetLog(path, capture_mode_, GetURLRequestContexts()); + StartNetLog(path); // IMPORTANT: resetting the dialog may lead to the deletion of |path|, so keep // this line last. @@ -338,6 +328,15 @@ void NetExportMessageHandler::SendEmail(const base::FilePath& file_to_send) { #endif } +void NetExportMessageHandler::StartNetLog(const base::FilePath& path) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + file_writer_->StartNetLog( + path, capture_mode_, max_log_file_size_, + base::CommandLine::ForCurrentProcess()->GetCommandLineString(), + chrome::GetChannelString(), GetURLRequestContexts()); +} + void NetExportMessageHandler::ShowFileInShell(const base::FilePath& path) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (path.empty()) @@ -351,7 +350,7 @@ void NetExportMessageHandler::ShowFileInShell(const base::FilePath& path) { // static bool NetExportMessageHandler::UsingMobileUI() { -#if defined(OS_ANDROID) || defined(OS_IOS) +#if defined(OS_ANDROID) return true; #else return false; @@ -399,8 +398,6 @@ NetExportMessageHandler::GetURLRequestContexts() const { ->GetMediaURLRequestContext()); context_getters.push_back( g_browser_process->io_thread()->system_url_request_context_getter()); - context_getters.push_back( - new ProxyScriptFetcherContextGetter(g_browser_process->io_thread())); return context_getters; } diff --git a/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui.cc index 2fa6e2ae757..57f7ed64a22 100644 --- a/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui.cc +++ b/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui.cc @@ -72,7 +72,6 @@ #include "net/log/net_log_capture_mode.h" #include "net/log/net_log_entry.h" #include "net/log/net_log_util.h" -#include "net/log/write_to_file_net_log_observer.h" #include "net/proxy/proxy_service.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -86,7 +85,6 @@ #include "chromeos/dbus/debug_daemon_client.h" #include "chromeos/network/onc/onc_certificate_importer_impl.h" #include "chromeos/network/onc/onc_utils.h" -#include "components/user_manager/user.h" #endif using base::Value; @@ -595,7 +593,7 @@ void NetInternalsMessageHandler::IOThreadImpl::Detach() { DCHECK_CURRENTLY_ON(BrowserThread::IO); // Unregister with network stack to observe events. if (net_log()) - net_log()->DeprecatedRemoveObserver(this); + net_log()->RemoveObserver(this); } void NetInternalsMessageHandler::IOThreadImpl::OnWebUIDeleted() { @@ -611,7 +609,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady( // pending events, so they won't appear before the status events created for // currently active network objects below. if (net_log()) { - net_log()->DeprecatedRemoveObserver(this); + net_log()->RemoveObserver(this); PostPendingEntries(); } @@ -624,7 +622,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady( PrePopulateEventList(); // Register with network stack to observe events. - io_thread_->net_log()->DeprecatedAddObserver( + io_thread_->net_log()->AddObserver( this, net::NetLogCaptureMode::IncludeCookiesAndCredentials()); } @@ -1027,8 +1025,7 @@ void NetInternalsMessageHandler::IOThreadImpl::PrePopulateEventList() { std::set<net::URLRequestContext*> contexts; for (const auto& getter : context_getters_) contexts.insert(getter->GetURLRequestContext()); - contexts.insert(io_thread_->globals()->proxy_script_fetcher_context.get()); - contexts.insert(io_thread_->globals()->system_request_context.get()); + contexts.insert(io_thread_->globals()->system_request_context); // Add entries for ongoing network objects. CreateNetLogEntriesForActiveObjects(contexts, this); diff --git a/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc index 7ab14c99ba1..c03a04922fb 100644 --- a/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc @@ -42,11 +42,11 @@ #include "net/dns/mock_host_resolver.h" #include "net/http/http_network_session.h" #include "net/http/http_transaction_factory.h" +#include "net/log/file_net_log_observer.h" #include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_source_type.h" #include "net/log/net_log_with_source.h" -#include "net/log/write_to_file_net_log_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "net/url_request/url_request_context.h" @@ -91,6 +91,11 @@ void AddCacheEntryOnIOThread(net::URLRequestContextGetter* context_getter, ttl); } +struct WriteNetLogState { + base::ScopedTempDir temp_directory; + base::FilePath log_path; +}; + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -140,14 +145,17 @@ class NetInternalsTest::MessageHandler : public content::WebUIMessageHandler { // Closes an incognito browser created with CreateIncognitoBrowser. void CloseIncognitoBrowser(const base::ListValue* list_value); - // Creates a simple log using WriteToFileNetLogObserver, and returns it to - // the Javascript callback. + // Creates a simple NetLog and returns it to the Javascript callback. void GetNetLogFileContents(const base::ListValue* list_value); // Changes the data reduction proxy mode. A boolean is assumed to exist at // index 0 which enables the proxy is set to true. void EnableDataReductionProxy(const base::ListValue* list_value); + // Called after the NetLog started by GetNetLogFileContents() has been written + // to disk. Responds to the Javascript caller with the log contents. + void OnFinishedWritingNetLog(std::unique_ptr<WriteNetLogState> state); + Browser* browser() { return net_internals_test_->browser(); } NetInternalsTest* net_internals_test_; @@ -292,37 +300,37 @@ void NetInternalsTest::MessageHandler::CloseIncognitoBrowser( void NetInternalsTest::MessageHandler::GetNetLogFileContents( const base::ListValue* list_value) { base::ThreadRestrictions::ScopedAllowIO allow_io; - base::ScopedTempDir temp_directory; - ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); - base::FilePath temp_file; - ASSERT_TRUE( - base::CreateTemporaryFileInDir(temp_directory.GetPath(), &temp_file)); - base::ScopedFILE temp_file_handle(base::OpenFile(temp_file, "w")); - ASSERT_TRUE(temp_file_handle); + + std::unique_ptr<WriteNetLogState> state = + base::MakeUnique<WriteNetLogState>(); + + ASSERT_TRUE(state->temp_directory.CreateUniqueTempDir()); + ASSERT_TRUE(base::CreateTemporaryFileInDir(state->temp_directory.GetPath(), + &state->log_path)); std::unique_ptr<base::Value> constants(net_log::ChromeNetLog::GetConstants( base::CommandLine::ForCurrentProcess()->GetCommandLineString(), chrome::GetChannelString())); - std::unique_ptr<net::WriteToFileNetLogObserver> net_log_logger( - new net::WriteToFileNetLogObserver()); + + std::unique_ptr<net::FileNetLogObserver> net_log_logger = + net::FileNetLogObserver::CreateUnbounded(state->log_path, + std::move(constants)); + net_log_logger->StartObserving(g_browser_process->net_log(), - std::move(temp_file_handle), constants.get(), - nullptr); + net::NetLogCaptureMode::Default()); + g_browser_process->net_log()->AddGlobalEntry( net::NetLogEventType::NETWORK_IP_ADDRESSES_CHANGED); net::NetLogWithSource net_log_with_source = net::NetLogWithSource::Make( g_browser_process->net_log(), net::NetLogSourceType::URL_REQUEST); net_log_with_source.BeginEvent(net::NetLogEventType::REQUEST_ALIVE); - net_log_logger->StopObserving(nullptr); - net_log_logger.reset(); - std::string log_contents; - ASSERT_TRUE(base::ReadFileToString(temp_file, &log_contents)); - ASSERT_GT(log_contents.length(), 0u); - - std::unique_ptr<base::Value> log_contents_value( - new base::Value(log_contents)); - RunJavascriptCallback(log_contents_value.get()); + // Call OnFinishedWritingNetLog() once net_log_logger has completed writing it + // to disk. + net_log_logger->StopObserving( + nullptr, + base::Bind(&NetInternalsTest::MessageHandler::OnFinishedWritingNetLog, + base::Unretained(this), base::Passed(std::move(state)))); } void NetInternalsTest::MessageHandler::EnableDataReductionProxy( @@ -333,6 +341,21 @@ void NetInternalsTest::MessageHandler::EnableDataReductionProxy( prefs::kDataSaverEnabled, enable); } +void NetInternalsTest::MessageHandler::OnFinishedWritingNetLog( + std::unique_ptr<WriteNetLogState> state) { + base::ThreadRestrictions::ScopedAllowIO allow_io; + + std::string log_contents; + ASSERT_TRUE(base::ReadFileToString(state->log_path, &log_contents)); + ASSERT_GT(log_contents.length(), 0u); + + std::unique_ptr<base::Value> log_contents_value( + new base::Value(log_contents)); + RunJavascriptCallback(log_contents_value.get()); + + state.reset(); +} + //////////////////////////////////////////////////////////////////////////////// // NetInternalsTest //////////////////////////////////////////////////////////////////////////////// diff --git a/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index 0b2364d867e..ad2603e6cd0 100644 --- a/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.cc @@ -595,7 +595,7 @@ void AppLauncherHandler::HandleUninstallApp(const base::ListValue* args) { base::Bind(&base::DoNothing), nullptr); CleanupAfterUninstall(); } else { - GetExtensionUninstallDialog()->ConfirmUninstall( + CreateExtensionUninstallDialog()->ConfirmUninstall( extension, extensions::UNINSTALL_REASON_USER_INITIATED, extensions::UNINSTALL_SOURCE_CHROME_APPS_PAGE); } @@ -630,9 +630,9 @@ void AppLauncherHandler::HandleShowAppInfo(const base::ListValue* args) { AppInfoLaunchSource::FROM_APPS_PAGE, AppInfoLaunchSource::NUM_LAUNCH_SOURCES); - ShowAppInfoInNativeDialog( - web_ui()->GetWebContents(), GetAppInfoNativeDialogSize(), - Profile::FromWebUI(web_ui()), extension, base::Closure()); + ShowAppInfoInNativeDialog(web_ui()->GetWebContents(), + Profile::FromWebUI(web_ui()), extension, + base::Closure()); } void AppLauncherHandler::HandleReorderApps(const base::ListValue* args) { @@ -856,16 +856,13 @@ void AppLauncherHandler::ExtensionEnableFlowAborted(bool user_initiated) { } extensions::ExtensionUninstallDialog* -AppLauncherHandler::GetExtensionUninstallDialog() { - if (!extension_uninstall_dialog_.get()) { - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); - extension_uninstall_dialog_.reset( - extensions::ExtensionUninstallDialog::Create( - extension_service_->profile(), - browser->window()->GetNativeWindow(), - this)); - } +AppLauncherHandler::CreateExtensionUninstallDialog() { + Browser* browser = + chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); + extension_uninstall_dialog_.reset( + extensions::ExtensionUninstallDialog::Create( + extension_service_->profile(), browser->window()->GetNativeWindow(), + this)); return extension_uninstall_dialog_.get(); } diff --git a/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.h index e808463991e..6bf2f8346c3 100644 --- a/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.h +++ b/chromium/chrome/browser/ui/webui/ntp/app_launcher_handler.h @@ -165,7 +165,7 @@ class AppLauncherHandler // Returns the ExtensionUninstallDialog object for this class, creating it if // needed. - extensions::ExtensionUninstallDialog* GetExtensionUninstallDialog(); + extensions::ExtensionUninstallDialog* CreateExtensionUninstallDialog(); // Continuation for installing a bookmark app after favicon lookup. void OnFaviconForApp(std::unique_ptr<AppInstallInfo> install_info, diff --git a/chromium/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chromium/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index 444478cf76f..9a2137b2a20 100644 --- a/chromium/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chromium/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc @@ -32,7 +32,6 @@ #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" #include "chrome/grit/theme_resources.h" #include "components/bookmarks/common/bookmark_pref_names.h" #include "components/google/core/browser/google_util.h" @@ -337,22 +336,32 @@ void NTPResourceCache::CreateNewTabGuestHTML() { policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - std::string enterprise_domain = connector->GetEnterpriseDomain(); - // TODO(jamescook): What about Active Directory managed devices? - if (!enterprise_domain.empty()) { - // Device is enterprise enrolled. + if (connector->IsEnterpriseManaged()) { localized_strings.SetString("enterpriseInfoVisible", "true"); - base::string16 enterprise_info = - l10n_util::GetStringFUTF16(IDS_ASH_ENTERPRISE_DEVICE_MANAGED_BY, - base::UTF8ToUTF16(enterprise_domain)); - localized_strings.SetString("enterpriseInfoMessage", enterprise_info); localized_strings.SetString("enterpriseLearnMore", - l10n_util::GetStringUTF16(IDS_LEARN_MORE)); + l10n_util::GetStringUTF16(IDS_LEARN_MORE)); localized_strings.SetString("enterpriseInfoHintLink", chrome::kLearnMoreEnterpriseURL); + base::string16 enterprise_info; + if (connector->IsCloudManaged()) { + const std::string enterprise_display_domain = + connector->GetEnterpriseDisplayDomain(); + enterprise_info = l10n_util::GetStringFUTF16( + IDS_ASH_ENTERPRISE_DEVICE_MANAGED_BY, + base::UTF8ToUTF16(enterprise_display_domain)); + } else if (connector->IsActiveDirectoryManaged()) { + enterprise_info = + l10n_util::GetStringUTF16(IDS_ASH_ENTERPRISE_DEVICE_MANAGED); + } else { + NOTREACHED() << "Unknown management type"; + } + localized_strings.SetString("enterpriseInfoMessage", enterprise_info); } else { localized_strings.SetString("enterpriseInfoVisible", "false"); + localized_strings.SetString("enterpriseInfoMessage", ""); + localized_strings.SetString("enterpriseLearnMore", ""); + localized_strings.SetString("enterpriseInfoHintLink", ""); } #endif @@ -370,17 +379,10 @@ void NTPResourceCache::CreateNewTabGuestHTML() { static const base::StringPiece guest_tab_html( ResourceBundle::GetSharedInstance().GetRawDataResource(guest_tab_ids)); -#if defined(OS_CHROMEOS) - // TODO(dbeam): convert c/b/resources/chromeos/guest_session_tab.html from - // i18n-* to $i18n{}. - std::string full_html = webui::GetI18nTemplateHtml( - guest_tab_html, &localized_strings); -#else ui::TemplateReplacements replacements; ui::TemplateReplacementsFromDictionaryValue(localized_strings, &replacements); std::string full_html = ui::ReplaceTemplateExpressions(guest_tab_html, replacements); -#endif new_tab_guest_html_ = base::RefCountedString::TakeString(&full_html); } diff --git a/chromium/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/chromium/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc index 5f679da3960..c9e54c0d2c5 100644 --- a/chromium/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc +++ b/chromium/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc @@ -34,7 +34,10 @@ class ChromeNTPTilesInternalsMessageHandlerClient : public content::WebUIMessageHandler, public ntp_tiles::NTPTilesInternalsMessageHandlerClient { public: - ChromeNTPTilesInternalsMessageHandlerClient() {} + // |favicon_service| must not be null and must outlive this object. + explicit ChromeNTPTilesInternalsMessageHandlerClient( + favicon::FaviconService* favicon_service) + : handler_(favicon_service) {} private: // content::WebUIMessageHandler: @@ -122,10 +125,12 @@ content::WebUIDataSource* CreateNTPTilesInternalsHTMLSource() { NTPTilesInternalsUI::NTPTilesInternalsUI(content::WebUI* web_ui) : WebUIController(web_ui) { - content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), - CreateNTPTilesInternalsHTMLSource()); + Profile* profile = Profile::FromWebUI(web_ui); + content::WebUIDataSource::Add(profile, CreateNTPTilesInternalsHTMLSource()); web_ui->AddMessageHandler( - base::MakeUnique<ChromeNTPTilesInternalsMessageHandlerClient>()); + base::MakeUnique<ChromeNTPTilesInternalsMessageHandlerClient>( + FaviconServiceFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS))); } NTPTilesInternalsUI::~NTPTilesInternalsUI() {} diff --git a/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc b/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc index 2d7be60d63f..3e370fc2487 100644 --- a/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc @@ -6,32 +6,39 @@ #include <stdint.h> #include <stdlib.h> + +#include <algorithm> #include <utility> -#include <vector> #include "base/bind.h" #include "base/guid.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/values.h" -#include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/offline_pages/prefetch/prefetch_background_task.h" -#include "chrome/browser/android/offline_pages/request_coordinator_factory.h" +#include "chrome/browser/offline_pages/offline_page_model_factory.h" +#include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" +#include "chrome/browser/offline_pages/request_coordinator_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/channel_info.h" +#include "chrome/common/chrome_content_client.h" #include "components/offline_pages/core/client_namespace_constants.h" +#include "components/offline_pages/core/offline_page_feature.h" +#include "components/offline_pages/core/prefetch/generate_page_bundle_request.h" +#include "components/offline_pages/core/prefetch/get_operation_request.h" +#include "components/offline_pages/core/prefetch/prefetch_downloader.h" +#include "components/offline_pages/core/prefetch/prefetch_service.h" #include "content/public/browser/web_ui.h" #include "net/base/network_change_notifier.h" namespace offline_internals { -OfflineInternalsUIMessageHandler::OfflineInternalsUIMessageHandler() - : offline_page_model_(nullptr), - request_coordinator_(nullptr), - weak_ptr_factory_(this) {} +namespace { -OfflineInternalsUIMessageHandler::~OfflineInternalsUIMessageHandler() {} - -std::string OfflineInternalsUIMessageHandler::GetStringFromDeletePageResult( +std::string GetStringFromDeletePageResult( offline_pages::DeletePageResult value) { switch (value) { case offline_pages::DeletePageResult::SUCCESS: @@ -51,7 +58,7 @@ std::string OfflineInternalsUIMessageHandler::GetStringFromDeletePageResult( return "Unknown"; } -std::string OfflineInternalsUIMessageHandler::GetStringFromDeleteRequestResults( +std::string GetStringFromDeleteRequestResults( const offline_pages::MultipleItemStatuses& results) { // If any requests failed, return "failure", else "success". for (const auto& result : results) { @@ -62,10 +69,62 @@ std::string OfflineInternalsUIMessageHandler::GetStringFromDeleteRequestResults( return "Success"; } -std::string OfflineInternalsUIMessageHandler::GetStringFromSavePageStatus() { +std::string GetStringFromSavePageStatus() { return "Available"; } +std::string GetStringFromPrefetchRequestStatus( + offline_pages::PrefetchRequestStatus status) { + switch (status) { + case offline_pages::PrefetchRequestStatus::SUCCESS: + return "Success"; + case offline_pages::PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF: + return "Retry w/out backoff"; + case offline_pages::PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF: + return "Retry w/ backoff"; + case offline_pages::PrefetchRequestStatus::SHOULD_SUSPEND: + return "Suspend"; + default: + NOTREACHED(); + return "Unknown"; + } +} + +std::string GetStringRenderPageInfoList( + const std::vector<offline_pages::RenderPageInfo>& pages) { + std::string str("[\n"); + bool first = true; + for (const auto& page : pages) { + if (first) + first = false; + else + str += ",\n"; + str += base::StringPrintf( + " {\n" + " url: \"%s\",\n" + " redirect_url: \"%s\",\n" + " status: %d,\n" + " body_name: \"%s\",\n" + " body_length: %lld\n" + " }", + page.url.c_str(), page.redirect_url.c_str(), + static_cast<int>(page.status), page.body_name.c_str(), + static_cast<long long>(page.body_length)); + } + str += "\n]"; + return str; +} + +} // namespace + +OfflineInternalsUIMessageHandler::OfflineInternalsUIMessageHandler() + : offline_page_model_(nullptr), + request_coordinator_(nullptr), + prefetch_service_(nullptr), + weak_ptr_factory_(this) {} + +OfflineInternalsUIMessageHandler::~OfflineInternalsUIMessageHandler() {} + void OfflineInternalsUIMessageHandler::HandleDeleteSelectedPages( const base::ListValue* args) { std::string callback_id; @@ -236,7 +295,7 @@ void OfflineInternalsUIMessageHandler::HandleScheduleNwake( const base::Value* callback_id; CHECK(args->Get(0, &callback_id)); - offline_pages::PrefetchBackgroundTask::Schedule(); + offline_pages::PrefetchBackgroundTask::Schedule(0); ResolveJavascriptCallback(*callback_id, base::Value("Scheduled.")); } @@ -252,6 +311,68 @@ void OfflineInternalsUIMessageHandler::HandleCancelNwake( ResolveJavascriptCallback(*callback_id, base::Value("Cancelled.")); } +void OfflineInternalsUIMessageHandler::HandleGeneratePageBundle( + const base::ListValue* args) { + AllowJavascript(); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + + std::string data; + CHECK(args->GetString(1, &data)); + std::vector<std::string> page_urls = base::SplitStringUsingSubstr( + data, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + generate_page_bundle_request_.reset( + new offline_pages::GeneratePageBundleRequest( + GetUserAgent(), "GCM ID", 1000000, page_urls, chrome::GetChannel(), + Profile::FromWebUI(web_ui())->GetRequestContext(), + base::Bind( + &OfflineInternalsUIMessageHandler::HandlePrefetchRequestCallback, + weak_ptr_factory_.GetWeakPtr(), callback_id))); +} + +void OfflineInternalsUIMessageHandler::HandleGetOperation( + const base::ListValue* args) { + AllowJavascript(); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + + std::string name; + CHECK(args->GetString(1, &name)); + base::TrimWhitespaceASCII(name, base::TRIM_ALL, &name); + + get_operation_request_.reset(new offline_pages::GetOperationRequest( + name, chrome::GetChannel(), + Profile::FromWebUI(web_ui())->GetRequestContext(), + base::Bind( + &OfflineInternalsUIMessageHandler::HandlePrefetchRequestCallback, + weak_ptr_factory_.GetWeakPtr(), callback_id))); +} + +void OfflineInternalsUIMessageHandler::HandleDownloadArchive( + const base::ListValue* args) { + AllowJavascript(); + std::string name; + CHECK(args->GetString(0, &name)); + base::TrimWhitespaceASCII(name, base::TRIM_ALL, &name); + + if (prefetch_service_) { + prefetch_service_->GetPrefetchDownloader()->StartDownload( + base::GenerateGUID(), name); + } +} + +void OfflineInternalsUIMessageHandler::HandlePrefetchRequestCallback( + std::string callback_id, + offline_pages::PrefetchRequestStatus status, + const std::string& operation_name, + const std::vector<offline_pages::RenderPageInfo>& pages) { + ResolveJavascriptCallback( + base::Value(callback_id), + base::Value(GetStringFromPrefetchRequestStatus(status) + "\n" + + operation_name + "\n" + GetStringRenderPageInfoList(pages))); +} + void OfflineInternalsUIMessageHandler::HandleSetRecordRequestQueue( const base::ListValue* args) { AllowJavascript(); @@ -261,6 +382,15 @@ void OfflineInternalsUIMessageHandler::HandleSetRecordRequestQueue( request_coordinator_->GetLogger()->SetIsLogging(should_record); } +void OfflineInternalsUIMessageHandler::HandleSetRecordPrefetchService( + const base::ListValue* args) { + AllowJavascript(); + bool should_record; + CHECK(args->GetBoolean(0, &should_record)); + if (prefetch_service_) + prefetch_service_->GetLogger()->SetIsLogging(should_record); +} + void OfflineInternalsUIMessageHandler::HandleGetLoggingState( const base::ListValue* args) { AllowJavascript(); @@ -276,6 +406,11 @@ void OfflineInternalsUIMessageHandler::HandleGetLoggingState( request_coordinator_ ? request_coordinator_->GetLogger()->GetIsLogging() : false); + bool prefetch_logging = false; + if (prefetch_service_) { + prefetch_logging = prefetch_service_->GetLogger()->GetIsLogging(); + } + result.SetBoolean("prefetchIsLogging", prefetch_logging); ResolveJavascriptCallback(*callback_id, result); } @@ -290,6 +425,8 @@ void OfflineInternalsUIMessageHandler::HandleGetEventLogs( offline_page_model_->GetLogger()->GetLogs(&logs); if (request_coordinator_) request_coordinator_->GetLogger()->GetLogs(&logs); + if (prefetch_service_) + prefetch_service_->GetLogger()->GetLogs(&logs); std::sort(logs.begin(), logs.end()); base::ListValue result; @@ -355,6 +492,11 @@ void OfflineInternalsUIMessageHandler::RegisterMessages() { base::Bind(&OfflineInternalsUIMessageHandler::HandleSetRecordPageModel, weak_ptr_factory_.GetWeakPtr())); web_ui()->RegisterMessageCallback( + "setRecordPrefetchService", + base::Bind( + &OfflineInternalsUIMessageHandler::HandleSetRecordPrefetchService, + weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( "getLoggingState", base::Bind(&OfflineInternalsUIMessageHandler::HandleGetLoggingState, weak_ptr_factory_.GetWeakPtr())); @@ -374,6 +516,18 @@ void OfflineInternalsUIMessageHandler::RegisterMessages() { "cancelNwake", base::Bind(&OfflineInternalsUIMessageHandler::HandleCancelNwake, weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "generatePageBundle", + base::Bind(&OfflineInternalsUIMessageHandler::HandleGeneratePageBundle, + weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "getOperation", + base::Bind(&OfflineInternalsUIMessageHandler::HandleGetOperation, + weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + "downloadArchive", + base::Bind(&OfflineInternalsUIMessageHandler::HandleDownloadArchive, + weak_ptr_factory_.GetWeakPtr())); // Get the offline page model associated with this web ui. Profile* profile = Profile::FromWebUI(web_ui()); @@ -381,6 +535,8 @@ void OfflineInternalsUIMessageHandler::RegisterMessages() { offline_pages::OfflinePageModelFactory::GetForBrowserContext(profile); request_coordinator_ = offline_pages::RequestCoordinatorFactory::GetForBrowserContext(profile); + prefetch_service_ = + offline_pages::PrefetchServiceFactory::GetForBrowserContext(profile); } } // namespace offline_internals diff --git a/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h b/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h index 2dba260b69e..00a595de20f 100644 --- a/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h +++ b/chromium/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.h @@ -5,16 +5,24 @@ #ifndef CHROME_BROWSER_UI_WEBUI_OFFLINE_OFFLINE_INTERNALS_UI_MESSAGE_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_OFFLINE_OFFLINE_INTERNALS_UI_MESSAGE_HANDLER_H_ +#include <memory> +#include <string> +#include <vector> + #include "base/memory/weak_ptr.h" #include "base/values.h" #include "components/offline_pages/core/background/request_coordinator.h" #include "components/offline_pages/core/background/save_page_request.h" #include "components/offline_pages/core/offline_page_model.h" #include "components/offline_pages/core/offline_store_types.h" +#include "components/offline_pages/core/prefetch/prefetch_types.h" #include "content/public/browser/web_ui_message_handler.h" namespace offline_pages { +class PrefetchService; enum class GetRequestsResult; +class GeneratePageBundleRequest; +class GetOperationRequest; } namespace offline_internals { @@ -47,7 +55,10 @@ class OfflineInternalsUIMessageHandler : public content::WebUIMessageHandler { // Set whether to record request queue events. void HandleSetRecordRequestQueue(const base::ListValue* args); - // Load both Page Model and Request Queue event logs. + // Set whether to record prefetch service events. + void HandleSetRecordPrefetchService(const base::ListValue* args); + + // Load all offline services' event logs. void HandleGetEventLogs(const base::ListValue* args); // Load whether logs are being recorded. @@ -65,6 +76,15 @@ class OfflineInternalsUIMessageHandler : public content::WebUIMessageHandler { // Cancels an NWake signal. void HandleCancelNwake(const base::ListValue* args); + // Sends and processes the request to generate page bundle. + void HandleGeneratePageBundle(const base::ListValue* args); + + // Sends and processes a request to get the info about an operation. + void HandleGetOperation(const base::ListValue* args); + + // Downloads an archive. + void HandleDownloadArchive(const base::ListValue* args); + // Callback for async GetAllPages calls. void HandleStoredPagesCallback( std::string callback_id, @@ -85,16 +105,12 @@ class OfflineInternalsUIMessageHandler : public content::WebUIMessageHandler { std::string callback_id, const offline_pages::MultipleItemStatuses& results); - // Turns a DeletePageResult enum into logical string. - std::string GetStringFromDeletePageResult( - offline_pages::DeletePageResult value); - - // Summarizes the MultipleItemStatuses vector with a string. - std::string GetStringFromDeleteRequestResults( - const offline_pages::MultipleItemStatuses& result); - - // Turns a SavePageRequest::Status into logical string. - std::string GetStringFromSavePageStatus(); + // Callback for GeneratePageBundle/GetOperation request calls. + void HandlePrefetchRequestCallback( + std::string callback_id, + offline_pages::PrefetchRequestStatus status, + const std::string& operation_name, + const std::vector<offline_pages::RenderPageInfo>& pages); // Offline page model to call methods on. offline_pages::OfflinePageModel* offline_page_model_; @@ -102,6 +118,13 @@ class OfflineInternalsUIMessageHandler : public content::WebUIMessageHandler { // Request coordinator for background offline actions. offline_pages::RequestCoordinator* request_coordinator_; + // Prefetch service for prefetching service logs and actions. + offline_pages::PrefetchService* prefetch_service_; + + std::unique_ptr<offline_pages::GeneratePageBundleRequest> + generate_page_bundle_request_; + std::unique_ptr<offline_pages::GetOperationRequest> get_operation_request_; + // Factory for creating references in callbacks. base::WeakPtrFactory<OfflineInternalsUIMessageHandler> weak_ptr_factory_; @@ -110,4 +133,4 @@ class OfflineInternalsUIMessageHandler : public content::WebUIMessageHandler { } // namespace offline_internals -#endif // CHROME_BROWSER_UI_WEBUI_OFFLINE_OFFLINE_INTERNALS_UI_MESSAGE_HANDLER_H_ +#endif // CHROME_BROWSER_UI_WEBUI_OFFLINE_OFFLINE_INTERNALS_UI_MESSAGE_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.cc b/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.cc index 439115ef720..788d8c37c1f 100644 --- a/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.cc +++ b/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.cc @@ -20,7 +20,7 @@ OmniboxUI::OmniboxUI(content::WebUI* web_ui) : MojoWebUIController(web_ui) { content::WebUIDataSource::Create(chrome::kChromeUIOmniboxHost); source->AddResourcePath("omnibox.css", IDR_OMNIBOX_CSS); source->AddResourcePath("omnibox.js", IDR_OMNIBOX_JS); - source->AddResourcePath("chrome/browser/ui/webui/omnibox/omnibox.mojom", + source->AddResourcePath("chrome/browser/ui/webui/omnibox/omnibox.mojom.js", IDR_OMNIBOX_MOJO_JS); source->SetDefaultResource(IDR_OMNIBOX_HTML); @@ -30,7 +30,6 @@ OmniboxUI::OmniboxUI(content::WebUI* web_ui) : MojoWebUIController(web_ui) { OmniboxUI::~OmniboxUI() {} void OmniboxUI::BindUIHandler( - const service_manager::BindSourceInfo& source_info, mojom::OmniboxPageHandlerRequest request) { omnibox_handler_.reset( new OmniboxPageHandler(Profile::FromWebUI(web_ui()), std::move(request))); diff --git a/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.h b/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.h index a5a11a3295e..613dbbb78cb 100644 --- a/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.h +++ b/chromium/chrome/browser/ui/webui/omnibox/omnibox_ui.h @@ -19,8 +19,7 @@ class OmniboxUI : public MojoWebUIController<mojom::OmniboxPageHandler> { private: // MojoWebUIController overrides: - void BindUIHandler(const service_manager::BindSourceInfo& source_info, - mojom::OmniboxPageHandlerRequest request) override; + void BindUIHandler(mojom::OmniboxPageHandlerRequest request) override; std::unique_ptr<OmniboxPageHandler> omnibox_handler_; diff --git a/chromium/chrome/browser/ui/webui/options/OWNERS b/chromium/chrome/browser/ui/webui/options/OWNERS index 5fb82a30bed..12eda5ad501 100644 --- a/chromium/chrome/browser/ui/webui/options/OWNERS +++ b/chromium/chrome/browser/ui/webui/options/OWNERS @@ -1,4 +1,4 @@ -# This UI is deprecated. See chrome/browser/ui/webui/options/ instead. +# This UI is deprecated. See chrome/browser/ui/webui/settings/ instead. set noparent dbeam@chromium.org diff --git a/chromium/chrome/browser/ui/webui/options/autofill_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/autofill_options_browsertest.js deleted file mode 100644 index 79109af9407..00000000000 --- a/chromium/chrome/browser/ui/webui/options/autofill_options_browsertest.js +++ /dev/null @@ -1,174 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * Returns the HTML element for the |field|. - * @param {string} field The field name for the element. - * @return {HTMLElement} The HTML element. - */ -function getField(field) { - return document.querySelector( - '#autofill-edit-address-overlay [field=' + field + ']'); -} - -/** - * Returns the size of the |list|. - * @param {HTMLElement} list The list to check. - * @return {number} The size of the list. - */ -function getListSize(list) { - // Remove 1 for placeholder input field. - return list.items.length - 1; -} - -/** - * TestFixture for autofill options WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function AutofillOptionsWebUITest() {} - -AutofillOptionsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to autofill options. - * @override - */ - browsePreload: 'chrome://settings-frame/autofill', -}; - -// TODO(crbug.com/617066) Flakes on Win. -GEN('#if defined(OS_WIN)'); -GEN('#define MAYBE_testOpenAutofillOptions ' + - 'DISABLED_testOpenAutofillOptions'); -GEN('#else'); -GEN('#define MAYBE_testOpenAutofillOptions testOpenAutofillOptions'); -GEN('#endif'); -// Test opening the autofill options has correct location. -TEST_F('AutofillOptionsWebUITest', 'MAYBE_testOpenAutofillOptions', - function() { - assertEquals(this.browsePreload, document.location.href); -}); - -/** - * TestFixture for autofill edit address overlay WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function AutofillEditAddressWebUITest() {} - -AutofillEditAddressWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/autofillEditAddress', -}; - -TEST_F('AutofillEditAddressWebUITest', 'testInitialFormLayout', function() { - assertEquals(this.browsePreload, document.location.href); - - var fields = ['country', 'phone', 'email', 'fullName', 'city']; - for (field in fields) { - assertEquals('', getField(fields[field]).value, 'Field: ' + fields[field]); - } - - testDone(); -}); - -TEST_F('AutofillEditAddressWebUITest', 'testLoadAddress', function() { - // http://crbug.com/434502 - // Accessibility failure was originally (and consistently) seen on Mac OS and - // Chromium OS. Disabling for all OSs because of a flake in Windows. There is - // a possibility for flake in linux too. - this.disableAccessibilityChecks(); - - assertEquals(this.browsePreload, document.location.href); - - var testAddress = { - guid: 'GUID Value', - fullName: 'Full Name 1', - companyName: 'Company Name Value', - addrLines: 'First Line Value\nSecond Line Value', - dependentLocality: 'Dependent Locality Value', - city: 'City Value', - state: 'State Value', - postalCode: 'Postal Code Value', - sortingCode: 'Sorting Code Value', - country: 'CH', - phone: '123', - email: 'a@b.c', - languageCode: 'de', - components: [[ - {field: 'postalCode', length: 'short'}, - {field: 'sortingCode', length: 'short'}, - {field: 'dependentLocality', length: 'short'}, - {field: 'city', length: 'short'}, - {field: 'state', length: 'short'}, - {field: 'addrLines', length: 'long'}, - {field: 'companyName', length: 'long'}, - {field: 'country', length: 'long'}, - {field: 'fullName', length: 'long', placeholder: 'Add name'} - ]] - }; - AutofillEditAddressOverlay.loadAddress(testAddress); - - var overlay = AutofillEditAddressOverlay.getInstance(); - assertEquals(testAddress.guid, overlay.guid_); - assertEquals(testAddress.languageCode, overlay.languageCode_); - - var inputs = ['companyName', 'dependentLocality', 'city', 'state', - 'postalCode', 'sortingCode', 'fullName', 'email', 'phone']; - for (var i in inputs) { - var field = getField(inputs[i]); - assertEquals(testAddress[inputs[i]], field.value); - assertTrue(field instanceof HTMLInputElement); - } - - var addrLines = getField('addrLines'); - assertEquals(testAddress.addrLines, addrLines.value); - assertTrue(addrLines instanceof HTMLTextAreaElement); - - var country = getField('country'); - assertEquals(testAddress.country, country.value); - assertTrue(country instanceof HTMLSelectElement); -}); - -TEST_F('AutofillEditAddressWebUITest', 'testLoadAddressComponents', function() { - assertEquals(this.browsePreload, document.location.href); - - var testInput = { - languageCode: 'fr', - components: [[{field: 'city'}], - [{field: 'state'}]] - }; - AutofillEditAddressOverlay.loadAddressComponents(testInput); - - assertEquals('fr', AutofillEditAddressOverlay.getInstance().languageCode_); - expectEquals(2, $('autofill-edit-address-fields').children.length); -}); - -TEST_F('AutofillEditAddressWebUITest', 'testFieldValuesSaved', function() { - assertEquals(this.browsePreload, document.location.href); - - AutofillEditAddressOverlay.loadAddressComponents({ - languageCode: 'en', - components: [[{field: 'city'}]] - }); - getField('city').value = 'New York'; - - AutofillEditAddressOverlay.loadAddressComponents({ - languageCode: 'en', - components: [[{field: 'state'}]] - }); - assertEquals(null, getField('city')); - - AutofillEditAddressOverlay.loadAddressComponents({ - languageCode: 'en', - components: [[{field: 'city'}]] - }); - assertEquals('New York', getField('city').value); -}); diff --git a/chromium/chrome/browser/ui/webui/options/autofill_options_handler_unittest.cc b/chromium/chrome/browser/ui/webui/options/autofill_options_handler_unittest.cc deleted file mode 100644 index a00cc4cb3d7..00000000000 --- a/chromium/chrome/browser/ui/webui/options/autofill_options_handler_unittest.cc +++ /dev/null @@ -1,62 +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 "chrome/browser/ui/webui/options/autofill_options_handler.h" - -#include "base/values.h" -#include "components/autofill/core/browser/autofill_profile.h" -#include "components/autofill/core/browser/autofill_test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace options { - -TEST(AutofillOptionsHandlerTest, AddressToDictionary) { - autofill::AutofillProfile profile; - autofill::test::SetProfileInfoWithGuid(&profile, - "guid", - "First", - "Middle", - "Last", - "fml@example.com", - "Acme inc", - "123 Main", - "Apt 2", - "Laredo", - "TX", - "77300", - "US", - "832-555-1000"); - - base::DictionaryValue dictionary; - options::AutofillOptionsHandler::AutofillProfileToDictionary(profile, - &dictionary); - - std::string value; - EXPECT_TRUE(dictionary.GetString("addrLines", &value)); - EXPECT_EQ("123 Main\nApt 2", value); - EXPECT_TRUE(dictionary.GetString("city", &value)); - EXPECT_EQ("Laredo", value); - EXPECT_TRUE(dictionary.GetString("country", &value)); - EXPECT_EQ("US", value); - EXPECT_TRUE(dictionary.GetString("dependentLocality", &value)); - EXPECT_EQ("", value); - EXPECT_TRUE(dictionary.GetString("guid", &value)); - EXPECT_EQ("guid", value); - EXPECT_TRUE(dictionary.GetString("languageCode", &value)); - EXPECT_EQ("", value); - EXPECT_TRUE(dictionary.GetString("postalCode", &value)); - EXPECT_EQ("77300", value); - EXPECT_TRUE(dictionary.GetString("sortingCode", &value)); - EXPECT_EQ("", value); - EXPECT_TRUE(dictionary.GetString("state", &value)); - EXPECT_EQ("TX", value); - EXPECT_TRUE(dictionary.GetString("email", &value)); - EXPECT_EQ("fml@example.com", value); - EXPECT_TRUE(dictionary.GetString("fullName", &value)); - EXPECT_EQ("First Middle Last", value); - EXPECT_TRUE(dictionary.GetString("phone", &value)); - EXPECT_EQ("832-555-1000", value); -} - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/browser_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/browser_options_browsertest.js deleted file mode 100644 index b5713f60ca6..00000000000 --- a/chromium/chrome/browser/ui/webui/options/browser_options_browsertest.js +++ /dev/null @@ -1,131 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for browser options WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function BrowserOptionsWebUITest() {} - -BrowserOptionsWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - browsePreload: 'chrome://chrome/settings/', -}; - -// Test opening the browser options has correct location. -// Times out on Mac debug only. See http://crbug.com/121030 -GEN('#if defined(OS_MACOSX) && !defined(NDEBUG)'); -GEN('#define MAYBE_testOpenBrowserOptions ' + - 'DISABLED_testOpenBrowserOptions'); -GEN('#else'); -GEN('#define MAYBE_testOpenBrowserOptions testOpenBrowserOptions'); -GEN('#endif // defined(OS_MACOSX)'); -TEST_F('BrowserOptionsWebUITest', 'MAYBE_testOpenBrowserOptions', function() { - assertEquals(this.browsePreload, document.location.href); - expectFalse($('navigation').classList.contains('background')); -}); - -/** - * TestFixture for the uber page when the browser options page has an overlay. - * @extends {testing.Test} - * @constructor - */ -function BrowserOptionsOverlayWebUITest() {} - -BrowserOptionsOverlayWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - browsePreload: 'chrome://chrome/settings/autofill', - - /** @override */ - isAsync: true, -}; - -TEST_F('BrowserOptionsOverlayWebUITest', 'testNavigationInBackground', - function() { - assertEquals(this.browsePreload, document.location.href); - - if ($('navigation').classList.contains('background')) { - testDone(); - return; - } - - // Wait for the message to be posted to the Uber page. - window.addEventListener('message', function(e) { - if (e.data.method == 'beginInterceptingEvents') { - window.setTimeout(function() { - assertTrue($('navigation').classList.contains('background')); - testDone(); - }); - } - }); -}); - -/** - * @extends {testing.Test} - * @constructor - */ -function BrowserOptionsFrameWebUITest() {} - -BrowserOptionsFrameWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/', - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/570721 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#sync-overview > A'); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/570723 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#profiles-list'); - }, -}; - -TEST_F('BrowserOptionsFrameWebUITest', 'testAdvancedSettingsHiddenByDefault', - function() { - assertEquals(this.browsePreload, document.location.href); - expectTrue($('advanced-settings').hidden); -}); - -/** - * @extends {testing.Test} - * @constructor - */ -function AdvancedSettingsWebUITest() {} - -AdvancedSettingsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/autofill', -}; - -// TODO(crbug.com/617066) Flakes on Win. -GEN('#if defined(OS_WIN)'); -GEN('#define MAYBE_testAdvancedSettingsShown ' + - 'DISABLED_testAdvancedSettingsShown'); -GEN('#else'); -GEN('#define MAYBE_testAdvancedSettingsShown testAdvancedSettingsShown'); -GEN('#endif'); -TEST_F('AdvancedSettingsWebUITest', 'MAYBE_testAdvancedSettingsShown', - function() { - assertEquals(this.browsePreload, document.location.href); - expectFalse($('advanced-settings').hidden); -}); diff --git a/chromium/chrome/browser/ui/webui/options/browser_options_handler.cc b/chromium/chrome/browser/ui/webui/options/browser_options_handler.cc index 61ce8bf577c..d775e136f69 100644 --- a/chromium/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/browser_options_handler.cc @@ -293,8 +293,6 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { {"downloadLocationGroupName", IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME}, {"easyUnlockDescription", IDS_OPTIONS_EASY_UNLOCK_DESCRIPTION, device_type_resource_id}, - {"easyUnlockRequireProximityLabel", - IDS_OPTIONS_EASY_UNLOCK_REQUIRE_PROXIMITY_LABEL, device_type_resource_id}, {"easyUnlockSectionTitle", IDS_OPTIONS_EASY_UNLOCK_SECTION_TITLE}, {"easyUnlockSetupButton", IDS_OPTIONS_EASY_UNLOCK_SETUP_BUTTON}, {"easyUnlockSetupIntro", IDS_OPTIONS_EASY_UNLOCK_SETUP_INTRO, @@ -740,9 +738,6 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { #endif #if defined(OS_CHROMEOS) - values->SetBoolean("cupsPrintDisabled", - base::CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kDisableNativeCups)); values->SetString("cupsPrintLearnMoreURL", chrome::kCrosPrintingLearnMoreURL); #endif // defined(OS_CHROMEOS) @@ -762,9 +757,6 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { values->SetBoolean( "easyUnlockAllowed", EasyUnlockService::Get(profile)->IsAllowed()); values->SetString("easyUnlockLearnMoreURL", chrome::kEasyUnlockLearnMoreUrl); - values->SetBoolean("easyUnlockProximityDetectionAllowed", - base::CommandLine::ForCurrentProcess()->HasSwitch( - proximity_auth::switches::kEnableProximityDetection)); #if defined(OS_CHROMEOS) RegisterTitle(values, "thirdPartyImeConfirmOverlay", @@ -992,8 +984,7 @@ void BrowserOptionsHandler::OnStateChanged(syncer::SyncService* sync) { } void BrowserOptionsHandler::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username, - const std::string& password) { + const std::string& username) { UpdateSyncState(); } diff --git a/chromium/chrome/browser/ui/webui/options/browser_options_handler.h b/chromium/chrome/browser/ui/webui/options/browser_options_handler.h index 2d117952b04..0fccab7731a 100644 --- a/chromium/chrome/browser/ui/webui/options/browser_options_handler.h +++ b/chromium/chrome/browser/ui/webui/options/browser_options_handler.h @@ -88,8 +88,7 @@ class BrowserOptionsHandler // SigninManagerBase::Observer implementation. void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username, - const std::string& password) override; + const std::string& username) override; void GoogleSignedOut(const std::string& account_id, const std::string& username) override; diff --git a/chromium/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc b/chromium/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc deleted file mode 100644 index ed0ae533f40..00000000000 --- a/chromium/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc +++ /dev/null @@ -1,108 +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. - -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/webui/options/options_ui_browsertest.h" -#include "components/policy/core/browser/browser_policy_connector.h" -#include "components/policy/core/common/external_data_fetcher.h" -#include "components/policy/core/common/mock_configuration_policy_provider.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_types.h" -#include "components/policy/policy_constants.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" -#include "chromeos/network/onc/onc_test_utils.h" -#endif - -using testing::Return; -using testing::_; - -class CertificateManagerBrowserTest : public options::OptionsUIBrowserTest { - public: - CertificateManagerBrowserTest() {} - ~CertificateManagerBrowserTest() override {} - - protected: - void SetUpInProcessBrowserTestFixture() override { - options::OptionsUIBrowserTest::SetUpInProcessBrowserTestFixture(); -#if defined(OS_CHROMEOS) - device_policy_test_helper_.MarkAsEnterpriseOwned(); -#endif - // Setup the policy provider for injecting certs through ONC policy. - EXPECT_CALL(provider_, IsInitializationComplete(_)) - .WillRepeatedly(Return(true)); - policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); - } - -#if defined(OS_CHROMEOS) - void LoadONCPolicy(const std::string& filename) { - const std::string& user_policy_blob = - chromeos::onc::test_utils::ReadTestData(filename); - policy::PolicyMap policy; - policy.Set(policy::key::kOpenNetworkConfiguration, - policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, - base::MakeUnique<base::Value>(user_policy_blob), nullptr); - provider_.UpdateChromePolicy(policy); - content::RunAllPendingInMessageLoop(); - } -#endif - - void ClickElement(const std::string& selector) { - EXPECT_TRUE(content::ExecuteScript( - GetSettingsFrame(), - "document.querySelector(\"" + selector + "\").click()")); - } - - bool HasElement(const std::string& selector) { - bool result; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - GetSettingsFrame(), - "window.domAutomationController.send(" - " !!document.querySelector('" + selector + "'));", - &result)); - return result; - } - - policy::MockConfigurationPolicyProvider provider_; -#if defined(OS_CHROMEOS) - policy::DevicePolicyCrosTestHelper device_policy_test_helper_; -#endif -}; - -#if defined(OS_CHROMEOS) -// Ensure policy-installed certificates without web trust do not display -// the managed setting indicator (only on Chrome OS). -IN_PROC_BROWSER_TEST_F(CertificateManagerBrowserTest, - PolicyCertificateWithoutWebTrustHasNoIndicator) { - LoadONCPolicy("certificate-authority.onc"); - NavigateToSettings(); - ClickElement("#certificatesManageButton"); - ClickElement("#ca-certs-nav-tab"); - EXPECT_FALSE(HasElement(".cert-policy")); -} -#endif - -#if defined(OS_CHROMEOS) -// Ensure policy-installed certificates with web trust display the -// managed setting indicator (only on Chrome OS). -IN_PROC_BROWSER_TEST_F(CertificateManagerBrowserTest, - PolicyCertificateWithWebTrustHasIndicator) { - LoadONCPolicy("certificate-web-authority.onc"); - NavigateToSettings(); - ClickElement("#certificatesManageButton"); - ClickElement("#ca-certs-nav-tab"); - EXPECT_TRUE(HasElement(".cert-policy")); -} -#endif diff --git a/chromium/chrome/browser/ui/webui/options/certificate_manager_browsertest.js b/chromium/chrome/browser/ui/webui/options/certificate_manager_browsertest.js deleted file mode 100644 index cb9e3d81840..00000000000 --- a/chromium/chrome/browser/ui/webui/options/certificate_manager_browsertest.js +++ /dev/null @@ -1,405 +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. - -// Mac and Windows go to native certificate manager, and certificate manager -// isn't implemented if OpenSSL is used. -GEN('#if defined(USE_NSS_CERTS)'); - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * URL of the Certificates dialog in the Settings page. - * @const - */ -var CERTIFICATE_MANAGER_SETTINGS_PAGE_URL = - 'chrome://settings-frame/certificates'; - -// Standalone certificate manager dialog page is implemented only in Chrome OS. -GEN('#if defined(OS_CHROMEOS)'); - -/** - * URL of the standalone certificate manager dialog page. - * @const - */ -var CERTIFICATE_MANAGER_STANDALONE_PAGE_URL = 'chrome://certificate-manager/'; - -GEN('#endif // defined(OS_CHROMEOS)'); - -/** - * TestFixture for certificate manager WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function CertificateManagerWebUIBaseTest() {} - -CertificateManagerWebUIBaseTest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - preLoad: function() { - // We can't check cr.isChromeOS in the preLoad since "cr" doesn't exist yet. - // This is copied from ui/webui/resources/js/cr.js, maybe - // there's a better way to do this. - this.isChromeOS = /CrOS/.test(navigator.userAgent); - - this.makeAndRegisterMockHandler( - [ - 'editCaCertificateTrust', - 'exportPersonalCertificate', - 'importPersonalCertificate', - 'importCaCertificate', - 'exportCertificate', - 'deleteCertificate', - 'populateCertificateManager', - 'viewCertificate', - ]); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - var ariaRoleNotScopedSelectors = [ - '#tree-item-autogen-id-0', - '#tree-item-autogen-id-1', - '#tree-item-autogen-id-2', - '#tree-item-autogen-id-3', - '#tree-item-autogen-id-4', - ]; - - // Enable when failure is resolved. - // AX_ARIA_09: http://crbug.com/570567 - this.accessibilityAuditConfig.ignoreSelectors( - 'ariaRoleNotScoped', - ariaRoleNotScopedSelectors); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/570566 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#caCertsTab-tree'); - - var focusableElementNotVisibleAndNotAriaHiddenSelectors = [ - '#personalCertsTab-tree', - '#personalCertsTab-import', - '#personalCertsTab-import-and-bind', - '#certificate-confirm', - ]; - - // Enable when failure is resolved. - // AX_FOCUS_01: http://crbug.com/570568 - this.accessibilityAuditConfig.ignoreSelectors( - 'focusableElementNotVisibleAndNotAriaHidden', - focusableElementNotVisibleAndNotAriaHiddenSelectors); - }, -}; - -/** - * TestFixture for certificate manager WebUI testing. - * @extends {CertificateManagerWebUIBaseTest} - * @constructor - */ -function CertificateManagerWebUIUnpopulatedTest() {} - -CertificateManagerWebUIUnpopulatedTest.prototype = { - __proto__: CertificateManagerWebUIBaseTest.prototype, - - /** - * Browse to the certificate manager dialog in the Settings page. - */ - browsePreload: CERTIFICATE_MANAGER_SETTINGS_PAGE_URL, - - /** @override */ - preLoad: function() { - CertificateManagerWebUIBaseTest.prototype.preLoad.call(this); - - // We expect the populateCertificateManager callback, but do not reply to - // it. This simulates what will be displayed if retrieving the cert list - // from NSS is slow. - this.mockHandler.expects(once()).populateCertificateManager(); - }, -}; - -// Test opening the certificate manager has correct location and buttons have -// correct initial states when onPopulateTree has not been called. -TEST_F('CertificateManagerWebUIUnpopulatedTest', - 'testUnpopulatedCertificateManager', function() { - assertEquals(this.browsePreload, document.location.href); - - // All buttons should be disabled to start. - expectTrue($('personalCertsTab-view').disabled); - expectTrue($('personalCertsTab-backup').disabled); - expectTrue($('personalCertsTab-delete').disabled); - expectTrue($('personalCertsTab-import').disabled); - if (this.isChromeOS) - expectTrue($('personalCertsTab-import-and-bind').disabled); - - expectTrue($('serverCertsTab-view').disabled); - expectTrue($('serverCertsTab-export').disabled); - expectTrue($('serverCertsTab-delete').disabled); - expectTrue($('serverCertsTab-import').disabled); - - expectTrue($('caCertsTab-view').disabled); - expectTrue($('caCertsTab-edit').disabled); - expectTrue($('caCertsTab-export').disabled); - expectTrue($('caCertsTab-delete').disabled); - expectTrue($('caCertsTab-import').disabled); - - expectTrue($('otherCertsTab-view').disabled); - expectTrue($('otherCertsTab-export').disabled); - expectTrue($('otherCertsTab-delete').disabled); - - Mock4JS.verifyAllMocks(); - - // If user database is not available, import buttons should be disabled. - CertificateManager.onModelReady(false /* userDbAvailable*/, - false /* tpmAvailable */); - - expectTrue($('personalCertsTab-import').disabled); - expectTrue($('serverCertsTab-import').disabled); - expectTrue($('caCertsTab-import').disabled); - - // Once we get the onModelReady call, the import buttons should be enabled, - // others should still be disabled. - CertificateManager.onModelReady(true /* userDbAvailable*/, - false /* tpmAvailable */); - - expectTrue($('personalCertsTab-view').disabled); - expectTrue($('personalCertsTab-backup').disabled); - expectTrue($('personalCertsTab-delete').disabled); - expectFalse($('personalCertsTab-import').disabled); - - expectTrue($('serverCertsTab-view').disabled); - expectTrue($('serverCertsTab-export').disabled); - expectTrue($('serverCertsTab-delete').disabled); - expectFalse($('serverCertsTab-import').disabled); - - expectTrue($('caCertsTab-view').disabled); - expectTrue($('caCertsTab-edit').disabled); - expectTrue($('caCertsTab-export').disabled); - expectTrue($('caCertsTab-delete').disabled); - expectFalse($('caCertsTab-import').disabled); - - expectTrue($('otherCertsTab-view').disabled); - expectTrue($('otherCertsTab-export').disabled); - expectTrue($('otherCertsTab-delete').disabled); - - // On ChromeOS, the import and bind button should only be enabled if TPM is - // present. - if (this.isChromeOS) { - expectTrue($('personalCertsTab-import-and-bind').disabled); - CertificateManager.onModelReady(true /* userDbAvailable*/, - true /* tpmAvailable */); - expectFalse($('personalCertsTab-import-and-bind').disabled); - } -}); - -/** - * TestFixture for certificate manager WebUI testing. - * @extends {CertificateManagerWebUIBaseTest} - * @constructor - */ -function CertificateManagerWebUITest() {} - -CertificateManagerWebUITest.prototype = { - __proto__: CertificateManagerWebUIBaseTest.prototype, - - /** @override */ - preLoad: function() { - CertificateManagerWebUIBaseTest.prototype.preLoad.call(this); - - var tpmAvailable = this.isChromeOS; - var userDbAvailable = true; - this.mockHandler.expects(once()).populateCertificateManager().will( - callFunction(function() { - CertificateManager.onModelReady(userDbAvailable, tpmAvailable); - - [['personalCertsTab-tree', - [{'id': 'o1', - 'name': 'org1', - 'subnodes': [{ 'id': 'c1', - 'name': 'cert1', - 'readonly': false, - 'untrusted': false, - 'extractable': true }], - }], - ], - ['caCertsTab-tree', - [{'id': 'o2', - 'name': 'org2', - 'subnodes': [{ 'id': 'ca_cert0', - 'name': 'ca_cert0', - 'readonly': false, - 'untrusted': false, - 'extractable': true, - 'policy': false }, - { 'id': 'ca_cert1', - 'name': 'ca_cert1', - 'readonly': false, - 'untrusted': false, - 'extractable': true, - 'policy': true }, - { 'id': 'ca_cert2', - 'name': 'ca_cert2', - 'readonly': false, - 'untrusted': false, - 'extractable': true, - 'policy': false }], - }], - ] - ].forEach(CertificateManager.onPopulateTree)})); - }, -}; - -/** - * TestFixture for testing certificate manager WebUI in the Settings page. - * @extends {CertificateManagerWebUITest} - * @constructor - */ -function CertificateManagerSettingsWebUITest() {} - -CertificateManagerSettingsWebUITest.prototype = { - __proto__: CertificateManagerWebUITest.prototype, - - /** - * Browse to the certificate manager dialog in the Settings page. - */ - browsePreload: CERTIFICATE_MANAGER_SETTINGS_PAGE_URL, -}; - -TEST_F('CertificateManagerSettingsWebUITest', - 'testViewAndDeleteCert', function() { - assertEquals(this.browsePreload, document.location.href); - - this.mockHandler.expects(once()).viewCertificate(['c1']); - - expectTrue($('personalCertsTab-view').disabled); - expectTrue($('personalCertsTab-backup').disabled); - expectTrue($('personalCertsTab-delete').disabled); - expectFalse($('personalCertsTab-import').disabled); - if (this.isChromeOS) - expectFalse($('personalCertsTab-import-and-bind').disabled); - - var personalCerts = $('personalCertsTab'); - - // Click on the first folder. - personalCerts.querySelector('div.tree-item').click(); - // Buttons should still be in same state. - expectTrue($('personalCertsTab-view').disabled); - expectTrue($('personalCertsTab-backup').disabled); - expectTrue($('personalCertsTab-delete').disabled); - expectFalse($('personalCertsTab-import').disabled); - if (this.isChromeOS) - expectFalse($('personalCertsTab-import-and-bind').disabled); - - // Click on the first cert. - personalCerts.querySelector('div.tree-item div.tree-item').click(); - // Buttons should now allow you to act on the cert. - expectFalse($('personalCertsTab-view').disabled); - expectFalse($('personalCertsTab-backup').disabled); - expectFalse($('personalCertsTab-delete').disabled); - expectFalse($('personalCertsTab-import').disabled); - if (this.isChromeOS) - expectFalse($('personalCertsTab-import-and-bind').disabled); - - // Click on the view button. - $('personalCertsTab-view').click(); - - Mock4JS.verifyAllMocks(); - - this.mockHandler.expects(once()).deleteCertificate(['c1']).will(callFunction( - function() { - CertificateManager.onPopulateTree(['personalCertsTab-tree', []]); - })); - - // Click on the delete button. - $('personalCertsTab-delete').click(); - - // Click on the cancel button to verify the confirmation overlay closes. - $('alertOverlayCancel').click(); - expectTrue($('alertOverlay').parentNode.classList.contains('transparent')); - - // Click on the delete button. - $('personalCertsTab-delete').click(); - - // Click on the ok button in the confirmation overlay. - $('alertOverlayOk').click(); - expectTrue($('alertOverlay').parentNode.classList.contains('transparent')); - - // Context sensitive buttons should be disabled. - expectTrue($('personalCertsTab-view').disabled); - expectTrue($('personalCertsTab-backup').disabled); - expectTrue($('personalCertsTab-delete').disabled); - expectFalse($('personalCertsTab-import').disabled); - if (this.isChromeOS) - expectFalse($('personalCertsTab-import-and-bind').disabled); - // Tree should be empty. - expectTrue(personalCerts.querySelector('div.tree-item') === null); -}); - -// Ensure certificate objects with the 'policy' property set have -// the cert-policy CSS class appended. -TEST_F('CertificateManagerSettingsWebUITest', - 'testPolicyInstalledCertificate', function() { - // Click on the first folder and get the certificates. - var caCertsTab = $('caCertsTab'); - caCertsTab.querySelector('div.tree-item').click(); - var certs = caCertsTab.querySelectorAll('div.tree-item div.tree-item'); - - // First cert shouldn't show the controlled setting badge, and the - // edit and delete buttons should be enabled. - var cert0 = certs[0]; - expectEquals('ca_cert0', cert0.data.name); - expectEquals(null, cert0.querySelector('.cert-policy')); - cert0.click(); - expectFalse($('caCertsTab-edit').disabled); - expectFalse($('caCertsTab-delete').disabled); - - // But the second should show the controlled setting badge, and the - // edit and delete buttons should be disabled. - var cert1 = certs[1]; - expectEquals('ca_cert1', cert1.data.name); - expectNotEquals(null, cert1.querySelector('.cert-policy')); - cert1.click(); - expectTrue($('caCertsTab-edit').disabled); - expectTrue($('caCertsTab-delete').disabled); -}); - -// Standalone certificate manager dialog page is implemented only in Chrome OS. -GEN('#if defined(OS_CHROMEOS)'); - -/** - * TestFixture for testing standalone certificate manager WebUI. - * @extends {CertificateManagerWebUITest} - * @constructor - */ -function CertificateManagerStandaloneWebUITest() {} - -CertificateManagerStandaloneWebUITest.prototype = { - __proto__: CertificateManagerWebUITest.prototype, - - /** - * Browse to the certificate manager page. - */ - browsePreload: CERTIFICATE_MANAGER_STANDALONE_PAGE_URL, -}; - -// Ensure that the standalone certificate manager page loads and displays the -// ceertificates correctly. -TEST_F('CertificateManagerStandaloneWebUITest', 'testCertsDisplaying', - function() { - assertEquals(this.browsePreload, document.location.href); - - // Click on the first folder and get the certificates. - var caCertsTab = $('caCertsTab'); - caCertsTab.querySelector('div.tree-item').click(); - var certs = caCertsTab.querySelectorAll('div.tree-item div.tree-item'); - - // There should be exactly three certificates displayed. - expectEquals(certs.length, 3); -}); - -GEN('#endif // defined(OS_CHROMEOS)'); - -GEN('#endif // defined(USE_NSS_CERTS)'); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc b/chromium/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc deleted file mode 100644 index 34ea81b1ced..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc +++ /dev/null @@ -1,166 +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 <stddef.h> - -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/login_manager_test.h" -#include "chrome/browser/chromeos/login/startup_utils.h" -#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/ui_test_utils.h" -#include "chromeos/settings/cros_settings_names.h" -#include "components/prefs/pref_service.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_utils.h" - -namespace chromeos { - -namespace { - -const char* kTestUsers[] = { "test-user1@gmail.com", "test-user2@gmail.com" }; - -} // namespace - -class AccountsOptionsTest : public LoginManagerTest { - public: - AccountsOptionsTest() - : LoginManagerTest(false), - stub_settings_provider_(base::MakeUnique<StubCrosSettingsProvider>()), - stub_settings_provider_ptr_(static_cast<StubCrosSettingsProvider*>( - stub_settings_provider_.get())) { - stub_settings_provider_->Set(kDeviceOwner, base::Value(kTestUsers[0])); - for (size_t i = 0; i < arraysize(kTestUsers); ++i) { - test_users_.push_back(AccountId::FromUserEmail(kTestUsers[i])); - } - } - - ~AccountsOptionsTest() override {} - - void SetUpOnMainThread() override { - LoginManagerTest::SetUpOnMainThread(); - CrosSettings* settings = CrosSettings::Get(); - CrosSettingsProvider* device_settings_provider = - settings->GetProvider(kDeviceOwner); - device_settings_provider_ = - settings->RemoveSettingsProvider(device_settings_provider); - settings->AddSettingsProvider(std::move(stub_settings_provider_)); - - // Notify ChromeUserManager of ownership change. - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, - content::Source<AccountsOptionsTest>(this), - content::NotificationService::NoDetails()); - } - - void TearDownOnMainThread() override { - CrosSettings* settings = CrosSettings::Get(); - stub_settings_provider_ = - settings->RemoveSettingsProvider(stub_settings_provider_ptr_); - settings->AddSettingsProvider(std::move(device_settings_provider_)); - LoginManagerTest::TearDownOnMainThread(); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - LoginManagerTest::SetUpCommandLine(command_line); - } - - protected: - void CheckAccountsUI(const user_manager::User* user, bool is_owner) { - Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user); - - ui_test_utils::BrowserAddedObserver observer; - Browser* browser = CreateBrowser(profile); - observer.WaitForSingleNewBrowser(); - - ui_test_utils::NavigateToURL(browser, - GURL("chrome://settings-frame/accounts")); - content::WebContents* contents = - browser->tab_strip_model()->GetActiveWebContents(); - - bool warning_visible; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - "var e = document.getElementById('ownerOnlyWarning');" - "var visible = e.offsetWidth > 0 && e.offsetHeight > 0;" - "window.domAutomationController.send(visible);", - &warning_visible)); - EXPECT_EQ(is_owner, !warning_visible); - - bool guest_option_enabled; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - "var e = document.getElementById('allowBwsiCheck');" - "window.domAutomationController.send(!e.disabled);", - &guest_option_enabled)); - EXPECT_EQ(is_owner, guest_option_enabled); - - bool supervised_users_enabled; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - "var e = document.getElementById('allowSupervisedCheck');" - "window.domAutomationController.send(!e.disabled);", - &supervised_users_enabled)); - ASSERT_EQ(is_owner, supervised_users_enabled); - - bool user_pods_enabled; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - "var e = document.getElementById('showUserNamesCheck');" - "window.domAutomationController.send(!e.disabled);", - &user_pods_enabled)); - EXPECT_EQ(is_owner, user_pods_enabled); - - bool whitelist_enabled; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - "var e = document.getElementById('useWhitelistCheck');" - "window.domAutomationController.send(!e.disabled);", - &whitelist_enabled)); - EXPECT_EQ(is_owner, whitelist_enabled); - } - - std::unique_ptr<CrosSettingsProvider> stub_settings_provider_; - StubCrosSettingsProvider* stub_settings_provider_ptr_; - std::unique_ptr<CrosSettingsProvider> device_settings_provider_; - std::vector<AccountId> test_users_; - - private: - DISALLOW_COPY_AND_ASSIGN(AccountsOptionsTest); -}; - -IN_PROC_BROWSER_TEST_F(AccountsOptionsTest, PRE_MultiProfilesAccountsOptions) { - RegisterUser(test_users_[0].GetUserEmail()); - RegisterUser(test_users_[1].GetUserEmail()); - StartupUtils::MarkOobeCompleted(); -} - -IN_PROC_BROWSER_TEST_F(AccountsOptionsTest, MultiProfilesAccountsOptions) { - LoginUser(test_users_[0].GetUserEmail()); - UserAddingScreen::Get()->Start(); - content::RunAllPendingInMessageLoop(); - AddUser(test_users_[1].GetUserEmail()); - - user_manager::UserManager* manager = user_manager::UserManager::Get(); - ASSERT_EQ(2u, manager->GetLoggedInUsers().size()); - - CheckAccountsUI(manager->FindUser(test_users_[0]), true /* is_owner */); - CheckAccountsUI(manager->FindUser(test_users_[1]), false /* is_owner */); -} - -} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js deleted file mode 100644 index 381aead5130..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js +++ /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. - -GEN_INCLUDE(['../options_browsertest_base.js']); - -function AccountsOptionsWebUITest() {} - -AccountsOptionsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to accounts options. - */ - browsePreload: 'chrome://settings-frame/accounts', -}; - -function createEnterKeyboardEvent(type) { - return new KeyboardEvent(type, { - 'bubbles': true, - 'cancelable': true, - 'key': 'Enter' - }); -} - -TEST_F('AccountsOptionsWebUITest', 'testNoCloseOnEnter', function() { - assertEquals(this.browsePreload, document.location.href); - - var inputField = $('userNameEdit'); - var accountsOptionsPage = AccountsOptions.getInstance(); - - // Overlay is visible. - assertTrue(accountsOptionsPage.visible); - - // Simulate pressing the enter key in the edit field. - inputField.dispatchEvent(createEnterKeyboardEvent('keydown')); - inputField.dispatchEvent(createEnterKeyboardEvent('keypress')); - inputField.dispatchEvent(createEnterKeyboardEvent('keyup')); - - // Verify the overlay is still visible. - assertTrue(accountsOptionsPage.visible); -}); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js deleted file mode 100644 index 38e4c9bc063..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js +++ /dev/null @@ -1,440 +0,0 @@ -// Copyright (c) 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. - -GEN('#if defined(OS_CHROMEOS)'); - -GEN_INCLUDE(['../options_browsertest_base.js']); - -function BluetoothWebUITestAsync() {} - -BluetoothWebUITestAsync.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - isAsync: true, - - /** - * Start tests from the main-settings page. - */ - browsePreload: 'chrome://settings-frame/', - - // These entries match the fake entries in FakeBluetoothDeviceClient. - fakePairedDevice: { - address: '00:11:22:33:44:55', - connectable: true, - connected: false, - name: 'Fake Device (name)', - paired: true - }, - - fakePairedDevice2: { - address: '20:7D:74:00:00:04', - connectable: false, - connected: false, - name: 'Paired Unconnectable Device (name)', - paired: true - }, - - fakeUnpairedDevice: { - address: '28:CF:DA:00:00:00', - connectable: true, - connected: false, - name: 'Bluetooth 2.0 Mouse', - paired: false - }, - - fakeUnpairedDevice2: { - address: '00:24:BE:00:00:00', - connectable: true, - connected: false, - name: 'PIN Device', - paired: false - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - var unsupportedAriaAttributeSelectors = [ - '#bluetooth-paired-devices-list', - '#bluetooth-unpaired-devices-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/570564 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - unsupportedAriaAttributeSelectors); - }, - - /** - * Retrieves the list item associated with a Bluetooth device. - * @param {!Element} listElement Element containing a list of devices. - * @param {string} deviceName The name of the device. - * @return {Element|undefined} List item matching the device name. - */ - getElementForDevice: function(listElement, deviceName) { - var items = listElement.querySelectorAll('.bluetooth-device'); - for (var i = 0; i < items.length; i++) { - var candidate = items[i]; - var name = candidate.data.name; - if (name == deviceName) - return candidate; - } - return undefined; - }, - - /** - * Selects a bluetooth device from the list with the matching address. - * @param {!Element} listElement A list of Bluetooth devices. - * @param {string} address Device address. - */ - selectDevice: function(listElement, address) { - listElement.setSelectedDevice_(address); - cr.dispatchSimpleEvent(listElement, 'change'); - }, - - /** - * Fake input of a pincode or passkey. - * @param {!Element} element Text input field. - * @param {string} text New value for the input field. - */ - fakeInput: function(element, text) { - element.value = text; - cr.dispatchSimpleEvent(element, 'input'); - }, -}; - -TEST_F('BluetoothWebUITestAsync', 'testEnableBluetooth', function() { - assertEquals(this.browsePreload, document.location.href); - expectFalse($('enable-bluetooth').checked); - expectTrue($('bluetooth-paired-devices-list').parentNode.hidden); - - $('enable-bluetooth').click(); - - // The UI may not be updated until all callbacks have been handled, so - // send a new request that will get processed after any currently pending - // callbacks. - chrome.bluetooth.getAdapterState(function(state) { - expectTrue(state.powered); - expectFalse($('bluetooth-paired-devices-list').parentNode.hidden); - testDone(); - }.bind(this)); -}); - -// TODO(crbug.com/603499) Test is flaky. -TEST_F('BluetoothWebUITestAsync', 'DISABLED_testAddDevice', function() { - assertEquals(this.browsePreload, document.location.href); - - // Enable bluetooth. - $('enable-bluetooth').click(); - - // Wait for the UI to process any pending messages. - window.setTimeout(function() { - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - var pairedDeviceList = $('bluetooth-paired-devices-list'); - var unpairedDeviceList = $('bluetooth-unpaired-devices-list'); - - // Verify that devices are in the correct list. - var index = pairedDeviceList.find(this.fakePairedDevice.address); - expectEquals(1, index); - index = pairedDeviceList.find(this.fakePairedDevice2.address); - expectEquals(0, index); - index = pairedDeviceList.find(this.fakeUnpairedDevice.address); - expectEquals(undefined, index); - expectTrue(!!this.getElementForDevice(pairedDeviceList, - this.fakePairedDevice.name)); - expectFalse(!!this.getElementForDevice(unpairedDeviceList, - this.fakePairedDevice.name)); - - // Test clicking on the 'Add a device' button. This should send a - // startDiscovering request. - $('bluetooth-add-device').click(); - expectFalse($('bluetooth-options').hidden); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - expectTrue(state.discovering); - expectFalse(unpairedDeviceList.parentNode.hidden); - - index = unpairedDeviceList.find(this.fakeUnpairedDevice.address); - expectEquals(0, index); - - var connectButton = $('bluetooth-add-device-apply-button'); - expectTrue(connectButton.disabled); - expectFalse($('bluetooth-add-device-cancel-button').disabled); - - // Test selecting an element and clicking on the connect button. - this.selectDevice(unpairedDeviceList, this.fakeUnpairedDevice.address); - expectFalse(connectButton.disabled); - connectButton.click(); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - // Verify that the pairing UI is shown. - expectFalse($('bluetooth-pairing').hidden); - testDone(); - }.bind(this)); - }.bind(this)); - }.bind(this)); - }.bind(this)); -}); - -TEST_F('BluetoothWebUITestAsync', 'testDevicePairing', function() { - assertEquals(this.browsePreload, document.location.href); - - // Enable bluetooth. - $('enable-bluetooth').click(); - - // Wait for the UI to process any pending messages. - window.setTimeout(function() { - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - var pairedDeviceList = $('bluetooth-paired-devices-list'); - var unpairedDeviceList = $('bluetooth-unpaired-devices-list'); - - $('bluetooth-add-device').click(); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - expectFalse(unpairedDeviceList.parentNode.hidden); - - // Test selecting an element and clicking on the connect button. - var index = unpairedDeviceList.find(this.fakeUnpairedDevice2.address); - expectNotEquals(undefined, index); - this.selectDevice(unpairedDeviceList, this.fakeUnpairedDevice2.address); - var connectButton = $('bluetooth-add-device-apply-button'); - expectFalse(connectButton.disabled); - connectButton.click(); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - // Verify that the pairing UI is shown. - expectFalse($('bluetooth-pairing').hidden); - expectTrue($('bluetooth-pairing-passkey-display').hidden); - expectTrue($('bluetooth-pairing-passkey-entry').hidden); - expectFalse($('bluetooth-pairing-pincode-entry').hidden); - - var pincode = '123456'; - this.fakeInput($('bluetooth-pincode'), pincode); - $('bluetooth-pair-device-connect-button').click(); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - expectTrue($('bluetooth-pairing-pincode-entry').hidden); - testDone(); - }.bind(this)); - }.bind(this)); - }.bind(this)); - }.bind(this)); - }.bind(this)); -}); - -// TODO(crbug.com/608126) Test is flaky. -TEST_F('BluetoothWebUITestAsync', 'DISABLED_testConnect', function() { - assertEquals(this.browsePreload, document.location.href); - - // Enable bluetooth. - $('enable-bluetooth').click(); - - // Wait for the UI to process any pending messages. - window.setTimeout(function() { - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - var pairedDeviceList = $('bluetooth-paired-devices-list'); - var element = this.getElementForDevice( - pairedDeviceList, this.fakePairedDevice.name); - assertTrue(!!element, this.fakePairedDevice.name); - expectFalse(!!element.getAttribute('connected')); - - var connectButton = $('bluetooth-reconnect-device'); - expectTrue(connectButton.disabled); - - // Simulate connecting to a previously paired device. - this.selectDevice(pairedDeviceList, this.fakePairedDevice.address); - expectFalse(connectButton.disabled); - connectButton.click(); - - // Call bluetooth.getAdapterState to ensure that all state has been - // updated. - chrome.bluetooth.getAdapterState(function(state) { - element = this.getElementForDevice( - pairedDeviceList, this.fakePairedDevice.name); - expectTrue(!!element.getAttribute('connected')); - var deleteButton = element.querySelector('.row-delete-button'); - expectTrue(!!deleteButton); - testDone(); - }.bind(this)); - }.bind(this)); - }.bind(this)); -}); - -TEST_F('BluetoothWebUITestAsync', 'testDisconnect', function() { - assertEquals(this.browsePreload, document.location.href); - - // Enable bluetooth. - $('enable-bluetooth').click(); - - // Wait for the UI to process any pending messages. - window.setTimeout(function() { - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - var pairedDeviceList = $('bluetooth-paired-devices-list'); - - // First connect to the device so that the fake implementation state is - // connected. - chrome.bluetoothPrivate.connect( - this.fakePairedDevice.address, function(result) { - assertEquals( - chrome.bluetoothPrivate.ConnectResultType.SUCCESS, result); - - var element = this.getElementForDevice( - pairedDeviceList, this.fakePairedDevice.name); - assertTrue(!!element, this.fakePairedDevice.name); - expectTrue(!!element.getAttribute('connected')); - - // Simulate disconnecting from a connected device. - var button = element.querySelector('.row-delete-button'); - button.click(); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - element = this.getElementForDevice( - pairedDeviceList, this.fakePairedDevice.name); - expectFalse(!!element.getAttribute('connected')); - button = element.querySelector('.row-delete-button'); - expectTrue(!!button); - testDone(); - }.bind(this)); - }.bind(this)); - }.bind(this)); - }.bind(this)); -}); - -// TODO(crbug.com/605090): Disabled because of flakiness. -TEST_F('BluetoothWebUITestAsync', 'DISABLED_testForget', function() { - assertEquals(this.browsePreload, document.location.href); - - // Enable bluetooth. - $('enable-bluetooth').click(); - - // Wait for the UI to process any pending messages. - window.setTimeout(function() { - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - var pairedDeviceList = $('bluetooth-paired-devices-list'); - - var element = this.getElementForDevice(pairedDeviceList, - this.fakePairedDevice.name); - var button = element.querySelector('.row-delete-button'); - button.click(); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - expectFalse(!!this.getElementForDevice(pairedDeviceList, - this.fakePairedDevice.name)); - testDone(); - }.bind(this)); - }.bind(this)); - }.bind(this)); -}); - - -TEST_F('BluetoothWebUITestAsync', 'testMaliciousInput', function() { - assertEquals(this.browsePreload, document.location.href); - - var maliciousStrings = [ - '<SCRIPT>alert(1)</SCRIPT>', - '>\'>\\"><SCRIPT>alert(1)</SCRIPT>', - '<IMG SRC=\\"javascript:alert(1)\\">', - '<A HREF=\\"data:text/html;base64,' + - 'PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo=\\">..</A>', - '<div>', - '<textarea>', - '<style>', - '[0xC0][0xBC]SCRIPT[0xC0][0xBE]alert(1)[0xC0][0xBC]/SCRIPT[0xC0][0xBE]', - '+ADw-SCRIPT+AD4-alert(1)+ADw-/SCRIPT+AD4-', - '&#<script>alert(1)</script>;', - '<!-- Hello -- world > <SCRIPT>alert(1)</SCRIPT> -->', - '<!<!-- Hello world > <SCRIPT>alert(1)</SCRIPT> -->', - '\x3CSCRIPT\x3Ealert(1)\x3C/SCRIPT\x3E', - '<IMG SRC=\\"j[0x00]avascript:alert(1)\\">', - '<BASE HREF=\\"javascript:1;/**/\\"><IMG SRC=\\"alert(1)\\">', - 'javascript:alert(1);', - ' xss_injection=\\"\\" ', - '\\" xss_injection=\\"', - '\' xss_injection=\'', - '<!--', - '\'', - '\\"' - ]; - - var fakeEvent = { - device: { - address: '28:CF:DA:00:00:00', - connectable: true, - connected: false, - name: 'Bluetooth 2.0 Mouse', - paired: false - }, - pairing: 'bluetoothStartConnecting' - }; - - var nodeCount = function(node) { - if (node.getAttribute) - assertFalse(!!node.getAttribute('xss_injection')); - var length = node.childNodes.length; - var tally = length; - for (var i = 0; i < length; i++) { - tally += nodeCount(node.childNodes[i]); - } - return tally; - }; - - // Enable bluetooth. - $('enable-bluetooth').click(); - - // Wait for the UI to process any pending messages. - window.setTimeout(function() { - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - var unpairedDeviceList = $('bluetooth-unpaired-devices-list'); - var pairDeviceDialog = $('bluetooth-pairing'); - - // Show the pairing dialog. - $('bluetooth-add-device').click(); - BluetoothPairing.showDialog(fakeEvent); - - // Wait for fake bluetooth impl to send any updates. - chrome.bluetooth.getAdapterState(function(state) { - expectFalse(unpairedDeviceList.parentNode.hidden); - - // Determine the expected sizes. - var unpairedDeviceListSize = nodeCount(unpairedDeviceList); - var pairDeviceDialogSize = nodeCount(pairDeviceDialog); - - // Ensure that updating the device with a malicious name does not - // corrupt the structure of the document. Tests the unpaired device - // list and bluetooth pairing dialog. - for (var i = 0; i < maliciousStrings.length; i++) { - fakeEvent.device.name = maliciousStrings[i]; - BluetoothPairing.showDialog(fakeEvent); - assertEquals(unpairedDeviceListSize, nodeCount(unpairedDeviceList)); - var element = this.getElementForDevice( - unpairedDeviceList, fakeEvent.device.name); - assertTrue(!!element, fakeEvent.device.name); - var label = element.querySelector('.bluetooth-device-label'); - assertTrue(!!label); - assertEquals(maliciousStrings[i], label.textContent); - assertEquals(pairDeviceDialogSize, nodeCount(pairDeviceDialog)); - } - - testDone(); - }.bind(this)); - }.bind(this)); - }.bind(this)); -}); - -GEN('#endif'); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc index e5661d299db..bd265d2e10a 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc @@ -163,24 +163,10 @@ void ChangePictureOptionsHandler::RegisterMessages() { } void ChangePictureOptionsHandler::SendDefaultImages() { - base::ListValue image_urls; - for (int i = default_user_image::kFirstDefaultImageIndex; - i < default_user_image::kDefaultImagesCount; ++i) { - std::unique_ptr<base::DictionaryValue> image_data( - new base::DictionaryValue); - image_data->SetString("url", default_user_image::GetDefaultImageUrl(i)); - image_data->SetString("author", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageAuthorIDs[i])); - image_data->SetString("website", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageWebsiteIDs[i])); - image_data->SetString("title", - default_user_image::GetDefaultImageDescription(i)); - image_urls.Append(std::move(image_data)); - } + std::unique_ptr<base::ListValue> image_urls = + default_user_image::GetAsDictionary(false /* all */); web_ui()->CallJavascriptFunctionUnsafe( - "ChangePictureOptions.setDefaultImages", image_urls); + "ChangePictureOptions.setDefaultImages", *image_urls); } void ChangePictureOptionsHandler::HandleChooseFile( @@ -280,10 +266,7 @@ void ChangePictureOptionsHandler::SendSelectedImage() { break; } default: { - DCHECK(previous_image_index_ >= 0 && - previous_image_index_ < default_user_image::kDefaultImagesCount); - if (previous_image_index_ >= - default_user_image::kFirstDefaultImageIndex) { + if (default_user_image::IsInCurrentImageSet(previous_image_index_)) { // User has image from the current set of default images. base::Value image_url( default_user_image::GetDefaultImageUrl(previous_image_index_)); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc index 1c938f22190..8811f6ac820 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc @@ -17,7 +17,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/lifetime/application_lifetime.h" @@ -27,7 +26,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" -#include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "components/user_manager/user_manager.h" @@ -40,6 +38,7 @@ #include "ui/base/ime/chromeos/component_extension_ime_manager.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/l10n/l10n_util.h" using base::UserMetricsAction; diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler_unittest.cc b/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler_unittest.cc deleted file mode 100644 index 74dbe665a63..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler_unittest.cc +++ /dev/null @@ -1,92 +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 "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" - -#include <memory> - -#include "base/values.h" -#include "chrome/browser/chromeos/input_method/input_method_configuration.h" -#include "chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { -namespace options { - -class CrosLanguageOptionsHandlerTest : public testing::Test { - public: - CrosLanguageOptionsHandlerTest() - : input_manager_(new MockInputMethodManagerWithInputMethods) { - chromeos::input_method::InitializeForTesting(input_manager_); - } - - ~CrosLanguageOptionsHandlerTest() override { - chromeos::input_method::Shutdown(); - } - - // testing::Test: - void SetUp() override { - input_manager_->AddInputMethod("xkb:us::eng", "us", "en-US"); - input_manager_->AddInputMethod("xkb:fr::fra", "fr", "fr"); - input_manager_->AddInputMethod("xkb:be::fra", "be", "fr"); - input_manager_->AddInputMethod("xkb:is::ice", "is", "is"); - } - - private: - MockInputMethodManagerWithInputMethods* input_manager_; -}; - -TEST_F(CrosLanguageOptionsHandlerTest, GetInputMethodList) { - std::unique_ptr<base::ListValue> list( - CrosLanguageOptionsHandler::GetInputMethodList()); - ASSERT_EQ(4U, list->GetSize()); - - base::DictionaryValue* entry = NULL; - base::DictionaryValue *language_code_set = NULL; - std::string input_method_id; - std::string display_name; - std::string language_code; - - // As shown below, the list should be input method ids should appear in - // the same order of the descriptors. - ASSERT_TRUE(list->GetDictionary(0, &entry)); - ASSERT_TRUE(entry->GetString("id", &input_method_id)); - ASSERT_TRUE(entry->GetString("displayName", &display_name)); - ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); - EXPECT_EQ("xkb:us::eng", input_method_id); - // Commented out as it depends on translation in generated_resources.grd - // (i.e. makes the test fragile). - // EXPECT_EQ("English (USA) keyboard layout", display_name); - ASSERT_TRUE(language_code_set->HasKey("en-US")); - - ASSERT_TRUE(list->GetDictionary(1, &entry)); - ASSERT_TRUE(entry->GetString("id", &input_method_id)); - ASSERT_TRUE(entry->GetString("displayName", &display_name)); - ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); - EXPECT_EQ("xkb:fr::fra", input_method_id); - // Commented out. See above. - // EXPECT_EQ("French keyboard layout", display_name); - ASSERT_TRUE(language_code_set->HasKey("fr")); - - ASSERT_TRUE(list->GetDictionary(2, &entry)); - ASSERT_TRUE(entry->GetString("id", &input_method_id)); - ASSERT_TRUE(entry->GetString("displayName", &display_name)); - ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); - EXPECT_EQ("xkb:be::fra", input_method_id); - // Commented out. See above. - // EXPECT_EQ("Belgian keyboard layout", display_name); - ASSERT_TRUE(language_code_set->HasKey("fr")); - - ASSERT_TRUE(list->GetDictionary(3, &entry)); - ASSERT_TRUE(entry->GetString("id", &input_method_id)); - ASSERT_TRUE(entry->GetString("displayName", &display_name)); - ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); - EXPECT_EQ("xkb:is::ice", input_method_id); - // Commented out. See above. - // EXPECT_EQ("Japanese input method (for US keyboard)", display_name); - ASSERT_TRUE(language_code_set->HasKey("is")); -} - -} // namespace options -} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js deleted file mode 100644 index 4f0845beb37..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/date_time_options_browsertest.js +++ /dev/null @@ -1,38 +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. - -GEN_INCLUDE(['../options_browsertest_base.js']); - -GEN('#if defined(OS_CHROMEOS)'); - -/** - * DateTimeOptionsWebUITest tests the date and time section of the options page. - * @constructor - * @extends {testing.Test} - */ -function DateTimeOptionsWebUITest() {} - -DateTimeOptionsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to date/time options. - * @override - */ - browsePreload: 'chrome://settings-frame/search#date', -}; - -TEST_F('DateTimeOptionsWebUITest', 'testShowSetTimeButton', function() { - assertEquals(this.browsePreload, document.location.href); - - // Show button. - BrowserOptions.setCanSetTime(true); - expectFalse($('set-time').hidden); - - // Hide button. - BrowserOptions.setCanSetTime(false); - expectTrue($('set-time').hidden); -}); - -GEN('#endif'); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.cc b/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.cc deleted file mode 100644 index d2bdaa8dec6..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.cc +++ /dev/null @@ -1,28 +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 "chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.h" - -#include "base/command_line.h" -#include "chrome/browser/ui/webui/options/options_ui_browsertest.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/test/base/testing_profile.h" -#include "chromeos/chromeos_switches.h" -#include "components/signin/core/account_id/account_id.h" -#include "components/user_manager/user_names.h" - -GuestModeOptionsUIBrowserTest::GuestModeOptionsUIBrowserTest() {} - -GuestModeOptionsUIBrowserTest::~GuestModeOptionsUIBrowserTest() {} - -void GuestModeOptionsUIBrowserTest::SetUpCommandLine( - base::CommandLine* command_line) { - command_line->AppendSwitch(chromeos::switches::kGuestSession); - command_line->AppendSwitchASCII( - chromeos::switches::kLoginUser, - user_manager::GuestAccountId().GetUserEmail()); - command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, - TestingProfile::kTestUserProfileDir); - command_line->AppendSwitch(switches::kIncognito); -} diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.h b/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.h deleted file mode 100644 index 33ccde9a7cc..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.h +++ /dev/null @@ -1,27 +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 CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_GUEST_MODE_OPTIONS_BROWSERTEST_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_GUEST_MODE_OPTIONS_BROWSERTEST_H_ - -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/test/base/web_ui_browser_test.h" -#include "content/public/browser/web_ui_message_handler.h" - -// This is a helper class used by guest_mode_options_browsertest.js to enable -// guest mode. -class GuestModeOptionsUIBrowserTest : public WebUIBrowserTest { - public: - GuestModeOptionsUIBrowserTest(); - ~GuestModeOptionsUIBrowserTest() override; - - private: - void SetUpCommandLine(base::CommandLine* command_line) override; - - DISALLOW_COPY_AND_ASSIGN(GuestModeOptionsUIBrowserTest); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_GUEST_MODE_OPTIONS_BROWSERTEST_H_ diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.js deleted file mode 100644 index f4a0d0eb76c..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_browsertest.js +++ /dev/null @@ -1,80 +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. - -GEN_INCLUDE(['../options_browsertest_base.js']); -GEN('#include "chrome/browser/ui/webui/options/chromeos/' + - 'guest_mode_options_browsertest.h"'); - -/** - * TestFixture for guest mode options WebUI testing. - * @extends {OptionsBrowsertestBase} - * @constructor - */ -function GuestModeOptionsUIBrowserTest() {} - -GuestModeOptionsUIBrowserTest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame', - - /** @override */ - typedefCppFixture: 'GuestModeOptionsUIBrowserTest', - - /** - * Returns the element that sets a given preference, failing if no such - * element is found. - * @param {string} pref Name of the preference. - * @return {!HTMLElement} The element controlling the preference. - */ - getControlForPref: function(pref) { - var control = document.querySelector('[pref="' + pref + '"]'); - assertTrue(!!control); - return control; - }, - - /** @param {!HTMLElement} el */ - expectHidden: function(el) { - expectFalse(el.offsetHeight > 0 && el.offsetWidth > 0); - }, -}; - -/** Test sections that should be hidden in guest mode. */ -TEST_F('GuestModeOptionsUIBrowserTest', 'testSections', function() { - this.expectHidden($('startup-section')); - this.expectHidden($('appearance-section')); - this.expectHidden($('android-apps-section')); - this.expectHidden($('sync-users-section')); - this.expectHidden($('easy-unlock-section')); - this.expectHidden($('reset-profile-settings-section')); -}); - -/** Test controls that should be disabled in guest mode. */ -TEST_F('GuestModeOptionsUIBrowserTest', 'testControls', function() { - // Appearance section. - var setWallpaper = $('set-wallpaper'); - expectTrue(setWallpaper.disabled); - - // Passwords and autofill section. - expectTrue($('autofill-enabled').disabled); - - // Date and time section. - expectTrue($('timezone-value-select').disabled); - expectFalse($('resolve-timezone-by-geolocation').disabled); - expectFalse($('use-24hour-clock').disabled); - - // Privacy section. - expectTrue(this.getControlForPref('search.suggest_enabled').disabled); - expectTrue($('networkPredictionOptions').disabled); - - // Web content section. - expectTrue($('defaultZoomFactor').disabled); - - // Downloads section. - expectTrue(this.getControlForPref('gdata.disabled').disabled); - - // Content settings overlay. - expectTrue(this.getControlForPref('settings.privacy.drm_enabled').disabled); - expectTrue($('protected-content-exceptions').disabled); -}); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_ui_browsertest.cc deleted file mode 100644 index 3d7a39ccd1c..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/guest_mode_options_ui_browsertest.cc +++ /dev/null @@ -1,38 +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 "base/command_line.h" -#include "chrome/browser/ui/webui/options/options_ui_browsertest.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/test/base/testing_profile.h" -#include "chromeos/chromeos_switches.h" -#include "components/signin/core/account_id/account_id.h" -#include "components/user_manager/user_names.h" - -namespace { - -// Same as OptionsUIBrowserTest but launches with Guest mode command line -// switches. -class GuestModeOptionsBrowserTest : public options::OptionsUIBrowserTest { - public: - GuestModeOptionsBrowserTest() : OptionsUIBrowserTest() {} - - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(chromeos::switches::kGuestSession); - command_line->AppendSwitchASCII( - chromeos::switches::kLoginUser, - user_manager::GuestAccountId().GetUserEmail()); - command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, - TestingProfile::kTestUserProfileDir); - command_line->AppendSwitch(switches::kIncognito); - } -}; - -IN_PROC_BROWSER_TEST_F(GuestModeOptionsBrowserTest, LoadOptionsByURL) { - NavigateToSettings(); - VerifyTitle(); - VerifyNavbar(); -} - -} // namespace diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc index 9933d21f4bc..75dab74707b 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc @@ -183,7 +183,7 @@ const PrefService* InternetOptionsHandler::GetPrefs() const { void InternetOptionsHandler::AddVPNConnection(const base::ListValue* args) { if (args->empty()) { // Show the "add network" dialog for the built-in OpenVPN/L2TP provider. - NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow()); + NetworkConfigView::ShowForType(shill::kTypeVPN); return; } @@ -206,7 +206,7 @@ void InternetOptionsHandler::AddNonVPNConnection(const base::ListValue* args) { return; } if (onc_type == ::onc::network_type::kWiFi) { - NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow()); + NetworkConfigView::ShowForType(shill::kTypeWifi); } else if (onc_type == ::onc::network_type::kCellular) { ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); } else { @@ -246,7 +246,7 @@ void InternetOptionsHandler::ConfigureNetwork(const base::ListValue* args) { return; } - NetworkConfigView::ShowForNetworkId(guid, GetNativeWindow()); + NetworkConfigView::ShowForNetworkId(guid); } } // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc b/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc index 6a89972c128..accea7676a2 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.cc @@ -74,8 +74,9 @@ StringResource kStringResources[] = { {"OncCellular-RoamingStateHome", IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME}, {"OncCellular-RoamingStateRoaming", IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING}, - {"OncTypeCellular", IDS_NETWORK_TYPE_CELLULAR}, + {"OncTypeCellular", IDS_NETWORK_TYPE_MOBILE_DATA}, {"OncTypeEthernet", IDS_NETWORK_TYPE_ETHERNET}, + {"OncTypeTether", IDS_NETWORK_TYPE_MOBILE_DATA}, {"OncTypeWiFi", IDS_NETWORK_TYPE_WIFI}, {"OncTypeWimax", IDS_NETWORK_TYPE_WIMAX}, {"OncVPN-TypeL2TP-IPsecCert", diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc index 8d2c9a2c80e..e705e1f6748 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.cc @@ -84,6 +84,11 @@ void OptionsStylusHandler::OnAvailableNoteTakingAppsUpdated() { UpdateNoteTakingApps(); } +void OptionsStylusHandler::OnPreferredNoteTakingAppUpdated(Profile* profile) { + if (Profile::FromWebUI(web_ui()) == profile) + UpdateNoteTakingApps(); +} + void OptionsStylusHandler::OnDeviceListsComplete() { SendHasStylus(); } diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h b/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h index 6e729c69959..3a51832affe 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h +++ b/chromium/chrome/browser/ui/webui/options/chromeos/options_stylus_handler.h @@ -14,6 +14,8 @@ #include "chrome/browser/ui/webui/options/options_ui.h" #include "ui/events/devices/input_device_event_observer.h" +class Profile; + namespace base { class ListValue; } // namespace base @@ -36,6 +38,7 @@ class OptionsStylusHandler : public ::options::OptionsPageUIHandler, // NoteTakingHelper::Observer implementation. void OnAvailableNoteTakingAppsUpdated() override; + void OnPreferredNoteTakingAppUpdated(Profile* profile) override; // ui::InputDeviceEventObserver implementation: void OnDeviceListsComplete() override; diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/power_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/power_handler.cc index 8cd2cb22176..d5221833499 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/power_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/power_handler.cc @@ -6,7 +6,6 @@ #include <utility> -#include "ash/resources/grit/ash_resources.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/strings/string_number_conversions.h" diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/power_overlay_browsertest.js b/chromium/chrome/browser/ui/webui/options/chromeos/power_overlay_browsertest.js deleted file mode 100644 index d49131c5f80..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/power_overlay_browsertest.js +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2015 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. - -GEN_INCLUDE(['../options_browsertest_base.js']); - -function PowerOverlayWebUITest() {} - -PowerOverlayWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - browsePreload: 'chrome://settings-frame/', - - commandLineSwitches: [{ - switchName: 'enable-power-overlay', - }], - - /** @override */ - preLoad: function() { - this.makeAndRegisterMockHandler([ - 'updatePowerStatus', - 'setPowerSource', - ]); - this.mockHandler.expects(atLeastOnce()).updatePowerStatus(); - }, - - /** - * Sets power sources using a deep copy of |sources|. - * @param {Array<Object>} sources - * @param {string} sourceId - * @param {bool} isUsbCharger - * @param {bool} isCalculating - */ - setPowerSources: function(sources, sourceId, isUsbCharger, isCalculating) { - var sourcesCopy = sources.map(function(source) { - return Object.assign({}, source); - }); - options.PowerOverlay.setPowerSources( - sourcesCopy, sourceId, isUsbCharger, isCalculating); - }, - - /** - * Simulates the user selecting a power source, verifying that the overlay - * calls setPowerSource. - * @param {string} sourceId - */ - selectPowerSource: function(sourceId) { - this.mockHandler.expects(once()).setPowerSource(eq(sourceId)); - $('power-source-dropdown').value = sourceId; - expectTrue(cr.dispatchSimpleEvent($('power-source-dropdown'), 'change')); - }, - - /** - * Checks that the sources dropdown is visible. - * @param {string} sourceId The ID of the source that should be selected. - */ - checkSource: function(sourceId) { - expectTrue($('power-source-charger').hidden); - expectFalse($('power-sources').hidden); - expectEquals(sourceId, $('power-source-dropdown').value); - }, - - checkNoSources: function() { - expectTrue($('power-source-charger').hidden); - expectTrue($('power-sources').hidden); - }, - - checkDedicatedCharger: function() { - expectFalse($('power-source-charger').hidden); - expectTrue($('power-sources').hidden); - }, -}; - -TEST_F('PowerOverlayWebUITest', 'testNoPowerSources', function() { - assertEquals(this.browsePreload, document.location.href); - this.mockHandler.expects(never()).setPowerSource(); - $('power-settings-link').click(); - - // This should be the initial state. - this.checkNoSources(); - - // Setting an empty sources list shouldn't change the state. - this.setPowerSources([], '', false, false); - this.checkNoSources(); -}); - -TEST_F('PowerOverlayWebUITest', 'testDedicatedCharger', function() { - assertEquals(this.browsePreload, document.location.href); - this.mockHandler.expects(never()).setPowerSource(); - $('power-settings-link').click(); - - var fakeSources = [{ - id: 'source1', - description: 'Left port', - type: options.PowerStatusDeviceType.DEDICATED_CHARGER, - }]; - - this.setPowerSources(fakeSources, 'source1', false, false); - this.checkDedicatedCharger(); - - // Remove the charger. - this.setPowerSources([], ''); - this.checkNoSources(); - - // Set a low-powered charger. - this.setPowerSources(fakeSources, 'source1', true, false); - this.checkDedicatedCharger(); -}); - -TEST_F('PowerOverlayWebUITest', 'testSingleSource', function() { - assertEquals(this.browsePreload, document.location.href); - $('power-settings-link').click(); - - var fakeSources = [{ - id: 'source1', - description: 'Left port', - type: options.PowerStatusDeviceType.DUAL_ROLE_USB, - }]; - - this.setPowerSources(fakeSources, '', false, false); - this.checkSource(''); - - this.selectPowerSource('source1'); - this.checkSource('source1'); - - // Remove the device. - this.setPowerSources([], '', false, false); - this.checkNoSources(); -}); - -TEST_F('PowerOverlayWebUITest', 'testMultipleSources', function() { - assertEquals(this.browsePreload, document.location.href); - $('power-settings-link').click(); - - var fakeSources = [{ - id: 'source1', - description: 'Left port', - type: options.PowerStatusDeviceType.DUAL_ROLE_USB, - }, { - id: 'source2', - description: 'Right port', - type: options.PowerStatusDeviceType.DUAL_ROLE_USB, - }, { - id: 'source3', - description: 'Front port', - type: options.PowerStatusDeviceType.DUAL_ROLE_USB, - }, { - id: 'source4', - description: 'Rear port', - type: options.PowerStatusDeviceType.DUAL_ROLE_USB, - }]; - - // Use a dual-role device. - this.setPowerSources(fakeSources, 'source2', false, false); - this.checkSource('source2'); - - // Use a USB charger. - this.setPowerSources(fakeSources, 'source3', true, false); - this.checkSource('source3'); - - // Remove the currently used device. - fakeSources.splice(2, 1); - this.setPowerSources(fakeSources, 'source4', false, false); - this.checkSource('source4'); - - // Do not charge (use battery). - this.setPowerSources(fakeSources, '', false, false); - this.checkSource(''); - - // The user selects a device. - this.selectPowerSource('source1'); - - // The user selects the battery. - this.selectPowerSource(''); -}); diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc index 72c066e765e..6a6a7062d91 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/proxy_handler.cc @@ -13,7 +13,6 @@ #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/common/chrome_constants.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" #include "chromeos/chromeos_constants.h" #include "content/public/browser/web_ui.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc b/chromium/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc deleted file mode 100644 index 7e7b7fa708f..00000000000 --- a/chromium/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc +++ /dev/null @@ -1,467 +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 <stddef.h> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/strings/stringprintf.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/login_manager_test.h" -#include "chrome/browser/chromeos/login/startup_utils.h" -#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/ui_test_utils.h" -#include "chromeos/settings/cros_settings_names.h" -#if defined(GOOGLE_CHROME_BUILD) -#include "components/spellcheck/browser/pref_names.h" -#endif -#include "components/prefs/pref_service.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_utils.h" - -namespace chromeos { - -namespace { - -// Because policy is not needed in this test it is better to use e-mails that -// are definitely not enterprise. This lets us to avoid faking of policy fetch -// procedure. -const char* kTestOwner = "test-owner@gmail.com"; -const char* kTestNonOwner = "test-user1@gmail.com"; - -const char* kKnownSettings[] = { - kDeviceOwner, - kAccountsPrefAllowGuest, - kAccountsPrefAllowNewUser, - kAccountsPrefDeviceLocalAccounts, - kAccountsPrefShowUserNamesOnSignIn, - kAccountsPrefSupervisedUsersEnabled, -}; - -// Stub settings provider that only handles the settings we need to control. -// StubCrosSettingsProvider handles more settings but leaves many of them unset -// which the Settings page doesn't expect. -class StubAccountSettingsProvider : public StubCrosSettingsProvider { - public: - StubAccountSettingsProvider() { - } - - ~StubAccountSettingsProvider() override {} - - // StubCrosSettingsProvider implementation. - bool HandlesSetting(const std::string& path) const override { - const char** end = kKnownSettings + arraysize(kKnownSettings); - return std::find(kKnownSettings, end, path) != end; - } -}; - -struct PrefTest { - const char* pref_name; - bool owner_only; - bool indicator; -}; - -const PrefTest kPrefTests[] = { - { kSystemTimezone, false, false }, - { prefs::kUse24HourClock, false, false }, - { kAttestationForContentProtectionEnabled, true, true }, - { kAccountsPrefAllowGuest, true, false }, - { kAccountsPrefAllowNewUser, true, false }, - { kAccountsPrefShowUserNamesOnSignIn, true, false }, - { kAccountsPrefSupervisedUsersEnabled, true, false }, -#if defined(GOOGLE_CHROME_BUILD) - { kStatsReportingPref, true, true }, - { spellcheck::prefs::kSpellCheckUseSpellingService, false, false }, -#endif -}; - -} // namespace - -class SharedOptionsTest : public LoginManagerTest { - public: - SharedOptionsTest() - : LoginManagerTest(false), - stub_settings_provider_(base::MakeUnique<StubCrosSettingsProvider>()), - stub_settings_provider_ptr_(static_cast<StubCrosSettingsProvider*>( - stub_settings_provider_.get())), - test_owner_account_id_(AccountId::FromUserEmail(kTestOwner)), - test_non_owner_account_id_(AccountId::FromUserEmail(kTestNonOwner)) { - stub_settings_provider_->Set(kDeviceOwner, base::Value(kTestOwner)); - } - - ~SharedOptionsTest() override {} - - void SetUpOnMainThread() override { - LoginManagerTest::SetUpOnMainThread(); - - CrosSettings* settings = CrosSettings::Get(); - - // Add the stub settings provider, moving the device settings provider - // behind it so our stub takes precedence. - std::unique_ptr<CrosSettingsProvider> device_settings_provider = - settings->RemoveSettingsProvider(settings->GetProvider(kDeviceOwner)); - settings->AddSettingsProvider(std::move(stub_settings_provider_)); - settings->AddSettingsProvider(std::move(device_settings_provider)); - - // Notify ChromeUserManager of ownership change. - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, - content::Source<SharedOptionsTest>(this), - content::NotificationService::NoDetails()); - } - - void TearDownOnMainThread() override { - CrosSettings* settings = CrosSettings::Get(); - settings->RemoveSettingsProvider(stub_settings_provider_ptr_); - LoginManagerTest::TearDownOnMainThread(); - } - - protected: - void CheckOptionsUI(const user_manager::User* user, - bool is_owner, - bool is_primary) { - ASSERT_NE(nullptr, user); - Browser* browser = CreateBrowserForUser(user); - content::WebContents* contents = - browser->tab_strip_model()->GetActiveWebContents(); - - for (size_t i = 0; i < sizeof(kPrefTests) / sizeof(kPrefTests[0]); i++) { - bool disabled = !is_owner && kPrefTests[i].owner_only; - if (strcmp(kPrefTests[i].pref_name, kSystemTimezone) == 0) { - disabled = ProfileHelper::Get() - ->GetProfileByUser(user) - ->GetPrefs() - ->GetBoolean(prefs::kResolveTimezoneByGeolocation); - } - - CheckPreference( - contents, kPrefTests[i].pref_name, disabled, - !is_owner && kPrefTests[i].indicator ? "owner" : std::string()); - } - CheckBanner(contents, is_primary); - CheckSharedSections(contents, is_primary); - CheckAccountsOverlay(contents, is_owner); - } - - // Creates a browser and navigates to the Settings page. - Browser* CreateBrowserForUser(const user_manager::User* user) { - Profile* profile = ProfileHelper::Get()->GetProfileByUser(user); - SigninManagerFactory::GetForProfile(profile)->SetAuthenticatedAccountInfo( - GetGaiaIDForUserID(user->GetAccountId().GetUserEmail()), - user->GetAccountId().GetUserEmail()); - - ui_test_utils::BrowserAddedObserver observer; - Browser* browser = CreateBrowser(profile); - observer.WaitForSingleNewBrowser(); - - ui_test_utils::NavigateToURL(browser, - GURL("chrome://settings-frame")); - return browser; - } - - // Verifies a preference's disabled state and controlled-by indicator. - void CheckPreference(content::WebContents* contents, - std::string pref_name, - bool disabled, - std::string controlled_by) { - bool success; - std::string js_expression = base::StringPrintf( - "var prefSelector = '[pref=\"%s\"]';" - "var controlledBy = '%s';" - "var input = document.querySelector(" - " 'input' + prefSelector + ', select' + prefSelector);" - "var success = false;" - "if (input) {" - " success = input.disabled == %d;" - " var indicator = input.parentNode.parentNode.querySelector(" - " '.controlled-setting-indicator');" - " if (controlledBy) {" - " success = success && indicator &&" - " indicator.getAttribute('controlled-by') == controlledBy;" - " } else {" - " success = success && (!indicator ||" - " !indicator.hasAttribute('controlled-by') ||" - " indicator.getAttribute('controlled-by') == '')" - " }" - "}" - "window.domAutomationController.send(!!success);", - pref_name.c_str(), controlled_by.c_str(), disabled); - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, js_expression, &success)); - EXPECT_TRUE(success); - } - - // Verifies a checkbox's disabled state, controlled-by indicator and value. - void CheckBooleanPreference(content::WebContents* contents, - std::string pref_name, - bool disabled, - std::string controlled_by, - bool expected_value) { - CheckPreference(contents, pref_name, disabled, controlled_by); - bool actual_value; - std::string js_expression = base::StringPrintf( - "window.domAutomationController.send(document.querySelector('" - " input[type=\"checkbox\"][pref=\"%s\"]').checked);", - pref_name.c_str()); - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, js_expression, &actual_value)); - EXPECT_EQ(expected_value, actual_value); - } - - // Verifies that the shared settings banner is visible only for - // secondary users. - void CheckBanner(content::WebContents* contents, - bool is_primary) { - bool banner_visible; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, - "var e = $('secondary-user-banner');" - "window.domAutomationController.send(e && !e.hidden);", - &banner_visible)); - EXPECT_EQ(!is_primary, banner_visible); - } - - // Verifies that sections of shared settings have the appropriate indicator. - void CheckSharedSections(content::WebContents* contents, - bool is_primary) { - // This only applies to the Internet options section. - std::string controlled_by; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - contents, - "var e = document.querySelector(" - " '#network-section-header span.controlled-setting-indicator');" - "if (!e || !e.getAttribute('controlled-by')) {" - " window.domAutomationController.send('');" - "} else {" - " window.domAutomationController.send(" - " e.getAttribute('controlled-by'));" - "}", - &controlled_by)); - EXPECT_EQ(!is_primary ? "shared" : std::string(), controlled_by); - } - - // Checks the Accounts header and non-checkbox inputs. - void CheckAccountsOverlay(content::WebContents* contents, bool is_owner) { - // Set cros.accounts.allowGuest to false so we can test the accounts list. - // This has to be done after the PRE_* test or we can't add the owner. - stub_settings_provider_ptr_->Set(kAccountsPrefAllowNewUser, - base::Value(false)); - - bool success; - std::string js_expression = base::StringPrintf( - "var controlled = %d;" - "var warning = $('ownerOnlyWarning');" - "var userList = $('userList');" - "var input = $('userNameEdit');" - "var success;" - "if (controlled)" - " success = warning && !warning.hidden && userList.disabled &&" - " input.disabled;" - "else" - " success = (!warning || warning.hidden) && !userList.disabled &&" - " !input.disabled;" - "window.domAutomationController.send(!!success);", - !is_owner); - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - contents, js_expression, &success)); - EXPECT_TRUE(success) << "Accounts overlay incorrect for " << - (is_owner ? "owner." : "non-owner."); - } - - std::unique_ptr<CrosSettingsProvider> stub_settings_provider_; - StubCrosSettingsProvider* stub_settings_provider_ptr_; - - const AccountId test_owner_account_id_; - const AccountId test_non_owner_account_id_; - - private: - DISALLOW_COPY_AND_ASSIGN(SharedOptionsTest); -}; - -IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_SharedOptions) { - RegisterUser(test_owner_account_id_.GetUserEmail()); - RegisterUser(test_non_owner_account_id_.GetUserEmail()); - StartupUtils::MarkOobeCompleted(); -} - -IN_PROC_BROWSER_TEST_F(SharedOptionsTest, SharedOptions) { - // Log in the owner first, then add a secondary user. - LoginUser(test_owner_account_id_.GetUserEmail()); - UserAddingScreen::Get()->Start(); - content::RunAllPendingInMessageLoop(); - AddUser(test_non_owner_account_id_.GetUserEmail()); - - user_manager::UserManager* manager = user_manager::UserManager::Get(); - ASSERT_EQ(2u, manager->GetLoggedInUsers().size()); - { - SCOPED_TRACE("Checking settings for owner, primary user."); - CheckOptionsUI(manager->FindUser(manager->GetOwnerAccountId()), true, true); - } - { - SCOPED_TRACE("Checking settings for non-owner, secondary user."); - CheckOptionsUI(manager->FindUser(test_non_owner_account_id_), false, false); - } - // TODO(michaelpg): Add tests for non-primary owner and primary non-owner - // when the owner-only multiprofile restriction is removed, probably M38. -} - -IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferencePrimary) { - RegisterUser(test_owner_account_id_.GetUserEmail()); - RegisterUser(test_non_owner_account_id_.GetUserEmail()); - StartupUtils::MarkOobeCompleted(); -} - -// Tests the shared setting indicator for the primary user's auto-lock setting -// when the secondary user has enabled or disabled their preference. -// (The checkbox is unset if the current user's preference is false, but if any -// other signed-in user has enabled this preference, the shared setting -// indicator explains this.) -IN_PROC_BROWSER_TEST_F(SharedOptionsTest, ScreenLockPreferencePrimary) { - LoginUser(test_owner_account_id_.GetUserEmail()); - UserAddingScreen::Get()->Start(); - content::RunAllPendingInMessageLoop(); - AddUser(test_non_owner_account_id_.GetUserEmail()); - - user_manager::UserManager* manager = user_manager::UserManager::Get(); - const user_manager::User* user1 = manager->FindUser(test_owner_account_id_); - const user_manager::User* user2 = - manager->FindUser(test_non_owner_account_id_); - - PrefService* prefs1 = - ProfileHelper::Get()->GetProfileByUser(user1)->GetPrefs(); - PrefService* prefs2 = - ProfileHelper::Get()->GetProfileByUser(user2)->GetPrefs(); - - // Set both users' preference to false, then change the secondary user's to - // true. We'll do the opposite in the next test. Doesn't provide 100% coverage - // but reloading the settings page is super slow on debug builds. - prefs1->SetBoolean(prefs::kEnableAutoScreenLock, false); - prefs2->SetBoolean(prefs::kEnableAutoScreenLock, false); - - Browser* browser = CreateBrowserForUser(user1); - content::WebContents* contents = - browser->tab_strip_model()->GetActiveWebContents(); - - bool disabled = false; - bool expected_value; - std::string empty_controlled; - std::string shared_controlled("shared"); - - { - SCOPED_TRACE("Screen lock false for both users"); - expected_value = false; - CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled, - empty_controlled, expected_value); - } - - // Set the secondary user's preference to true, and reload the primary user's - // browser to see the updated controlled-by indicator. - prefs2->SetBoolean(prefs::kEnableAutoScreenLock, true); - chrome::Reload(browser, WindowOpenDisposition::CURRENT_TAB); - content::WaitForLoadStop(contents); - { - SCOPED_TRACE("Screen lock false for primary user"); - expected_value = false; - CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled, - shared_controlled, expected_value); - } - - // Set the preference to true for the primary user and check that the - // indicator disappears. - prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true); - { - SCOPED_TRACE("Screen lock true for both users"); - expected_value = true; - CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled, - empty_controlled, expected_value); - } -} - -IN_PROC_BROWSER_TEST_F(SharedOptionsTest, PRE_ScreenLockPreferenceSecondary) { - RegisterUser(test_owner_account_id_.GetUserEmail()); - RegisterUser(test_non_owner_account_id_.GetUserEmail()); - StartupUtils::MarkOobeCompleted(); -} - -// Tests the shared setting indicator for the secondary user's auto-lock setting -// when the primary user has enabled or disabled their preference. -// (The checkbox is unset if the current user's preference is false, but if any -// other signed-in user has enabled this preference, the shared setting -// indicator explains this.) -IN_PROC_BROWSER_TEST_F(SharedOptionsTest, ScreenLockPreferenceSecondary) { - LoginUser(test_owner_account_id_.GetUserEmail()); - UserAddingScreen::Get()->Start(); - content::RunAllPendingInMessageLoop(); - AddUser(test_non_owner_account_id_.GetUserEmail()); - - user_manager::UserManager* manager = user_manager::UserManager::Get(); - const user_manager::User* user1 = manager->FindUser(test_owner_account_id_); - const user_manager::User* user2 = - manager->FindUser(test_non_owner_account_id_); - - PrefService* prefs1 = - ProfileHelper::Get()->GetProfileByUser(user1)->GetPrefs(); - PrefService* prefs2 = - ProfileHelper::Get()->GetProfileByUser(user2)->GetPrefs(); - - // Set both users' preference to true, then change the secondary user's to - // false. - prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true); - prefs2->SetBoolean(prefs::kEnableAutoScreenLock, true); - - Browser* browser = CreateBrowserForUser(user2); - content::WebContents* contents = - browser->tab_strip_model()->GetActiveWebContents(); - - bool disabled = false; - bool expected_value; - std::string empty_controlled; - std::string shared_controlled("shared"); - - { - SCOPED_TRACE("Screen lock true for both users"); - expected_value = true; - CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled, - empty_controlled, expected_value); - } - - // Set the secondary user's preference to false and check that the - // controlled-by indicator is shown. - prefs2->SetBoolean(prefs::kEnableAutoScreenLock, false); - { - SCOPED_TRACE("Screen lock false for secondary user"); - expected_value = false; - CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled, - shared_controlled, expected_value); - } - - // Set the preference to false for the primary user and check that the - // indicator disappears. - prefs1->SetBoolean(prefs::kEnableAutoScreenLock, false); - chrome::Reload(browser, WindowOpenDisposition::CURRENT_TAB); - content::WaitForLoadStop(contents); - { - SCOPED_TRACE("Screen lock false for both users"); - expected_value = false; - CheckBooleanPreference(contents, prefs::kEnableAutoScreenLock, disabled, - empty_controlled, expected_value); - } -} - -} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc b/chromium/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc index c6e0c9f4d74..d5d1da4f2bb 100644 --- a/chromium/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc @@ -191,7 +191,10 @@ void StorageManagerHandler::HandleOpenDownloads( void StorageManagerHandler::HandleOpenArcStorage( const base::ListValue* unused_args) { - arc::ArcStorageManager::Get()->OpenPrivateVolumeSettings(); + auto* arc_storage_manager = arc::ArcStorageManager::GetForBrowserContext( + Profile::FromWebUI(web_ui())); + if (arc_storage_manager) + arc_storage_manager->OpenPrivateVolumeSettings(); } void StorageManagerHandler::HandleClearDriveCache( @@ -418,9 +421,13 @@ void StorageManagerHandler::UpdateArcSize() { // Shows the item "Android apps and cache" and start calculating size. web_ui()->CallJavascriptFunctionUnsafe( "options.StorageManager.showArcItem"); - bool success = arc::ArcStorageManager::Get()->GetApplicationsSize( - base::Bind(&StorageManagerHandler::OnGetArcSize, - weak_ptr_factory_.GetWeakPtr())); + bool success = false; + auto* arc_storage_manager = + arc::ArcStorageManager::GetForBrowserContext(profile); + if (arc_storage_manager) { + success = arc_storage_manager->GetApplicationsSize(base::Bind( + &StorageManagerHandler::OnGetArcSize, weak_ptr_factory_.GetWeakPtr())); + } if (!success) updating_arc_size_ = false; } diff --git a/chromium/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc b/chromium/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc deleted file mode 100644 index 78063231dd4..00000000000 --- a/chromium/chrome/browser/ui/webui/options/clear_browser_data_browsertest.cc +++ /dev/null @@ -1,115 +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 <stddef.h> - -#include "base/macros.h" -#include "build/build_config.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/webui/options/options_ui_browsertest.h" -#include "chrome/common/url_constants.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/browsing_data_remover.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/browsing_data_remover_test_util.h" - -namespace options { - -class ClearBrowserDataBrowserTest : public OptionsUIBrowserTest { - protected: - void ClickElement(const std::string& selector) { - bool element_enabled = false; - ASSERT_NO_FATAL_FAILURE(GetElementEnabledState(selector, &element_enabled)); - ASSERT_TRUE(element_enabled); - ASSERT_TRUE(content::ExecuteScript( - GetSettingsFrame(), - "document.querySelector('" + selector + "').click();")); - } - - bool IsElementEnabled(const std::string& selector) { - bool element_enabled = false; - GetElementEnabledState(selector, &element_enabled); - return element_enabled; - } - - private: - void GetElementEnabledState( - const std::string& selector, - bool* enabled) { - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - GetSettingsFrame(), - "window.domAutomationController.send(!document.querySelector('" + - selector + "').disabled);", - enabled)); - } -}; - -// http://crbug.com/458684 -#if defined(OS_WIN) || defined(OS_MACOSX) -#define MAYBE_CommitButtonDisabledWhileDeletionInProgress \ - DISABLED_CommitButtonDisabledWhileDeletionInProgress -#else -#define MAYBE_CommitButtonDisabledWhileDeletionInProgress \ - CommitButtonDisabledWhileDeletionInProgress -#endif - -IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest, - MAYBE_CommitButtonDisabledWhileDeletionInProgress) { - const char kCommitButtonId[] = "#clear-browser-data-commit"; - content::BrowsingDataRemoverCompletionInhibitor completion_inhibitor( - content::BrowserContext::GetBrowsingDataRemover(browser()->profile())); - - // Navigate to the Clear Browsing Data dialog to ensure that the commit button - // is initially enabled, usable, and gets disabled after having been pressed. - NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage); - ASSERT_NO_FATAL_FAILURE(ClickElement(kCommitButtonId)); - EXPECT_FALSE(IsElementEnabled(kCommitButtonId)); - - completion_inhibitor.BlockUntilNearCompletion(); - - // Simulate a reload while the previous removal is still running, and verify - // that the button is still disabled. - NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage); - EXPECT_FALSE(IsElementEnabled(kCommitButtonId)); - - completion_inhibitor.ContinueToCompletion(); - - // However, the button should be enabled again once the process has finished. - NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage); - EXPECT_TRUE(IsElementEnabled(kCommitButtonId)); -} - -IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest, - CommitButtonDisabledWhenNoDataTypesSelected) { - const char kCommitButtonId[] = "#clear-browser-data-commit"; - const char* kDataTypes[] = {"browser.clear_data.browsing_history", - "browser.clear_data.download_history", - "browser.clear_data.cache", - "browser.clear_data.cookies", - "browser.clear_data.passwords", - "browser.clear_data.form_data", - "browser.clear_data.hosted_apps_data", - "browser.clear_data.media_licenses"}; - - PrefService* prefs = browser()->profile()->GetPrefs(); - for (size_t i = 0; i < arraysize(kDataTypes); ++i) { - prefs->SetBoolean(kDataTypes[i], false); - } - - // Navigate to the Clear Browsing Data dialog to ensure that the commit button - // is disabled if clearing is not requested for any of the data types. - NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage); - EXPECT_FALSE(IsElementEnabled(kCommitButtonId)); - - // However, expect the commit button to be re-enabled if any of the data types - // gets selected to be cleared. - for (size_t i = 0; i < arraysize(kDataTypes); ++i) { - prefs->SetBoolean(kDataTypes[i], true); - EXPECT_TRUE(IsElementEnabled(kCommitButtonId)); - prefs->SetBoolean(kDataTypes[i], false); - } -} - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/content_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/content_options_browsertest.js deleted file mode 100644 index 863fb28f880..00000000000 --- a/chromium/chrome/browser/ui/webui/options/content_options_browsertest.js +++ /dev/null @@ -1,27 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for content options WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function ContentOptionsWebUITest() {} - -ContentOptionsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to content options. - * @override - */ - browsePreload: 'chrome://settings-frame/content', -}; - -// Test opening the content options has correct location. -TEST_F('ContentOptionsWebUITest', 'testOpenContentOptions', function() { - assertEquals(this.browsePreload, document.location.href); -}); diff --git a/chromium/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.cc b/chromium/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.cc deleted file mode 100644 index e149f7e45ef..00000000000 --- a/chromium/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.cc +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 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 "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/webui/options/options_ui_browsertest.h" - -typedef options::OptionsUIBrowserTest ContentSettingsExceptionsAreaBrowserTest; - -// Test that an incognito window can be opened while the exceptions page is -// open. If this test fails it could indicate that a new content setting has -// been added but is not being dealt with correctly by the content settings -// handling WebUI code. -#if defined(OS_MACOSX) && defined(ADDRESS_SANITIZER) -// Flaky on ASAN on Mac. See https://crbug.com/674497. -#define MAYBE_OpenIncognitoWindow DISABLED_OpenIncognitoWindow -#else -#define MAYBE_OpenIncognitoWindow OpenIncognitoWindow -#endif -IN_PROC_BROWSER_TEST_F(ContentSettingsExceptionsAreaBrowserTest, - MAYBE_OpenIncognitoWindow) { - NavigateToSettingsSubpage("contentExceptions"); - chrome::NewIncognitoWindow(browser()); -} diff --git a/chromium/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js b/chromium/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js deleted file mode 100644 index 7cfc1edc633..00000000000 --- a/chromium/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js +++ /dev/null @@ -1,109 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for content settings exception area WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function ContentSettingsExceptionAreaWebUITest() {} - -ContentSettingsExceptionAreaWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/contentExceptions', -}; - -// See crbug.com/579666 for OS_LINUX and crbug.com/588586 for Windows and -// crbug.com/718947 for Mac. -GEN('#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN) || ' + - 'defined(OS_MACOSX)'); -GEN('#define MAYBE_testOpenContentSettingsExceptionArea ' + - 'DISABLED_testOpenContentSettingsExceptionArea'); -GEN('#else'); -GEN('#define MAYBE_testOpenContentSettingsExceptionArea ' + - 'testOpenContentSettingsExceptionArea'); -GEN('#endif // defined(OS_CHROMEOS) || defined(OS_LINUX)'); -// Test opening the content settings exception area has correct location. -TEST_F('ContentSettingsExceptionAreaWebUITest', - 'MAYBE_testOpenContentSettingsExceptionArea', function() { - assertEquals(this.browsePreload, document.location.href); -}); - -/** - * A class to asynchronously test the content settings exception area dialog. - * @extends {testing.Test} - * @constructor - */ -function ContentSettingsExceptionsAreaAsyncWebUITest() {} - -ContentSettingsExceptionsAreaAsyncWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/contentExceptions', - - /** @override */ - isAsync: true, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_TEXT_01: http://crbug.com/570562 - this.accessibilityAuditConfig.ignoreSelectors( - 'controlsWithoutLabel', - '#content-settings-exceptions-area > .content-area > *'); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/570563 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#content-settings-exceptions-area > .action-area > *'); - }, -}; - -// Adds and removes a location content setting exception. -TEST_F('ContentSettingsExceptionsAreaAsyncWebUITest', - 'testAddRemoveLocationExceptions', function() { - assertEquals(this.browsePreload, document.location.href); - - /** @const */ var origin = 'http://google.com:80'; - /** @const */ var setExceptions = ContentSettings.setExceptions; - - var list = ContentSettings.getExceptionsList('cookies', 'normal'); - assertEquals(1, list.items.length); - - var setExceptionsCounter = 0; - var setExceptionsCallback = function() { - setExceptionsCounter++; - if (setExceptionsCounter == 1) { - // The first item is now the exception (edit items are always last). - expectEquals('block', list.dataModel.item(0).setting); - expectEquals(origin, list.dataModel.item(0).origin); - - // Delete the item and verify it worked. - list.deleteItemAtIndex(0); - } else if (setExceptionsCounter == 2) { - // Verify the item was deleted, restore the original method, and finish. - expectEquals(1, list.items.length); - ContentSettings.setExceptions = setExceptions; - testDone(); - } - }; - - // NOTE: if this test doesn't succeed, |ContentSettings.setExceptions| may not - // be restored to its original method. I know no easy way to fix this. - ContentSettings.setExceptions = function() { - setExceptions.apply(ContentSettings, arguments); - setExceptionsCallback(); - }; - - // Add an item to the location exception area to start the test. - list.items[0].finishEdit(origin, 'block'); -}); diff --git a/chromium/chrome/browser/ui/webui/options/content_settings_handler.cc b/chromium/chrome/browser/ui/webui/options/content_settings_handler.cc index b72dfe7301f..074fa9710d7 100644 --- a/chromium/chrome/browser/ui/webui/options/content_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/content_settings_handler.cc @@ -205,7 +205,7 @@ std::unique_ptr<base::DictionaryValue> GetGeolocationExceptionForPage( const ContentSettingsPattern& origin, const ContentSettingsPattern& embedding_origin, ContentSetting setting) { - base::DictionaryValue* exception = new base::DictionaryValue(); + auto exception = base::MakeUnique<base::DictionaryValue>(); std::string setting_string = content_settings::ContentSettingToString(setting); @@ -215,7 +215,7 @@ std::unique_ptr<base::DictionaryValue> GetGeolocationExceptionForPage( exception->SetString(site_settings::kOrigin, origin.ToString()); exception->SetString( site_settings::kEmbeddingOrigin, embedding_origin.ToString()); - return base::WrapUnique(exception); + return exception; } // Create a DictionaryValue* that will act as a data source for a single row @@ -229,7 +229,7 @@ std::unique_ptr<base::DictionaryValue> GetNotificationExceptionForPage( if (secondary_pattern != ContentSettingsPattern::Wildcard()) embedding_origin = secondary_pattern.ToString(); - base::DictionaryValue* exception = new base::DictionaryValue(); + auto exception = base::MakeUnique<base::DictionaryValue>(); std::string setting_string = content_settings::ContentSettingToString(setting); @@ -239,7 +239,7 @@ std::unique_ptr<base::DictionaryValue> GetNotificationExceptionForPage( exception->SetString(site_settings::kOrigin, primary_pattern.ToString()); exception->SetString(site_settings::kEmbeddingOrigin, embedding_origin); exception->SetString(site_settings::kSource, provider_name); - return base::WrapUnique(exception); + return exception; } // Returns true whenever the |extension| is hosted and has |permission|. @@ -838,7 +838,7 @@ void ContentSettingsHandler::UpdateGeolocationExceptionsView() { continue; } all_patterns_settings[std::make_pair(i->primary_pattern, i->source)] - [i->secondary_pattern] = i->setting; + [i->secondary_pattern] = i->GetContentSetting(); } base::ListValue exceptions; @@ -909,11 +909,9 @@ void ContentSettingsHandler::UpdateNotificationExceptionsView() { continue; } - exceptions.Append( - GetNotificationExceptionForPage(i->primary_pattern, - i->secondary_pattern, - i->setting, - i->source)); + exceptions.Append(GetNotificationExceptionForPage( + i->primary_pattern, i->secondary_pattern, i->GetContentSetting(), + i->source)); } base::Value type_string(site_settings::ContentSettingsTypeToGroupName( diff --git a/chromium/chrome/browser/ui/webui/options/cookies_view_browsertest.js b/chromium/chrome/browser/ui/webui/options/cookies_view_browsertest.js deleted file mode 100644 index e2c094d2ca7..00000000000 --- a/chromium/chrome/browser/ui/webui/options/cookies_view_browsertest.js +++ /dev/null @@ -1,60 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for cookies view WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function CookiesViewWebUITest() {} - -CookiesViewWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to the cookies view. - */ - browsePreload: 'chrome://settings-frame/cookies', - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_TEXT_01: http://crbug.com/570560 - this.accessibilityAuditConfig.ignoreSelectors( - 'controlsWithoutLabel', - '#cookies-view-page > .content-area.cookies-list-content-area > *'); - - var requiredOwnedAriaRoleMissingSelectors = [ - '#default-search-engine-list', - '#other-search-engine-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_08: http://crbug.com/605689 - this.accessibilityAuditConfig.ignoreSelectors( - 'requiredOwnedAriaRoleMissing', - requiredOwnedAriaRoleMissingSelectors); - }, -}; - -// Test opening the cookies view has correct location. -TEST_F('CookiesViewWebUITest', 'testOpenCookiesView', function() { - assertEquals(this.browsePreload, document.location.href); -}); - -TEST_F('CookiesViewWebUITest', 'testNoCloseOnSearchEnter', function() { - var cookiesView = CookiesView.getInstance(); - assertTrue(cookiesView.visible); - var searchBox = cookiesView.pageDiv.querySelector('.cookies-search-box'); - searchBox.dispatchEvent(new KeyboardEvent('keydown', { - 'bubbles': true, - 'cancelable': true, - 'key': 'Enter' - })); - assertTrue(cookiesView.visible); -}); diff --git a/chromium/chrome/browser/ui/webui/options/core_options_handler.cc b/chromium/chrome/browser/ui/webui/options/core_options_handler.cc index ec45725bbe2..45ca990799b 100644 --- a/chromium/chrome/browser/ui/webui/options/core_options_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/core_options_handler.cc @@ -29,7 +29,6 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" #include "components/proxy_config/proxy_config_pref_names.h" #include "components/strings/grit/components_strings.h" #include "components/url_formatter/url_fixer.h" diff --git a/chromium/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js b/chromium/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js deleted file mode 100644 index 5bcb0e0b18a..00000000000 --- a/chromium/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js +++ /dev/null @@ -1,166 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for EditDictionaryOverlay WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function EditDictionaryWebUITest() {} - -EditDictionaryWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to the edit dictionary page & call our preLoad(). - */ - browsePreload: 'chrome://settings-frame/editDictionary', - - /** - * Register a mock dictionary handler. - */ - preLoad: function() { - this.makeAndRegisterMockHandler( - ['refreshDictionaryWords', - 'addDictionaryWord', - 'removeDictionaryWord', - ]); - this.mockHandler.stubs().refreshDictionaryWords(). - will(callFunction(function() { - EditDictionaryOverlay.setWordList([]); - })); - this.mockHandler.stubs().addDictionaryWord(ANYTHING); - this.mockHandler.stubs().removeDictionaryWord(ANYTHING); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_TEXT_01: http://crbug.com/570556 - this.accessibilityAuditConfig.ignoreSelectors( - 'controlsWithoutLabel', - '#language-dictionary-overlay-word-list > .deletable-item > *'); - - var unsupportedAriaAttributeSelectors = [ - '#language-dictionary-overlay-word-list', - '#language-options-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/570559 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - unsupportedAriaAttributeSelectors); - }, -}; - -// Verify that users can add and remove words in the dictionary. -TEST_F('EditDictionaryWebUITest', 'testAddRemoveWords', function() { - var testWord = 'foo'; - $('language-dictionary-overlay-word-list').querySelector('input').value = - testWord; - - this.mockHandler.expects(once()).addDictionaryWord([testWord]). - will(callFunction(function() { - EditDictionaryOverlay.setWordList([testWord]); - })); - var addWordItem = EditDictionaryOverlay.getWordListForTesting().items[0]; - addWordItem.onEditCommitted_({currentTarget: addWordItem}); - - this.mockHandler.expects(once()).removeDictionaryWord([testWord]). - will(callFunction(function() { - EditDictionaryOverlay.setWordList([]); - })); - EditDictionaryOverlay.getWordListForTesting().deleteItemAtIndex(0); -}); - -// Verify that users can search words in the dictionary. -TEST_F('EditDictionaryWebUITest', 'testSearch', function() { - EditDictionaryOverlay.setWordList(['foo', 'bar']); - expectEquals(3, EditDictionaryOverlay.getWordListForTesting().items.length); - - /** - * @param {Element} el The element to dispatch an event on. - * @param {string} value The text of the search event. - */ - var fakeSearchEvent = function(el, value) { - el.value = value; - cr.dispatchSimpleEvent(el, 'search'); - }; - var searchField = $('language-dictionary-overlay-search-field'); - fakeSearchEvent(searchField, 'foo'); - expectEquals(2, EditDictionaryOverlay.getWordListForTesting().items.length); - - fakeSearchEvent(searchField, ''); - expectEquals(3, EditDictionaryOverlay.getWordListForTesting().items.length); -}); - -TEST_F('EditDictionaryWebUITest', 'testNoCloseOnSearchEnter', function() { - var editDictionaryPage = EditDictionaryOverlay.getInstance(); - assertTrue(editDictionaryPage.visible); - var searchField = $('language-dictionary-overlay-search-field'); - searchField.dispatchEvent(new KeyboardEvent('keydown', { - 'bubbles': true, - 'cancelable': true, - 'key': 'Enter' - })); - assertTrue(editDictionaryPage.visible); -}); - -// Verify that dictionary shows newly added words that arrived in a -// notification, but ignores duplicate add notifications. -TEST_F('EditDictionaryWebUITest', 'testAddNotification', function() { - // Begin with an empty dictionary. - EditDictionaryOverlay.setWordList([]); - expectEquals(1, EditDictionaryOverlay.getWordListForTesting().items.length); - - // User adds word 'foo'. - EditDictionaryOverlay.getWordListForTesting().addDictionaryWord_('foo'); - expectEquals(2, EditDictionaryOverlay.getWordListForTesting().items.length); - - // Backend notifies UI that the word 'foo' has been added. UI ignores this - // notification, because the word is displayed immediately after user added - // it. - EditDictionaryOverlay.updateWords(['foo'], []); - expectEquals(2, EditDictionaryOverlay.getWordListForTesting().items.length); - - // Backend notifies UI that the words 'bar' and 'baz' were added. UI shows - // these new words. - EditDictionaryOverlay.updateWords(['bar', 'baz'], []); - expectEquals(4, EditDictionaryOverlay.getWordListForTesting().items.length); -}); - -// Verify that dictionary hides newly removed words that arrived in a -// notification, but ignores duplicate remove notifications. -// TODO(crbug.com/631940): Flaky on Win 7. -GEN('#if defined(OS_WIN)'); -GEN('#define MAYBE_testRemoveNotification DISABLED_testRemoveNotification'); -GEN('#else'); -GEN('#define MAYBE_testRemoveNotification testRemoveNotification'); -GEN('#endif // defined(OS_WIN)'); -TEST_F('EditDictionaryWebUITest', 'MAYBE_testRemoveNotification', function() { - // Begin with a dictionary with words 'foo', 'bar', 'baz', and 'baz'. The - // second instance of 'baz' appears because the user added the word twice. - // The backend keeps only one copy of the word. - EditDictionaryOverlay.setWordList(['foo', 'bar', 'baz', 'baz']); - expectEquals(5, EditDictionaryOverlay.getWordListForTesting().items.length); - - // User deletes the second instance of 'baz'. - EditDictionaryOverlay.getWordListForTesting().deleteItemAtIndex(3); - expectEquals(4, EditDictionaryOverlay.getWordListForTesting().items.length); - - // Backend notifies UI that the word 'baz' has been removed. UI ignores this - // notification. - EditDictionaryOverlay.updateWords([], ['baz']); - expectEquals(4, EditDictionaryOverlay.getWordListForTesting().items.length); - - // Backend notifies UI that words 'foo' and 'bar' have been removed. UI - // removes these words. - EditDictionaryOverlay.updateWords([], ['foo', 'bar']); - expectEquals(2, EditDictionaryOverlay.getWordListForTesting().items.length); -}); diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_browsertest.js b/chromium/chrome/browser/ui/webui/options/font_settings_browsertest.js deleted file mode 100644 index 6e419a207cf..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_browsertest.js +++ /dev/null @@ -1,66 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for font settings WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function FontSettingsWebUITest() {} - -FontSettingsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to the font settings page. - */ - browsePreload: 'chrome://settings-frame/fonts', - - /** @override */ - preLoad: function() { - this.makeAndRegisterMockHandler(['openAdvancedFontSettingsOptions']); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - var controlsWithoutLabelSelectors = [ - '#standard-font-size', - '#minimum-font-size', - ]; - - // Enable when failure is resolved. - // AX_TEXT_01: http://crbug.com/570555 - this.accessibilityAuditConfig.ignoreSelectors( - 'controlsWithoutLabel', - controlsWithoutLabelSelectors); - }, -}; - -// Test opening font settings has correct location. -TEST_F('FontSettingsWebUITest', 'testOpenFontSettings', function() { - assertEquals(this.browsePreload, document.location.href); -}); - -// Test setup of the Advanced Font Settings links. -TEST_F('FontSettingsWebUITest', 'testAdvancedFontSettingsLink', function() { - var installElement = $('advanced-font-settings-install'); - var optionsElement = $('advanced-font-settings-options'); - var expectedUrl = 'https://chrome.google.com/webstore/detail/' + - 'caclkomlalccbpcdllchkeecicepbmbm'; - - FontSettings.notifyAdvancedFontSettingsAvailability(false); - assertFalse(installElement.hidden); - assertEquals(expectedUrl, installElement.querySelector('a').href); - assertTrue(optionsElement.hidden); - - FontSettings.notifyAdvancedFontSettingsAvailability(true); - assertTrue(installElement.hidden); - assertFalse(optionsElement.hidden); - this.mockHandler.expects(once()).openAdvancedFontSettingsOptions(); - optionsElement.click(); -}); diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_handler.cc b/chromium/chrome/browser/ui/webui/options/font_settings_handler.cc index f5a045c438c..7b1ca1ff248 100644 --- a/chromium/chrome/browser/ui/webui/options/font_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/font_settings_handler.cc @@ -23,7 +23,7 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/webui/options/font_settings_utils.h" +#include "chrome/browser/ui/webui/settings_utils.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h" @@ -116,7 +116,9 @@ void FontSettingsHandler::InitializePage() { void FontSettingsHandler::RegisterMessages() { // Perform validation for saved fonts. PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - FontSettingsUtilities::ValidateSavedFonts(pref_service); +#if defined(OS_MACOSX) + settings_utils::ValidateSavedFonts(pref_service); +#endif // Register for preferences that we need to observe manually. standard_font_.Init(prefs::kWebKitStandardFontFamily, @@ -192,14 +194,14 @@ void FontSettingsHandler::FontsListHasLoaded( } base::ListValue selected_values; - selected_values.AppendString(FontSettingsUtilities::MaybeGetLocalizedFontName( - standard_font_.GetValue())); selected_values.AppendString( - FontSettingsUtilities::MaybeGetLocalizedFontName(serif_font_.GetValue())); - selected_values.AppendString(FontSettingsUtilities::MaybeGetLocalizedFontName( - sans_serif_font_.GetValue())); + settings_utils::MaybeGetLocalizedFontName(standard_font_.GetValue())); selected_values.AppendString( - FontSettingsUtilities::MaybeGetLocalizedFontName(fixed_font_.GetValue())); + settings_utils::MaybeGetLocalizedFontName(serif_font_.GetValue())); + selected_values.AppendString( + settings_utils::MaybeGetLocalizedFontName(sans_serif_font_.GetValue())); + selected_values.AppendString( + settings_utils::MaybeGetLocalizedFontName(fixed_font_.GetValue())); web_ui()->CallJavascriptFunctionUnsafe( "FontSettings.setFontsData", *list.get(), selected_values); @@ -207,7 +209,7 @@ void FontSettingsHandler::FontsListHasLoaded( void FontSettingsHandler::SetUpStandardFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(standard_font_.GetValue())); + settings_utils::ResolveFontList(standard_font_.GetValue())); base::Value size_value(default_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpStandardFontSample", font_value, size_value); @@ -215,7 +217,7 @@ void FontSettingsHandler::SetUpStandardFontSample() { void FontSettingsHandler::SetUpSerifFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(serif_font_.GetValue())); + settings_utils::ResolveFontList(serif_font_.GetValue())); base::Value size_value(default_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpSerifFontSample", font_value, size_value); @@ -223,7 +225,7 @@ void FontSettingsHandler::SetUpSerifFontSample() { void FontSettingsHandler::SetUpSansSerifFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(sans_serif_font_.GetValue())); + settings_utils::ResolveFontList(sans_serif_font_.GetValue())); base::Value size_value(default_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe( "FontSettings.setUpSansSerifFontSample", font_value, size_value); @@ -231,7 +233,7 @@ void FontSettingsHandler::SetUpSansSerifFontSample() { void FontSettingsHandler::SetUpFixedFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(fixed_font_.GetValue())); + settings_utils::ResolveFontList(fixed_font_.GetValue())); base::Value size_value(default_fixed_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpFixedFontSample", font_value, size_value); diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_utils.cc b/chromium/chrome/browser/ui/webui/options/font_settings_utils.cc deleted file mode 100644 index 516b138c93e..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_utils.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 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 "chrome/browser/ui/webui/options/font_settings_utils.h" - -#include "ui/gfx/font_list.h" - -namespace options { - -std::string FontSettingsUtilities::ResolveFontList( - const std::string& font_name_or_list) { - if (!font_name_or_list.empty() && font_name_or_list[0] == ',') - return gfx::FontList::FirstAvailableOrFirst(font_name_or_list); - return font_name_or_list; -} - -#if !defined(OS_WIN) -std::string FontSettingsUtilities::MaybeGetLocalizedFontName( - const std::string& font_name_or_list) { - return ResolveFontList(font_name_or_list); -} -#endif - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_utils.h b/chromium/chrome/browser/ui/webui/options/font_settings_utils.h deleted file mode 100644 index 35801bb471f..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_utils.h +++ /dev/null @@ -1,41 +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 CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_UTILS_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_UTILS_H_ - -#include <string> - -#include "base/macros.h" - -class PrefService; - -namespace options { - -// Chrome advanced options utility methods. -class FontSettingsUtilities { - public: - static void ValidateSavedFonts(PrefService* prefs); - - // When |font_name_or_list| starts with ",", it is a list of font names - // separated by "," and this function returns the first available font name. - // Otherwise returns |font_name_or_list| as is. - // Unlike gfx::FontList, this function picks one font, and character-level - // fallback is handled in CSS. - static std::string ResolveFontList(const std::string& font_name_or_list); - - // Returns the localized name of a font so that settings can find it within - // the list of system fonts. On Windows, the list of system fonts has names - // only for the system locale, but the pref value may be in the English name. - // For example, "MS Gothic" becomes "ï¼ï¼³ ゴシック" on localized Windows. - static std::string MaybeGetLocalizedFontName( - const std::string& font_name_or_list); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(FontSettingsUtilities); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_UTILS_H_ diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_utils_linux.cc b/chromium/chrome/browser/ui/webui/options/font_settings_utils_linux.cc deleted file mode 100644 index 1576d03be1f..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_utils_linux.cc +++ /dev/null @@ -1,14 +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 "chrome/browser/ui/webui/options/font_settings_utils.h" - -namespace options { - -// static -void FontSettingsUtilities::ValidateSavedFonts(PrefService* prefs) { - // Nothing to do for X11. -} - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_utils_mac.mm b/chromium/chrome/browser/ui/webui/options/font_settings_utils_mac.mm deleted file mode 100644 index 85c220f9399..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_utils_mac.mm +++ /dev/null @@ -1,42 +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 "chrome/browser/ui/webui/options/font_settings_utils.h" - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsautorelease_pool.h" -#include "base/strings/sys_string_conversions.h" -#include "base/values.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" - -namespace options { - -static void ValidateFontFamily(PrefService* prefs, - const char* family_pref_name) { - // The native font settings dialog saved fonts by the font name, rather - // than the family name. This worked for the old dialog since - // -[NSFont fontWithName:size] accepted a font or family name, but the - // behavior was technically wrong. Since we really need the family name for - // the dom-ui options window, we will fix the saved preference if necessary. - NSString *family_name = - base::SysUTF8ToNSString(prefs->GetString(family_pref_name)); - NSFont *font = [NSFont fontWithName:family_name - size:[NSFont systemFontSize]]; - if (font && - [[font familyName] caseInsensitiveCompare:family_name] != NSOrderedSame) { - std::string new_family_name = base::SysNSStringToUTF8([font familyName]); - prefs->SetString(family_pref_name, new_family_name); - } -} - -// static -void FontSettingsUtilities::ValidateSavedFonts(PrefService* prefs) { - ValidateFontFamily(prefs, prefs::kWebKitSerifFontFamily); - ValidateFontFamily(prefs, prefs::kWebKitSansSerifFontFamily); - ValidateFontFamily(prefs, prefs::kWebKitFixedFontFamily); -} - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_utils_unittest.cc b/chromium/chrome/browser/ui/webui/options/font_settings_utils_unittest.cc deleted file mode 100644 index 2c274d1029d..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_utils_unittest.cc +++ /dev/null @@ -1,30 +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 "chrome/browser/ui/webui/options/font_settings_utils.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace options { - -TEST(FontSettingsUtilitiesTest, ResolveFontList) { - EXPECT_TRUE(FontSettingsUtilities::ResolveFontList("").empty()); - - // Returns the first available font if starts with ",". - EXPECT_EQ("Arial", - FontSettingsUtilities::ResolveFontList(",not exist, Arial")); - - // Returns the first font if no fonts are available. - EXPECT_EQ("not exist", - FontSettingsUtilities::ResolveFontList(",not exist, not exist 2")); - - // Otherwise returns any strings as they were set. - std::string non_lists[] = { - "Arial", "not exist", "not exist, Arial", - }; - for (const std::string& name : non_lists) - EXPECT_EQ(name, FontSettingsUtilities::ResolveFontList(name)); -} - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/font_settings_utils_win.cc b/chromium/chrome/browser/ui/webui/options/font_settings_utils_win.cc deleted file mode 100644 index aa3dd7941ee..00000000000 --- a/chromium/chrome/browser/ui/webui/options/font_settings_utils_win.cc +++ /dev/null @@ -1,27 +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 "chrome/browser/ui/webui/options/font_settings_utils.h" - -#include "ui/gfx/font.h" -#include "ui/gfx/platform_font_win.h" - -namespace options { - -// static -void FontSettingsUtilities::ValidateSavedFonts(PrefService* prefs) { - // Nothing to do for Windows. -} - -std::string FontSettingsUtilities::MaybeGetLocalizedFontName( - const std::string& font_name_or_list) { - std::string font_name = ResolveFontList(font_name_or_list); - if (font_name.empty()) - return font_name; - gfx::Font font(font_name, 12); // dummy font size - return static_cast<gfx::PlatformFontWin*>(font.platform_font()) - ->GetLocalizedFontName(); -} - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc b/chromium/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc deleted file mode 100644 index dbdad4f2af1..00000000000 --- a/chromium/chrome/browser/ui/webui/options/language_dictionary_interactive_uitest.cc +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright 2015 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 "base/strings/stringprintf.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/interactive_test_utils.h" -#include "content/public/test/browser_test_utils.h" - -namespace { - -// This class tests the language dictionary settings. -// This test is part of the interactive_ui_tests instead of browser_tests -// because it is necessary to emulate pushing the tab key. -class LanguageDictionaryWebUITest : public InProcessBrowserTest { - public: - LanguageDictionaryWebUITest() {} - - // Navigate to the editDictionary page. - void SetUpOnMainThread() override { - disable_md_settings_.InitAndDisableFeature( - features::kMaterialDesignSettings); - const GURL url = chrome::GetSettingsUrl("editDictionary"); - ui_test_utils::NavigateToURL(browser(), url); - } - - protected: - const std::string kDictionaryListSelector = - "#language-dictionary-overlay-word-list"; - - content::RenderFrameHost* GetActiveFrame() { - return GetActiveWebContents()->GetFocusedFrame(); - } - - content::RenderViewHost* GetRenderViewHost() { - return GetActiveWebContents()->GetRenderViewHost(); - } - - content::WebContents* GetActiveWebContents() { - return browser()->tab_strip_model()->GetActiveWebContents(); - } - - // Add a few test words to the dictionary. - void SetTestWords(const std::string& list_selector) { - const std::string script = base::StringPrintf( - "document.querySelector('%s').setWordList(['cat', 'dog', 'bird']);", - list_selector.c_str()); - EXPECT_TRUE(content::ExecuteScript(GetActiveFrame(), script)); - // Expected list size is 4: 3 word items + 1 placeholder. - EXPECT_EQ(4, GetListSize(list_selector)); - } - - // Returns the number of items in the list. - int GetListSize(const std::string& list_selector) { - const std::string script = base::StringPrintf( - "domAutomationController.send(" - "document.querySelector('%s').items.length);", - list_selector.c_str()); - int length = -1; - EXPECT_TRUE(content::ExecuteScriptAndExtractInt( - GetActiveFrame(), - script, - &length)); - return length; - } - - // Returns true if element contains document.activeElement. - bool ContainsActiveElement(const std::string& element_selector) { - const std::string script = base::StringPrintf( - "domAutomationController.send(" - "document.querySelector('%s').contains(document.activeElement));", - element_selector.c_str()); - bool result; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - GetActiveFrame(), - script, - &result)); - return result; - } - - // Returns true if list item[|index|] contains document.activeElement. - bool ListItemContainsActiveElement(const std::string& list_selector, - int index) { - EXPECT_GE(index, 0); - // EXPECT_TRUE will fail if index is out of bounds. - const std::string script = base::StringPrintf( - "domAutomationController.send(" - "document.querySelector('%s').items[%d].contains(" - "document.activeElement));", - list_selector.c_str(), - index); - bool result; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - GetActiveFrame(), - script, - &result)); - return result; - } - - // Returns true if list item[|index|] has 'selected' attribute. - bool ListItemSelected(const std::string& list_selector, int index) { - EXPECT_GE(index, 0); - // EXPECT_TRUE will fail if index is out of bounds. - const std::string script = base::StringPrintf( - "domAutomationController.send(" - "document.querySelector('%s').items[%d].hasAttribute('selected'));", - list_selector.c_str(), - index); - bool result = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - GetActiveFrame(), - script, - &result)); - return result; - } - - // Returns true if list item[|index|] has 'selected' attribute and contains - // document.activeElement. - bool ListItemSelectedAndFocused(const std::string& list_selector, - int index) { - EXPECT_GE(index, 0); - return ListItemSelected(list_selector, index) && - ListItemContainsActiveElement(list_selector, index); - } - - // Press and release a key in the browser. This will wait for the element on - // the page to change. - bool PressKey(ui::KeyboardCode key_code, bool shift) { - return ui_test_utils::SendKeyPressAndWait( - browser(), - key_code, - false, - shift, - false, - false, - content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::Source<content::RenderViewHost>(GetRenderViewHost())); - } - - void InitializeDomMessageQueue() { - dom_message_queue_.reset(new content::DOMMessageQueue); - } - - // Wait for a message from the DOM automation controller. - void WaitForDomMessage(const std::string& message) { - const std::string expected = "\"" + message + "\""; - std::string received; - do { - ASSERT_TRUE(dom_message_queue_->WaitForMessage(&received)); - } while (received != expected); - } - - // Add a JavaScript event listener to send a DOM automation controller message - // whenever the |selected| property of the list item changes. - void ListenForItemSelectedChange(const std::string& list_selector, - int index) { - EXPECT_GE(index, 0); - // EXPECT_TRUE will fail if index is out of bounds. - const std::string script = base::StringPrintf( - "document.querySelector('%s').items[%d].addEventListener(" - "'selectedChange', function() {" - "domAutomationController.setAutomationId(0);" - "domAutomationController.send('selected=' + this.selected);" - "});", - list_selector.c_str(), - index); - - EXPECT_TRUE(content::ExecuteScript( - GetActiveFrame(), - script)); - } - - private: - std::unique_ptr<content::DOMMessageQueue> dom_message_queue_; - base::test::ScopedFeatureList disable_md_settings_; - - DISALLOW_COPY_AND_ASSIGN(LanguageDictionaryWebUITest); -}; - -} // namespace - -// Test InlineEditableItemList keyboard focus behavior in editDictionary -// overlay. -// editDictionary overlay doesn't exist on OSX so disable it there. -#if !defined(OS_MACOSX) - -// Crashes on Win 7. http://crbug.com/500609 -#if defined(OS_WIN) -#define MAYBE_TestListKeyboardFocus DISABLED_TestListKeyboardFocus -#else -#define MAYBE_TestListKeyboardFocus TestListKeyboardFocus -#endif - -IN_PROC_BROWSER_TEST_F(LanguageDictionaryWebUITest, - MAYBE_TestListKeyboardFocus) { - const std::string list_selector = kDictionaryListSelector; - - // Populate the list with some test words. - SetTestWords(list_selector); - int placeholder_index = GetListSize(list_selector) - 1; - - // Listen for changes of the placeholder item's |selected| property so that - // test can wait until change has taken place after key press before - // continuing. - InitializeDomMessageQueue(); - ListenForItemSelectedChange(list_selector, placeholder_index); - - // Press tab to focus the placeholder. - PressKey(ui::VKEY_TAB, false); - - // Wait for placeholder item to become selected. - WaitForDomMessage("selected=true"); - - // Verify that the placeholder is selected and has focus. - EXPECT_TRUE(ListItemSelectedAndFocused(list_selector, placeholder_index)); - - // Press up arrow to select item above the placeholder. - PressKey(ui::VKEY_UP, false); - - // Wait for placeholder to become unselected. - WaitForDomMessage("selected=false"); - - // Verify that the placeholder is no longer selected. - EXPECT_FALSE(ListItemSelected(list_selector, placeholder_index)); - - // Verify that the item above the placeholder is selected and has focus. - EXPECT_TRUE(ListItemSelectedAndFocused(list_selector, - placeholder_index - 1)); - - // Press tab to leave the list. - PressKey(ui::VKEY_TAB, false); - - // Verify that focus has left the list. - EXPECT_FALSE(ContainsActiveElement(list_selector)); - - // Verify that the item above the placeholder is still selected. - EXPECT_TRUE(ListItemSelected(list_selector, placeholder_index - 1)); - - // Press shift+tab to go back to the list. - PressKey(ui::VKEY_TAB, true); - - // Verify that the item above the placeholder is selected and has focus. - EXPECT_TRUE(ListItemSelectedAndFocused(list_selector, - placeholder_index - 1)); -} -#endif // !defined(OS_MACOSX) diff --git a/chromium/chrome/browser/ui/webui/options/language_options_browsertest.js b/chromium/chrome/browser/ui/webui/options/language_options_browsertest.js deleted file mode 100644 index bfd3acb62c9..00000000000 --- a/chromium/chrome/browser/ui/webui/options/language_options_browsertest.js +++ /dev/null @@ -1,56 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for language options WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function LanguageOptionsWebUITest() {} - -LanguageOptionsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/languages', - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/559266 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#language-options-list'); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/559271 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#languagePage > .content-area > .language-options-header > A'); - } -}; - -// Test opening language options has correct location. -TEST_F('LanguageOptionsWebUITest', 'testOpenLanguageOptions', function() { - assertEquals(this.browsePreload, document.location.href); -}); - -GEN('#if defined(OS_WIN) || defined(OS_CHROMEOS)'); -// Test reselecting the same language as the current UI locale. This should show -// a "Chrome is displayed in this language" message rather than a restart banner -// or a [ Display Chrome in this language ] button. -TEST_F('LanguageOptionsWebUITest', 'reselectUILocale', function() { - var currentLang = loadTimeData.getString('currentUiLanguageCode'); - $('language-options-list').selectLanguageByCode(currentLang); - LanguageOptions.uiLanguageSaved(currentLang); - - expectTrue($('language-options-ui-language-button').hidden); - expectFalse($('language-options-ui-language-message').hidden); - expectTrue($('language-options-ui-notification-bar').hidden); -}); -GEN('#endif'); // defined(OS_WIN) || defined(OS_CHROMEOS) diff --git a/chromium/chrome/browser/ui/webui/options/language_options_dictionary_download_browsertest.js b/chromium/chrome/browser/ui/webui/options/language_options_dictionary_download_browsertest.js deleted file mode 100644 index 174b32365a4..00000000000 --- a/chromium/chrome/browser/ui/webui/options/language_options_dictionary_download_browsertest.js +++ /dev/null @@ -1,129 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for testing messages of dictionary download progress in language - * options WebUI. - * @extends {testing.Test} - * @constructor - */ -function LanguagesOptionsDictionaryDownloadWebUITest() {} - -LanguagesOptionsDictionaryDownloadWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to languages options. - */ - browsePreload: 'chrome://settings-frame/languages', - - /** - * Register a mock dictionary handler. - */ - preLoad: function() { - this.makeAndRegisterMockHandler(['retryDictionaryDownload']); - this.mockHandler.stubs().retryDictionaryDownload(). - will(callFunction(function() { - options.LanguageOptions.onDictionaryDownloadBegin('en-US'); - })); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/570554 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#language-options-list'); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/570553 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#languagePage > .content-area > .language-options-header > A'); - }, -}; - -// Verify that dictionary download success does not show, "This language can't -// be used for spellchecking." or "Download failed." -// Disabled due to flakiness (crbug.com/616550). -TEST_F('LanguagesOptionsDictionaryDownloadWebUITest', - 'DISABLED_testdictionaryDownloadSuccess', - function() { - options.LanguageOptions.onDictionaryDownloadSuccess('en-US'); - expectTrue($('spellcheck-language-message').hidden); - expectTrue($('language-options-dictionary-downloading-message').hidden); - expectTrue($('language-options-dictionary-download-failed-message').hidden); - expectTrue( - $('language-options-dictionary-download-fail-help-message').hidden); -}); - -// Verify that dictionary download in progress shows 'Downloading spell check -// language' message. -// Disabled due to flakiness (crbug.com/616550). -TEST_F('LanguagesOptionsDictionaryDownloadWebUITest', - 'DISABLED_testdictionaryDownloadProgress', - function() { - options.LanguageOptions.onDictionaryDownloadBegin('en-US'); - expectTrue($('spellcheck-language-message').hidden); - expectFalse($('language-options-dictionary-downloading-message').hidden); - expectTrue($('language-options-dictionary-download-failed-message').hidden); - expectTrue( - $('language-options-dictionary-download-fail-help-message').hidden); -}); - -// Verify that failure in dictionary download shows 'Dictionary download failed' -// message. -TEST_F('LanguagesOptionsDictionaryDownloadWebUITest', - 'testdictionaryDownloadFailed', - function() { - // Clear the failure counter: - options.LanguageOptions.onDictionaryDownloadSuccess('en-US'); - - // First failure shows a short error message. - options.LanguageOptions.onDictionaryDownloadFailure('en-US'); - expectTrue($('spellcheck-language-message').hidden); - expectTrue($('language-options-dictionary-downloading-message').hidden); - expectFalse($('language-options-dictionary-download-failed-message').hidden); - expectTrue( - $('language-options-dictionary-download-fail-help-message').hidden); - - // Second and all following failures show a longer error message. - options.LanguageOptions.onDictionaryDownloadFailure('en-US'); - expectTrue($('spellcheck-language-message').hidden); - expectTrue($('language-options-dictionary-downloading-message').hidden); - expectFalse($('language-options-dictionary-download-failed-message').hidden); - expectFalse( - $('language-options-dictionary-download-fail-help-message').hidden); - - options.LanguageOptions.onDictionaryDownloadFailure('en-US'); - expectTrue($('spellcheck-language-message').hidden); - expectTrue($('language-options-dictionary-downloading-message').hidden); - expectFalse($('language-options-dictionary-download-failed-message').hidden); - expectFalse( - $('language-options-dictionary-download-fail-help-message').hidden); -}); - -// Verify that clicking the retry button calls the handler. -// This test is flaky on Windows. https://crbug.com/616791 -GEN('#if defined(OS_WIN)'); -GEN('#define MAYBE_testdictionaryDownloadRetry ' + - 'DISABLED_testdictionaryDownloadRetry'); -GEN('#else'); -GEN('#define MAYBE_testdictionaryDownloadRetry testdictionaryDownloadRetry'); -GEN('#endif // defined(OS_WIN)'); -TEST_F('LanguagesOptionsDictionaryDownloadWebUITest', - 'MAYBE_testdictionaryDownloadRetry', - function() { - this.mockHandler.expects(once()).retryDictionaryDownload('en-US'). - will(callFunction(function() { - options.LanguageOptions.onDictionaryDownloadBegin('en-US'); - })); - options.LanguageOptions.onDictionaryDownloadFailure('en-US'); - $('dictionary-download-retry-button').click(); -}); diff --git a/chromium/chrome/browser/ui/webui/options/language_options_handler_unittest.cc b/chromium/chrome/browser/ui/webui/options/language_options_handler_unittest.cc deleted file mode 100644 index e290a9874d7..00000000000 --- a/chromium/chrome/browser/ui/webui/options/language_options_handler_unittest.cc +++ /dev/null @@ -1,28 +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 "chrome/browser/ui/webui/options/language_options_handler.h" - -#include <string> - -#include "base/values.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if !defined(OS_MACOSX) -TEST(LanguageOptionsHandlerTest, GetUILanguageCodeSet) { - std::unique_ptr<base::DictionaryValue> dictionary( - options::LanguageOptionsHandler::GetUILanguageCodeSet()); - EXPECT_TRUE(dictionary->HasKey("en-US")); - // Note that we don't test a false case, as such an expectation will - // fail when we add support for the language. - // EXPECT_FALSE(dictionary->HasKey("no")); -} -#endif // !defined(OS_MACOSX) - -TEST(LanguageOptionsHandlerTest, GetSpellCheckLanguageCodeSet) { - std::unique_ptr<base::DictionaryValue> dictionary( - options::LanguageOptionsHandler::GetSpellCheckLanguageCodeSet()); - EXPECT_TRUE(dictionary->HasKey("en-US")); -} diff --git a/chromium/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc b/chromium/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc deleted file mode 100644 index e9fa0e27030..00000000000 --- a/chromium/chrome/browser/ui/webui/options/language_options_interactive_uitest.cc +++ /dev/null @@ -1,166 +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 "base/macros.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/interactive_test_utils.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" - -namespace language_options_ui_test { - -namespace { - -// This class will test the language options settings. -// This test is part of the interactive_ui_tests isntead of browser_tests -// because it is necessary to emulate pushing a button in order to properly -// test accessibility. -class LanguageOptionsWebUITest : public InProcessBrowserTest { - public: - LanguageOptionsWebUITest() {} - - void SetUpInProcessBrowserTestFixture() override { - disable_md_settings_.InitAndDisableFeature( - features::kMaterialDesignSettings); - } - - // This method will navigate to the language settings page and show - // a subset of languages from the list of available languages. - void SetUpOnMainThread() override { -#if defined(OS_CHROMEOS) - auto* setting_name = prefs::kLanguagePreferredLanguages; -#else - auto* setting_name = prefs::kAcceptLanguages; -#endif - - const GURL url = chrome::GetSettingsUrl(chrome::kLanguageOptionsSubPage); - ui_test_utils::NavigateToURL(browser(), url); - browser()->profile()->GetPrefs()->SetString(setting_name, "en-US,es,fr"); - } - - protected: - // Will get the id of the element in the UI that has focus. - std::string GetActiveElementId() { - std::string get_element_id_script = - "domAutomationController.send(document.activeElement.id);"; - std::string element_id; - EXPECT_TRUE(content::ExecuteScriptAndExtractString( - GetActiveFrame(), - get_element_id_script, - &element_id)); - return element_id; - } - - content::RenderFrameHost* GetActiveFrame() { - return GetActiveWebContents()->GetFocusedFrame(); - } - - content::RenderViewHost* GetRenderViewHost() { - return GetActiveWebContents()->GetRenderViewHost(); - } - - content::WebContents* GetActiveWebContents() { - return browser()->tab_strip_model()->GetActiveWebContents(); - } - - // Press and release a key in the browser. This will wait for the element on - // the page to change. - bool PressKey(ui::KeyboardCode key_code) { - return ui_test_utils::SendKeyPressAndWait( - browser(), - key_code, - false, - false, - false, - false, - content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::Source<content::RenderViewHost>(GetRenderViewHost())); - } - - private: - base::test::ScopedFeatureList disable_md_settings_; - - DISALLOW_COPY_AND_ASSIGN(LanguageOptionsWebUITest); -}; - -} // namespace - -// This test will verify that the appropriate languages are available. -// This test will also fail if the language page is not loaded because a random -// page will not have the language list. -// Test assumes that the default active element is the list of languages. -IN_PROC_BROWSER_TEST_F(LanguageOptionsWebUITest, TestAvailableLanguages) { - // Verify that the language list is focused by default. - std::string original_id = GetActiveElementId(); - EXPECT_EQ("language-options-list", original_id); - - content::RenderFrameHost* active_frame = GetActiveFrame(); - - std::string count_deletable_items_script = - "domAutomationController.send(" - " document.activeElement.querySelectorAll('.deletable-item').length);"; - - // Count the number of languages in the list. - int language_count = 0; - ASSERT_TRUE(content::ExecuteScriptAndExtractInt( - active_frame, - count_deletable_items_script, - &language_count)); - EXPECT_EQ(3, language_count); - - std::string get_children_of_current_element_script = - "domAutomationController.send(document.activeElement.textContent);"; - - // Verify that the correct languages are added to the list. - std::string languages; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - active_frame, - get_children_of_current_element_script, - &languages)); - EXPECT_EQ("English (United States)SpanishFrench", languages); -} - -// This test will validate that the language webui is accessible through -// the keyboard. -// This test must be updated if the tab order of the elements on this page -// is changed. - -// Crashes on Win 7. http://crbug.com/500609 -#if defined(OS_WIN) -#define MAYBE_TestListTabAccessibility DISABLED_TestListTabAccessibility -#else -#define MAYBE_TestListTabAccessibility TestListTabAccessibility -#endif - -IN_PROC_BROWSER_TEST_F(LanguageOptionsWebUITest, - MAYBE_TestListTabAccessibility) { - // Verify that the language list is focused by default. - std::string original_id = GetActiveElementId(); - EXPECT_EQ("language-options-list", original_id); - - // Press tab to select the next element. - ASSERT_TRUE(PressKey(ui::VKEY_TAB)); - - // Make sure that the element is now the button that is next in the tab order. - // Checking that the list is no longer selected is not sufficient to validate - // this use case because this test should fail if an item inside the list is - // selected. - std::string new_id = GetActiveElementId(); - EXPECT_EQ("language-options-add-button", new_id); -} - -} // namespace language_options_ui_test - diff --git a/chromium/chrome/browser/ui/webui/options/manage_profile_browsertest.js b/chromium/chrome/browser/ui/webui/options/manage_profile_browsertest.js deleted file mode 100644 index d4144e03322..00000000000 --- a/chromium/chrome/browser/ui/webui/options/manage_profile_browsertest.js +++ /dev/null @@ -1,672 +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. - -// None of these tests is relevant for Chrome OS. -GEN('#if !defined(OS_CHROMEOS)'); - -/** - * TestFixture for ManageProfileOverlay and CreateProfileOverlay WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function ManageProfileUITest() {} - -ManageProfileUITest.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/manageProfile', - - /** - * No need to run these for every OptionsPage test, since they'll cover the - * whole consolidated page each time. - * @override - */ - runAccessibilityChecks: false, - - /** - * Some default profile infos. - */ - defaultIconURLs: [], - defaultNames: [], - - /** - * Returns a test profile-info object with configurable "supervised" status. - * @param {boolean} supervised If true, the test profile will be marked as - * supervised. - * @return {Object} A test profile-info object. - */ - testProfileInfo_: function(supervised) { - return { - name: 'Test Profile', - iconURL: 'chrome://path/to/icon/image', - filePath: '/path/to/profile/data/on/disk', - isCurrentProfile: true, - isSupervised: supervised - }; - }, - - /** - * Overrides WebUI methods that provide profile info, making them return a - * test profile-info object. - * @param {boolean} supervised Whether the test profile should be marked - * as supervised. - * @param {string} mode The mode of the overlay (either 'manage' or 'create'). - */ - setProfileSupervised_: function(supervised, mode) { - // Override the BrowserOptions method to return the fake info. - BrowserOptions.getCurrentProfile = function() { - return this.testProfileInfo_(supervised); - }.bind(this); - // Set the profile info in the overlay. - ManageProfileOverlay.setProfileInfo(this.testProfileInfo_(supervised), - mode); - }, - - /** - * Set some default profile infos (icon URLs and names). - * @param {boolean} supervised Whether the test profile should be marked as - * supervised. - * @param {string} mode The mode of the overlay (either 'manage' or 'create'). - */ - initDefaultProfiles_: function(mode) { - PageManager.showPageByName(mode + 'Profile'); - - var defaultProfile = { - name: 'Default Name', - iconURL: '/default/path', - }; - this.defaultIconURLs = ['/some/path', - defaultProfile.iconURL, - '/another/path', - '/one/more/path']; - this.defaultNames = ['Some Name', defaultProfile.name, '', 'Another Name']; - ManageProfileOverlay.receiveDefaultProfileIconsAndNames( - mode, this.defaultIconURLs, this.defaultNames); - ManageProfileOverlay.receiveNewProfileDefaults(defaultProfile); - - // Make sure the correct item in the icon grid was selected. - var gridEl = $(mode + '-profile-icon-grid'); - expectEquals(defaultProfile.iconURL, gridEl.selectedItem); - }, -}; - -// Receiving the new profile defaults in the manage-user overlay shouldn't mess -// up the focus in a visible higher-level overlay. -TEST_F('ManageProfileUITest', 'NewProfileDefaultsFocus', function() { - var self = this; - - function checkFocus(pageName, expectedFocus, initialFocus) { - PageManager.showPageByName(pageName); - initialFocus.focus(); - expectEquals(initialFocus, document.activeElement, pageName); - - ManageProfileOverlay.receiveNewProfileDefaults( - self.testProfileInfo_(false)); - expectEquals(expectedFocus, document.activeElement, pageName); - PageManager.closeOverlay(); - } - - // Receiving new profile defaults sets focus to the name field if the create - // overlay is open, and should not change focus at all otherwise. - checkFocus('manageProfile', - $('manage-profile-cancel'), - $('manage-profile-cancel')); - checkFocus('createProfile', - $('create-profile-name'), - $('create-profile-cancel')); - checkFocus('supervisedUserLearnMore', - $('supervised-user-learn-more-done'), - $('supervised-user-learn-more-done')); - checkFocus('supervisedUserLearnMore', - document.querySelector('#supervised-user-learn-more-text a'), - document.querySelector('#supervised-user-learn-more-text a')); -}); - -// The default options should be reset each time the creation overlay is shown. -TEST_F('ManageProfileUITest', 'DefaultCreateOptions', function() { - PageManager.showPageByName('createProfile'); - var shortcutsAllowed = loadTimeData.getBoolean('profileShortcutsEnabled'); - var createShortcut = $('create-shortcut'); - var createSupervised = $('create-profile-supervised'); - assertEquals(shortcutsAllowed, createShortcut.checked); - assertFalse(createSupervised.checked); - - createShortcut.checked = !shortcutsAllowed; - createSupervised.checked = true; - PageManager.closeOverlay(); - PageManager.showPageByName('createProfile'); - assertEquals(shortcutsAllowed, createShortcut.checked); - assertFalse(createSupervised.checked); -}); - -// The checkbox label should change depending on whether the user is signed in. -TEST_F('ManageProfileUITest', 'CreateSupervisedUserText', function() { - var signedInText = $('create-profile-supervised-signed-in'); - var notSignedInText = $('create-profile-supervised-not-signed-in'); - - ManageProfileOverlay.getInstance().initializePage(); - - var custodianEmail = 'chrome.playpen.test@gmail.com'; - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - assertEquals(custodianEmail, - CreateProfileOverlay.getInstance().signedInEmail_); - assertFalse(signedInText.hidden); - assertTrue(notSignedInText.hidden); - // Make sure the email is in the string somewhere, without depending on the - // exact details of the message. - assertNotEquals(-1, signedInText.textContent.indexOf(custodianEmail)); - - CreateProfileOverlay.updateSignedInStatus(''); - assertEquals('', CreateProfileOverlay.getInstance().signedInEmail_); - assertTrue(signedInText.hidden); - assertFalse(notSignedInText.hidden); - assertFalse($('create-profile-supervised').checked); - assertTrue($('create-profile-supervised').disabled); -}); - -function ManageProfileUITestAsync() {} - -ManageProfileUITestAsync.prototype = { - __proto__: ManageProfileUITest.prototype, - - isAsync: true, -}; - -// The import link should show up if the user tries to create a profile with the -// same name as an existing supervised user profile. -TEST_F('ManageProfileUITestAsync', 'CreateExistingSupervisedUser', function() { - // Initialize the list of existing supervised users. - var supervisedUsers = [ - { - id: 'supervisedUser1', - name: 'Rosalie', - iconURL: 'chrome://path/to/icon/image', - onCurrentDevice: false, - needAvatar: false - }, - { - id: 'supervisedUser2', - name: 'Fritz', - iconURL: 'chrome://path/to/icon/image', - onCurrentDevice: false, - needAvatar: true - }, - { - id: 'supervisedUser3', - name: 'Test', - iconURL: 'chrome://path/to/icon/image', - onCurrentDevice: true, - needAvatar: false - }, - { - id: 'supervisedUser4', - name: 'RepeatingName', - iconURL: 'chrome://path/to/icon/image', - onCurrentDevice: true, - needAvatar: false - }, - { - id: 'supervisedUser5', - name: 'RepeatingName', - iconURL: 'chrome://path/to/icon/image', - onCurrentDevice: false, - needAvatar: false - }]; - var promise = Promise.resolve(supervisedUsers); - options.SupervisedUserListData.getInstance().promise_ = promise; - - // Initialize the ManageProfileOverlay. - ManageProfileOverlay.getInstance().initializePage(); - var custodianEmail = 'chrome.playpen.test@gmail.com'; - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - assertEquals(custodianEmail, - CreateProfileOverlay.getInstance().signedInEmail_); - this.setProfileSupervised_(false, 'create'); - - // Also add the names 'Test' and 'RepeatingName' to |existingProfileNames_| to - // simulate that profiles with those names exist on the device. - ManageProfileOverlay.getInstance().existingProfileNames_.Test = true; - ManageProfileOverlay.getInstance().existingProfileNames_.RepeatingName = true; - - // Initially, the ok button should be enabled and the import link should not - // exist. - assertFalse($('create-profile-ok').disabled); - assertTrue($('supervised-user-import-existing') == null); - - // Now try to create profiles with the names of existing supervised users. - $('create-profile-supervised').checked = true; - var nameField = $('create-profile-name'); - // A profile which already has an avatar. - nameField.value = 'Rosalie'; - ManageProfileOverlay.getInstance().onNameChanged_('create'); - // Need to wait until the promise resolves. - promise.then(function() { - assertTrue($('create-profile-ok').disabled); - assertFalse($('supervised-user-import-existing') == null); - - // A profile which doesn't have an avatar yet. - nameField.value = 'Fritz'; - ManageProfileOverlay.getInstance().onNameChanged_('create'); - return options.SupervisedUserListData.getInstance().promise_; - }).then(function() { - assertTrue($('create-profile-ok').disabled); - assertFalse($('supervised-user-import-existing') == null); - - // A profile which already exists on the device. - nameField.value = 'Test'; - ManageProfileOverlay.getInstance().onNameChanged_('create'); - return options.SupervisedUserListData.getInstance().promise_; - }).then(function() { - assertTrue($('create-profile-ok').disabled); - assertTrue($('supervised-user-import-existing') == null); - - // A supervised user profile that is on the device, but has the same name - // as a supervised user profile that is not imported. - // This can happen due to a bug (https://crbug.com/557445) - nameField.value = 'RepeatingName'; - ManageProfileOverlay.getInstance().onNameChanged_('create'); - return options.SupervisedUserListData.getInstance().promise_; - }).then(function() { - assertTrue($('create-profile-ok').disabled); - assertFalse($('supervised-user-import-existing') == null); - - // A profile which does not exist yet. - nameField.value = 'NewProfileName'; - ManageProfileOverlay.getInstance().onNameChanged_('create'); - return options.SupervisedUserListData.getInstance().promise_; - }).then(function() { - assertFalse($('create-profile-ok').disabled); - assertTrue($('supervised-user-import-existing') == null); - testDone(); - }); -}); - -// Supervised users should not be able to edit their profile names, and the -// initial focus should be adjusted accordingly. -TEST_F('ManageProfileUITest', 'EditSupervisedUserNameAllowed', function() { - var nameField = $('manage-profile-name'); - - this.setProfileSupervised_(false, 'manage'); - ManageProfileOverlay.showManageDialog(); - expectFalse(nameField.disabled); - expectEquals(nameField, document.activeElement); - - PageManager.closeOverlay(); - - this.setProfileSupervised_(true, 'manage'); - ManageProfileOverlay.showManageDialog(); - expectTrue(nameField.disabled); - expectEquals($('manage-profile-ok'), document.activeElement); -}); - -// Setting profile information should allow the confirmation to be shown. -TEST_F('ManageProfileUITest', 'ShowCreateConfirmation', function() { - var testProfile = this.testProfileInfo_(true); - testProfile.custodianEmail = 'foo@bar.example.com'; - SupervisedUserCreateConfirmOverlay.setProfileInfo(testProfile); - assertTrue(SupervisedUserCreateConfirmOverlay.getInstance().canShowPage()); - PageManager.showPageByName('supervisedUserCreateConfirm', false); - assertEquals('supervisedUserCreateConfirm', - PageManager.getTopmostVisiblePage().name); -}); - -// Trying to show a confirmation dialog with no profile information should fall -// back to the default (main) settings page. -TEST_F('ManageProfileUITest', 'NoEmptyConfirmation', function() { - assertEquals('manageProfile', PageManager.getTopmostVisiblePage().name); - assertFalse(SupervisedUserCreateConfirmOverlay.getInstance().canShowPage()); - PageManager.showPageByName('supervisedUserCreateConfirm', true); - assertEquals('settings', PageManager.getTopmostVisiblePage().name); -}); - -// A confirmation dialog should be shown after creating a new supervised user. -TEST_F('ManageProfileUITest', 'ShowCreateConfirmationOnSuccess', function() { - PageManager.showPageByName('createProfile'); - assertEquals('createProfile', PageManager.getTopmostVisiblePage().name); - CreateProfileOverlay.onSuccess(this.testProfileInfo_(false)); - assertEquals('settings', PageManager.getTopmostVisiblePage().name); - - PageManager.showPageByName('createProfile'); - assertEquals('createProfile', PageManager.getTopmostVisiblePage().name); - CreateProfileOverlay.onSuccess(this.testProfileInfo_(true)); - assertEquals('supervisedUserCreateConfirm', - PageManager.getTopmostVisiblePage().name); - expectEquals($('supervised-user-created-switch'), document.activeElement); -}); - -// An error should be shown if creating a new supervised user fails. -TEST_F('ManageProfileUITest', 'NoCreateConfirmationOnError', function() { - PageManager.showPageByName('createProfile'); - assertEquals('createProfile', PageManager.getTopmostVisiblePage().name); - var errorBubble = $('create-profile-error-bubble'); - assertTrue(errorBubble.hidden); - - CreateProfileOverlay.onError('An Error Message!'); - assertEquals('createProfile', PageManager.getTopmostVisiblePage().name); - assertFalse(errorBubble.hidden); -}); - -// The name and email should be inserted into the confirmation dialog. -TEST_F('ManageProfileUITest', 'CreateConfirmationText', function() { - var self = this; - var custodianEmail = 'foo@example.com'; - - // Checks the strings in the confirmation dialog. If |expectedNameText| is - // given, it should be present in the dialog's textContent; otherwise the name - // is expected. If |expectedNameHtml| is given, it should be present in the - // dialog's innerHTML; otherwise the expected text is expected in the HTML - // too. - function checkDialog(name, expectedNameText, expectedNameHtml) { - var expectedText = expectedNameText || name; - var expectedHtml = expectedNameHtml || expectedText; - - // Configure the test profile and show the confirmation dialog. - var testProfile = self.testProfileInfo_(true); - testProfile.name = name; - CreateProfileOverlay.onSuccess(testProfile); - assertEquals('supervisedUserCreateConfirm', - PageManager.getTopmostVisiblePage().name); - - // Check for the presence of the name and email in the UI, without depending - // on the details of the messages. - assertNotEquals(-1, - $('supervised-user-created-title').textContent.indexOf(expectedText)); - assertNotEquals(-1, - $('supervised-user-created-switch').textContent.indexOf(expectedText)); - var message = $('supervised-user-created-text'); - assertNotEquals(-1, message.textContent.indexOf(expectedText)); - assertNotEquals(-1, message.textContent.indexOf(custodianEmail)); - - // The name should be properly HTML-escaped. - assertNotEquals(-1, message.innerHTML.indexOf(expectedHtml)); - - PageManager.closeOverlay(); - assertEquals('settings', PageManager.getTopmostVisiblePage().name, name); - } - - // Show and configure the create-profile dialog. - PageManager.showPageByName('createProfile'); - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - assertEquals('createProfile', PageManager.getTopmostVisiblePage().name); - - checkDialog('OneWord'); - checkDialog('Multiple Words'); - checkDialog('It\'s "<HTML> injection" & more!', - 'It\'s "<HTML> injection" & more!', - // The innerHTML getter doesn't escape quotation marks, - // independent of whether they were escaped in the setter. - 'It\'s "<HTML> injection" & more!'); - - // Test elision. MAX_LENGTH = 50, minus 1 for the ellipsis. - var name49Characters = '0123456789012345678901234567890123456789012345678'; - var name50Characters = name49Characters + '9'; - var name51Characters = name50Characters + '0'; - var name60Characters = name51Characters + '123456789'; - checkDialog(name49Characters, name49Characters); - checkDialog(name50Characters, name50Characters); - checkDialog(name51Characters, name49Characters + '\u2026'); - checkDialog(name60Characters, name49Characters + '\u2026'); - - // Test both elision and HTML escaping. The allowed string length is the - // visible length, not the length including the entity names. - name49Characters = name49Characters.replace('0', '&').replace('1', '>'); - name60Characters = name60Characters.replace('0', '&').replace('1', '>'); - var escaped = name49Characters.replace('&', '&').replace('>', '>'); - checkDialog( - name60Characters, name49Characters + '\u2026', escaped + '\u2026'); -}); - -// The confirmation dialog should close if the new supervised user is deleted. -TEST_F('ManageProfileUITest', 'CloseConfirmationOnDelete', function() { - // Configure the test profile and show the confirmation dialog. - var testProfile = this.testProfileInfo_(true); - CreateProfileOverlay.onSuccess(testProfile); - assertEquals('supervisedUserCreateConfirm', - PageManager.getTopmostVisiblePage().name); - - SupervisedUserCreateConfirmOverlay.onDeletedProfile(testProfile.filePath); - assertEquals('settings', PageManager.getTopmostVisiblePage().name, name); -}); - -// The confirmation dialog should update if the new supervised user's name is -// changed. -TEST_F('ManageProfileUITest', 'UpdateConfirmationOnRename', function() { - // Configure the test profile and show the confirmation dialog. - var testProfile = this.testProfileInfo_(true); - CreateProfileOverlay.onSuccess(testProfile); - assertEquals('supervisedUserCreateConfirm', - PageManager.getTopmostVisiblePage().name); - - var oldName = testProfile.name; - var newName = 'New Name'; - SupervisedUserCreateConfirmOverlay.onUpdatedProfileName(testProfile.filePath, - newName); - assertEquals('supervisedUserCreateConfirm', - PageManager.getTopmostVisiblePage().name); - - var titleElement = $('supervised-user-created-title'); - var switchElement = $('supervised-user-created-switch'); - var messageElement = $('supervised-user-created-text'); - - assertEquals(-1, titleElement.textContent.indexOf(oldName)); - assertEquals(-1, switchElement.textContent.indexOf(oldName)); - assertEquals(-1, messageElement.textContent.indexOf(oldName)); - - assertNotEquals(-1, titleElement.textContent.indexOf(newName)); - assertNotEquals(-1, switchElement.textContent.indexOf(newName)); - assertNotEquals(-1, messageElement.textContent.indexOf(newName)); -}); - -// An additional warning should be shown when deleting a supervised user. -TEST_F('ManageProfileUITest', 'DeleteSupervisedUserWarning', function() { - var addendum = $('delete-supervised-profile-addendum'); - - ManageProfileOverlay.showDeleteDialog(this.testProfileInfo_(true)); - assertFalse(addendum.hidden); - - ManageProfileOverlay.showDeleteDialog(this.testProfileInfo_(false)); - assertTrue(addendum.hidden); -}); - -// The policy prohibiting supervised users should update the UI dynamically. -TEST_F('ManageProfileUITest', 'PolicyDynamicRefresh', function() { - ManageProfileOverlay.getInstance().initializePage(); - - var custodianEmail = 'chrome.playpen.test@gmail.com'; - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - CreateProfileOverlay.updateSupervisedUsersAllowed(true); - var checkbox = $('create-profile-supervised'); - var signInPromo = $('create-profile-supervised-not-signed-in'); - var signInLink = $('create-profile-supervised-sign-in-link'); - var indicator = $('create-profile-supervised-indicator'); - - assertFalse(checkbox.disabled, 'allowed and signed in'); - assertTrue(signInPromo.hidden, 'allowed and signed in'); - assertEquals('none', window.getComputedStyle(indicator, null).display, - 'allowed and signed in'); - - CreateProfileOverlay.updateSignedInStatus(''); - CreateProfileOverlay.updateSupervisedUsersAllowed(true); - assertTrue(checkbox.disabled, 'allowed, not signed in'); - assertFalse(signInPromo.hidden, 'allowed, not signed in'); - assertTrue(signInLink.enabled, 'allowed, not signed in'); - assertEquals('none', window.getComputedStyle(indicator, null).display, - 'allowed, not signed in'); - - CreateProfileOverlay.updateSignedInStatus(''); - CreateProfileOverlay.updateSupervisedUsersAllowed(false); - assertTrue(checkbox.disabled, 'disallowed, not signed in'); - assertFalse(signInPromo.hidden, 'disallowed, not signed in'); - assertFalse(signInLink.enabled, 'disallowed, not signed in'); - assertEquals('inline-block', window.getComputedStyle(indicator, null).display, - 'disallowed, not signed in'); - assertEquals('policy', indicator.getAttribute('controlled-by')); - - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - CreateProfileOverlay.updateSupervisedUsersAllowed(false); - assertTrue(checkbox.disabled, 'disallowed, signed in'); - assertTrue(signInPromo.hidden, 'disallowed, signed in'); - assertEquals('inline-block', window.getComputedStyle(indicator, null).display, - 'disallowed, signed in'); - assertEquals('policy', indicator.getAttribute('controlled-by')); - - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - CreateProfileOverlay.updateSupervisedUsersAllowed(true); - assertFalse(checkbox.disabled, 're-allowed and signed in'); - assertTrue(signInPromo.hidden, 're-allowed and signed in'); - assertEquals('none', window.getComputedStyle(indicator, null).display, - 're-allowed and signed in'); -}); - -// The supervised user checkbox should correctly update its state during profile -// creation and afterwards. -TEST_F('ManageProfileUITest', 'CreateInProgress', function() { - ManageProfileOverlay.getInstance().initializePage(); - - var custodianEmail = 'chrome.playpen.test@gmail.com'; - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - CreateProfileOverlay.updateSupervisedUsersAllowed(true); - var checkbox = $('create-profile-supervised'); - var signInPromo = $('create-profile-supervised-not-signed-in'); - var indicator = $('create-profile-supervised-indicator'); - - assertFalse(checkbox.disabled, 'allowed and signed in'); - assertTrue(signInPromo.hidden, 'allowed and signed in'); - assertEquals('none', window.getComputedStyle(indicator, null).display, - 'allowed and signed in'); - assertFalse(indicator.hasAttribute('controlled-by')); - - CreateProfileOverlay.updateCreateInProgress(true); - assertTrue(checkbox.disabled, 'creation in progress'); - - // A no-op update to the sign-in status should not change the UI. - CreateProfileOverlay.updateSignedInStatus(custodianEmail); - CreateProfileOverlay.updateSupervisedUsersAllowed(true); - assertTrue(checkbox.disabled, 'creation in progress'); - - CreateProfileOverlay.updateCreateInProgress(false); - assertFalse(checkbox.disabled, 'creation finished'); -}); - -// Supervised users should be able to open the delete dialog, but not the -// create dialog. -TEST_F('ManageProfileUITest', 'SupervisedShowCreate', function() { - this.setProfileSupervised_(false, 'create'); - - ManageProfileOverlay.showCreateDialog(); - assertEquals('createProfile', PageManager.getTopmostVisiblePage().name); - PageManager.closeOverlay(); - assertEquals('settings', PageManager.getTopmostVisiblePage().name); - ManageProfileOverlay.showDeleteDialog(this.testProfileInfo_(false)); - assertEquals('manageProfile', PageManager.getTopmostVisiblePage().name); - assertFalse($('manage-profile-overlay-delete').hidden); - PageManager.closeOverlay(); - assertEquals('settings', PageManager.getTopmostVisiblePage().name); - - this.setProfileSupervised_(true, 'create'); - ManageProfileOverlay.showCreateDialog(); - assertEquals('settings', PageManager.getTopmostVisiblePage().name); - ManageProfileOverlay.showDeleteDialog(this.testProfileInfo_(false)); - assertEquals('manageProfile', PageManager.getTopmostVisiblePage().name); -}); - -// Selecting a different avatar image should update the suggested profile name. -TEST_F('ManageProfileUITest', 'Create_NameUpdateOnAvatarSelected', function() { - var mode = 'create'; - this.initDefaultProfiles_(mode); - - var gridEl = $(mode + '-profile-icon-grid'); - var nameEl = $(mode + '-profile-name'); - - // Select another icon and check that the profile name was updated. - assertNotEquals(gridEl.selectedItem, this.defaultIconURLs[0]); - gridEl.selectedItem = this.defaultIconURLs[0]; - expectEquals(this.defaultNames[0], nameEl.value); - - // Select icon without an associated name; the profile name shouldn't change. - var oldName = nameEl.value; - assertEquals('', this.defaultNames[2]); - gridEl.selectedItem = this.defaultIconURLs[2]; - expectEquals(oldName, nameEl.value); - - // Select another icon with a name and check that the name is updated again. - assertNotEquals('', this.defaultNames[1]); - gridEl.selectedItem = this.defaultIconURLs[1]; - expectEquals(this.defaultNames[1], nameEl.value); - - PageManager.closeOverlay(); -}); - -// After the user edited the profile name, selecting a different avatar image -// should not update the suggested name anymore. -TEST_F('ManageProfileUITest', 'Create_NoNameUpdateOnAvatarSelectedAfterEdit', - function() { - var mode = 'create'; - this.initDefaultProfiles_(mode); - - var gridEl = $(mode + '-profile-icon-grid'); - var nameEl = $(mode + '-profile-name'); - - // After the user manually entered a name, it should not be changed anymore - // (even if the entered name is another default name). - nameEl.value = this.defaultNames[3]; - nameEl.oninput(); - gridEl.selectedItem = this.defaultIconURLs[0]; - expectEquals(this.defaultNames[3], nameEl.value); - - PageManager.closeOverlay(); -}); - -// After the user edited the profile name, selecting a different avatar image -// should not update the suggested name anymore even if the original suggestion -// is entered again. -TEST_F('ManageProfileUITest', 'Create_NoNameUpdateOnAvatarSelectedAfterRevert', - function() { - var mode = 'create'; - this.initDefaultProfiles_(mode); - - var gridEl = $(mode + '-profile-icon-grid'); - var nameEl = $(mode + '-profile-name'); - - // After the user manually entered a name, it should not be changed anymore, - // even if the user then reverts to the original suggestion. - var oldName = nameEl.value; - nameEl.value = 'Custom Name'; - nameEl.oninput(); - nameEl.value = oldName; - nameEl.oninput(); - // Now select another avatar and check that the name remained the same. - assertNotEquals(gridEl.selectedItem, this.defaultIconURLs[0]); - gridEl.selectedItem = this.defaultIconURLs[0]; - expectEquals(oldName, nameEl.value); - - PageManager.closeOverlay(); -}); - -// In the manage dialog, the name should never be updated on avatar selection. -TEST_F('ManageProfileUITest', 'Manage_NoNameUpdateOnAvatarSelected', - function() { - var mode = 'manage'; - this.setProfileSupervised_(false, mode); - PageManager.showPageByName(mode + 'Profile'); - - var testProfile = this.testProfileInfo_(false); - var iconURLs = [testProfile.iconURL, '/some/path', '/another/path']; - var names = [testProfile.name, 'Some Name', '']; - ManageProfileOverlay.receiveDefaultProfileIconsAndNames( - mode, iconURLs, names); - - var gridEl = $(mode + '-profile-icon-grid'); - var nameEl = $(mode + '-profile-name'); - - // Select another icon and check if the profile name was updated. - var oldName = nameEl.value; - gridEl.selectedItem = iconURLs[1]; - expectEquals(oldName, nameEl.value); - - PageManager.closeOverlay(); -}); - -GEN('#endif // OS_CHROMEOS'); diff --git a/chromium/chrome/browser/ui/webui/options/multilanguage_options_browsertest.cc b/chromium/chrome/browser/ui/webui/options/multilanguage_options_browsertest.cc deleted file mode 100644 index 4c95d59f7b9..00000000000 --- a/chromium/chrome/browser/ui/webui/options/multilanguage_options_browsertest.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2015 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 "chrome/browser/ui/webui/options/multilanguage_options_browsertest.h" - -#include <string> - -#include "base/command_line.h" -#include "build/build_config.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" -#include "components/spellcheck/browser/pref_names.h" - -MultilanguageOptionsBrowserTest::MultilanguageOptionsBrowserTest() { -} - -MultilanguageOptionsBrowserTest::~MultilanguageOptionsBrowserTest() { -} - -void MultilanguageOptionsBrowserTest::ClearSpellcheckDictionaries() { - SetDictionariesPref(base::ListValue()); -} - -void MultilanguageOptionsBrowserTest::SetUpOnMainThread() { - WebUIBrowserTest::SetUpOnMainThread(); -#if defined(OS_CHROMEOS) - std::string setting_name = prefs::kLanguagePreferredLanguages; -#else - std::string setting_name = prefs::kAcceptLanguages; -#endif - - PrefService* pref_service = browser()->profile()->GetPrefs(); - pref_service->SetString(setting_name, "fr,es,de,en"); - base::ListValue dictionaries; - dictionaries.AppendString("fr"); - SetDictionariesPref(dictionaries); - pref_service->SetString(spellcheck::prefs::kSpellCheckDictionary, - std::string()); -} - -void MultilanguageOptionsBrowserTest::SetDictionariesPref( - const base::ListValue& value) { - browser()->profile()->GetPrefs()->Set( - spellcheck::prefs::kSpellCheckDictionaries, value); -} diff --git a/chromium/chrome/browser/ui/webui/options/multilanguage_options_browsertest.h b/chromium/chrome/browser/ui/webui/options/multilanguage_options_browsertest.h deleted file mode 100644 index 2ea4c66e0dc..00000000000 --- a/chromium/chrome/browser/ui/webui/options/multilanguage_options_browsertest.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 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 CHROME_BROWSER_UI_WEBUI_OPTIONS_MULTILANGUAGE_OPTIONS_BROWSERTEST_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_MULTILANGUAGE_OPTIONS_BROWSERTEST_H_ - -#include "base/macros.h" -#include "chrome/test/base/web_ui_browser_test.h" - -// This is a helper class used by multilanguage_options_webui_browsertest.js -// to flip the enable-multilingual-spellchecker command line switch and set -// the AcceptLanguages and SpellcheckDictionaries preferences. -class MultilanguageOptionsBrowserTest : public WebUIBrowserTest { - public: - MultilanguageOptionsBrowserTest(); - ~MultilanguageOptionsBrowserTest() override; - // Set the kSpellCheckDictionaries preference to an empty list value. - void ClearSpellcheckDictionaries(); - - private: - // WebUIBrowserTest implementation. - void SetUpOnMainThread() override; - void SetDictionariesPref(const base::ListValue& value); - - DISALLOW_COPY_AND_ASSIGN(MultilanguageOptionsBrowserTest); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_MULTILANGUAGE_OPTIONS_BROWSERTEST_H_ diff --git a/chromium/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js b/chromium/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js deleted file mode 100644 index 222016cd4c6..00000000000 --- a/chromium/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2015 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. - -GEN_INCLUDE(['options_browsertest_base.js']); -GEN('#include "chrome/browser/ui/webui/options/' + - 'multilanguage_options_browsertest.h"'); - -/** - * Test C++ fixture for Language Options WebUI testing. - * @constructor - * @extends {testing.Test} - */ -function MultilanguageOptionsWebUIBrowserTest() {} - -MultilanguageOptionsWebUIBrowserTest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/languages', - - /** @override */ - typedefCppFixture: 'MultilanguageOptionsBrowserTest', - - /** @override */ - accessibilityIssuesAreErrors: true, - - /** @param {string} expected Sorted currently selected languages. */ - expectCurrentlySelected: function(expected) { - var languages = LanguageOptions.getInstance().spellCheckLanguages_; - expectEquals(expected, Object.keys(languages).sort().join()); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - assertFalse(cr.isMac); - expectFalse($('edit-custom-dictionary-button').hidden); - this.expectEnableSpellcheckCheckboxVisible(); - this.expectCurrentlySelected('fr'); - - var requiredOwnedAriaRoleMissingSelectors = [ - '#default-search-engine-list', - '#other-search-engine-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_08: http://crbug.com/559320 - this.accessibilityAuditConfig.ignoreSelectors( - 'requiredOwnedAriaRoleMissing', - requiredOwnedAriaRoleMissingSelectors); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/559266 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#language-options-list'); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/559271 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#languagePage > .content-area > .language-options-header > A'); - }, - - /** @override */ - tearDown: function() { - testing.Test.prototype.tearDown.call(this); - this.expectEnableSpellcheckCheckboxVisible(); - }, - - /** Make sure the 'Enable spell checking' checkbox is visible. */ - expectEnableSpellcheckCheckboxVisible: function() { - if ($('enable-spellcheck-container')) - expectFalse($('enable-spellcheck-container').hidden); - }, -}; - -// Test that opening language options has the correct location. -TEST_F('MultilanguageOptionsWebUIBrowserTest', 'TestOpenLanguageOptions', - function() { - expectEquals('chrome://settings-frame/languages', document.location.href); -}); - -// Test that only certain languages can be selected and used for spellchecking. -// prefs::kLanguagePreferredLanguages/prefs::kAcceptLanguages is set to -// 'fr,es,de,en' and prefs::kSpellCheckDictionaries is just 'fr' -TEST_F('MultilanguageOptionsWebUIBrowserTest', 'ChangeSpellcheckLanguages', - function() { - expectTrue($('language-options-list').selectLanguageByCode('es')); - expectFalse($('spellcheck-language-checkbox').checked, 'es'); - - // Click 'es' and ensure that it gets checked and 'fr' stays checked. - $('spellcheck-language-checkbox').click(); - expectTrue($('spellcheck-language-checkbox').checked, 'es'); - expectTrue($('language-options-list').selectLanguageByCode('fr')); - expectTrue($('spellcheck-language-checkbox').checked, 'fr'); - this.expectCurrentlySelected('es,fr'); - - // Click 'fr' and ensure that it gets unchecked and 'es' stays checked. - $('spellcheck-language-checkbox').click(); - expectFalse($('spellcheck-language-checkbox').checked, 'fr'); - $('language-options-list').selectLanguageByCode('es'); - expectTrue($('spellcheck-language-checkbox').checked, 'es'); - this.expectCurrentlySelected('es'); -}); - -// Make sure 'am' cannot be selected as a language and 'fr' stays selected. -TEST_F('MultilanguageOptionsWebUIBrowserTest', 'NotAcceptLanguage', function() { - expectFalse($('language-options-list').selectLanguageByCode('am')); - expectTrue($('language-options-list').selectLanguageByCode('fr')); - expectTrue($('spellcheck-language-checkbox').checked, 'fr'); - this.expectCurrentlySelected('fr'); -}); - -// Make sure 'en' cannot be used as a language and 'fr' stays selected. -TEST_F('MultilanguageOptionsWebUIBrowserTest', 'UnusableLanguage', function() { - expectTrue($('language-options-list').selectLanguageByCode('en')); - expectTrue($('spellcheck-language-checkbox-container').hidden); - expectFalse($('spellcheck-language-checkbox').checked, 'en'); - this.expectCurrentlySelected('fr'); -}); - -/** - * Test C++ fixture for Language Options WebUI testing. - * @constructor - * @extends {MultilanguageOptionsWebUIBrowserTest} - */ -function MultilanguagePreferenceWebUIBrowserTest() {} - -MultilanguagePreferenceWebUIBrowserTest.prototype = { - __proto__: MultilanguageOptionsWebUIBrowserTest.prototype, - - /** @override */ - testGenPreamble: function() { - GEN('ClearSpellcheckDictionaries();'); - }, - - /** @override */ - isAsync: true, - - /** - * @param {string} expected Sorted languages in the kSpellCheckDictionaries - * preference. - */ - expectRegisteredDictionariesPref: function(expected) { - var registeredPrefs = - options.Preferences.getInstance().registeredPreferences_; - expectEquals(expected, - registeredPrefs['spellcheck.dictionaries'].orig.value.sort().join()); - }, - - /** - * Watch for a change to the preference |pref| and then call |callback|. - * @param {string} pref The preference to listen for a change on. - * @param {function} callback The function to run after a listener event. - */ - addPreferenceListener: function(pref, callback) { - options.Preferences.getInstance().addEventListener(pref, callback); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - assertFalse(cr.isMac); - expectTrue($('edit-custom-dictionary-button').hidden); - this.expectEnableSpellcheckCheckboxVisible(); - this.expectCurrentlySelected(''); - this.expectRegisteredDictionariesPref(''); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/559266 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#language-options-list'); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/559271 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#languagePage > .content-area > .language-options-header > A'); - - // Enable when failure is resolved. - // AX_FOCUS_01: http://crbug.com/570046 - this.accessibilityAuditConfig.ignoreSelectors( - 'focusableElementNotVisibleAndNotAriaHidden', - '#offer-to-translate-in-this-language'); - }, -}; - -// Make sure the case where no languages are selected is handled properly. -TEST_F('MultilanguagePreferenceWebUIBrowserTest', 'SelectFromBlank', - function() { - expectTrue($('language-options-list').selectLanguageByCode('fr')); - expectFalse($('spellcheck-language-checkbox').checked, 'fr'); - expectTrue($('edit-custom-dictionary-button').hidden); - - // Add a preference change event listener which ensures that the preference is - // updated correctly and that 'fr' is the only thing in the dictionary object. - this.addPreferenceListener('spellcheck.dictionaries', function() { - expectTrue($('spellcheck-language-checkbox').checked, 'fr'); - this.expectRegisteredDictionariesPref('fr'); - this.expectCurrentlySelected('fr'); - expectFalse($('edit-custom-dictionary-button').hidden); - testDone(); - }.bind(this)); - - // Click 'fr' and trigger the preference listener. - $('spellcheck-language-checkbox').click(); -}); diff --git a/chromium/chrome/browser/ui/webui/options/options_browsertest.cc b/chromium/chrome/browser/ui/webui/options/options_browsertest.cc deleted file mode 100644 index 6eca2fc2dff..00000000000 --- a/chromium/chrome/browser/ui/webui/options/options_browsertest.cc +++ /dev/null @@ -1,70 +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. - -#include "chrome/browser/ui/webui/options/options_browsertest.h" - -#include "base/bind.h" -#include "base/values.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "url/gurl.h" - -using content::NavigationController; -using content::NavigationEntry; -using content::WebUIMessageHandler; - -OptionsBrowserTest::OptionsBrowserTest() { -} - -OptionsBrowserTest::~OptionsBrowserTest() { -} - -void OptionsBrowserTest::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "optionsTestReportHistory", base::Bind(&OptionsBrowserTest::ReportHistory, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "optionsTestSetPref", base::Bind(&OptionsBrowserTest::HandleSetPref, - base::Unretained(this))); -} - -// Includes the current entry. -void OptionsBrowserTest::ReportHistory(const base::ListValue* list_value) { - const NavigationController& controller = - browser()->tab_strip_model()->GetActiveWebContents()->GetController(); - base::ListValue history; - const int current = controller.GetCurrentEntryIndex(); - for (int i = 0; i <= current; ++i) { - GURL url = controller.GetEntryAtIndex(i)->GetVirtualURL(); - history.AppendString(url.spec()); - } - web_ui()->CallJavascriptFunctionUnsafe( - "OptionsWebUIExtendedTest.verifyHistoryCallback", history); -} - -void OptionsBrowserTest::ClearPref(const char* path) { - browser()->profile()->GetPrefs()->ClearPref(path); -} - -void OptionsBrowserTest::HandleSetPref(const base::ListValue* args) { - ASSERT_EQ(2u, args->GetSize()); - - std::string pref_name; - ASSERT_TRUE(args->GetString(0, &pref_name)); - const base::Value* pref_value; - ASSERT_TRUE(args->Get(1, &pref_value)); - - browser()->profile()->GetPrefs()->Set(pref_name.c_str(), *pref_value); -} - -content::WebUIMessageHandler* OptionsBrowserTest::GetMockMessageHandler() { - return this; -} diff --git a/chromium/chrome/browser/ui/webui/options/options_browsertest.h b/chromium/chrome/browser/ui/webui/options/options_browsertest.h deleted file mode 100644 index d8135a81dd7..00000000000 --- a/chromium/chrome/browser/ui/webui/options/options_browsertest.h +++ /dev/null @@ -1,45 +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 CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_BROWSERTEST_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_BROWSERTEST_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/test/base/web_ui_browser_test.h" -#include "content/public/browser/web_ui_message_handler.h" - -// This is a helper class used by options_browsertest.js to feed the navigation -// history back to the test. -class OptionsBrowserTest : public WebUIBrowserTest, - public content::WebUIMessageHandler { - public: - OptionsBrowserTest(); - ~OptionsBrowserTest() override; - - protected: - // Clears the preference at the given |path|. - void ClearPref(const char* path); - - private: - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // WebUIBrowserTest implementation. - content::WebUIMessageHandler* GetMockMessageHandler() override; - - // A callback for the 'optionsTestReportHistory' message, this sends the - // URLs in the "back" tab history, including the current entry, back to the - // WebUI via a callback. - void ReportHistory(const base::ListValue* list_value); - - // A callback for the 'optionsTestSetPref' message. The first argument should - // be a pref path (e.g., "profile.managed_users"); the second, the new value - // to set for that pref. - void HandleSetPref(const base::ListValue* args); - - DISALLOW_COPY_AND_ASSIGN(OptionsBrowserTest); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_BROWSERTEST_H_ diff --git a/chromium/chrome/browser/ui/webui/options/options_browsertest.js b/chromium/chrome/browser/ui/webui/options/options_browsertest.js deleted file mode 100644 index 05dfd8c96b3..00000000000 --- a/chromium/chrome/browser/ui/webui/options/options_browsertest.js +++ /dev/null @@ -1,969 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); -GEN('#include "chrome/browser/ui/webui/options/options_browsertest.h"'); - -/** @const */ var SUPERVISED_USERS_PREF = 'profile.managed_users'; - -/** - * Wait for the method specified by |methodName|, on the |object| object, to be - * called, then execute |afterFunction|. - * @param {*} object Object with callable property named |methodName|. - * @param {string} methodName The name of the property on |object| to use as a - * callback. - * @param {!Function} afterFunction A function to call after object.methodName() - * is called. - */ -function waitForResponse(object, methodName, afterFunction) { - var originalCallback = object[methodName]; - - // Install a wrapper that temporarily replaces the original function. - object[methodName] = function() { - object[methodName] = originalCallback; - originalCallback.apply(this, arguments); - afterFunction(); - }; -} - -/** - * Wait for the global window.onpopstate callback to be called (after a tab - * history navigation), then execute |afterFunction|. - * @param {!Function} afterFunction A function to call after pop state events. - */ -function waitForPopstate(afterFunction) { - waitForResponse(window, 'onpopstate', afterFunction); -} - -/** - * TestFixture for OptionsPage WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function OptionsWebUITest() {} - -OptionsWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to the options page & call our preLoad(). - * @override - */ - browsePreload: 'chrome://settings-frame', - - /** @override */ - isAsync: true, - - /** - * Register a mock handler to ensure expectations are met and options pages - * behave correctly. - */ - preLoad: function() { - this.makeAndRegisterMockHandler( - ['defaultZoomFactorAction', - 'fetchPrefs', - 'observePrefs', - 'setBooleanPref', - 'setIntegerPref', - 'setDoublePref', - 'setStringPref', - 'setObjectPref', - 'clearPref', - 'coreOptionsUserMetricsAction', - ]); - - // Register stubs for methods expected to be called before/during tests. - // Specific expectations can be made in the tests themselves. - this.mockHandler.stubs().fetchPrefs(ANYTHING); - this.mockHandler.stubs().observePrefs(ANYTHING); - this.mockHandler.stubs().coreOptionsUserMetricsAction(ANYTHING); - }, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/559329 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#profiles-list'); - - var linkWithUnclearPurposeSelectors = [ - '#sync-overview > A', - '#privacy-explanation > A', - '#languages-section > .settings-row > A', - '#cloudprint-options-mdns > .settings-row > A', - '#cups-printers-section > .settings-row > A', - '#do-not-track-confirm-overlay > .action-area > .hbox.stretch > A', - ]; - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/559318 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - linkWithUnclearPurposeSelectors); - - // Causes testDefaultZoomFactor to flake. See http://crbug.com/611233. - var requiredOwnedAriaRoleMissingSelectors = [ - '#default-search-engine-list', - '#other-search-engine-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_08: http://crbug.com/606657 - this.accessibilityAuditConfig.ignoreSelectors( - 'requiredOwnedAriaRoleMissing', - requiredOwnedAriaRoleMissingSelectors); - }, -}; - -/** - * Wait for all targets to be hidden. - * @param {Array<Element>} targets - */ -function waitUntilHidden(targets) { - function isHidden(el) { return el.hidden; } - function ensureTransition(el) { ensureTransitionEndEvent(el, 500); } - - document.addEventListener('transitionend', function f(e) { - if (targets.indexOf(e.target) >= 0 && targets.every(isHidden)) { - document.removeEventListener(f, 'transitionend'); - testDone(); - } - }); - - targets.forEach(ensureTransition); -} - -// Crashes on Mac only. See http://crbug.com/79181 -GEN('#if defined(OS_MACOSX)'); -GEN('#define MAYBE_testSetBooleanPrefTriggers ' + - 'DISABLED_testSetBooleanPrefTriggers'); -GEN('#else'); -GEN('#define MAYBE_testSetBooleanPrefTriggers testSetBooleanPrefTriggers'); -GEN('#endif // defined(OS_MACOSX)'); - -TEST_F('OptionsWebUITest', 'MAYBE_testSetBooleanPrefTriggers', function() { - // TODO(dtseng): make generic to click all buttons. - var showHomeButton = - document.querySelector('input[pref="browser.show_home_button"]'); - var trueListValue = [ - 'browser.show_home_button', - true, - 'Options_Homepage_HomeButton', - ]; - // Note: this expectation is checked in testing::Test::tearDown. - this.mockHandler.expects(once()).setBooleanPref(trueListValue); - - // Cause the handler to be called. - showHomeButton.click(); - showHomeButton.blur(); - testDone(); -}); - -// Not meant to run on ChromeOS at this time. -// Not finishing in windows. http://crbug.com/81723 -TEST_F('OptionsWebUITest', 'DISABLED_testRefreshStaysOnCurrentPage', - function() { - assertTrue($('search-engine-manager-page').hidden); - var item = $('manage-default-search-engines'); - item.click(); - - assertFalse($('search-engine-manager-page').hidden); - - window.location.reload(); - - assertEquals('chrome://settings-frame/searchEngines', document.location.href); - assertFalse($('search-engine-manager-page').hidden); - testDone(); -}); - -/** - * Test the default zoom factor select element. - */ -TEST_F('OptionsWebUITest', 'testDefaultZoomFactor', function() { - // The expected minimum length of the |defaultZoomFactor| element. - var defaultZoomFactorMinimumLength = 10; - // Verify that the zoom factor element exists. - var defaultZoomFactor = $('defaultZoomFactor'); - assertNotEquals(defaultZoomFactor, null); - - // Verify that the zoom factor element has a reasonable number of choices. - expectGE(defaultZoomFactor.options.length, defaultZoomFactorMinimumLength); - - // Simulate a change event, selecting the highest zoom value. Verify that - // the javascript handler was invoked once. - this.mockHandler.expects(once()).defaultZoomFactorAction(NOT_NULL). - will(callFunction(function() { })); - defaultZoomFactor.selectedIndex = defaultZoomFactor.options.length - 1; - var event = {target: defaultZoomFactor}; - if (defaultZoomFactor.onchange) defaultZoomFactor.onchange(event); - testDone(); -}); - -/** - * If |confirmInterstitial| is true, the OK button of the Do Not Track - * interstitial is pressed, otherwise the abort button is pressed. - * @param {boolean} confirmInterstitial Whether to confirm the Do Not Track - * interstitial. - */ -OptionsWebUITest.prototype.testDoNotTrackInterstitial = - function(confirmInterstitial) { - Preferences.prefsFetchedCallback({'enable_do_not_track': {'value': false}}); - var buttonToClick = confirmInterstitial ? $('do-not-track-confirm-ok') : - $('do-not-track-confirm-cancel'); - var dntCheckbox = $('do-not-track-enabled'); - var dntOverlay = PageManager.registeredOverlayPages['donottrackconfirm']; - assertFalse(dntCheckbox.checked); - - var visibleChangeCounter = 0; - var visibleChangeHandler = function() { - ++visibleChangeCounter; - switch (visibleChangeCounter) { - case 1: - window.setTimeout(function() { - assertTrue(dntOverlay.visible); - buttonToClick.click(); - }, 0); - break; - case 2: - window.setTimeout(function() { - assertFalse(dntOverlay.visible); - assertEquals(confirmInterstitial, dntCheckbox.checked); - dntOverlay.removeEventListener('visibleChange', visibleChangeHandler); - testDone(); - }, 0); - break; - default: - assertTrue(false); - } - }; - dntOverlay.addEventListener('visibleChange', visibleChangeHandler); - - if (confirmInterstitial) { - this.mockHandler.expects(once()).setBooleanPref( - ['enable_do_not_track', true, 'Options_DoNotTrackCheckbox']); - } else { - // The mock handler complains if setBooleanPref is called even though - // it should not be. - } - - dntCheckbox.click(); -}; - -TEST_F('OptionsWebUITest', 'EnableDoNotTrackAndConfirmInterstitial', - function() { - this.testDoNotTrackInterstitial(true); -}); - -TEST_F('OptionsWebUITest', 'EnableDoNotTrackAndCancelInterstitial', - function() { - this.testDoNotTrackInterstitial(false); -}); - -// Check that the "Do not Track" preference can be correctly disabled. -// In order to do that, we need to enable it first. -TEST_F('OptionsWebUITest', 'EnableAndDisableDoNotTrack', function() { - Preferences.prefsFetchedCallback({'enable_do_not_track': {'value': false}}); - var dntCheckbox = $('do-not-track-enabled'); - var dntOverlay = PageManager.registeredOverlayPages.donottrackconfirm; - assertFalse(dntCheckbox.checked); - - var visibleChangeCounter = 0; - var visibleChangeHandler = function() { - ++visibleChangeCounter; - switch (visibleChangeCounter) { - case 1: - window.setTimeout(function() { - assertTrue(dntOverlay.visible); - $('do-not-track-confirm-ok').click(); - }, 0); - break; - case 2: - window.setTimeout(function() { - assertFalse(dntOverlay.visible); - assertTrue(dntCheckbox.checked); - dntOverlay.removeEventListener('visibleChange', visibleChangeHandler); - dntCheckbox.click(); - }, 0); - break; - default: - assertNotReached(); - } - }; - dntOverlay.addEventListener('visibleChange', visibleChangeHandler); - - this.mockHandler.expects(once()).setBooleanPref( - eq(['enable_do_not_track', true, 'Options_DoNotTrackCheckbox'])); - - var verifyCorrectEndState = function() { - window.setTimeout(function() { - assertFalse(dntOverlay.visible); - assertFalse(dntCheckbox.checked); - testDone(); - }, 0); - }; - this.mockHandler.expects(once()).setBooleanPref( - eq(['enable_do_not_track', false, 'Options_DoNotTrackCheckbox'])).will( - callFunction(verifyCorrectEndState)); - - dntCheckbox.click(); -}); - -// Fails on chromeos, http://crbug.com/660867 -// Verify that preventDefault() is called on 'Enter' keydown events that trigger -// the default button. If this doesn't happen, other elements that may get -// focus (by the overlay closing for instance), will execute in addition to the -// default button. See crbug.com/268336. -TEST_F('OptionsWebUITest', 'DISABLED_EnterPreventsDefault', function() { - var page = HomePageOverlay.getInstance(); - PageManager.showPageByName(page.name); - var event = new KeyboardEvent('keydown', { - 'bubbles': true, - 'cancelable': true, - 'key': 'Enter' - }); - assertFalse(event.defaultPrevented); - page.pageDiv.dispatchEvent(event); - assertTrue(event.defaultPrevented); - testDone(); -}); - -// Verifies that sending an empty list of indexes to move doesn't crash chrome. -TEST_F('OptionsWebUITest', 'emptySelectedIndexesDoesntCrash', function() { - chrome.send('dragDropStartupPage', [0, []]); - setTimeout(testDone); -}); - -// This test turns out to be flaky on all platforms. -// See http://crbug.com/315250. - -// An overlay's position should remain the same as it shows. -TEST_F('OptionsWebUITest', 'DISABLED_OverlayShowDoesntShift', function() { - var overlayName = 'startup'; - var overlay = $('startup-overlay'); - var frozenPages = document.getElementsByClassName('frozen'); // Gets updated. - expectEquals(0, frozenPages.length); - - document.addEventListener('transitionend', function(e) { - if (e.target != overlay) - return; - - assertFalse(overlay.classList.contains('transparent')); - expectEquals(numFrozenPages, frozenPages.length); - testDone(); - }); - - PageManager.showPageByName(overlayName); - var numFrozenPages = frozenPages.length; - expectGT(numFrozenPages, 0); -}); - -GEN('#if defined(OS_CHROMEOS)'); -// Verify that range inputs respond to touch events. Currently only Chrome OS -// uses slider options. -TEST_F('OptionsWebUITest', 'RangeInputHandlesTouchEvents', function() { - this.mockHandler.expects(once()).setIntegerPref([ - 'settings.touchpad.sensitivity2', 1]); - - var touchpadRange = $('touchpad-sensitivity-range'); - var event = document.createEvent('UIEvent'); - event.initUIEvent('touchstart', true, true, window); - touchpadRange.dispatchEvent(event); - - event = document.createEvent('UIEvent'); - event.initUIEvent('touchmove', true, true, window); - touchpadRange.dispatchEvent(event); - - touchpadRange.value = 1; - - event = document.createEvent('UIEvent'); - event.initUIEvent('touchend', true, true, window); - touchpadRange.dispatchEvent(event); - - // touchcancel should also trigger the handler, since it - // changes the slider position. - this.mockHandler.expects(once()).setIntegerPref([ - 'settings.touchpad.sensitivity2', 2]); - - event = document.createEvent('UIEvent'); - event.initUIEvent('touchstart', true, true, window); - touchpadRange.dispatchEvent(event); - - touchpadRange.value = 2; - - event = document.createEvent('UIEvent'); - event.initUIEvent('touchcancel', true, true, window); - touchpadRange.dispatchEvent(event); - - testDone(); -}); -GEN('#endif'); // defined(OS_CHROMEOS) - -/** - * TestFixture for OptionsPage WebUI testing including tab history and support - * for preference manipulation. If you don't need the features in the C++ - * fixture, use the simpler OptionsWebUITest (above) instead. - * @extends {testing.Test} - * @constructor - */ -function OptionsWebUIExtendedTest() {} - -OptionsWebUIExtendedTest.prototype = { - __proto__: OptionsWebUITest.prototype, - - /** @override */ - typedefCppFixture: 'OptionsBrowserTest', - - /** @override */ - setUp: function() { - OptionsWebUITest.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/559329 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#profiles-list'); - - var controlsWithoutLabelSelectors = [ - '#cookies-view-page > .content-area.cookies-list-content-area > *', - '#other-search-engine-list > .deletable-item > DIV > *', - ]; - - // Enable when failure is resolved. - // AX_TEXT_01: http://crbug.com/559330 - this.accessibilityAuditConfig.ignoreSelectors( - 'controlsWithoutLabel', - controlsWithoutLabelSelectors); - - var linkWithUnclearPurposeSelectors = [ - '#sync-overview > A', - '#privacy-explanation > A', - '#languages-section > .settings-row > A', - '#cloudprint-options-mdns > .settings-row > A', - // Selectors below only affect ChromeOS tests. - '#privacy-section > DIV > DIV:nth-of-type(9) > A', - '#accessibility-learn-more', - ]; - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/559326 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - linkWithUnclearPurposeSelectors); - - var requiredOwnedAriaRoleMissingSelectors = [ - '#default-search-engine-list', - '#other-search-engine-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_08: http://crbug.com/605689 - this.accessibilityAuditConfig.ignoreSelectors( - 'requiredOwnedAriaRoleMissing', - requiredOwnedAriaRoleMissingSelectors); - }, - - testGenPreamble: function() { - // Start with no supervised users managed by this profile. - GEN(' ClearPref("' + SUPERVISED_USERS_PREF + '");'); - }, - - /** - * Asserts that two non-nested arrays are equal. The arrays must contain only - * plain data types, no nested arrays or other objects. - * @param {Array} expected An array of expected values. - * @param {Array} result An array of actual values. - * @param {boolean} doSort If true, the arrays will be sorted before being - * compared. - * @param {string} description A brief description for the array of actual - * values, to use in an error message if the arrays differ. - * @private - */ - compareArrays_: function(expected, result, doSort, description) { - var errorMessage = '\n' + description + ': ' + result + - '\nExpected: ' + expected; - assertEquals(expected.length, result.length, errorMessage); - - var expectedSorted = expected.slice(); - var resultSorted = result.slice(); - if (doSort) { - expectedSorted.sort(); - resultSorted.sort(); - } - - for (var i = 0; i < expectedSorted.length; ++i) { - assertEquals(expectedSorted[i], resultSorted[i], errorMessage); - } - }, - - /** - * Verifies that the correct pages are currently open/visible. - * @param {!Array<string>} expectedPages An array of page names expected to - * be open, with the topmost listed last. - * @param {string=} opt_expectedUrl The URL path, including hash, expected to - * be open. If undefined, the topmost (last) page name in |expectedPages| - * will be used. In either case, 'chrome://settings-frame/' will be - * prepended. - * @private - */ - verifyOpenPages_: function(expectedPages, opt_expectedUrl) { - // Check the topmost page. - expectEquals(null, PageManager.getVisibleBubble()); - var currentPage = PageManager.getTopmostVisiblePage(); - - var lastExpected = expectedPages[expectedPages.length - 1]; - expectEquals(lastExpected, currentPage.name); - // We'd like to check the title too, but we have to load the settings-frame - // instead of the outer settings page in order to have access to - // OptionsPage, and setting the title from within the settings-frame fails - // because of cross-origin access restrictions. - // TODO(pamg): Add a test fixture that loads chrome://settings and uses - // UI elements to access sub-pages, so we can test the titles and - // search-page URLs. - var expectedUrl = (typeof opt_expectedUrl == 'undefined') ? - lastExpected : opt_expectedUrl; - var fullExpectedUrl = 'chrome://settings-frame/' + expectedUrl; - expectEquals(fullExpectedUrl, window.location.href); - - // Collect open pages. - var allPageNames = Object.keys(PageManager.registeredPages).concat( - Object.keys(PageManager.registeredOverlayPages)); - var openPages = []; - for (var i = 0; i < allPageNames.length; ++i) { - var name = allPageNames[i]; - var page = PageManager.registeredPages[name] || - PageManager.registeredOverlayPages[name]; - if (page.visible) - openPages.push(page.name); - } - - this.compareArrays_(expectedPages, openPages, true, 'Open pages'); - }, - - /* - * Verifies that the correct URLs are listed in the history. Asynchronous. - * @param {!Array<string>} expectedHistory An array of URL paths expected to - * be in the tab navigation history, sorted by visit time, including the - * current page as the last entry. The base URL (chrome://settings-frame/) - * will be prepended to each. An initial 'about:blank' history entry is - * assumed and should not be included in this list. - * @param {Function=} callback A function to be called after the history has - * been verified successfully. May be undefined. - * @private - */ - verifyHistory_: function(expectedHistory, callback) { - var self = this; - OptionsWebUIExtendedTest.verifyHistoryCallback = function(results) { - // The history always starts with a blank page. - assertEquals('about:blank', results.shift()); - var fullExpectedHistory = []; - for (var i = 0; i < expectedHistory.length; ++i) { - fullExpectedHistory.push( - 'chrome://settings-frame/' + expectedHistory[i]); - } - self.compareArrays_(fullExpectedHistory, results, false, 'History'); - callback(); - }; - - // The C++ fixture will call verifyHistoryCallback with the results. - chrome.send('optionsTestReportHistory'); - }, - - /** - * Overrides the page callbacks for the given PageManager overlay to verify - * that they are not called. - * @param {Object} overlay The singleton instance of the overlay. - * @private - */ - prohibitChangesToOverlay_: function(overlay) { - overlay.initializePage = - overlay.didShowPage = - overlay.didClosePage = function() { - assertTrue(false, - 'Overlay was affected when changes were prohibited.'); - }; - }, -}; - -/** - * Set by verifyHistory_ to incorporate a followup callback, then called by the - * C++ fixture with the navigation history to be verified. - * @type {Function} - */ -OptionsWebUIExtendedTest.verifyHistoryCallback = null; - -// Show the search page with no query string, to fall back to the settings page. -// Test disabled because it's flaky. crbug.com/303841 -TEST_F('OptionsWebUIExtendedTest', 'DISABLED_ShowSearchPageNoQuery', - function() { - PageManager.showPageByName('search'); - this.verifyOpenPages_(['settings']); - this.verifyHistory_(['settings'], testDone); -}); - -// Manipulate the search page via the search field. -TEST_F('OptionsWebUIExtendedTest', 'ShowSearchFromField', function() { - $('search-field').onsearch({currentTarget: {value: 'query'}}); - this.verifyOpenPages_(['settings', 'search'], 'search#query'); - this.verifyHistory_(['', 'search#query'], function() { - $('search-field').onsearch({currentTarget: {value: 'query2'}}); - this.verifyOpenPages_(['settings', 'search'], 'search#query2'); - this.verifyHistory_(['', 'search#query', 'search#query2'], function() { - $('search-field').onsearch({currentTarget: {value: ''}}); - this.verifyOpenPages_(['settings'], ''); - this.verifyHistory_(['', 'search#query', 'search#query2', ''], testDone); - }.bind(this)); - }.bind(this)); -}); - -// Show a page without updating history. -TEST_F('OptionsWebUIExtendedTest', 'ShowPageNoHistory', function() { - this.verifyOpenPages_(['settings'], ''); - PageManager.showPageByName('search', true, {hash: '#query'}); - - // The settings page is also still "open" (i.e., visible), in order to show - // the search results. Furthermore, the URL hasn't been updated in the parent - // page, because we've loaded the chrome-settings frame instead of the whole - // settings page, so the cross-origin call to set the URL fails. - this.verifyOpenPages_(['settings', 'search'], 'search#query'); - var self = this; - this.verifyHistory_(['', 'search#query'], function() { - PageManager.showPageByName('settings', false); - self.verifyOpenPages_(['settings'], 'search#query'); - self.verifyHistory_(['', 'search#query'], testDone); - }); -}); - -TEST_F('OptionsWebUIExtendedTest', 'ShowPageWithHistory', function() { - PageManager.showPageByName('search', true, {hash: '#query'}); - var self = this; - this.verifyHistory_(['', 'search#query'], function() { - PageManager.showPageByName('settings', true); - self.verifyOpenPages_(['settings'], ''); - self.verifyHistory_(['', 'search#query', ''], - testDone); - }); -}); - -TEST_F('OptionsWebUIExtendedTest', 'ShowPageReplaceHistory', function() { - PageManager.showPageByName('search', true, {hash: '#query'}); - var self = this; - this.verifyHistory_(['', 'search#query'], function() { - PageManager.showPageByName('settings', true, {'replaceState': true}); - self.verifyOpenPages_(['settings'], ''); - self.verifyHistory_(['', ''], testDone); - }); -}); - -// This should be identical to ShowPageWithHisory. -TEST_F('OptionsWebUIExtendedTest', 'NavigateToPage', function() { - PageManager.showPageByName('search', true, {hash: '#query'}); - var self = this; - this.verifyHistory_(['', 'search#query'], function() { - PageManager.showPageByName('settings'); - self.verifyOpenPages_(['settings'], ''); - self.verifyHistory_(['', 'search#query', ''], testDone); - }); -}); - -// Settings overlays are much more straightforward than settings pages, opening -// normally with none of the latter's quirks in the expected history or URL. -TEST_F('OptionsWebUIExtendedTest', 'ShowOverlayNoHistory', function() { - // Open a layer-1 overlay, not updating history. - PageManager.showPageByName('languages', false); - this.verifyOpenPages_(['settings', 'languages'], ''); - - var self = this; - this.verifyHistory_([''], function() { - // Open a layer-2 overlay for which the layer-1 is a parent, not updating - // history. - PageManager.showPageByName('addLanguage', false); - self.verifyOpenPages_(['settings', 'languages', 'addLanguage'], - ''); - self.verifyHistory_([''], testDone); - }); -}); - -TEST_F('OptionsWebUIExtendedTest', 'ShowOverlayWithHistory', function() { - // Open a layer-1 overlay, updating history. - PageManager.showPageByName('languages', true); - this.verifyOpenPages_(['settings', 'languages']); - - var self = this; - this.verifyHistory_(['', 'languages'], function() { - // Open a layer-2 overlay, updating history. - PageManager.showPageByName('addLanguage', true); - self.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - self.verifyHistory_(['', 'languages', 'addLanguage'], testDone); - }); -}); - -TEST_F('OptionsWebUIExtendedTest', 'ShowOverlayReplaceHistory', function() { - // Open a layer-1 overlay, updating history. - PageManager.showPageByName('languages', true); - var self = this; - this.verifyHistory_(['', 'languages'], function() { - // Open a layer-2 overlay, replacing history. - PageManager.showPageByName('addLanguage', true, {'replaceState': true}); - self.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - self.verifyHistory_(['', 'addLanguage'], testDone); - }); -}); - -// Directly show an overlay further above this page, i.e. one for which the -// current page is an ancestor but not a parent. -TEST_F('OptionsWebUIExtendedTest', 'ShowOverlayFurtherAbove', function() { - // Open a layer-2 overlay directly. - PageManager.showPageByName('addLanguage', true); - this.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - var self = this; - this.verifyHistory_(['', 'addLanguage'], testDone); -}); - -// Directly show a layer-2 overlay for which the layer-1 overlay is not a -// parent. -TEST_F('OptionsWebUIExtendedTest', 'ShowUnrelatedOverlay', function() { - // Open a layer-1 overlay. - PageManager.showPageByName('languages', true); - this.verifyOpenPages_(['settings', 'languages']); - - var self = this; - this.verifyHistory_(['', 'languages'], function() { - // Open an unrelated layer-2 overlay. - PageManager.showPageByName('cookies', true); - self.verifyOpenPages_(['settings', 'content', 'cookies']); - self.verifyHistory_(['', 'languages', 'cookies'], testDone); - }); -}); - -// Close an overlay. -TEST_F('OptionsWebUIExtendedTest', 'CloseOverlay', function() { - // Open a layer-1 overlay, then a layer-2 overlay on top of it. - PageManager.showPageByName('languages', true); - this.verifyOpenPages_(['settings', 'languages']); - PageManager.showPageByName('addLanguage', true); - this.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - - var self = this; - this.verifyHistory_(['', 'languages', 'addLanguage'], function() { - // Close the layer-2 overlay. - PageManager.closeOverlay(); - self.verifyOpenPages_(['settings', 'languages']); - self.verifyHistory_( - ['', 'languages', 'addLanguage', 'languages'], - function() { - // Close the layer-1 overlay. - PageManager.closeOverlay(); - self.verifyOpenPages_(['settings'], ''); - self.verifyHistory_( - ['', 'languages', 'addLanguage', 'languages', ''], - function noop() {}); - waitUntilHidden([$('overlay-container-1'), $('overlay-container-2')]); - }); - }); -}); - -// Hashes are maintained separately for each page and are preserved when -// overlays close. -TEST_F('OptionsWebUIExtendedTest', 'CloseOverlayWithHashes', function() { - // Open an overlay on top of the search page. - PageManager.showPageByName('search', true, {hash: '#1'}); - this.verifyOpenPages_(['settings', 'search'], 'search#1'); - PageManager.showPageByName('languages', true, {hash: '#2'}); - this.verifyOpenPages_(['settings', 'search', 'languages'], - 'languages#2'); - PageManager.showPageByName('addLanguage', true, {hash: '#3'}); - this.verifyOpenPages_(['settings', 'search', 'languages', 'addLanguage'], - 'addLanguage#3'); - - this.verifyHistory_(['', 'search#1', 'languages#2', 'addLanguage#3'], - function() { - // Close the layer-2 overlay. - PageManager.closeOverlay(); - this.verifyOpenPages_(['settings', 'search', 'languages'], 'languages#2'); - this.verifyHistory_( - ['', 'search#1', 'languages#2', 'addLanguage#3', 'languages#2'], - function() { - // Close the layer-1 overlay. - PageManager.closeOverlay(); - this.verifyOpenPages_(['settings', 'search'], 'search#1'); - this.verifyHistory_( - ['', 'search#1', 'languages#2', 'addLanguage#3', 'languages#2', - 'search#1'], - function noop() {}); - waitUntilHidden([$('overlay-container-1'), $('overlay-container-2')]); - }.bind(this)); - }.bind(this)); -}); - -// Test that closing an overlay that did not push history when opening does not -// again push history. -TEST_F('OptionsWebUIExtendedTest', 'CloseOverlayNoHistory', function() { - // Open the do not track confirmation prompt. - PageManager.showPageByName('doNotTrackConfirm', false); - - // Opening the prompt does not add to the history. - this.verifyHistory_([''], function() { - // Close the overlay. - PageManager.closeOverlay(); - // Still no history changes. - this.verifyHistory_([''], function noop() {}); - waitUntilHidden([$('overlay-container-1')]); - }.bind(this)); -}); - -// Make sure an overlay isn't closed (even temporarily) when another overlay is -// opened on top. -TEST_F('OptionsWebUIExtendedTest', 'OverlayAboveNoReset', function() { - // Open a layer-1 overlay. - PageManager.showPageByName('languages', true); - this.verifyOpenPages_(['settings', 'languages']); - - // Open a layer-2 overlay on top. This should not close 'languages'. - this.prohibitChangesToOverlay_(options.LanguageOptions.getInstance()); - PageManager.showPageByName('addLanguage', true); - this.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - testDone(); -}); - -TEST_F('OptionsWebUIExtendedTest', 'OverlayTabNavigation', function() { - // Open a layer-1 overlay, then a layer-2 overlay on top of it. - PageManager.showPageByName('languages', true); - PageManager.showPageByName('addLanguage', true); - var self = this; - - // Go back twice, then forward twice. - self.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - self.verifyHistory_(['', 'languages', 'addLanguage'], function() { - window.history.back(); - waitForPopstate(function() { - self.verifyOpenPages_(['settings', 'languages']); - self.verifyHistory_(['', 'languages'], function() { - window.history.back(); - waitForPopstate(function() { - self.verifyOpenPages_(['settings'], ''); - self.verifyHistory_([''], function() { - window.history.forward(); - waitForPopstate(function() { - self.verifyOpenPages_(['settings', 'languages']); - self.verifyHistory_(['', 'languages'], function() { - window.history.forward(); - waitForPopstate(function() { - self.verifyOpenPages_( - ['settings', 'languages', 'addLanguage']); - self.verifyHistory_( - ['', 'languages', 'addLanguage'], testDone); - }); - }); - }); - }); - }); - }); - }); - }); -}); - -// Going "back" to an overlay that's a child of the current overlay shouldn't -// close the current one. -TEST_F('OptionsWebUIExtendedTest', 'OverlayBackToChild', function() { - // Open a layer-1 overlay, then a layer-2 overlay on top of it. - PageManager.showPageByName('languages', true); - PageManager.showPageByName('addLanguage', true); - var self = this; - - self.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - self.verifyHistory_(['', 'languages', 'addLanguage'], function() { - // Close the top overlay, then go back to it. - PageManager.closeOverlay(); - self.verifyOpenPages_(['settings', 'languages']); - self.verifyHistory_( - ['', 'languages', 'addLanguage', 'languages'], - function() { - // Going back to the 'addLanguage' page should not close 'languages'. - self.prohibitChangesToOverlay_(options.LanguageOptions.getInstance()); - window.history.back(); - waitForPopstate(function() { - self.verifyOpenPages_(['settings', 'languages', 'addLanguage']); - self.verifyHistory_(['', 'languages', 'addLanguage'], - testDone); - }); - }); - }); -}); - -// Going back to an unrelated overlay should close the overlay and its parent. -TEST_F('OptionsWebUIExtendedTest', 'OverlayBackToUnrelated', function() { - // Open a layer-1 overlay, then an unrelated layer-2 overlay. - PageManager.showPageByName('languages', true); - PageManager.showPageByName('cookies', true); - var self = this; - self.verifyOpenPages_(['settings', 'content', 'cookies']); - self.verifyHistory_(['', 'languages', 'cookies'], function() { - window.history.back(); - waitForPopstate(function() { - self.verifyOpenPages_(['settings', 'languages']); - testDone(); - }); - }); -}); - -// Verify history changes properly while the page is loading. -TEST_F('OptionsWebUIExtendedTest', 'HistoryUpdatedAfterLoading', function() { - var loc = location.href; - - document.documentElement.classList.add('loading'); - assertTrue(PageManager.isLoading()); - PageManager.showPageByName('searchEngines'); - expectNotEquals(loc, location.href); - - document.documentElement.classList.remove('loading'); - assertFalse(PageManager.isLoading()); - PageManager.showDefaultPage(); - expectEquals(loc, location.href); - - testDone(); -}); - -// A tip should be shown or hidden depending on whether this profile manages any -// supervised users. -TEST_F('OptionsWebUIExtendedTest', 'SupervisingUsers', function() { - // We start managing no supervised users. - assertTrue($('profiles-supervised-dashboard-tip').hidden); - - // Remove all supervised users, then add some, watching for the pref change - // notifications and UI updates in each case. Any non-empty pref dictionary - // is interpreted as having supervised users. - chrome.send('optionsTestSetPref', [SUPERVISED_USERS_PREF, {key: 'value'}]); - waitForResponse(BrowserOptions, 'updateManagesSupervisedUsers', function() { - assertFalse($('profiles-supervised-dashboard-tip').hidden); - chrome.send('optionsTestSetPref', [SUPERVISED_USERS_PREF, {}]); - waitForResponse(BrowserOptions, 'updateManagesSupervisedUsers', function() { - assertTrue($('profiles-supervised-dashboard-tip').hidden); - testDone(); - }); - }); -}); - -/** - * TestFixture that loads the options page at a bogus URL. - * @extends {OptionsWebUIExtendedTest} - * @constructor - */ -function OptionsWebUIRedirectTest() { - OptionsWebUIExtendedTest.call(this); -} - -OptionsWebUIRedirectTest.prototype = { - __proto__: OptionsWebUIExtendedTest.prototype, - - /** @override */ - browsePreload: 'chrome://settings-frame/nonexistantPage', -}; - -TEST_F('OptionsWebUIRedirectTest', 'TestURL', function() { - assertEquals('chrome://settings-frame/', document.location.href); - this.verifyHistory_([''], testDone); -}); diff --git a/chromium/chrome/browser/ui/webui/options/options_browsertest_base.js b/chromium/chrome/browser/ui/webui/options/options_browsertest_base.js deleted file mode 100644 index 073c7dc847e..00000000000 --- a/chromium/chrome/browser/ui/webui/options/options_browsertest_base.js +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 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. - -/** - * @constructor - * @extends {testing.Test} - */ -function OptionsBrowsertestBase() {} - -OptionsBrowsertestBase.prototype = { - __proto__: testing.Test.prototype, - - /** @override */ - runAccessibilityChecks: true, - - /** @override */ - accessibilityIssuesAreErrors: true, - - /** @override */ - setUp: function() { - testing.Test.prototype.setUp.call(this); - - var requiredOwnedAriaRoleMissingSelectors = [ - '#address-list', - '#creditcard-list', - '#home-page-overlay > .autocomplete-suggestions', - '#language-options-list', - '#manage-profile-icon-grid', - '#create-profile-icon-grid', - '#saved-passwords-list', - '#password-exceptions-list', - '#extension-keyword-list', - '#startup-overlay > .autocomplete-suggestions', - '#content-settings-exceptions-area > .content-area > *', - '#cookies-list', - '#handlers-list', - '#ignored-handlers-list', - '#supervised-user-list', - '#select-avatar-grid', - '#language-dictionary-overlay-word-list', - // Selectors below only affect ChromeOS tests. - '#bluetooth-unpaired-devices-list', - '#ignored-host-list', - '#remembered-network-list', - '#bluetooth-paired-devices-list', - ]; - - // Enable when failure is resolved. - // AX_ARIA_08: http://crbug.com/559265 - this.accessibilityAuditConfig.ignoreSelectors( - 'requiredOwnedAriaRoleMissing', - requiredOwnedAriaRoleMissingSelectors); - - var tabIndexGreaterThanZeroSelectors = [ - '#user-image-grid', - '#discard-photo', - '#take-photo', - '#flip-photo', - '#change-picture-overlay-confirm', - ]; - - // Enable when failure is resolved. - // AX_FOCUS_03: http://crbug.com/560910 - this.accessibilityAuditConfig.ignoreSelectors( - 'tabIndexGreaterThanZero', - tabIndexGreaterThanZeroSelectors); - - // Enable when audit has improved performance. - // AX_HTML_02: - // https://github.com/GoogleChrome/accessibility-developer-tools/issues/263 - this.accessibilityAuditConfig.auditRulesToIgnore.push( - 'duplicateId'); - - // Enable when failure is resolved. - // AX_ARIA_02: http://crbug.com/591547 - this.accessibilityAuditConfig.ignoreSelectors( - 'nonExistentAriaRelatedElement', '#input'); - - // Enable when failure is resolved. - // AX_ARIA_04: http://crbug.com/591550 - this.accessibilityAuditConfig.ignoreSelectors( - 'badAriaAttributeValue', '#input'); - - }, -}; diff --git a/chromium/chrome/browser/ui/webui/options/options_ui.cc b/chromium/chrome/browser/ui/webui/options/options_ui.cc index 4fea457622d..aaf5474e7fc 100644 --- a/chromium/chrome/browser/ui/webui/options/options_ui.cc +++ b/chromium/chrome/browser/ui/webui/options/options_ui.cc @@ -54,9 +54,7 @@ #include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" #include "chrome/grit/options_resources.h" -#include "chrome/grit/theme_resources.h" #include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_result.h" #include "components/strings/grit/components_strings.h" @@ -85,6 +83,7 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/system/pointer_device_observer.h" +#include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h" @@ -101,7 +100,6 @@ #include "chrome/browser/ui/webui/options/chromeos/proxy_handler.h" #include "chrome/browser/ui/webui/options/chromeos/stats_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/storage_manager_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/user_image_source.h" #endif #if defined(USE_NSS_CERTS) @@ -232,7 +230,11 @@ OptionsUIHTMLSource::OptionsUIHTMLSource( } std::string OptionsUIHTMLSource::GetSource() const { - return chrome::kChromeUISettingsFrameHost; + // TODO(stevenjb): Remove this file. Because everything in this directory + // depends on this, we will remove the entire directory at once after + // the old CrOS oobe/login UI dependencies are removed. crbug.com/748164. + NOTREACHED(); + return "settings-frame"; } void OptionsUIHTMLSource::StartDataRequest( @@ -540,8 +542,8 @@ OptionsUI::OptionsUI(content::WebUI* web_ui) #if defined(OS_CHROMEOS) // Set up the chrome://userimage/ source. - chromeos::options::UserImageSource* user_image_source = - new chromeos::options::UserImageSource(); + chromeos::UserImageSource* user_image_source = + new chromeos::UserImageSource(); content::URLDataSource::Add(profile, user_image_source); pointer_device_observer_.reset( @@ -593,8 +595,7 @@ void OptionsUI::ReadyToCommitNavigation( load_start_time_ = base::Time::Now(); if (navigation_handle->GetRenderFrameHost()->GetRenderViewHost() == web_ui()->GetWebContents()->GetRenderViewHost() && - navigation_handle->GetURL().host_piece() == - chrome::kChromeUISettingsFrameHost) { + navigation_handle->GetURL().host_piece() == "settings-frame") { for (size_t i = 0; i < handlers_.size(); ++i) handlers_[i]->PageLoadStarted(); } diff --git a/chromium/chrome/browser/ui/webui/options/options_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/options/options_ui_browsertest.cc deleted file mode 100644 index b37522637fc..00000000000 --- a/chromium/chrome/browser/ui/webui/options/options_ui_browsertest.cc +++ /dev/null @@ -1,344 +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 "chrome/browser/ui/webui/options/options_ui_browsertest.h" - -#include "base/scoped_observer.h" -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/signin/account_tracker_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/browser/ui/webui/uber/uber_ui.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/prefs/pref_service.h" -#include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_utils.h" -#include "ui/base/l10n/l10n_util.h" - -#if !defined(OS_CHROMEOS) -#include <string> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/files/file_path.h" -#include "base/run_loop.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/browser_commands.h" -#include "content/public/test/test_navigation_observer.h" -#include "ui/base/window_open_disposition.h" -#include "url/gurl.h" -#endif - -using content::MessageLoopRunner; - -namespace options { - -namespace { - -class SignOutWaiter : public SigninManagerBase::Observer { - public: - explicit SignOutWaiter(SigninManagerBase* signin_manager) - : seen_(false), running_(false), scoped_observer_(this) { - scoped_observer_.Add(signin_manager); - } - ~SignOutWaiter() override {} - - void Wait() { - if (seen_) - return; - - running_ = true; - message_loop_runner_ = new MessageLoopRunner; - message_loop_runner_->Run(); - EXPECT_TRUE(seen_); - } - - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override { - seen_ = true; - if (!running_) - return; - - message_loop_runner_->Quit(); - running_ = false; - } - - private: - bool seen_; - bool running_; - ScopedObserver<SigninManagerBase, SignOutWaiter> scoped_observer_; - scoped_refptr<MessageLoopRunner> message_loop_runner_; -}; - -#if !defined(OS_CHROMEOS) -void RunClosureWhenProfileInitialized(const base::Closure& closure, - Profile* profile, - Profile::CreateStatus status) { - if (status == Profile::CREATE_STATUS_INITIALIZED) - closure.Run(); -} -#endif - -bool FrameHasSettingsSourceHost(content::RenderFrameHost* frame) { - return frame->GetLastCommittedURL().DomainIs( - chrome::kChromeUISettingsFrameHost); -} - -} // namespace - -OptionsUIBrowserTest::OptionsUIBrowserTest() { -} - -void OptionsUIBrowserTest::SetUpInProcessBrowserTestFixture() { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - disable_md_settings_.InitAndDisableFeature(features::kMaterialDesignSettings); -} - -void OptionsUIBrowserTest::NavigateToSettings() { - NavigateToSettingsSubpage(""); -} - -void OptionsUIBrowserTest::NavigateToSettingsSubpage( - const std::string& sub_page) { - const GURL& url = chrome::GetSettingsUrl(sub_page); - ui_test_utils::NavigateToURLWithDisposition( - browser(), url, WindowOpenDisposition::CURRENT_TAB, 0); - - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(web_contents); - ASSERT_TRUE(web_contents->GetWebUI()); - - content::WebUIController* controller = - web_contents->GetWebUI()->GetController(); -#if !defined(OS_CHROMEOS) - controller = static_cast<UberUI*>(controller)-> - GetSubpage(chrome::kChromeUISettingsFrameURL)->GetController(); -#endif - OptionsUI* options_ui = static_cast<OptionsUI*>(controller); - - // It is not possible to subscribe to the OnFinishedLoading event before the - // call to NavigateToURL(), because the WebUI does not yet exist at that time. - // However, it is safe to subscribe afterwards, because the event will always - // be posted asynchronously to the message loop. - scoped_refptr<MessageLoopRunner> message_loop_runner(new MessageLoopRunner); - std::unique_ptr<OptionsUI::OnFinishedLoadingCallbackList::Subscription> - subscription = options_ui->RegisterOnFinishedLoadingCallback( - message_loop_runner->QuitClosure()); - message_loop_runner->Run(); - - // The OnFinishedLoading event, which indicates that all WebUI initialization - // methods have been called on the JS side, is temporally unrelated to whether - // or not the WebContents considers itself to have finished loading. We want - // to wait for this too, however, because, e.g. this is a sufficient condition - // to get the focus properly placed on a form element. - content::WaitForLoadStop(web_contents); -} - -void OptionsUIBrowserTest::NavigateToSettingsFrame() { - const GURL& url = GURL(chrome::kChromeUISettingsFrameURL); - ui_test_utils::NavigateToURL(browser(), url); -} - -void OptionsUIBrowserTest::VerifyNavbar() { - bool navbar_exist = false; -#if defined(OS_CHROMEOS) - bool should_navbar_exist = false; -#else - bool should_navbar_exist = true; -#endif - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - browser()->tab_strip_model()->GetActiveWebContents(), - "domAutomationController.send(" - " !!document.getElementById('navigation'))", - &navbar_exist)); - EXPECT_EQ(should_navbar_exist, navbar_exist); -} - -void OptionsUIBrowserTest::VerifyTitle() { - base::string16 title = - browser()->tab_strip_model()->GetActiveWebContents()->GetTitle(); - base::string16 expected_title = l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE); - EXPECT_NE(title.find(expected_title), base::string16::npos); -} - -content::RenderFrameHost* OptionsUIBrowserTest::GetSettingsFrame() { - // NB: The utility function content::FrameHasSourceUrl can't be used because - // the settings frame navigates itself to chrome://settings-frame/settings - // to indicate that it's showing the top-level settings. Therefore, just - // match the host. - return content::FrameMatchingPredicate( - browser()->tab_strip_model()->GetActiveWebContents(), - base::Bind(&FrameHasSettingsSourceHost)); -} - -IN_PROC_BROWSER_TEST_F(OptionsUIBrowserTest, LoadOptionsByURL) { - NavigateToSettings(); - VerifyTitle(); - VerifyNavbar(); -} - -// Flaky on Linux, Mac and Win: http://crbug.com/469113 -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) -#define MAYBE_VerifyManagedSignout DISABLED_VerifyManagedSignout -#else -#define MAYBE_VerifyManagedSignout VerifyManagedSignout -#endif - -#if !defined(OS_CHROMEOS) -IN_PROC_BROWSER_TEST_F(OptionsUIBrowserTest, MAYBE_VerifyManagedSignout) { - SigninManager* signin = - SigninManagerFactory::GetForProfile(browser()->profile()); - signin->OnExternalSigninCompleted("test@example.com"); - signin->ProhibitSignout(true); - - NavigateToSettingsFrame(); - - // This script simulates a click on the "Disconnect your Google Account" - // button and returns true if the hidden flag of the appropriate dialog gets - // flipped. - bool result = false; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - browser()->tab_strip_model()->GetActiveWebContents(), - "var dialog = $('manage-profile-overlay-disconnect-managed');" - "var original_status = dialog.hidden;" - "var original = ManageProfileOverlay.showDisconnectManagedProfileDialog;" - "var teststub = function(event) {" - " original(event);" - " domAutomationController.send(original_status && !dialog.hidden);" - "};" - "ManageProfileOverlay.showDisconnectManagedProfileDialog = teststub;" - "$('start-stop-sync').click();", - &result)); - - EXPECT_TRUE(result); - - base::FilePath profile_dir = browser()->profile()->GetPath(); - ProfileAttributesStorage& storage = - g_browser_process->profile_manager()->GetProfileAttributesStorage(); - ProfileAttributesEntry* entry; - - EXPECT_TRUE(DirectoryExists(profile_dir)); - EXPECT_TRUE(storage.GetProfileAttributesWithPath(profile_dir, &entry)); - - // TODO(kaliamoorthi): Get the macos problem fixed and remove this code. - // Deleting the Profile also destroys all browser windows of that Profile. - // Wait for the current browser to close before resuming, otherwise - // the browser_tests shutdown code will be confused on the Mac. - content::WindowedNotificationObserver wait_for_browser_closed( - chrome::NOTIFICATION_BROWSER_CLOSED, - content::NotificationService::AllSources()); - - ASSERT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents(), - "$('disconnect-managed-profile-ok').click();")); - - EXPECT_TRUE(storage.GetProfileAttributesWithPath(profile_dir, &entry)); - - wait_for_browser_closed.Wait(); -} - -IN_PROC_BROWSER_TEST_F(OptionsUIBrowserTest, VerifyUnmanagedSignout) { - const std::string user = "test@example.com"; - AccountTrackerServiceFactory::GetForProfile(browser()->profile()) - ->SeedAccountInfo("12345", user); - SigninManager* signin = - SigninManagerFactory::GetForProfile(browser()->profile()); - signin->OnExternalSigninCompleted(user); - - NavigateToSettingsFrame(); - - // This script simulates a click on the "Disconnect your Google Account" - // button and returns true if the hidden flag of the appropriate dialog gets - // flipped. - bool result = false; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool( - browser()->tab_strip_model()->GetActiveWebContents(), - "var dialog = $('sync-setup-stop-syncing');" - "var original_status = dialog.hidden;" - "$('start-stop-sync').click();" - "domAutomationController.send(original_status && !dialog.hidden);", - &result)); - - EXPECT_TRUE(result); - - SignOutWaiter sign_out_waiter(signin); - - ASSERT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents(), - "$('stop-syncing-ok').click();")); - - sign_out_waiter.Wait(); - - EXPECT_TRUE(browser()->profile()->GetProfileUserName() != user); - EXPECT_FALSE(signin->IsAuthenticated()); -} - -// Regression test for http://crbug.com/301436, excluded on Chrome OS because -// profile management in the settings UI exists on desktop platforms only. -IN_PROC_BROWSER_TEST_F(OptionsUIBrowserTest, NavigateBackFromOverlayDialog) { - NavigateToSettingsFrame(); - - // Click a button that opens an overlay dialog. - content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(content::ExecuteScript( - contents, "$('manage-default-search-engines').click();")); - - // Go back to the settings page. - content::TestNavigationObserver observer(contents); - chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); - observer.Wait(); - - // Verify that the settings page lists one profile. - const char javascript[] = - "domAutomationController.send(" - " document.querySelectorAll('list#profiles-list > div[role=listitem]')" - " .length);"; - int profiles; - ASSERT_TRUE(content::ExecuteScriptAndExtractInt( - contents, javascript, &profiles)); - EXPECT_EQ(1, profiles); - - // Create a second profile. - ProfileManager* profile_manager = g_browser_process->profile_manager(); - const base::FilePath profile_path = - profile_manager->GenerateNextProfileDirectoryPath(); - - base::RunLoop run_loop; - profile_manager->CreateProfileAsync( - profile_manager->GenerateNextProfileDirectoryPath(), - base::Bind(&RunClosureWhenProfileInitialized, - run_loop.QuitClosure()), - base::string16(), - std::string(), - std::string()); - run_loop.Run(); - - // Verify that the settings page has updated and lists two profiles. - ASSERT_TRUE(content::ExecuteScriptAndExtractInt( - contents, javascript, &profiles)); - EXPECT_EQ(2, profiles); -} -#endif - -} // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/options_ui_browsertest.h b/chromium/chrome/browser/ui/webui/options/options_ui_browsertest.h deleted file mode 100644 index 35b49b2e6dd..00000000000 --- a/chromium/chrome/browser/ui/webui/options/options_ui_browsertest.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 CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_UI_BROWSERTEST_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_UI_BROWSERTEST_H_ - -#include <string> - -#include "base/macros.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/test/base/in_process_browser_test.h" - -namespace content { -class RenderFrameHost; -} - -namespace options { - -class OptionsUIBrowserTest : public InProcessBrowserTest { - public: - OptionsUIBrowserTest(); - - void SetUpInProcessBrowserTestFixture() override; - - // Navigate to the Uber/Settings page and block until it has loaded. - void NavigateToSettings(); - - // Navigate to a certain subpage in the Uber/Settings page and block until it - // has loaded. - void NavigateToSettingsSubpage(const std::string& sub_page); - - // Navigate to the Settings frame and block until complete. - void NavigateToSettingsFrame(); - - // Check navbar's existence. - void VerifyNavbar(); - - // Verify that the page title is correct. - // The only guarantee we can make about the title of a settings tab is that - // it should contain IDS_SETTINGS_TITLE somewhere. - void VerifyTitle(); - - protected: - // Returns the RenderFrameHost associated with the Settings frame inside the - // Uber UI page (which must be already loaded). - content::RenderFrameHost* GetSettingsFrame(); - - private: - base::test::ScopedFeatureList disable_md_settings_; - - DISALLOW_COPY_AND_ASSIGN(OptionsUIBrowserTest); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_OPTIONS_UI_BROWSERTEST_H_ diff --git a/chromium/chrome/browser/ui/webui/options/password_manager_browsertest.js b/chromium/chrome/browser/ui/webui/options/password_manager_browsertest.js deleted file mode 100644 index e94a72b946e..00000000000 --- a/chromium/chrome/browser/ui/webui/options/password_manager_browsertest.js +++ /dev/null @@ -1,26 +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. - -/** - * TestFixture for password manager WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function PasswordManagerWebUITest() {} - -PasswordManagerWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** - * Browse to the password manager. - */ - browsePreload: 'chrome://settings-frame/passwords', -}; - -// Test opening the password manager has correct location. -// Fails on Linux and Windows. http://crbug.com/467916 -TEST_F('PasswordManagerWebUITest', 'DISABLED_testOpenPasswordManager', - function() { - assertEquals(this.browsePreload, document.location.href); - }); diff --git a/chromium/chrome/browser/ui/webui/options/password_manager_handler.cc b/chromium/chrome/browser/ui/webui/options/password_manager_handler.cc index e9f434bb59e..85035294649 100644 --- a/chromium/chrome/browser/ui/webui/options/password_manager_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/password_manager_handler.cc @@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/options/password_manager_handler.h" #include <memory> +#include <tuple> #include <utility> #include "base/bind.h" @@ -29,6 +30,7 @@ #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/password_form.h" #include "components/browser_sync/profile_sync_service.h" +#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/export/password_exporter.h" #include "components/password_manager/core/browser/password_bubble_experiment.h" #include "components/password_manager/core/browser/password_manager_constants.h" @@ -39,13 +41,13 @@ #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" #include "components/url_formatter/url_formatter.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/common/origin_util.h" #include "ui/base/l10n/l10n_util.h" +#include "url/gurl.h" namespace options { @@ -65,20 +67,20 @@ const char kFederationField[] = "federation"; // Android URI, and whether the origin is secure. void CopyOriginInfoOfPasswordForm(const autofill::PasswordForm& form, base::DictionaryValue* entry) { - bool is_android_uri = false; - bool origin_is_clickable = false; + std::string shown_origin; GURL link_url; - entry->SetString( - kShownOriginField, - password_manager::GetShownOriginAndLinkUrl( - form, &is_android_uri, &link_url, &origin_is_clickable)); + std::tie(shown_origin, link_url) = + password_manager::GetShownOriginAndLinkUrl(form); + entry->SetString(kShownOriginField, shown_origin); DCHECK(link_url.is_valid()); - entry->SetString( - kUrlField, url_formatter::FormatUrl( - link_url, url_formatter::kFormatUrlOmitNothing, - net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); - entry->SetBoolean(kIsAndroidUriField, is_android_uri); - entry->SetBoolean(kIsClickable, origin_is_clickable); + entry->SetString(kUrlField, + url_formatter::FormatUrl( + link_url, url_formatter::kFormatUrlOmitNothing, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); + entry->SetBoolean( + kIsAndroidUriField, + password_manager::IsValidAndroidFacetURI(form.signon_realm)); + entry->SetBoolean(kIsClickable, true); entry->SetBoolean(kIsSecureField, content::IsOriginSecure(link_url)); } @@ -331,11 +333,8 @@ void PasswordManagerHandler::ImportPasswordFileSelected( new ImportPasswordResultConsumer(GetProfile())); password_manager::PasswordImporter::Import( - path, content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::FILE) - .get(), - base::Bind(&ImportPasswordResultConsumer::ConsumePassword, - form_consumer)); + path, base::Bind(&ImportPasswordResultConsumer::ConsumePassword, + form_consumer)); } PasswordManagerHandler::ImportPasswordResultConsumer:: @@ -393,10 +392,7 @@ void PasswordManagerHandler::ExportPasswordFileSelected( password_manager_presenter_->GetAllPasswords(); UMA_HISTOGRAM_COUNTS("PasswordManager.ExportedPasswordsPerUserInCSV", password_list.size()); - password_manager::PasswordExporter::Export( - path, password_list, content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::FILE) - .get()); + password_manager::PasswordExporter::Export(path, password_list); } } // namespace options diff --git a/chromium/chrome/browser/ui/webui/options/password_manager_handler_unittest.cc b/chromium/chrome/browser/ui/webui/options/password_manager_handler_unittest.cc deleted file mode 100644 index bdd275e306a..00000000000 --- a/chromium/chrome/browser/ui/webui/options/password_manager_handler_unittest.cc +++ /dev/null @@ -1,244 +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 "chrome/browser/ui/webui/options/password_manager_handler.h" - -#include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" -#include "base/metrics/statistics_recorder.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/password_manager/password_store_factory.h" -#include "chrome/browser/ui/passwords/password_manager_presenter.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/testing_profile.h" -#include "components/password_manager/core/browser/mock_password_store.h" -#include "components/password_manager/core/browser/password_manager_test_utils.h" -#include "content/public/test/test_web_ui.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/shell_dialogs/select_file_dialog.h" -#include "ui/shell_dialogs/select_file_dialog_factory.h" -#include "ui/shell_dialogs/select_file_policy.h" - -using password_manager::MockPasswordStore; - -namespace { - -class TestSelectFileDialogFactory final : public ui::SelectFileDialogFactory { - public: - TestSelectFileDialogFactory() {} - ~TestSelectFileDialogFactory() override {} - ui::SelectFileDialog* Create(ui::SelectFileDialog::Listener* listener, - ui::SelectFilePolicy* policy) override { - delete policy; // Ignore the policy, replace it with a test one. - return new TestSelectFileDialog(listener, new TestSelectFilePolicy); - } - - private: - class TestSelectFilePolicy : public ui::SelectFilePolicy { - public: - bool CanOpenSelectFileDialog() override { return true; } - void SelectFileDenied() override {} - }; - - class TestSelectFileDialog : public ui::SelectFileDialog { - public: - TestSelectFileDialog(Listener* listener, ui::SelectFilePolicy* policy) - : ui::SelectFileDialog(listener, policy) {} - - protected: - void SelectFileImpl(Type type, - const base::string16& title, - const base::FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const base::FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params) override { - listener_->FileSelected(default_path, file_type_index, params); - } - bool IsRunning(gfx::NativeWindow owning_window) const override { - return false; - } - void ListenerDestroyed() override {} - bool HasMultipleFileTypeChoicesImpl() override { return false; } - ~TestSelectFileDialog() override {} - }; -}; - -class CallbackTestWebUI : public content::TestWebUI { - public: - CallbackTestWebUI() {} - ~CallbackTestWebUI() override {} - void RegisterMessageCallback(const std::string& message, - const MessageCallback& callback) override; - void ProcessWebUIMessage(const GURL& source_url, - const std::string& message, - const base::ListValue& args) override; - - MOCK_CONST_METHOD0(GetWebContents, content::WebContents*()); - - private: - std::map<std::string, MessageCallback> message_callbacks_; -}; - -void CallbackTestWebUI::RegisterMessageCallback( - const std::string& message, - const MessageCallback& callback) { - message_callbacks_.insert(std::make_pair(message, callback)); -} - -void CallbackTestWebUI::ProcessWebUIMessage(const GURL& source_url, - const std::string& message, - const base::ListValue& args) { - std::map<std::string, MessageCallback>::const_iterator callback = - message_callbacks_.find(message); - if (callback != message_callbacks_.end()) { - callback->second.Run(&args); - } -} - -class TestPasswordManagerHandler : public options::PasswordManagerHandler { - public: - TestPasswordManagerHandler( - std::unique_ptr<PasswordManagerPresenter> presenter, - CallbackTestWebUI* web_ui) - : PasswordManagerHandler(std::move(presenter)) { - set_web_ui(web_ui); - } - ~TestPasswordManagerHandler() override {} -#if !defined(OS_ANDROID) - gfx::NativeWindow GetNativeWindow() const override; -#endif - - MOCK_METHOD3(FileSelected, void(const base::FilePath& path, int, void*)); -}; -#if !defined(OS_ANDROID) -gfx::NativeWindow TestPasswordManagerHandler::GetNativeWindow() const { - return NULL; -} -#endif - -class MockPasswordManagerPresenter : public PasswordManagerPresenter { - public: - explicit MockPasswordManagerPresenter(PasswordUIView* handler) - : PasswordManagerPresenter(handler) {} - ~MockPasswordManagerPresenter() override {} - - MOCK_METHOD0(IsUserAuthenticated, bool()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerPresenter); -}; - -class DummyPasswordManagerHandler : public PasswordUIView { - public: - explicit DummyPasswordManagerHandler(Profile* profile) - : profile_(profile), password_manager_presenter_(this) { - password_manager_presenter_.Initialize(); - } - ~DummyPasswordManagerHandler() override {} - Profile* GetProfile() override; - - void ShowPassword(size_t, - const std::string&, - const std::string&, - const base::string16&) override {} - void SetPasswordList( - const std::vector<std::unique_ptr<autofill::PasswordForm>>&) override {} - void SetPasswordExceptionList( - const std::vector<std::unique_ptr<autofill::PasswordForm>>&) override {} - -#if !defined(OS_ANDROID) - gfx::NativeWindow GetNativeWindow() const override; -#endif - private: - Profile* profile_; - PasswordManagerPresenter password_manager_presenter_; - - DISALLOW_COPY_AND_ASSIGN(DummyPasswordManagerHandler); -}; - -#if !defined(OS_ANDROID) -gfx::NativeWindow DummyPasswordManagerHandler::GetNativeWindow() const { - return NULL; -} -#endif - -Profile* DummyPasswordManagerHandler::GetProfile() { - return profile_; -} - -} // namespace - -class PasswordManagerHandlerTest : public ChromeRenderViewHostTestHarness { - protected: - PasswordManagerHandlerTest() {} - ~PasswordManagerHandlerTest() override {} - - void SetUp() override { - ChromeRenderViewHostTestHarness::SetUp(); - dummy_handler_.reset(new DummyPasswordManagerHandler(profile())); - presenter_raw_ = new MockPasswordManagerPresenter(dummy_handler_.get()); - handler_.reset(new TestPasswordManagerHandler( - base::WrapUnique(presenter_raw_), &web_ui_)); - handler_->RegisterMessages(); - ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory); - handler_->InitializeHandler(); - web_ui_.set_web_contents(web_contents()); - } - - void TearDown() override { - handler_.reset(); - dummy_handler_.reset(); - ChromeRenderViewHostTestHarness::TearDown(); - } - - void ExportPassword() { - base::ListValue tmp; - web_ui_.ProcessWebUIMessage(GURL(), "exportPassword", tmp); - } - - void ImportPassword() { - base::ListValue tmp; - web_ui_.ProcessWebUIMessage(GURL(), "importPassword", tmp); - } - - PasswordManagerPresenter* presenter_raw_; - CallbackTestWebUI web_ui_; - std::unique_ptr<DummyPasswordManagerHandler> dummy_handler_; - std::unique_ptr<TestPasswordManagerHandler> handler_; - - private: - DISALLOW_COPY_AND_ASSIGN(PasswordManagerHandlerTest); -}; - -MATCHER(IsEmptyPath, "") { - return arg.empty(); -} - -TEST_F(PasswordManagerHandlerTest, PasswordImport) { - EXPECT_CALL(web_ui_, GetWebContents()) - .WillRepeatedly(testing::Return(web_contents())); - EXPECT_CALL( - *handler_, - FileSelected(IsEmptyPath(), 1, - reinterpret_cast<void*>( - TestPasswordManagerHandler::IMPORT_FILE_SELECTED))); - ImportPassword(); -} - -TEST_F(PasswordManagerHandlerTest, PasswordExport) { - const base::FilePath file_path; - EXPECT_CALL(*(static_cast<MockPasswordManagerPresenter*>(presenter_raw_)), - IsUserAuthenticated()) - .Times(testing::AtLeast(1)) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL( - *handler_, - FileSelected(IsEmptyPath(), 1, - reinterpret_cast<void*>( - TestPasswordManagerHandler::EXPORT_FILE_SELECTED))); - ExportPassword(); -} diff --git a/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc b/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc index 9dbab9f5369..542498b7447 100644 --- a/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc +++ b/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.cc @@ -57,8 +57,8 @@ void PepperFlashContentSettingsUtils::FlashSiteSettingsToMediaExceptions( MediaExceptions* media_exceptions) { media_exceptions->clear(); - std::unique_ptr<ContentSettingsPattern::BuilderInterface> builder( - ContentSettingsPattern::CreateBuilder(false)); + std::unique_ptr<ContentSettingsPattern::BuilderInterface> builder = + ContentSettingsPattern::CreateBuilder(); builder->WithSchemeWildcard()->WithPortWildcard(); for (ppapi::FlashSiteSettings::const_iterator iter = site_settings.begin(); iter != site_settings.end(); ++iter) { diff --git a/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils_unittest.cc b/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils_unittest.cc deleted file mode 100644 index dd1317c88c2..00000000000 --- a/chromium/chrome/browser/ui/webui/options/pepper_flash_content_settings_utils_unittest.cc +++ /dev/null @@ -1,137 +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 "chrome/browser/ui/webui/options/pepper_flash_content_settings_utils.h" - -#include <stddef.h> - -#include "base/macros.h" -#include "testing/gtest/include/gtest/gtest.h" - -using options::MediaException; -using options::MediaExceptions; -using options::PepperFlashContentSettingsUtils; - -namespace { - -MediaExceptions ConvertAndSort(const MediaException* items, size_t count) { - MediaExceptions result(items, items + count); - PepperFlashContentSettingsUtils::SortMediaExceptions(&result); - return result; -} - -} // namespace - -TEST(PepperFlashContentSettingsUtilsTest, SortMediaExceptions) { - MediaException entry_1(ContentSettingsPattern::FromString("www.google.com"), - CONTENT_SETTING_ALLOW); - MediaException entry_2(ContentSettingsPattern::FromString("www.youtube.com"), - CONTENT_SETTING_BLOCK); - MediaException entry_3(ContentSettingsPattern::Wildcard(), - CONTENT_SETTING_ASK); - MediaException entry_4(ContentSettingsPattern(), - CONTENT_SETTING_SESSION_ONLY); - - MediaExceptions list_1; - list_1.push_back(entry_1); - list_1.push_back(entry_2); - list_1.push_back(entry_3); - list_1.push_back(entry_4); - - MediaExceptions list_2; - list_2.push_back(entry_1); - list_2.push_back(entry_3); - list_2.push_back(entry_2); - list_2.push_back(entry_4); - - MediaExceptions list_3; - list_3.push_back(entry_4); - list_3.push_back(entry_1); - list_3.push_back(entry_2); - list_3.push_back(entry_3); - - EXPECT_NE(list_1, list_2); - EXPECT_NE(list_2, list_3); - EXPECT_NE(list_3, list_1); - - PepperFlashContentSettingsUtils::SortMediaExceptions(&list_1); - PepperFlashContentSettingsUtils::SortMediaExceptions(&list_2); - PepperFlashContentSettingsUtils::SortMediaExceptions(&list_3); - - EXPECT_EQ(list_1, list_2); - EXPECT_EQ(list_2, list_3); -} - -TEST(PepperFlashContentSettingsUtilsTest, AreMediaExceptionsEqual) { - { - // Empty lists are equal. - // Default settings are not compared directly, so it is possible to return - // true when they are different. - EXPECT_TRUE(PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - CONTENT_SETTING_BLOCK, - MediaExceptions(), - CONTENT_SETTING_ASK, - MediaExceptions())); - } - - { - MediaException exceptions_1[] = { - MediaException(ContentSettingsPattern::FromString("www.google.com"), - CONTENT_SETTING_ALLOW), - MediaException(ContentSettingsPattern::FromString("www.youtube.com"), - CONTENT_SETTING_ASK) - }; - - MediaException exceptions_2[] = { - MediaException(ContentSettingsPattern::FromString("www.google.com"), - CONTENT_SETTING_ALLOW) - }; - - // The exception of "www.youtube.com" in |exceptions_1| should not affect - // the result, because it has the same settings as |default_setting_2|. - EXPECT_TRUE(PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_1, arraysize(exceptions_1)), - CONTENT_SETTING_ASK, - ConvertAndSort(exceptions_2, arraysize(exceptions_2)))); - EXPECT_TRUE(PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - CONTENT_SETTING_ASK, - ConvertAndSort(exceptions_2, arraysize(exceptions_2)), - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_1, arraysize(exceptions_1)))); - // Changing |default_setting_2| should change the result. - EXPECT_FALSE(PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_1, arraysize(exceptions_1)), - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_2, arraysize(exceptions_2)))); - } - - { - // Similar to the previous block, but reoder the exceptions. The outcome - // should be the same. - MediaException exceptions_1[] = { - MediaException(ContentSettingsPattern::FromString("www.youtube.com"), - CONTENT_SETTING_ASK), - MediaException(ContentSettingsPattern::FromString("www.google.com"), - CONTENT_SETTING_ALLOW) - }; - - MediaException exceptions_2[] = { - MediaException(ContentSettingsPattern::FromString("www.google.com"), - CONTENT_SETTING_ALLOW) - }; - - EXPECT_TRUE(PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_1, arraysize(exceptions_1)), - CONTENT_SETTING_ASK, - ConvertAndSort(exceptions_2, arraysize(exceptions_2)))); - EXPECT_FALSE(PepperFlashContentSettingsUtils::AreMediaExceptionsEqual( - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_1, arraysize(exceptions_1)), - CONTENT_SETTING_ALLOW, - ConvertAndSort(exceptions_2, arraysize(exceptions_2)))); - } -} diff --git a/chromium/chrome/browser/ui/webui/options/preferences_browsertest.cc b/chromium/chrome/browser/ui/webui/options/preferences_browsertest.cc deleted file mode 100644 index 3cc4c0bd3a3..00000000000 --- a/chromium/chrome/browser/ui/webui/options/preferences_browsertest.cc +++ /dev/null @@ -1,1106 +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 "chrome/browser/ui/webui/options/preferences_browsertest.h" - -#include <stddef.h> - -#include <iostream> -#include <memory> -#include <sstream> -#include <utility> - -#include "base/callback.h" -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/policy/core/browser/browser_policy_connector.h" -#include "components/policy/core/common/external_data_fetcher.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_types.h" -#include "components/policy/policy_constants.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -#if defined(OS_CHROMEOS) -#include "base/strings/stringprintf.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/proxy_cros_settings_parser.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/settings/stub_install_attributes.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/shill_profile_client.h" -#include "chromeos/dbus/shill_service_client.h" -#include "chromeos/network/network_state.h" -#include "chromeos/network/network_state_handler.h" -#include "chromeos/network/proxy/proxy_config_handler.h" -#include "chromeos/settings/cros_settings_names.h" -#include "components/onc/onc_pref_names.h" -#include "components/proxy_config/proxy_config_dictionary.h" -#include "components/proxy_config/proxy_config_pref_names.h" -#include "content/public/test/test_utils.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -#endif - -using testing::AllOf; -using testing::Mock; -using testing::Property; -using testing::Return; -using testing::_; - -namespace base { - -// Helper for pretty-printing the contents of base::Value in case of failures. -void PrintTo(const base::Value& value, std::ostream* stream) { - std::string json; - JSONWriter::Write(value, &json); - *stream << json; -} - -} // namespace base - -// Googlemock matcher for base::Value. -MATCHER_P(EqualsValue, expected, "") { - return arg && arg->Equals(expected); -} - -PreferencesBrowserTest::PreferencesBrowserTest() { -} - -PreferencesBrowserTest::~PreferencesBrowserTest() { -} - -PrefService* PreferencesBrowserTest::pref_service() { - DCHECK(pref_change_registrar_); - return pref_change_registrar_->prefs(); -} - -// Navigates to the settings page, causing the JavaScript pref handling code to -// load and injects JavaScript testing code. -void PreferencesBrowserTest::SetUpOnMainThread() { - ui_test_utils::NavigateToURL(browser(), - GURL(chrome::kChromeUISettingsFrameURL)); - SetUpPrefs(); -} - -void PreferencesBrowserTest::TearDownOnMainThread() { - pref_change_registrar_.reset(); -} - -void PreferencesBrowserTest::SetUpPrefs() { - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(web_contents); - render_view_host_ = web_contents->GetRenderViewHost(); - ASSERT_TRUE(render_view_host_); - - DCHECK(!pref_change_registrar_); - pref_change_registrar_.reset(new PrefChangeRegistrar); - pref_change_registrar_->Init(browser()->profile()->GetPrefs()); - - ASSERT_TRUE(content::ExecuteScript(render_view_host_, - "function TestEnv() {" - " this.sentinelName_ = 'download.prompt_for_download';" - " this.prefs_ = [];" - " TestEnv.instance_ = this;" - "}" - "" - "TestEnv.handleEvent = function(event) {" - " var env = TestEnv.instance_;" - " var name = event.type;" - " env.removePrefListener_(name);" - " if (name == TestEnv.sentinelName_)" - " env.sentinelValue_ = event.value.value;" - " else" - " env.reply_[name] = event.value;" - " if (env.fetching_ && !--env.fetching_ ||" - " !env.fetching_ && name == env.sentinelName_) {" - " env.removePrefListeners_();" - " window.domAutomationController.send(JSON.stringify(env.reply_));" - " delete env.reply_;" - " }" - "};" - "" - "TestEnv.prototype = {" - " addPrefListener_: function(name) {" - " Preferences.getInstance().addEventListener(name," - " TestEnv.handleEvent);" - " }," - "" - " addPrefListeners_: function() {" - " for (var i in this.prefs_)" - " this.addPrefListener_(this.prefs_[i]);" - " }," - "" - " removePrefListener_: function(name) {" - " Preferences.getInstance().removeEventListener(name," - " TestEnv.handleEvent);" - " }," - "" - " removePrefListeners_: function() {" - " for (var i in this.prefs_)" - " this.removePrefListener_(this.prefs_[i]);" - " }," - "" - "" - " addPref: function(name) {" - " this.prefs_.push(name);" - " }," - "" - " setupAndReply: function() {" - " this.reply_ = {};" - " Preferences.instance_ = new Preferences();" - " this.addPref(this.sentinelName_);" - " this.fetching_ = this.prefs_.length;" - " this.addPrefListeners_();" - " Preferences.getInstance().initialize();" - " }," - "" - " runAndReply: function(test) {" - " this.reply_ = {};" - " this.addPrefListeners_();" - " test();" - " this.sentinelValue_ = !this.sentinelValue_;" - " Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_," - " true);" - " }," - "" - " startObserving: function() {" - " this.reply_ = {};" - " this.addPrefListeners_();" - " }," - "" - " finishObservingAndReply: function() {" - " this.sentinelValue_ = !this.sentinelValue_;" - " Preferences.setBooleanPref(this.sentinelName_, this.sentinelValue_," - " true);" - " }" - "};")); -} - -// Forwards notifications received when pref values change in the backend. -void PreferencesBrowserTest::OnPreferenceChanged(const std::string& pref_name) { - OnCommit(pref_service()->FindPreference(pref_name.c_str())); -} - -void PreferencesBrowserTest::SetUpInProcessBrowserTestFixture() { - // Sets up a mock policy provider for user and device policies. - EXPECT_CALL(policy_provider_, IsInitializationComplete(_)) - .WillRepeatedly(Return(true)); - policy::BrowserPolicyConnector::SetPolicyProviderForTesting( - &policy_provider_); -} - -void PreferencesBrowserTest::SetUserPolicies( - const std::vector<std::string>& names, - const std::vector<std::unique_ptr<base::Value>>& values, - policy::PolicyLevel level) { - policy::PolicyMap map; - for (size_t i = 0; i < names.size(); ++i) { - map.Set(names[i], level, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, values[i]->CreateDeepCopy(), nullptr); - } - policy_provider_.UpdateChromePolicy(map); -} - -void PreferencesBrowserTest::ClearUserPolicies() { - policy::PolicyMap empty_policy_map; - policy_provider_.UpdateChromePolicy(empty_policy_map); -} - -void PreferencesBrowserTest::SetUserValues( - const std::vector<std::string>& names, - const std::vector<std::unique_ptr<base::Value>>& values) { - for (size_t i = 0; i < names.size(); ++i) { - pref_service()->Set(names[i].c_str(), *values[i]); - } -} - -void PreferencesBrowserTest::VerifyKeyValue(const base::DictionaryValue& dict, - const std::string& key, - const base::Value& expected) { - const base::Value* actual = NULL; - EXPECT_TRUE(dict.Get(key, &actual)) << "Was checking key: " << key; - if (actual) - EXPECT_EQ(expected, *actual) << "Was checking key: " << key; -} - -void PreferencesBrowserTest::VerifyPref( - const base::DictionaryValue* prefs, - const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy, - bool disabled, - bool uncommitted) { - const base::Value* pref = NULL; - const base::DictionaryValue* dict = NULL; - ASSERT_TRUE(prefs->GetWithoutPathExpansion(name, &pref)); - ASSERT_TRUE(pref->GetAsDictionary(&dict)); - VerifyKeyValue(*dict, "value", *value); - if (!controlledBy.empty()) - VerifyKeyValue(*dict, "controlledBy", base::Value(controlledBy)); - else - EXPECT_FALSE(dict->HasKey("controlledBy")); - - if (disabled) - VerifyKeyValue(*dict, "disabled", base::Value(true)); - else if (dict->HasKey("disabled")) - VerifyKeyValue(*dict, "disabled", base::Value(false)); - - if (uncommitted) - VerifyKeyValue(*dict, "uncommitted", base::Value(true)); - else if (dict->HasKey("uncommitted")) - VerifyKeyValue(*dict, "uncommitted", base::Value(false)); -} - -void PreferencesBrowserTest::VerifyObservedPref( - const std::string& json, - const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy, - bool disabled, - bool uncommitted) { - std::unique_ptr<base::Value> observed_value_ptr = - base::JSONReader::Read(json); - const base::DictionaryValue* observed_dict; - ASSERT_TRUE(observed_value_ptr.get()); - ASSERT_TRUE(observed_value_ptr->GetAsDictionary(&observed_dict)); - VerifyPref(observed_dict, name, value, controlledBy, disabled, uncommitted); -} - -void PreferencesBrowserTest::VerifyObservedPrefs( - const std::string& json, - const std::vector<std::string>& names, - const std::vector<std::unique_ptr<base::Value>>& values, - const std::string& controlledBy, - bool disabled, - bool uncommitted) { - std::unique_ptr<base::Value> observed_value_ptr = - base::JSONReader::Read(json); - const base::DictionaryValue* observed_dict; - ASSERT_TRUE(observed_value_ptr.get()); - ASSERT_TRUE(observed_value_ptr->GetAsDictionary(&observed_dict)); - for (size_t i = 0; i < names.size(); ++i) { - VerifyPref(observed_dict, names[i], values[i], controlledBy, disabled, - uncommitted); - } -} - -void PreferencesBrowserTest::ExpectNoCommit(const std::string& name) { - pref_change_registrar_->Add( - name.c_str(), - base::Bind(&PreferencesBrowserTest::OnPreferenceChanged, - base::Unretained(this))); - EXPECT_CALL(*this, OnCommit(Property(&PrefService::Preference::name, name))) - .Times(0); -} - -void PreferencesBrowserTest::ExpectSetCommit( - const std::string& name, - const std::unique_ptr<base::Value>& value) { - pref_change_registrar_->Add( - name.c_str(), - base::Bind(&PreferencesBrowserTest::OnPreferenceChanged, - base::Unretained(this))); - EXPECT_CALL( - *this, - OnCommit(AllOf(Property(&PrefService::Preference::name, name), - Property(&PrefService::Preference::IsUserControlled, true), - Property(&PrefService::Preference::GetValue, - EqualsValue(value.get()))))); -} - -void PreferencesBrowserTest::ExpectClearCommit(const std::string& name) { - pref_change_registrar_->Add( - name.c_str(), - base::Bind(&PreferencesBrowserTest::OnPreferenceChanged, - base::Unretained(this))); - EXPECT_CALL(*this, OnCommit(AllOf( - Property(&PrefService::Preference::name, name), - Property(&PrefService::Preference::IsUserControlled, false)))); -} - -void PreferencesBrowserTest::VerifyAndClearExpectations() { - Mock::VerifyAndClearExpectations(this); - pref_change_registrar_->RemoveAll(); -} - -void PreferencesBrowserTest::SetupJavaScriptTestEnvironment( - const std::vector<std::string>& pref_names, - std::string* observed_json) const { - std::stringstream javascript; - javascript << "var testEnv = new TestEnv();"; - for (const auto& name : pref_names) { - javascript << "testEnv.addPref('" << name.c_str() << "');"; - } - javascript << "testEnv.setupAndReply();"; - std::string temp_observed_json; - if (!observed_json) - observed_json = &temp_observed_json; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - render_view_host_, javascript.str(), observed_json)); -} - -void PreferencesBrowserTest::SetPref(const std::string& name, - const std::string& type, - const std::unique_ptr<base::Value>& value, - bool commit, - std::string* observed_json) { - std::unique_ptr<base::Value> commit_ptr(new base::Value(commit)); - std::stringstream javascript; - javascript << "testEnv.runAndReply(function() {" - << " Preferences.set" << type << "Pref(" - << " '" << name << "'," - << " " << *value << "," - << " " << *commit_ptr << ");" - << "});"; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - render_view_host_, javascript.str(), observed_json)); -} - -void PreferencesBrowserTest::VerifySetPref( - const std::string& name, - const std::string& type, - const std::unique_ptr<base::Value>& value, - bool commit) { - if (commit) - ExpectSetCommit(name, value); - else - ExpectNoCommit(name); - std::string observed_json; - SetPref(name, type, value, commit, &observed_json); - VerifyObservedPref(observed_json, name, value, std::string(), false, !commit); - VerifyAndClearExpectations(); -} - -void PreferencesBrowserTest::VerifyClearPref( - const std::string& name, - const std::unique_ptr<base::Value>& value, - bool commit) { - if (commit) - ExpectClearCommit(name); - else - ExpectNoCommit(name); - std::string commit_json; - base::JSONWriter::Write(base::Value(commit), &commit_json); - std::stringstream javascript; - javascript << "testEnv.runAndReply(function() {" - << " Preferences.clearPref(" - << " '" << name.c_str() << "'," - << " " << commit_json.c_str() << ");});"; - std::string observed_json; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - render_view_host_, javascript.str(), &observed_json)); - VerifyObservedPref(observed_json, name, value, "recommended", false, !commit); - VerifyAndClearExpectations(); -} - -void PreferencesBrowserTest::VerifyCommit( - const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy) { - std::stringstream javascript; - javascript << "testEnv.runAndReply(function() {" - << " Preferences.getInstance().commitPref(" - << " '" << name.c_str() << "');});"; - std::string observed_json; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - render_view_host_, javascript.str(), &observed_json)); - VerifyObservedPref(observed_json, name, value, controlledBy, false, false); -} - -void PreferencesBrowserTest::VerifySetCommit( - const std::string& name, - const std::unique_ptr<base::Value>& value) { - ExpectSetCommit(name, value); - VerifyCommit(name, value, std::string()); - VerifyAndClearExpectations(); -} - -void PreferencesBrowserTest::VerifyClearCommit( - const std::string& name, - const std::unique_ptr<base::Value>& value) { - ExpectClearCommit(name); - VerifyCommit(name, value, "recommended"); - VerifyAndClearExpectations(); -} - -void PreferencesBrowserTest::VerifyRollback( - const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy) { - ExpectNoCommit(name); - std::stringstream javascript; - javascript << "testEnv.runAndReply(function() {" - << " Preferences.getInstance().rollbackPref(" - << " '" << name.c_str() << "');});"; - std::string observed_json; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - render_view_host_, javascript.str(), &observed_json)); - VerifyObservedPref(observed_json, name, value, controlledBy, false, true); - VerifyAndClearExpectations(); -} - -void PreferencesBrowserTest::StartObserving() { - ASSERT_TRUE(content::ExecuteScript( - render_view_host_, "testEnv.startObserving();")); -} - -void PreferencesBrowserTest::FinishObserving(std::string* observed_json) { - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - render_view_host_, - "testEnv.finishObservingAndReply();", - observed_json)); -} - -void PreferencesBrowserTest::UseDefaultTestPrefs(bool includeListPref) { - // Boolean pref. - types_.push_back("Boolean"); - pref_names_.push_back(prefs::kAlternateErrorPagesEnabled); - policy_names_.push_back(policy::key::kAlternateErrorPagesEnabled); - non_default_values_.push_back(base::MakeUnique<base::Value>(false)); - - // Integer pref. - types_.push_back("Integer"); - pref_names_.push_back(prefs::kRestoreOnStartup); - policy_names_.push_back(policy::key::kRestoreOnStartup); - non_default_values_.push_back(base::MakeUnique<base::Value>(4)); - - // List pref. - if (includeListPref) { - types_.push_back("List"); - pref_names_.push_back(prefs::kURLsToRestoreOnStartup); - policy_names_.push_back(policy::key::kRestoreOnStartupURLs); - auto list = base::MakeUnique<base::ListValue>(); - list->AppendString("http://www.example.com"); - list->AppendString("http://example.com"); - non_default_values_.push_back(std::move(list)); - } - - // Retrieve default values. - for (const auto& name : pref_names_) { - default_values_.push_back( - pref_service()->GetDefaultPrefValue(name.c_str())->CreateDeepCopy()); - } -} - -// Verifies that initializing the JavaScript Preferences class fires the correct -// notifications in JavaScript. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, FetchPrefs) { - UseDefaultTestPrefs(true); - std::string observed_json; - - // Verify notifications when default values are in effect. - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, default_values_, - std::string(), false, false); - - // Verify notifications when recommended values are in effect. - SetUserPolicies(policy_names_, non_default_values_, - policy::POLICY_LEVEL_RECOMMENDED); - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, - "recommended", false, false); - - // Verify notifications when mandatory values are in effect. - SetUserPolicies(policy_names_, non_default_values_, - policy::POLICY_LEVEL_MANDATORY); - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "policy", - true, false); - - // Verify notifications when user-modified values are in effect. - ClearUserPolicies(); - SetUserValues(pref_names_, non_default_values_); - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, - std::string(), false, false); -} - -// Verifies that setting a user-modified pref value through the JavaScript -// Preferences class fires the correct notification in JavaScript and causes the -// change to be committed to the C++ backend. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, SetPrefs) { - UseDefaultTestPrefs(false); - - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], true); - } -} - -// Verifies that clearing a user-modified pref value through the JavaScript -// Preferences class fires the correct notification in JavaScript and causes the -// change to be committed to the C++ backend. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ClearPrefs) { - UseDefaultTestPrefs(false); - - SetUserPolicies(policy_names_, default_values_, - policy::POLICY_LEVEL_RECOMMENDED); - SetUserValues(pref_names_, non_default_values_); - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifyClearPref(pref_names_[i], default_values_[i], true); - } -} - -// Verifies that when the user-modified value of a dialog pref is set and the -// change then committed through the JavaScript Preferences class, the correct -// notifications fire and a commit to the C++ backend occurs in the latter step -// only. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsSetCommit) { - UseDefaultTestPrefs(false); - - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], false); - VerifySetCommit(pref_names_[i], non_default_values_[i]); - } -} - -// Verifies that when the user-modified value of a dialog pref is set and the -// change then rolled back through the JavaScript Preferences class, the correct -// notifications fire and no commit to the C++ backend occurs. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsSetRollback) { - UseDefaultTestPrefs(false); - - // Verify behavior when default values are in effect. - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], false); - VerifyRollback(pref_names_[i], default_values_[i], std::string()); - } - - // Verify behavior when recommended values are in effect. - SetUserPolicies(policy_names_, default_values_, - policy::POLICY_LEVEL_RECOMMENDED); - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifySetPref(pref_names_[i], types_[i], non_default_values_[i], false); - VerifyRollback(pref_names_[i], default_values_[i], "recommended"); - } -} - -// Verifies that when the user-modified value of a dialog pref is cleared and -// the change then committed through the JavaScript Preferences class, the -// correct notifications fire and a commit to the C++ backend occurs in the -// latter step only. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsClearCommit) { - UseDefaultTestPrefs(false); - - SetUserPolicies(policy_names_, default_values_, - policy::POLICY_LEVEL_RECOMMENDED); - SetUserValues(pref_names_, non_default_values_); - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifyClearPref(pref_names_[i], default_values_[i], false); - VerifyClearCommit(pref_names_[i], default_values_[i]); - } -} - -// Verifies that when the user-modified value of a dialog pref is cleared and -// the change then rolled back through the JavaScript Preferences class, the -// correct notifications fire and no commit to the C++ backend occurs. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, DialogPrefsClearRollback) { - UseDefaultTestPrefs(false); - - SetUserPolicies(policy_names_, default_values_, - policy::POLICY_LEVEL_RECOMMENDED); - SetUserValues(pref_names_, non_default_values_); - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - for (size_t i = 0; i < pref_names_.size(); ++i) { - VerifyClearPref(pref_names_[i], default_values_[i], false); - VerifyRollback(pref_names_[i], non_default_values_[i], std::string()); - } -} - -// Verifies that when preference values change in the C++ backend, the correct -// notifications fire in JavaScript. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, NotificationsOnBackendChanges) { - UseDefaultTestPrefs(false); - std::string observed_json; - - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - - // Verify notifications when recommended values come into effect. - StartObserving(); - SetUserPolicies(policy_names_, non_default_values_, - policy::POLICY_LEVEL_RECOMMENDED); - FinishObserving(&observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, - "recommended", false, false); - - // Verify notifications when mandatory values come into effect. - StartObserving(); - SetUserPolicies(policy_names_, non_default_values_, - policy::POLICY_LEVEL_MANDATORY); - FinishObserving(&observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "policy", - true, false); - - // Verify notifications when default values come into effect. - StartObserving(); - ClearUserPolicies(); - FinishObserving(&observed_json); - VerifyObservedPrefs(observed_json, pref_names_, default_values_, - std::string(), false, false); - - // Verify notifications when user-modified values come into effect. - StartObserving(); - SetUserValues(pref_names_, non_default_values_); - FinishObserving(&observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, - std::string(), false, false); -} - -#if defined(OS_CHROMEOS) - -// Verifies that initializing the JavaScript Preferences class fires the correct -// notifications in JavaScript for pref values handled by the -// CoreChromeOSOptionsHandler class. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, ChromeOSDeviceFetchPrefs) { - std::string observed_json; - - // Boolean pref. - pref_names_.push_back(chromeos::kAccountsPrefAllowGuest); - default_values_.push_back(base::MakeUnique<base::Value>(true)); - - // String pref. - pref_names_.push_back(chromeos::kReleaseChannel); - default_values_.push_back(base::MakeUnique<base::Value>("")); - - // List pref. - pref_names_.push_back(chromeos::kAccountsPrefUsers); - default_values_.push_back(base::MakeUnique<base::ListValue>()); - - // Verify notifications when default values are in effect. - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, default_values_, "owner", - true, false); -} - -// Verifies that initializing the JavaScript Preferences class fires the correct -// notifications in JavaScript for non-privileged pref values handled by the -// CoreChromeOSOptionsHandler class. -IN_PROC_BROWSER_TEST_F(PreferencesBrowserTest, - ChromeOSDeviceFetchNonPrivilegedPrefs) { - std::vector<std::unique_ptr<base::Value>> decorated_non_default_values; - std::string observed_json; - - // Non-privileged string pref. - pref_names_.push_back(chromeos::kSystemTimezone); - default_values_.push_back( - base::MakeUnique<base::Value>("America/Los_Angeles")); - non_default_values_.push_back( - base::MakeUnique<base::Value>("America/New_York")); - decorated_non_default_values.push_back( - non_default_values_.back()->CreateDeepCopy()); - - // Verify notifications when default values are in effect. - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, default_values_, - std::string(), false, false); - - chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); - cros_settings->Set(pref_names_[0], *non_default_values_[0]); - - // Verify notifications when non-default values are in effect. - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, decorated_non_default_values, - std::string(), false, false); -} - -class ManagedPreferencesBrowserTest : public PreferencesBrowserTest { - protected: - // PreferencesBrowserTest implementation: - void SetUpInProcessBrowserTestFixture() override { - // Set up fake install attributes. - std::unique_ptr<chromeos::StubInstallAttributes> attributes = - base::MakeUnique<chromeos::StubInstallAttributes>(); - attributes->SetCloudManaged("example.com", "fake-id"); - policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( - attributes.release()); - - PreferencesBrowserTest::SetUpInProcessBrowserTestFixture(); - } -}; - -// Verifies that initializing the JavaScript Preferences class fires the correct -// notifications in JavaScript for pref values handled by the -// CoreChromeOSOptionsHandler class for a managed device. -IN_PROC_BROWSER_TEST_F(ManagedPreferencesBrowserTest, - ChromeOSDeviceFetchPrefs) { - std::vector<std::unique_ptr<base::Value>> decorated_non_default_values; - std::string observed_json; - - // Boolean pref. - pref_names_.push_back(chromeos::kAccountsPrefAllowGuest); - non_default_values_.push_back(base::MakeUnique<base::Value>(false)); - decorated_non_default_values.push_back( - non_default_values_.back()->CreateDeepCopy()); - - // String pref. - pref_names_.push_back(chromeos::kReleaseChannel); - non_default_values_.push_back( - base::MakeUnique<base::Value>("stable-channel")); - decorated_non_default_values.push_back( - non_default_values_.back()->CreateDeepCopy()); - - // List pref. - pref_names_.push_back(chromeos::kAccountsPrefUsers); - auto list = base::MakeUnique<base::ListValue>(); - list->AppendString("me@google.com"); - list->AppendString("you@google.com"); - non_default_values_.push_back(std::move(list)); - list = base::MakeUnique<base::ListValue>(); - auto dict = base::MakeUnique<base::DictionaryValue>(); - dict->SetString("username", "me@google.com"); - dict->SetString("name", "me@google.com"); - dict->SetString("email", ""); - dict->SetBoolean("owner", false); - list->Append(std::move(dict)); - dict = base::MakeUnique<base::DictionaryValue>(); - dict->SetString("username", "you@google.com"); - dict->SetString("name", "you@google.com"); - dict->SetString("email", ""); - dict->SetBoolean("owner", false); - list->Append(std::move(dict)); - decorated_non_default_values.push_back(std::move(list)); - - chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); - for (size_t i = 0; i < pref_names_.size(); ++i) { - cros_settings->Set(pref_names_[i], *non_default_values_[i]); - } - - // Verify notifications when mandatory values are in effect. - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, decorated_non_default_values, - "policy", true, false); -} - -// Verifies that initializing the JavaScript Preferences class fires the correct -// notifications in JavaScript for non-privileged pref values handled by the -// CoreChromeOSOptionsHandler class for a managed device. -IN_PROC_BROWSER_TEST_F(ManagedPreferencesBrowserTest, - ChromeOSDeviceFetchNonPrivilegedPrefs) { - std::vector<std::unique_ptr<base::Value>> decorated_non_default_values; - std::string observed_json; - - // Non-privileged string pref. - pref_names_.push_back(chromeos::kSystemTimezone); - non_default_values_.push_back( - base::MakeUnique<base::Value>("America/New_York")); - decorated_non_default_values.push_back( - non_default_values_.back()->CreateDeepCopy()); - - // Verify notifications when mandatory values are in effect. - chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); - cros_settings->Set(pref_names_[0], *non_default_values_[0]); - - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, decorated_non_default_values, - std::string(), false, false); -} - -namespace { - -const char* kUserProfilePath = "user_profile"; - -} // namespace - -class ProxyPreferencesBrowserTest : public PreferencesBrowserTest { - public: - void SetUpOnMainThread() override { - SetupNetworkEnvironment(); - content::RunAllPendingInMessageLoop(); - - std::unique_ptr<base::DictionaryValue> proxy_config_dict( - ProxyConfigDictionary::CreateFixedServers("127.0.0.1:8080", - "*.google.com, 1.2.3.4:22")); - - ProxyConfigDictionary proxy_config(std::move(proxy_config_dict)); - - const chromeos::NetworkState* network = GetDefaultNetwork(); - ASSERT_TRUE(network); - chromeos::proxy_config::SetProxyConfigForNetwork(proxy_config, *network); - - std::string url = base::StringPrintf("%s?network=%s", - chrome::kChromeUIProxySettingsURL, - network->guid().c_str()); - - ui_test_utils::NavigateToURL(browser(), GURL(url)); - SetUpPrefs(); - } - - protected: - void SetupNetworkEnvironment() { - chromeos::ShillProfileClient::TestInterface* profile_test = - chromeos::DBusThreadManager::Get()->GetShillProfileClient() - ->GetTestInterface(); - chromeos::ShillServiceClient::TestInterface* service_test = - chromeos::DBusThreadManager::Get()->GetShillServiceClient() - ->GetTestInterface(); - - profile_test->AddProfile(kUserProfilePath, "user"); - - service_test->ClearServices(); - service_test->AddService("stub_ethernet", - "stub_ethernet_guid", - "eth0", - shill::kTypeEthernet, - shill::kStateOnline, - true /* add_to_visible */ ); - service_test->SetServiceProperty("stub_ethernet", shill::kProfileProperty, - base::Value(kUserProfilePath)); - profile_test->AddService(kUserProfilePath, "stub_wifi2"); - } - - void SetONCPolicy(const char* policy_name, policy::PolicyScope scope) { - std::string onc_policy = - "{ \"NetworkConfigurations\": [" - " { \"GUID\": \"stub_ethernet_guid\"," - " \"Type\": \"Ethernet\"," - " \"Name\": \"My Ethernet\"," - " \"Ethernet\": {" - " \"Authentication\": \"None\" }," - " \"ProxySettings\": {" - " \"PAC\": \"http://domain.com/x\"," - " \"Type\": \"PAC\" }" - " }" - " ]," - " \"Type\": \"UnencryptedConfiguration\"" - "}"; - - policy::PolicyMap map; - map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY, scope, - policy::POLICY_SOURCE_CLOUD, - base::MakeUnique<base::Value>(onc_policy), nullptr); - policy_provider_.UpdateChromePolicy(map); - - content::RunAllPendingInMessageLoop(); - } - - const chromeos::NetworkState* GetDefaultNetwork() { - chromeos::NetworkStateHandler* handler = - chromeos::NetworkHandler::Get()->network_state_handler(); - return handler->DefaultNetwork(); - } - - void SetProxyPref(const std::string& name, const base::Value& value) { - std::string type; - switch (value.GetType()) { - case base::Value::Type::BOOLEAN: - type = "Boolean"; - break; - case base::Value::Type::INTEGER: - type = "Integer"; - break; - case base::Value::Type::STRING: - type = "String"; - break; - default: - ASSERT_TRUE(false); - } - - std::string observed_json; - SetPref(name, type, value.CreateDeepCopy(), true, &observed_json); - } - - void VerifyCurrentProxyServer(const std::string& expected_server, - onc::ONCSource expected_source) { - const chromeos::NetworkState* network = GetDefaultNetwork(); - ASSERT_TRUE(network); - onc::ONCSource actual_source; - std::unique_ptr<ProxyConfigDictionary> proxy_dict = - chromeos::proxy_config::GetProxyConfigForNetwork( - g_browser_process->local_state(), pref_service(), *network, - &actual_source); - ASSERT_TRUE(proxy_dict); - std::string actual_proxy_server; - EXPECT_TRUE(proxy_dict->GetProxyServer(&actual_proxy_server)); - EXPECT_EQ(expected_server, actual_proxy_server); - EXPECT_EQ(expected_source, actual_source); - } -}; - -// Verifies that proxy settings are correctly pushed to JavaScript during -// initialization of the proxy settings page. -IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSInitializeProxy) { - // Boolean pref. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxySingle); - non_default_values_.push_back(base::MakeUnique<base::Value>(true)); - - // Integer prefs. - pref_names_.push_back( - chromeos::proxy_cros_settings_parser::kProxySingleHttpPort); - non_default_values_.push_back(base::MakeUnique<base::Value>(8080)); - - // String pref. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxySingleHttp); - non_default_values_.push_back(base::MakeUnique<base::Value>("127.0.0.1")); - - // List pref. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxyIgnoreList); - auto list = base::MakeUnique<base::ListValue>(); - list->AppendString("*.google.com"); - list->AppendString("1.2.3.4:22"); - non_default_values_.push_back(std::move(list)); - - // Verify that no policy is presented to the UI. This must be verified on the - // kProxyType and the kUseSharedProxies prefs. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxyType); - non_default_values_.push_back(base::MakeUnique<base::Value>(2)); - - pref_names_.push_back(proxy_config::prefs::kUseSharedProxies); - non_default_values_.push_back(base::MakeUnique<base::Value>(false)); - - std::string observed_json; - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "", - false, false); -} - -IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ONCPolicy) { - SetONCPolicy(policy::key::kOpenNetworkConfiguration, - policy::POLICY_SCOPE_USER); - - // Verify that per-network policy is presented to the UI. This must be - // verified on the kProxyType. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxyType); - non_default_values_.push_back(base::MakeUnique<base::Value>(3)); - - std::string observed_json; - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "policy", - true, false); - - // Verify that 'use-shared-proxies' is not affected by per-network policy. - pref_names_.clear(); - non_default_values_.clear(); - pref_names_.push_back(proxy_config::prefs::kUseSharedProxies); - non_default_values_.push_back(base::MakeUnique<base::Value>(false)); - - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "", - false, false); -} - -IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, DeviceONCPolicy) { - SetONCPolicy(policy::key::kDeviceOpenNetworkConfiguration, - policy::POLICY_SCOPE_MACHINE); - - // Verify that the policy is presented to the UI. This verification must be - // done on the kProxyType pref. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxyType); - non_default_values_.push_back(base::MakeUnique<base::Value>(3)); - - std::string observed_json; - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "policy", - true, false); - - // Verify that 'use-shared-proxies' is not affected by per-network policy. - pref_names_.clear(); - non_default_values_.clear(); - pref_names_.push_back(proxy_config::prefs::kUseSharedProxies); - non_default_values_.push_back(base::MakeUnique<base::Value>(false)); - - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "", - false, false); -} - -IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, UserProxyPolicy) { - policy_names_.push_back(policy::key::kProxyMode); - default_values_.push_back( - base::MakeUnique<base::Value>(ProxyPrefs::kAutoDetectProxyModeName)); - SetUserPolicies(policy_names_, default_values_, - policy::POLICY_LEVEL_MANDATORY); - content::RunAllPendingInMessageLoop(); - - // Verify that the policy is presented to the UI. This verification must be - // done on the kProxyType pref. - pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxyType); - non_default_values_.push_back(base::MakeUnique<base::Value>(3)); - - // Verify that 'use-shared-proxies' is controlled by the policy. - pref_names_.push_back(proxy_config::prefs::kUseSharedProxies); - non_default_values_.push_back(base::MakeUnique<base::Value>(false)); - - std::string observed_json; - SetupJavaScriptTestEnvironment(pref_names_, &observed_json); - VerifyObservedPrefs(observed_json, pref_names_, non_default_values_, "policy", - true, false); -} - -// Verifies that modifications to the proxy settings are correctly pushed from -// JavaScript to the ProxyConfig property stored in the network configuration. -IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSSetProxy) { - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySingleHttpPort, - base::Value(123)); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySingleHttp, - base::Value("www.adomain.xy")); - - VerifyCurrentProxyServer("www.adomain.xy:123", - onc::ONC_SOURCE_NONE); -} - -// Verify that default proxy ports are used and that ports can be updated -// without affecting the previously set hosts. -IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSProxyDefaultPorts) { - ASSERT_NO_FATAL_FAILURE(SetupJavaScriptTestEnvironment(pref_names_, NULL)); - - // Set to manual, per scheme proxy. - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySingle, - base::Value(false)); - - // Set hosts but no ports. - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyHttpUrl, - base::Value("a.com")); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyHttpsUrl, - base::Value("4.3.2.1")); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyFtpUrl, - base::Value("c.com")); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySocks, - base::Value("d.com")); - - // Verify default ports. - VerifyCurrentProxyServer( - "http=a.com:80;https=4.3.2.1:80;ftp=c.com:80;socks=socks4://d.com:1080", - onc::ONC_SOURCE_NONE); - - // Set and verify the ports. - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyHttpPort, - base::Value(1)); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyHttpsPort, - base::Value(2)); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyFtpPort, - base::Value(3)); - SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySocksPort, - base::Value(4)); - - VerifyCurrentProxyServer( - "http=a.com:1;https=4.3.2.1:2;ftp=c.com:3;socks=socks4://d.com:4", - onc::ONC_SOURCE_NONE); -} - -#endif diff --git a/chromium/chrome/browser/ui/webui/options/preferences_browsertest.h b/chromium/chrome/browser/ui/webui/options/preferences_browsertest.h deleted file mode 100644 index d2136d36e8a..00000000000 --- a/chromium/chrome/browser/ui/webui/options/preferences_browsertest.h +++ /dev/null @@ -1,196 +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 CHROME_BROWSER_UI_WEBUI_OPTIONS_PREFERENCES_BROWSERTEST_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_PREFERENCES_BROWSERTEST_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "components/policy/core/common/mock_configuration_policy_provider.h" -#include "components/policy/core/common/policy_types.h" -#include "components/prefs/pref_change_registrar.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/notification_observer.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace base { -class DictionaryValue; -class Value; -} - -namespace content { -class RenderViewHost; -} - -// Tests verifying that the JavaScript Preferences class, the underlying C++ -// CoreOptionsHandler and the specialized classes handling Chrome OS device and -// proxy prefs behave correctly. -class PreferencesBrowserTest : public InProcessBrowserTest { - public: - PreferencesBrowserTest(); - ~PreferencesBrowserTest() override; - - // InProcessBrowserTest implementation: - void SetUpOnMainThread() override; - void TearDownOnMainThread() override; - - void OnPreferenceChanged(const std::string& pref_name); - - protected: - MOCK_METHOD1(OnCommit, void(const PrefService::Preference*)); - - // The pref service that holds the current pref values in the C++ backend. - PrefService* pref_service(); - - void SetUpPrefs(); - - // InProcessBrowserTest implementation: - void SetUpInProcessBrowserTestFixture() override; - - // Sets user policies through the mock policy provider. - void SetUserPolicies(const std::vector<std::string>& names, - const std::vector<std::unique_ptr<base::Value>>& values, - policy::PolicyLevel level); - // Clears user policies. - void ClearUserPolicies(); - // Set user-modified pref values directly in the C++ backend. - void SetUserValues(const std::vector<std::string>& names, - const std::vector<std::unique_ptr<base::Value>>& values); - - // Verifies that a dictionary contains a (key, value) pair. Takes ownership of - // |expected|. - void VerifyKeyValue(const base::DictionaryValue& dict, - const std::string& key, - const base::Value& expected); - // Verifies that a dictionary contains a given pref and that its value has - // been decorated correctly. - void VerifyPref(const base::DictionaryValue* prefs, - const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy, - bool disabled, - bool uncommitted); - // Verifies that a notification received from the JavaScript Preferences - // class contains a given pref and that its value has been decorated - // correctly. - void VerifyObservedPref(const std::string& observed_json, - const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy, - bool disabled, - bool uncommitted); - // Verifies that notifications received from the JavaScript Preferences class - // contain the given prefs and that their values have been decorated - // correctly. - void VerifyObservedPrefs( - const std::string& observed_json, - const std::vector<std::string>& names, - const std::vector<std::unique_ptr<base::Value>>& values, - const std::string& controlledBy, - bool disabled, - bool uncommitted); - - // Sets up the expectation that the JavaScript Preferences class will make no - // change to a user-modified pref value in the C++ backend. - void ExpectNoCommit(const std::string& name); - // Sets up the expectation that the JavaScript Preferences class will set a - // user-modified pref value in the C++ backend. - void ExpectSetCommit(const std::string& name, - const std::unique_ptr<base::Value>& value); - // Sets up the expectation that the JavaScript Preferences class will clear a - // user-modified pref value in the C++ backend. - void ExpectClearCommit(const std::string& name); - // Verifies that previously set expectations are met and clears them. - void VerifyAndClearExpectations(); - - // Sets up the JavaScript part of the test environment. - void SetupJavaScriptTestEnvironment( - const std::vector<std::string>& pref_names, - std::string* observed_json) const; - - // Sets a value through the JavaScript Preferences class as if the user had - // modified it. Returns the observation which can be verified using the - // VerifyObserved* methods. - void SetPref(const std::string& name, - const std::string& type, - const std::unique_ptr<base::Value>& value, - bool commit, - std::string* observed_json); - - // Verifies that setting a user-modified pref value through the JavaScript - // Preferences class fires the correct notification in JavaScript and commits - // the change to C++ if |commit| is true. - void VerifySetPref(const std::string& name, - const std::string& type, - const std::unique_ptr<base::Value>& value, - bool commit); - // Verifies that clearing a user-modified pref value through the JavaScript - // Preferences class fires the correct notification in JavaScript and does - // respectively does not cause the change to be committed to the C++ backend. - void VerifyClearPref(const std::string& name, - const std::unique_ptr<base::Value>& value, - bool commit); - // Verifies that committing a previously made change of a user-modified pref - // value through the JavaScript Preferences class fires the correct - // notification in JavaScript. - void VerifyCommit(const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy); - // Verifies that committing a previously set user-modified pref value through - // the JavaScript Preferences class fires the correct notification in - // JavaScript and causes the change to be committed to the C++ backend. - void VerifySetCommit(const std::string& name, - const std::unique_ptr<base::Value>& value); - // Verifies that committing the previously cleared user-modified pref value - // through the JavaScript Preferences class fires the correct notification in - // JavaScript and causes the change to be committed to the C++ backend. - void VerifyClearCommit(const std::string& name, - const std::unique_ptr<base::Value>& value); - // Verifies that rolling back a previously made change of a user-modified pref - // value through the JavaScript Preferences class fires the correct - // notification in JavaScript and does not cause the change to be committed to - // the C++ backend. - void VerifyRollback(const std::string& name, - const std::unique_ptr<base::Value>& value, - const std::string& controlledBy); - // Start observing notifications sent by the JavaScript Preferences class for - // pref values changes. - void StartObserving(); - // Change the value of a sentinel pref in the C++ backend and finish observing - // notifications sent by the JavaScript Preferences class when the - // notification for this pref is received. - void FinishObserving(std::string* observed_json); - - // Populate the lists of test prefs and corresponding policies with default - // values used by most tests. - void UseDefaultTestPrefs(bool includeListPref); - - // The current tab's render view host, required to inject JavaScript code into - // the tab. - content::RenderViewHost* render_view_host_; - - // Mock policy provider for both user and device policies. - policy::MockConfigurationPolicyProvider policy_provider_; - - // Pref change registrar that detects changes to user-modified pref values - // made in the C++ backend by the JavaScript Preferences class. - std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; - - // The prefs and corresponding policies used by the current test. - std::vector<std::string> types_; - std::vector<std::string> pref_names_; - std::vector<std::string> policy_names_; - std::vector<std::unique_ptr<base::Value>> default_values_; - std::vector<std::unique_ptr<base::Value>> non_default_values_; - - private: - DISALLOW_COPY_AND_ASSIGN(PreferencesBrowserTest); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_PREFERENCES_BROWSERTEST_H_ diff --git a/chromium/chrome/browser/ui/webui/options/profile_settings_reset_browsertest.js b/chromium/chrome/browser/ui/webui/options/profile_settings_reset_browsertest.js deleted file mode 100644 index 2bd7a053aab..00000000000 --- a/chromium/chrome/browser/ui/webui/options/profile_settings_reset_browsertest.js +++ /dev/null @@ -1,38 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for profile settings reset WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function ProfileSettingsResetWebUITest() {} - -ProfileSettingsResetWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Browse to the reset profile settings page. - */ - browsePreload: 'chrome://settings-frame/resetProfileSettings', - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/570551 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#reset-profile-settings-overlay > .action-area > .hbox.stretch > A'); - }, -}; - -// Test opening the profile settings reset has correct location. -TEST_F('ProfileSettingsResetWebUITest', 'testOpenProfileSettingsReset', - function() { - assertEquals(this.browsePreload, document.location.href); - }); diff --git a/chromium/chrome/browser/ui/webui/options/search_engine_manager_browsertest.js b/chromium/chrome/browser/ui/webui/options/search_engine_manager_browsertest.js deleted file mode 100644 index 88b4a27c2f9..00000000000 --- a/chromium/chrome/browser/ui/webui/options/search_engine_manager_browsertest.js +++ /dev/null @@ -1,26 +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. - -/** - * TestFixture for search engine manager WebUI testing. - * @extends {testing.Test} - * @constructor - */ -function SearchEngineManagerWebUITest() {} - -SearchEngineManagerWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** - * Browse to the search engine manager. - */ - browsePreload: 'chrome://settings-frame/searchEngines', -}; - -// Disabled due to flaky timeouts; see crbug.com/205693 . -// Test opening the search engine manager has correct location. -TEST_F('SearchEngineManagerWebUITest', 'DISABLED_testOpenSearchEngineManager', - function() { - assertEquals(this.browsePreload, document.location.href); - }); diff --git a/chromium/chrome/browser/ui/webui/options/settings_format_browsertest.js b/chromium/chrome/browser/ui/webui/options/settings_format_browsertest.js deleted file mode 100644 index a84873fede6..00000000000 --- a/chromium/chrome/browser/ui/webui/options/settings_format_browsertest.js +++ /dev/null @@ -1,176 +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. - -GEN_INCLUDE(['options_browsertest_base.js']); - -/** - * TestFixture for testing the formatting of settings pages. - * @extends {testing.Test} - * @constructor - */ -function SettingsFormatWebUITest() {} - -/** - * Map of rule exemptions grouped by test. - * @const - */ -SettingsFormatWebUITest.Filters = { - /** - * Exemption for checkboxes that do not require an id or pref property. - * Input methods use inputMethodId instead of id for unique identification. - */ - 'pref': ['language-options-input-method-template', - 'language-options-input-method-list'] -}; - -/** - * Collection of error messages. - * @const - */ -SettingsFormatWebUITest.Messages = { - MISSING_CHECK_WRAPPER: 'Element $1 should be enclosed in <div class="$2">', - MISSING_ID_OR_PREF: 'Missing id or pref preoperty for checkbox $1.', - MISSING_RADIO_BUTTON_NAME: 'Radio button $1 is missing the name property', - MISSING_RADIO_BUTTON_VALUE: 'Radio button $1 is missing the value property', -}; - -SettingsFormatWebUITest.prototype = { - __proto__: OptionsBrowsertestBase.prototype, - - /** - * Navigate to browser settings. - */ - browsePreload: 'chrome://settings-frame/', - - /** - * List of errors generated during a test. Used instead of expect* functions - * to suppress verbosity. The implementation of errorsToMessage in the - * testing API generates a call stack for each error produced which greatly - * reduces readability. - * @type {Array<string>} - */ - errors: null, - - /** @override */ - setUp: function() { - OptionsBrowsertestBase.prototype.setUp.call(this); - - this.errors = []; - - // Enable when failure is resolved. - // AX_TEXT_04: http://crbug.com/570727 - this.accessibilityAuditConfig.ignoreSelectors( - 'linkWithUnclearPurpose', - '#sync-overview > A'); - - // Enable when failure is resolved. - // AX_ARIA_10: http://crbug.com/570725 - this.accessibilityAuditConfig.ignoreSelectors( - 'unsupportedAriaAttribute', - '#profiles-list'); - }, - - tearDown: function() { - assertTrue(this.errors.length == 0, '\n' + this.errors.join('\n')); - }, - - /** - * Generates a failure message. During tear down of the test, the accumulation - * of pending messages triggers a test failure. - * @param {string} key Label of the message formatting string. - * @param {!Element} element The element that triggered the failure. - * @param {...string} args Additional arguments for formatting the message. - */ - fail: function(key, element, args) { - var subs = [this.getLabel(element)].concat( - Array.prototype.slice.call(arguments, 2)); - var message = SettingsFormatWebUITest.Messages[key].replace( - /\$\d/g, - function(m) { - return subs[m[1] - 1] || '$' + m[1]; - }); - assertFalse(/\$\d/.test(message), 'found unreplaced subs'); - this.errors.push(message); - }, - - /** - * String for identifying a node within an error message. - * @param {!Element} element The target element to identify. - * @return {string} Name to facilitate tracking down the element. - */ - getLabel: function(element) { - if (element.id) - return element.id; - - if (element.pref) - return element.pref; - - if (element.name && element.value) - return element.name + '-' + element.value; - - return this.getLabel(element.parentNode); - }, - - - /** - * Checks if the node is exempt from following the formatting rule. - * @param {!Element} element The candidate element. - * @param {Array<string>} filters List of exemptions. - * @return {boolean} True if the element is exempt. - */ - isExempt: function(element, filters) { - var target = this.getLabel(element); - for (var i = 0; i < filters.length; i++) { - if (filters[i] == target) - return true; - } - return false; - } -}; - -/** - * Ensure that radio and checkbox buttons have consistent layout. - */ -TEST_F('SettingsFormatWebUITest', 'RadioCheckboxStyleCheck', function() { - var settings = $('settings'); - assertTrue(settings != null, 'Unable to access settings'); - var query = 'input[type=checkbox], input[type=radio]'; - var elements = document.querySelectorAll(query); - assertTrue(elements.length > 0); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - if (!findAncestorByClass(element, element.type)) - this.fail('MISSING_CHECK_WRAPPER', element, element.type); - } -}); - -/** - * Each checkbox requires an id or pref property. - */ -// Flaky crashes on all platforms; http://crbug.com/613034. -TEST_F('SettingsFormatWebUITest', 'DISABLED_CheckboxIdOrPrefCheck', function() { - var query = - 'input[type=checkbox]:not([pref]):not([id]):not(.spacer-checkbox)'; - var elements = document.querySelectorAll(query); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - if (!this.isExempt(element, SettingsFormatWebUITest.Filters['pref'])) - this.fail('MISSING_ID_OR_PREF', element); - } -}); - -/** - * Each radio button requires name and value properties. - */ -TEST_F('SettingsFormatWebUITest', 'RadioButtonNameValueCheck', function() { - var elements = document.querySelectorAll('input[type=radio]'); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - if (!element.name) - this.fail('MISSING_RADIO_BUTTON_NAME', element); - - if (!element.getAttribute('value')) - this.fail('MISSING_RADIO_BUTTON_VALUE', element); - } -}); diff --git a/chromium/chrome/browser/ui/webui/options/startup_page_list_browsertest.js b/chromium/chrome/browser/ui/webui/options/startup_page_list_browsertest.js deleted file mode 100644 index 1df6e28c69b..00000000000 --- a/chromium/chrome/browser/ui/webui/options/startup_page_list_browsertest.js +++ /dev/null @@ -1,151 +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. - -/** - * Fixture for startup pages WebUI tests. - * @extends {testing.Test} - * @constructor - */ -function StartupPageListWebUITest() {} - -StartupPageListWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** - * Browse to the options page & call our preLoad(). - * @override - */ - browsePreload: 'chrome://settings-frame/startup', - - /** @override */ - setUp: function() { - StartupOverlay.updateStartupPages(this.fakeStartupList); - // 1 item for entering data, 1+ from |this.fakeStartupList|. - assertGE(this.getList().items.length, 2); - }, - - /** - * Returns the list to be tested. - * @return {Element} The start-up pages list. - * @protected - */ - getList: function() { - return $('startupPagesList'); - }, - - /** - * Register a mock handler to ensure expectations are met and options pages - * behave correctly. - * @override - */ - preLoad: function() { - this.makeAndRegisterMockHandler(['addStartupPage', - 'dragDropStartupPage']); - }, - - /** - * A fake list of startup pages to send to the overlay. - * @protected - */ - fakeStartupList: [ - { - title: 'Yahoo!', - url: 'http://yahoo.com', - tooltip: 'Yahoo! homepage', - modelIndex: 0 - }, - { - title: 'Facebook', - url: 'http://facebook.com', - tooltip: 'Facebook :: Sign In', - modelIndex: 1 - } - ], -}; - -(function() { - -/** - * A mock data transfer object for drag/drop events. - * @constructor - */ -function MockDataTransfer() { - /** - * The data this dataTransfer object knows about. - * @type {!Object<string>} - * @private - */ - this.data_ = {}; -} - -/** - * Installs a lazily created MockDataTransfer on event#dataTransfer. - * @param {!Event} event An event to modify. - */ -MockDataTransfer.install = function(event) { - event.__defineGetter__('dataTransfer', function() { - event.dataTransfer_ = event.dataTransfer_ || new MockDataTransfer; - return event.dataTransfer_; - }); -}; - -MockDataTransfer.prototype = { - /** - * The URL data in this mock drop event. - * @param {string} type The text of data being set. - * @param {*} val The data to set. Will be stringified. - */ - setData: function(type, val) { - this.data_[type] = String(val); - }, - - /** - * Gets data associated with this fake data transfer. - * @param {string} type The type of data to get. - * @return {string} The requested type of data or '' if not set. - */ - getData: function(type) { - return this.data_[type] || ''; - }, -}; - -/** - * Creates a fake bubbling, cancelable mouse event with a mock data transfer - * installed. - * @param {string} type A type of mouse event (e.g. 'drop'). - * @return {!Event} A fake mouse event. - */ -function createMouseEvent(type) { - var event = new MouseEvent(type, {bubbles: true, cancelable: true}); - MockDataTransfer.install(event); - return event; -} - -// Disabled due to: crbug.com/419370 -TEST_F('StartupPageListWebUITest', 'DISABLED_testDropFromOutsideSource', - function() { - /** @const */ var NEW_PAGE = 'http://google.com'; - - var mockDropEvent = createMouseEvent('drop'); - mockDropEvent.dataTransfer.setData('url', NEW_PAGE); - - this.mockHandler.expects(once()).addStartupPage([NEW_PAGE, 0]); - - this.getList().items[0].dispatchEvent(mockDropEvent); - - expectTrue(mockDropEvent.defaultPrevented); -}); - -// Disabled due to: crbug.com/419370 -TEST_F('StartupPageListWebUITest', 'DISABLED_testDropToReorder', function() { - // TODO(dbeam): mock4js doesn't handle complex arguments well. Fix this. - this.mockHandler.expects(once()).dragDropStartupPage([0, [1].join()]); - - this.getList().selectionModel.selectedIndex = 1; - expectEquals(1, this.getList().selectionModel.selectedIndexes.length); - - this.getList().items[0].dispatchEvent(createMouseEvent('drop')); -}); - -}()); diff --git a/chromium/chrome/browser/ui/webui/options/startup_pages_handler.cc b/chromium/chrome/browser/ui/webui/options/startup_pages_handler.cc index b80a4c07e3c..70e46552469 100644 --- a/chromium/chrome/browser/ui/webui/options/startup_pages_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/startup_pages_handler.cc @@ -150,7 +150,8 @@ void StartupPagesHandler::OnItemsRemoved(int start, int length) { void StartupPagesHandler::SetStartupPagesToCurrentPages( const base::ListValue* args) { - startup_custom_pages_table_model_->SetToCurrentlyOpenPages(); + startup_custom_pages_table_model_->SetToCurrentlyOpenPages( + web_ui()->GetWebContents()); } void StartupPagesHandler::RemoveStartupPages(const base::ListValue* args) { diff --git a/chromium/chrome/browser/ui/webui/options/sync_setup_handler.cc b/chromium/chrome/browser/ui/webui/options/sync_setup_handler.cc index 6c4e9b632f0..de91eaf7914 100644 --- a/chromium/chrome/browser/ui/webui/options/sync_setup_handler.cc +++ b/chromium/chrome/browser/ui/webui/options/sync_setup_handler.cc @@ -38,7 +38,6 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/locale_settings.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/browser_sync/profile_sync_service.h" diff --git a/chromium/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc b/chromium/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc deleted file mode 100644 index e24b055d615..00000000000 --- a/chromium/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc +++ /dev/null @@ -1,951 +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 "chrome/browser/ui/webui/options/sync_setup_handler.h" - -#include <memory> -#include <string> -#include <vector> - -#include "base/command_line.h" -#include "base/json/json_writer.h" -#include "base/macros.h" -#include "base/stl_util.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/signin/fake_signin_manager_builder.h" -#include "chrome/browser/signin/signin_error_controller_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/sync/profile_sync_test_util.h" -#include "chrome/browser/ui/webui/signin/login_ui_service.h" -#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/scoped_testing_local_state.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" -#include "components/prefs/pref_service.h" -#include "components/signin/core/browser/fake_auth_status_provider.h" -#include "components/signin/core/browser/signin_manager.h" -#include "components/sync/base/sync_prefs.h" -#include "content/public/browser/web_ui.h" -#include "content/public/test/test_browser_thread.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_web_ui.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/layout.h" - -using ::testing::_; -using ::testing::Mock; -using ::testing::Return; -using ::testing::ReturnRef; -using ::testing::Values; -using browser_sync::ProfileSyncService; -using browser_sync::ProfileSyncServiceMock; - -typedef GoogleServiceAuthError AuthError; - -namespace { - -MATCHER_P(ModelTypeSetMatches, value, "") { - return arg == value; -} - -const char kTestUser[] = "chrome.p13n.test@gmail.com"; - -// Returns a ModelTypeSet with all user selectable types set. -syncer::ModelTypeSet GetAllTypes() { - return syncer::UserSelectableTypes(); -} - -enum SyncAllDataConfig { - SYNC_ALL_DATA, - CHOOSE_WHAT_TO_SYNC -}; - -enum EncryptAllConfig { - ENCRYPT_ALL_DATA, - ENCRYPT_PASSWORDS -}; - -enum PaymentsIntegrationConfig { - PAYMENTS_INTEGRATION_ENABLED, - PAYMENTS_INTEGRATION_DISABLED -}; - -// Create a json-format string with the key/value pairs appropriate for a call -// to HandleConfigure(). If |extra_values| is non-null, then the values from -// the passed dictionary are added to the json. -std::string GetConfiguration(const base::DictionaryValue* extra_values, - SyncAllDataConfig sync_all, - syncer::ModelTypeSet types, - const std::string& passphrase, - EncryptAllConfig encrypt_all, - PaymentsIntegrationConfig payments_integration) { - base::DictionaryValue result; - if (extra_values) - result.MergeDictionary(extra_values); - result.SetBoolean("syncAllDataTypes", sync_all == SYNC_ALL_DATA); - result.SetBoolean("encryptAllData", encrypt_all == ENCRYPT_ALL_DATA); - result.SetBoolean("usePassphrase", !passphrase.empty()); - if (!passphrase.empty()) - result.SetString("passphrase", passphrase); - // Add all of our data types. - result.SetBoolean("appsSynced", types.Has(syncer::APPS)); - result.SetBoolean("autofillSynced", types.Has(syncer::AUTOFILL)); - result.SetBoolean("bookmarksSynced", types.Has(syncer::BOOKMARKS)); - result.SetBoolean("extensionsSynced", types.Has(syncer::EXTENSIONS)); - result.SetBoolean("passwordsSynced", types.Has(syncer::PASSWORDS)); - result.SetBoolean("preferencesSynced", types.Has(syncer::PREFERENCES)); - result.SetBoolean("tabsSynced", types.Has(syncer::PROXY_TABS)); - result.SetBoolean("themesSynced", types.Has(syncer::THEMES)); - result.SetBoolean("typedUrlsSynced", types.Has(syncer::TYPED_URLS)); - result.SetBoolean("paymentsIntegrationEnabled", - payments_integration == PAYMENTS_INTEGRATION_ENABLED); - std::string args; - base::JSONWriter::Write(result, &args); - return args; -} - -// Checks whether the passed |dictionary| contains a |key| with the given -// |expected_value|. If |omit_if_false| is true, then the value should only -// be present if |expected_value| is true. -void CheckBool(const base::DictionaryValue* dictionary, - const std::string& key, - bool expected_value, - bool omit_if_false) { - if (omit_if_false && !expected_value) { - EXPECT_FALSE(dictionary->HasKey(key)) << - "Did not expect to find value for " << key; - } else { - bool actual_value; - EXPECT_TRUE(dictionary->GetBoolean(key, &actual_value)) << - "No value found for " << key; - EXPECT_EQ(expected_value, actual_value) << - "Mismatch found for " << key; - } -} - -void CheckBool(const base::DictionaryValue* dictionary, - const std::string& key, - bool expected_value) { - return CheckBool(dictionary, key, expected_value, false); -} - -// Checks to make sure that the values stored in |dictionary| match the values -// expected by the showSyncSetupPage() JS function for a given set of data -// types. -void CheckConfigDataTypeArguments(const base::DictionaryValue* dictionary, - SyncAllDataConfig config, - syncer::ModelTypeSet types) { - CheckBool(dictionary, "syncAllDataTypes", config == SYNC_ALL_DATA); - CheckBool(dictionary, "appsSynced", types.Has(syncer::APPS)); - CheckBool(dictionary, "autofillSynced", types.Has(syncer::AUTOFILL)); - CheckBool(dictionary, "bookmarksSynced", types.Has(syncer::BOOKMARKS)); - CheckBool(dictionary, "extensionsSynced", types.Has(syncer::EXTENSIONS)); - CheckBool(dictionary, "passwordsSynced", types.Has(syncer::PASSWORDS)); - CheckBool(dictionary, "preferencesSynced", types.Has(syncer::PREFERENCES)); - CheckBool(dictionary, "tabsSynced", types.Has(syncer::PROXY_TABS)); - CheckBool(dictionary, "themesSynced", types.Has(syncer::THEMES)); - CheckBool(dictionary, "typedUrlsSynced", types.Has(syncer::TYPED_URLS)); -} - - -} // namespace - -class TestingSyncSetupHandler : public SyncSetupHandler { - public: - TestingSyncSetupHandler(content::WebUI* web_ui, Profile* profile) - : profile_(profile) { - set_web_ui(web_ui); - } - ~TestingSyncSetupHandler() override { set_web_ui(NULL); } - - void FocusUI() override {} - - Profile* GetProfile() const override { return profile_; } - - using SyncSetupHandler::is_configuring_sync; - - private: -#if !defined(OS_CHROMEOS) - void DisplayGaiaLoginInNewTabOrWindow( - signin_metrics::AccessPoint access_point) override {} -#endif - - // Weak pointer to parent profile. - Profile* profile_; - DISALLOW_COPY_AND_ASSIGN(TestingSyncSetupHandler); -}; - -// The boolean parameter indicates whether the test is run with ClientOAuth -// or not. The test parameter is a bool: whether or not to test with/ -// /ClientLogin enabled or not. -class SyncSetupHandlerTest : public testing::Test { - public: - SyncSetupHandlerTest() : error_(GoogleServiceAuthError::NONE) {} - void SetUp() override { - error_ = GoogleServiceAuthError::AuthErrorNone(); - - TestingProfile::Builder builder; - builder.AddTestingFactory(SigninManagerFactory::GetInstance(), - BuildFakeSigninManagerBase); - profile_ = builder.Build(); - - // Sign in the user. - mock_signin_ = static_cast<SigninManagerBase*>( - SigninManagerFactory::GetForProfile(profile_.get())); - std::string username = GetTestUser(); - if (!username.empty()) - mock_signin_->SetAuthenticatedAccountInfo(username, username); - - mock_pss_ = static_cast<ProfileSyncServiceMock*>( - ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile_.get(), BuildMockProfileSyncService)); - EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_)); - ON_CALL(*mock_pss_, GetPassphraseType()) - .WillByDefault(Return(syncer::PassphraseType::IMPLICIT_PASSPHRASE)); - ON_CALL(*mock_pss_, GetExplicitPassphraseTime()).WillByDefault( - Return(base::Time())); - ON_CALL(*mock_pss_, GetRegisteredDataTypes()) - .WillByDefault(Return(syncer::ModelTypeSet())); - - mock_pss_->Initialize(); - - handler_.reset(new TestingSyncSetupHandler(&web_ui_, profile_.get())); - } - - // Setup the expectations for calls made when displaying the config page. - void SetDefaultExpectationsForConfigPage() { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, GetRegisteredDataTypes()) - .WillRepeatedly(Return(GetAllTypes())); - EXPECT_CALL(*mock_pss_, GetPreferredDataTypes()) - .WillRepeatedly(Return(GetAllTypes())); - EXPECT_CALL(*mock_pss_, GetActiveDataTypes()) - .WillRepeatedly(Return(GetAllTypes())); - EXPECT_CALL(*mock_pss_, IsEncryptEverythingAllowed()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsEncryptEverythingEnabled()) - .WillRepeatedly(Return(false)); - } - - void SetupInitializedProfileSyncService() { - // An initialized ProfileSyncService will have already completed sync setup - // and will have an initialized sync engine. - ASSERT_TRUE(mock_signin_->IsInitialized()); - EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(true)); - } - - void ExpectConfig() { - ASSERT_EQ(1U, web_ui_.call_data().size()); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name()); - std::string page; - ASSERT_TRUE(data.arg1()->GetAsString(&page)); - EXPECT_EQ(page, "configure"); - } - - void ExpectDone() { - ASSERT_EQ(1U, web_ui_.call_data().size()); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name()); - std::string page; - ASSERT_TRUE(data.arg1()->GetAsString(&page)); - EXPECT_EQ(page, "done"); - } - - void ExpectSpinnerAndClose() { - // We expect a call to SyncSetupOverlay.showSyncSetupPage. - EXPECT_EQ(1U, web_ui_.call_data().size()); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name()); - - std::string page; - ASSERT_TRUE(data.arg1()->GetAsString(&page)); - EXPECT_EQ(page, "spinner"); - // Cancelling the spinner dialog will cause CloseSyncSetup(). - handler_->CloseSyncSetup(); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); - } - - // It's difficult to notify sync listeners when using a ProfileSyncServiceMock - // so this helper routine dispatches an OnStateChanged() notification to the - // SyncStartupTracker. - void NotifySyncListeners() { - if (handler_->sync_startup_tracker_) - handler_->sync_startup_tracker_->OnStateChanged(mock_pss_); - } - - virtual std::string GetTestUser() { - return std::string(kTestUser); - } - - content::TestBrowserThreadBundle thread_bundle_; - std::unique_ptr<Profile> profile_; - ProfileSyncServiceMock* mock_pss_; - GoogleServiceAuthError error_; - SigninManagerBase* mock_signin_; - content::TestWebUI web_ui_; - std::unique_ptr<TestingSyncSetupHandler> handler_; -}; - -class SyncSetupHandlerFirstSigninTest : public SyncSetupHandlerTest { - std::string GetTestUser() override { return std::string(); } -}; - -TEST_F(SyncSetupHandlerTest, Basic) { -} - -#if !defined(OS_CHROMEOS) -TEST_F(SyncSetupHandlerFirstSigninTest, DisplayBasicLogin) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - // Ensure that the user is not signed in before calling |HandleStartSignin()|. - SigninManager* manager = static_cast<SigninManager*>(mock_signin_); - manager->SignOut(signin_metrics::SIGNOUT_TEST, - signin_metrics::SignoutDelete::IGNORE_METRIC); - base::ListValue list_args; - handler_->HandleStartSignin(&list_args); - - // Sync setup hands off control to the gaia login tab. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); - - ASSERT_FALSE(handler_->is_configuring_sync()); - - handler_->CloseSyncSetup(); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); -} - -TEST_F(SyncSetupHandlerTest, ShowSyncSetupWhenNotSignedIn) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - handler_->HandleShowSetupUI(NULL); - - // We expect a call to SyncSetupOverlay.showSyncSetupPage. - ASSERT_EQ(1U, web_ui_.call_data().size()); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name()); - - ASSERT_FALSE(handler_->is_configuring_sync()); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); -} -#endif // !defined(OS_CHROMEOS) - -// Verifies that the sync setup is terminated correctly when the -// sync is disabled. -TEST_F(SyncSetupHandlerTest, HandleSetupUIWhenSyncDisabled) { - EXPECT_CALL(*mock_pss_, IsManaged()).WillRepeatedly(Return(true)); - handler_->HandleShowSetupUI(NULL); - - // Sync setup is closed when sync is disabled. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); - ASSERT_FALSE(handler_->is_configuring_sync()); -} - -// Verifies that the handler correctly handles a cancellation when -// it is displaying the spinner to the user. -TEST_F(SyncSetupHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - error_ = GoogleServiceAuthError::AuthErrorNone(); - EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false)); - - // We're simulating a user setting up sync, which would cause the engine to - // kick off initialization, but not download user data types. The sync - // engine will try to download control data types (e.g encryption info), but - // that won't finish for this test as we're simulating cancelling while the - // spinner is showing. - handler_->HandleShowSetupUI(NULL); - - EXPECT_EQ(handler_.get(), - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); - - ExpectSpinnerAndClose(); -} - -// Verifies that the handler correctly transitions from showing the spinner -// to showing a configuration page when sync setup completes successfully. -TEST_F(SyncSetupHandlerTest, - DisplayConfigureWithEngineDisabledAndSyncStartupCompleted) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - error_ = GoogleServiceAuthError::AuthErrorNone(); - // Sync engine is stopped initially, and will start up. - EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false)); - SetDefaultExpectationsForConfigPage(); - - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - // We expect a call to SyncSetupOverlay.showSyncSetupPage. - EXPECT_EQ(1U, web_ui_.call_data().size()); - - const content::TestWebUI::CallData& data0 = *web_ui_.call_data()[0]; - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data0.function_name()); - std::string page; - ASSERT_TRUE(data0.arg1()->GetAsString(&page)); - EXPECT_EQ(page, "spinner"); - - Mock::VerifyAndClearExpectations(mock_pss_); - // Now, act as if the ProfileSyncService has started up. - SetDefaultExpectationsForConfigPage(); - EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(true)); - error_ = GoogleServiceAuthError::AuthErrorNone(); - EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_)); - NotifySyncListeners(); - - // We expect a second call to SyncSetupOverlay.showSyncSetupPage. - EXPECT_EQ(2U, web_ui_.call_data().size()); - const content::TestWebUI::CallData& data1 = *web_ui_.call_data().back(); - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data1.function_name()); - ASSERT_TRUE(data1.arg1()->GetAsString(&page)); - EXPECT_EQ(page, "configure"); - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data1.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "passphraseFailed", false); - CheckBool(dictionary, "syncAllDataTypes", true); - CheckBool(dictionary, "encryptAllDataAllowed", true); - CheckBool(dictionary, "encryptAllData", false); - CheckBool(dictionary, "usePassphrase", false); -} - -// Verifies the case where the user cancels after the sync engine has -// initialized (meaning it already transitioned from the spinner to a proper -// configuration page, tested by -// DisplayConfigureWithEngineDisabledAndSyncStartupCompleted), but before the -// user has continued on. -TEST_F(SyncSetupHandlerTest, - DisplayConfigureWithEngineDisabledAndCancelAfterSigninSuccess) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - error_ = GoogleServiceAuthError::AuthErrorNone(); - EXPECT_CALL(*mock_pss_, IsEngineInitialized()) - .WillOnce(Return(false)) - .WillRepeatedly(Return(true)); - SetDefaultExpectationsForConfigPage(); - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - // It's important to tell sync the user cancelled the setup flow before we - // tell it we're through with the setup progress. - testing::InSequence seq; - EXPECT_CALL(*mock_pss_, RequestStop(ProfileSyncService::CLEAR_DATA)); - EXPECT_CALL(*mock_pss_, OnSetupInProgressHandleDestroyed()); - - handler_->CloseSyncSetup(); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); -} - -TEST_F(SyncSetupHandlerTest, - DisplayConfigureWithEngineDisabledAndSigninFailed) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - error_ = GoogleServiceAuthError::AuthErrorNone(); - EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false)); - - handler_->OpenSyncSetup(false /* creating_supervised_user */); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name()); - std::string page; - ASSERT_TRUE(data.arg1()->GetAsString(&page)); - EXPECT_EQ(page, "spinner"); - Mock::VerifyAndClearExpectations(mock_pss_); - error_ = GoogleServiceAuthError( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); - EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_)); - NotifySyncListeners(); - - // On failure, the dialog will be closed. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); -} - -#if !defined(OS_CHROMEOS) - -class SyncSetupHandlerNonCrosTest : public SyncSetupHandlerTest { - public: - SyncSetupHandlerNonCrosTest() {} -}; - -TEST_F(SyncSetupHandlerNonCrosTest, HandleGaiaAuthFailure) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, HasUnrecoverableError()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - // Open the web UI. - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ASSERT_FALSE(handler_->is_configuring_sync()); -} - -// TODO(kochi): We need equivalent tests for ChromeOS. -TEST_F(SyncSetupHandlerNonCrosTest, UnrecoverableErrorInitializingSync) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - // Open the web UI. - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ASSERT_FALSE(handler_->is_configuring_sync()); -} - -TEST_F(SyncSetupHandlerNonCrosTest, GaiaErrorInitializingSync) { - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false)); - // Open the web UI. - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ASSERT_FALSE(handler_->is_configuring_sync()); -} - -#endif // #if !defined(OS_CHROMEOS) - -TEST_F(SyncSetupHandlerTest, TestSyncEverything) { - std::string args = - GetConfiguration(NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), - ENCRYPT_PASSWORDS, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(true, _)); - handler_->HandleConfigure(&list_args); - - // Ensure that we navigated to the "done" state since we don't need a - // passphrase. - ExpectDone(); -} - -TEST_F(SyncSetupHandlerTest, TurnOnEncryptAll) { - std::string args = - GetConfiguration(NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), - ENCRYPT_ALL_DATA, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsEncryptEverythingAllowed()) - .WillRepeatedly(Return(true)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, EnableEncryptEverything()); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(true, _)); - handler_->HandleConfigure(&list_args); - - // Ensure that we navigated to the "done" state since we don't need a - // passphrase. - ExpectDone(); -} - -TEST_F(SyncSetupHandlerTest, TestPassphraseStillRequired) { - std::string args = - GetConfiguration(NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), - ENCRYPT_PASSWORDS, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _)); - SetDefaultExpectationsForConfigPage(); - - // We should navigate back to the configure page since we need a passphrase. - handler_->HandleConfigure(&list_args); - - ExpectConfig(); -} - -TEST_F(SyncSetupHandlerTest, SuccessfullySetPassphrase) { - base::DictionaryValue dict; - dict.SetBoolean("isGooglePassphrase", true); - std::string args = - GetConfiguration(&dict, SYNC_ALL_DATA, GetAllTypes(), "gaiaPassphrase", - ENCRYPT_PASSWORDS, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - // Act as if an encryption passphrase is required the first time, then never - // again after that. - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()).WillOnce(Return(true)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _)); - EXPECT_CALL(*mock_pss_, SetDecryptionPassphrase("gaiaPassphrase")). - WillOnce(Return(true)); - - handler_->HandleConfigure(&list_args); - // We should navigate to "done" page since we finished configuring. - ExpectDone(); -} - -TEST_F(SyncSetupHandlerTest, SelectCustomEncryption) { - base::DictionaryValue dict; - dict.SetBoolean("isGooglePassphrase", false); - std::string args = - GetConfiguration(&dict, SYNC_ALL_DATA, GetAllTypes(), "custom_passphrase", - ENCRYPT_PASSWORDS, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _)); - EXPECT_CALL(*mock_pss_, - SetEncryptionPassphrase("custom_passphrase", - ProfileSyncService::EXPLICIT)); - - handler_->HandleConfigure(&list_args); - // We should navigate to "done" page since we finished configuring. - ExpectDone(); -} - -TEST_F(SyncSetupHandlerTest, UnsuccessfullySetPassphrase) { - base::DictionaryValue dict; - dict.SetBoolean("isGooglePassphrase", true); - std::string args = GetConfiguration(&dict, SYNC_ALL_DATA, GetAllTypes(), - "invalid_passphrase", ENCRYPT_PASSWORDS, - PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _)); - EXPECT_CALL(*mock_pss_, SetDecryptionPassphrase("invalid_passphrase")). - WillOnce(Return(false)); - - SetDefaultExpectationsForConfigPage(); - // We should navigate back to the configure page since we need a passphrase. - handler_->HandleConfigure(&list_args); - - ExpectConfig(); - - // Make sure we display an error message to the user due to the failed - // passphrase. - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "passphraseFailed", true); -} - -// Walks through each user selectable type, and tries to sync just that single -// data type. -TEST_F(SyncSetupHandlerTest, TestSyncIndividualTypes) { - syncer::ModelTypeSet user_selectable_types = GetAllTypes(); - syncer::ModelTypeSet::Iterator it; - for (it = user_selectable_types.First(); it.Good(); it.Inc()) { - syncer::ModelTypeSet type_to_set; - type_to_set.Put(it.Get()); - std::string args = - GetConfiguration(NULL, CHOOSE_WHAT_TO_SYNC, type_to_set, std::string(), - ENCRYPT_PASSWORDS, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, - OnUserChoseDatatypes(false, ModelTypeSetMatches(type_to_set))); - handler_->HandleConfigure(&list_args); - - ExpectDone(); - Mock::VerifyAndClearExpectations(mock_pss_); - web_ui_.ClearTrackedCalls(); - } -} - -TEST_F(SyncSetupHandlerTest, TestSyncAllManually) { - std::string args = - GetConfiguration(NULL, CHOOSE_WHAT_TO_SYNC, GetAllTypes(), std::string(), - ENCRYPT_PASSWORDS, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, - OnUserChoseDatatypes(false, ModelTypeSetMatches(GetAllTypes()))); - handler_->HandleConfigure(&list_args); - - ExpectDone(); -} - -TEST_F(SyncSetupHandlerTest, ShowSyncSetup) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - // This should display the sync setup dialog (not login). - SetDefaultExpectationsForConfigPage(); - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); -} - -// We do not display signin on chromeos in the case of auth error. -TEST_F(SyncSetupHandlerTest, ShowSigninOnAuthError) { - // Initialize the system to a signed in state, but with an auth error. - error_ = GoogleServiceAuthError( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); - - SetupInitializedProfileSyncService(); - mock_signin_->SetAuthenticatedAccountInfo(kTestUser, kTestUser); - FakeAuthStatusProvider provider( - SigninErrorControllerFactory::GetForProfile(profile_.get())); - provider.SetAuthError(kTestUser, error_); - EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false)); - -#if defined(OS_CHROMEOS) - // On ChromeOS, auth errors are ignored - instead we just try to start the - // sync engine (which will fail due to the auth error). This should only - // happen if the user manually navigates to chrome://settings/syncSetup - - // clicking on the button in the UI will sign the user out rather than - // displaying a spinner. Should be no visible UI on ChromeOS in this case. - EXPECT_EQ(NULL, LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); -#else - - // On ChromeOS, this should display the spinner while we try to startup the - // sync engine, and on desktop this displays the login dialog. - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - // Sync setup is closed when re-auth is in progress. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_.get())->current_login_ui()); - - ASSERT_FALSE(handler_->is_configuring_sync()); -#endif -} - -TEST_F(SyncSetupHandlerTest, ShowSetupSyncEverything) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - SetDefaultExpectationsForConfigPage(); - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "syncAllDataTypes", true); - CheckBool(dictionary, "appsRegistered", true); - CheckBool(dictionary, "autofillRegistered", true); - CheckBool(dictionary, "bookmarksRegistered", true); - CheckBool(dictionary, "extensionsRegistered", true); - CheckBool(dictionary, "passwordsRegistered", true); - CheckBool(dictionary, "preferencesRegistered", true); - CheckBool(dictionary, "tabsRegistered", true); - CheckBool(dictionary, "themesRegistered", true); - CheckBool(dictionary, "typedUrlsRegistered", true); - CheckBool(dictionary, "paymentsIntegrationEnabled", true); - CheckBool(dictionary, "showPassphrase", false); - CheckBool(dictionary, "usePassphrase", false); - CheckBool(dictionary, "passphraseFailed", false); - CheckBool(dictionary, "encryptAllData", false); - CheckConfigDataTypeArguments(dictionary, SYNC_ALL_DATA, GetAllTypes()); -} - -TEST_F(SyncSetupHandlerTest, ShowSetupManuallySyncAll) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - syncer::SyncPrefs sync_prefs(profile_->GetPrefs()); - sync_prefs.SetKeepEverythingSynced(false); - SetDefaultExpectationsForConfigPage(); - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, GetAllTypes()); -} - -TEST_F(SyncSetupHandlerTest, ShowSetupSyncForAllTypesIndividually) { - syncer::ModelTypeSet user_selectable_types = GetAllTypes(); - syncer::ModelTypeSet::Iterator it; - for (it = user_selectable_types.First(); it.Good(); it.Inc()) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - syncer::SyncPrefs sync_prefs(profile_->GetPrefs()); - sync_prefs.SetKeepEverythingSynced(false); - SetDefaultExpectationsForConfigPage(); - syncer::ModelTypeSet types; - types.Put(it.Get()); - EXPECT_CALL(*mock_pss_, GetPreferredDataTypes()). - WillRepeatedly(Return(types)); - - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - // Close the config overlay. - LoginUIServiceFactory::GetForProfile(profile_.get())->LoginUIClosed( - handler_.get()); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, types); - Mock::VerifyAndClearExpectations(mock_pss_); - // Clean up so we can loop back to display the dialog again. - web_ui_.ClearTrackedCalls(); - } -} - -TEST_F(SyncSetupHandlerTest, ShowSetupGaiaPassphraseRequired) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - SetDefaultExpectationsForConfigPage(); - - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "showPassphrase", true); - CheckBool(dictionary, "usePassphrase", false); - CheckBool(dictionary, "passphraseFailed", false); -} - -TEST_F(SyncSetupHandlerTest, ShowSetupCustomPassphraseRequired) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pss_, GetPassphraseType()) - .WillRepeatedly(Return(syncer::PassphraseType::CUSTOM_PASSPHRASE)); - SetupInitializedProfileSyncService(); - SetDefaultExpectationsForConfigPage(); - - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "showPassphrase", true); - CheckBool(dictionary, "usePassphrase", true); - CheckBool(dictionary, "passphraseFailed", false); -} - -TEST_F(SyncSetupHandlerTest, ShowSetupEncryptAll) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - SetDefaultExpectationsForConfigPage(); - EXPECT_CALL(*mock_pss_, IsEncryptEverythingEnabled()) - .WillRepeatedly(Return(true)); - - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "encryptAllData", true); -} - -TEST_F(SyncSetupHandlerTest, ShowSetupEncryptAllDisallowed) { - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - SetDefaultExpectationsForConfigPage(); - EXPECT_CALL(*mock_pss_, IsEncryptEverythingAllowed()) - .WillRepeatedly(Return(false)); - - // This should display the sync setup dialog (not login). - handler_->OpenSyncSetup(false /* creating_supervised_user */); - - ExpectConfig(); - const content::TestWebUI::CallData& data = *web_ui_.call_data()[0]; - const base::DictionaryValue* dictionary = nullptr; - ASSERT_TRUE(data.arg2()->GetAsDictionary(&dictionary)); - CheckBool(dictionary, "encryptAllData", false); - CheckBool(dictionary, "encryptAllDataAllowed", false); -} - -TEST_F(SyncSetupHandlerTest, TurnOnEncryptAllDisallowed) { - std::string args = - GetConfiguration(NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), - ENCRYPT_ALL_DATA, PAYMENTS_INTEGRATION_ENABLED); - base::ListValue list_args; - list_args.AppendString(args); - EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) - .WillRepeatedly(Return(false)); - SetupInitializedProfileSyncService(); - EXPECT_CALL(*mock_pss_, IsEncryptEverythingAllowed()) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*mock_pss_, EnableEncryptEverything()).Times(0); - EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(true, _)); - handler_->HandleConfigure(&list_args); - - // Ensure that we navigated to the "done" state since we don't need a - // passphrase. - ExpectDone(); -} diff --git a/chromium/chrome/browser/ui/webui/plural_string_handler.cc b/chromium/chrome/browser/ui/webui/plural_string_handler.cc new file mode 100644 index 00000000000..4693d198562 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/plural_string_handler.cc @@ -0,0 +1,45 @@ +// 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 "chrome/browser/ui/webui/plural_string_handler.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/values.h" +#include "content/public/browser/web_ui.h" +#include "ui/base/l10n/l10n_util.h" + +PluralStringHandler::PluralStringHandler() {} + +PluralStringHandler::~PluralStringHandler() {} + +void PluralStringHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "getPluralString", base::Bind(&PluralStringHandler::HandleGetPluralString, + base::Unretained(this))); +} + +void PluralStringHandler::AddLocalizedString(const std::string& name, int id) { + name_to_id_[name] = id; +} + +void PluralStringHandler::HandleGetPluralString(const base::ListValue* args) { + AllowJavascript(); + CHECK_EQ(3U, args->GetSize()); + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); + + std::string message_name; + CHECK(args->GetString(1, &message_name)); + + int count; + CHECK(args->GetInteger(2, &count)); + + auto message_id_it = name_to_id_.find(message_name); + CHECK(name_to_id_.end() != message_id_it); + + ResolveJavascriptCallback(*callback_id, + base::Value(l10n_util::GetPluralStringFUTF8( + message_id_it->second, count))); +} diff --git a/chromium/chrome/browser/ui/webui/plural_string_handler.h b/chromium/chrome/browser/ui/webui/plural_string_handler.h new file mode 100644 index 00000000000..c9535247d0a --- /dev/null +++ b/chromium/chrome/browser/ui/webui/plural_string_handler.h @@ -0,0 +1,30 @@ +// 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 CHROME_BROWSER_UI_WEBUI_PLURAL_STRING_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_PLURAL_STRING_HANDLER_H_ + +#include "base/macros.h" +#include "content/public/browser/web_ui_message_handler.h" + +// A handler which provides pluralized strings. +class PluralStringHandler : public content::WebUIMessageHandler { + public: + PluralStringHandler(); + ~PluralStringHandler() override; + + void AddLocalizedString(const std::string& name, int id); + + // WebUIMessageHandler: + void RegisterMessages() override; + + private: + void HandleGetPluralString(const base::ListValue* args); + + std::map<std::string, int> name_to_id_; + + DISALLOW_COPY_AND_ASSIGN(PluralStringHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_PLURAL_STRING_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/policy_material_design_ui.cc b/chromium/chrome/browser/ui/webui/policy_material_design_ui.cc index 7948c1c9ceb..d6f0cccf381 100644 --- a/chromium/chrome/browser/ui/webui/policy_material_design_ui.cc +++ b/chromium/chrome/browser/ui/webui/policy_material_design_ui.cc @@ -79,7 +79,7 @@ void PolicyMaterialDesignUIHandler::AddPolicyName( if (tags[i] != policy::RISK_TAG_NONE) list->AppendString(kPolicyRiskTags[tags[i]].key); } - names->Set(name, std::move(list)); + names->SetWithoutPathExpansion(name, std::move(list)); } void PolicyMaterialDesignUIHandler::SendPolicyNames() const { diff --git a/chromium/chrome/browser/ui/webui/policy_ui.cc b/chromium/chrome/browser/ui/webui/policy_ui.cc index 802be6a4970..35c90bc0941 100644 --- a/chromium/chrome/browser/ui/webui/policy_ui.cc +++ b/chromium/chrome/browser/ui/webui/policy_ui.cc @@ -25,7 +25,10 @@ content::WebUIDataSource* CreatePolicyUIHtmlSource() { source->AddLocalizedString("status", IDS_POLICY_STATUS); source->AddLocalizedString("statusDevice", IDS_POLICY_STATUS_DEVICE); source->AddLocalizedString("statusUser", IDS_POLICY_STATUS_USER); - source->AddLocalizedString("labelDomain", IDS_POLICY_LABEL_DOMAIN); + source->AddLocalizedString("labelEnterpriseEnrollmentDomain", + IDS_POLICY_LABEL_ENTERPRISE_ENROLLMENT_DOMAIN); + source->AddLocalizedString("labelEnterpriseDisplayDomain", + IDS_POLICY_LABEL_ENTERPRISE_DISPLAY_DOMAIN); source->AddLocalizedString("labelUsername", IDS_POLICY_LABEL_USERNAME); source->AddLocalizedString("labelClientId", IDS_POLICY_LABEL_CLIENT_ID); source->AddLocalizedString("labelAssetId", IDS_POLICY_LABEL_ASSET_ID); @@ -46,7 +49,6 @@ content::WebUIDataSource* CreatePolicyUIHtmlSource() { // Add required resources. source->AddResourcePath("policy.css", IDR_POLICY_CSS); source->AddResourcePath("policy.js", IDR_POLICY_JS); - source->AddResourcePath("uber_utils.js", IDR_UBER_UTILS_JS); source->SetDefaultResource(IDR_POLICY_HTML); return source; } diff --git a/chromium/chrome/browser/ui/webui/policy_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/policy_ui_browsertest.cc index 5514daf8734..38dbbb45d6f 100644 --- a/chromium/chrome/browser/ui/webui/policy_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/policy_ui_browsertest.cc @@ -241,6 +241,12 @@ IN_PROC_BROWSER_TEST_F(PolicyUITest, SendPolicyValues) { policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>(true), nullptr); expected_values[kUnknownPolicy] = "true"; + const std::string kUnknownPolicyWithDots = "no.such.thing"; + values.Set(kUnknownPolicyWithDots, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_PLATFORM, + base::MakeUnique<base::Value>("blub"), nullptr); + expected_values[kUnknownPolicyWithDots] = "blub"; + UpdateProviderPolicy(values); // Expect that the policy table contains, in order: @@ -273,6 +279,11 @@ IN_PROC_BROWSER_TEST_F(PolicyUITest, SendPolicyValues) { "Platform", values.Get(kUnknownPolicy), true)); + expected_policies.insert( + expected_policies.begin() + first_unset_position++, + PopulateExpectedPolicy( + kUnknownPolicyWithDots, expected_values[kUnknownPolicyWithDots], + "Platform", values.Get(kUnknownPolicyWithDots), true)); // Retrieve the contents of the policy table from the UI and verify that it // matches the expectation. diff --git a/chromium/chrome/browser/ui/webui/policy_ui_handler.cc b/chromium/chrome/browser/ui/webui/policy_ui_handler.cc index 5ea1cbb4b50..8f3a4dca664 100644 --- a/chromium/chrome/browser/ui/webui/policy_ui_handler.cc +++ b/chromium/chrome/browser/ui/webui/policy_ui_handler.cc @@ -27,8 +27,6 @@ #include "chrome/browser/policy/schema_registry_service.h" #include "chrome/browser/policy/schema_registry_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/grit/policy_resources.h" -#include "chrome/grit/policy_resources_map.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/browser/cloud/message_util.h" #include "components/policy/core/browser/configuration_policy_handler_list.h" @@ -274,7 +272,8 @@ class DevicePolicyStatusProvider : public CloudPolicyCoreStatusProvider { void GetStatus(base::DictionaryValue* dict) override; private: - std::string domain_; + std::string enterprise_enrollment_domain_; + std::string enterprise_display_domain_; DISALLOW_COPY_AND_ASSIGN(DevicePolicyStatusProvider); }; @@ -386,7 +385,8 @@ DevicePolicyStatusProvider::DevicePolicyStatusProvider( policy::BrowserPolicyConnectorChromeOS* connector) : CloudPolicyCoreStatusProvider( connector->GetDeviceCloudPolicyManager()->core()) { - domain_ = connector->GetEnterpriseDomain(); + enterprise_enrollment_domain_ = connector->GetEnterpriseEnrollmentDomain(); + enterprise_display_domain_ = connector->GetEnterpriseDisplayDomain(); } DevicePolicyStatusProvider::~DevicePolicyStatusProvider() { @@ -394,7 +394,8 @@ DevicePolicyStatusProvider::~DevicePolicyStatusProvider() { void DevicePolicyStatusProvider::GetStatus(base::DictionaryValue* dict) { GetStatusFromCore(core_, dict); - dict->SetString("domain", domain_); + dict->SetString("enterpriseEnrollmentDomain", enterprise_enrollment_domain_); + dict->SetString("enterpriseDisplayDomain", enterprise_display_domain_); } DeviceLocalAccountPolicyStatusProvider::DeviceLocalAccountPolicyStatusProvider( @@ -631,7 +632,7 @@ void PolicyUIHandler::OnPolicyUpdated(const policy::PolicyNamespace& ns, void PolicyUIHandler::AddPolicyName(const std::string& name, base::DictionaryValue* names) const { - names->SetBoolean(name, true); + names->SetBooleanWithoutPathExpansion(name, true); } void PolicyUIHandler::SendPolicyNames() const { @@ -738,7 +739,7 @@ void PolicyUIHandler::GetPolicyValues(const policy::PolicyMap& map, base::string16 error = errors->GetErrors(entry.first); if (!error.empty()) value->SetString("error", error); - values->Set(entry.first, std::move(value)); + values->SetWithoutPathExpansion(entry.first, std::move(value)); } } diff --git a/chromium/chrome/browser/ui/webui/popular_sites_internals_ui.cc b/chromium/chrome/browser/ui/webui/popular_sites_internals_ui.cc deleted file mode 100644 index 88e07798e3f..00000000000 --- a/chromium/chrome/browser/ui/webui/popular_sites_internals_ui.cc +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2015 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 "chrome/browser/ui/webui/popular_sites_internals_ui.h" - -#include "base/memory/ptr_util.h" -#include "chrome/browser/ntp_tiles/chrome_popular_sites_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "components/grit/components_resources.h" -#include "components/ntp_tiles/popular_sites.h" -#include "components/ntp_tiles/webui/popular_sites_internals_message_handler.h" -#include "components/ntp_tiles/webui/popular_sites_internals_message_handler_client.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" -#include "content/public/browser/web_ui_message_handler.h" - -namespace { - -// The implementation for the chrome://popular-sites-internals page. -class ChromePopularSitesInternalsMessageHandlerBridge - : public content::WebUIMessageHandler, - public ntp_tiles::PopularSitesInternalsMessageHandlerClient { - public: - ChromePopularSitesInternalsMessageHandlerBridge() : handler_(this) {} - - private: - // content::WebUIMessageHandler: - void RegisterMessages() override; - - // ntp_tiles::PopularSitesInternalsMessageHandlerClient - std::unique_ptr<ntp_tiles::PopularSites> MakePopularSites() override; - PrefService* GetPrefs() override; - void RegisterMessageCallback( - const std::string& message, - const base::Callback<void(const base::ListValue*)>& callback) override; - void CallJavascriptFunctionVector( - const std::string& name, - const std::vector<const base::Value*>& values) override; - - ntp_tiles::PopularSitesInternalsMessageHandler handler_; - - DISALLOW_COPY_AND_ASSIGN(ChromePopularSitesInternalsMessageHandlerBridge); -}; - -void ChromePopularSitesInternalsMessageHandlerBridge::RegisterMessages() { - handler_.RegisterMessages(); -} - -std::unique_ptr<ntp_tiles::PopularSites> -ChromePopularSitesInternalsMessageHandlerBridge::MakePopularSites() { - return ChromePopularSitesFactory::NewForProfile(Profile::FromWebUI(web_ui())); -} - -PrefService* ChromePopularSitesInternalsMessageHandlerBridge::GetPrefs() { - return Profile::FromWebUI(web_ui())->GetPrefs(); -} - -void ChromePopularSitesInternalsMessageHandlerBridge::RegisterMessageCallback( - const std::string& message, - const base::Callback<void(const base::ListValue*)>& callback) { - web_ui()->RegisterMessageCallback(message, callback); -} - -void ChromePopularSitesInternalsMessageHandlerBridge:: - CallJavascriptFunctionVector( - const std::string& name, - const std::vector<const base::Value*>& values) { - web_ui()->CallJavascriptFunctionUnsafe(name, values); -} - -} // namespace - -content::WebUIDataSource* CreatePopularSitesInternalsHTMLSource() { - content::WebUIDataSource* source = content::WebUIDataSource::Create( - chrome::kChromeUIPopularSitesInternalsHost); - - source->AddResourcePath("popular_sites_internals.js", - IDR_POPULAR_SITES_INTERNALS_JS); - source->AddResourcePath("popular_sites_internals.css", - IDR_POPULAR_SITES_INTERNALS_CSS); - source->SetDefaultResource(IDR_POPULAR_SITES_INTERNALS_HTML); - return source; -} - -PopularSitesInternalsUI::PopularSitesInternalsUI(content::WebUI* web_ui) - : WebUIController(web_ui) { - content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), - CreatePopularSitesInternalsHTMLSource()); - web_ui->AddMessageHandler( - base::MakeUnique<ChromePopularSitesInternalsMessageHandlerBridge>()); -} - -PopularSitesInternalsUI::~PopularSitesInternalsUI() {} diff --git a/chromium/chrome/browser/ui/webui/popular_sites_internals_ui.h b/chromium/chrome/browser/ui/webui/popular_sites_internals_ui.h deleted file mode 100644 index 8995536620b..00000000000 --- a/chromium/chrome/browser/ui/webui/popular_sites_internals_ui.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015 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 CHROME_BROWSER_UI_WEBUI_POPULAR_SITES_INTERNALS_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_POPULAR_SITES_INTERNALS_UI_H_ - -#include "base/macros.h" -#include "content/public/browser/web_ui_controller.h" - -// The implementation for the chrome://popular-sites-internals page. -class PopularSitesInternalsUI : public content::WebUIController { - public: - explicit PopularSitesInternalsUI(content::WebUI* web_ui); - ~PopularSitesInternalsUI() override; - - private: - DISALLOW_COPY_AND_ASSIGN(PopularSitesInternalsUI); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_POPULAR_SITES_INTERNALS_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/predictors/predictors_handler.cc b/chromium/chrome/browser/ui/webui/predictors/predictors_handler.cc index 76c8ee20444..e078a6604a4 100644 --- a/chromium/chrome/browser/ui/webui/predictors/predictors_handler.cc +++ b/chromium/chrome/browser/ui/webui/predictors/predictors_handler.cc @@ -97,18 +97,33 @@ void PredictorsHandler::RequestResourcePrefetchPredictorDb( dict.SetBoolean("enabled", enabled); if (enabled) { - // Url Database cache. - auto db = base::MakeUnique<base::ListValue>(); auto* resource_prefetch_predictor = loading_predictor_->resource_prefetch_predictor(); - AddPrefetchDataMapToListValue( - *resource_prefetch_predictor->url_table_cache_, db.get()); - dict.Set("url_db", std::move(db)); - - db = base::MakeUnique<base::ListValue>(); - AddPrefetchDataMapToListValue( - *resource_prefetch_predictor->host_table_cache_, db.get()); - dict.Set("host_db", std::move(db)); + const bool initialized = + resource_prefetch_predictor->initialization_state_ == + ResourcePrefetchPredictor::INITIALIZED; + + if (initialized) { + // URL table cache. + auto db = base::MakeUnique<base::ListValue>(); + AddPrefetchDataMapToListValue( + *resource_prefetch_predictor->url_resource_data_->data_cache_, + db.get()); + dict.Set("url_db", std::move(db)); + + // Host table cache. + db = base::MakeUnique<base::ListValue>(); + AddPrefetchDataMapToListValue( + *resource_prefetch_predictor->host_resource_data_->data_cache_, + db.get()); + dict.Set("host_db", std::move(db)); + + // Origin table cache. + db = base::MakeUnique<base::ListValue>(); + AddOriginDataMapToListValue( + *resource_prefetch_predictor->origin_data_->data_cache_, db.get()); + dict.Set("origin_db", std::move(db)); + } } web_ui()->CallJavascriptFunctionUnsafe("updateResourcePrefetchPredictorDb", @@ -116,15 +131,14 @@ void PredictorsHandler::RequestResourcePrefetchPredictorDb( } void PredictorsHandler::AddPrefetchDataMapToListValue( - const ResourcePrefetchPredictor::PrefetchDataMap& data_map, + const std::map<std::string, predictors::PrefetchData>& data_map, base::ListValue* db) const { for (const auto& p : data_map) { - std::unique_ptr<base::DictionaryValue> main(new base::DictionaryValue()); + auto main = base::MakeUnique<base::DictionaryValue>(); main->SetString("main_frame_url", p.first); auto resources = base::MakeUnique<base::ListValue>(); for (const predictors::ResourceData& r : p.second.resources()) { - std::unique_ptr<base::DictionaryValue> resource( - new base::DictionaryValue()); + auto resource = base::MakeUnique<base::DictionaryValue>(); resource->SetString("resource_url", r.resource_url()); resource->SetString("resource_type", ConvertResourceType(r.resource_type())); @@ -147,3 +161,28 @@ void PredictorsHandler::AddPrefetchDataMapToListValue( db->Append(std::move(main)); } } + +void PredictorsHandler::AddOriginDataMapToListValue( + const std::map<std::string, predictors::OriginData>& data_map, + base::ListValue* db) const { + for (const auto& p : data_map) { + auto main = base::MakeUnique<base::DictionaryValue>(); + main->SetString("main_frame_host", p.first); + auto origins = base::MakeUnique<base::ListValue>(); + for (const predictors::OriginStat& o : p.second.origins()) { + auto origin = base::MakeUnique<base::DictionaryValue>(); + origin->SetString("origin", o.origin()); + origin->SetInteger("number_of_hits", o.number_of_hits()); + origin->SetInteger("number_of_misses", o.number_of_misses()); + origin->SetInteger("consecutive_misses", o.consecutive_misses()); + origin->SetDouble("position", o.average_position()); + origin->SetBoolean("always_access_network", o.always_access_network()); + origin->SetBoolean("accessed_network", o.accessed_network()); + origin->SetDouble("score", + ResourcePrefetchPredictorTables::ComputeOriginScore(o)); + origins->Append(std::move(origin)); + } + main->Set("origins", std::move(origins)); + db->Append(std::move(main)); + } +} diff --git a/chromium/chrome/browser/ui/webui/predictors/predictors_handler.h b/chromium/chrome/browser/ui/webui/predictors/predictors_handler.h index 99796e0234e..e9a4e086b00 100644 --- a/chromium/chrome/browser/ui/webui/predictors/predictors_handler.h +++ b/chromium/chrome/browser/ui/webui/predictors/predictors_handler.h @@ -39,9 +39,12 @@ class PredictorsHandler : public content::WebUIMessageHandler { // DictionaryValue to the JS. void RequestResourcePrefetchPredictorDb(const base::ListValue* args); - // Helper for RequestResourcePrefetchPredictorDb. + // Helpers for RequestResourcePrefetchPredictorDb. void AddPrefetchDataMapToListValue( - const predictors::ResourcePrefetchPredictor::PrefetchDataMap& data_map, + const std::map<std::string, predictors::PrefetchData>& data_map, + base::ListValue* db) const; + void AddOriginDataMapToListValue( + const std::map<std::string, predictors::OriginData>& data_map, base::ListValue* db) const; predictors::AutocompleteActionPredictor* autocomplete_action_predictor_; diff --git a/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc index 2814faff606..af7cbcc2d35 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc +++ b/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc @@ -173,7 +173,7 @@ void ExtensionPrinterHandler::StartGetCapability( ->DispatchGetCapabilityRequested( destination_id, base::Bind(&ExtensionPrinterHandler::WrapGetCapabilityCallback, - weak_ptr_factory_.GetWeakPtr(), callback, destination_id)); + weak_ptr_factory_.GetWeakPtr(), callback)); } void ExtensionPrinterHandler::StartPrint( @@ -300,9 +300,8 @@ void ExtensionPrinterHandler::WrapGetPrintersCallback( void ExtensionPrinterHandler::WrapGetCapabilityCallback( const PrinterHandler::GetCapabilityCallback& callback, - const std::string& destination_id, const base::DictionaryValue& capability) { - callback.Run(destination_id, capability); + callback.Run(capability); } void ExtensionPrinterHandler::WrapPrintCallback( @@ -336,7 +335,7 @@ void ExtensionPrinterHandler::OnUsbDevicesEnumerated( const extensions::DevicePermissions* device_permissions = permissions_manager->GetForExtension(extension->id()); for (const auto& device : devices) { - if (manifest_data->SupportsDevice(device)) { + if (manifest_data->SupportsDevice(*device)) { std::unique_ptr<extensions::UsbDevicePermission::CheckParam> param = extensions::UsbDevicePermission::CheckParam::ForUsbDevice( extension.get(), device.get()); diff --git a/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.h b/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.h index 183d172cae4..266cc1179eb 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.h +++ b/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler.h @@ -102,7 +102,6 @@ class ExtensionPrinterHandler : public PrinterHandler { bool done); void WrapGetCapabilityCallback( const PrinterHandler::GetCapabilityCallback& callback, - const std::string& destination_id, const base::DictionaryValue& capability); void WrapPrintCallback(const PrinterHandler::PrintCallback& callback, bool success, diff --git a/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc index 668f8d6d60e..94d1ab74df5 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc @@ -203,12 +203,9 @@ void RecordPrinterList(size_t* call_count, // Used as a callback to StartGetCapability in tests. // Increases |*call_count| and records values returned by StartGetCapability. void RecordCapability(size_t* call_count, - std::string* destination_id_out, std::unique_ptr<base::DictionaryValue>* capability_out, - const std::string& destination_id, const base::DictionaryValue& capability) { ++(*call_count); - *destination_id_out = destination_id; capability_out->reset(capability.DeepCopy()); } @@ -609,12 +606,10 @@ TEST_F(ExtensionPrinterHandlerTest, GetUsbPrinters) { TEST_F(ExtensionPrinterHandlerTest, GetCapability) { size_t call_count = 0; - std::string destination_id; std::unique_ptr<base::DictionaryValue> capability; extension_printer_handler_->StartGetCapability( - kPrinterId, - base::Bind(&RecordCapability, &call_count, &destination_id, &capability)); + kPrinterId, base::Bind(&RecordCapability, &call_count, &capability)); EXPECT_EQ(0u, call_count); @@ -631,7 +626,6 @@ TEST_F(ExtensionPrinterHandlerTest, GetCapability) { fake_api->TriggerNextGetCapabilityCallback(*original_capability); EXPECT_EQ(1u, call_count); - EXPECT_EQ(kPrinterId, destination_id); ASSERT_TRUE(capability.get()); EXPECT_TRUE(capability->Equals(original_capability.get())) << *capability << ", expected: " << *original_capability; @@ -639,12 +633,10 @@ TEST_F(ExtensionPrinterHandlerTest, GetCapability) { TEST_F(ExtensionPrinterHandlerTest, GetCapability_Reset) { size_t call_count = 0; - std::string destination_id; std::unique_ptr<base::DictionaryValue> capability; extension_printer_handler_->StartGetCapability( - kPrinterId, - base::Bind(&RecordCapability, &call_count, &destination_id, &capability)); + kPrinterId, base::Bind(&RecordCapability, &call_count, &capability)); EXPECT_EQ(0u, call_count); diff --git a/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index fba7d030cbe..e9a5a4fef1d 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.cc @@ -88,8 +88,6 @@ #include "third_party/icu/source/i18n/unicode/ulocdata.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" #include "chrome/common/url_constants.h" @@ -188,8 +186,6 @@ const char kPrintAutomaticallyInKioskMode[] = "printAutomaticallyInKioskMode"; // Dictionary field to indicate whether Chrome is running in forced app (app // kiosk) mode. It's not the same as desktop Chrome kiosk (the one above). const char kAppKioskMode[] = "appKioskMode"; -// Dictionary field to store Cloud Print base URL. -const char kCloudPrintUrl[] = "cloudPrintUrl"; // Name of a dictionary field holding the state of selection for document. const char kDocumentHasSelection[] = "documentHasSelection"; // Dictionary field holding the default destination selection rules. @@ -199,15 +195,13 @@ const char kDefaultDestinationSelectionRules[] = // Id of the predefined PDF printer. const char kLocalPdfPrinterId[] = "Save as PDF"; -// Get the print job settings dictionary from |args|. The caller takes -// ownership of the returned DictionaryValue. Returns NULL on failure. +// Timeout for searching for privet printers, in seconds. +const int kPrivetTimeoutSec = 5; + +// Get the print job settings dictionary from |json_str|. Returns NULL on +// failure. std::unique_ptr<base::DictionaryValue> GetSettingsDictionary( - const base::ListValue* args) { - std::string json_str; - if (!args->GetString(0, &json_str)) { - NOTREACHED() << "Could not read JSON argument"; - return NULL; - } + const std::string& json_str) { if (json_str.empty()) { NOTREACHED() << "Empty print job settings"; return NULL; @@ -455,6 +449,11 @@ base::FilePath GetUniquePath(const base::FilePath& path) { return unique_path; } +void CreateDirectoryIfNeeded(const base::FilePath& path) { + if (!base::DirectoryExists(path)) + base::CreateDirectory(path); +} + bool PrivetPrintingEnabled() { #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) return true; @@ -473,9 +472,9 @@ class PrintPreviewHandler::AccessTokenService handler_(handler) { } - void RequestToken(const std::string& type) { + void RequestToken(const std::string& type, const std::string& callback_id) { if (requests_.find(type) != requests_.end()) - return; // Already in progress. + return; // Should never happen, see cloud_print_interface.js OAuth2TokenService* service = NULL; std::string account_id; @@ -504,29 +503,32 @@ class PrintPreviewHandler::AccessTokenService std::unique_ptr<OAuth2TokenService::Request> request( service->StartRequest(account_id, oauth_scopes, this)); requests_[type] = std::move(request); + callbacks_[type] = callback_id; } else { - handler_->SendAccessToken(type, std::string()); // Unknown type. + // Unknown type. + handler_->SendAccessToken(callback_id, std::string()); } } void OnGetTokenSuccess(const OAuth2TokenService::Request* request, const std::string& access_token, const base::Time& expiration_time) override { - OnServiceResponce(request, access_token); + OnServiceResponse(request, access_token); } void OnGetTokenFailure(const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) override { - OnServiceResponce(request, std::string()); + OnServiceResponse(request, std::string()); } private: - void OnServiceResponce(const OAuth2TokenService::Request* request, + void OnServiceResponse(const OAuth2TokenService::Request* request, const std::string& access_token) { for (Requests::iterator i = requests_.begin(); i != requests_.end(); ++i) { if (i->second.get() == request) { - handler_->SendAccessToken(i->first, access_token); + handler_->SendAccessToken(callbacks_[i->first], access_token); requests_.erase(i); + callbacks_.erase(i->first); return; } } @@ -536,6 +538,8 @@ class PrintPreviewHandler::AccessTokenService using Requests = std::map<std::string, std::unique_ptr<OAuth2TokenService::Request>>; Requests requests_; + using Callbacks = std::map<std::string, std::string>; + Callbacks callbacks_; PrintPreviewHandler* handler_; DISALLOW_COPY_AND_ASSIGN(AccessTokenService); @@ -615,9 +619,6 @@ void PrintPreviewHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("getPrivetPrinters", base::Bind(&PrintPreviewHandler::HandleGetPrivetPrinters, base::Unretained(this))); - web_ui()->RegisterMessageCallback("stopGetPrivetPrinters", - base::Bind(&PrintPreviewHandler::HandleStopGetPrivetPrinters, - base::Unretained(this))); web_ui()->RegisterMessageCallback("getPrivetPrinterCapabilities", base::Bind(&PrintPreviewHandler::HandleGetPrivetPrinterCapabilities, base::Unretained(this))); @@ -661,90 +662,130 @@ printing::PrinterBackendProxy* PrintPreviewHandler::printer_backend_proxy() { return printer_backend_proxy_.get(); } -void PrintPreviewHandler::HandleGetPrinters(const base::ListValue* /*args*/) { +void PrintPreviewHandler::HandleGetPrinters(const base::ListValue* args) { VLOG(1) << "Enumerate printers start"; - printer_backend_proxy()->EnumeratePrinters(base::Bind( - &PrintPreviewHandler::SetupPrinterList, weak_factory_.GetWeakPtr())); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + CHECK(!callback_id.empty()); + printer_backend_proxy()->EnumeratePrinters( + base::Bind(&PrintPreviewHandler::SetupPrinterList, + weak_factory_.GetWeakPtr(), callback_id)); } void PrintPreviewHandler::HandleGetPrivetPrinters(const base::ListValue* args) { - if (!PrivetPrintingEnabled()) - return web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrinterSearchDone"); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + CHECK(!callback_id.empty()); + if (!PrivetPrintingEnabled()) { + RejectJavascriptCallback(base::Value(callback_id), base::Value()); + return; + } #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) using local_discovery::ServiceDiscoverySharedClient; scoped_refptr<ServiceDiscoverySharedClient> service_discovery = ServiceDiscoverySharedClient::GetInstance(); + DCHECK(privet_search_callback_id_.empty()); + privet_search_callback_id_ = callback_id; StartPrivetLister(service_discovery); #endif } -void PrintPreviewHandler::HandleStopGetPrivetPrinters( - const base::ListValue* args) { +void PrintPreviewHandler::StopPrivetLister() { #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) + privet_lister_timer_.reset(); if (PrivetPrintingEnabled() && printer_lister_) { printer_lister_->Stop(); } + ResolveJavascriptCallback(base::Value(privet_search_callback_id_), + base::Value()); + privet_search_callback_id_.clear(); #endif } void PrintPreviewHandler::HandleGetPrivetPrinterCapabilities( const base::ListValue* args) { + std::string callback_id; + std::string printer_name; + if (!args->GetString(0, &callback_id) || !args->GetString(1, &printer_name) || + callback_id.empty() || printer_name.empty()) { + RejectJavascriptCallback(base::Value(callback_id), base::Value()); + return; + } #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) - std::string name; - bool success = args->GetString(0, &name); - DCHECK(success); - - CreatePrivetHTTP( - name, base::Bind(&PrintPreviewHandler::PrivetCapabilitiesUpdateClient, - weak_factory_.GetWeakPtr())); + if (CreatePrivetHTTP( + printer_name, + base::Bind(&PrintPreviewHandler::PrivetCapabilitiesUpdateClient, + weak_factory_.GetWeakPtr(), callback_id))) { + return; + } #endif + RejectJavascriptCallback(base::Value(callback_id), base::Value()); } void PrintPreviewHandler::HandleGetExtensionPrinters( const base::ListValue* args) { + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + CHECK(!callback_id.empty()); + EnsureExtensionPrinterHandlerSet(); // Make sure all in progress requests are canceled before new printer search // starts. extension_printer_handler_->Reset(); extension_printer_handler_->StartGetPrinters( base::Bind(&PrintPreviewHandler::OnGotPrintersForExtension, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), callback_id)); } void PrintPreviewHandler::HandleGrantExtensionPrinterAccess( const base::ListValue* args) { + std::string callback_id; std::string printer_id; - bool ok = args->GetString(0, &printer_id); + bool ok = args->GetString(0, &callback_id) && + args->GetString(1, &printer_id) && !callback_id.empty(); DCHECK(ok); EnsureExtensionPrinterHandlerSet(); extension_printer_handler_->StartGrantPrinterAccess( printer_id, base::Bind(&PrintPreviewHandler::OnGotExtensionPrinterInfo, - weak_factory_.GetWeakPtr(), printer_id)); + weak_factory_.GetWeakPtr(), callback_id)); } void PrintPreviewHandler::HandleGetExtensionPrinterCapabilities( const base::ListValue* args) { - std::string printer_id; - bool ok = args->GetString(0, &printer_id); - DCHECK(ok); + std::string callback_id; + std::string printer_name; + if (!args->GetString(0, &callback_id) || !args->GetString(1, &printer_name) || + callback_id.empty() || printer_name.empty()) { + RejectJavascriptCallback(base::Value(callback_id), base::Value()); + return; + } EnsureExtensionPrinterHandlerSet(); extension_printer_handler_->StartGetCapability( - printer_id, + printer_name, base::Bind(&PrintPreviewHandler::OnGotExtensionPrinterCapabilities, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), callback_id)); } void PrintPreviewHandler::HandleGetPreview(const base::ListValue* args) { - DCHECK_EQ(2U, args->GetSize()); - std::unique_ptr<base::DictionaryValue> settings = GetSettingsDictionary(args); - if (!settings) - return; + DCHECK_EQ(3U, args->GetSize()); + std::string callback_id; + std::string json_str; + + // All of the conditions below should be guaranteed by the print preview + // javascript. + args->GetString(0, &callback_id); + CHECK(!callback_id.empty()); + args->GetString(1, &json_str); + std::unique_ptr<base::DictionaryValue> settings = + GetSettingsDictionary(json_str); + CHECK(settings); int request_id = -1; - if (!settings->GetInteger(printing::kPreviewRequestID, &request_id)) - return; + settings->GetInteger(printing::kPreviewRequestID, &request_id); + CHECK_GT(request_id, -1); + preview_callbacks_.push(callback_id); print_preview_ui()->OnPrintPreviewRequest(request_id); // Add an additional key in order to identify |print_preview_ui| later on // when calling PrintPreviewUI::GetCurrentPrintPreviewStatus() on the IO @@ -795,7 +836,7 @@ void PrintPreviewHandler::HandleGetPreview(const base::ListValue* args) { if (!generate_draft_data) { int page_count = -1; - success = args->GetInteger(1, &page_count); + success = args->GetInteger(2, &page_count); DCHECK(success); if (page_count != -1) { @@ -823,10 +864,18 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { // before printing. UMA_HISTOGRAM_COUNTS("PrintPreview.RegeneratePreviewRequest.BeforePrint", regenerate_preview_request_count_); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + CHECK(!callback_id.empty()); + std::string json_str; + CHECK(args->GetString(1, &json_str)); - std::unique_ptr<base::DictionaryValue> settings = GetSettingsDictionary(args); - if (!settings) + std::unique_ptr<base::DictionaryValue> settings = + GetSettingsDictionary(json_str); + if (!settings) { + RejectJavascriptCallback(base::Value(callback_id), base::Value(-1)); return; + } ReportPrintSettingsStats(*settings); @@ -858,6 +907,8 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { if (print_to_pdf) { UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.PrintToPDF", page_count); ReportUserActionHistogram(PRINT_TO_PDF); + DCHECK(pdf_callback_id_.empty()); + pdf_callback_id_ = callback_id; PrintToPdf(); return; } @@ -879,14 +930,14 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { !settings->GetInteger(printing::kSettingPageHeight, &height) || width <= 0 || height <= 0) { NOTREACHED(); - base::Value http_code_value(-1); - web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrintFailed", - http_code_value); + RejectJavascriptCallback(base::Value(callback_id), base::Value(-1)); return; } - PrintToPrivetPrinter( - printer_name, print_ticket, capabilities, gfx::Size(width, height)); + DCHECK(privet_print_callback_id_.empty()); + privet_print_callback_id_ = callback_id; + PrintToPrivetPrinter(callback_id, printer_name, print_ticket, capabilities, + gfx::Size(width, height)); return; } #endif @@ -908,7 +959,7 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { !settings->GetInteger(printing::kSettingPageHeight, &height) || width <= 0 || height <= 0) { NOTREACHED(); - OnExtensionPrintResult(false, "FAILED"); + RejectJavascriptCallback(base::Value(callback_id), base::Value("FAILED")); return; } @@ -916,7 +967,8 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { scoped_refptr<base::RefCountedBytes> data; if (!GetPreviewDataAndTitle(&data, &title)) { LOG(ERROR) << "Nothing to print; no preview available."; - OnExtensionPrintResult(false, "NO_DATA"); + RejectJavascriptCallback(base::Value(callback_id), + base::Value("NO_DATA")); return; } @@ -925,7 +977,7 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { destination_id, capabilities, title, print_ticket, gfx::Size(width, height), data, base::Bind(&PrintPreviewHandler::OnExtensionPrintResult, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), callback_id)); return; } @@ -933,6 +985,7 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { base::string16 title; if (!GetPreviewDataAndTitle(&data, &title)) { // Nothing to print, no preview available. + RejectJavascriptCallback(base::Value(callback_id), base::Value()); return; } @@ -940,7 +993,7 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.PrintToCloudPrint", page_count); ReportUserActionHistogram(PRINT_WITH_CLOUD_PRINT); - SendCloudPrintJob(data.get()); + SendCloudPrintJob(callback_id, data.get()); return; } @@ -955,13 +1008,6 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { ReportUserActionHistogram(PRINT_TO_PRINTER); } - // This tries to activate the initiator as well, so do not clear the - // association with the initiator yet. - print_preview_ui()->OnHidePreviewDialog(); - - // Grab the current initiator before calling ClearInitiatorDetails() below. - // Otherwise calling GetInitiator() later will return the wrong WebContents. - // https://crbug.com/407080 WebContents* initiator = GetInitiator(); if (initiator) { // Save initiator IDs. PrintMsg_PrintForPrintPreview below should cause @@ -974,24 +1020,16 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { main_render_frame->GetRoutingID()); } - // Do this so the initiator can open a new print preview dialog, while the - // current print preview dialog is still handling its print job. - ClearInitiatorDetails(); - // Set ID to know whether printing is for preview. settings->SetInteger(printing::kPreviewUIID, print_preview_ui()->GetIDForPrintPreviewUI()); - RenderFrameHost* rfh = preview_web_contents()->GetMainFrame(); - rfh->Send(new PrintMsg_PrintForPrintPreview(rfh->GetRoutingID(), *settings)); - // For all other cases above, the preview dialog will stay open until the - // printing has finished. Then the dialog closes and PrintPreviewDone() gets - // called. In the case below, since the preview dialog will be hidden and - // not closed, we need to make this call. - if (initiator) { - auto* print_view_manager = PrintViewManager::FromWebContents(initiator); - print_view_manager->PrintPreviewDone(); - } + // Save the settings and notify print preview. Print preview will respond + // with a "hidePreviewDialog" message, and then the message can be sent to + // the renderer in HandleHidePreview(). + settings_ = std::move(settings); + ResolveJavascriptCallback(base::Value(callback_id), base::Value()); + #else NOTREACHED(); #endif // BUILDFLAG(ENABLE_BASIC_PRINTING) @@ -1000,6 +1038,8 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { void PrintPreviewHandler::PrintToPdf() { if (!print_to_pdf_path_.empty()) { // User has already selected a path, no need to show the dialog again. + ResolveJavascriptCallback(base::Value(pdf_callback_id_), base::Value()); + pdf_callback_id_.clear(); PostPrintToPdfTask(); } else if (!select_file_dialog_.get() || !select_file_dialog_->IsRunning(platform_util::GetTopLevel( @@ -1027,6 +1067,27 @@ void PrintPreviewHandler::PrintToPdf() { } void PrintPreviewHandler::HandleHidePreview(const base::ListValue* /*args*/) { + if (settings_) { + // Print preview is responding to a resolution of "print" promise. Send the + // print message to the renderer. + RenderFrameHost* rfh = preview_web_contents()->GetMainFrame(); + rfh->Send( + new PrintMsg_PrintForPrintPreview(rfh->GetRoutingID(), *settings_)); + settings_.reset(); + + // Clear the initiator so that it can open a new print preview dialog, while + // the current print preview dialog is still handling its print job. + WebContents* initiator = GetInitiator(); + ClearInitiatorDetails(); + + // Since the preview dialog will be hidden and not closed, we need to make + // this call. + if (initiator) { + auto* print_view_manager = PrintViewManager::FromWebContents(initiator); + print_view_manager->PrintPreviewDone(); + } + } + print_preview_ui()->OnHidePreviewDialog(); } @@ -1049,10 +1110,13 @@ void PrintPreviewHandler::HandleSaveAppState(const base::ListValue* args) { void PrintPreviewHandler::HandleGetPrinterCapabilities( const base::ListValue* args) { + std::string callback_id; std::string printer_name; - bool ret = args->GetString(0, &printer_name); - if (!ret || printer_name.empty()) + if (!args->GetString(0, &callback_id) || !args->GetString(1, &printer_name) || + callback_id.empty() || printer_name.empty()) { + RejectJavascriptCallback(base::Value(callback_id), base::Value()); return; + } if (printer_name == kLocalPdfPrinterId) { auto printer_info = base::MakeUnique<base::DictionaryValue>(); @@ -1060,13 +1124,13 @@ void PrintPreviewHandler::HandleGetPrinterCapabilities( printer_info->Set( printing::kPrinterCapabilities, GetPdfCapabilities(g_browser_process->GetApplicationLocale())); - SendPrinterCapabilities(printer_name, std::move(printer_info)); + SendPrinterCapabilities(callback_id, printer_name, std::move(printer_info)); return; } printing::PrinterSetupCallback cb = base::Bind(&PrintPreviewHandler::SendPrinterCapabilities, - weak_factory_.GetWeakPtr(), printer_name); + weak_factory_.GetWeakPtr(), callback_id, printer_name); printer_backend_proxy()->ConfigurePrinterAndFetchCapabilities(printer_name, cb); @@ -1075,8 +1139,6 @@ void PrintPreviewHandler::HandleGetPrinterCapabilities( // |args| is expected to contain a string with representing the callback id // followed by a list of arguments the first of which should be the printer id. void PrintPreviewHandler::HandlePrinterSetup(const base::ListValue* args) { - AllowJavascript(); - std::string callback_id; std::string printer_name; if (!args->GetString(0, &callback_id) || !args->GetString(1, &printer_name) || @@ -1092,33 +1154,37 @@ void PrintPreviewHandler::HandlePrinterSetup(const base::ListValue* args) { weak_factory_.GetWeakPtr(), callback_id, printer_name)); } -void PrintPreviewHandler::OnSigninComplete() { - if (print_preview_ui()) - print_preview_ui()->OnReloadPrintersList(); +void PrintPreviewHandler::OnSigninComplete(const std::string& callback_id) { + ResolveJavascriptCallback(base::Value(callback_id), base::Value()); } void PrintPreviewHandler::HandleSignin(const base::ListValue* args) { + std::string callback_id; bool add_account = false; - bool success = args->GetBoolean(0, &add_account); - DCHECK(success); + CHECK(args->GetString(0, &callback_id)); + CHECK(!callback_id.empty()); + CHECK(args->GetBoolean(1, &add_account)); Profile* profile = Profile::FromBrowserContext( preview_web_contents()->GetBrowserContext()); chrome::ScopedTabbedBrowserDisplayer displayer(profile); print_dialog_cloud::CreateCloudPrintSigninTab( - displayer.browser(), - add_account, + displayer.browser(), add_account, base::Bind(&PrintPreviewHandler::OnSigninComplete, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), callback_id)); } void PrintPreviewHandler::HandleGetAccessToken(const base::ListValue* args) { + std::string callback_id; std::string type; - if (!args->GetString(0, &type)) - return; + + bool ok = args->GetString(0, &callback_id) && args->GetString(1, &type) && + !callback_id.empty(); + DCHECK(ok); + if (!token_service_) token_service_ = base::MakeUnique<AccessTokenService>(this); - token_service_->RequestToken(type); + token_service_->RequestToken(type, callback_id); } void PrintPreviewHandler::HandleManageCloudPrint( @@ -1129,7 +1195,7 @@ void PrintPreviewHandler::HandleManageCloudPrint( if (!args->GetString(0, &user)) return; if (!user.empty()) - manage_url = net::AppendQueryParameter(manage_url, "user", user); + manage_url = net::AppendQueryParameter(manage_url, "authuser", user); preview_web_contents()->OpenURL( content::OpenURLParams(manage_url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, @@ -1277,27 +1343,26 @@ void PrintPreviewHandler::ClosePreviewDialog() { print_preview_ui()->OnClosePrintPreviewDialog(); } -void PrintPreviewHandler::SendAccessToken(const std::string& type, +void PrintPreviewHandler::SendAccessToken(const std::string& callback_id, const std::string& access_token) { VLOG(1) << "Get getAccessToken finished"; - web_ui()->CallJavascriptFunctionUnsafe( - "onDidGetAccessToken", base::Value(type), base::Value(access_token)); + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(access_token)); } void PrintPreviewHandler::SendPrinterCapabilities( + const std::string& callback_id, const std::string& printer_name, std::unique_ptr<base::DictionaryValue> settings_info) { // Check that |settings_info| is valid. if (settings_info && settings_info->Get("capabilities", nullptr)) { VLOG(1) << "Get printer capabilities finished"; - web_ui()->CallJavascriptFunctionUnsafe("updateWithPrinterCapabilities", - *settings_info); + ResolveJavascriptCallback(base::Value(callback_id), *settings_info); return; } VLOG(1) << "Get printer capabilities failed"; - web_ui()->CallJavascriptFunctionUnsafe("failedToGetPrinterCapabilities", - base::Value(printer_name)); + RejectJavascriptCallback(base::Value(callback_id), base::Value()); } void PrintPreviewHandler::SendPrinterSetup( @@ -1325,6 +1390,7 @@ void PrintPreviewHandler::SendPrinterSetup( } void PrintPreviewHandler::SetupPrinterList( + const std::string& callback_id, const printing::PrinterList& printer_list) { base::ListValue printers; PrintersToValues(printer_list, &printers); @@ -1337,7 +1403,7 @@ void PrintPreviewHandler::SetupPrinterList( has_logged_printers_count_ = true; } - web_ui()->CallJavascriptFunctionUnsafe("setPrinters", printers); + ResolveJavascriptCallback(base::Value(callback_id), printers); } void PrintPreviewHandler::SendCloudPrintEnabled() { @@ -1345,23 +1411,22 @@ void PrintPreviewHandler::SendCloudPrintEnabled() { preview_web_contents()->GetBrowserContext()); PrefService* prefs = profile->GetPrefs(); if (prefs->GetBoolean(prefs::kCloudPrintSubmitEnabled)) { - base::DictionaryValue settings; - settings.SetString(kCloudPrintUrl, - GURL(cloud_devices::GetCloudPrintURL()).spec()); - settings.SetBoolean(kAppKioskMode, chrome::IsRunningInForcedAppMode()); - web_ui()->CallJavascriptFunctionUnsafe("setUseCloudPrint", settings); + FireWebUIListener( + "use-cloud-print", + base::Value(GURL(cloud_devices::GetCloudPrintURL()).spec()), + base::Value(chrome::IsRunningInForcedAppMode())); } } -void PrintPreviewHandler::SendCloudPrintJob(const base::RefCountedBytes* data) { +void PrintPreviewHandler::SendCloudPrintJob(const std::string& callback_id, + const base::RefCountedBytes* data) { // BASE64 encode the job data. const base::StringPiece raw_data(reinterpret_cast<const char*>(data->front()), data->size()); std::string base64_data; base::Base64Encode(raw_data, &base64_data); - base::Value data_value(base64_data); - web_ui()->CallJavascriptFunctionUnsafe("printToCloud", data_value); + ResolveJavascriptCallback(base::Value(callback_id), base::Value(base64_data)); } WebContents* PrintPreviewHandler::GetInitiator() const { @@ -1375,7 +1440,7 @@ WebContents* PrintPreviewHandler::GetInitiator() const { void PrintPreviewHandler::OnAddAccountToCookieCompleted( const std::string& account_id, const GoogleServiceAuthError& error) { - OnSigninComplete(); + FireWebUIListener("reload-printer-list"); } void PrintPreviewHandler::SelectFile(const base::FilePath& default_filename, @@ -1384,43 +1449,64 @@ void PrintPreviewHandler::SelectFile(const base::FilePath& default_filename, ChromeSelectFilePolicy policy(GetInitiator()); if (!policy.CanOpenSelectFileDialog()) { policy.SelectFileDenied(); - return ClosePreviewDialog(); + RejectJavascriptCallback(base::Value(pdf_callback_id_), base::Value()); + pdf_callback_id_.clear(); + return; } } // Get save location from Download Preferences. DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext( preview_web_contents()->GetBrowserContext()); - base::FilePath file_path = download_prefs->SaveFilePath(); + base::FilePath path = download_prefs->SaveFilePath(); printing::StickySettings* sticky_settings = GetStickySettings(); sticky_settings->SaveInPrefs(Profile::FromBrowserContext( preview_web_contents()->GetBrowserContext())->GetPrefs()); + // Handle the no prompting case. Like the dialog prompt, this function // returns and eventually FileSelected() gets called. if (!prompt_user) { base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&GetUniquePath, - download_prefs->SaveFilePath().Append(default_filename)), + base::Bind(&GetUniquePath, path.Append(default_filename)), base::Bind(&PrintPreviewHandler::OnGotUniqueFileName, weak_factory_.GetWeakPtr())); return; } - // Otherwise prompt the user. + // If the directory is empty there is no reason to create it. + if (path.empty()) { + OnDirectoryCreated(default_filename); + return; + } + + // Create the directory to save in if it does not exist. + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::Bind(&CreateDirectoryIfNeeded, path), + base::Bind(&PrintPreviewHandler::OnDirectoryCreated, + weak_factory_.GetWeakPtr(), path.Append(default_filename))); +} + +void PrintPreviewHandler::OnDirectoryCreated(const base::FilePath& path) { + // Prompts the user to select the file. ui::SelectFileDialog::FileTypeInfo file_type_info; file_type_info.extensions.resize(1); file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pdf")); + file_type_info.include_all_files = true; + // Print Preview requires native paths to write PDF files. + // Note that Chrome OS save-as dialog has Google Drive as a saving location + // even when a client requires native paths. In this case, Chrome OS save-as + // dialog returns native paths to write files and uploads the saved files to + // Google Drive later. + file_type_info.allowed_paths = + ui::SelectFileDialog::FileTypeInfo::NATIVE_PATH; select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr /*policy already checked*/); select_file_dialog_->SelectFile( - ui::SelectFileDialog::SELECT_SAVEAS_FILE, - base::string16(), - download_prefs->SaveFilePath().Append(default_filename), - &file_type_info, - 0, - base::FilePath::StringType(), + ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(), path, + &file_type_info, 0, base::FilePath::StringType(), platform_util::GetTopLevel(preview_web_contents()->GetNativeView()), NULL); } @@ -1429,11 +1515,70 @@ void PrintPreviewHandler::OnGotUniqueFileName(const base::FilePath& path) { FileSelected(path, 0, nullptr); } -void PrintPreviewHandler::OnPrintPreviewFailed() { - if (reported_failed_preview_) +void PrintPreviewHandler::OnPrintPreviewReady(int preview_uid, int request_id) { + if (request_id < 0) // invalid ID. return; - reported_failed_preview_ = true; - ReportUserActionHistogram(PREVIEW_FAILED); + CHECK(!preview_callbacks_.empty()); + ResolveJavascriptCallback(base::Value(preview_callbacks_.front()), + base::Value(preview_uid)); + preview_callbacks_.pop(); +} + +void PrintPreviewHandler::OnPrintPreviewFailed() { + CHECK(!preview_callbacks_.empty()); + if (!reported_failed_preview_) { + reported_failed_preview_ = true; + ReportUserActionHistogram(PREVIEW_FAILED); + } + RejectJavascriptCallback(base::Value(preview_callbacks_.front()), + base::Value("PREVIEW_FAILED")); + preview_callbacks_.pop(); +} + +void PrintPreviewHandler::OnInvalidPrinterSettings() { + CHECK(!preview_callbacks_.empty()); + RejectJavascriptCallback(base::Value(preview_callbacks_.front()), + base::Value("SETTINGS_INVALID")); + preview_callbacks_.pop(); +} + +void PrintPreviewHandler::SendPrintPresetOptions(bool disable_scaling, + int copies, + int duplex) { + FireWebUIListener("print-preset-options", base::Value(disable_scaling), + base::Value(copies), base::Value(duplex)); +} + +void PrintPreviewHandler::SendPageCountReady(int page_count, + int request_id, + int fit_to_page_scaling) { + FireWebUIListener("page-count-ready", base::Value(page_count), + base::Value(request_id), base::Value(fit_to_page_scaling)); +} + +void PrintPreviewHandler::SendPageLayoutReady( + const base::DictionaryValue& layout, + bool has_custom_page_size_style) { + FireWebUIListener("page-layout-ready", layout, + base::Value(has_custom_page_size_style)); +} + +void PrintPreviewHandler::SendPagePreviewReady(int page_index, + int preview_uid, + int preview_response_id) { + FireWebUIListener("page-preview-ready", base::Value(page_index), + base::Value(preview_uid), base::Value(preview_response_id)); +} + +void PrintPreviewHandler::OnPrintPreviewCancelled() { + CHECK(!preview_callbacks_.empty()); + RejectJavascriptCallback(base::Value(preview_callbacks_.front()), + base::Value("CANCELLED")); + preview_callbacks_.pop(); +} + +void PrintPreviewHandler::OnPrintRequestCancelled() { + HandleCancelPendingPrintRequest(nullptr); } #if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG) @@ -1453,7 +1598,8 @@ void PrintPreviewHandler::FileSelected(const base::FilePath& path, sticky_settings->SaveInPrefs( Profile::FromBrowserContext(preview_web_contents()->GetBrowserContext()) ->GetPrefs()); - web_ui()->CallJavascriptFunctionUnsafe("fileSelectionCompleted"); + ResolveJavascriptCallback(base::Value(pdf_callback_id_), base::Value()); + pdf_callback_id_.clear(); print_to_pdf_path_ = path; PostPrintToPdfTask(); } @@ -1475,7 +1621,8 @@ void PrintPreviewHandler::PostPrintToPdfTask() { } void PrintPreviewHandler::FileSelectionCanceled(void* params) { - print_preview_ui()->OnFileSelectionCancelled(); + RejectJavascriptCallback(base::Value(pdf_callback_id_), base::Value()); + pdf_callback_id_.clear(); } void PrintPreviewHandler::ClearInitiatorDetails() { @@ -1514,15 +1661,16 @@ bool PrintPreviewHandler::GetPreviewDataAndTitle( #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) void PrintPreviewHandler::StartPrivetLister(const scoped_refptr< local_discovery::ServiceDiscoverySharedClient>& client) { - if (!PrivetPrintingEnabled()) - return web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrinterSearchDone"); - Profile* profile = Profile::FromWebUI(web_ui()); DCHECK(!service_discovery_client_.get() || service_discovery_client_.get() == client.get()); service_discovery_client_ = client; printer_lister_ = base::MakeUnique<cloud_print::PrivetLocalPrinterLister>( service_discovery_client_.get(), profile->GetRequestContext(), this); + privet_lister_timer_.reset(new base::OneShotTimer()); + privet_lister_timer_->Start(FROM_HERE, + base::TimeDelta::FromSeconds(kPrivetTimeoutSec), + this, &PrintPreviewHandler::StopPrivetLister); printer_lister_->Start(); } @@ -1535,7 +1683,7 @@ void PrintPreviewHandler::LocalPrinterChanged( command_line->HasSwitch(switches::kEnablePrintPreviewRegisterPromos)) { base::DictionaryValue info; FillPrinterDescription(name, description, has_local_printing, &info); - web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrinterChanged", info); + FireWebUIListener("privet-printer-added", info); } } @@ -1546,22 +1694,26 @@ void PrintPreviewHandler::LocalPrinterCacheFlushed() { } void PrintPreviewHandler::PrivetCapabilitiesUpdateClient( + const std::string& callback_id, std::unique_ptr<cloud_print::PrivetHTTPClient> http_client) { - if (!PrivetUpdateClient(std::move(http_client))) + if (!PrivetUpdateClient(callback_id, std::move(http_client))) return; privet_capabilities_operation_ = privet_http_client_->CreateCapabilitiesOperation( base::Bind(&PrintPreviewHandler::OnPrivetCapabilities, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), callback_id)); privet_capabilities_operation_->Start(); } bool PrintPreviewHandler::PrivetUpdateClient( + const std::string& callback_id, std::unique_ptr<cloud_print::PrivetHTTPClient> http_client) { if (!http_client) { - SendPrivetCapabilitiesError(privet_http_resolution_->GetName()); + RejectJavascriptCallback(base::Value(callback_id), base::Value()); privet_http_resolution_.reset(); + if (callback_id == privet_print_callback_id_) + privet_print_callback_id_.clear(); return false; } @@ -1576,11 +1728,12 @@ bool PrintPreviewHandler::PrivetUpdateClient( } void PrintPreviewHandler::PrivetLocalPrintUpdateClient( + const std::string& callback_id, std::string print_ticket, std::string capabilities, gfx::Size page_size, std::unique_ptr<cloud_print::PrivetHTTPClient> http_client) { - if (!PrivetUpdateClient(std::move(http_client))) + if (!PrivetUpdateClient(callback_id, std::move(http_client))) return; StartPrivetLocalPrint(print_ticket, capabilities, page_size); @@ -1599,9 +1752,9 @@ void PrintPreviewHandler::StartPrivetLocalPrint(const std::string& print_ticket, base::string16 title; if (!GetPreviewDataAndTitle(&data, &title)) { - base::Value http_code_value(-1); - web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrintFailed", - http_code_value); + RejectJavascriptCallback(base::Value(privet_print_callback_id_), + base::Value(-1)); + privet_print_callback_id_.clear(); return; } @@ -1621,49 +1774,53 @@ void PrintPreviewHandler::StartPrivetLocalPrint(const std::string& print_ticket, privet_local_print_operation_->Start(); } - void PrintPreviewHandler::OnPrivetCapabilities( + const std::string& callback_id, const base::DictionaryValue* capabilities) { std::string name = privet_capabilities_operation_->GetHTTPClient()->GetName(); if (!capabilities || capabilities->HasKey(cloud_print::kPrivetKeyError) || !printer_lister_) { - SendPrivetCapabilitiesError(name); + RejectJavascriptCallback(base::Value(callback_id), base::Value()); return; } - base::DictionaryValue printer_info; const cloud_print::DeviceDescription* description = printer_lister_->GetDeviceDescription(name); if (!description) { - SendPrivetCapabilitiesError(name); + RejectJavascriptCallback(base::Value(callback_id), base::Value()); return; } - FillPrinterDescription(name, *description, true, &printer_info); - - web_ui()->CallJavascriptFunctionUnsafe("onPrivetCapabilitiesSet", - printer_info, *capabilities); + std::unique_ptr<base::DictionaryValue> printer_info = + base::MakeUnique<base::DictionaryValue>(); + FillPrinterDescription(name, *description, true, printer_info.get()); + base::DictionaryValue printer_info_and_caps; + printer_info_and_caps.SetDictionary("printer", std::move(printer_info)); + std::unique_ptr<base::DictionaryValue> capabilities_copy = + capabilities->CreateDeepCopy(); + printer_info_and_caps.SetDictionary("capabilities", + std::move(capabilities_copy)); + ResolveJavascriptCallback(base::Value(callback_id), printer_info_and_caps); privet_capabilities_operation_.reset(); } -void PrintPreviewHandler::SendPrivetCapabilitiesError( - const std::string& device_name) { - base::Value name_value(device_name); - web_ui()->CallJavascriptFunctionUnsafe("failedToGetPrivetPrinterCapabilities", - name_value); -} - -void PrintPreviewHandler::PrintToPrivetPrinter(const std::string& device_name, +void PrintPreviewHandler::PrintToPrivetPrinter(const std::string& callback_id, + const std::string& device_name, const std::string& ticket, const std::string& capabilities, const gfx::Size& page_size) { - CreatePrivetHTTP( - device_name, - base::Bind(&PrintPreviewHandler::PrivetLocalPrintUpdateClient, - weak_factory_.GetWeakPtr(), ticket, capabilities, page_size)); + if (!CreatePrivetHTTP( + device_name, + base::Bind(&PrintPreviewHandler::PrivetLocalPrintUpdateClient, + weak_factory_.GetWeakPtr(), callback_id, ticket, + capabilities, page_size))) { + RejectJavascriptCallback(base::Value(privet_print_callback_id_), + base::Value(-1)); + privet_print_callback_id_.clear(); + } } bool PrintPreviewHandler::CreatePrivetHTTP( @@ -1673,10 +1830,8 @@ bool PrintPreviewHandler::CreatePrivetHTTP( const cloud_print::DeviceDescription* device_description = printer_lister_ ? printer_lister_->GetDeviceDescription(name) : NULL; - if (!device_description) { - SendPrivetCapabilitiesError(name); + if (!device_description) return false; - } privet_http_factory_ = cloud_print::PrivetHTTPAsynchronousFactory::CreateInstance( @@ -1689,15 +1844,17 @@ bool PrintPreviewHandler::CreatePrivetHTTP( void PrintPreviewHandler::OnPrivetPrintingDone( const cloud_print::PrivetLocalPrintOperation* print_operation) { - ClosePreviewDialog(); + ResolveJavascriptCallback(base::Value(privet_print_callback_id_), + base::Value()); + privet_print_callback_id_.clear(); } void PrintPreviewHandler::OnPrivetPrintingError( const cloud_print::PrivetLocalPrintOperation* print_operation, int http_code) { - base::Value http_code_value(http_code); - web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrintFailed", - http_code_value); + RejectJavascriptCallback(base::Value(privet_print_callback_id_), + base::Value(http_code)); + privet_print_callback_id_.clear(); } void PrintPreviewHandler::FillPrinterDescription( @@ -1727,55 +1884,50 @@ void PrintPreviewHandler::EnsureExtensionPrinterHandlerSet() { } void PrintPreviewHandler::OnGotPrintersForExtension( + const std::string& callback_id, const base::ListValue& printers, bool done) { - web_ui()->CallJavascriptFunctionUnsafe("onExtensionPrintersAdded", printers, - base::Value(done)); + FireWebUIListener("extension-printers-added", printers); + if (done) { + ResolveJavascriptCallback(base::Value(callback_id), base::Value()); + } } void PrintPreviewHandler::OnGotExtensionPrinterInfo( - const std::string& printer_id, + const std::string& callback_id, const base::DictionaryValue& printer_info) { if (printer_info.empty()) { - web_ui()->CallJavascriptFunctionUnsafe("failedToResolveProvisionalPrinter", - base::Value(printer_id)); + RejectJavascriptCallback(base::Value(callback_id), base::Value()); return; } - - web_ui()->CallJavascriptFunctionUnsafe("onProvisionalPrinterResolved", - base::Value(printer_id), printer_info); + ResolveJavascriptCallback(base::Value(callback_id), printer_info); } void PrintPreviewHandler::OnGotExtensionPrinterCapabilities( - const std::string& printer_id, + const std::string& callback_id, const base::DictionaryValue& capabilities) { if (capabilities.empty()) { - web_ui()->CallJavascriptFunctionUnsafe( - "failedToGetExtensionPrinterCapabilities", base::Value(printer_id)); + RejectJavascriptCallback(base::Value(callback_id), base::Value()); return; } - - web_ui()->CallJavascriptFunctionUnsafe("onExtensionCapabilitiesSet", - base::Value(printer_id), capabilities); + ResolveJavascriptCallback(base::Value(callback_id), capabilities); } -void PrintPreviewHandler::OnExtensionPrintResult(bool success, +void PrintPreviewHandler::OnExtensionPrintResult(const std::string& callback_id, + bool success, const std::string& status) { if (success) { - ClosePreviewDialog(); + ResolveJavascriptCallback(base::Value(callback_id), base::Value()); return; } - - // TODO(tbarzic): This function works for extension printers case too, but it - // should be renamed to something more generic. - web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrintFailed", - base::Value(status)); + RejectJavascriptCallback(base::Value(callback_id), base::Value(status)); } void PrintPreviewHandler::RegisterForGaiaCookieChanges() { DCHECK(!gaia_cookie_manager_service_); Profile* profile = Profile::FromWebUI(web_ui()); - if (switches::IsEnableAccountConsistency() && !profile->IsOffTheRecord()) { + if (switches::IsAccountConsistencyMirrorEnabled() && + !profile->IsOffTheRecord()) { gaia_cookie_manager_service_ = GaiaCookieManagerServiceFactory::GetForProfile(profile); if (gaia_cookie_manager_service_) @@ -1792,3 +1944,12 @@ void PrintPreviewHandler::SetPdfSavedClosureForTesting( const base::Closure& closure) { pdf_file_saved_closure_ = closure; } + +void PrintPreviewHandler::SendEnableManipulateSettingsForTest() { + FireWebUIListener("enable-manipulate-settings-for-test", base::Value()); +} + +void PrintPreviewHandler::SendManipulateSettingsForTest( + const base::DictionaryValue& settings) { + FireWebUIListener("manipulate-settings-for-test", settings); +} diff --git a/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.h index 2166080fc28..c638f650756 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.h +++ b/chromium/chrome/browser/ui/webui/print_preview/print_preview_handler.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_ #include <memory> +#include <queue> #include <string> #include "base/files/file_path.h" @@ -13,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" #include "chrome/common/features.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "content/public/browser/web_ui_message_handler.h" @@ -75,6 +77,35 @@ class PrintPreviewHandler // Called when print preview failed. void OnPrintPreviewFailed(); + // Called when print preview is cancelled due to a new request. + void OnPrintPreviewCancelled(); + + // Called when printer settings were invalid. + void OnInvalidPrinterSettings(); + + // Called when print preview is ready. + void OnPrintPreviewReady(int preview_uid, int request_id); + + // Called when a print request is cancelled due to its initiator closing. + void OnPrintRequestCancelled(); + + // Send the print preset options from the document. + void SendPrintPresetOptions(bool disable_scaling, int copies, int duplex); + + // Send the print preview page count and fit to page scaling + void SendPageCountReady(int page_count, + int request_id, + int fit_to_page_scaling); + + // Send the default page layout + void SendPageLayoutReady(const base::DictionaryValue& layout, + bool has_custom_page_size_style); + + // Notify the WebUI that the page preview is ready. + void SendPagePreviewReady(int page_index, + int preview_uid, + int preview_response_id); + #if BUILDFLAG(ENABLE_BASIC_PRINTING) // Called when the user press ctrl+shift+p to display the native system // dialog. @@ -105,9 +136,17 @@ class PrintPreviewHandler // Sets |pdf_file_saved_closure_| to |closure|. void SetPdfSavedClosureForTesting(const base::Closure& closure); + // Fires the 'enable-manipulate-settings-for-test' WebUI event. + void SendEnableManipulateSettingsForTest(); + + // Fires the 'manipulate-settings-for-test' WebUI event with |settings|. + void SendManipulateSettingsForTest(const base::DictionaryValue& settings); + protected: - // If |prompt_user| is true, displays a modal dialog, prompting the user to - // select a file. Otherwise, just accept |default_path| and uniquify it. + // If |prompt_user| is true, starts a task to create the default Save As PDF + // directory if needed. OnDirectoryCreated() will be called when it + // finishes to open the modal dialog and prompt the user. Otherwise, just + // accept |default_path| and uniquify it. // Protected so unit tests can access. virtual void SelectFile(const base::FilePath& default_path, bool prompt_user); @@ -142,9 +181,6 @@ class PrintPreviewHandler // |args| is the provisional printer ID. void HandleGrantExtensionPrinterAccess(const base::ListValue* args); - // Stops getting all local privet printers. |arg| is unused. - void HandleStopGetPrivetPrinters(const base::ListValue* args); - // Asks the initiator renderer to generate a preview. First element of |args| // is a job settings JSON string. void HandleGetPreview(const base::ListValue* args); @@ -177,7 +213,7 @@ class PrintPreviewHandler #endif // Callback for the signin dialog to call once signin is complete. - void OnSigninComplete(); + void OnSigninComplete(const std::string& callback_id); // Brings up a dialog to allow the user to sign into cloud print. // |args| is unused. @@ -225,13 +261,17 @@ class PrintPreviewHandler const std::string& default_printer); // Send OAuth2 access token. - void SendAccessToken(const std::string& type, + void SendAccessToken(const std::string& callback_id, const std::string& access_token); + // Send message indicating a request for token was already in progress. + void SendRequestInProgress(const std::string& callback_id); + // Sends the printer capabilities to the Web UI. |settings_info| contains // printer capabilities information. If |settings_info| is empty, sends // error notification to the Web UI instead. void SendPrinterCapabilities( + const std::string& callback_id, const std::string& printer_name, std::unique_ptr<base::DictionaryValue> settings_info); @@ -242,13 +282,15 @@ class PrintPreviewHandler std::unique_ptr<base::DictionaryValue> settings_info); // Send the list of printers to the Web UI. - void SetupPrinterList(const printing::PrinterList& printer_list); + void SetupPrinterList(const std::string& callback_id, + const printing::PrinterList& printer_list); // Send whether cloud print integration should be enabled. void SendCloudPrintEnabled(); // Send the PDF data to the cloud to print. - void SendCloudPrintJob(const base::RefCountedBytes* data); + void SendCloudPrintJob(const std::string& callback_id, + const base::RefCountedBytes* data); // Gets the initiator for the print preview dialog. content::WebContents* GetInitiator() const; @@ -262,6 +304,10 @@ class PrintPreviewHandler // Clears initiator details for the print preview dialog. void ClearInitiatorDetails(); + // Called when the directory to save to has been created. Opens a modal + // dialog to prompt the user to select the file for Save As PDF. + void OnDirectoryCreated(const base::FilePath& path); + // Posts a task to save |data| to pdf at |print_to_pdf_path_|. void PostPrintToPdfTask(); @@ -285,21 +331,27 @@ class PrintPreviewHandler #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) void StartPrivetLister(const scoped_refptr< local_discovery::ServiceDiscoverySharedClient>& client); - void OnPrivetCapabilities(const base::DictionaryValue* capabilities); + void StopPrivetLister(); + void OnPrivetCapabilities(const std::string& callback_id, + const base::DictionaryValue* capabilities); void PrivetCapabilitiesUpdateClient( + const std::string& callback_id, std::unique_ptr<cloud_print::PrivetHTTPClient> http_client); void PrivetLocalPrintUpdateClient( + const std::string& callback_id, std::string print_ticket, std::string capabilities, gfx::Size page_size, std::unique_ptr<cloud_print::PrivetHTTPClient> http_client); bool PrivetUpdateClient( + const std::string& callback_id, std::unique_ptr<cloud_print::PrivetHTTPClient> http_client); void StartPrivetLocalPrint(const std::string& print_ticket, const std::string& capabilities, const gfx::Size& page_size); void SendPrivetCapabilitiesError(const std::string& id); - void PrintToPrivetPrinter(const std::string& printer_name, + void PrintToPrivetPrinter(const std::string& callback_id, + const std::string& printer_name, const std::string& print_ticket, const std::string& capabilities, const gfx::Size& page_size); @@ -319,31 +371,38 @@ class PrintPreviewHandler void EnsureExtensionPrinterHandlerSet(); // Called when a list of printers is reported by an extension. + // |callback_id|: The javascript callback to call if all extension printers + // are loaded (when |done| = true) // |printers|: The list of printers managed by the extension. // |done|: Whether all the extensions have reported the list of printers // they manage. - void OnGotPrintersForExtension(const base::ListValue& printers, bool done); + void OnGotPrintersForExtension(const std::string& callback_id, + const base::ListValue& printers, + bool done); // Called when an extension reports information requested for a provisional // printer. - // |printer_id|: The provisional printer id. + // |callback_id|: The javascript callback to resolve or reject. // |printer_info|: The data reported by the extension. - void OnGotExtensionPrinterInfo(const std::string& printer_id, + void OnGotExtensionPrinterInfo(const std::string& callback_id, const base::DictionaryValue& printer_info); // Called when an extension reports the set of print capabilites for a // printer. - // |printer_id|: The id of the printer whose capabilities are reported. + // |callback_id|: The Javascript callback to reject or resolve // |capabilities|: The printer capabilities. void OnGotExtensionPrinterCapabilities( - const std::string& printer_id, + const std::string& callback_id, const base::DictionaryValue& capabilities); // Called when an extension print job is completed. + // |callback_id|: The javascript callback to run. // |success|: Whether the job succeeded. // |status|: The returned print job status. Useful for reporting a specific // error. - void OnExtensionPrintResult(bool success, const std::string& status); + void OnExtensionPrintResult(const std::string& callback_id, + bool success, + const std::string& status); // Register/unregister from notifications of changes done to the GAIA // cookie. @@ -379,7 +438,7 @@ class PrintPreviewHandler scoped_refptr<local_discovery::ServiceDiscoverySharedClient> service_discovery_client_; std::unique_ptr<cloud_print::PrivetLocalPrinterLister> printer_lister_; - + std::unique_ptr<base::OneShotTimer> privet_lister_timer_; std::unique_ptr<cloud_print::PrivetHTTPAsynchronousFactory> privet_http_factory_; std::unique_ptr<cloud_print::PrivetHTTPResolution> privet_http_resolution_; @@ -398,6 +457,23 @@ class PrintPreviewHandler // notify the test if it was a successful save, only that it was attempted. base::Closure pdf_file_saved_closure_; + std::queue<std::string> preview_callbacks_; + +#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) + // Callback ID to be used to notify UI that privet search is finished. + std::string privet_search_callback_id_; + + // Callback ID to be used to notify UI that privet printing is finished. + std::string privet_print_callback_id_; +#endif + + // Callback ID to be used to notify UI that PDF file selection has finished. + std::string pdf_callback_id_; + + // Print settings to use in the local print request to send when + // HandleHidePreview() is called. + std::unique_ptr<base::DictionaryValue> settings_; + // Proxy for calls to the print backend. Lazily initialized since web_ui() is // not available at construction time. std::unique_ptr<printing::PrinterBackendProxy> printer_backend_proxy_; diff --git a/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index e675add9cbe..2294f9ca85b 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.cc @@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h" #include <map> +#include <memory> #include <utility> #include <vector> @@ -31,10 +32,12 @@ #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h" #include "chrome/browser/ui/webui/theme_source.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" +#include "components/prefs/pref_service.h" #include "components/printing/common/print_messages.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/url_data_source.h" @@ -49,11 +52,6 @@ #include "ui/web_dialogs/web_dialog_delegate.h" #include "ui/web_dialogs/web_dialog_ui.h" -#if defined(OS_CHROMEOS) -#include "base/command_line.h" -#include "chrome/common/chrome_switches.h" -#endif - using content::WebContents; using printing::PageSizeMargins; @@ -165,7 +163,7 @@ bool HandleRequestCallback( return true; } -content::WebUIDataSource* CreatePrintPreviewUISource() { +content::WebUIDataSource* CreatePrintPreviewUISource(Profile* profile) { content::WebUIDataSource* source = content::WebUIDataSource::Create(chrome::kChromeUIPrintHost); #if defined(OS_CHROMEOS) @@ -420,14 +418,15 @@ content::WebUIDataSource* CreatePrintPreviewUISource() { #else source->AddBoolean("printPdfAsImageEnabled", false); #endif + #if defined(OS_CHROMEOS) - bool cups_and_md_settings_enabled = - !base::CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kDisableNativeCups); - source->AddBoolean("showLocalManageButton", cups_and_md_settings_enabled); + source->AddBoolean("useSystemDefaultPrinter", false); #else - source->AddBoolean("showLocalManageButton", true); + bool system_default_printer = profile->GetPrefs()->GetBoolean( + prefs::kPrintPreviewUseSystemDefaultPrinter); + source->AddBoolean("useSystemDefaultPrinter", system_default_printer); #endif + source->AddBoolean("showLocalManageButton", true); return source; } @@ -444,7 +443,7 @@ PrintPreviewUI::PrintPreviewUI(content::WebUI* web_ui) dialog_closed_(false) { // Set up the chrome://print/ data source. Profile* profile = Profile::FromWebUI(web_ui); - content::WebUIDataSource::Add(profile, CreatePrintPreviewUISource()); + content::WebUIDataSource::Add(profile, CreatePrintPreviewUISource(profile)); // Set up the chrome://theme/ source. content::URLDataSource::Add(profile, new ThemeSource(profile)); @@ -529,13 +528,24 @@ void PrintPreviewUI::OnPrintPreviewDialogClosed() { } void PrintPreviewUI::OnInitiatorClosed() { + // Should only get here if the initiator was still tracked by the Print + // Preview Dialog Controller, so the print job has not yet been sent. WebContents* preview_dialog = web_ui()->GetWebContents(); printing::BackgroundPrintingManager* background_printing_manager = g_browser_process->background_printing_manager(); - if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) - web_ui()->CallJavascriptFunctionUnsafe("cancelPendingPrintRequest"); - else + if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) { + // Dialog is hidden but is still generating the preview. Cancel the print + // request as it can't be completed. + background_printing_manager->OnPrintRequestCancelled(preview_dialog); + handler_->OnPrintRequestCancelled(); + } else { + // Initiator was closed while print preview dialog was still open. OnClosePrintPreviewDialog(); + } +} + +void PrintPreviewUI::OnPrintPreviewCancelled() { + handler_->OnPrintPreviewCancelled(); } void PrintPreviewUI::OnPrintPreviewRequest(int request_id) { @@ -551,11 +561,8 @@ void PrintPreviewUI::OnDidGetPreviewPageCount( DCHECK_GT(params.page_count, 0); if (g_testing_delegate) g_testing_delegate->DidGetPreviewPageCount(params.page_count); - base::Value count(params.page_count); - base::Value request_id(params.preview_request_id); - base::Value fit_to_page_scaling(params.fit_to_page_scaling); - web_ui()->CallJavascriptFunctionUnsafe("onDidGetPreviewPageCount", count, - request_id, fit_to_page_scaling); + handler_->SendPageCountReady(params.page_count, params.preview_request_id, + params.fit_to_page_scaling); } void PrintPreviewUI::OnDidGetDefaultPageLayout( @@ -582,22 +589,15 @@ void PrintPreviewUI::OnDidGetDefaultPageLayout( printable_area.width()); layout.SetInteger(printing::kSettingPrintableAreaHeight, printable_area.height()); - - base::Value has_page_size_style(has_custom_page_size_style); - web_ui()->CallJavascriptFunctionUnsafe("onDidGetDefaultPageLayout", layout, - has_page_size_style); + handler_->SendPageLayoutReady(layout, has_custom_page_size_style); } void PrintPreviewUI::OnDidPreviewPage(int page_number, int preview_request_id) { DCHECK_GE(page_number, 0); - base::Value number(page_number); - base::Value ui_identifier(id_); - base::Value request_id(preview_request_id); if (g_testing_delegate) g_testing_delegate->DidRenderPreviewPage(web_ui()->GetWebContents()); - web_ui()->CallJavascriptFunctionUnsafe("onDidPreviewPage", number, - ui_identifier, request_id); + handler_->SendPagePreviewReady(page_number, id_, preview_request_id); } void PrintPreviewUI::OnPreviewDataIsAvailable(int expected_pages_count, @@ -615,14 +615,7 @@ void PrintPreviewUI::OnPreviewDataIsAvailable(int expected_pages_count, handler_->regenerate_preview_request_count()); initial_preview_start_time_ = base::TimeTicks(); } - base::Value ui_identifier(id_); - base::Value ui_preview_request_id(preview_request_id); - web_ui()->CallJavascriptFunctionUnsafe("updatePrintPreview", ui_identifier, - ui_preview_request_id); -} - -void PrintPreviewUI::OnFileSelectionCancelled() { - web_ui()->CallJavascriptFunctionUnsafe("fileSelectionCancelled"); + handler_->OnPrintPreviewReady(id_, preview_request_id); } void PrintPreviewUI::OnCancelPendingPreviewRequest() { @@ -631,11 +624,10 @@ void PrintPreviewUI::OnCancelPendingPreviewRequest() { void PrintPreviewUI::OnPrintPreviewFailed() { handler_->OnPrintPreviewFailed(); - web_ui()->CallJavascriptFunctionUnsafe("printPreviewFailed"); } void PrintPreviewUI::OnInvalidPrinterSettings() { - web_ui()->CallJavascriptFunctionUnsafe("invalidPrinterSettings"); + handler_->OnInvalidPrinterSettings(); } void PrintPreviewUI::OnHidePreviewDialog() { @@ -667,19 +659,10 @@ void PrintPreviewUI::OnClosePrintPreviewDialog() { delegate->OnDialogCloseFromWebUI(); } -void PrintPreviewUI::OnReloadPrintersList() { - web_ui()->CallJavascriptFunctionUnsafe("reloadPrintersList"); -} - void PrintPreviewUI::OnSetOptionsFromDocument( const PrintHostMsg_SetOptionsFromDocument_Params& params) { - base::DictionaryValue options; - options.SetBoolean(printing::kSettingDisableScaling, - params.is_scaling_disabled); - options.SetInteger(printing::kSettingCopies, params.copies); - options.SetInteger(printing::kSettingDuplexMode, params.duplex); - web_ui()->CallJavascriptFunctionUnsafe("printPresetOptionsFromDocument", - options); + handler_->SendPrintPresetOptions(params.is_scaling_disabled, params.copies, + params.duplex); } // static @@ -695,3 +678,12 @@ void PrintPreviewUI::SetPdfSavedClosureForTesting( const base::Closure& closure) { handler_->SetPdfSavedClosureForTesting(closure); } + +void PrintPreviewUI::SendEnableManipulateSettingsForTest() { + handler_->SendEnableManipulateSettingsForTest(); +} + +void PrintPreviewUI::SendManipulateSettingsForTest( + const base::DictionaryValue& settings) { + handler_->SendManipulateSettingsForTest(settings); +} diff --git a/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.h index 360a1cd23ef..1a7a40a57ce 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.h +++ b/chromium/chrome/browser/ui/webui/print_preview/print_preview_ui.h @@ -23,6 +23,7 @@ struct PrintHostMsg_RequestPrintPreview_Params; struct PrintHostMsg_SetOptionsFromDocument_Params; namespace base { +class DictionaryValue; class FilePath; class RefCountedBytes; } @@ -115,13 +116,13 @@ class PrintPreviewUI : public ConstrainedWebDialogUI { // closed, which may occur for several reasons, e.g. tab closure or crash. void OnPrintPreviewDialogClosed(); + // Notifies the Web UI that the preview request was cancelled. + void OnPrintPreviewCancelled(); + // Notifies the Web UI that initiator is closed, so we can disable all the // controls that need the initiator for generating the preview data. void OnInitiatorClosed(); - // Notifies the Web UI renderer that file selection has been cancelled. - void OnFileSelectionCancelled(); - // Notifies the Web UI that the printer is unavailable or its settings are // invalid. void OnInvalidPrinterSettings(); @@ -135,9 +136,6 @@ class PrintPreviewUI : public ConstrainedWebDialogUI { // Closes the print preview dialog. void OnClosePrintPreviewDialog(); - // Reload the printers list. - void OnReloadPrintersList(); - // Notifies the WebUI to set print preset options from source PDF. void OnSetOptionsFromDocument( const PrintHostMsg_SetOptionsFromDocument_Params& params); @@ -158,6 +156,14 @@ class PrintPreviewUI : public ConstrainedWebDialogUI { // Passes |closure| to PrintPreviewHandler::SetPdfSavedClosureForTesting(). void SetPdfSavedClosureForTesting(const base::Closure& closure); + // Tell the handler to send the enable-manipulate-settings-for-test WebUI + // event. + void SendEnableManipulateSettingsForTest(); + + // Tell the handler to send the manipulate-settings-for-test WebUI event + // to set the print preview settings contained in |settings|. + void SendManipulateSettingsForTest(const base::DictionaryValue& settings); + private: FRIEND_TEST_ALL_PREFIXES(PrintPreviewDialogControllerUnitTest, TitleAfterReload); diff --git a/chromium/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc b/chromium/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc index 2286776946f..3b0de65648f 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc +++ b/chromium/chrome/browser/ui/webui/print_preview/printer_backend_proxy_chromeos.cc @@ -8,7 +8,6 @@ #include <vector> #include "base/bind_helpers.h" -#include "base/command_line.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -16,13 +15,11 @@ #include "base/values.h" #include "chrome/browser/chromeos/printing/cups_print_job_manager.h" #include "chrome/browser/chromeos/printing/cups_print_job_manager_factory.h" +#include "chrome/browser/chromeos/printing/cups_printers_manager.h" #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printers_manager.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/print_preview/printer_capabilities.h" -#include "chrome/common/chrome_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/debug_daemon_client.h" #include "chromeos/printing/ppd_provider.h" @@ -34,6 +31,8 @@ namespace printing { namespace { +using chromeos::CupsPrintersManager; + // Store the name used in CUPS, Printer#id in |printer_name|, the description // as the system_driverinfo option value, and the Printer#display_name in // the |printer_description| field. This will match how Mac OS X presents @@ -52,11 +51,10 @@ printing::PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) { return basic_info; } -void AddPrintersToList( - const std::vector<std::unique_ptr<chromeos::Printer>>& printers, - PrinterList* list) { +void AddPrintersToList(const std::vector<chromeos::Printer>& printers, + PrinterList* list) { for (const auto& printer : printers) { - list->push_back(ToBasicInfo(*printer)); + list->push_back(ToBasicInfo(printer)); } } @@ -74,7 +72,7 @@ void FetchCapabilities(std::unique_ptr<chromeos::Printer> printer, class PrinterBackendProxyChromeos : public PrinterBackendProxy { public: explicit PrinterBackendProxyChromeos(Profile* profile) - : prefs_(chromeos::PrintersManagerFactory::GetForBrowserContext(profile)), + : printers_manager_(CupsPrintersManager::Create(profile)), printer_configurer_(chromeos::PrinterConfigurer::Create(profile)), weak_factory_(this) { // Construct the CupsPrintJobManager to listen for printing events. @@ -94,17 +92,20 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy { }; void EnumeratePrinters(const EnumeratePrintersCallback& cb) override { - // PrintersManager is not thread safe and must be called from the UI + // SyncedPrintersManager is not thread safe and must be called from the UI // thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); PrinterList printer_list; - - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableNativeCups)) { - AddPrintersToList(prefs_->GetPrinters(), &printer_list); - AddPrintersToList(prefs_->GetRecommendedPrinters(), &printer_list); - } + AddPrintersToList( + printers_manager_->GetPrinters(CupsPrintersManager::kConfigured), + &printer_list); + AddPrintersToList( + printers_manager_->GetPrinters(CupsPrintersManager::kEnterprise), + &printer_list); + AddPrintersToList( + printers_manager_->GetPrinters(CupsPrintersManager::kAutomatic), + &printer_list); content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(cb, printer_list)); @@ -116,7 +117,7 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); std::unique_ptr<chromeos::Printer> printer = - prefs_->GetPrinter(printer_name); + printers_manager_->GetPrinter(printer_name); if (!printer) { // If the printer was removed, the lookup will fail. content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, @@ -129,7 +130,7 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy { printer->GetProtocol(), chromeos::Printer::kProtocolMax); - if (prefs_->IsConfigurationCurrent(*printer)) { + if (printers_manager_->IsPrinterInstalled(*printer)) { // Skip setup if the printer is already installed. HandlePrinterSetup(std::move(printer), cb, chromeos::kSuccess); return; @@ -152,7 +153,7 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy { case chromeos::PrinterSetupResult::kSuccess: VLOG(1) << "Printer setup successful for " << printer->id() << " fetching properties"; - prefs_->PrinterInstalled(*printer); + printers_manager_->PrinterInstalled(*printer); // fetch settings on the blocking pool and invoke callback. FetchCapabilities(std::move(printer), cb); @@ -183,8 +184,8 @@ class PrinterBackendProxyChromeos : public PrinterBackendProxy { cb.Run(nullptr); } - chromeos::PrintersManager* prefs_; - scoped_refptr<chromeos::printing::PpdProvider> ppd_provider_; + std::unique_ptr<CupsPrintersManager> printers_manager_; + scoped_refptr<chromeos::PpdProvider> ppd_provider_; std::unique_ptr<chromeos::PrinterConfigurer> printer_configurer_; base::WeakPtrFactory<PrinterBackendProxyChromeos> weak_factory_; diff --git a/chromium/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc b/chromium/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc index be776532888..f06e3f26e6f 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc +++ b/chromium/chrome/browser/ui/webui/print_preview/printer_capabilities_unittest.cc @@ -7,81 +7,51 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "base/task_runner_util.h" #include "base/test/values_test_util.h" -#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/ui/webui/print_preview/printer_capabilities.h" -#include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "printing/backend/test_print_backend.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" -namespace { - -void SettingsReply(std::unique_ptr<base::DictionaryValue>* out, - std::unique_ptr<base::DictionaryValue> reply) { - *out = std::move(reply); -} - -std::unique_ptr<base::DictionaryValue> GetSettingsSynchronous( - const std::string& printer_name, - const printing::PrinterBasicInfo& basic_info) { - std::unique_ptr<base::DictionaryValue> settings_dictionary; - - base::SequencedWorkerPool* worker_pool = - content::BrowserThread::GetBlockingPool(); - - base::PostTaskAndReplyWithResult( - worker_pool, FROM_HERE, base::Bind(&printing::GetSettingsOnBlockingPool, - printer_name, basic_info), - base::Bind(&SettingsReply, base::Unretained(&settings_dictionary))); - - worker_pool->FlushForTesting(); - base::RunLoop().RunUntilIdle(); - - return settings_dictionary; -} - -} // namespace +namespace printing { class PrinterCapabilitiesTest : public testing::Test { public: - PrinterCapabilitiesTest() : test_browser_threads_() {} + PrinterCapabilitiesTest() {} + ~PrinterCapabilitiesTest() override {} protected: void SetUp() override { - test_backend_ = new printing::TestPrintBackend(); - printing::PrintBackend::SetPrintBackendForTesting(test_backend_.get()); + test_backend_ = new TestPrintBackend(); + PrintBackend::SetPrintBackendForTesting(test_backend_.get()); } void TearDown() override { test_backend_ = nullptr; } - printing::TestPrintBackend* print_backend() { return test_backend_.get(); } + TestPrintBackend* print_backend() { return test_backend_.get(); } private: content::TestBrowserThreadBundle test_browser_threads_; - scoped_refptr<printing::TestPrintBackend> test_backend_; + scoped_refptr<TestPrintBackend> test_backend_; }; // Verify that we don't crash for a missing printer and a nullptr is never // returned. TEST_F(PrinterCapabilitiesTest, NonNullForMissingPrinter) { - printing::PrinterBasicInfo basic_info; + PrinterBasicInfo basic_info; std::string printer_name = "missing_printer"; std::unique_ptr<base::DictionaryValue> settings_dictionary = - GetSettingsSynchronous(printer_name, basic_info); + GetSettingsOnBlockingPool(printer_name, basic_info); ASSERT_TRUE(settings_dictionary); } TEST_F(PrinterCapabilitiesTest, ProvidedCapabilitiesUsed) { std::string printer_name = "test_printer"; - printing::PrinterBasicInfo basic_info; - std::unique_ptr<printing::PrinterSemanticCapsAndDefaults> caps = - base::MakeUnique<printing::PrinterSemanticCapsAndDefaults>(); + PrinterBasicInfo basic_info; + auto caps = base::MakeUnique<PrinterSemanticCapsAndDefaults>(); // set a capability caps->dpis = {gfx::Size(600, 600)}; @@ -89,7 +59,7 @@ TEST_F(PrinterCapabilitiesTest, ProvidedCapabilitiesUsed) { print_backend()->AddValidPrinter(printer_name, std::move(caps)); std::unique_ptr<base::DictionaryValue> settings_dictionary = - GetSettingsSynchronous(printer_name, basic_info); + GetSettingsOnBlockingPool(printer_name, basic_info); // verify settings were created ASSERT_TRUE(settings_dictionary); @@ -108,13 +78,13 @@ TEST_F(PrinterCapabilitiesTest, ProvidedCapabilitiesUsed) { // doesn't return capabilities. TEST_F(PrinterCapabilitiesTest, NullCapabilitiesExcluded) { std::string printer_name = "test_printer"; - printing::PrinterBasicInfo basic_info; + PrinterBasicInfo basic_info; // return false when attempting to retrieve capabilities print_backend()->AddValidPrinter(printer_name, nullptr); std::unique_ptr<base::DictionaryValue> settings_dictionary = - GetSettingsSynchronous(printer_name, basic_info); + GetSettingsOnBlockingPool(printer_name, basic_info); // verify settings were created ASSERT_TRUE(settings_dictionary); @@ -124,3 +94,5 @@ TEST_F(PrinterCapabilitiesTest, NullCapabilitiesExcluded) { ASSERT_TRUE(settings_dictionary->GetDictionary("capabilities", &caps_dict)); EXPECT_TRUE(caps_dict->empty()); } + +} // namespace printing diff --git a/chromium/chrome/browser/ui/webui/print_preview/printer_handler.h b/chromium/chrome/browser/ui/webui/print_preview/printer_handler.h index ccf12af9e2b..58b215f6008 100644 --- a/chromium/chrome/browser/ui/webui/print_preview/printer_handler.h +++ b/chromium/chrome/browser/ui/webui/print_preview/printer_handler.h @@ -35,8 +35,7 @@ class PrinterHandler { using GetPrintersCallback = base::Callback<void(const base::ListValue& printers, bool done)>; using GetCapabilityCallback = - base::Callback<void(const std::string& printer_id, - const base::DictionaryValue& capability)>; + base::Callback<void(const base::DictionaryValue& capability)>; using PrintCallback = base::Callback<void(bool success, const std::string& error)>; using GetPrinterInfoCallback = diff --git a/chromium/chrome/browser/ui/webui/profile_helper.cc b/chromium/chrome/browser/ui/webui/profile_helper.cc index 528292e1003..fb660613cde 100644 --- a/chromium/chrome/browser/ui/webui/profile_helper.cc +++ b/chromium/chrome/browser/ui/webui/profile_helper.cc @@ -14,6 +14,7 @@ #include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/profiles/profiles_state.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" @@ -27,7 +28,7 @@ namespace { void ShowUserManager(const ProfileManager::CreateCallback& callback) { if (!UserManager::IsShowing()) { - UserManager::Show(base::FilePath(), profiles::USER_MANAGER_NO_TUTORIAL, + UserManager::Show(base::FilePath(), profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); } @@ -72,7 +73,7 @@ void DeleteProfileCallback(std::unique_ptr<ScopedKeepAlive> keep_alive, void OpenNewWindowForProfile(Profile* profile) { if (profiles::IsProfileLocked(profile->GetPath())) { - if (signin::IsForceSigninEnabled()) { + if (signin_util::IsForceSigninEnabled()) { ShowUserManager(base::Bind(&ShowSigninDialog, profile->GetPath())); } else { ShowUserManager( diff --git a/chromium/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc b/chromium/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc index eef4638710b..be244e8172f 100644 --- a/chromium/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc +++ b/chromium/chrome/browser/ui/webui/set_as_default_browser_ui_browsertest_win.cc @@ -28,7 +28,6 @@ class SetAsDefaultBrowserUIBrowserTestWithFirstRun : public InProcessBrowserTest { public: void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kForceFirstRun); } @@ -40,8 +39,8 @@ class SetAsDefaultBrowserUIBrowserTestWithFirstRun IN_PROC_BROWSER_TEST_F(SetAsDefaultBrowserUIBrowserTestWithFirstRun, Test) { // Windows 8 only test case. - if (base::win::GetVersion() <= base::win::VERSION_WIN7 || - base::win::GetVersion() >= base::win::VERSION_WIN10) { + if (base::win::GetVersion() != base::win::VERSION_WIN8 && + base::win::GetVersion() != base::win::VERSION_WIN8_1) { return; } ASSERT_FALSE(IsBrowserVisible(browser())); diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.cc b/chromium/chrome/browser/ui/webui/settings/about_handler.cc index 05db7d110ad..f4e3bd21af2 100644 --- a/chromium/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/about_handler.cc @@ -27,12 +27,12 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/obsolete_system/obsolete_system.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/upgrade_detector.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/pref_names.h" @@ -46,7 +46,6 @@ #include "components/strings/grit/components_strings.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" @@ -149,7 +148,7 @@ bool CanChangeChannel(Profile* profile) { domain = email.substr(email.find('@') + 1); policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return domain == connector->GetEnterpriseDomain(); + return domain == connector->GetEnterpriseEnrollmentDomain(); } // On non-managed machines, only the local owner can change the channel. @@ -265,9 +264,14 @@ std::string UpdateStatusToString(VersionUpdater::Status status) { namespace settings { -AboutHandler::AboutHandler() : weak_factory_(this) {} +AboutHandler::AboutHandler() + : apply_changes_from_upgrade_observer_(false), weak_factory_(this) { + UpgradeDetector::GetInstance()->AddObserver(this); +} -AboutHandler::~AboutHandler() {} +AboutHandler::~AboutHandler() { + UpgradeDetector::GetInstance()->RemoveObserver(this); +} AboutHandler* AboutHandler::Create(content::WebUIDataSource* html_source, Profile* profile) { @@ -385,9 +389,8 @@ void AboutHandler::RegisterMessages() { } void AboutHandler::OnJavascriptAllowed() { + apply_changes_from_upgrade_observer_ = true; version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents())); - registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, - content::NotificationService::AllSources()); policy_registrar_.reset(new policy::PolicyChangeRegistrar( g_browser_process->policy_service(), policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()))); @@ -398,20 +401,17 @@ void AboutHandler::OnJavascriptAllowed() { } void AboutHandler::OnJavascriptDisallowed() { + apply_changes_from_upgrade_observer_ = false; version_updater_.reset(); policy_registrar_.reset(); - registrar_.Remove(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, - content::NotificationService::AllSources()); } -void AboutHandler::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type); - - // A version update is installed and ready to go. Refresh the UI so the - // correct state will be shown. - RequestUpdate(); +void AboutHandler::OnUpgradeRecommended() { + if (apply_changes_from_upgrade_observer_) { + // A version update is installed and ready to go. Refresh the UI so the + // correct state will be shown. + RequestUpdate(); + } } void AboutHandler::OnDeviceAutoUpdatePolicyChanged( diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.h b/chromium/chrome/browser/ui/webui/settings/about_handler.h index 5dc9d2331b3..3c6577519d1 100644 --- a/chromium/chrome/browser/ui/webui/settings/about_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/about_handler.h @@ -15,9 +15,8 @@ #include "build/build_config.h" #include "chrome/browser/ui/webui/help/version_updater.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "chrome/browser/upgrade_observer.h" #include "components/policy/core/common/policy_service.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_ui_message_handler.h" #if defined(OS_CHROMEOS) @@ -41,7 +40,7 @@ namespace settings { // WebUI message handler for the help page. class AboutHandler : public settings::SettingsPageUIHandler, - public content::NotificationObserver { + public UpgradeObserver { public: AboutHandler(); ~AboutHandler() override; @@ -54,10 +53,8 @@ class AboutHandler : public settings::SettingsPageUIHandler, void OnJavascriptAllowed() override; void OnJavascriptDisallowed() override; - // NotificationObserver implementation. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + // UpgradeObserver implementation. + void OnUpgradeRecommended() override; // Returns the browser version as a string. static base::string16 BuildBrowserVersionString(); @@ -151,12 +148,12 @@ class AboutHandler : public settings::SettingsPageUIHandler, // Specialized instance of the VersionUpdater used to update the browser. std::unique_ptr<VersionUpdater> version_updater_; - // Used to observe notifications. - content::NotificationRegistrar registrar_; - // Used to observe changes in the |kDeviceAutoUpdateDisabled| policy. std::unique_ptr<policy::PolicyChangeRegistrar> policy_registrar_; + // If true changes to UpgradeObserver are applied, if false they are ignored. + bool apply_changes_from_upgrade_observer_; + // Used for callbacks. base::WeakPtrFactory<AboutHandler> weak_factory_; diff --git a/chromium/chrome/browser/ui/webui/settings/certificates_handler.cc b/chromium/chrome/browser/ui/webui/settings/certificates_handler.cc index f3d3a22f896..70a3a822373 100644 --- a/chromium/chrome/browser/ui/webui/settings/certificates_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/certificates_handler.cc @@ -1133,8 +1133,7 @@ void CertificatesHandler::RejectCallbackWithImportError( std::unique_ptr<base::DictionaryValue> error_info(new base::DictionaryValue); error_info->SetString(kErrorTitle, title); error_info->SetString(kErrorDescription, error); - error_info->Set(kCertificateErrors, - base::WrapUnique(cert_error_list.release())); + error_info->Set(kCertificateErrors, std::move(cert_error_list)); RejectCallback(*error_info); } diff --git a/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc b/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc new file mode 100644 index 00000000000..25352bdd42e --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc @@ -0,0 +1,190 @@ +// Copyright (c) 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 "chrome/browser/ui/webui/settings/chrome_cleanup_handler.h" + +#include <string> + +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/metrics/histogram_macros.h" +#include "base/synchronization/lock.h" +#include "base/values.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" +#include "ui/base/l10n/l10n_util.h" + +using safe_browsing::ChromeCleanerController; + +namespace settings { + +namespace { + +// Returns a ListValue containing a copy of the file paths stored in |files|. +base::ListValue GetFilesAsListStorage(const std::set<base::FilePath>& files) { + base::ListValue value; + for (const base::FilePath& path : files) + value.AppendString(path.value()); + + return value; +} + +std::string IdleReasonToString( + ChromeCleanerController::IdleReason idle_reason) { + switch (idle_reason) { + case ChromeCleanerController::IdleReason::kInitial: + return "initial"; + case ChromeCleanerController::IdleReason::kScanningFoundNothing: + return "scanning_found_nothing"; + case ChromeCleanerController::IdleReason::kScanningFailed: + return "scanning_failed"; + case ChromeCleanerController::IdleReason::kConnectionLost: + return "connection_lost"; + case ChromeCleanerController::IdleReason::kUserDeclinedCleanup: + return "user_declined_cleanup"; + case ChromeCleanerController::IdleReason::kCleaningFailed: + return "cleaning_failed"; + case ChromeCleanerController::IdleReason::kCleaningSucceeded: + return "cleaning_succeeded"; + } + NOTREACHED(); + return ""; +} + +} // namespace + +ChromeCleanupHandler::ChromeCleanupHandler(Profile* profile) + : controller_(ChromeCleanerController::GetInstance()), profile_(profile) {} + +ChromeCleanupHandler::~ChromeCleanupHandler() { + controller_->RemoveObserver(this); +} + +void ChromeCleanupHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "dismissCleanupPage", + base::Bind(&ChromeCleanupHandler::HandleDismiss, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "registerChromeCleanerObserver", + base::Bind(&ChromeCleanupHandler::HandleRegisterChromeCleanerObserver, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "restartComputer", + base::Bind(&ChromeCleanupHandler::HandleRestartComputer, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "setLogsUploadPermission", + base::Bind(&ChromeCleanupHandler::HandleSetLogsUploadPermission, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "startCleanup", base::Bind(&ChromeCleanupHandler::HandleStartCleanup, + base::Unretained(this))); +} + +void ChromeCleanupHandler::OnJavascriptAllowed() { + controller_->AddObserver(this); +} + +void ChromeCleanupHandler::OnJavascriptDisallowed() { + controller_->RemoveObserver(this); +} + +void ChromeCleanupHandler::OnIdle( + ChromeCleanerController::IdleReason idle_reason) { + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-idle"), + base::Value(IdleReasonToString(idle_reason))); +} + +void ChromeCleanupHandler::OnScanning() { + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-scanning")); +} + +void ChromeCleanupHandler::OnInfected(const std::set<base::FilePath>& files) { + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-infected"), + GetFilesAsListStorage(files)); +} + +void ChromeCleanupHandler::OnCleaning(const std::set<base::FilePath>& files) { + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-cleaning"), + GetFilesAsListStorage(files)); +} + +void ChromeCleanupHandler::OnRebootRequired() { + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-reboot-required")); +} + +void ChromeCleanupHandler::OnLogsEnabledChanged(bool logs_enabled) { + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-upload-permission-change"), + base::Value(logs_enabled)); +} + +void ChromeCleanupHandler::HandleDismiss(const base::ListValue* args) { + DCHECK_EQ(0U, args->GetSize()); + + controller_->RemoveObserver(this); + controller_->ResetIdleState(); + + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-dismiss")); +} + +void ChromeCleanupHandler::HandleRegisterChromeCleanerObserver( + const base::ListValue* args) { + DCHECK_EQ(0U, args->GetSize()); + // The Polymer element should never be attached if the feature is + // disabled. + DCHECK( + base::FeatureList::IsEnabled(safe_browsing::kInBrowserCleanerUIFeature)); + + UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.CleanupCard", true); + AllowJavascript(); + + // Send the current logs upload state. + OnLogsEnabledChanged(controller_->logs_enabled()); +} + +void ChromeCleanupHandler::HandleRestartComputer(const base::ListValue* args) { + DCHECK_EQ(0U, args->GetSize()); + + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value("chrome-cleanup-on-dismiss")); + + controller_->Reboot(); +} + +void ChromeCleanupHandler::HandleSetLogsUploadPermission( + const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + bool allow_logs_upload = false; + args->GetBoolean(0, &allow_logs_upload); + + controller_->SetLogsEnabled(allow_logs_upload); +} + +void ChromeCleanupHandler::HandleStartCleanup(const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + bool allow_logs_upload = false; + args->GetBoolean(0, &allow_logs_upload); + + // The state is propagated to all open tabs and should be consistent. + DCHECK_EQ(controller_->logs_enabled(), allow_logs_upload); + + safe_browsing::RecordCleanupStartedHistogram( + safe_browsing::CLEANUP_STARTED_FROM_PROMPT_IN_SETTINGS); + controller_->ReplyWithUserResponse( + profile_, + allow_logs_upload + ? ChromeCleanerController::UserResponse::kAcceptedWithLogs + : ChromeCleanerController::UserResponse::kAcceptedWithoutLogs); +} + +} // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h b/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h new file mode 100644 index 00000000000..59f4493ceb6 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h @@ -0,0 +1,73 @@ +// 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROME_CLEANUP_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROME_CLEANUP_HANDLER_H_ + +#include <set> + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + +class Profile; + +namespace settings { + +// Chrome Cleanup settings page UI handler. +class ChromeCleanupHandler + : public SettingsPageUIHandler, + public safe_browsing::ChromeCleanerController::Observer { + public: + explicit ChromeCleanupHandler(Profile* profile); + ~ChromeCleanupHandler() override; + + // SettingsPageUIHandler implementation. + void RegisterMessages() override; + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; + + // ChromeCleanerController::Observer implementation. + void OnIdle( + safe_browsing::ChromeCleanerController::IdleReason idle_reason) override; + void OnScanning() override; + void OnInfected(const std::set<base::FilePath>& files) override; + void OnCleaning(const std::set<base::FilePath>& files) override; + void OnRebootRequired() override; + void OnLogsEnabledChanged(bool logs_enabled) override; + + private: + // Callback for the "dismissCleanupPage" message to hide the Cleanup page + // from the settings. + void HandleDismiss(const base::ListValue* args); + + // Callback for the "registerChromeCleanerObserver" message. This registers + // this object as an observer of the Chrome Cleanup global state and + // and retrieves the current cleanup state. + void HandleRegisterChromeCleanerObserver(const base::ListValue* args); + + // Callback for the "restartComputer" message to finalize the cleanup with a + // system restart. + void HandleRestartComputer(const base::ListValue* args); + + // Callback for the "setLogsUploadPermission" message to keep track of + // whether the user opted-out of logs upload or not. + void HandleSetLogsUploadPermission(const base::ListValue* args); + + // Callback for the "startCleanup" message to start removing unwanted + // software from the user's computer. + void HandleStartCleanup(const base::ListValue* args); + + // Raw pointer to a singleton. Must outlive this object. + safe_browsing::ChromeCleanerController* controller_; + + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(ChromeCleanupHandler); +}; + +} // namespace settings + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROME_CLEANUP_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc index 51e85cb3f92..fccd102c341 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc @@ -71,9 +71,12 @@ AndroidAppsHandler::BuildAndroidAppsInfo() { std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue); info->SetBoolean("playStoreEnabled", arc::IsArcPlayStoreEnabledForProfile(profile_)); + const ArcAppListPrefs* arc_apps_pref = ArcAppListPrefs::Get(profile_); + // TODO(khmel): Inverstigate why in some browser tests + // playStoreEnabled is true but arc_apps_pref is not set. info->SetBoolean( "settingsAppAvailable", - ArcAppListPrefs::Get(profile_)->IsRegistered(arc::kSettingsAppId)); + arc_apps_pref && arc_apps_pref->IsRegistered(arc::kSettingsAppId)); return info; } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc index 378b08c4b00..4c75079683d 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc @@ -80,8 +80,7 @@ const char kProfileDownloadReason[] = "Preferences"; } // namespace ChangePictureHandler::ChangePictureHandler() - : previous_image_url_(url::kAboutBlankURL), - previous_image_index_(user_manager::User::USER_IMAGE_INVALID), + : previous_image_index_(user_manager::User::USER_IMAGE_INVALID), user_manager_observer_(this), camera_observer_(this) { ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); @@ -114,6 +113,10 @@ void ChangePictureHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "selectImage", base::Bind(&ChangePictureHandler::HandleSelectImage, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "requestSelectedImage", + base::Bind(&ChangePictureHandler::HandleRequestSelectedImage, + base::Unretained(this))); } void ChangePictureHandler::OnJavascriptAllowed() { @@ -127,23 +130,12 @@ void ChangePictureHandler::OnJavascriptDisallowed() { } void ChangePictureHandler::SendDefaultImages() { - base::ListValue image_urls; - for (int i = default_user_image::kFirstDefaultImageIndex; - i < default_user_image::kDefaultImagesCount; ++i) { - std::unique_ptr<base::DictionaryValue> image_data( - new base::DictionaryValue); - image_data->SetString("url", default_user_image::GetDefaultImageUrl(i)); - image_data->SetString("author", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageAuthorIDs[i])); - image_data->SetString("website", - l10n_util::GetStringUTF16( - default_user_image::kDefaultImageWebsiteIDs[i])); - image_data->SetString("title", - default_user_image::GetDefaultImageDescription(i)); - image_urls.Append(std::move(image_data)); - } - FireWebUIListener("default-images-changed", image_urls); + base::DictionaryValue result; + result.SetInteger("first", default_user_image::GetFirstDefaultImage()); + std::unique_ptr<base::ListValue> default_images = + default_user_image::GetAsDictionary(true /* all */); + result.Set("images", std::move(default_images)); + FireWebUIListener("default-images-changed", result); } void ChangePictureHandler::HandleChooseFile(const base::ListValue* args) { @@ -214,7 +206,7 @@ void ChangePictureHandler::SendSelectedImage() { case user_manager::User::USER_IMAGE_EXTERNAL: { // User has image from camera/file, record it and add to the image list. previous_image_ = user->GetImage(); - SendOldImage(webui::GetBitmapDataUrl(*previous_image_.bitmap())); + SendOldImage(webui::GetBitmapDataUrl(*previous_image_.bitmap()), -1); break; } case user_manager::User::USER_IMAGE_PROFILE: { @@ -223,10 +215,7 @@ void ChangePictureHandler::SendSelectedImage() { break; } default: { - DCHECK(previous_image_index_ >= 0 && - previous_image_index_ < default_user_image::kDefaultImagesCount); - if (previous_image_index_ >= - default_user_image::kFirstDefaultImageIndex) { + if (default_user_image::IsInCurrentImageSet(previous_image_index_)) { // User has image from the current set of default images. base::Value image_url( default_user_image::GetDefaultImageUrl(previous_image_index_)); @@ -234,8 +223,10 @@ void ChangePictureHandler::SendSelectedImage() { } else { // User has an old default image, so present it in the same manner as a // previous image from file. + previous_image_ = user->GetImage(); SendOldImage( - default_user_image::GetDefaultImageUrl(previous_image_index_)); + default_user_image::GetDefaultImageUrl(previous_image_index_), + previous_image_index_); } } } @@ -254,16 +245,18 @@ void ChangePictureHandler::UpdateProfileImage() { // If we have a downloaded profile image and haven't sent it in // |SendSelectedImage|, send it now (without selecting). if (previous_image_index_ != user_manager::User::USER_IMAGE_PROFILE && - !user_image_manager->DownloadedProfileImage().isNull()) + !user_image_manager->DownloadedProfileImage().isNull()) { SendProfileImage(user_image_manager->DownloadedProfileImage(), false); - + } user_image_manager->DownloadProfileImage(kProfileDownloadReason); } -void ChangePictureHandler::SendOldImage(const std::string& image_url) { - previous_image_url_ = image_url; - base::Value url(image_url); - FireWebUIListener("old-image-changed", url); +void ChangePictureHandler::SendOldImage(const std::string& image_url, + int image_index) { + base::DictionaryValue result; + result.SetString("url", image_url); + result.SetInteger("index", image_index); + FireWebUIListener("old-image-changed", result); } void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { @@ -279,7 +272,6 @@ void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { UserImageManager* user_image_manager = ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId()); - int image_index = user_manager::User::USER_IMAGE_INVALID; bool waiting_for_camera_photo = false; if (image_type == "old") { @@ -294,8 +286,11 @@ void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { default_user_image::kHistogramImageOld, default_user_image::kHistogramImagesCount); VLOG(1) << "Selected old user image"; - } else if (image_type == "default" && - default_user_image::IsDefaultImageUrl(image_url, &image_index)) { + } else if (image_type == "default") { + int image_index = user_manager::User::USER_IMAGE_INVALID; + if (!default_user_image::IsDefaultImageUrl(image_url, &image_index)) + LOG(FATAL) << "Invalid image_url for default image type: " << image_url; + // One of the default user images. user_image_manager->SaveUserDefaultImageIndex(image_index); @@ -336,6 +331,11 @@ void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { ImageDecoder::Cancel(this); } +void ChangePictureHandler::HandleRequestSelectedImage( + const base::ListValue* args) { + SendSelectedImage(); +} + void ChangePictureHandler::FileSelected(const base::FilePath& path, int index, void* params) { diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h index a213282241e..77586cf2e67 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h @@ -60,8 +60,11 @@ class ChangePictureHandler : public ::settings::SettingsPageUIHandler, // if any, on the page. Shouldn't be called before |SendProfileImage|. void UpdateProfileImage(); - // Sends previous user image to the page. - void SendOldImage(const std::string& image_url); + // Sends the previous user image to the page. Also sends |image_index| which + // is either the index of the previous user image (if it was from an older + // default image set) or -1 otherwise. This allows the WebUI to show credits + // for older default images. + void SendOldImage(const std::string& image_url, int image_index); // Starts camera presence check. void CheckCameraPresence(); @@ -87,6 +90,9 @@ class ChangePictureHandler : public ::settings::SettingsPageUIHandler, // Selects one of the available images as user's. void HandleSelectImage(const base::ListValue* args); + // Requests the currently selected image. + void HandleRequestSelectedImage(const base::ListValue* args); + // SelectFileDialog::Delegate implementation. void FileSelected(const base::FilePath& path, int index, @@ -115,7 +121,6 @@ class ChangePictureHandler : public ::settings::SettingsPageUIHandler, // Previous user image from camera/file and its data URL. gfx::ImageSkia previous_image_; - std::string previous_image_url_; // Index of the previous user image. int previous_image_index_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc index e5d02eb7315..9ec43165c6a 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc @@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/files/file_util.h" #include "base/json/json_string_value_serializer.h" +#include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/path_service.h" @@ -17,10 +18,12 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/printing/cups_printers_manager.h" #include "chrome/browser/chromeos/printing/ppd_provider_factory.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printer_discoverer.h" -#include "chrome/browser/chromeos/printing/printers_manager_factory.h" +#include "chrome/browser/chromeos/printing/printer_event_tracker.h" +#include "chrome/browser/chromeos/printing/printer_event_tracker_factory.h" +#include "chrome/browser/chromeos/printing/printer_info.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" @@ -45,6 +48,14 @@ namespace settings { namespace { +constexpr char kIppScheme[] = "ipp"; +constexpr char kIppsScheme[] = "ipps"; + +constexpr int kIppPort = 631; +// IPPS commonly uses the HTTPS port despite the spec saying it should use the +// IPP port. +constexpr int kIppsPort = 443; + // These values are written to logs. New enum values can be added, but existing // enums must never be renumbered or deleted and reused. enum PpdSourceForHistogram { kUser = 0, kScs = 1, kPpdSourceMax }; @@ -58,14 +69,39 @@ void OnRemovedPrinter(const Printer::PrinterProtocol& protocol, bool success) { Printer::PrinterProtocol::kProtocolMax); } -std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) { +// Create an empty CupsPrinterInfo dictionary value. It should be consistent +// with the fields in js side. See cups_printers_browser_proxy.js for the +// definition of CupsPrinterInfo. +std::unique_ptr<base::DictionaryValue> CreateEmptyPrinterInfo() { std::unique_ptr<base::DictionaryValue> printer_info = base::MakeUnique<base::DictionaryValue>(); + printer_info->SetString("ppdManufacturer", ""); + printer_info->SetString("ppdModel", ""); + printer_info->SetString("printerAddress", ""); + printer_info->SetBoolean("printerAutoconf", false); + printer_info->SetString("printerDescription", ""); + printer_info->SetString("printerId", ""); + printer_info->SetString("printerManufacturer", ""); + printer_info->SetString("printerModel", ""); + printer_info->SetString("printerMakeAndModel", ""); + printer_info->SetString("printerName", ""); + printer_info->SetString("printerPPDPath", ""); + printer_info->SetString("printerProtocol", "ipp"); + printer_info->SetString("printerQueue", ""); + printer_info->SetString("printerStatus", ""); + return printer_info; +} + +// Returns a JSON representation of |printer| as a CupsPrinterInfo. +std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) { + std::unique_ptr<base::DictionaryValue> printer_info = + CreateEmptyPrinterInfo(); printer_info->SetString("printerId", printer.id()); printer_info->SetString("printerName", printer.display_name()); printer_info->SetString("printerDescription", printer.description()); printer_info->SetString("printerManufacturer", printer.manufacturer()); printer_info->SetString("printerModel", printer.model()); + printer_info->SetString("printerMakeAndModel", printer.make_and_model()); // Get protocol, ip address and queue from the printer's URI. const std::string printer_uri = printer.uri(); url::Parsed parsed; @@ -98,15 +134,31 @@ std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) { return printer_info; } +// Extracts a sanitized value of printerQueue from |printer_dict|. Returns an +// empty string if the value was not present in the dictionary. +std::string GetPrinterQueue(const base::DictionaryValue& printer_dict) { + std::string queue; + if (!printer_dict.GetString("printerQueue", &queue)) { + return queue; + } + + if (!queue.empty() && queue[0] == '/') { + // Strip the leading backslash. It is expected that this results in an + // empty string if the input is just a backslash. + queue = queue.substr(1); + } + + return queue; +} + } // namespace CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui) - : printer_discoverer_(nullptr), - profile_(Profile::FromWebUI(webui)), - weak_factory_(this) { - ppd_provider_ = printing::CreateProvider(profile_); - printer_configurer_ = chromeos::PrinterConfigurer::Create(profile_); -} + : profile_(Profile::FromWebUI(webui)), + ppd_provider_(CreatePpdProvider(profile_)), + printer_configurer_(PrinterConfigurer::Create(profile_)), + printers_manager_(CupsPrintersManager::Create(profile_)), + weak_factory_(this) {} CupsPrintersHandler::~CupsPrintersHandler() {} @@ -127,6 +179,9 @@ void CupsPrintersHandler::RegisterMessages() { "addCupsPrinter", base::Bind(&CupsPrintersHandler::HandleAddCupsPrinter, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "getPrinterInfo", base::Bind(&CupsPrintersHandler::HandleGetPrinterInfo, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "getCupsPrinterManufacturersList", base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterManufacturers, base::Unretained(this))); @@ -145,6 +200,14 @@ void CupsPrintersHandler::RegisterMessages() { "stopDiscoveringPrinters", base::Bind(&CupsPrintersHandler::HandleStopDiscovery, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "getPrinterPpdManufacturerAndModel", + base::Bind(&CupsPrintersHandler::HandleGetPrinterPpdManufacturerAndModel, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "addDiscoveredPrinter", + base::Bind(&CupsPrintersHandler::HandleAddDiscoveredPrinter, + base::Unretained(this))); } void CupsPrintersHandler::HandleGetCupsPrintersList( @@ -155,14 +218,12 @@ void CupsPrintersHandler::HandleGetCupsPrintersList( std::string callback_id; CHECK(args->GetString(0, &callback_id)); - std::vector<std::unique_ptr<Printer>> printers = - PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinters(); + std::vector<Printer> printers = + printers_manager_->GetPrinters(CupsPrintersManager::kConfigured); auto printers_list = base::MakeUnique<base::ListValue>(); - for (const std::unique_ptr<Printer>& printer : printers) { - std::unique_ptr<base::DictionaryValue> printer_info = - GetPrinterInfo(*printer.get()); - printers_list->Append(std::move(printer_info)); + for (const Printer& printer : printers) { + printers_list->Append(GetPrinterInfo(printer)); } auto response = base::MakeUnique<base::DictionaryValue>(); @@ -176,10 +237,14 @@ void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) { CHECK(args->GetString(0, &printer_id)); CHECK(args->GetString(1, &printer_name)); - std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); - printer->set_display_name(printer_name); - PrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter( - std::move(printer)); + Printer printer(printer_id); + printer.set_display_name(printer_name); + printers_manager_->UpdateConfiguredPrinter(printer); + + // TODO(xdai): Replace "on-add-cups-printer" callback with Promise resolve + // function. + FireWebUIListener("on-add-cups-printer", base::Value(true), + base::Value(printer_name)); } void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) { @@ -187,22 +252,113 @@ void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) { std::string printer_name; CHECK(args->GetString(0, &printer_id)); CHECK(args->GetString(1, &printer_name)); - PrintersManager* prefs = - PrintersManagerFactory::GetForBrowserContext(profile_); - auto printer = prefs->GetPrinter(printer_id); + auto printer = printers_manager_->GetPrinter(printer_id); if (!printer) return; + // Record removal before the printer is deleted. + PrinterEventTrackerFactory::GetForBrowserContext(profile_) + ->RecordPrinterRemoved(*printer); + Printer::PrinterProtocol protocol = printer->GetProtocol(); - prefs->RemovePrinter(printer_id); + // Printer is deleted here. Do not access after this line. + printers_manager_->RemoveConfiguredPrinter(printer_id); - chromeos::DebugDaemonClient* client = - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); + DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient(); client->CupsRemovePrinter(printer_name, base::Bind(&OnRemovedPrinter, protocol), base::Bind(&base::DoNothing)); } +void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) { + DCHECK(args); + std::string callback_id; + if (!args->GetString(0, &callback_id)) { + NOTREACHED() << "Expected request for a promise"; + return; + } + + const base::DictionaryValue* printer_dict = nullptr; + if (!args->GetDictionary(1, &printer_dict)) { + NOTREACHED() << "Dictionary missing"; + return; + } + + AllowJavascript(); + + std::string printer_address; + if (!printer_dict->GetString("printerAddress", &printer_address)) { + NOTREACHED() << "Address missing"; + return; + } + + if (printer_address.empty()) { + // Run the failure callback. + OnPrinterInfo(callback_id, false, "", "", "", false); + return; + } + + std::string printer_queue = GetPrinterQueue(*printer_dict); + + std::string printer_protocol; + if (!printer_dict->GetString("printerProtocol", &printer_protocol)) { + NOTREACHED() << "Protocol missing"; + return; + } + + // Parse url to separate address and port. ParseStandardURL expects a scheme, + // so add the printer_protocol. + std::string printer_uri = + printer_protocol + url::kStandardSchemeSeparator + printer_address; + const char* uri_ptr = printer_uri.c_str(); + url::Parsed parsed; + url::ParseStandardURL(uri_ptr, printer_uri.length(), &parsed); + base::StringPiece host(&printer_uri[parsed.host.begin], parsed.host.len); + + bool encrypted = printer_protocol != kIppScheme; + int port = ParsePort(uri_ptr, parsed.port); + // Port not specified. + if (port == url::SpecialPort::PORT_UNSPECIFIED || + port == url::SpecialPort::PORT_INVALID) { + if (printer_protocol == kIppScheme) { + port = kIppPort; + } else if (printer_protocol == kIppsScheme) { + port = kIppsPort; + } else { + // Port was not defined explicitly and scheme is not recognized. Cannot + // infer a port number. + NOTREACHED() << "Unrecognized protocol. Port was not set."; + } + } + + QueryIppPrinter(host.as_string(), port, printer_queue, encrypted, + base::Bind(&CupsPrintersHandler::OnPrinterInfo, + weak_factory_.GetWeakPtr(), callback_id)); +} + +void CupsPrintersHandler::OnPrinterInfo(const std::string& callback_id, + bool success, + const std::string& make, + const std::string& model, + const std::string& make_and_model, + bool ipp_everywhere) { + UMA_HISTOGRAM_BOOLEAN("Printing.CUPS.IppAttributesSuccess", success); + + if (!success) { + base::DictionaryValue reject; + reject.SetString("message", "Querying printer failed"); + RejectJavascriptCallback(base::Value(callback_id), reject); + return; + } + + base::DictionaryValue info; + info.SetString("manufacturer", make); + info.SetString("model", model); + info.SetString("makeAndModel", make_and_model); + info.SetBoolean("autoconf", ipp_everywhere); + ResolveJavascriptCallback(base::Value(callback_id), info); +} + void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) { AllowJavascript(); @@ -214,36 +370,52 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) { std::string printer_description; std::string printer_manufacturer; std::string printer_model; + std::string printer_make_and_model; std::string printer_address; std::string printer_protocol; - std::string printer_queue; - std::string printer_ppd_path; CHECK(printer_dict->GetString("printerId", &printer_id)); CHECK(printer_dict->GetString("printerName", &printer_name)); CHECK(printer_dict->GetString("printerDescription", &printer_description)); CHECK(printer_dict->GetString("printerManufacturer", &printer_manufacturer)); CHECK(printer_dict->GetString("printerModel", &printer_model)); + CHECK( + printer_dict->GetString("printerMakeAndModel", &printer_make_and_model)); CHECK(printer_dict->GetString("printerAddress", &printer_address)); CHECK(printer_dict->GetString("printerProtocol", &printer_protocol)); - // printerQueue might be null for a printer whose protocol is not 'LPD'. - printer_dict->GetString("printerQueue", &printer_queue); - // printerPPDPath might be null for an auto-discovered printer. - printer_dict->GetString("printerPPDPath", &printer_ppd_path); - std::string printer_uri = printer_protocol + "://" + printer_address; + std::string printer_queue = GetPrinterQueue(*printer_dict); + + std::string printer_uri = + printer_protocol + url::kStandardSchemeSeparator + printer_address; if (!printer_queue.empty()) { printer_uri += "/" + printer_queue; } - std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id); - printer->set_display_name(printer_name); - printer->set_description(printer_description); - printer->set_manufacturer(printer_manufacturer); - printer->set_model(printer_model); - printer->set_uri(printer_uri); + // Read PPD selection if it was used. + std::string ppd_manufacturer; + std::string ppd_model; + printer_dict->GetString("ppdManufacturer", &ppd_manufacturer); + printer_dict->GetString("ppdModel", &ppd_model); - // Verify a valid ppd path is present. - if (!printer_ppd_path.empty()) { + // Read user provided PPD if it was used. + std::string printer_ppd_path; + printer_dict->GetString("printerPPDPath", &printer_ppd_path); + + Printer printer(printer_id); + printer.set_display_name(printer_name); + printer.set_description(printer_description); + printer.set_manufacturer(printer_manufacturer); + printer.set_model(printer_model); + printer.set_make_and_model(printer_make_and_model); + printer.set_uri(printer_uri); + + bool autoconf = false; + printer_dict->GetBoolean("printerAutoconf", &autoconf); + + // Verify that the printer is autoconf or a valid ppd path is present. + if (autoconf) { + printer.mutable_ppd_reference()->autoconf = true; + } else if (!printer_ppd_path.empty()) { RecordPpdSource(kUser); GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path)); if (!tmp.is_valid()) { @@ -251,69 +423,104 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) { OnAddPrinterError(); return; } - printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec(); - } else if (!printer_manufacturer.empty() && !printer_model.empty()) { + printer.mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec(); + } else if (!ppd_manufacturer.empty() && !ppd_model.empty()) { RecordPpdSource(kScs); - // Using the manufacturer and model, get a ppd reference. - if (!ppd_provider_->GetPpdReference(printer_manufacturer, printer_model, - printer->mutable_ppd_reference())) { + // Pull out the ppd reference associated with the selected manufacturer and + // model. + bool found = false; + for (const auto& resolved_printer : resolved_printers_[ppd_manufacturer]) { + if (resolved_printer.first == ppd_model) { + *printer.mutable_ppd_reference() = resolved_printer.second; + found = true; + break; + } + } + if (!found) { LOG(ERROR) << "Failed to get ppd reference"; OnAddPrinterError(); return; } + + if (printer.make_and_model().empty()) { + // In lieu of more accurate information, populate the make and model + // fields with the PPD information. + printer.set_manufacturer(ppd_manufacturer); + printer.set_model(ppd_model); + // PPD Model names are actually make and model. + printer.set_make_and_model(ppd_model); + } + } else { + // TODO(crbug.com/738514): Support PPD guessing for non-autoconf printers. + // i.e. !autoconf && !manufacturer.empty() && !model.empty() + NOTREACHED() + << "A configuration option must have been selected to add a printer"; } - // Copy the printer for the configurer. Ownership needs to be transfered to - // the receiver of the callback. - const Printer printer_copy = *printer; printer_configurer_->SetUpPrinter( - printer_copy, - base::Bind(&CupsPrintersHandler::OnAddedPrinter, - weak_factory_.GetWeakPtr(), base::Passed(&printer))); + printer, base::Bind(&CupsPrintersHandler::OnAddedSpecifiedPrinter, + weak_factory_.GetWeakPtr(), printer)); } -void CupsPrintersHandler::OnAddedPrinter( - std::unique_ptr<Printer> printer, - chromeos::PrinterSetupResult result_code) { - std::string printer_name = printer->display_name(); +bool CupsPrintersHandler::OnAddedPrinterCommon(const Printer& printer, + PrinterSetupResult result_code) { UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code, - chromeos::PrinterSetupResult::kMaxValue); + PrinterSetupResult::kMaxValue); switch (result_code) { - case chromeos::PrinterSetupResult::kSuccess: { + case PrinterSetupResult::kSuccess: UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded", - printer->GetProtocol(), Printer::kProtocolMax); - auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_); - manager->PrinterInstalled(*printer); - manager->RegisterPrinter(std::move(printer)); - break; - } - case chromeos::PrinterSetupResult::kPpdNotFound: + printer.GetProtocol(), Printer::kProtocolMax); + printers_manager_->PrinterInstalled(printer); + printers_manager_->UpdateConfiguredPrinter(printer); + return true; + case PrinterSetupResult::kPpdNotFound: LOG(WARNING) << "Could not locate requested PPD"; break; - case chromeos::PrinterSetupResult::kPpdTooLarge: + case PrinterSetupResult::kPpdTooLarge: LOG(WARNING) << "PPD is too large"; break; - case chromeos::PrinterSetupResult::kPpdUnretrievable: + case PrinterSetupResult::kPpdUnretrievable: LOG(WARNING) << "Could not retrieve PPD from server"; break; - case chromeos::PrinterSetupResult::kInvalidPpd: + case PrinterSetupResult::kInvalidPpd: LOG(WARNING) << "Provided PPD is invalid."; break; - case chromeos::PrinterSetupResult::kPrinterUnreachable: + case PrinterSetupResult::kPrinterUnreachable: LOG(WARNING) << "Could not contact printer for configuration"; break; - case chromeos::PrinterSetupResult::kDbusError: - case chromeos::PrinterSetupResult::kFatalError: + case PrinterSetupResult::kDbusError: + case PrinterSetupResult::kFatalError: LOG(ERROR) << "Unrecoverable error. Reboot required."; break; - case chromeos::PrinterSetupResult::kMaxValue: + case PrinterSetupResult::kMaxValue: NOTREACHED() << "This is not an expected value"; break; } - CallJavascriptFunction( - "cr.webUIListenerCallback", base::Value("on-add-cups-printer"), - base::Value(result_code == chromeos::PrinterSetupResult::kSuccess), - base::Value(printer_name)); + // Log an event that tells us this printer setup failed, so we can get + // statistics about which printers are giving users difficulty. + printers_manager_->RecordSetupAbandoned(printer); + return false; +} + +void CupsPrintersHandler::OnAddedDiscoveredPrinter( + const Printer& printer, + PrinterSetupResult result_code) { + if (OnAddedPrinterCommon(printer, result_code)) { + FireWebUIListener("on-add-cups-printer", base::Value(true), + base::Value(printer.display_name())); + } else { + FireWebUIListener("on-manually-add-discovered-printer", + base::Value(result_code == PrinterSetupResult::kSuccess), + base::Value(printer.display_name())); + } +} + +void CupsPrintersHandler::OnAddedSpecifiedPrinter( + const Printer& printer, + PrinterSetupResult result_code) { + FireWebUIListener("on-add-cups-printer", + base::Value(OnAddedPrinterCommon(printer, result_code)), + base::Value(printer.display_name())); } void CupsPrintersHandler::OnAddPrinterError() { @@ -351,8 +558,9 @@ void CupsPrintersHandler::HandleGetCupsPrinterModels( } ppd_provider_->ResolvePrinters( - manufacturer, base::Bind(&CupsPrintersHandler::ResolvePrintersDone, - weak_factory_.GetWeakPtr(), js_callback)); + manufacturer, + base::Bind(&CupsPrintersHandler::ResolvePrintersDone, + weak_factory_.GetWeakPtr(), manufacturer, js_callback)); } void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) { @@ -377,30 +585,32 @@ void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) { void CupsPrintersHandler::ResolveManufacturersDone( const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, + PpdProvider::CallbackResultCode result_code, const std::vector<std::string>& manufacturers) { auto manufacturers_value = base::MakeUnique<base::ListValue>(); - if (result_code == chromeos::printing::PpdProvider::SUCCESS) { + if (result_code == PpdProvider::SUCCESS) { manufacturers_value->AppendStrings(manufacturers); } base::DictionaryValue response; - response.SetBoolean("success", - result_code == chromeos::printing::PpdProvider::SUCCESS); + response.SetBoolean("success", result_code == PpdProvider::SUCCESS); response.Set("manufacturers", std::move(manufacturers_value)); ResolveJavascriptCallback(base::Value(js_callback), response); } void CupsPrintersHandler::ResolvePrintersDone( + const std::string& manufacturer, const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, - const std::vector<std::string>& printers) { + PpdProvider::CallbackResultCode result_code, + const PpdProvider::ResolvedPrintersList& printers) { auto printers_value = base::MakeUnique<base::ListValue>(); - if (result_code == chromeos::printing::PpdProvider::SUCCESS) { - printers_value->AppendStrings(printers); + if (result_code == PpdProvider::SUCCESS) { + resolved_printers_[manufacturer] = printers; + for (const auto& printer : printers) { + printers_value->AppendString(printer.first); + } } base::DictionaryValue response; - response.SetBoolean("success", - result_code == chromeos::printing::PpdProvider::SUCCESS); + response.SetBoolean("success", result_code == PpdProvider::SUCCESS); response.Set("models", std::move(printers_value)); ResolveJavascriptCallback(base::Value(js_callback), response); } @@ -415,32 +625,122 @@ void CupsPrintersHandler::FileSelected(const base::FilePath& path, } void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) { - if (!printer_discoverer_.get()) { - printer_discoverer_ = - chromeos::PrinterDiscoverer::CreateForProfile(profile_); - } - - printer_discoverer_->AddObserver(this); + discovery_active_ = true; + OnPrintersChanged( + CupsPrintersManager::kAutomatic, + printers_manager_->GetPrinters(CupsPrintersManager::kAutomatic)); + OnPrintersChanged( + CupsPrintersManager::kDiscovered, + printers_manager_->GetPrinters(CupsPrintersManager::kDiscovered)); + UMA_HISTOGRAM_COUNTS_100( + "Printing.CUPS.PrintersDiscovered", + discovered_printers_.size() + automatic_printers_.size()); } void CupsPrintersHandler::HandleStopDiscovery(const base::ListValue* args) { - printer_discoverer_.reset(); + discovered_printers_.clear(); + automatic_printers_.clear(); + + // Free up memory while we're not discovering. + discovered_printers_.shrink_to_fit(); + automatic_printers_.shrink_to_fit(); + discovery_active_ = false; } -void CupsPrintersHandler::OnPrintersFound( +void CupsPrintersHandler::OnPrintersChanged( + CupsPrintersManager::PrinterClass printer_class, const std::vector<Printer>& printers) { + if (!discovery_active_) { + return; + } + switch (printer_class) { + case CupsPrintersManager::kAutomatic: + automatic_printers_ = printers; + break; + case CupsPrintersManager::kDiscovered: + discovered_printers_ = printers; + break; + default: + // It's a class we don't care about. + return; + } std::unique_ptr<base::ListValue> printers_list = base::MakeUnique<base::ListValue>(); - for (const auto& printer : printers) { + for (const Printer& printer : automatic_printers_) { + printers_list->Append(GetPrinterInfo(printer)); + } + for (const Printer& printer : discovered_printers_) { printers_list->Append(GetPrinterInfo(printer)); } FireWebUIListener("on-printer-discovered", *printers_list); + FireWebUIListener("on-printer-discovery-done"); } -void CupsPrintersHandler::OnDiscoveryInitialScanDone(int printer_count) { - UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", printer_count); - FireWebUIListener("on-printer-discovery-done"); +void CupsPrintersHandler::HandleAddDiscoveredPrinter( + const base::ListValue* args) { + AllowJavascript(); + CHECK_EQ(1U, args->GetSize()); + std::string printer_id; + CHECK(args->GetString(0, &printer_id)); + + auto printer = printers_manager_->GetPrinter(printer_id); + if (printer == nullptr) { + // Printer disappeared, so we don't have information about it anymore and + // can't really do much. Fail the add. + FireWebUIListener("on-add-cups-printer", base::Value(false), + base::Value(printer_id)); + } else if (printer->ppd_reference().autoconf || + !printer->ppd_reference().effective_make_and_model.empty() || + !printer->ppd_reference().user_supplied_ppd_url.empty()) { + // If we have something that looks like a ppd reference for this printer, + // try to configure it. + printer_configurer_->SetUpPrinter( + *printer, base::Bind(&CupsPrintersHandler::OnAddedDiscoveredPrinter, + weak_factory_.GetWeakPtr(), *printer)); + } else { + // We don't have enough from discovery to configure the printer. Fill in as + // much information as we can about the printer, and ask the user to supply + // the rest. + FireWebUIListener("on-manually-add-discovered-printer", + *GetPrinterInfo(*printer)); + } +} + +void CupsPrintersHandler::HandleGetPrinterPpdManufacturerAndModel( + const base::ListValue* args) { + AllowJavascript(); + CHECK_EQ(2U, args->GetSize()); + std::string callback_id; + CHECK(args->GetString(0, &callback_id)); + std::string printer_id; + CHECK(args->GetString(1, &printer_id)); + + auto printer = printers_manager_->GetPrinter(printer_id); + if (!printer) { + RejectJavascriptCallback(base::Value(callback_id), base::Value()); + return; + } + + ppd_provider_->ReverseLookup( + printer->ppd_reference().effective_make_and_model, + base::Bind(&CupsPrintersHandler::OnGetPrinterPpdManufacturerAndModel, + weak_factory_.GetWeakPtr(), callback_id)); +} + +void CupsPrintersHandler::OnGetPrinterPpdManufacturerAndModel( + const std::string& callback_id, + PpdProvider::CallbackResultCode result_code, + const std::string& manufacturer, + const std::string& model) { + if (result_code != PpdProvider::SUCCESS) { + RejectJavascriptCallback(base::Value(callback_id), base::Value()); + return; + } + base::DictionaryValue info; + info.SetString("ppdManufacturer", manufacturer); + info.SetString("ppdModel", model); + ResolveJavascriptCallback(base::Value(callback_id), info); } } // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h index 343daeab6df..8a92dd25f51 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h @@ -5,14 +5,16 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_ +#include <map> #include <memory> #include <string> #include <vector> #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/printing/cups_printers_manager.h" #include "chrome/browser/chromeos/printing/printer_configurer.h" -#include "chrome/browser/chromeos/printing/printer_discoverer.h" +#include "chrome/browser/chromeos/printing/printer_event_tracker.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" #include "chromeos/printing/ppd_provider.h" #include "chromeos/printing/printer_configuration.h" @@ -25,15 +27,15 @@ class ListValue; class Profile; namespace chromeos { -namespace printing { + class PpdProvider; -} + namespace settings { // Chrome OS CUPS printing settings page UI handler. class CupsPrintersHandler : public ::settings::SettingsPageUIHandler, public ui::SelectFileDialog::Listener, - public chromeos::PrinterDiscoverer::Observer { + public CupsPrintersManager::Observer { public: explicit CupsPrintersHandler(content::WebUI* webui); ~CupsPrintersHandler() override; @@ -49,9 +51,30 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler, void HandleUpdateCupsPrinter(const base::ListValue* args); void HandleRemoveCupsPrinter(const base::ListValue* args); + // For a CupsPrinterInfo in |args|, retrieves the relevant PrinterInfo object + // using an IPP call to the printer. + void HandleGetPrinterInfo(const base::ListValue* args); + + // Handles the callback for HandleGetPrinterInfo. |callback_id| is the + // identifier to resolve the correct Promise. |success| indicates if the query + // was successful. |make| is the detected printer manufacturer. |model| is the + // detected model. |make_and_model| is the unparsed printer-make-and-model + // string. |ipp_everywhere| indicates if configuration using the CUPS IPP + // Everywhere driver should be attempted. If |success| is false, the values of + // |make|, |model|, |make_and_model|, and |ipp_everywhere| are not specified. + void OnPrinterInfo(const std::string& callback_id, + bool success, + const std::string& make, + const std::string& model, + const std::string& make_and_model, + bool ipp_everywhere); + void HandleAddCupsPrinter(const base::ListValue* args); - void OnAddedPrinter(std::unique_ptr<Printer> printer, - chromeos::PrinterSetupResult result); + + // Handles the result of adding a printer which the user specified the + // location of (i.e. a printer that was not 'discovered' automatically). + void OnAddedSpecifiedPrinter(const Printer& printer, + PrinterSetupResult result); void OnAddPrinterError(); // Get a list of all manufacturers for which we have at least one model of @@ -69,43 +92,69 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler, void HandleSelectPPDFile(const base::ListValue* args); // PpdProvider callback handlers. - void ResolveManufacturersDone( - const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, - const std::vector<std::string>& available); - void ResolvePrintersDone( - const std::string& js_callback, - chromeos::printing::PpdProvider::CallbackResultCode result_code, - const std::vector<std::string>& available); + void ResolveManufacturersDone(const std::string& js_callback, + PpdProvider::CallbackResultCode result_code, + const std::vector<std::string>& available); + void ResolvePrintersDone(const std::string& manufacturer, + const std::string& js_callback, + PpdProvider::CallbackResultCode result_code, + const PpdProvider::ResolvedPrintersList& printers); + + void HandleStartDiscovery(const base::ListValue* args); + void HandleStopDiscovery(const base::ListValue* args); + + // Given a printer id, find the corresponding ppdManufacturer and ppdModel. + void HandleGetPrinterPpdManufacturerAndModel(const base::ListValue* args); + void OnGetPrinterPpdManufacturerAndModel( + const std::string& callback_id, + PpdProvider::CallbackResultCode result_code, + const std::string& manufacturer, + const std::string& model); + + // Attempt to add a discovered printer. + void HandleAddDiscoveredPrinter(const base::ListValue* args); + + // Post printer setup callback. + void OnAddedDiscoveredPrinter(const Printer& printer, + PrinterSetupResult result_code); + + // Code common between the discovered and manual add printer code paths. + // Returns true if the printer was added successfully, false otherwise. + bool OnAddedPrinterCommon(const Printer& printer, + PrinterSetupResult result_code); + + // CupsPrintersManager::Observer override: + void OnPrintersChanged(CupsPrintersManager::PrinterClass printer_class, + const std::vector<Printer>& printers) override; // ui::SelectFileDialog::Listener override: void FileSelected(const base::FilePath& path, int index, void* params) override; - void HandleStartDiscovery(const base::ListValue* args); - void HandleStopDiscovery(const base::ListValue* args); + Profile* profile_; - // chromeos::PrinterDiscoverer::Observer override: - void OnPrintersFound(const std::vector<Printer>& printers) override; - void OnDiscoveryInitialScanDone(int printer_count) override; + // Discovery support. discovery_active_ tracks whether or not the UI + // currently wants updates about printer availability. The two vectors track + // the most recent list of printers in each class. + bool discovery_active_ = false; + std::vector<Printer> discovered_printers_; + std::vector<Printer> automatic_printers_; - // Invokes debugd to add the printer to CUPS. If |ipp_everywhere| is true, - // automatic configuration will be attempted and |ppd_path| is ignored. - // |ppd_path| is the path to a Postscript Printer Description file that will - // be used to configure the printer capabilities. This file must be in - // Downloads or the PPD Cache. - void AddPrinterToCups(std::unique_ptr<Printer> printer, - const base::FilePath& ppd_path, - bool ipp_everywhere); + // These must be initialized before printers_manager_, as they are + // used by callbacks that may be issued immediately by printers_manager_. + // + // TODO(crbug/757887) - Remove this subtle initialization constraint. + scoped_refptr<PpdProvider> ppd_provider_; + std::unique_ptr<PrinterConfigurer> printer_configurer_; - std::unique_ptr<chromeos::PrinterDiscoverer> printer_discoverer_; - scoped_refptr<chromeos::printing::PpdProvider> ppd_provider_; - std::unique_ptr<chromeos::PrinterConfigurer> printer_configurer_; + // Cached list of {printer name, PpdReference} pairs for each manufacturer + // that has been resolved in the lifetime of this object. + std::map<std::string, PpdProvider::ResolvedPrintersList> resolved_printers_; - Profile* profile_; scoped_refptr<ui::SelectFileDialog> select_file_dialog_; std::string webui_callback_id_; + std::unique_ptr<CupsPrintersManager> printers_manager_; base::WeakPtrFactory<CupsPrintersHandler> weak_factory_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc index dbd70059915..1fea2b86685 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/values.h" -#include "chrome/browser/profiles/profile.h" #include "chromeos/chromeos_switches.h" #include "content/public/browser/web_ui.h" #include "ui/events/devices/input_device_manager.h" @@ -31,12 +30,17 @@ bool HasExternalKeyboard() { namespace chromeos { namespace settings { -KeyboardHandler::KeyboardHandler(content::WebUI* webui) - : profile_(Profile::FromWebUI(webui)), observer_(this) {} +const char KeyboardHandler::kShowKeysChangedName[] = "show-keys-changed"; -KeyboardHandler::~KeyboardHandler() { +void KeyboardHandler::TestAPI::Initialize() { + base::ListValue args; + handler_->HandleInitialize(&args); } +KeyboardHandler::KeyboardHandler() : observer_(this) {} + +KeyboardHandler::~KeyboardHandler() = default; + void KeyboardHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "initializeKeyboardSettings", @@ -71,11 +75,16 @@ void KeyboardHandler::HandleShowKeyboardShortcutsOverlay( } void KeyboardHandler::UpdateShowKeys() { - const base::Value has_caps_lock(HasExternalKeyboard()); + // kHasChromeOSKeyboard will be unset on Chromebooks that have standalone Caps + // Lock keys. + const base::Value has_caps_lock( + HasExternalKeyboard() || + !base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kHasChromeOSKeyboard)); const base::Value has_diamond_key( base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kHasChromeOSDiamondKey)); - FireWebUIListener("show-keys-changed", has_caps_lock, has_diamond_key); + FireWebUIListener(kShowKeysChangedName, has_caps_lock, has_diamond_key); } } // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h index 7ac9d447d48..d1afe730e6d 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h @@ -14,16 +14,10 @@ namespace base { class ListValue; } -namespace content { -class WebUI; -} - namespace ui { class InputDeviceManager; } -class Profile; - namespace chromeos { namespace settings { @@ -32,7 +26,24 @@ class KeyboardHandler : public ::settings::SettingsPageUIHandler, public ui::InputDeviceEventObserver { public: - explicit KeyboardHandler(content::WebUI* webui); + // Name of the message sent to WebUI when the keys that should be shown + // change. + static const char kShowKeysChangedName[]; + + // Class used by tests to interact with KeyboardHandler internals. + class TestAPI { + public: + explicit TestAPI(KeyboardHandler* handler) { handler_ = handler; } + + // Simulates a request from WebUI to initialize the page. + void Initialize(); + + private: + KeyboardHandler* handler_; // Not owned. + DISALLOW_COPY_AND_ASSIGN(TestAPI); + }; + + KeyboardHandler(); ~KeyboardHandler() override; // SettingsPageUIHandler implementation. @@ -54,8 +65,6 @@ class KeyboardHandler // system status. void UpdateShowKeys(); - Profile* profile_; // Weak pointer. - ScopedObserver<ui::InputDeviceManager, KeyboardHandler> observer_; DISALLOW_COPY_AND_ASSIGN(KeyboardHandler); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc new file mode 100644 index 00000000000..7d837497c67 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc @@ -0,0 +1,151 @@ +// 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 "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" + +#include <memory> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/observer_list.h" +#include "chromeos/chromeos_switches.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/devices/input_device.h" +#include "ui/events/test/device_data_manager_test_api.h" + +namespace chromeos { +namespace settings { + +namespace { + +class TestKeyboardHandler : public KeyboardHandler { + public: + // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it. + using KeyboardHandler::set_web_ui; +}; + +} // namespace + +class KeyboardHandlerTest : public testing::Test { + public: + KeyboardHandlerTest() : handler_test_api_(&handler_) { + handler_.set_web_ui(&web_ui_); + handler_.RegisterMessages(); + handler_.AllowJavascriptForTesting(); + + // Make sure that we start out without any keyboards reported. + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>()); + } + + protected: + // Updates out-params from the last message sent to WebUI about a change to + // which keys should be shown. False is returned if the message was invalid or + // not found. + bool GetLastShowKeysChangedMessage(bool* has_caps_lock_out, + bool* has_diamond_key_out) + WARN_UNUSED_RESULT { + for (auto it = web_ui_.call_data().rbegin(); + it != web_ui_.call_data().rend(); ++it) { + const content::TestWebUI::CallData* data = it->get(); + std::string name; + if (data->function_name() != "cr.webUIListenerCallback" || + !data->arg1()->GetAsString(&name) || + name != KeyboardHandler::kShowKeysChangedName) { + continue; + } + return data->arg2()->GetAsBoolean(has_caps_lock_out) && + data->arg3()->GetAsBoolean(has_diamond_key_out); + } + return false; + } + + // Returns true if the last keys-changed message reported that a Caps Lock key + // is present and false otherwise. A failure is added if a message wasn't + // found. + bool HasCapsLock() { + bool has_caps_lock = false, has_diamond_key = false; + if (!GetLastShowKeysChangedMessage(&has_caps_lock, &has_diamond_key)) { + ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; + return false; + } + return has_caps_lock; + } + + // Returns true if the last keys-changed message reported that a "diamond" key + // is present and false otherwise. A failure is added if a message wasn't + // found. + bool HasDiamondKey() { + bool has_caps_lock = false, has_diamond_key = false; + if (!GetLastShowKeysChangedMessage(&has_caps_lock, &has_diamond_key)) { + ADD_FAILURE() << "Didn't get " << KeyboardHandler::kShowKeysChangedName; + return false; + } + return has_diamond_key; + } + + ui::test::DeviceDataManagerTestAPI device_test_api_; + content::TestWebUI web_ui_; + TestKeyboardHandler handler_; + KeyboardHandler::TestAPI handler_test_api_; + + private: + DISALLOW_COPY_AND_ASSIGN(KeyboardHandlerTest); +}; + +TEST_F(KeyboardHandlerTest, DefaultKeys) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSKeyboard); + handler_test_api_.Initialize(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); +} + +TEST_F(KeyboardHandlerTest, NonChromeOSKeyboard) { + // If kHasChromeOSKeyboard isn't passed, we should assume there's a Caps Lock + // key. + handler_test_api_.Initialize(); + EXPECT_TRUE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); +} + +TEST_F(KeyboardHandlerTest, ExternalKeyboard) { + // An internal keyboard shouldn't change the defaults. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSKeyboard); + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ + {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"}}); + handler_test_api_.Initialize(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); + + // Simulate an external keyboard being connected. We should assume there's a + // Caps Lock key now. + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{ + {1, ui::INPUT_DEVICE_EXTERNAL, "external keyboard"}}); + device_test_api_.NotifyObserversKeyboardDeviceConfigurationChanged(); + EXPECT_TRUE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); + + // Disconnect the external keyboard and check that the key goes away. + device_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>()); + device_test_api_.NotifyObserversKeyboardDeviceConfigurationChanged(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_FALSE(HasDiamondKey()); +} + +TEST_F(KeyboardHandlerTest, DiamondKey) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSKeyboard); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + chromeos::switches::kHasChromeOSDiamondKey); + handler_test_api_.Initialize(); + EXPECT_FALSE(HasCapsLock()); + EXPECT_TRUE(HasDiamondKey()); +} + +} // namespace settings +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc index 535e9418eeb..5ff31cac218 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc @@ -7,13 +7,18 @@ #include <memory> #include <utility> -#include "ash/resources/grit/ash_resources.h" #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" #include "base/values.h" +#include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_service.h" #include "content/public/browser/web_ui.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/time_format.h" @@ -43,8 +48,41 @@ base::string16 GetBatteryTimeText(base::TimeDelta time_left) { } // namespace -PowerHandler::PowerHandler() - : power_observer_(this) { +const char PowerHandler::kPowerManagementSettingsChangedName[] = + "power-management-settings-changed"; +const char PowerHandler::kIdleBehaviorKey[] = "idleBehavior"; +const char PowerHandler::kIdleControlledKey[] = "idleControlled"; +const char PowerHandler::kLidClosedBehaviorKey[] = "lidClosedBehavior"; +const char PowerHandler::kLidClosedControlledKey[] = "lidClosedControlled"; +const char PowerHandler::kHasLidKey[] = "hasLid"; + +PowerHandler::TestAPI::TestAPI(PowerHandler* handler) : handler_(handler) {} + +PowerHandler::TestAPI::~TestAPI() = default; + +void PowerHandler::TestAPI::RequestPowerManagementSettings() { + base::ListValue args; + handler_->HandleRequestPowerManagementSettings(&args); +} + +void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior) { + base::ListValue args; + args.AppendInteger(static_cast<int>(behavior)); + handler_->HandleSetIdleBehavior(&args); +} + +void PowerHandler::TestAPI::SetLidClosedBehavior( + PowerPolicyController::Action behavior) { + base::ListValue args; + args.AppendInteger(behavior); + handler_->HandleSetLidClosedBehavior(&args); +} + +PowerHandler::PowerHandler(PrefService* prefs) + : prefs_(prefs), + power_status_observer_(this), + power_manager_client_observer_(this), + weak_ptr_factory_(this) { power_status_ = ash::PowerStatus::Get(); } @@ -57,14 +95,48 @@ void PowerHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "setPowerSource", base::Bind(&PowerHandler::HandleSetPowerSource, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "requestPowerManagementSettings", + base::Bind(&PowerHandler::HandleRequestPowerManagementSettings, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "setLidClosedBehavior", + base::Bind(&PowerHandler::HandleSetLidClosedBehavior, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "setIdleBehavior", + base::Bind(&PowerHandler::HandleSetIdleBehavior, base::Unretained(this))); } void PowerHandler::OnJavascriptAllowed() { - power_observer_.Add(power_status_); + power_status_observer_.Add(power_status_); + + PowerManagerClient* power_manager_client = + DBusThreadManager::Get()->GetPowerManagerClient(); + power_manager_client_observer_.Add(power_manager_client); + power_manager_client->GetSwitchStates(base::Bind( + &PowerHandler::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr())); + + // Observe power management prefs used in the UI. + base::Closure callback(base::Bind(&PowerHandler::SendPowerManagementSettings, + base::Unretained(this), false /* force */)); + pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); + pref_change_registrar_->Init(prefs_); + pref_change_registrar_->Add(prefs::kPowerAcIdleAction, callback); + pref_change_registrar_->Add(prefs::kPowerAcScreenDimDelayMs, callback); + pref_change_registrar_->Add(prefs::kPowerAcScreenOffDelayMs, callback); + pref_change_registrar_->Add(prefs::kPowerAcScreenLockDelayMs, callback); + pref_change_registrar_->Add(prefs::kPowerBatteryIdleAction, callback); + pref_change_registrar_->Add(prefs::kPowerBatteryScreenDimDelayMs, callback); + pref_change_registrar_->Add(prefs::kPowerBatteryScreenOffDelayMs, callback); + pref_change_registrar_->Add(prefs::kPowerBatteryScreenLockDelayMs, callback); + pref_change_registrar_->Add(prefs::kPowerLidClosedAction, callback); } void PowerHandler::OnJavascriptDisallowed() { - power_observer_.RemoveAll(); + power_status_observer_.RemoveAll(); + power_manager_client_observer_.RemoveAll(); + pref_change_registrar_.reset(); } void PowerHandler::OnPowerStatusChanged() { @@ -72,6 +144,17 @@ void PowerHandler::OnPowerStatusChanged() { SendPowerSources(); } +void PowerHandler::PowerManagerRestarted() { + DBusThreadManager::Get()->GetPowerManagerClient()->GetSwitchStates(base::Bind( + &PowerHandler::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr())); +} + +void PowerHandler::LidEventReceived(PowerManagerClient::LidState state, + const base::TimeTicks& timestamp) { + lid_state_ = state; + SendPowerManagementSettings(false /* force */); +} + void PowerHandler::HandleUpdatePowerStatus(const base::ListValue* args) { AllowJavascript(); power_status_->RequestStatusUpdate(); @@ -85,6 +168,81 @@ void PowerHandler::HandleSetPowerSource(const base::ListValue* args) { power_status_->SetPowerSource(id); } +void PowerHandler::HandleRequestPowerManagementSettings( + const base::ListValue* args) { + AllowJavascript(); + SendPowerManagementSettings(true /* force */); +} + +void PowerHandler::HandleSetIdleBehavior(const base::ListValue* args) { + AllowJavascript(); + + int value = 0; + CHECK(args->GetInteger(0, &value)); + switch (static_cast<IdleBehavior>(value)) { + case IdleBehavior::DISPLAY_OFF_SLEEP: + // The default behavior is to turn the display off and sleep. Clear the + // prefs so we use the default delays. + prefs_->ClearPref(prefs::kPowerAcIdleAction); + prefs_->ClearPref(prefs::kPowerAcScreenDimDelayMs); + prefs_->ClearPref(prefs::kPowerAcScreenOffDelayMs); + prefs_->ClearPref(prefs::kPowerAcScreenLockDelayMs); + prefs_->ClearPref(prefs::kPowerBatteryIdleAction); + prefs_->ClearPref(prefs::kPowerBatteryScreenDimDelayMs); + prefs_->ClearPref(prefs::kPowerBatteryScreenOffDelayMs); + prefs_->ClearPref(prefs::kPowerBatteryScreenLockDelayMs); + break; + case IdleBehavior::DISPLAY_OFF: + // Override idle actions to keep the system awake, but use the default + // screen delays. + prefs_->SetInteger(prefs::kPowerAcIdleAction, + PowerPolicyController::ACTION_DO_NOTHING); + prefs_->ClearPref(prefs::kPowerAcScreenDimDelayMs); + prefs_->ClearPref(prefs::kPowerAcScreenOffDelayMs); + prefs_->ClearPref(prefs::kPowerAcScreenLockDelayMs); + prefs_->SetInteger(prefs::kPowerBatteryIdleAction, + PowerPolicyController::ACTION_DO_NOTHING); + prefs_->ClearPref(prefs::kPowerBatteryScreenDimDelayMs); + prefs_->ClearPref(prefs::kPowerBatteryScreenOffDelayMs); + prefs_->ClearPref(prefs::kPowerBatteryScreenLockDelayMs); + break; + case IdleBehavior::DISPLAY_ON: + // Override idle actions and set screen delays to 0 in order to disable + // them (i.e. keep the screen on). + prefs_->SetInteger(prefs::kPowerAcIdleAction, + PowerPolicyController::ACTION_DO_NOTHING); + prefs_->SetInteger(prefs::kPowerAcScreenDimDelayMs, 0); + prefs_->SetInteger(prefs::kPowerAcScreenOffDelayMs, 0); + prefs_->SetInteger(prefs::kPowerAcScreenLockDelayMs, 0); + prefs_->SetInteger(prefs::kPowerBatteryIdleAction, + PowerPolicyController::ACTION_DO_NOTHING); + prefs_->SetInteger(prefs::kPowerBatteryScreenDimDelayMs, 0); + prefs_->SetInteger(prefs::kPowerBatteryScreenOffDelayMs, 0); + prefs_->SetInteger(prefs::kPowerBatteryScreenLockDelayMs, 0); + break; + default: + NOTREACHED() << "Invalid idle behavior " << value; + } +} + +void PowerHandler::HandleSetLidClosedBehavior(const base::ListValue* args) { + AllowJavascript(); + + int value = 0; + CHECK(args->GetInteger(0, &value)); + switch (static_cast<PowerPolicyController::Action>(value)) { + case PowerPolicyController::ACTION_SUSPEND: + prefs_->ClearPref(prefs::kPowerLidClosedAction); + break; + case PowerPolicyController::ACTION_DO_NOTHING: + prefs_->SetInteger(prefs::kPowerLidClosedAction, + PowerPolicyController::ACTION_DO_NOTHING); + break; + default: + NOTREACHED() << "Unsupported lid-closed behavior " << value; + } +} + void PowerHandler::SendBatteryStatus() { bool charging = power_status_->IsBatteryCharging(); bool calculating = power_status_->IsBatteryTimeBeingCalculated(); @@ -134,5 +292,71 @@ void PowerHandler::SendPowerSources() { base::Value(power_status_->IsUsbChargerConnected())); } +void PowerHandler::SendPowerManagementSettings(bool force) { + // Infer the idle behavior based on the idle action (determining whether we'll + // sleep eventually or not) and the AC screen-off delay. Policy can request + // more-nuanced combinations of AC/battery actions and delays, but we wouldn't + // be able to display something meaningful in the UI in those cases anyway. + const PowerPolicyController::Action idle_action = + static_cast<PowerPolicyController::Action>( + prefs_->GetInteger(prefs::kPowerAcIdleAction)); + IdleBehavior idle_behavior = IdleBehavior::OTHER; + if (idle_action == PowerPolicyController::ACTION_SUSPEND) { + idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP; + } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) { + idle_behavior = (prefs_->GetInteger(prefs::kPowerAcScreenOffDelayMs) > 0 + ? IdleBehavior::DISPLAY_OFF + : IdleBehavior::DISPLAY_ON); + } + + const bool idle_controlled = + prefs_->IsManagedPreference(prefs::kPowerAcIdleAction) || + prefs_->IsManagedPreference(prefs::kPowerAcScreenDimDelayMs) || + prefs_->IsManagedPreference(prefs::kPowerAcScreenOffDelayMs) || + prefs_->IsManagedPreference(prefs::kPowerAcScreenLockDelayMs) || + prefs_->IsManagedPreference(prefs::kPowerBatteryIdleAction) || + prefs_->IsManagedPreference(prefs::kPowerBatteryScreenDimDelayMs) || + prefs_->IsManagedPreference(prefs::kPowerBatteryScreenOffDelayMs) || + prefs_->IsManagedPreference(prefs::kPowerBatteryScreenLockDelayMs); + + const PowerPolicyController::Action lid_closed_behavior = + static_cast<PowerPolicyController::Action>( + prefs_->GetInteger(prefs::kPowerLidClosedAction)); + const bool lid_closed_controlled = + prefs_->IsManagedPreference(prefs::kPowerLidClosedAction); + const bool has_lid = lid_state_ != PowerManagerClient::LidState::NOT_PRESENT; + + // Don't notify the UI if nothing changed. + if (!force && idle_behavior == last_idle_behavior_ && + idle_controlled == last_idle_controlled_ && + lid_closed_behavior == last_lid_closed_behavior_ && + lid_closed_controlled == last_lid_closed_controlled_ && + has_lid == last_has_lid_) + return; + + base::DictionaryValue dict; + dict.SetInteger(kIdleBehaviorKey, static_cast<int>(idle_behavior)); + dict.SetBoolean(kIdleControlledKey, idle_controlled); + dict.SetInteger(kLidClosedBehaviorKey, lid_closed_behavior); + dict.SetBoolean(kLidClosedControlledKey, lid_closed_controlled); + dict.SetBoolean(kHasLidKey, has_lid); + CallJavascriptFunction("cr.webUIListenerCallback", + base::Value(kPowerManagementSettingsChangedName), + dict); + + last_idle_behavior_ = idle_behavior; + last_idle_controlled_ = idle_controlled; + last_lid_closed_behavior_ = lid_closed_behavior; + last_lid_closed_controlled_ = lid_closed_controlled; + last_has_lid_ = has_lid; +} + +void PowerHandler::OnGotSwitchStates( + PowerManagerClient::LidState lid_state, + PowerManagerClient::TabletMode tablet_mode) { + lid_state_ = lid_state; + SendPowerManagementSettings(false /* force */); +} + } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h index eaaf0cc9a58..68398175b0b 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h @@ -5,14 +5,23 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_ +#include <memory> + #include "ash/system/power/power_status.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" #include "base/strings/string16.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "chromeos/dbus/power_manager_client.h" +#include "chromeos/dbus/power_policy_controller.h" + +class PrefChangeRegistrar; +class PrefService; namespace base { class ListValue; +class TimeTicks; } namespace chromeos { @@ -20,9 +29,44 @@ namespace settings { // Chrome OS battery status and power settings handler. class PowerHandler : public ::settings::SettingsPageUIHandler, - public ash::PowerStatus::Observer { + public ash::PowerStatus::Observer, + public PowerManagerClient::Observer { public: - PowerHandler(); + // Idle behaviors presented in the UI. These are mapped to preferences by + // HandleSetIdleBehavior(). Values are shared with JS and exposed here for + // tests. + enum class IdleBehavior { + DISPLAY_OFF_SLEEP = 0, + DISPLAY_OFF = 1, + DISPLAY_ON = 2, + OTHER = 3, + }; + + // WebUI message name and dictionary keys. Shared with tests. + static const char kPowerManagementSettingsChangedName[]; + static const char kIdleBehaviorKey[]; + static const char kIdleControlledKey[]; + static const char kLidClosedBehaviorKey[]; + static const char kLidClosedControlledKey[]; + static const char kHasLidKey[]; + + // Class used by tests to interact with PowerHandler internals. + class TestAPI { + public: + explicit TestAPI(PowerHandler* handler); + ~TestAPI(); + + void RequestPowerManagementSettings(); + void SetIdleBehavior(IdleBehavior behavior); + void SetLidClosedBehavior(PowerPolicyController::Action behavior); + + private: + PowerHandler* handler_; // Not owned. + + DISALLOW_COPY_AND_ASSIGN(TestAPI); + }; + + explicit PowerHandler(PrefService* prefs); ~PowerHandler() override; // SettingsPageUIHandler implementation. @@ -33,6 +77,11 @@ class PowerHandler : public ::settings::SettingsPageUIHandler, // ash::PowerStatus::Observer implementation. void OnPowerStatusChanged() override; + // PowerManagerClient implementation. + void PowerManagerRestarted() override; + void LidEventReceived(PowerManagerClient::LidState state, + const base::TimeTicks& timestamp) override; + private: // Handler to request updating the power status. void HandleUpdatePowerStatus(const base::ListValue* args); @@ -40,15 +89,53 @@ class PowerHandler : public ::settings::SettingsPageUIHandler, // Handler to change the power source. void HandleSetPowerSource(const base::ListValue* args); + // Handler to request the current power management settings. Just calls + // SendPowerManagementSettings(). + void HandleRequestPowerManagementSettings(const base::ListValue* args); + + // Handlers to change the idle and lid-closed behaviors. + void HandleSetIdleBehavior(const base::ListValue* args); + void HandleSetLidClosedBehavior(const base::ListValue* args); + // Updates the UI with the current battery status. void SendBatteryStatus(); // Updates the UI with a list of available dual-role power sources. void SendPowerSources(); - ash::PowerStatus* power_status_; + // Updates the UI to display the current power management settings. If the + // settings didn't change since the previous call, nothing is sent unless + // |force| is true. + void SendPowerManagementSettings(bool force); + + // Callback used to receive switch states from PowerManagerClient. + void OnGotSwitchStates(PowerManagerClient::LidState lid_state, + PowerManagerClient::TabletMode tablet_mode); + + PrefService* prefs_; // Not owned. + ash::PowerStatus* power_status_; // Not owned. + + // Used to watch power management prefs for changes so the UI can be notified. + std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; + + ScopedObserver<ash::PowerStatus, PowerHandler> power_status_observer_; + ScopedObserver<PowerManagerClient, PowerHandler> + power_manager_client_observer_; + + // Last lid state received from powerd. + PowerManagerClient::LidState lid_state_ = PowerManagerClient::LidState::OPEN; + + // Last values sent by SendPowerManagementSettings(), cached here so + // SendPowerManagementSettings() can avoid spamming the UI after this class + // changes multiple prefs at once. + IdleBehavior last_idle_behavior_ = IdleBehavior::DISPLAY_OFF_SLEEP; + PowerPolicyController::Action last_lid_closed_behavior_ = + PowerPolicyController::ACTION_SUSPEND; + bool last_idle_controlled_ = false; + bool last_lid_closed_controlled_ = false; + bool last_has_lid_ = true; - ScopedObserver<ash::PowerStatus, PowerHandler> power_observer_; + base::WeakPtrFactory<PowerHandler> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(PowerHandler); }; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc new file mode 100644 index 00000000000..c5a0b4c189f --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_unittest.cc @@ -0,0 +1,311 @@ +// 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 "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h" + +#include <memory> + +#include "ash/system/power/power_status.h" +#include "base/json/json_writer.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/values.h" +#include "chrome/browser/chromeos/power/power_prefs.h" +#include "chrome/common/pref_names.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_power_manager_client.h" +#include "chromeos/dbus/power_policy_controller.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace settings { + +class TestPowerHandler : public PowerHandler { + public: + explicit TestPowerHandler(PrefService* prefs) : PowerHandler(prefs) {} + + // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it. + using PowerHandler::set_web_ui; +}; + +class PowerHandlerTest : public testing::Test { + public: + PowerHandlerTest() { + // This initializes chromeos::DBusThreadManager. + std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = + chromeos::DBusThreadManager::GetSetterForTesting(); + dbus_setter->SetPowerManagerClient( + base::MakeUnique<chromeos::FakePowerManagerClient>()); + power_manager_client_ = static_cast<chromeos::FakePowerManagerClient*>( + chromeos::DBusThreadManager::Get()->GetPowerManagerClient()); + ash::PowerStatus::Initialize(); + + chromeos::PowerPrefs::RegisterUserProfilePrefs(prefs_.registry()); + + handler_ = base::MakeUnique<TestPowerHandler>(&prefs_); + test_api_ = base::MakeUnique<PowerHandler::TestAPI>(handler_.get()); + handler_->set_web_ui(&web_ui_); + handler_->RegisterMessages(); + handler_->AllowJavascriptForTesting(); + base::RunLoop().RunUntilIdle(); + } + + ~PowerHandlerTest() override { + handler_.reset(); + ash::PowerStatus::Shutdown(); + chromeos::DBusThreadManager::Shutdown(); + } + + protected: + // Returns a JSON representation of the contents of the last message sent to + // WebUI about settings being changed. + std::string GetLastSettingsChangedMessage() WARN_UNUSED_RESULT { + for (auto it = web_ui_.call_data().rbegin(); + it != web_ui_.call_data().rend(); ++it) { + const content::TestWebUI::CallData* data = it->get(); + std::string name; + const base::DictionaryValue* dict = nullptr; + if (data->function_name() != "cr.webUIListenerCallback" || + !data->arg1()->GetAsString(&name) || + name != PowerHandler::kPowerManagementSettingsChangedName) { + continue; + } + if (!data->arg2()->GetAsDictionary(&dict)) { + ADD_FAILURE() << "Failed to get dict from " << name << " message"; + continue; + } + std::string out; + EXPECT_TRUE(base::JSONWriter::Write(*dict, &out)); + return out; + } + + ADD_FAILURE() << PowerHandler::kPowerManagementSettingsChangedName + << " message was not sent"; + return std::string(); + } + + // Returns a string for the given settings that can be compared against the + // output of GetLastSettingsChangedMessage(). + std::string CreateSettingsChangedString( + PowerHandler::IdleBehavior idle_behavior, + bool idle_controlled, + PowerPolicyController::Action lid_closed_behavior, + bool lid_closed_controlled, + bool has_lid) { + base::DictionaryValue dict; + dict.SetInteger(PowerHandler::kIdleBehaviorKey, + static_cast<int>(idle_behavior)); + dict.SetBoolean(PowerHandler::kIdleControlledKey, idle_controlled); + dict.SetInteger(PowerHandler::kLidClosedBehaviorKey, lid_closed_behavior); + dict.SetBoolean(PowerHandler::kLidClosedControlledKey, + lid_closed_controlled); + dict.SetBoolean(PowerHandler::kHasLidKey, has_lid); + + std::string out; + EXPECT_TRUE(base::JSONWriter::Write(dict, &out)); + return out; + } + + // Returns the user-set value of the integer pref identified by |name| or -1 + // if the pref is unset. + int GetIntPref(const std::string& name) { + const base::Value* value = prefs_.GetUserPref(name); + return value ? value->GetInt() : -1; + } + + base::test::ScopedTaskEnvironment scoped_task_environment_; + sync_preferences::TestingPrefServiceSyncable prefs_; + content::TestWebUI web_ui_; + + // Owned by chromeos::DBusThreadManager. + chromeos::FakePowerManagerClient* power_manager_client_; + + std::unique_ptr<TestPowerHandler> handler_; + std::unique_ptr<TestPowerHandler::TestAPI> test_api_; + + private: + DISALLOW_COPY_AND_ASSIGN(PowerHandlerTest); +}; + +// Verifies that settings are sent to WebUI when requested. +TEST_F(PowerHandlerTest, SendInitialSettings) { + test_api_->RequestPowerManagementSettings(); + EXPECT_EQ( + CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); +} + +// Verifies that WebUI receives updated settings when the lid state changes. +TEST_F(PowerHandlerTest, SendSettingsForLidStateChanges) { + power_manager_client_->SetLidState(PowerManagerClient::LidState::NOT_PRESENT, + base::TimeTicks()); + EXPECT_EQ( + CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, false /* has_lid */), + GetLastSettingsChangedMessage()); + + power_manager_client_->SetLidState(PowerManagerClient::LidState::OPEN, + base::TimeTicks()); + EXPECT_EQ( + CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); +} + +// Verifies that when various prefs are controlled, the corresponding settings +// are reported as controlled to WebUI. +TEST_F(PowerHandlerTest, SendSettingsForControlledPrefs) { + // Making an arbitrary delay pref managed should result in the idle setting + // being reported as controlled. + prefs_.SetManagedPref(prefs::kPowerAcScreenDimDelayMs, + base::MakeUnique<base::Value>(10000)); + EXPECT_EQ( + CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); + + // Ditto for making the lid action pref managed. + prefs_.SetManagedPref( + prefs::kPowerLidClosedAction, + base::MakeUnique<base::Value>(PowerPolicyController::ACTION_SUSPEND)); + EXPECT_EQ( + CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND, + true /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); +} + +// Verifies that idle-related prefs are distilled into the proper WebUI +// settings. +TEST_F(PowerHandlerTest, SendIdleSettingForPrefChanges) { + // Set a do-nothing idle action and a nonzero screen-off delay. + prefs_.SetUserPref( + prefs::kPowerAcIdleAction, + base::MakeUnique<base::Value>(PowerPolicyController::ACTION_DO_NOTHING)); + prefs_.SetUserPref(prefs::kPowerAcScreenOffDelayMs, + base::MakeUnique<base::Value>(10000)); + EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_OFF, + false /* idle_controlled */, + PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, + true /* has_lid */), + GetLastSettingsChangedMessage()); + + // Now set the delay to zero and check that the setting goes to "display on". + prefs_.SetUserPref(prefs::kPowerAcScreenOffDelayMs, + base::MakeUnique<base::Value>(0)); + EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_ON, + false /* idle_controlled */, + PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, + true /* has_lid */), + GetLastSettingsChangedMessage()); + + // Other idle actions should result in an "other" setting. + prefs_.SetUserPref(prefs::kPowerAcIdleAction, + base::MakeUnique<base::Value>( + PowerPolicyController::ACTION_STOP_SESSION)); + EXPECT_EQ(CreateSettingsChangedString( + PowerHandler::IdleBehavior::OTHER, false /* idle_controlled */, + PowerPolicyController::ACTION_SUSPEND, + false /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); +} + +// Verifies that the lid-closed pref's value is sent directly to WebUI. +TEST_F(PowerHandlerTest, SendLidSettingForPrefChanges) { + prefs_.SetUserPref( + prefs::kPowerLidClosedAction, + base::MakeUnique<base::Value>(PowerPolicyController::ACTION_SHUT_DOWN)); + EXPECT_EQ( + CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + false /* idle_controlled */, PowerPolicyController::ACTION_SHUT_DOWN, + false /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); + + prefs_.SetUserPref(prefs::kPowerLidClosedAction, + base::MakeUnique<base::Value>( + PowerPolicyController::ACTION_STOP_SESSION)); + EXPECT_EQ(CreateSettingsChangedString( + PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP, + false /* idle_controlled */, + PowerPolicyController::ACTION_STOP_SESSION, + false /* lid_closed_controlled */, true /* has_lid */), + GetLastSettingsChangedMessage()); +} + +// Verifies that requests from WebUI to update the idle behavior update prefs +// appropriately. +TEST_F(PowerHandlerTest, SetIdleBehavior) { + // Request the "Keep display on" setting and check that prefs are set + // appropriately. + test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON); + EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING, + GetIntPref(prefs::kPowerAcIdleAction)); + EXPECT_EQ(0, GetIntPref(prefs::kPowerAcScreenDimDelayMs)); + EXPECT_EQ(0, GetIntPref(prefs::kPowerAcScreenOffDelayMs)); + EXPECT_EQ(0, GetIntPref(prefs::kPowerAcScreenLockDelayMs)); + EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING, + GetIntPref(prefs::kPowerBatteryIdleAction)); + EXPECT_EQ(0, GetIntPref(prefs::kPowerBatteryScreenDimDelayMs)); + EXPECT_EQ(0, GetIntPref(prefs::kPowerBatteryScreenOffDelayMs)); + EXPECT_EQ(0, GetIntPref(prefs::kPowerBatteryScreenLockDelayMs)); + + // "Turn off display" should set the idle prefs but clear the screen + // delays. + test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF); + EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING, + GetIntPref(prefs::kPowerAcIdleAction)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcScreenDimDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcScreenOffDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcScreenLockDelayMs)); + EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING, + GetIntPref(prefs::kPowerBatteryIdleAction)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryScreenDimDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryScreenOffDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryScreenLockDelayMs)); + + // Now switch to the "Keep display on" setting (to set the prefs again) and + // check that the "Turn off display and sleep" setting clears all the prefs. + test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON); + test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcIdleAction)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcScreenDimDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcScreenOffDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerAcScreenLockDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryIdleAction)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryScreenDimDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryScreenOffDelayMs)); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerBatteryScreenLockDelayMs)); +} + +// Verifies that requests from WebUI to change the lid behavior update the pref. +TEST_F(PowerHandlerTest, SetLidBehavior) { + // The "do nothing" setting should update the pref. + test_api_->SetLidClosedBehavior(PowerPolicyController::ACTION_DO_NOTHING); + EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING, + GetIntPref(prefs::kPowerLidClosedAction)); + + // Selecting the "suspend" setting should just clear the pref. + test_api_->SetLidClosedBehavior(PowerPolicyController::ACTION_SUSPEND); + EXPECT_EQ(-1, GetIntPref(prefs::kPowerLidClosedAction)); +} + +} // namespace settings +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc index 5b59c57ccdb..b6ddf0a4ecf 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc @@ -122,7 +122,10 @@ void StorageHandler::HandleOpenDownloads( void StorageHandler::HandleOpenArcStorage( const base::ListValue* unused_args) { - arc::ArcStorageManager::Get()->OpenPrivateVolumeSettings(); + auto* arc_storage_manager = arc::ArcStorageManager::GetForBrowserContext( + Profile::FromWebUI(web_ui())); + if (arc_storage_manager) + arc_storage_manager->OpenPrivateVolumeSettings(); } void StorageHandler::HandleClearDriveCache( @@ -340,8 +343,13 @@ void StorageHandler::UpdateAndroidSize() { // Shows the item "Android apps and cache" and start calculating size. FireWebUIListener("storage-android-enabled-changed", base::Value(true)); - bool success = arc::ArcStorageManager::Get()->GetApplicationsSize(base::Bind( - &StorageHandler::OnGetAndroidSize, weak_ptr_factory_.GetWeakPtr())); + bool success = false; + auto* arc_storage_manager = + arc::ArcStorageManager::GetForBrowserContext(profile); + if (arc_storage_manager) { + success = arc_storage_manager->GetApplicationsSize(base::Bind( + &StorageHandler::OnGetAndroidSize, weak_ptr_factory_.GetWeakPtr())); + } if (!success) updating_android_size_ = false; } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc index 7f7ba9c3b47..0d356464b37 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc @@ -24,7 +24,7 @@ namespace { constexpr char kAppNameKey[] = "name"; constexpr char kAppIdKey[] = "value"; constexpr char kAppPreferredKey[] = "preferred"; -constexpr char kAppLockScreenSupportKey[] = "supportsLockScreen"; +constexpr char kAppLockScreenSupportKey[] = "lockScreenSupport"; } // namespace @@ -52,6 +52,10 @@ void StylusHandler::RegisterMessages() { base::Bind(&StylusHandler::SetPreferredNoteTakingApp, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "setPreferredNoteTakingAppEnabledOnLockScreen", + base::Bind(&StylusHandler::SetPreferredNoteTakingAppEnabledOnLockScreen, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "showPlayStoreApps", base::Bind(&StylusHandler::ShowPlayStoreApps, base::Unretained(this))); } @@ -60,6 +64,11 @@ void StylusHandler::OnAvailableNoteTakingAppsUpdated() { UpdateNoteTakingApps(); } +void StylusHandler::OnPreferredNoteTakingAppUpdated(Profile* profile) { + if (Profile::FromWebUI(web_ui()) == profile) + UpdateNoteTakingApps(); +} + void StylusHandler::OnDeviceListsComplete() { SendHasStylus(); } @@ -82,9 +91,8 @@ void StylusHandler::UpdateNoteTakingApps() { dict->SetString(kAppNameKey, info.name); dict->SetString(kAppIdKey, info.app_id); dict->SetBoolean(kAppPreferredKey, info.preferred); - dict->SetBoolean(kAppLockScreenSupportKey, - info.lock_screen_support != - NoteTakingLockScreenSupport::kNotSupported); + dict->SetInteger(kAppLockScreenSupportKey, + static_cast<int>(info.lock_screen_support)); apps_list.Append(std::move(dict)); note_taking_app_ids_.insert(info.app_id); @@ -115,6 +123,15 @@ void StylusHandler::SetPreferredNoteTakingApp(const base::ListValue* args) { app_id); } +void StylusHandler::SetPreferredNoteTakingAppEnabledOnLockScreen( + const base::ListValue* args) { + bool enabled = false; + CHECK(args->GetBoolean(0, &enabled)); + + NoteTakingHelper::Get()->SetPreferredAppEnabledOnLockScreen( + Profile::FromWebUI(web_ui()), enabled); +} + void StylusHandler::HandleInitialize(const base::ListValue* args) { if (ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete()) SendHasStylus(); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h index b8cd2567f99..ac52790f5ad 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STYLUS_HANDLER_H_ #include <set> +#include <string> #include "base/macros.h" #include "chrome/browser/chromeos/note_taking_helper.h" @@ -34,6 +35,7 @@ class StylusHandler : public ::settings::SettingsPageUIHandler, // chromeos::NoteTakingHelper::Observer implementation. void OnAvailableNoteTakingAppsUpdated() override; + void OnPreferredNoteTakingAppUpdated(Profile* profile) override; // ui::InputDeviceObserver: void OnDeviceListsComplete() override; @@ -42,6 +44,8 @@ class StylusHandler : public ::settings::SettingsPageUIHandler, void UpdateNoteTakingApps(); void RequestApps(const base::ListValue* unused_args); void SetPreferredNoteTakingApp(const base::ListValue* args); + void SetPreferredNoteTakingAppEnabledOnLockScreen( + const base::ListValue* args); // Called by JS to request a |SendHasStylus| call. void HandleInitialize(const base::ListValue* args); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc index 299d20bd1b7..e761beaf2f5 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc @@ -40,11 +40,6 @@ EasyUnlockSettingsHandler* EasyUnlockSettingsHandler::Create( if (!allowed) return nullptr; - html_source->AddBoolean( - "easyUnlockProximityDetectionAllowed", - base::CommandLine::ForCurrentProcess()->HasSwitch( - proximity_auth::switches::kEnableProximityDetection)); - return new EasyUnlockSettingsHandler(profile); } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc index afcd3c13819..4e9147b6155 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc @@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" +#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -58,7 +59,9 @@ FingerprintHandler::FingerprintHandler(Profile* profile) service_manager::Connector* connector = content::ServiceManagerConnection::GetForProcess()->GetConnector(); connector->BindInterface(device::mojom::kServiceName, &fp_service_); - fp_service_->AddFingerprintObserver(binding_.CreateInterfacePtrAndBind()); + device::mojom::FingerprintObserverPtr observer; + binding_.Bind(mojo::MakeRequest(&observer)); + fp_service_->AddFingerprintObserver(std::move(observer)); user_id_ = ProfileHelper::Get()->GetUserIdHashFromProfile(profile); // SessionManager may not exist in some tests. if (SessionManager::Get()) @@ -219,8 +222,7 @@ void FingerprintHandler::HandleStartEnroll(const base::ListValue* args) { std::string fingerprint_name = l10n_util::GetStringFUTF8( IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME, base::IntToString16(i)); - if (std::find(fingerprints_labels_.begin(), fingerprints_labels_.end(), - fingerprint_name) == fingerprints_labels_.end()) { + if (!base::ContainsValue(fingerprints_labels_, fingerprint_name)) { fp_service_->StartEnrollSession(user_id_, fingerprint_name); break; } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc new file mode 100644 index 00000000000..d046f21e27d --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc @@ -0,0 +1,75 @@ +// 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 "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h" + +#include <utility> + +#include "base/bind.h" +#include "base/values.h" +#include "chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h" +#include "chrome/browser/profiles/profile.h" +#include "components/arc/arc_service_manager.h" + +namespace chromeos { +namespace settings { + +GoogleAssistantHandler::GoogleAssistantHandler(Profile* profile) + : profile_(profile) {} + +GoogleAssistantHandler::~GoogleAssistantHandler() {} + +void GoogleAssistantHandler::OnJavascriptAllowed() {} +void GoogleAssistantHandler::OnJavascriptDisallowed() {} + +void GoogleAssistantHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "setGoogleAssistantEnabled", + base::Bind(&GoogleAssistantHandler::HandleSetGoogleAssistantEnabled, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "setGoogleAssistantContextEnabled", + base::Bind( + &GoogleAssistantHandler::HandleSetGoogleAssistantContextEnabled, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "showGoogleAssistantSettings", + base::Bind(&GoogleAssistantHandler::HandleShowGoogleAssistantSettings, + base::Unretained(this))); +} + +void GoogleAssistantHandler::HandleSetGoogleAssistantEnabled( + const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + bool enabled; + CHECK(args->GetBoolean(0, &enabled)); + + auto* service = + arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_); + if (service) + service->SetVoiceInteractionEnabled(enabled); +} + +void GoogleAssistantHandler::HandleSetGoogleAssistantContextEnabled( + const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + bool enabled; + CHECK(args->GetBoolean(0, &enabled)); + + auto* service = + arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_); + if (service) + service->SetVoiceInteractionContextEnabled(enabled); +} + +void GoogleAssistantHandler::HandleShowGoogleAssistantSettings( + const base::ListValue* args) { + auto* service = + arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile_); + if (service) + service->ShowVoiceInteractionSettings(); +} + +} // namespace settings +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h new file mode 100644 index 00000000000..01c4116d775 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h @@ -0,0 +1,41 @@ +// 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_GOOGLE_ASSISTANT_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_GOOGLE_ASSISTANT_HANDLER_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + +class Profile; + +namespace chromeos { +namespace settings { + +class GoogleAssistantHandler : public ::settings::SettingsPageUIHandler { + public: + explicit GoogleAssistantHandler(Profile* profile); + ~GoogleAssistantHandler() override; + + void RegisterMessages() override; + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; + + private: + // WebUI call to enable the Google Assistant. + void HandleSetGoogleAssistantEnabled(const base::ListValue* args); + // WebUI call to enable context for the Google Assistant. + void HandleSetGoogleAssistantContextEnabled(const base::ListValue* args); + // WebUI call to launch into the Google Assistant app settings. + void HandleShowGoogleAssistantSettings(const base::ListValue* args); + + Profile* const profile_; + + DISALLOW_COPY_AND_ASSIGN(GoogleAssistantHandler); +}; + +} // namespace settings +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_GOOGLE_ASSISTANT_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc index 1af49e99b48..c819ff40281 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc @@ -74,7 +74,7 @@ void InternetHandler::AddNetwork(const base::ListValue* args) { args->GetString(1, &extension_id); if (extension_id.empty()) { // Show the "add network" dialog for the built-in OpenVPN/L2TP provider. - NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow()); + NetworkConfigView::ShowForType(shill::kTypeVPN); return; } // Request that the third-party VPN provider identified by |provider_id| @@ -82,7 +82,7 @@ void InternetHandler::AddNetwork(const base::ListValue* args) { VpnServiceFactory::GetForBrowserContext(GetProfileForPrimaryUser()) ->SendShowAddDialogToExtension(extension_id); } else if (onc_type == ::onc::network_type::kWiFi) { - NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow()); + NetworkConfigView::ShowForType(shill::kTypeWifi); } else if (onc_type == ::onc::network_type::kCellular) { ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); } else { @@ -121,7 +121,7 @@ void InternetHandler::ConfigureNetwork(const base::ListValue* args) { return; } - NetworkConfigView::ShowForNetworkId(network->guid(), GetNativeWindow()); + NetworkConfigView::ShowForNetworkId(network->guid()); } gfx::NativeWindow InternetHandler::GetNativeWindow() const { diff --git a/chromium/chrome/browser/ui/webui/settings/font_handler.cc b/chromium/chrome/browser/ui/webui/settings/font_handler.cc index 954f7f6633f..abd118e6a53 100644 --- a/chromium/chrome/browser/ui/webui/settings/font_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/font_handler.cc @@ -16,7 +16,6 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/webui/options/font_settings_utils.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/browser/font_list_async.h" @@ -25,6 +24,10 @@ #include "extensions/browser/extension_system.h" #include "extensions/common/extension_urls.h" +#if defined(OS_MACOSX) +#include "chrome/browser/ui/webui/settings_utils.h" +#endif + namespace { const char kAdvancedFontSettingsExtensionId[] = @@ -38,8 +41,10 @@ FontHandler::FontHandler(content::WebUI* webui) : extension_registry_observer_(this), profile_(Profile::FromWebUI(webui)), weak_ptr_factory_(this) { +#if defined(OS_MACOSX) // Perform validation for saved fonts. - options::FontSettingsUtilities::ValidateSavedFonts(profile_->GetPrefs()); + settings_utils::ValidateSavedFonts(profile_->GetPrefs()); +#endif } FontHandler::~FontHandler() {} diff --git a/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index b714d9b070f..3dbd09b2a41 100644 --- a/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc @@ -34,6 +34,7 @@ #include "ui/base/l10n/l10n_util.h" #if defined(OS_CHROMEOS) +#include "ash/strings/grit/ash_strings.h" #include "ash/system/devicetype_utils.h" #include "ash/system/night_light/night_light_controller.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" @@ -43,14 +44,18 @@ #include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h" #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h" #include "chromeos/chromeos_switches.h" -#include "components/user_manager/user.h" +#include "components/arc/arc_util.h" #include "components/user_manager/user_manager.h" -#include "ui/chromeos/strings/grit/ui_chromeos_strings.h" +#include "ui/chromeos/events/keyboard_layout_util.h" #include "ui/display/display_switches.h" #else #include "chrome/browser/ui/webui/settings/system_handler.h" #endif +#if defined(OS_WIN) +#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" +#endif + namespace settings { namespace { @@ -299,7 +304,9 @@ void AddAccountUITweaksStrings(content::WebUIDataSource* html_source, void AddAndroidAppStrings(content::WebUIDataSource* html_source) { LocalizedString localized_strings[] = { - {"androidAppsPageTitle", IDS_SETTINGS_ANDROID_APPS_TITLE}, + {"androidAppsPageTitle", arc::IsPlayStoreAvailable() + ? IDS_SETTINGS_ANDROID_APPS_TITLE + : IDS_SETTINGS_ANDROID_SETTINGS_TITLE}, {"androidAppsPageLabel", IDS_SETTINGS_ANDROID_APPS_LABEL}, {"androidAppsEnable", IDS_SETTINGS_ANDROID_APPS_ENABLE}, {"androidAppsManageApps", IDS_SETTINGS_ANDROID_APPS_MANAGE_APPS}, @@ -532,7 +539,10 @@ void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source) { {"historyDeletionDialogTitle", IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_TITLE}, {"historyDeletionDialogOK", IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_OK}, - {"importantSitesSubtitle", IDS_SETTINGS_IMPORTANT_SITES_SUBTITLE}, + {"importantSitesSubtitleCookies", + IDS_SETTINGS_IMPORTANT_SITES_SUBTITLE_COOKIES}, + {"importantSitesSubtitleCookiesAndCache", + IDS_SETTINGS_IMPORTANT_SITES_SUBTITLE_COOKIES_AND_CACHE}, {"importantSitesConfirm", IDS_SETTINGS_IMPORTANT_SITES_CONFIRM}, {"notificationWarning", IDS_SETTINGS_NOTIFICATION_WARNING}, }; @@ -599,7 +609,9 @@ void AddDeviceStrings(content::WebUIDataSource* html_source) { LocalizedString keyboard_strings[] = { {"keyboardTitle", IDS_SETTINGS_KEYBOARD_TITLE}, - {"keyboardKeySearch", IDS_SETTINGS_KEYBOARD_KEY_SEARCH}, + {"keyboardKeySearch", ui::DeviceUsesKeyboardLayout2() + ? IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER + : IDS_SETTINGS_KEYBOARD_KEY_SEARCH}, {"keyboardKeyCtrl", IDS_SETTINGS_KEYBOARD_KEY_LEFT_CTRL}, {"keyboardKeyAlt", IDS_SETTINGS_KEYBOARD_KEY_LEFT_ALT}, {"keyboardKeyCapsLock", IDS_SETTINGS_KEYBOARD_KEY_CAPS_LOCK}, @@ -609,7 +621,9 @@ void AddDeviceStrings(content::WebUIDataSource* html_source) { {"keyboardKeyDisabled", IDS_SETTINGS_KEYBOARD_KEY_DISABLED}, {"keyboardSendFunctionKeys", IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS}, {"keyboardSendFunctionKeysDescription", - IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION}, + ui::DeviceUsesKeyboardLayout2() + ? IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION + : IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION}, {"keyboardEnableAutoRepeat", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE}, {"keyRepeatDelay", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY}, {"keyRepeatDelayLong", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_LONG}, @@ -635,6 +649,10 @@ void AddDeviceStrings(content::WebUIDataSource* html_source) { {"stylusNoteTakingApp", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LABEL}, {"stylusNoteTakingAppEnabledOnLockScreen", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LOCK_SCREEN_CHECKBOX}, + {"stylusNoteTakingAppKeepsLastNoteOnLockScreen", + IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_KEEP_LATEST_NOTE}, + {"stylusNoteTakingAppLockScreenSettingsHeader", + IDS_SETTINGS_STYLUS_LOCK_SCREEN_NOTES_TITLE}, {"stylusNoteTakingAppNoneAvailable", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE}, {"stylusNoteTakingAppWaitingForAndroid", @@ -656,6 +674,9 @@ void AddDeviceStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER}, {"displayNightLightScheduleSunsetToSunRise", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE}, + {"displayNightLightStartTime", + IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME}, + {"displayNightLightStopTime", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME}, {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT}, {"displayNightLightTemperatureLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL}, @@ -739,7 +760,16 @@ void AddDeviceStrings(content::WebUIDataSource* html_source) { {"powerSourceAcAdapter", IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER}, {"powerSourceLowPowerCharger", IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER}, - {"calculatingPower", IDS_SETTINGS_POWER_SOURCE_CALCULATING}}; + {"calculatingPower", IDS_SETTINGS_POWER_SOURCE_CALCULATING}, + {"powerIdleLabel", IDS_SETTINGS_POWER_IDLE_LABEL}, + {"powerIdleDisplayOffSleep", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP}, + {"powerIdleDisplayOff", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF}, + {"powerIdleDisplayOn", IDS_SETTINGS_POWER_IDLE_DISPLAY_ON}, + {"powerIdleOther", IDS_SETTINGS_POWER_IDLE_OTHER}, + {"powerLidSleepLabel", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL}, + {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL}, + {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL}, + }; AddLocalizedStringsBulk(html_source, power_strings, arraysize(power_strings)); html_source->AddString("naturalScrollLearnMoreLink", @@ -760,6 +790,41 @@ void AddDownloadsStrings(content::WebUIDataSource* html_source) { arraysize(localized_strings)); } +#if defined(OS_WIN) +void AddChromeCleanupStrings(content::WebUIDataSource* html_source) { + LocalizedString localized_strings[] = { + {"chromeCleanupExplanation", IDS_CHROME_CLEANUP_WEBUI_EXPLANATION}, + {"chromeCleanupDoneButtonLabel", + IDS_CHROME_CLEANUP_WEBUI_DONE_BUTTON_LABEL}, + {"chromeCleanupLinkShowFiles", IDS_CHROME_CLEANUP_WEBUI_LINK_SHOW_FILES}, + {"chromeCleanupLogsUploadPermission", IDS_CHROME_CLEANUP_LOGS_PERMISSION}, + {"chromeCleanupRemoveButtonLabel", + IDS_CHROME_CLEANUP_WEBUI_REMOVE_BUTTON_LABEL}, + {"chromeCleanupRestartButtonLabel", + IDS_CHROME_CLEANUP_WEBUI_RESTART_BUTTON_LABEL}, + {"chromeCleanupTitleErrorCantRemove", + IDS_CHROME_CLEANUP_WEBUI_TITLE_ERROR_CANT_REMOVE}, + {"chromeCleanupTitleRemove", IDS_CHROME_CLEANUP_WEBUI_TITLE_REMOVE}, + {"chromeCleanupTitleRemoved", IDS_CHROME_CLEANUP_WEBUI_TITLE_REMOVED}, + {"chromeCleanupTitleRemoving", IDS_CHROME_CLEANUP_WEBUI_TITLE_REMOVING}, + {"chromeCleanupTitleRestart", IDS_CHROME_CLEANUP_WEBUI_TITLE_RESTART}, + }; + AddLocalizedStringsBulk(html_source, localized_strings, + arraysize(localized_strings)); + const std::string cleanup_learn_more_url = + google_util::AppendGoogleLocaleParam( + GURL(chrome::kChromeCleanerLearnMoreURL), + g_browser_process->GetApplicationLocale()) + .spec(); + html_source->AddString("chromeCleanupLearnMoreUrl", cleanup_learn_more_url); + + base::string16 powered_by_html = l10n_util::GetStringFUTF16( + IDS_CHROME_CLEANUP_WEBUI_FOOTER_POWERED_BY, + L"<span id='powered-by-logo'></span><span>®</span>"); + html_source->AddString("chromeCleanupPoweredByHtml", powered_by_html); +} +#endif // defined(OS_WIN) + void AddResetStrings(content::WebUIDataSource* html_source) { LocalizedString localized_strings[] = { {"resetPageTitle", IDS_SETTINGS_RESET}, @@ -848,6 +913,18 @@ void AddEasyUnlockStrings(content::WebUIDataSource* html_source) { {"easyUnlockTurnOffErrorMessage", IDS_SETTINGS_EASY_UNLOCK_TURN_OFF_ERROR_MESSAGE}, {"easyUnlockTurnOffRetryButton", IDS_SETTINGS_EASY_UNLOCK_TURN_OFF_RETRY}, + {"easyUnlockAllowSignInLabel", + IDS_SETTINGS_EASY_UNLOCK_ALLOW_SIGN_IN_LABEL}, + {"easyUnlockProximityThresholdLabel", + IDS_SETTINGS_EASY_UNLOCK_PROXIMITY_THRESHOLD_LABEL}, + {"easyUnlockProximityThresholdVeryClose", + IDS_SETTINGS_EASY_UNLOCK_PROXIMITY_THRESHOLD_VERY_CLOSE}, + {"easyUnlockProximityThresholdClose", + IDS_SETTINGS_EASY_UNLOCK_PROXIMITY_THRESHOLD_CLOSE}, + {"easyUnlockProximityThresholdFar", + IDS_SETTINGS_EASY_UNLOCK_PROXIMITY_THRESHOLD_FAR}, + {"easyUnlockProximityThresholdVeryFar", + IDS_SETTINGS_EASY_UNLOCK_PROXIMITY_THRESHOLD_VERY_FAR}, }; AddLocalizedStringsBulk(html_source, localized_strings, arraysize(localized_strings)); @@ -871,9 +948,9 @@ void AddEasyUnlockStrings(content::WebUIDataSource* html_source) { l10n_util::GetStringFUTF16(IDS_SETTINGS_EASY_UNLOCK_TURN_OFF_DESCRIPTION, device_name)); html_source->AddString( - "easyUnlockRequireProximityLabel", + "easyUnlockProximityThresholdLabel", l10n_util::GetStringFUTF16( - IDS_SETTINGS_EASY_UNLOCK_REQUIRE_PROXIMITY_LABEL, device_name)); + IDS_SETTINGS_EASY_UNLOCK_PROXIMITY_THRESHOLD_LABEL, device_name)); html_source->AddString("easyUnlockLearnMoreURL", chrome::kEasyUnlockLearnMoreUrl); @@ -898,8 +975,9 @@ void AddInternetStrings(content::WebUIDataSource* html_source) { {"internetPageTitle", IDS_SETTINGS_INTERNET}, {"internetToggleMobileA11yLabel", IDS_SETTINGS_INTERNET_TOGGLE_MOBILE_ACCESSIBILITY_LABEL}, - {"internetToggleTetherA11yLabel", - IDS_SETTINGS_INTERNET_TOGGLE_TETHER_ACCESSIBILITY_LABEL}, + {"internetToggleTetherLabel", IDS_SETTINGS_INTERNET_TOGGLE_TETHER_LABEL}, + {"internetToggleTetherSubtext", + IDS_SETTINGS_INTERNET_TOGGLE_TETHER_SUBTEXT}, {"internetToggleWiFiA11yLabel", IDS_SETTINGS_INTERNET_TOGGLE_WIFI_ACCESSIBILITY_LABEL}, {"internetToggleWiMAXA11yLabel", @@ -917,6 +995,10 @@ void AddInternetStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_FORGET}, {"networkAllowDataRoaming", IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING}, + {"networkChooseMobileButton", + IDS_SETTINGS_SETTINGS_NETWORK_CHOOSE_MOBILE_BUTTON}, + {"networkChooseMobileDetail", + IDS_SETTINGS_SETTINGS_NETWORK_CHOOSE_MOBILE_DETAIL}, {"networkAutoConnect", IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT}, {"networkButtonActivate", IDS_SETTINGS_INTERNET_BUTTON_ACTIVATE}, {"networkButtonConfigure", IDS_SETTINGS_INTERNET_BUTTON_CONFIGURE}, @@ -1005,6 +1087,8 @@ void AddInternetStrings(content::WebUIDataSource* html_source) { {"networkVpnBuiltin", IDS_NETWORK_TYPE_VPN_BUILTIN}, {"tetherConnectionDialogTitle", IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DIALOG_TITLE}, + {"tetherConnectionAvailableDeviceTitle", + IDS_SETTINGS_INTERNET_TETHER_CONNECTION_AVAILABLE_DEVICE_TITLE}, {"tetherConnectionBatteryPercentage", IDS_SETTINGS_INTERNET_TETHER_CONNECTION_BATTERY_PERCENTAGE}, {"tetherConnectionExplanation", @@ -1013,8 +1097,8 @@ void AddInternetStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CARRIER_WARNING}, {"tetherConnectionDescriptionTitle", IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_TITLE}, - {"tetherConnectionDescriptionCellData", - IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_CELLULAR_DATA}, + {"tetherConnectionDescriptionMobileData", + IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_MOBILE_DATA}, {"tetherConnectionDescriptionBattery", IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_BATTERY}, {"tetherConnectionDescriptionWiFi", @@ -1023,12 +1107,18 @@ void AddInternetStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_INTERNET_TETHER_CONNECTION_NOT_NOW_BUTTON}, {"tetherConnectionConnectButton", IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CONNECT_BUTTON}, + {"tetherEnableBluetooth", IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH}, }; AddLocalizedStringsBulk(html_source, localized_strings, arraysize(localized_strings)); html_source->AddBoolean("networkSettingsConfig", base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kNetworkSettingsConfig)); + html_source->AddString( + "internetNoNetworksMobileData", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_INTERNET_NO_NETWORKS_MOBILE_DATA, + base::ASCIIToUTF16(chrome::kInstantTetheringLearnMoreURL))); } #endif @@ -1130,6 +1220,9 @@ void AddChromeOSUserStrings(content::WebUIDataSource* html_source, void AddOnStartupStrings(content::WebUIDataSource* html_source) { LocalizedString localized_strings[] = { {"onStartup", IDS_SETTINGS_ON_STARTUP}, + {"onStartupDescription", IDS_SETTINGS_ON_STARTUP_DESCRIPTION}, + {"onStartupManage", IDS_SETTINGS_ON_STARTUP_MANAGE}, + {"onStartupPages", IDS_SETTINGS_ON_STARTUP_PAGES}, {"onStartupOpenNewTab", IDS_SETTINGS_ON_STARTUP_OPEN_NEW_TAB}, {"onStartupContinue", IDS_SETTINGS_ON_STARTUP_CONTINUE}, {"onStartupOpenSpecific", IDS_SETTINGS_ON_STARTUP_OPEN_SPECIFIC}, @@ -1310,7 +1403,7 @@ void AddPeopleStrings(content::WebUIDataSource* html_source) { {"oldPhoto", IDS_SETTINGS_CHANGE_PICTURE_OLD_PHOTO}, {"profilePhotoLoading", IDS_SETTINGS_CHANGE_PICTURE_PROFILE_LOADING_PHOTO}, {"previewAltText", IDS_SETTINGS_CHANGE_PICTURE_PREVIEW_ALT}, - {"authorCredit", IDS_SETTINGS_CHANGE_PICTURE_AUTHOR_TEXT}, + {"authorCreditText", IDS_SETTINGS_CHANGE_PICTURE_AUTHOR_CREDIT_TEXT}, {"photoFlippedAccessibleText", IDS_SETTINGS_PHOTO_FLIP_ACCESSIBLE_TEXT}, {"photoFlippedBackAccessibleText", IDS_SETTINGS_PHOTO_FLIPBACK_ACCESSIBLE_TEXT}, @@ -1443,12 +1536,13 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) { {"printingManageCloudPrintDevices", IDS_SETTINGS_PRINTING_MANAGE_CLOUD_PRINT_DEVICES}, {"cloudPrintersTitle", IDS_SETTINGS_PRINTING_CLOUD_PRINTERS}, - {"cloudPrintersTitleDescription", - IDS_SETTINGS_PRINTING_CLOUD_PRINTERS_DESCRIPTION}, #if defined(OS_CHROMEOS) {"cupsPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTERS}, + {"cupsPrintersLearnMoreLabel", + IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL}, {"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER}, {"cupsPrinterDetails", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_DETAILS}, + {"editPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_EDIT}, {"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE}, {"searchLabel", IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL}, {"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE}, @@ -1459,6 +1553,8 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_NEARBY_TITLE}, {"addPrintersManuallyTitle", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_MANUALLY_TITLE}, + {"selectManufacturerAndModelTitle", + IDS_SETTINGS_PRINTING_CUPS_SELECT_MANUFACTURER_AND_MODEL_TITLE}, {"cancelButtonText", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_CANCEL}, {"addPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_ADD}, {"printerDetailsAdvanced", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED}, @@ -1500,6 +1596,9 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_TRY_AGAIN_MESSAGE}, {"requireNetworkMessage", IDS_SETTINGS_PRINTING_CUPS_PRINTER_REQUIRE_INTERNET_MESSAGE}, + {"editPrinterDialogTitle", + IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_DIALOG_TITLE}, + {"editPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_BUTTON}, #endif }; AddLocalizedStringsBulk(html_source, localized_strings, @@ -1510,9 +1609,8 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) { chrome::kCloudPrintLearnMoreURL); #if defined(OS_CHROMEOS) - html_source->AddBoolean("showCupsPrintingFeatures", - !base::CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kDisableNativeCups)); + html_source->AddString("printingCUPSPrintLearnMoreUrl", + chrome::kCupsPrintLearnMoreURL); #endif } @@ -1595,19 +1693,35 @@ void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) { void AddSearchStrings(content::WebUIDataSource* html_source) { LocalizedString localized_strings[] = { - {"searchPageTitle", IDS_SETTINGS_SEARCH}, - {"searchEnginesManage", IDS_SETTINGS_SEARCH_MANAGE_SEARCH_ENGINES}, - {"searchOkGoogleLabel", IDS_SETTINGS_SEARCH_OK_GOOGLE_LABEL}, - {"searchOkGoogleSubtextAlwaysOn", - IDS_SETTINGS_SEARCH_OK_GOOGLE_SUBTEXT_ALWAYS_ON}, - {"searchOkGoogleSubtextNoHardware", - IDS_SETTINGS_SEARCH_OK_GOOGLE_SUBTEXT_NO_HARDWARE}, - {"searchOkGoogleAudioHistoryLabel", - IDS_SETTINGS_SEARCH_OK_GOOGLE_AUDIO_HISTORY_LABEL}, - {"searchOkGoogleAudioHistorySubtext", - IDS_SETTINGS_SEARCH_OK_GOOGLE_AUDIO_HISTORY_SUBTEXT}, - {"searchOkGoogleRetrain", IDS_SETTINGS_SEARCH_OK_GOOGLE_RETRAIN}, - {"searchEnableGoogleNowLabel", IDS_SETTINGS_SEARCH_ENABLE_GOOGLE_NOW}, +#if defined(OS_CHROMEOS) + {"searchPageTitle", chromeos::switches::IsVoiceInteractionEnabled() + ? IDS_SETTINGS_SEARCH_AND_ASSISTANT + : IDS_SETTINGS_SEARCH}, +#else + {"searchPageTitle", IDS_SETTINGS_SEARCH}, +#endif + {"searchEnginesManage", IDS_SETTINGS_SEARCH_MANAGE_SEARCH_ENGINES}, + {"searchOkGoogleLabel", IDS_SETTINGS_SEARCH_OK_GOOGLE_LABEL}, +#if defined(OS_CHROMEOS) + {"searchGoogleAssistant", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT}, + {"searchGoogleAssistantEnabled", + IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ENABLED}, + {"searchGoogleAssistantDisabled", + IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_DISABLED}, +#endif + {"searchOkGoogleSubtextAlwaysOn", + IDS_SETTINGS_SEARCH_OK_GOOGLE_SUBTEXT_ALWAYS_ON}, + {"searchOkGoogleSubtextNoHardware", + IDS_SETTINGS_SEARCH_OK_GOOGLE_SUBTEXT_NO_HARDWARE}, + {"searchOkGoogleAudioHistoryLabel", + IDS_SETTINGS_SEARCH_OK_GOOGLE_AUDIO_HISTORY_LABEL}, + {"searchOkGoogleAudioHistorySubtext", + IDS_SETTINGS_SEARCH_OK_GOOGLE_AUDIO_HISTORY_SUBTEXT}, + {"searchOkGoogleRetrain", IDS_SETTINGS_SEARCH_OK_GOOGLE_RETRAIN}, +#if defined(OS_CHROMEOS) + {"searchOkGoogleDisabled", IDS_SETTINGS_SEARCH_OK_GOOGLE_DISABLED}, +#endif + {"searchEnableGoogleNowLabel", IDS_SETTINGS_SEARCH_ENABLE_GOOGLE_NOW}, }; AddLocalizedStringsBulk(html_source, localized_strings, arraysize(localized_strings)); @@ -1619,6 +1733,10 @@ void AddSearchStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_SEARCH_EXPLANATION, base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL)); html_source->AddString("searchExplanation", search_explanation_text); +#if defined(OS_CHROMEOS) + html_source->AddBoolean("enableVoiceInteraction", + chromeos::switches::IsVoiceInteractionEnabled()); +#endif } void AddSearchEnginesStrings(content::WebUIDataSource* html_source) { @@ -1649,6 +1767,21 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) { arraysize(localized_strings)); } +#if defined(OS_CHROMEOS) +void AddGoogleAssistantStrings(content::WebUIDataSource* html_source) { + LocalizedString localized_strings[] = { + {"googleAssistantPageTitle", IDS_SETTINGS_GOOGLE_ASSISTANT}, + {"googleAssistantEnableContext", + IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_CONTEXT}, + {"googleAssistantEnableContextDescription", + IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_CONTEXT_DESCRIPTION}, + {"googleAssistantSettings", IDS_SETTINGS_GOOGLE_ASSISTANT_SETTINGS}, + }; + AddLocalizedStringsBulk(html_source, localized_strings, + arraysize(localized_strings)); +} +#endif + void AddSiteSettingsStrings(content::WebUIDataSource* html_source, Profile* profile) { LocalizedString localized_strings[] = { @@ -1667,7 +1800,8 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, {"cookiePlural", IDS_SETTINGS_COOKIES_PLURAL_COOKIES}, {"cookieServiceWorker", IDS_SETTINGS_COOKIES_SERVICE_WORKER}, {"cookieSingular", IDS_SETTINGS_COOKIES_SINGLE_COOKIE}, - {"embeddedOnHost", IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST}, + {"embeddedOnAnyHost", IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_ANY_HOST}, + {"embeddedOnHost", IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_HOST}, {"editSiteTitle", IDS_SETTINGS_EDIT_SITE_TITLE}, {"appCacheManifest", IDS_SETTINGS_COOKIES_APPLICATION_CACHE_MANIFEST_LABEL}, {"cacheStorageLastModified", @@ -1781,9 +1915,9 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, {"siteSettingsFlashAllow", IDS_SETTINGS_SITE_SETTINGS_FLASH_ALLOW}, {"siteSettingsFlashBlock", IDS_SETTINGS_SITE_SETTINGS_FLASH_BLOCK}, {"siteSettingsAllowRecentlyClosedSites", - IDS_SETTINGS_SITE_SETTINGS_BACKGROUND_SYNC_ALLOW_RECENTLY_CLOSED_SITES}, + IDS_SETTINGS_SITE_SETTINGS_ALLOW_RECENTLY_CLOSED_SITES}, {"siteSettingsAllowRecentlyClosedSitesRecommended", - IDS_SETTINGS_SITE_SETTINGS_BACKGROUND_SYNC_ALLOW_RECENTLY_CLOSED_SITES_RECOMMENDED}, + IDS_SETTINGS_SITE_SETTINGS_ALLOW_RECENTLY_CLOSED_SITES_RECOMMENDED}, {"siteSettingsBackgroundSyncBlocked", IDS_SETTINGS_SITE_SETTINGS_BACKGROUND_SYNC_BLOCKED}, {"siteSettingsHandlersAsk", IDS_SETTINGS_SITE_SETTINGS_HANDLERS_ASK}, @@ -1821,6 +1955,12 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, {"siteSettingsBlockedRecommended", IDS_SETTINGS_SITE_SETTINGS_BLOCKED_RECOMMENDED}, {"siteSettingsSiteUrl", IDS_SETTINGS_SITE_SETTINGS_SITE_URL}, + {"siteSettingsActionAskDefault", + IDS_SETTINGS_SITE_SETTINGS_ASK_DEFAULT_MENU}, + {"siteSettingsActionAllowDefault", + IDS_SETTINGS_SITE_SETTINGS_ALLOW_DEFAULT_MENU}, + {"siteSettingsActionBlockDefault", + IDS_SETTINGS_SITE_SETTINGS_BLOCK_DEFAULT_MENU}, {"siteSettingsActionAllow", IDS_SETTINGS_SITE_SETTINGS_ALLOW_MENU}, {"siteSettingsActionBlock", IDS_SETTINGS_SITE_SETTINGS_BLOCK_MENU}, {"siteSettingsActionReset", IDS_SETTINGS_SITE_SETTINGS_RESET_MENU}, @@ -1866,9 +2006,10 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, {"embeddedIncognitoSite", IDS_SETTINGS_SITE_SETTINGS_INCOGNITO_EMBEDDED}, {"siteSettingsSiteDetails", IDS_SETTINGS_SITE_DETAILS}, {"noSitesAdded", IDS_SETTINGS_SITE_NO_SITES_ADDED}, - {"siteSettingsSubresourceFilter", IDS_SUBRESOURCE_FILTER_HEADER}, - {"siteSettingsSubresourceFilterAllow", IDS_SUBRESOURCE_FILTER_ALLOW_RADIO}, - {"siteSettingsSubresourceFilterBlock", IDS_SUBRESOURCE_FILTER_BLOCK_RADIO}, + {"siteSettingsAds", IDS_SETTINGS_SITE_SETTINGS_ADS}, + {"siteSettingsAdsBlock", IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCK}, + {"siteSettingsAdsBlockRecommended", + IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCK_RECOMMENDED}, }; AddLocalizedStringsBulk(html_source, localized_strings, arraysize(localized_strings)); @@ -1876,6 +2017,8 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, html_source->AddBoolean("enableSiteSettings", base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableSiteSettings)); + html_source->AddBoolean("enableSiteDetails", + base::FeatureList::IsEnabled(features::kSiteDetails)); html_source->AddBoolean( "enableSafeBrowsingSubresourceFilter", base::FeatureList::IsEnabled( @@ -1973,6 +2116,21 @@ void AddWebContentStrings(content::WebUIDataSource* html_source) { } #if defined(OS_CHROMEOS) +void AddMultideviceStrings(content::WebUIDataSource* html_source) { + LocalizedString localized_strings[] = { + {"multidevicePageTitle", IDS_SETTINGS_MULTIDEVICE}, + {"smsConnect", IDS_SETTINGS_MULTIDEVICE_SMS_CONNECT}, + {"smsConnectSummary", IDS_SETTINGS_MULTIDEVICE_SMS_CONNECT_SUMMARY}, + }; + AddLocalizedStringsBulk(html_source, localized_strings, + arraysize(localized_strings)); + + html_source->AddBoolean("enableMultideviceSettings", + base::FeatureList::IsEnabled(features::kMultidevice)); +} +#endif + +#if defined(OS_CHROMEOS) void AddOncStrings(content::WebUIDataSource* html_source) { LocalizedString onc_property_strings[] = { // Thes strings are generated by prepending 'Onc' to the ONC property @@ -2082,6 +2240,11 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source, AddA11yStrings(html_source); AddAboutStrings(html_source); AddAppearanceStrings(html_source, profile); + +#if defined(OS_WIN) + AddChromeCleanupStrings(html_source); +#endif // defined(OS_WIN) + AddClearBrowsingDataStrings(html_source); AddCommonStrings(html_source, profile); AddDownloadsStrings(html_source); @@ -2093,6 +2256,9 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source, AddPrivacyStrings(html_source, profile); AddResetStrings(html_source); AddSearchEnginesStrings(html_source); +#if defined(OS_CHROMEOS) + AddGoogleAssistantStrings(html_source); +#endif AddSearchInSettingsStrings(html_source); AddSearchStrings(html_source); AddSiteSettingsStrings(html_source, profile); @@ -2107,6 +2273,7 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source, AddDeviceStrings(html_source); AddEasyUnlockStrings(html_source); AddInternetStrings(html_source); + AddMultideviceStrings(html_source); AddOncStrings(html_source); AddUsersStrings(html_source); #else diff --git a/chromium/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/md_settings_ui.cc index d073d8dfa66..d2a801f5a63 100644 --- a/chromium/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chromium/chrome/browser/ui/webui/settings/md_settings_ui.cc @@ -6,7 +6,9 @@ #include <stddef.h> +#include <memory> #include <string> +#include <utility> #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -44,6 +46,15 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#if defined(OS_WIN) +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" +#include "chrome/browser/ui/webui/settings/chrome_cleanup_handler.h" +#if defined(GOOGLE_CHROME_BUILD) +#include "chrome/grit/chrome_unscaled_resources.h" +#endif +#endif // defined(OS_WIN) + #if defined(OS_WIN) || defined(OS_CHROMEOS) #include "chrome/browser/ui/webui/settings/languages_handler.h" #endif // defined(OS_WIN) || defined(OS_CHROMEOS) @@ -66,8 +77,10 @@ #include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h" #include "chrome/common/chrome_switches.h" +#include "chromeos/chromeos_switches.h" #include "components/arc/arc_util.h" #else // !defined(OS_CHROMEOS) #include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" @@ -83,6 +96,12 @@ namespace settings { +bool IsValidOrigin(const GURL& url) { + const GURL origin = url.GetOrigin(); + return origin == GURL(chrome::kChromeUISettingsURL).GetOrigin() || + origin == GURL(chrome::kChromeUIMdSettingsURL).GetOrigin(); +} + // static void MdSettingsUI::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { @@ -96,6 +115,10 @@ void MdSettingsUI::RegisterProfilePrefs( MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) : content::WebUIController(web_ui), WebContentsObserver(web_ui->GetWebContents()) { +#if BUILDFLAG(USE_VULCANIZE) + std::unordered_set<std::string> exclude_from_gzip; +#endif + Profile* profile = Profile::FromWebUI(web_ui); AddSettingsPageUIHandler(base::MakeUnique<AppearanceHandler>(web_ui)); @@ -122,7 +145,7 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) AddSettingsPageUIHandler(base::MakeUnique<MetricsReportingHandler>()); #endif - AddSettingsPageUIHandler(base::MakeUnique<OnStartupHandler>()); + AddSettingsPageUIHandler(base::MakeUnique<OnStartupHandler>(profile)); AddSettingsPageUIHandler(base::MakeUnique<PeopleHandler>(profile)); AddSettingsPageUIHandler(base::MakeUnique<ProfileInfoHandler>(profile)); AddSettingsPageUIHandler(base::MakeUnique<ProtocolHandlersHandler>()); @@ -143,8 +166,12 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) base::MakeUnique<chromeos::settings::CupsPrintersHandler>(web_ui)); AddSettingsPageUIHandler( base::MakeUnique<chromeos::settings::FingerprintHandler>(profile)); + if (chromeos::switches::IsVoiceInteractionEnabled()) { + AddSettingsPageUIHandler( + base::MakeUnique<chromeos::settings::GoogleAssistantHandler>(profile)); + } AddSettingsPageUIHandler( - base::MakeUnique<chromeos::settings::KeyboardHandler>(web_ui)); + base::MakeUnique<chromeos::settings::KeyboardHandler>()); AddSettingsPageUIHandler( base::MakeUnique<chromeos::settings::PointerHandler>()); AddSettingsPageUIHandler( @@ -161,13 +188,34 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) // Host must be derived from the visible URL, since this might be serving // either chrome://settings or chrome://md-settings. - CHECK(url.GetOrigin() == GURL(chrome::kChromeUISettingsURL).GetOrigin() || - url.GetOrigin() == GURL(chrome::kChromeUIMdSettingsURL).GetOrigin()); + CHECK(IsValidOrigin(url)); content::WebUIDataSource* html_source = content::WebUIDataSource::Create(url.host()); html_source->AddString("hostname", url.host()); +#if defined(OS_WIN) + if (base::FeatureList::IsEnabled(safe_browsing::kInBrowserCleanerUIFeature)) { + AddSettingsPageUIHandler(base::MakeUnique<ChromeCleanupHandler>(profile)); + + safe_browsing::ChromeCleanerController* cleaner_controller = + safe_browsing::ChromeCleanerController::GetInstance(); + if (cleaner_controller->ShouldShowCleanupInSettingsUI()) + html_source->AddBoolean("chromeCleanupEnabled", true); + +#if defined(GOOGLE_CHROME_BUILD) + if (cleaner_controller->IsPoweredByPartner()) + html_source->AddBoolean("cleanupPoweredByPartner", true); + + html_source->AddResourcePath("partner-logo.svg", + IDR_CHROME_CLEANUP_PARTNER); +#if BUILDFLAG(USE_VULCANIZE) + exclude_from_gzip.insert("partner-logo.svg"); +#endif +#endif // defined(GOOGLE_CHROME_BUILD) + } +#endif // defined(OS_WIN) + #if defined(OS_CHROMEOS) chromeos::settings::EasyUnlockSettingsHandler* easy_unlock_handler = chromeos::settings::EasyUnlockSettingsHandler::Create(html_source, @@ -185,20 +233,27 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); html_source->AddBoolean("fingerprintUnlockEnabled", chromeos::quick_unlock::IsFingerprintEnabled()); - html_source->AddBoolean("androidAppsAllowed", - arc::IsArcAllowedForProfile(profile) && - !arc::IsArcOptInVerificationDisabled()); + html_source->AddBoolean("hasInternalStylus", + ash::palette_utils::HasInternalStylus()); + + // We have 2 variants of Android apps settings. Default case, when the Play + // Store app exists we show expandable section that allows as to + // enable/disable the Play Store and link to Android settings which is + // available once settings app is registered in the system. + // For AOSP images we don't have the Play Store app. In last case we Android + // apps settings consists only from root link to Android settings and only + // visible once settings app is registered. + const bool androidAppsVisible = arc::IsArcAllowedForProfile(profile) && + !arc::IsArcOptInVerificationDisabled(); + html_source->AddBoolean("androidAppsVisible", androidAppsVisible); + html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable()); // TODO(mash): Support Chrome power settings in Mash. crbug.com/644348 - bool enable_power_settings = - !ash_util::IsRunningInMash() && - (switches::PowerOverlayEnabled() || - (ash::PowerStatus::Get()->IsBatteryPresent() && - ash::PowerStatus::Get()->SupportsDualRoleDevices())); + bool enable_power_settings = !ash_util::IsRunningInMash(); html_source->AddBoolean("enablePowerSettings", enable_power_settings); if (enable_power_settings) { - AddSettingsPageUIHandler( - base::MakeUnique<chromeos::settings::PowerHandler>()); + AddSettingsPageUIHandler(base::MakeUnique<chromeos::settings::PowerHandler>( + profile->GetPrefs())); } #endif @@ -217,7 +272,7 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) html_source->AddResourcePath("lazy_load.html", IDR_MD_SETTINGS_LAZY_LOAD_VULCANIZED_HTML); html_source->SetDefaultResource(IDR_MD_SETTINGS_VULCANIZED_HTML); - html_source->UseGzip(std::unordered_set<std::string>()); + html_source->UseGzip(exclude_from_gzip); #else // Add all settings resources. for (size_t i = 0; i < kSettingsResourcesSize; ++i) { @@ -231,6 +286,16 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url) content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), html_source); + +#if defined(OS_WIN) + // This needs to be below content::WebUIDataSource::Add to make sure there + // is a WebUIDataSource to update if the observer is immediately notified. + if (base::FeatureList::IsEnabled(safe_browsing::kInBrowserCleanerUIFeature)) { + cleanup_observer_.reset( + new safe_browsing::ChromeCleanerStateChangeObserver(base::Bind( + &MdSettingsUI::UpdateCleanupDataSource, base::Unretained(this)))); + } +#endif // defined(OS_WIN) } MdSettingsUI::~MdSettingsUI() { @@ -262,4 +327,19 @@ void MdSettingsUI::DocumentOnLoadCompletedInMainFrame() { base::Time::Now() - load_start_time_); } +#if defined(OS_WIN) +void MdSettingsUI::UpdateCleanupDataSource(bool cleanupEnabled, + bool partnerPowered) { + DCHECK(web_ui()); + Profile* profile = Profile::FromWebUI(web_ui()); + + std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue); + update->SetBoolean("chromeCleanupEnabled", cleanupEnabled); + update->SetBoolean("cleanupPoweredByPartner", partnerPowered); + + content::WebUIDataSource::Update(profile, chrome::kChromeUISettingsHost, + std::move(update)); +} +#endif // defined(OS_WIN) + } // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/md_settings_ui.h b/chromium/chrome/browser/ui/webui/settings/md_settings_ui.h index 2262702c736..1ca22c6e5ed 100644 --- a/chromium/chrome/browser/ui/webui/settings/md_settings_ui.h +++ b/chromium/chrome/browser/ui/webui/settings/md_settings_ui.h @@ -9,9 +9,14 @@ #include "base/macros.h" #include "base/time/time.h" +#include "build/build_config.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui_controller.h" +#if defined(OS_WIN) +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.h" +#endif + class GURL; namespace user_prefs { @@ -22,6 +27,9 @@ namespace settings { class SettingsPageUIHandler; +// Exposed for testing. +bool IsValidOrigin(const GURL& url); + // The WebUI handler for chrome://md-settings. class MdSettingsUI : public content::WebUIController, public content::WebContentsObserver { @@ -46,6 +54,12 @@ class MdSettingsUI : public content::WebUIController, base::Time load_start_time_; +#if defined(OS_WIN) + void UpdateCleanupDataSource(bool cleanupEnabled, bool partnerPowered); + std::unique_ptr<safe_browsing::ChromeCleanerStateChangeObserver> + cleanup_observer_; +#endif + DISALLOW_COPY_AND_ASSIGN(MdSettingsUI); }; diff --git a/chromium/chrome/browser/ui/webui/settings/md_settings_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/md_settings_ui_browsertest.cc index a6da5edc656..6d48adec4d9 100644 --- a/chromium/chrome/browser/ui/webui/settings/md_settings_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/settings/md_settings_ui_browsertest.cc @@ -5,7 +5,6 @@ #include <string> #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" @@ -14,14 +13,11 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_message_handler.h" #include "content/public/common/url_constants.h" -#include "content/public/test/browser_test_utils.h" -#include "ui/base/window_open_disposition.h" #include "url/gurl.h" typedef InProcessBrowserTest MdSettingsUITest; using ui_test_utils::NavigateToURL; -using content::WaitForLoadStop; IN_PROC_BROWSER_TEST_F(MdSettingsUITest, ViewSourceDoesntCrash) { NavigateToURL(browser(), GURL(content::kViewSourceScheme + std::string(":") + @@ -29,24 +25,6 @@ IN_PROC_BROWSER_TEST_F(MdSettingsUITest, ViewSourceDoesntCrash) { std::string("strings.js"))); } -// May not complete on memory and Windows debug bots. TODO(dbeam): investigate -// and fix. See https://crbug.com/558434, https://crbug.com/620370 and -// https://crbug.com/651296. -#if defined(MEMORY_SANITIZER) || defined(OS_WIN) || defined(OS_CHROMEOS) -#define MAYBE_BackForwardDoesntCrash DISABLED_BackForwardDoesntCrash -#else -#define MAYBE_BackForwardDoesntCrash BackForwardDoesntCrash -#endif - -IN_PROC_BROWSER_TEST_F(MdSettingsUITest, MAYBE_BackForwardDoesntCrash) { - NavigateToURL(browser(), GURL(chrome::kChromeUIMdSettingsURL)); - - NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); - - chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); - WaitForLoadStop(browser()->tab_strip_model()->GetActiveWebContents()); -} - // Catch lifetime issues in message handlers. There was previously a problem // with PrefMember calling Init again after Destroy. IN_PROC_BROWSER_TEST_F(MdSettingsUITest, ToggleJavaScript) { diff --git a/chromium/chrome/browser/ui/webui/settings/md_settings_ui_unittest.cc b/chromium/chrome/browser/ui/webui/settings/md_settings_ui_unittest.cc new file mode 100644 index 00000000000..01b50410761 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/md_settings_ui_unittest.cc @@ -0,0 +1,20 @@ +// 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 "chrome/browser/ui/webui/settings/md_settings_ui.h" + +#include "chrome/common/url_constants.h" +#include "content/public/common/url_constants.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +TEST(MdSettingsUITest, IsValidOrigin) { + EXPECT_TRUE(settings::IsValidOrigin(GURL(chrome::kChromeUISettingsURL))); + EXPECT_TRUE(settings::IsValidOrigin(GURL(chrome::kChromeUIMdSettingsURL))); + + EXPECT_FALSE(settings::IsValidOrigin(GURL("http://evil.com"))); + EXPECT_FALSE(settings::IsValidOrigin(GURL("https://google.com"))); + EXPECT_FALSE(settings::IsValidOrigin(GURL(chrome::kChromeUINewTabURL))); + EXPECT_FALSE(settings::IsValidOrigin(GURL(chrome::kChromeUIHistoryURL))); +} diff --git a/chromium/chrome/browser/ui/webui/settings/on_startup_handler.cc b/chromium/chrome/browser/ui/webui/settings/on_startup_handler.cc index b42ffc85717..fe50a556468 100644 --- a/chromium/chrome/browser/ui/webui/settings/on_startup_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/on_startup_handler.cc @@ -4,12 +4,15 @@ #include "chrome/browser/ui/webui/settings/on_startup_handler.h" +#include <string> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/logging.h" #include "chrome/browser/extensions/settings_api_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/settings_utils.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/management_policy.h" @@ -17,9 +20,25 @@ namespace settings { -OnStartupHandler::OnStartupHandler() {} +// static +const char OnStartupHandler::kOnStartupNtpExtensionEventName[] = + "update-ntp-extension"; + +OnStartupHandler::OnStartupHandler(Profile* profile) + : extension_registry_observer_(this), profile_(profile) { + DCHECK(profile); +} OnStartupHandler::~OnStartupHandler() {} +void OnStartupHandler::OnJavascriptAllowed() { + extension_registry_observer_.Add( + extensions::ExtensionRegistry::Get(profile_)); +} + +void OnStartupHandler::OnJavascriptDisallowed() { + extension_registry_observer_.RemoveAll(); +} + void OnStartupHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "getNtpExtension", base::Bind(&OnStartupHandler::HandleGetNtpExtension, @@ -30,41 +49,52 @@ void OnStartupHandler::RegisterMessages() { base::Unretained(this))); } -void OnStartupHandler::HandleGetNtpExtension(const base::ListValue* args) { - const base::Value* callback_id; - CHECK(args->Get(0, &callback_id)); +void OnStartupHandler::OnExtensionUnloaded( + content::BrowserContext* browser_context, + const extensions::Extension* extension, + extensions::UnloadedExtensionReason reason) { + FireWebUIListener(kOnStartupNtpExtensionEventName, *GetNtpExtension()); +} - AllowJavascript(); +void OnStartupHandler::OnExtensionReady( + content::BrowserContext* browser_context, + const extensions::Extension* extension) { + FireWebUIListener(kOnStartupNtpExtensionEventName, *GetNtpExtension()); +} - Profile* profile = Profile::FromWebUI(web_ui()); +std::unique_ptr<base::Value> OnStartupHandler::GetNtpExtension() { const extensions::Extension* ntp_extension = - extensions::GetExtensionOverridingNewTabPage(profile); - + extensions::GetExtensionOverridingNewTabPage(profile_); if (!ntp_extension) { - ResolveJavascriptCallback(*callback_id, base::Value()); - return; + std::unique_ptr<base::Value> none(new base::Value); + return none; } - base::DictionaryValue dict; - dict.SetString("id", ntp_extension->id()); - dict.SetString("name", ntp_extension->name()); - dict.SetBoolean("canBeDisabled", - !extensions::ExtensionSystem::Get(profile) - ->management_policy() - ->MustRemainEnabled(ntp_extension, nullptr)); - ResolveJavascriptCallback(*callback_id, dict); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); + dict->SetString("id", ntp_extension->id()); + dict->SetString("name", ntp_extension->name()); + dict->SetBoolean("canBeDisabled", + !extensions::ExtensionSystem::Get(profile_) + ->management_policy() + ->MustRemainEnabled(ntp_extension, nullptr)); + return dict; } -void OnStartupHandler::HandleValidateStartupPage(const base::ListValue* args) { +void OnStartupHandler::HandleGetNtpExtension(const base::ListValue* args) { + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); AllowJavascript(); - CHECK_EQ(args->GetSize(), 2U); + ResolveJavascriptCallback(*callback_id, *GetNtpExtension()); +} +void OnStartupHandler::HandleValidateStartupPage(const base::ListValue* args) { + CHECK_EQ(args->GetSize(), 2U); const base::Value* callback_id; CHECK(args->Get(0, &callback_id)); - std::string url_string; CHECK(args->GetString(1, &url_string)); + AllowJavascript(); bool valid = settings_utils::FixupAndValidateStartupPage(url_string, nullptr); ResolveJavascriptCallback(*callback_id, base::Value(valid)); diff --git a/chromium/chrome/browser/ui/webui/settings/on_startup_handler.h b/chromium/chrome/browser/ui/webui/settings/on_startup_handler.h index 013d1d98ff8..e5438a3a851 100644 --- a/chromium/chrome/browser/ui/webui/settings/on_startup_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/on_startup_handler.h @@ -5,8 +5,15 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ON_STARTUP_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_ON_STARTUP_HANDLER_H_ +#include <memory> + #include "base/macros.h" +#include "base/scoped_observer.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_registry_observer.h" + +class Profile; namespace base { class ListValue; @@ -14,17 +21,29 @@ class ListValue; namespace settings { -class OnStartupHandler : public SettingsPageUIHandler { +class OnStartupHandler : public SettingsPageUIHandler, + public extensions::ExtensionRegistryObserver { public: - OnStartupHandler(); + static const char kOnStartupNtpExtensionEventName[]; + + explicit OnStartupHandler(Profile* profile); ~OnStartupHandler() override; // SettingsPageUIHandler: + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; void RegisterMessages() override; - void OnJavascriptAllowed() override {} - void OnJavascriptDisallowed() override {} private: + FRIEND_TEST_ALL_PREFIXES(OnStartupHandlerTest, HandleGetNtpExtension); + FRIEND_TEST_ALL_PREFIXES(OnStartupHandlerTest, + HandleValidateStartupPage_Valid); + FRIEND_TEST_ALL_PREFIXES(OnStartupHandlerTest, + HandleValidateStartupPage_Invalid); + + // Info for extension controlling the NTP or empty value. + std::unique_ptr<base::Value> GetNtpExtension(); + // Handler for the "getNtpExtension" message. No arguments. void HandleGetNtpExtension(const base::ListValue* /*args*/); @@ -32,6 +51,20 @@ class OnStartupHandler : public SettingsPageUIHandler { // valid startup page. void HandleValidateStartupPage(const base::ListValue* args); + // extensions::ExtensionRegistryObserver. + void OnExtensionUnloaded(content::BrowserContext* browser_context, + const extensions::Extension* extension, + extensions::UnloadedExtensionReason reason) override; + void OnExtensionReady(content::BrowserContext* browser_context, + const extensions::Extension* extension) override; + + // Listen to extension unloaded notifications. + ScopedObserver<extensions::ExtensionRegistry, + extensions::ExtensionRegistryObserver> + extension_registry_observer_; + + Profile* profile_; + DISALLOW_COPY_AND_ASSIGN(OnStartupHandler); }; diff --git a/chromium/chrome/browser/ui/webui/settings/on_startup_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/on_startup_handler_unittest.cc new file mode 100644 index 00000000000..380a7165905 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/on_startup_handler_unittest.cc @@ -0,0 +1,146 @@ +// 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 "chrome/browser/ui/webui/settings/on_startup_handler.h" + +#include <string> + +#include "base/macros.h" +#include "base/values.h" +#include "build/build_config.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" +#endif +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kCallbackId[] = "test-on-startup-callback-id"; + +class TestOnStartupHandler : public settings::OnStartupHandler { + public: + explicit TestOnStartupHandler(Profile* profile) + : settings::OnStartupHandler(profile) {} + + using settings::OnStartupHandler::set_web_ui; +}; + +} // namespace + +namespace settings { + +class OnStartupHandlerTest : public testing::Test { + public: + OnStartupHandlerTest() + : profile_manager_(TestingBrowserProcess::GetGlobal()), + profile_(nullptr) {} + + void SetUp() override { + ASSERT_TRUE(profile_manager_.SetUp()); + +#if defined(OS_CHROMEOS) + chromeos::FakeChromeUserManager* fake_user_manager = + new chromeos::FakeChromeUserManager; + user_manager_enabler_.reset( + new chromeos::ScopedUserManagerEnabler(fake_user_manager)); + constexpr char kFakeEmail[] = "fake_id@gmail.com"; + profile_ = profile_manager_.CreateTestingProfile(kFakeEmail); + fake_user_manager->AddUser(AccountId::FromUserEmail(kFakeEmail)); +#else + profile_ = profile_manager_.CreateTestingProfile("Profile 1"); +#endif + + handler_.reset(new TestOnStartupHandler(profile_)); + handler_->set_web_ui(&web_ui_); + } + + TestOnStartupHandler* handler() { return handler_.get(); } + Profile* profile() const { return profile_; } + content::TestWebUI* web_ui() { return &web_ui_; } + + private: + content::TestBrowserThreadBundle thread_bundle_; + TestingProfileManager profile_manager_; + std::unique_ptr<TestOnStartupHandler> handler_; + Profile* profile_; +#if defined(OS_CHROMEOS) + std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_; +#endif + content::TestWebUI web_ui_; +}; + +TEST_F(OnStartupHandlerTest, HandleGetNtpExtension) { + base::ListValue list_args; + list_args.AppendString(kCallbackId); + handler()->HandleGetNtpExtension(&list_args); + + EXPECT_EQ(1U, web_ui()->call_data().size()); + + const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIResponse", data.function_name()); + + std::string callback_id; + ASSERT_TRUE(data.arg1()->GetAsString(&callback_id)); + EXPECT_EQ(kCallbackId, callback_id); + + bool success = false; + ASSERT_TRUE(data.arg2()->GetAsBoolean(&success)); + EXPECT_TRUE(success); +} + +TEST_F(OnStartupHandlerTest, HandleValidateStartupPage_Valid) { + base::ListValue list_args; + list_args.AppendString(kCallbackId); + list_args.AppendString("http://example.com"); + handler()->HandleValidateStartupPage(&list_args); + + EXPECT_EQ(1U, web_ui()->call_data().size()); + + const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIResponse", data.function_name()); + + std::string callback_id; + ASSERT_TRUE(data.arg1()->GetAsString(&callback_id)); + EXPECT_EQ(kCallbackId, callback_id); + + bool success = false; + ASSERT_TRUE(data.arg2()->GetAsBoolean(&success)); + EXPECT_TRUE(success); + + bool is_valid = false; + ASSERT_TRUE(data.arg2()->GetAsBoolean(&is_valid)); + EXPECT_TRUE(is_valid); +} + +TEST_F(OnStartupHandlerTest, HandleValidateStartupPage_Invalid) { + base::ListValue list_args; + list_args.AppendString(kCallbackId); + list_args.AppendString("@"); + handler()->HandleValidateStartupPage(&list_args); + + EXPECT_EQ(1U, web_ui()->call_data().size()); + + const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIResponse", data.function_name()); + + std::string callback_id; + ASSERT_TRUE(data.arg1()->GetAsString(&callback_id)); + EXPECT_EQ(kCallbackId, callback_id); + + bool success = false; + ASSERT_TRUE(data.arg2()->GetAsBoolean(&success)); + EXPECT_TRUE(success); + + bool is_valid = false; + ASSERT_TRUE(data.arg3()->GetAsBoolean(&is_valid)); + EXPECT_FALSE(is_valid); +} + +} // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.cc b/chromium/chrome/browser/ui/webui/settings/people_handler.cc index 4c37c95afc8..e6a1b37ef3d 100644 --- a/chromium/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/people_handler.cc @@ -29,12 +29,14 @@ #include "chrome/browser/sync/sync_ui_util.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/webui/profile_helper.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/autofill_pref_names.h" @@ -162,6 +164,8 @@ std::string GetSyncErrorAction(sync_ui_util::ActionType action_type) { return "upgradeClient"; case sync_ui_util::ENTER_PASSPHRASE: return "enterPassphrase"; + case sync_ui_util::CONFIRM_SYNC_SETTINGS: + return "confirmSyncSettings"; default: return "noAction"; } @@ -194,6 +198,7 @@ PeopleHandler::~PeopleHandler() { } void PeopleHandler::RegisterMessages() { + InitializeSyncBlocker(); web_ui()->RegisterMessageCallback( "SyncSetupDidClosePage", base::Bind(&PeopleHandler::OnDidClosePage, base::Unretained(this))); @@ -557,7 +562,7 @@ void PeopleHandler::HandleGetSyncStatus(const base::ListValue* args) { } void PeopleHandler::HandleManageOtherPeople(const base::ListValue* /* args */) { - UserManager::Show(base::FilePath(), profiles::USER_MANAGER_NO_TUTORIAL, + UserManager::Show(base::FilePath(), profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); } @@ -623,7 +628,7 @@ void PeopleHandler::OpenSyncSetup() { GetLoginUIService()->SetLoginUI(this); ProfileSyncService* service = GetSyncService(); - if (service) + if (service && !sync_blocker_) sync_blocker_ = service->GetSetupInProgressHandle(); // There are several different UI flows that can bring the user here: @@ -684,6 +689,20 @@ void PeopleHandler::OpenSyncSetup() { PushSyncPrefs(); } +void PeopleHandler::InitializeSyncBlocker() { + if (!web_ui()) + return; + WebContents* web_contents = web_ui()->GetWebContents(); + if (web_contents) { + ProfileSyncService* service = GetSyncService(); + const GURL current_url = web_contents->GetVisibleURL(); + if (service && + current_url == chrome::GetSettingsUrl(chrome::kSyncSetupSubPage)) { + sync_blocker_ = service->GetSetupInProgressHandle(); + } + } +} + void PeopleHandler::FocusUI() { WebContents* web_contents = web_ui()->GetWebContents(); web_contents->GetDelegate()->ActivateContents(web_contents); @@ -695,8 +714,7 @@ void PeopleHandler::CloseUI() { } void PeopleHandler::GoogleSigninSucceeded(const std::string& /* account_id */, - const std::string& /* username */, - const std::string& /* password */) { + const std::string& /* username */) { UpdateSyncStatus(); } diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.h b/chromium/chrome/browser/ui/webui/settings/people_handler.h index 255967957c1..be8ab4ea3a4 100644 --- a/chromium/chrome/browser/ui/webui/settings/people_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/people_handler.h @@ -98,6 +98,8 @@ class PeopleHandler : public SettingsPageUIHandler, FRIEND_TEST_ALL_PREFIXES(PeopleHandlerNonCrosTest, SubmitAuthWithInvalidUsername); FRIEND_TEST_ALL_PREFIXES(PeopleHandlerFirstSigninTest, DisplayBasicLogin); + FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, + AcquireSyncBlockerWhenLoadingSyncSettingsSubpage); // SettingsPageUIHandler implementation. void RegisterMessages() override; @@ -113,8 +115,7 @@ class PeopleHandler : public SettingsPageUIHandler, // SigninManagerBase::Observer implementation. void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username, - const std::string& password) override; + const std::string& username) override; void GoogleSignedOut(const std::string& account_id, const std::string& username) override; @@ -175,6 +176,15 @@ class PeopleHandler : public SettingsPageUIHandler, // Suppresses any further signin promos, since the user has signed in once. void MarkFirstSetupComplete(); + // If we're directly loading the sync setup page, we acquire a + // SetupInProgressHandle early in order to prevent a lapse in + // ProfileSyncService's "SetupInProgress" status. This lapse previously + // occured between when the sync confirmation dialog was closed and when the + // sync setup page hadn't yet fired the SyncSetupShowSetupUI event. + // InitializeSyncBlocker is responsible for checking if we're navigating to + // the setup page and acquiring the sync_blocker. + void InitializeSyncBlocker(); + // Weak pointer. Profile* profile_; diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc index 45c7fc1e74e..9318aff4dd6 100644 --- a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc @@ -19,23 +19,29 @@ #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_test_util.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "chrome/common/url_constants.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/test_chrome_web_ui_controller_factory.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" -#include "chrome/test/base/testing_profile_manager.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/fake_auth_status_provider.h" #include "components/signin/core/browser/signin_manager.h" #include "components/sync/base/sync_prefs.h" #include "components/sync_preferences/pref_service_syncable.h" +#include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_controller.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_web_ui.h" +#include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/layout.h" @@ -169,36 +175,36 @@ class TestingPeopleHandler : public PeopleHandler { DISALLOW_COPY_AND_ASSIGN(TestingPeopleHandler); }; +class TestWebUIProvider + : public TestChromeWebUIControllerFactory::WebUIProvider { + public: + content::WebUIController* NewWebUI(content::WebUI* web_ui, + const GURL& url) override { + content::WebUIController* controller = new content::WebUIController(web_ui); + return controller; + } +}; + // The boolean parameter indicates whether the test is run with ClientOAuth // or not. The test parameter is a bool: whether or not to test with/ // /ClientLogin enabled or not. -class PeopleHandlerTest : public testing::Test { +class PeopleHandlerTest : public ChromeRenderViewHostTestHarness { public: PeopleHandlerTest() : error_(GoogleServiceAuthError::NONE) {} void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); error_ = GoogleServiceAuthError::AuthErrorNone(); - profile_manager_.reset( - new TestingProfileManager(TestingBrowserProcess::GetGlobal())); - ASSERT_TRUE(profile_manager_->SetUp()); - - TestingProfile::TestingFactories testing_factories; - testing_factories.push_back(std::make_pair( - SigninManagerFactory::GetInstance(), BuildFakeSigninManagerBase)); - profile_ = profile_manager_->CreateTestingProfile( - "Person 1", nullptr, base::UTF8ToUTF16("Person 1"), 0, std::string(), - testing_factories); - // Sign in the user. mock_signin_ = static_cast<SigninManagerBase*>( - SigninManagerFactory::GetForProfile(profile_)); + SigninManagerFactory::GetForProfile(profile())); std::string username = GetTestUser(); if (!username.empty()) mock_signin_->SetAuthenticatedAccountInfo(username, username); mock_pss_ = static_cast<ProfileSyncServiceMock*>( ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile_, BuildMockProfileSyncService)); + profile(), BuildMockProfileSyncService)); EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_)); ON_CALL(*mock_pss_, GetPassphraseType()) .WillByDefault(Return(syncer::PassphraseType::IMPLICIT_PASSPHRASE)); @@ -209,10 +215,17 @@ class PeopleHandlerTest : public testing::Test { mock_pss_->Initialize(); - handler_.reset(new TestingPeopleHandler(&web_ui_, profile_)); + handler_.reset(new TestingPeopleHandler(&web_ui_, profile())); handler_->AllowJavascript(); } + void TearDown() override { + handler_->set_web_ui(nullptr); + handler_->DisallowJavascript(); + handler_->sync_startup_tracker_.reset(); + ChromeRenderViewHostTestHarness::TearDown(); + } + // Setup the expectations for calls made when displaying the config page. void SetDefaultExpectationsForConfigPage() { EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); @@ -265,9 +278,9 @@ class PeopleHandlerTest : public testing::Test { // Cancelling the spinner dialog will cause CloseSyncSetup(). handler_->CloseSyncSetup(); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); } const base::DictionaryValue* ExpectSyncPrefsChanged() { @@ -297,13 +310,12 @@ class PeopleHandlerTest : public testing::Test { return std::string(kTestUser); } - content::TestBrowserThreadBundle thread_bundle_; - std::unique_ptr<TestingProfileManager> profile_manager_; - Profile* profile_; ProfileSyncServiceMock* mock_pss_; GoogleServiceAuthError error_; SigninManagerBase* mock_signin_; content::TestWebUI web_ui_; + TestWebUIProvider test_provider_; + std::unique_ptr<TestChromeWebUIControllerFactory> test_factory_; std::unique_ptr<TestingPeopleHandler> handler_; }; @@ -326,16 +338,16 @@ TEST_F(PeopleHandlerFirstSigninTest, DisplayBasicLogin) { handler_->HandleStartSignin(&list_args); // Sync setup hands off control to the gaia login tab. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); ASSERT_FALSE(handler_->is_configuring_sync()); handler_->CloseSyncSetup(); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); } TEST_F(PeopleHandlerTest, ShowSyncSetupWhenNotSignedIn) { @@ -346,9 +358,9 @@ TEST_F(PeopleHandlerTest, ShowSyncSetupWhenNotSignedIn) { ExpectPageStatusChanged(PeopleHandler::kDonePageStatus); ASSERT_FALSE(handler_->is_configuring_sync()); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); } #endif // !defined(OS_CHROMEOS) @@ -359,9 +371,9 @@ TEST_F(PeopleHandlerTest, HandleSetupUIWhenSyncDisabled) { handler_->HandleShowSetupUI(NULL); // Sync setup is closed when sync is disabled. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); ASSERT_FALSE(handler_->is_configuring_sync()); } @@ -381,9 +393,9 @@ TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) { // spinner is showing. handler_->HandleShowSetupUI(NULL); - EXPECT_EQ(handler_.get(), - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + handler_.get(), + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); ExpectSpinnerAndClose(); } @@ -446,9 +458,9 @@ TEST_F(PeopleHandlerTest, EXPECT_CALL(*mock_pss_, OnSetupInProgressHandleDestroyed()); handler_->CloseSyncSetup(); - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); } TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndSigninFailed) { @@ -467,9 +479,9 @@ TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndSigninFailed) { NotifySyncListeners(); // On failure, the dialog will be closed. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); } // Tests that signals not related to user intention to configure sync don't @@ -480,6 +492,27 @@ TEST_F(PeopleHandlerTest, OnlyStartEngineWhenConfiguringSync) { NotifySyncStateChanged(); } +TEST_F(PeopleHandlerTest, AcquireSyncBlockerWhenLoadingSyncSettingsSubpage) { + /// We set up a factory override here to prevent a new web ui from being + /// created when we navigate to a page that would normally create one. + web_ui_.set_web_contents(web_contents()); + test_factory_ = base::MakeUnique<TestChromeWebUIControllerFactory>(); + test_factory_->AddFactoryOverride( + chrome::GetSettingsUrl(chrome::kSyncSetupSubPage).host(), + &test_provider_); + content::WebUIControllerFactory::RegisterFactory(test_factory_.get()); + content::WebUIControllerFactory::UnregisterFactoryForTesting( + ChromeWebUIControllerFactory::GetInstance()); + + EXPECT_FALSE(handler_->sync_blocker_); + + content::WebContentsTester::For(web_contents()) + ->StartNavigation(chrome::GetSettingsUrl(chrome::kSyncSetupSubPage)); + handler_->InitializeSyncBlocker(); + + EXPECT_TRUE(handler_->sync_blocker_); +} + #if !defined(OS_CHROMEOS) class PeopleHandlerNonCrosTest : public PeopleHandlerTest { @@ -726,7 +759,7 @@ TEST_F(PeopleHandlerTest, ShowSigninOnAuthError) { SetupInitializedProfileSyncService(); mock_signin_->SetAuthenticatedAccountInfo(kTestUser, kTestUser); FakeAuthStatusProvider provider( - SigninErrorControllerFactory::GetForProfile(profile_)); + SigninErrorControllerFactory::GetForProfile(profile())); provider.SetAuthError(kTestUser, error_); EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true)); EXPECT_CALL(*mock_pss_, IsPassphraseRequired()) @@ -741,8 +774,9 @@ TEST_F(PeopleHandlerTest, ShowSigninOnAuthError) { // happen if the user manually navigates to chrome://settings/syncSetup - // clicking on the button in the UI will sign the user out rather than // displaying a spinner. Should be no visible UI on ChromeOS in this case. - EXPECT_EQ(NULL, LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); #else // On ChromeOS, this should display the spinner while we try to startup the @@ -750,9 +784,9 @@ TEST_F(PeopleHandlerTest, ShowSigninOnAuthError) { handler_->OpenSyncSetup(); // Sync setup is closed when re-auth is in progress. - EXPECT_EQ(NULL, - LoginUIServiceFactory::GetForProfile( - profile_)->current_login_ui()); + EXPECT_EQ( + NULL, + LoginUIServiceFactory::GetForProfile(profile())->current_login_ui()); ASSERT_FALSE(handler_->is_configuring_sync()); #endif @@ -792,7 +826,7 @@ TEST_F(PeopleHandlerTest, ShowSetupManuallySyncAll) { EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) .WillRepeatedly(Return(false)); SetupInitializedProfileSyncService(); - syncer::SyncPrefs sync_prefs(profile_->GetPrefs()); + syncer::SyncPrefs sync_prefs(profile()->GetPrefs()); sync_prefs.SetKeepEverythingSynced(false); SetDefaultExpectationsForConfigPage(); // This should display the sync setup dialog (not login). @@ -811,7 +845,7 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) { EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase()) .WillRepeatedly(Return(false)); SetupInitializedProfileSyncService(); - syncer::SyncPrefs sync_prefs(profile_->GetPrefs()); + syncer::SyncPrefs sync_prefs(profile()->GetPrefs()); sync_prefs.SetKeepEverythingSynced(false); SetDefaultExpectationsForConfigPage(); syncer::ModelTypeSet types; @@ -823,7 +857,7 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) { handler_->OpenSyncSetup(); // Close the config overlay. - LoginUIServiceFactory::GetForProfile(profile_)->LoginUIClosed( + LoginUIServiceFactory::GetForProfile(profile())->LoginUIClosed( handler_.get()); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); diff --git a/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc index bac2e490ef5..304be428702 100644 --- a/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc @@ -17,7 +17,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/ui/webui/options/chromeos/user_image_source.h" +#include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "components/signin/core/account_id/account_id.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/notification_service.h" @@ -48,8 +48,7 @@ ProfileInfoHandler::ProfileInfoHandler(Profile* profile) callback_weak_ptr_factory_(this) { #if defined(OS_CHROMEOS) // Set up the chrome://userimage/ source. - content::URLDataSource::Add(profile, - new chromeos::options::UserImageSource()); + content::URLDataSource::Add(profile, new chromeos::UserImageSource()); #endif } @@ -131,9 +130,6 @@ void ProfileInfoHandler::HandleGetProfileInfo(const base::ListValue* args) { void ProfileInfoHandler::HandleGetProfileStats(const base::ListValue* args) { AllowJavascript(); - // Because there is open browser window for the current profile, statistics - // from the ProfileAttributesStorage may not be up-to-date or may be missing - // (e.g., |item.success| is false). Therefore, query the actual statistics. ProfileStatisticsFactory::GetForProfile(profile_)->GatherStatistics( base::Bind(&ProfileInfoHandler::PushProfileStatsCount, callback_weak_ptr_factory_.GetWeakPtr())); @@ -143,11 +139,6 @@ void ProfileInfoHandler::PushProfileStatsCount( profiles::ProfileCategoryStats stats) { int count = 0; for (const auto& item : stats) { - std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); - if (!item.success) { - count = 0; - break; - } count += item.count; } // PushProfileStatsCount gets invoked multiple times as each stat becomes @@ -194,7 +185,7 @@ ProfileInfoHandler::GetAccountNameAndIcon() const { // Get image as data URL instead of using chrome://userimage source to avoid // issues with caching. scoped_refptr<base::RefCountedMemory> image = - chromeos::options::UserImageSource::GetUserImage(user->GetAccountId()); + chromeos::UserImageSource::GetUserImage(user->GetAccountId()); icon_url = webui::GetPngDataUrl(image->front(), image->size()); #else // !defined(OS_CHROMEOS) ProfileAttributesEntry* entry; @@ -212,10 +203,10 @@ ProfileInfoHandler::GetAccountNameAndIcon() const { } #endif // defined(OS_CHROMEOS) - base::DictionaryValue* response = new base::DictionaryValue(); + auto response = base::MakeUnique<base::DictionaryValue>(); response->SetString("name", name); response->SetString("iconUrl", icon_url); - return base::WrapUnique(response); + return response; } bool ProfileInfoHandler::IsProfileManagingSupervisedUsers() const { diff --git a/chromium/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chromium/chrome/browser/ui/webui/settings/search_engines_handler.cc index 31be170b319..d41832aa15b 100644 --- a/chromium/chrome/browser/ui/webui/settings/search_engines_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/search_engines_handler.cc @@ -187,10 +187,9 @@ SearchEnginesHandler::GetSearchEnginesList() { std::unique_ptr<base::DictionaryValue> search_engines_info( new base::DictionaryValue); - search_engines_info->Set("defaults", base::WrapUnique(defaults.release())); - search_engines_info->Set("others", base::WrapUnique(others.release())); - search_engines_info->Set("extensions", - base::WrapUnique(extensions.release())); + search_engines_info->Set("defaults", std::move(defaults)); + search_engines_info->Set("others", std::move(others)); + search_engines_info->Set("extensions", std::move(extensions)); return search_engines_info; } diff --git a/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc index a29576c7926..a0a37b8a34f 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc @@ -27,8 +27,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/common/pref_names.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui.h" diff --git a/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc index 5c9142f2fbb..4b128752b02 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc @@ -174,7 +174,8 @@ void StartupPagesHandler::HandleRemoveStartupPage(const base::ListValue* args) { void StartupPagesHandler::HandleSetStartupPagesToCurrentPages( const base::ListValue* args) { - startup_custom_pages_table_model_.SetToCurrentlyOpenPages(); + startup_custom_pages_table_model_.SetToCurrentlyOpenPages( + web_ui()->GetWebContents()); SaveStartupPagesPref(); } diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc index 8d1981cadf5..0ecdfb29705 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc @@ -18,14 +18,18 @@ #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/content_settings/web_site_settings_uma_util.h" #include "chrome/browser/permissions/chooser_context_base.h" +#include "chrome/browser/permissions/permission_manager.h" +#include "chrome/browser/permissions/permission_result.h" #include "chrome/browser/permissions/permission_uma_util.h" #include "chrome/browser/permissions/permission_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/site_settings_helper.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/grit/generated_resources.h" +#include "components/content_settings/core/browser/content_settings_utils.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_types.h" +#include "components/content_settings/core/common/content_settings_utils.h" #include "components/crx_file/id_util.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" @@ -99,6 +103,89 @@ void AddExceptionsGrantedByHostedApps(content::BrowserContext* context, } } +// Retrieves the corresponding string, according to the following precedence +// order from highest to lowest priority: +// 1. Kill-switch. +// 2. Enterprise policy. +// 3. Extensions. +// 4. User-set per-origin setting. +// 5. Embargo. +// 6. User-set patterns. +// 7. User-set global default for a ContentSettingsType. +// 8. Chrome's built-in default. +std::string ConvertContentSettingSourceToString( + const content_settings::SettingInfo& info, + PermissionStatusSource permission_status_source) { + // TODO(patricialor): Do some plumbing for sources #1, #2, #3, and #5 through + // to the Web UI. Currently there aren't strings to represent these sources. + if (permission_status_source == PermissionStatusSource::KILL_SWITCH) + return site_settings::kPreferencesSource; // Source #1. + + if (info.source == content_settings::SETTING_SOURCE_POLICY || + info.source == content_settings::SETTING_SOURCE_SUPERVISED) { + return site_settings::kPolicyProviderId; // Source #2. + } + + if (info.source == content_settings::SETTING_SOURCE_EXTENSION) + return site_settings::kExtensionProviderId; // Source #3. + + DCHECK_NE(content_settings::SETTING_SOURCE_NONE, info.source); + if (info.source == content_settings::SETTING_SOURCE_USER) { + if (permission_status_source == + PermissionStatusSource::SAFE_BROWSING_BLACKLIST || + permission_status_source == + PermissionStatusSource::MULTIPLE_DISMISSALS || + permission_status_source == PermissionStatusSource::MULTIPLE_IGNORES) { + return site_settings::kPreferencesSource; // Source #5. + } + if (info.primary_pattern == ContentSettingsPattern::Wildcard() && + info.secondary_pattern == ContentSettingsPattern::Wildcard()) { + return "default"; // Source #7, #8. + } + // Source #4, #6. When #4 is the source, |permission_status_source| + // won't be set to any of the source #5 enum values, as PermissionManager is + // aware of the difference between these two sources internally. The + // subtlety here should go away when PermissionManager can handle all + // content settings and all possible sources. + return site_settings::kPreferencesSource; + } + + NOTREACHED(); + return site_settings::kPreferencesSource; +} + +ContentSetting GetContentSettingForOrigin(const GURL& origin, + ContentSettingsType content_type, + Profile* profile, + std::string* source_string) { + // TODO(patricialor): In future, PermissionManager should know about all + // content settings, not just the permissions, plus all the possible sources, + // and the calls to HostContentSettingsMap should be removed. + content_settings::SettingInfo info; + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(profile); + std::unique_ptr<base::Value> value = map->GetWebsiteSetting( + origin, origin, content_type, std::string(), &info); + + // Retrieve the content setting. + PermissionResult result(CONTENT_SETTING_DEFAULT, + PermissionStatusSource::UNSPECIFIED); + if (PermissionUtil::IsPermission(content_type)) { + result = PermissionManager::Get(profile)->GetPermissionStatus( + content_type, origin, origin); + } else { + DCHECK(value.get()); + DCHECK_EQ(base::Value::Type::INTEGER, value->GetType()); + result.content_setting = + content_settings::ValueToContentSetting(value.get()); + } + + // Retrieve the source of the content setting. + *source_string = ConvertContentSettingSourceToString(info, result.source); + + return result.content_setting; +} + } // namespace @@ -139,6 +226,10 @@ void SiteSettingsHandler::RegisterMessages() { base::Bind(&SiteSettingsHandler::HandleGetExceptionList, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "getOriginPermissions", + base::Bind(&SiteSettingsHandler::HandleGetOriginPermissions, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "resetCategoryPermissionForOrigin", base::Bind(&SiteSettingsHandler::HandleResetCategoryPermissionForOrigin, base::Unretained(this))); @@ -147,10 +238,6 @@ void SiteSettingsHandler::RegisterMessages() { base::Bind(&SiteSettingsHandler::HandleSetCategoryPermissionForOrigin, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "getSiteDetails", - base::Bind(&SiteSettingsHandler::HandleGetSiteDetails, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( "isPatternValid", base::Bind(&SiteSettingsHandler::HandleIsPatternValid, base::Unretained(this))); @@ -391,8 +478,7 @@ void SiteSettingsHandler::HandleSetDefaultValueForContentType( HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile); map->SetDefaultContentSetting( - static_cast<ContentSettingsType>(static_cast<int>( - site_settings::ContentSettingsTypeFromGroupName(content_type))), + site_settings::ContentSettingsTypeFromGroupName(content_type), default_setting); } @@ -407,8 +493,7 @@ void SiteSettingsHandler::HandleGetDefaultValueForContentType( CHECK(args->GetString(1, &type)); ContentSettingsType content_type = - static_cast<ContentSettingsType>(static_cast<int>( - site_settings::ContentSettingsTypeFromGroupName(type))); + site_settings::ContentSettingsTypeFromGroupName(type); HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile_); @@ -426,8 +511,7 @@ void SiteSettingsHandler::HandleGetExceptionList(const base::ListValue* args) { std::string type; CHECK(args->GetString(1, &type)); ContentSettingsType content_type = - static_cast<ContentSettingsType>(static_cast<int>( - site_settings::ContentSettingsTypeFromGroupName(type))); + site_settings::ContentSettingsTypeFromGroupName(type); std::unique_ptr<base::ListValue> exceptions(new base::ListValue); @@ -456,6 +540,48 @@ void SiteSettingsHandler::HandleGetExceptionList(const base::ListValue* args) { ResolveJavascriptCallback(*callback_id, *exceptions.get()); } +void SiteSettingsHandler::HandleGetOriginPermissions( + const base::ListValue* args) { + AllowJavascript(); + + CHECK_EQ(3U, args->GetSize()); + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); + std::string origin; + CHECK(args->GetString(1, &origin)); + const base::ListValue* types; + CHECK(args->GetList(2, &types)); + + // Note: Invalid URLs will just result in default settings being shown. + const GURL origin_url(origin); + auto exceptions = base::MakeUnique<base::ListValue>(); + for (size_t i = 0; i < types->GetSize(); ++i) { + std::string type; + types->GetString(i, &type); + ContentSettingsType content_type = + site_settings::ContentSettingsTypeFromGroupName(type); + + std::string source_string; + ContentSetting content_setting = GetContentSettingForOrigin( + origin_url, content_type, profile_, &source_string); + std::string content_setting_string = + content_settings::ContentSettingToString(content_setting); + + auto raw_site_exception = base::MakeUnique<base::DictionaryValue>(); + raw_site_exception->SetString(site_settings::kEmbeddingOrigin, origin); + raw_site_exception->SetBoolean(site_settings::kIncognito, + profile_->IsOffTheRecord()); + raw_site_exception->SetString(site_settings::kOrigin, origin); + raw_site_exception->SetString(site_settings::kDisplayName, origin); + raw_site_exception->SetString(site_settings::kSetting, + content_setting_string); + raw_site_exception->SetString(site_settings::kSource, source_string); + exceptions->Append(std::move(raw_site_exception)); + } + + ResolveJavascriptCallback(*callback_id, *exceptions); +} + void SiteSettingsHandler::HandleResetCategoryPermissionForOrigin( const base::ListValue* args) { CHECK_EQ(4U, args->GetSize()); @@ -469,8 +595,7 @@ void SiteSettingsHandler::HandleResetCategoryPermissionForOrigin( CHECK(args->GetBoolean(3, &incognito)); ContentSettingsType content_type = - static_cast<ContentSettingsType>(static_cast<int>( - site_settings::ContentSettingsTypeFromGroupName(type))); + site_settings::ContentSettingsTypeFromGroupName(type); Profile* profile = nullptr; if (incognito) { @@ -517,8 +642,7 @@ void SiteSettingsHandler::HandleSetCategoryPermissionForOrigin( CHECK(args->GetBoolean(4, &incognito)); ContentSettingsType content_type = - static_cast<ContentSettingsType>(static_cast<int>( - site_settings::ContentSettingsTypeFromGroupName(type))); + site_settings::ContentSettingsTypeFromGroupName(type); ContentSetting setting; CHECK(content_settings::ContentSettingFromString(value, &setting)); @@ -551,69 +675,6 @@ void SiteSettingsHandler::HandleSetCategoryPermissionForOrigin( WebSiteSettingsUmaUtil::LogPermissionChange(content_type, setting); } -void SiteSettingsHandler::HandleGetSiteDetails( - const base::ListValue* args) { - AllowJavascript(); - - CHECK_EQ(2U, args->GetSize()); - const base::Value* callback_id; - CHECK(args->Get(0, &callback_id)); - std::string site; - CHECK(args->GetString(1, &site)); - - // A subset of the ContentSettingsType enum that we show in the settings UI. - const ContentSettingsType kSettingsDetailTypes[] = { - CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTINGS_TYPE_IMAGES, - CONTENT_SETTINGS_TYPE_JAVASCRIPT, - CONTENT_SETTINGS_TYPE_PLUGINS, - CONTENT_SETTINGS_TYPE_POPUPS, - CONTENT_SETTINGS_TYPE_GEOLOCATION, - CONTENT_SETTINGS_TYPE_NOTIFICATIONS, - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, - CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, - CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, - CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, - CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, - CONTENT_SETTINGS_TYPE_USB_CHOOSER_DATA, - CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, - }; - - // Create a list to be consistent with existing API, we are expecting a single - // element (or none). - std::unique_ptr<base::ListValue> exceptions(new base::ListValue); - for (size_t type = 0; type < arraysize(kSettingsDetailTypes); ++type) { - ContentSettingsType content_type = kSettingsDetailTypes[type]; - - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile_); - const auto* extension_registry = - extensions::ExtensionRegistry::Get(profile_); - site_settings::GetExceptionsFromHostContentSettingsMap( - map, content_type, extension_registry, web_ui(), /*incognito=*/false, - /*filter=*/&site, exceptions.get()); - - if (profile_->HasOffTheRecordProfile()) { - Profile* incognito = profile_->GetOffTheRecordProfile(); - map = HostContentSettingsMapFactory::GetForProfile(incognito); - extension_registry = extensions::ExtensionRegistry::Get(incognito); - site_settings::GetExceptionsFromHostContentSettingsMap( - map, content_type, extension_registry, web_ui(), /*incognito=*/true, - /*filter=*/&site, exceptions.get()); - } - } - - if (!exceptions->GetSize()) { - RejectJavascriptCallback(*callback_id, base::Value()); - return; - } - - // We only need a single response element. - const base::DictionaryValue* exception = nullptr; - exceptions->GetDictionary(0, &exception); - ResolveJavascriptCallback(*callback_id, *exception); -} - void SiteSettingsHandler::HandleIsPatternValid( const base::ListValue* args) { CHECK_EQ(2U, args->GetSize()); diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h index 443da67359c..e735dd71fe6 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h @@ -59,6 +59,7 @@ class SiteSettingsHandler : public SettingsPageUIHandler, private: friend class SiteSettingsHandlerTest; + FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, DefaultSettingSource); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetDefault); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, Origins); FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExceptionHelpers); @@ -86,12 +87,13 @@ class SiteSettingsHandler : public SettingsPageUIHandler, // Returns the list of site exceptions for a given content settings type. void HandleGetExceptionList(const base::ListValue* args); - // Handles setting and resetting of an origin permission. + // Handles setting and resetting an origin permission. void HandleResetCategoryPermissionForOrigin(const base::ListValue* args); void HandleSetCategoryPermissionForOrigin(const base::ListValue* args); - // Return site exceptions for a single site. - void HandleGetSiteDetails(const base::ListValue* args); + // Retrieves the content settings for a given list of ContentSettingTypes for + // an origin. + void HandleGetOriginPermissions(const base::ListValue* args); // Returns whether a given pattern is valid. void HandleIsPatternValid(const base::ListValue* args); diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 53be2fd2283..2d843114943 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc @@ -8,10 +8,14 @@ #include "base/test/histogram_tester.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/ui/webui/site_settings_helper.h" #include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_ui_data_source.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -34,6 +38,40 @@ const char kSource[] = "source"; namespace settings { +// Helper class for setting ContentSettings via different sources. +class ContentSettingSourceSetter { + public: + ContentSettingSourceSetter(TestingProfile* profile, + ContentSettingsType content_type) + : prefs_(profile->GetTestingPrefService()), + host_content_settings_map_( + HostContentSettingsMapFactory::GetForProfile(profile)), + content_type_(content_type) {} + + void SetPolicyDefault(ContentSetting setting) { + prefs_->SetManagedPref(GetPrefNameForDefaultPermissionSetting(), + base::MakeUnique<base::Value>(setting)); + } + + const char* GetPrefNameForDefaultPermissionSetting() { + switch (content_type_) { + case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: + return prefs::kManagedDefaultNotificationsSetting; + default: + // Add support as needed. + NOTREACHED(); + return ""; + } + } + + private: + sync_preferences::TestingPrefServiceSyncable* prefs_; + HostContentSettingsMap* host_content_settings_map_; + ContentSettingsType content_type_; + + DISALLOW_COPY_AND_ASSIGN(ContentSettingSourceSetter); +}; + class SiteSettingsHandlerTest : public testing::Test { public: SiteSettingsHandlerTest() : handler_(&profile_) { @@ -50,7 +88,7 @@ class SiteSettingsHandlerTest : public testing::Test { web_ui()->ClearTrackedCalls(); } - Profile* profile() { return &profile_; } + TestingProfile* profile() { return &profile_; } content::TestWebUI* web_ui() { return &web_ui_; } SiteSettingsHandler* handler() { return &handler_; } @@ -232,22 +270,22 @@ class SiteSettingsHandlerTest : public testing::Test { TEST_F(SiteSettingsHandlerTest, GetAndSetDefault) { // Test the JS -> C++ -> JS callback path for getting and setting defaults. - base::ListValue getArgs; - getArgs.AppendString(kCallbackId); - getArgs.AppendString("notifications"); - handler()->HandleGetDefaultValueForContentType(&getArgs); + base::ListValue get_args; + get_args.AppendString(kCallbackId); + get_args.AppendString("notifications"); + handler()->HandleGetDefaultValueForContentType(&get_args); ValidateDefault("ask", "default", 1U); // Set the default to 'Blocked'. - base::ListValue setArgs; - setArgs.AppendString("notifications"); - setArgs.AppendString("block"); - handler()->HandleSetDefaultValueForContentType(&setArgs); + base::ListValue set_args; + set_args.AppendString("notifications"); + set_args.AppendString("block"); + handler()->HandleSetDefaultValueForContentType(&set_args); EXPECT_EQ(2U, web_ui()->call_data().size()); // Verify that the default has been set to 'Blocked'. - handler()->HandleGetDefaultValueForContentType(&getArgs); + handler()->HandleGetDefaultValueForContentType(&get_args); ValidateDefault("block", "default", 3U); } @@ -272,13 +310,27 @@ TEST_F(SiteSettingsHandlerTest, Origins) { histograms.ExpectTotalCount(kUmaBase + ".Reset", 0); } - // Verify the change was successful. - base::ListValue listArgs; - listArgs.AppendString(kCallbackId); - listArgs.AppendString("notifications"); - handler()->HandleGetExceptionList(&listArgs); + // If the change was successful, it should show up in the response from + // getExceptionList() as well as getOriginPermissions(). + // Check getOriginPermissions(). + base::ListValue get_origin_permissions_args; + get_origin_permissions_args.AppendString(kCallbackId); + get_origin_permissions_args.AppendString(google); + { + auto category_list = base::MakeUnique<base::ListValue>(); + category_list->AppendString("notifications"); + get_origin_permissions_args.Append(std::move(category_list)); + } + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); ValidateOrigin(google, google, google, "block", "preference", 2U); + // Check getExceptionList(). + base::ListValue get_exception_list_args; + get_exception_list_args.AppendString(kCallbackId); + get_exception_list_args.AppendString("notifications"); + handler()->HandleGetExceptionList(&get_exception_list_args); + ValidateOrigin(google, google, google, "block", "preference", 3U); + { // Reset things back to how they were. base::ListValue reset_args; @@ -288,7 +340,7 @@ TEST_F(SiteSettingsHandlerTest, Origins) { reset_args.AppendBoolean(false); // Incognito. base::HistogramTester histograms; handler()->HandleResetCategoryPermissionForOrigin(&reset_args); - EXPECT_EQ(3U, web_ui()->call_data().size()); + EXPECT_EQ(4U, web_ui()->call_data().size()); histograms.ExpectTotalCount(kUmaBase, 1); histograms.ExpectTotalCount(kUmaBase + ".Allowed", 0); histograms.ExpectTotalCount(kUmaBase + ".Blocked", 0); @@ -296,8 +348,66 @@ TEST_F(SiteSettingsHandlerTest, Origins) { } // Verify the reset was successful. - handler()->HandleGetExceptionList(&listArgs); - ValidateNoOrigin(4U); + handler()->HandleGetExceptionList(&get_exception_list_args); + ValidateNoOrigin(5U); + + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); + // "Ask" is the default value for Notifications. + ValidateOrigin(google, google, google, "ask", "default", 6U); +} + +TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) { + const std::string google("https://www.google.com"); + ContentSettingSourceSetter source_setter(profile(), + CONTENT_SETTINGS_TYPE_NOTIFICATIONS); + + base::ListValue get_origin_permissions_args; + get_origin_permissions_args.AppendString(kCallbackId); + get_origin_permissions_args.AppendString(google); + auto category_list = base::MakeUnique<base::ListValue>(); + category_list->AppendString("notifications"); + get_origin_permissions_args.Append(std::move(category_list)); + + // Test Chrome built-in defaults are marked as default. + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); + ValidateOrigin(google, google, google, "ask", "default", 1U); + + base::ListValue default_value_args; + default_value_args.AppendString("notifications"); + default_value_args.AppendString("block"); + handler()->HandleSetDefaultValueForContentType(&default_value_args); + // A user-set global default should also show up as default. + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); + ValidateOrigin(google, google, google, "block", "default", 3U); + + base::ListValue set_notification_pattern_args; + set_notification_pattern_args.AppendString("[*.]google.com"); + set_notification_pattern_args.AppendString("*"); + set_notification_pattern_args.AppendString("notifications"); + set_notification_pattern_args.AppendString("allow"); + set_notification_pattern_args.AppendBoolean(false); + handler()->HandleSetCategoryPermissionForOrigin( + &set_notification_pattern_args); + // A user-set pattern should not show up as default. + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); + ValidateOrigin(google, google, google, "allow", "preference", 5U); + + base::ListValue set_notification_origin_args; + set_notification_origin_args.AppendString(google); + set_notification_origin_args.AppendString(google); + set_notification_origin_args.AppendString("notifications"); + set_notification_origin_args.AppendString("block"); + set_notification_origin_args.AppendBoolean(false); + handler()->HandleSetCategoryPermissionForOrigin( + &set_notification_origin_args); + // A user-set per-origin permission should not show up as default. + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); + ValidateOrigin(google, google, google, "block", "preference", 7U); + + // Enterprise-policy set defaults should not show up as default. + source_setter.SetPolicyDefault(CONTENT_SETTING_ALLOW); + handler()->HandleGetOriginPermissions(&get_origin_permissions_args); + ValidateOrigin(google, google, google, "allow", "policy", 8U); } TEST_F(SiteSettingsHandlerTest, ExceptionHelpers) { diff --git a/chromium/chrome/browser/ui/webui/settings_utils.cc b/chromium/chrome/browser/ui/webui/settings_utils.cc index 687fe4ad4c4..4347b446a88 100644 --- a/chromium/chrome/browser/ui/webui/settings_utils.cc +++ b/chromium/chrome/browser/ui/webui/settings_utils.cc @@ -8,6 +8,7 @@ #include "chrome/grit/theme_resources.h" #include "components/url_formatter/url_fixer.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/font_list.h" #include "url/gurl.h" namespace settings_utils { @@ -26,4 +27,16 @@ base::RefCountedMemory* GetFaviconResourceBytes(ui::ScaleFactor scale_factor) { IDR_SETTINGS_FAVICON, scale_factor); } +std::string ResolveFontList(const std::string& font_name_or_list) { + if (!font_name_or_list.empty() && font_name_or_list[0] == ',') + return gfx::FontList::FirstAvailableOrFirst(font_name_or_list); + return font_name_or_list; +} + +#if !defined(OS_WIN) +std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list) { + return ResolveFontList(font_name_or_list); +} +#endif + } // namespace settings_utils diff --git a/chromium/chrome/browser/ui/webui/settings_utils.h b/chromium/chrome/browser/ui/webui/settings_utils.h index c32310e6800..d0f82b4a1fa 100644 --- a/chromium/chrome/browser/ui/webui/settings_utils.h +++ b/chromium/chrome/browser/ui/webui/settings_utils.h @@ -11,6 +11,7 @@ #include "ui/base/resource/scale_factor.h" class GURL; +class PrefService; namespace base { class RefCountedMemory; @@ -20,6 +21,7 @@ namespace content { class WebContents; } +// Chrome settings utility methods. namespace settings_utils { // Invoke UI for network proxy settings. @@ -35,6 +37,23 @@ bool FixupAndValidateStartupPage(const std::string& url_string, base::RefCountedMemory* GetFaviconResourceBytes(ui::ScaleFactor scale_factor); +#if defined(OS_MACOSX) +void ValidateSavedFonts(PrefService* prefs); +#endif + +// When |font_name_or_list| starts with ",", it is a list of font names +// separated by "," and this function returns the first available font name. +// Otherwise returns |font_name_or_list| as is. +// Unlike gfx::FontList, this function picks one font, and character-level +// fallback is handled in CSS. +std::string ResolveFontList(const std::string& font_name_or_list); + +// Returns the localized name of a font so that settings can find it within +// the list of system fonts. On Windows, the list of system fonts has names +// only for the system locale, but the pref value may be in the English name. +// For example, "MS Gothic" becomes "ï¼ï¼³ ゴシック" on localized Windows. +std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list); + } // namespace settings_utils #endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_UTILS_H_ diff --git a/chromium/chrome/browser/ui/webui/settings_utils_linux.cc b/chromium/chrome/browser/ui/webui/settings_utils_linux.cc index f72fa4d93f5..26a72ee7a76 100644 --- a/chromium/chrome/browser/ui/webui/settings_utils_linux.cc +++ b/chromium/chrome/browser/ui/webui/settings_utils_linux.cc @@ -11,6 +11,8 @@ #include "base/files/file_util.h" #include "base/nix/xdg_util.h" #include "base/process/launch.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/tab_contents/tab_util.h" #include "content/public/browser/browser_thread.h" @@ -39,7 +41,7 @@ const char* const kKDE5ProxyConfigCommand[] = {"kcmshell5", "proxy", nullptr}; // The URL for Linux proxy configuration help when not running under a // supported desktop environment. -const char kLinuxProxyConfigUrl[] = "about:linux-proxy-config"; +constexpr char kLinuxProxyConfigUrl[] = "about:linux-proxy-config"; // Show the proxy config URL in the given tab. void ShowLinuxProxyConfigUrl(int render_process_id, int render_view_id) { @@ -60,7 +62,7 @@ void ShowLinuxProxyConfigUrl(int render_process_id, int render_view_id) { // Start the given proxy configuration utility. bool StartProxyConfigUtil(const char* const command[]) { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); // base::LaunchProcess() returns true ("success") if the fork() // succeeds, but not necessarily the exec(). We'd like to be able to // use StartProxyConfigUtil() to search possible options and stop on @@ -86,7 +88,7 @@ bool StartProxyConfigUtil(const char* const command[]) { // failure to do so, show the Linux proxy config URL in a new tab instead. void DetectAndStartProxyConfigUtil(int render_process_id, int render_view_id) { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); std::unique_ptr<base::Environment> env(base::Environment::Create()); bool launched = false; @@ -135,8 +137,8 @@ void DetectAndStartProxyConfigUtil(int render_process_id, namespace settings_utils { void ShowNetworkProxySettings(content::WebContents* web_contents) { - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + base::PostTaskWithTraits( + FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, base::BindOnce(&DetectAndStartProxyConfigUtil, web_contents->GetRenderProcessHost()->GetID(), web_contents->GetRenderViewHost()->GetRoutingID())); diff --git a/chromium/chrome/browser/ui/webui/settings_utils_mac.mm b/chromium/chrome/browser/ui/webui/settings_utils_mac.mm index 1f68f49dae7..0611e978343 100644 --- a/chromium/chrome/browser/ui/webui/settings_utils_mac.mm +++ b/chromium/chrome/browser/ui/webui/settings_utils_mac.mm @@ -9,6 +9,28 @@ #include "base/logging.h" #include "base/mac/mac_logging.h" #include "base/mac/scoped_aedesc.h" +#include "base/mac/scoped_nsautorelease_pool.h" +#include "base/strings/sys_string_conversions.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" + +namespace { +void ValidateFontFamily(PrefService* prefs, const char* family_pref_name) { + // The native font settings dialog saved fonts by the font name, rather + // than the family name. This worked for the old dialog since + // -[NSFont fontWithName:size] accepted a font or family name, but the + // behavior was technically wrong. Since we really need the family name for + // the webui settings window, we will fix the saved preference if necessary. + NSString* family_name = + base::SysUTF8ToNSString(prefs->GetString(family_pref_name)); + NSFont* font = [NSFont fontWithName:family_name size:[NSFont systemFontSize]]; + if (font && + [[font familyName] caseInsensitiveCompare:family_name] != NSOrderedSame) { + std::string new_family_name = base::SysNSStringToUTF8([font familyName]); + prefs->SetString(family_pref_name, new_family_name); + } +} +} // namespace namespace settings_utils { @@ -41,4 +63,10 @@ void ShowManageSSLCertificates(content::WebContents* web_contents) { launchIdentifier:nil]; } +void ValidateSavedFonts(PrefService* prefs) { + ValidateFontFamily(prefs, prefs::kWebKitSerifFontFamily); + ValidateFontFamily(prefs, prefs::kWebKitSansSerifFontFamily); + ValidateFontFamily(prefs, prefs::kWebKitFixedFontFamily); +} + } // namespace settings_utils diff --git a/chromium/chrome/browser/ui/webui/settings_utils_win.cc b/chromium/chrome/browser/ui/webui/settings_utils_win.cc index 8380d43ef0e..7badcf5a77c 100644 --- a/chromium/chrome/browser/ui/webui/settings_utils_win.cc +++ b/chromium/chrome/browser/ui/webui/settings_utils_win.cc @@ -5,7 +5,6 @@ #include "chrome/browser/ui/webui/settings_utils.h" #include <windows.h> -#include <cryptuiapi.h> #include <shellapi.h> #include "base/bind.h" @@ -14,16 +13,17 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/single_thread_task_runner.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" -#include "content/public/browser/browser_thread.h" +#include "chrome/browser/ui/cryptuiapi_shim.h" #include "content/public/browser/web_contents.h" +#include "ui/gfx/font.h" +#include "ui/gfx/platform_font_win.h" #include "ui/shell_dialogs/base_shell_dialog_win.h" #include "ui/views/win/hwnd_util.h" -using content::BrowserThread; - namespace settings_utils { namespace { @@ -96,10 +96,9 @@ void OpenConnectionDialogCallback() { } void ShowNetworkProxySettings(content::WebContents* web_contents) { - DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::FILE)); - BrowserThread::PostTask(BrowserThread::FILE, - FROM_HERE, - base::Bind(&OpenConnectionDialogCallback)); + base::PostTaskWithTraits(FROM_HERE, + {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, + base::Bind(&OpenConnectionDialogCallback)); } void ShowManageSSLCertificates(content::WebContents* web_contents) { @@ -112,4 +111,13 @@ void ShowManageSSLCertificates(content::WebContents* web_contents) { base::Bind(&base::DeletePointer<ManageCertificatesDialog>, dialog)); } +std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list) { + std::string font_name = ResolveFontList(font_name_or_list); + if (font_name.empty()) + return font_name; + gfx::Font font(font_name, 12); // dummy font size + return static_cast<gfx::PlatformFontWin*>(font.platform_font()) + ->GetLocalizedFontName(); +} + } // namespace settings_utils diff --git a/chromium/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chromium/chrome/browser/ui/webui/signin/inline_login_handler.cc index 72d748ea7ec..71e633bf7b0 100644 --- a/chromium/chrome/browser/ui/webui/signin/inline_login_handler.cc +++ b/chromium/chrome/browser/ui/webui/signin/inline_login_handler.cc @@ -177,6 +177,10 @@ void InlineLoginHandler::RecordSigninUserActionForAccessPoint( base::RecordAction( base::UserMetricsAction("Signin_Signin_FromTabSwitcher")); break; + case signin_metrics::AccessPoint::ACCESS_POINT_FORCE_SIGNIN_WARNING: + base::RecordAction( + base::UserMetricsAction("Signin_Signin_FromForceSigninWarning")); + break; case signin_metrics::AccessPoint::ACCESS_POINT_MAX: NOTREACHED(); break; diff --git a/chromium/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chromium/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index 2dde2ab0a1e..7e5ee30a873 100644 --- a/chromium/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chromium/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc @@ -36,6 +36,7 @@ #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_promo.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" @@ -60,7 +61,6 @@ #include "components/signin/core/browser/signin_investigator.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/strings/grit/components_strings.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_ui.h" @@ -319,7 +319,7 @@ bool InlineSigninHelper::HandleCrossAccountError( // With force sign in enabled, cross account // sign in will be rejected in the early stage so there is no need to show the // warning page here. - if (signin::IsForceSigninEnabled()) + if (signin_util::IsForceSigninEnabled()) return false; std::string last_email = @@ -507,7 +507,7 @@ bool InlineLoginHandlerImpl::CanOffer(Profile* profile, } // With force sign in enabled, cross account sign in is not allowed. - if (signin::IsForceSigninEnabled() && + if (signin_util::IsForceSigninEnabled() && IsCrossAccountError(profile, email, gaia_id)) { if (error_message) { std::string last_email = @@ -650,7 +650,7 @@ void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) { // Otherwise, switch to the profile and finish the login. Pass the // profile path so it can be marked as unlocked. Don't pass a handler // pointer since it will be destroyed before the callback runs. - bool is_force_signin_enabled = signin::IsForceSigninEnabled(); + bool is_force_signin_enabled = signin_util::IsForceSigninEnabled(); InlineLoginHandlerImpl* handler = nullptr; if (is_force_signin_enabled) handler = this; diff --git a/chromium/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc index 34325a271b8..61c0d0e2c11 100644 --- a/chromium/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc @@ -136,6 +136,17 @@ bool AddToSet(std::set<content::WebContents*>* set, return false; } +std::unique_ptr<net::test_server::HttpResponse> EmptyHtmlResponseHandler( + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse()); + http_response->set_code(net::HTTP_OK); + http_response->set_content_type("text/html"); + http_response->set_content( + "<html><head><link rel=manifest href=/manifest.json></head></html>"); + return std::move(http_response); +} + // This class is used to mock out virtual methods with side effects so that // tests below can ensure they are called without causing side effects. class MockInlineSigninHelper : public InlineSigninHelper { @@ -450,8 +461,6 @@ class InlineLoginHelperBrowserTest : public InProcessBrowserTest { InlineLoginHelperBrowserTest() {} void SetUpInProcessBrowserTestFixture() override { - InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); - will_create_browser_context_services_subscription_ = BrowserContextDependencyManager::GetInstance() ->RegisterWillCreateBrowserContextServicesCallbackForTesting( @@ -471,8 +480,6 @@ class InlineLoginHelperBrowserTest : public InProcessBrowserTest { } void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - // Grab references to the fake signin manager and token service. Profile* profile = browser()->profile(); signin_manager_ = static_cast<FakeSigninManagerForTesting*>( @@ -809,6 +816,9 @@ class InlineLoginUISafeIframeBrowserTest : public InProcessBrowserTest { private: void SetUp() override { + embedded_test_server()->RegisterRequestHandler( + base::Bind(&EmptyHtmlResponseHandler)); + // Don't spin up the IO thread yet since no threads are allowed while // spawning sandbox host process. See crbug.com/322732. ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); @@ -869,7 +879,7 @@ IN_PROC_BROWSER_TEST_F(InlineLoginUISafeIframeBrowserTest, NoWebUIInIframe) { // http://crbug.com/709117. // Flaky on Linux and Mac. http://crbug.com/722164. IN_PROC_BROWSER_TEST_F(InlineLoginUISafeIframeBrowserTest, - DISABLED_LoadSuccessContinueURL) { + LoadSuccessContinueURL) { ui_test_utils::NavigateToURL(browser(), GetSigninPromoURL()); WaitUntilUIReady(browser()); @@ -888,13 +898,12 @@ IN_PROC_BROWSER_TEST_F(InlineLoginUISafeIframeBrowserTest, kLoadSuccessPageScript, success_url.c_str(), success_url.c_str()); std::string message; - ASSERT_TRUE(content::ExecuteScriptAndExtractString( + EXPECT_TRUE(content::ExecuteScriptAndExtractString( browser()->tab_strip_model()->GetActiveWebContents(), script, &message)); EXPECT_EQ("success_page_loaded", message); } // Make sure that the gaia iframe cannot trigger top-frame navigation. -// TODO(guohui): flaky on trybot crbug/364759. IN_PROC_BROWSER_TEST_F(InlineLoginUISafeIframeBrowserTest, TopFrameNavigationDisallowed) { // Loads into gaia iframe a web page that attempts to deframe on load. diff --git a/chromium/chrome/browser/ui/webui/signin/md_user_manager_ui.cc b/chromium/chrome/browser/ui/webui/signin/md_user_manager_ui.cc index f208584461f..7a0f7686f54 100644 --- a/chromium/chrome/browser/ui/webui/signin/md_user_manager_ui.cc +++ b/chromium/chrome/browser/ui/webui/signin/md_user_manager_ui.cc @@ -6,19 +6,21 @@ #include <string> +#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_shortcut_manager.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/webui/signin/signin_create_profile_handler.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h" #include "chrome/browser/ui/webui/theme_source.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" -#include "chrome/grit/settings_resources.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "ui/base/resource/resource_bundle.h" @@ -67,7 +69,11 @@ content::WebUIDataSource* MDUserManagerUI::CreateUIDataSource( source->AddLocalizedStrings(localized_strings); source->AddBoolean("profileShortcutsEnabled", ProfileShortcutManager::IsFeatureEnabled()); - source->AddBoolean("isForceSigninEnabled", signin::IsForceSigninEnabled()); + source->AddBoolean("isForceSigninEnabled", + signin_util::IsForceSigninEnabled()); + source->AddBoolean( + "isSupervisedUserCreationEnabled", + base::FeatureList::IsEnabled(features::kSupervisedUserCreation)); source->SetJsonPath("strings.js"); @@ -98,10 +104,6 @@ content::WebUIDataSource* MDUserManagerUI::CreateUIDataSource( source->AddResourcePath("supervised_user_learn_more.js", IDR_MD_SUPERVISED_USER_LEARN_MORE_JS); source->AddResourcePath("user_manager.js", IDR_MD_USER_MANAGER_JS); - source->AddResourcePath("user_manager_dialog.html", - IDR_MD_USER_MANAGER_DIALOG_HTML); - source->AddResourcePath("user_manager_dialog.js", - IDR_MD_USER_MANAGER_DIALOG_JS); source->AddResourcePath("user_manager_pages.html", IDR_MD_USER_MANAGER_PAGES_HTML); source->AddResourcePath("user_manager_pages.js", diff --git a/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc b/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc index c6f32829ea4..aff43866ce8 100644 --- a/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc +++ b/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc @@ -27,6 +27,7 @@ #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/user_manager.h" @@ -373,7 +374,7 @@ void SigninCreateProfileHandler::CreateShortcutAndShowSuccess( dict.SetString("name", profile->GetPrefs()->GetString(prefs::kProfileName)); dict.Set("filePath", base::CreateFilePathValue(profile->GetPath())); - bool is_force_signin_enabled = signin::IsForceSigninEnabled(); + bool is_force_signin_enabled = signin_util::IsForceSigninEnabled(); bool open_new_window = !is_force_signin_enabled; #if BUILDFLAG(ENABLE_SUPERVISED_USERS) diff --git a/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc b/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc index 5c746b5eb90..f10961a679a 100644 --- a/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/signin/fake_signin_manager_builder.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/common/features.h" #include "chrome/common/pref_names.h" @@ -374,9 +375,8 @@ TEST_F(SigninCreateProfileHandlerTest, CreateProfile) { } TEST_F(SigninCreateProfileHandlerTest, CreateProfileWithForceSignin) { - g_browser_process->local_state()->SetBoolean(prefs::kForceBrowserSignin, - true); - ASSERT_TRUE(signin::IsForceSigninEnabled()); + signin_util::SetForceSigninForTesting(true); + ASSERT_TRUE(signin_util::IsForceSigninEnabled()); // Expect the call to create the profile. EXPECT_CALL(*handler(), DoCreateProfile(_, _, _, _, _)) @@ -422,6 +422,7 @@ TEST_F(SigninCreateProfileHandlerTest, CreateProfileWithForceSignin) { bool show_confirmation; ASSERT_TRUE(profile->GetBoolean("showConfirmation", &show_confirmation)); ASSERT_FALSE(show_confirmation); + signin_util::SetForceSigninForTesting(false); } #if BUILDFLAG(ENABLE_SUPERVISED_USERS) diff --git a/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_handler.cc b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_handler.cc new file mode 100644 index 00000000000..48e1c14c118 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_handler.cc @@ -0,0 +1,63 @@ +// 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 "chrome/browser/ui/webui/signin/signin_dice_internals_handler.h" + +#include "base/values.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/account_tracker_service_factory.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" +#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/sync/one_click_signin_sync_starter.h" + +SigninDiceInternalsHandler::SigninDiceInternalsHandler(Profile* profile) + : profile_(profile) { + DCHECK(profile_); + DCHECK(!profile_->IsOffTheRecord()); +} + +SigninDiceInternalsHandler::~SigninDiceInternalsHandler() {} + +void SigninDiceInternalsHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "enableSync", base::Bind(&SigninDiceInternalsHandler::HandleEnableSync, + base::Unretained(this))); +} + +void SigninDiceInternalsHandler::HandleEnableSync(const base::ListValue* args) { + if (SigninManagerFactory::GetForProfile(profile_)->IsAuthenticated()) { + VLOG(1) << "[Dice] Cannot enable sync as profile is already authenticated"; + return; + } + + AccountTrackerService* tracker = + AccountTrackerServiceFactory::GetForProfile(profile_); + ProfileOAuth2TokenService* token_service = + ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); + std::vector<std::string> account_ids = token_service->GetAccounts(); + if (account_ids.empty()) { + VLOG(1) << "[Dice] No accounts available in the token service"; + return; + } + + Browser* browser = chrome::FindLastActiveWithProfile(profile_); + DCHECK(browser); + std::string account_id = account_ids[0]; + std::string gaia_id = tracker->GetAccountInfo(account_id).gaia; + std::string email = tracker->GetAccountInfo(account_id).email; + VLOG(1) << "[Dice] Start syncing with account " << email; + + // OneClickSigninSyncStarter is suicidal (it will kill itself once it finishes + // enabling sync). + OneClickSigninSyncStarter::Callback callback; + new OneClickSigninSyncStarter( + profile_, browser, gaia_id, email, "" /* password */, + "" /* refresh_token */, OneClickSigninSyncStarter::CURRENT_PROFILE, + OneClickSigninSyncStarter::CONFIRM_SYNC_SETTINGS_FIRST, + web_ui()->GetWebContents(), + OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN, + GURL("") /* current_url */, GURL("") /* continue_url */, callback); +} diff --git a/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_handler.h b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_handler.h new file mode 100644 index 00000000000..b9230a82f9f --- /dev/null +++ b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_handler.h @@ -0,0 +1,33 @@ +// 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 CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_DICE_INTERNALS_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_DICE_INTERNALS_HANDLER_H_ + +#include "base/macros.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace base { +class ListValue; +} +class Profile; + +class SigninDiceInternalsHandler : public content::WebUIMessageHandler { + public: + explicit SigninDiceInternalsHandler(Profile* profile); + ~SigninDiceInternalsHandler() override; + + // content::WebUIMessageHandler: + void RegisterMessages() override; + + private: + // Handler for enable sync event. + void HandleEnableSync(const base::ListValue* args); + + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(SigninDiceInternalsHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_DICE_INTERNALS_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_ui.cc b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_ui.cc new file mode 100644 index 00000000000..5b936a2f7f4 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_ui.cc @@ -0,0 +1,31 @@ +// 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 "chrome/browser/ui/webui/signin/signin_dice_internals_ui.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/signin/signin_dice_internals_handler.h" +#include "chrome/common/url_constants.h" +#include "chrome/grit/browser_resources.h" +#include "components/grit/components_resources.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" + +SigninDiceInternalsUI::SigninDiceInternalsUI(content::WebUI* web_ui) + : WebUIController(web_ui) { + Profile* profile = Profile::FromWebUI(web_ui); + DCHECK(!profile->IsOffTheRecord()); + + content::WebUIDataSource* source = content::WebUIDataSource::Create( + chrome::kChromeUISigninDiceInternalsHost); + source->AddResourcePath("signin_dice_internals.js", + IDR_SIGNIN_DICE_INTERNALS_JS); + source->SetDefaultResource(IDR_SIGNIN_DICE_INTERNALS_HTML); + content::WebUIDataSource::Add(profile, source); + + web_ui->AddMessageHandler( + base::MakeUnique<SigninDiceInternalsHandler>(profile)); +} + +SigninDiceInternalsUI::~SigninDiceInternalsUI() {} diff --git a/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_ui.h b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_ui.h new file mode 100644 index 00000000000..106f9506b41 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/signin/signin_dice_internals_ui.h @@ -0,0 +1,21 @@ +// 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 CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_DICE_INTERNALS_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_DICE_INTERNALS_UI_H_ + +#include "base/macros.h" +#include "content/public/browser/web_ui_controller.h" + +// The implementation for the chrome://signin-dice-internals page. +class SigninDiceInternalsUI : public content::WebUIController { + public: + explicit SigninDiceInternalsUI(content::WebUI* web_ui); + ~SigninDiceInternalsUI() override; + + private: + DISALLOW_COPY_AND_ASSIGN(SigninDiceInternalsUI); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_DICE_INTERNALS_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc b/chromium/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc index 2af9a846d7e..5183239f785 100644 --- a/chromium/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc +++ b/chromium/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc @@ -13,8 +13,6 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" -#include "chrome/grit/generated_resources.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui.h" diff --git a/chromium/chrome/browser/ui/webui/signin/signin_utils.cc b/chromium/chrome/browser/ui/webui/signin/signin_utils.cc index cc398328f66..d6d78cd206f 100644 --- a/chromium/chrome/browser/ui/webui/signin/signin_utils.cc +++ b/chromium/chrome/browser/ui/webui/signin/signin_utils.cc @@ -7,12 +7,9 @@ #include <set> #include "base/bind.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/common/pref_names.h" #include "components/guest_view/browser/guest_view_manager.h" -#include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "extensions/browser/guest_view/web_view/web_view_guest.h" @@ -81,10 +78,4 @@ void SetInitializedModalHeight(Browser* browser, static_cast<int>(height)); #endif } - -bool IsForceSigninEnabled() { - PrefService* prefs = g_browser_process->local_state(); - return prefs->GetBoolean(prefs::kForceBrowserSignin); -} - } // namespace signin diff --git a/chromium/chrome/browser/ui/webui/signin/signin_utils.h b/chromium/chrome/browser/ui/webui/signin/signin_utils.h index 6a05e7d5048..744e0f9302a 100644 --- a/chromium/chrome/browser/ui/webui/signin/signin_utils.h +++ b/chromium/chrome/browser/ui/webui/signin/signin_utils.h @@ -38,9 +38,6 @@ void SetInitializedModalHeight(Browser* browser, content::WebUI* web_ui, const base::ListValue* args); -// Return true if force signin is enabled by group policy. -bool IsForceSigninEnabled(); - } // namespace signin #endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_UTILS_H_ diff --git a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc index df79adbc471..ea307445a91 100644 --- a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc +++ b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc @@ -56,6 +56,9 @@ void SyncConfirmationHandler::RegisterMessages() { base::Unretained(this))); web_ui()->RegisterMessageCallback("undo", base::Bind(&SyncConfirmationHandler::HandleUndo, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "goToSettings", base::Bind(&SyncConfirmationHandler::HandleGoToSettings, + base::Unretained(this))); web_ui()->RegisterMessageCallback("initializedWithSize", base::Bind(&SyncConfirmationHandler::HandleInitializedWithSize, base::Unretained(this))); @@ -63,11 +66,12 @@ void SyncConfirmationHandler::RegisterMessages() { void SyncConfirmationHandler::HandleConfirm(const base::ListValue* args) { did_user_explicitly_interact = true; - bool configure_sync_first = false; - CHECK(args->GetBoolean(0, &configure_sync_first)); - CloseModalSigninWindow(configure_sync_first - ? LoginUIService::CONFIGURE_SYNC_FIRST - : LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); + CloseModalSigninWindow(LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); +} + +void SyncConfirmationHandler::HandleGoToSettings(const base::ListValue* args) { + did_user_explicitly_interact = true; + CloseModalSigninWindow(LoginUIService::CONFIGURE_SYNC_FIRST); } void SyncConfirmationHandler::HandleUndo(const base::ListValue* args) { @@ -85,11 +89,12 @@ void SyncConfirmationHandler::HandleUndo(const base::ListValue* args) { void SyncConfirmationHandler::SetUserImageURL(const std::string& picture_url) { std::string picture_url_to_load; - GURL url; - if (picture_url != AccountTrackerService::kNoPictureURLFound && - profiles::GetImageURLWithThumbnailSize(GURL(picture_url), - kProfileImageSize, &url)) { - picture_url_to_load = url.spec(); + GURL picture_gurl(picture_url); + if (picture_gurl.is_valid()) { + picture_url_to_load = + profiles::GetImageURLWithOptions(picture_gurl, kProfileImageSize, + false /* no_silhouette */) + .spec(); } else { // Use the placeholder avatar icon until the account picture URL is fetched. picture_url_to_load = profiles::GetPlaceholderAvatarIconUrl(); diff --git a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.h b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.h index 7de63347d18..8953681eb80 100644 --- a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.h +++ b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler.h @@ -36,8 +36,7 @@ class SyncConfirmationHandler : public content::WebUIMessageHandler, protected: // Handles "confirm" message from the page. No arguments. // This message is sent when the user confirms that they want complete sign in - // with default sync settings. Passed a single boolean argument: whether to - // configure settings before signing in. + // with default sync settings. virtual void HandleConfirm(const base::ListValue* args); // Handles "undo" message from the page. No arguments. @@ -45,6 +44,12 @@ class SyncConfirmationHandler : public content::WebUIMessageHandler, // dialog, which aborts signin and prevents sync from starting. virtual void HandleUndo(const base::ListValue* args); + // Handles "goToSettings" message from the page. No arguments. + // This message is sent when the user clicks on the "Settings" link in the + // sync confirmation dialog, which completes sign in but takes the user to the + // sync settings page for configuration before starting sync. + virtual void HandleGoToSettings(const base::ListValue* args); + // Handles the web ui message sent when the html content is done being laid // out and it's time to resize the native view hosting it to fit. |args| is // a single integer value for the height the native view should resize to. diff --git a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc index e5e5eabcefe..c6e65998f07 100644 --- a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc @@ -43,6 +43,7 @@ class TestingSyncConfirmationHandler : public SyncConfirmationHandler { using SyncConfirmationHandler::HandleConfirm; using SyncConfirmationHandler::HandleUndo; using SyncConfirmationHandler::HandleInitializedWithSize; + using SyncConfirmationHandler::HandleGoToSettings; using SyncConfirmationHandler::SetUserImageURL; private: @@ -91,7 +92,6 @@ class SyncConfirmationHandlerTest : public BrowserWithTestWindowTest { public: SyncConfirmationHandlerTest() : did_user_explicitly_interact(false), web_ui_(new content::TestWebUI) {} - void SetUp() override { BrowserWithTestWindowTest::SetUp(); chrome::NewTab(browser()); @@ -119,10 +119,11 @@ class SyncConfirmationHandlerTest : public BrowserWithTestWindowTest { web_ui_.reset(); BrowserWithTestWindowTest::TearDown(); - if (did_user_explicitly_interact) + if (did_user_explicitly_interact) { EXPECT_EQ(0, user_action_tester()->GetActionCount("Signin_Abort_Signin")); - else + } else { EXPECT_EQ(1, user_action_tester()->GetActionCount("Signin_Abort_Signin")); + } } TestingSyncConfirmationHandler* handler() { @@ -209,10 +210,9 @@ TEST_F(SyncConfirmationHandlerTest, TestSetImageIfPrimaryAccountReady) { std::string original_picture_url = AccountTrackerServiceFactory::GetForProfile(profile())-> GetAccountInfo("gaia").picture_url; - GURL picture_url_with_size; - EXPECT_TRUE(profiles::GetImageURLWithThumbnailSize(GURL(original_picture_url), - kExpectedProfileImageSize, - &picture_url_with_size)); + GURL picture_url_with_size = profiles::GetImageURLWithOptions( + GURL(original_picture_url), kExpectedProfileImageSize, + false /* no_silhouette */); EXPECT_EQ(picture_url_with_size.spec(), passed_picture_url); } @@ -260,10 +260,9 @@ TEST_F(SyncConfirmationHandlerTest, TestSetImageIfPrimaryAccountReadyLater) { std::string original_picture_url = AccountTrackerServiceFactory::GetForProfile(profile())-> GetAccountInfo("gaia").picture_url; - GURL picture_url_with_size; - EXPECT_TRUE(profiles::GetImageURLWithThumbnailSize(GURL(original_picture_url), - kExpectedProfileImageSize, - &picture_url_with_size)); + GURL picture_url_with_size = profiles::GetImageURLWithOptions( + GURL(original_picture_url), kExpectedProfileImageSize, + false /* no_silhouette */); EXPECT_EQ(picture_url_with_size.spec(), passed_picture_url); } @@ -318,9 +317,7 @@ TEST_F(SyncConfirmationHandlerTest, TestHandleConfirm) { EXPECT_FALSE(sync()->IsFirstSetupComplete()); EXPECT_TRUE(sync()->IsFirstSetupInProgress()); - base::ListValue args; - args.AppendBoolean(false /* show advanced */); - handler()->HandleConfirm(&args); + handler()->HandleConfirm(nullptr); did_user_explicitly_interact = true; EXPECT_FALSE(sync()->IsFirstSetupInProgress()); @@ -338,9 +335,7 @@ TEST_F(SyncConfirmationHandlerTest, TestHandleConfirmWithAdvancedSyncSettings) { EXPECT_FALSE(sync()->IsFirstSetupComplete()); EXPECT_TRUE(sync()->IsFirstSetupInProgress()); - base::ListValue args; - args.AppendBoolean(true /* show advanced */); - handler()->HandleConfirm(&args); + handler()->HandleGoToSettings(nullptr); did_user_explicitly_interact = true; EXPECT_FALSE(sync()->IsFirstSetupInProgress()); diff --git a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc index 701a65ff3a3..e6e68e00d1a 100644 --- a/chromium/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc +++ b/chromium/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc @@ -38,8 +38,8 @@ SyncConfirmationUI::SyncConfirmationUI(content::WebUI* web_ui) IDS_SYNC_CONFIRMATION_PERSONALIZE_SERVICES_TITLE); source->AddLocalizedString("syncConfirmationPersonalizeServicesBody", IDS_SYNC_CONFIRMATION_PERSONALIZE_SERVICES_BODY); - source->AddLocalizedString("syncConfirmationSyncSettingsLabel", - IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LABEL); + source->AddLocalizedString("syncConfirmationSyncSettingsLinkBody", + IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LINK_BODY); source->AddLocalizedString("syncDisabledConfirmationDetails", IDS_SYNC_DISABLED_CONFIRMATION_DETAILS); diff --git a/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc index 7436f8abffe..3b9bd1e0a88 100644 --- a/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc +++ b/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc @@ -10,9 +10,9 @@ #include <vector> #include "base/bind.h" -#include "base/feature_list.h" #include "base/location.h" #include "base/macros.h" +#include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/profiler/scoped_tracker.h" #include "base/single_thread_task_runner.h" @@ -47,7 +47,6 @@ #include "chrome/browser/ui/webui/profile_helper.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" @@ -90,7 +89,6 @@ const char kKeyIsDesktop[] = "isDesktopUser"; const char kKeyAvatarUrl[] = "userImage"; const char kKeyNeedsSignin[] = "needsSignin"; const char kKeyHasLocalCreds[] = "hasLocalCreds"; -const char kKeyStatistics[] = "statistics"; const char kKeyIsProfileLoaded[] = "isProfileLoaded"; // JS API callback names. @@ -104,8 +102,6 @@ const char kJsApiUserManagerLogRemoveUserWarningShown[] = "logRemoveUserWarningShown"; const char kJsApiUserManagerRemoveUserWarningLoadStats[] = "removeUserWarningLoadStats"; -const char kJsApiUserManagerGetRemoveWarningDialogMessage[] = - "getRemoveWarningDialogMessage"; const char kJsApiUserManagerAreAllProfilesLocked[] = "areAllProfilesLocked"; const size_t kAvatarIconSize = 180; @@ -306,9 +302,8 @@ UserManagerScreenHandler::UserManagerScreenHandler() : weak_ptr_factory_(this) { const PrefService::Preference* add_person_enabled_pref = service->FindPreference(prefs::kBrowserAddPersonEnabled); - if (base::FeatureList::IsEnabled(features::kMaterialDesignSettings) && - (guest_mode_enabled_pref->HasUserSetting() || - add_person_enabled_pref->HasUserSetting())) { + if (guest_mode_enabled_pref->HasUserSetting() || + add_person_enabled_pref->HasUserSetting()) { service->ClearPref(guest_mode_enabled_pref->name()); service->ClearPref(add_person_enabled_pref->name()); base::RecordAction( @@ -352,24 +347,25 @@ void UserManagerScreenHandler::EnableInput() { void UserManagerScreenHandler::SetAuthType( const AccountId& account_id, - proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type, + proximity_auth::mojom::AuthType auth_type, const base::string16& auth_value) { if (GetAuthType(account_id) == - proximity_auth::ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD) + proximity_auth::mojom::AuthType::FORCE_OFFLINE_PASSWORD) { return; + } user_auth_type_map_[account_id.GetUserEmail()] = auth_type; web_ui()->CallJavascriptFunctionUnsafe( "login.AccountPickerScreen.setAuthType", - base::Value(account_id.GetUserEmail()), base::Value(auth_type), - base::Value(auth_value)); + base::Value(account_id.GetUserEmail()), + base::Value(static_cast<int>(auth_type)), base::Value(auth_value)); } -proximity_auth::ScreenlockBridge::LockHandler::AuthType -UserManagerScreenHandler::GetAuthType(const AccountId& account_id) const { +proximity_auth::mojom::AuthType UserManagerScreenHandler::GetAuthType( + const AccountId& account_id) const { const auto it = user_auth_type_map_.find(account_id.GetUserEmail()); if (it == user_auth_type_map_.end()) - return proximity_auth::ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; + return proximity_auth::mojom::AuthType::OFFLINE_PASSWORD; return it->second; } @@ -583,10 +579,9 @@ void UserManagerScreenHandler::HandleHardlockUserPod( std::string email; CHECK(args->GetString(0, &email)); const AccountId account_id = AccountId::FromUserEmail(email); - SetAuthType( - account_id, - proximity_auth::ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD, - base::string16()); + SetAuthType(account_id, + proximity_auth::mojom::AuthType::FORCE_OFFLINE_PASSWORD, + base::string16()); HideUserPodCustomIcon(account_id); } @@ -597,6 +592,7 @@ void UserManagerScreenHandler::HandleRemoveUserWarningLoadStats( if (!args->Get(0, &profile_path_value)) return; + base::Time start_time = base::Time::Now(); base::FilePath profile_path; if (!base::GetValueAsFilePath(*profile_path_value, &profile_path)) @@ -606,91 +602,47 @@ void UserManagerScreenHandler::HandleRemoveUserWarningLoadStats( Profile* profile = g_browser_process->profile_manager()-> GetProfileByPath(profile_path); - if (!profile) - return; - - if (!chrome::FindAnyBrowser(profile, true)) { - // If no windows are open for that profile, the statistics in - // ProfileAttributesStorage are up to date. The statistics in - // ProfileAttributesStorage are returned because the copy in user_pod_row.js - // may be outdated. However, if some statistics are missing in - // ProfileAttributesStorage (i.e. |item.success| is false), then the actual - // statistics are queried instead. - base::DictionaryValue return_value; - profiles::ProfileCategoryStats stats = - ProfileStatistics::GetProfileStatisticsFromAttributesStorage( - profile_path); - bool stats_success = true; - for (const auto& item : stats) { - std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); - stat->SetIntegerWithoutPathExpansion("count", item.count); - stat->SetBooleanWithoutPathExpansion("success", item.success); - return_value.SetWithoutPathExpansion(item.category, std::move(stat)); - stats_success &= item.success; - } - if (stats_success) { - web_ui()->CallJavascriptFunctionUnsafe("updateRemoveWarningDialog", - base::Value(profile_path.value()), - return_value); - return; - } + if (profile) { + GatherStatistics(start_time, profile); + } else { + g_browser_process->profile_manager()->LoadProfileByPath( + profile_path, false, + base::Bind(&UserManagerScreenHandler::GatherStatistics, + weak_ptr_factory_.GetWeakPtr(), start_time)); } +} - ProfileStatisticsFactory::GetForProfile(profile)->GatherStatistics( - base::Bind( - &UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback, - weak_ptr_factory_.GetWeakPtr(), profile_path)); +void UserManagerScreenHandler::GatherStatistics(base::Time start_time, + Profile* profile) { + if (profile) { + ProfileStatisticsFactory::GetForProfile(profile)->GatherStatistics( + base::Bind(&UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback, + weak_ptr_factory_.GetWeakPtr(), profile->GetPath(), + start_time)); + } } void UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback( base::FilePath profile_path, + base::Time start_time, profiles::ProfileCategoryStats result) { // Copy result into return_value. base::DictionaryValue return_value; for (const auto& item : result) { - std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); + auto stat = base::MakeUnique<base::DictionaryValue>(); stat->SetIntegerWithoutPathExpansion("count", item.count); - stat->SetBooleanWithoutPathExpansion("success", item.success); return_value.SetWithoutPathExpansion(item.category, std::move(stat)); } + if (result.size() == profiles::kProfileStatisticsCategories.size()) { + // All categories are finished. + UMA_HISTOGRAM_TIMES("Profile.RemoveUserWarningStatsTime", + base::Time::Now() - start_time); + } web_ui()->CallJavascriptFunctionUnsafe("updateRemoveWarningDialog", base::Value(profile_path.value()), return_value); } -void UserManagerScreenHandler::HandleGetRemoveWarningDialogMessage( - const base::ListValue* args) { - const base::DictionaryValue* arg; - if (!args->GetDictionary(0, &arg)) - return; - - std::string profile_path(""); - bool is_synced_user = false; - bool has_errors = false; - - if (!arg->GetString("profilePath", &profile_path) || - !arg->GetBoolean("isSyncedUser", &is_synced_user) || - !arg->GetBoolean("hasErrors", &has_errors)) - return; - - int total_count = 0; - if (!arg->GetInteger("totalCount", &total_count)) - return; - - int message_id = is_synced_user ? - (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC_WITH_ERRORS : - IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC) : - (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC_WITH_ERRORS : - IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC); - - base::Value message = - base::Value(l10n_util::GetPluralStringFUTF16(message_id, total_count)); - - web_ui()->CallJavascriptFunctionUnsafe("updateRemoveWarningDialogSetMessage", - base::Value(profile_path), message, - base::Value(total_count)); -} - void UserManagerScreenHandler::OnGetTokenInfoResponse( std::unique_ptr<base::DictionaryValue> token_info) { // Password is unchanged so user just mistyped it. Ask again. @@ -737,10 +689,6 @@ void UserManagerScreenHandler::RegisterMessages() { base::Bind(&UserManagerScreenHandler::HandleRemoveUserWarningLoadStats, base::Unretained(this))); web_ui()->RegisterMessageCallback( - kJsApiUserManagerGetRemoveWarningDialogMessage, - base::Bind(&UserManagerScreenHandler::HandleGetRemoveWarningDialogMessage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( kJsApiUserManagerAreAllProfilesLocked, base::Bind(&UserManagerScreenHandler::HandleAreAllProfilesLocked, base::Unretained(this))); @@ -755,7 +703,6 @@ void UserManagerScreenHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("getTouchViewState", kDoNothingCallback); // Unused callbacks from display_manager.js web_ui()->RegisterMessageCallback("showAddUser", kDoNothingCallback); - web_ui()->RegisterMessageCallback("loadWallpaper", kDoNothingCallback); web_ui()->RegisterMessageCallback("updateCurrentScreen", kDoNothingCallback); web_ui()->RegisterMessageCallback("loginVisible", kDoNothingCallback); // Unused callbacks from user_pod_row.js @@ -801,28 +748,23 @@ void UserManagerScreenHandler::GetLocalizedValues( // For AccountPickerScreen, the remove user warning overlay. localized_strings->SetString("removeUserWarningButtonTitle", l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON)); - localized_strings->SetString("removeUserWarningTextNonSyncNoStats", - l10n_util::GetStringUTF16( - IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC_NOSTATS)); - localized_strings->SetString("removeUserWarningTextNonSyncCalculating", - l10n_util::GetStringUTF16( - IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC_CALCULATING)); + localized_strings->SetString( + "removeUserWarningTextNonSync", + l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC)); localized_strings->SetString("removeUserWarningTextHistory", l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_HISTORY)); localized_strings->SetString("removeUserWarningTextPasswords", l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_PASSWORDS)); localized_strings->SetString("removeUserWarningTextBookmarks", l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BOOKMARKS)); - localized_strings->SetString("removeUserWarningTextSettings", - l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_SETTINGS)); + localized_strings->SetString( + "removeUserWarningTextAutofill", + l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_AUTOFILL)); localized_strings->SetString("removeUserWarningTextCalculating", l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_CALCULATING)); - localized_strings->SetString("removeUserWarningTextSyncNoStats", - l10n_util::GetStringUTF16( - IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC_NOSTATS)); - localized_strings->SetString("removeUserWarningTextSyncCalculating", - l10n_util::GetStringUTF16( - IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC_CALCULATING)); + localized_strings->SetString( + "removeUserWarningTextSync", + l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC)); localized_strings->SetString("removeLegacySupervisedUserWarningText", l10n_util::GetStringFUTF16( IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING, @@ -927,8 +869,7 @@ void UserManagerScreenHandler::SendUserList() { if (entry->IsOmitted()) continue; - std::unique_ptr<base::DictionaryValue> profile_value( - new base::DictionaryValue()); + auto profile_value = base::MakeUnique<base::DictionaryValue>(); base::FilePath profile_path = entry->GetPath(); profile_value->SetString(kKeyUsername, entry->GetUserName()); @@ -949,20 +890,6 @@ void UserManagerScreenHandler::SendUserList() { profile_value->SetBoolean(kKeyIsDesktop, true); profile_value->SetString(kKeyAvatarUrl, GetAvatarImage(entry)); - profiles::ProfileCategoryStats stats = - ProfileStatistics::GetProfileStatisticsFromAttributesStorage( - profile_path); - std::unique_ptr<base::DictionaryValue> stats_dict( - new base::DictionaryValue); - for (const auto& item : stats) { - std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); - stat->SetIntegerWithoutPathExpansion("count", item.count); - stat->SetBooleanWithoutPathExpansion("success", item.success); - stats_dict->SetWithoutPathExpansion(item.category, std::move(stat)); - } - profile_value->SetWithoutPathExpansion(kKeyStatistics, - std::move(stats_dict)); - // GetProfileByPath returns a pointer if the profile is fully loaded, NULL // otherwise. Profile* profile = diff --git a/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.h b/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.h index 522737931bf..7c4ad86e067 100644 --- a/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.h +++ b/chromium/chrome/browser/ui/webui/signin/user_manager_screen_handler.h @@ -64,11 +64,11 @@ class UserManagerScreenHandler icon_options) override; void HideUserPodCustomIcon(const AccountId& account_id) override; void EnableInput() override; - void SetAuthType( - const AccountId& account_id, - proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type, - const base::string16& auth_value) override; - AuthType GetAuthType(const AccountId& account_id) const override; + void SetAuthType(const AccountId& account_id, + proximity_auth::mojom::AuthType auth_type, + const base::string16& auth_value) override; + proximity_auth::mojom::AuthType GetAuthType( + const AccountId& account_id) const override; ScreenType GetScreenType() const override; void Unlock(const AccountId& account_id) override; void AttemptEasySignin(const AccountId& account_id, @@ -86,10 +86,13 @@ class UserManagerScreenHandler void HandleRemoveUserWarningLoadStats(const base::ListValue* args); void HandleGetRemoveWarningDialogMessage(const base::ListValue* args); + // Function used to gather statistics from a profile. + void GatherStatistics(base::Time start_time, Profile* profile); + // Callback function used by HandleRemoveUserWarningLoadStats - void RemoveUserDialogLoadStatsCallback( - base::FilePath profile_path, - profiles::ProfileCategoryStats result); + void RemoveUserDialogLoadStatsCallback(base::FilePath profile_path, + base::Time start_time, + profiles::ProfileCategoryStats result); // Handle GAIA auth results. void OnGetTokenInfoResponse( @@ -127,8 +130,7 @@ class UserManagerScreenHandler // URL hash, used to key post-profile actions if present. std::string url_hash_; - typedef std::map<std::string, - proximity_auth::ScreenlockBridge::LockHandler::AuthType> + typedef std::map<std::string, proximity_auth::mojom::AuthType> UserAuthTypeMap; UserAuthTypeMap user_auth_type_map_; diff --git a/chromium/chrome/browser/ui/webui/site_settings_helper.cc b/chromium/chrome/browser/ui/webui/site_settings_helper.cc index 8c28fbeb998..299d94c1cc3 100644 --- a/chromium/chrome/browser/ui/webui/site_settings_helper.cc +++ b/chromium/chrome/browser/ui/webui/site_settings_helper.cc @@ -14,6 +14,7 @@ #include "chrome/browser/usb/usb_chooser_context_factory.h" #include "chrome/common/pref_names.h" #include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" #include "components/prefs/pref_service.h" #include "extensions/browser/extension_registry.h" @@ -25,6 +26,7 @@ const char kSetting[] = "setting"; const char kOrigin[] = "origin"; const char kDisplayName[] = "displayName"; const char kOriginForFavicon[] = "originForFavicon"; +const char kExtensionProviderId[] = "extension"; const char kPolicyProviderId[] = "policy"; const char kSource[] = "source"; const char kIncognito[] = "incognito"; @@ -73,7 +75,7 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, "protectedContent"}, #endif {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, "background-sync"}, - {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, "subresource-filter"}, + {CONTENT_SETTINGS_TYPE_ADS, "ads"}, }; } // namespace @@ -136,7 +138,7 @@ std::unique_ptr<base::DictionaryValue> GetExceptionForPage( const ContentSetting& setting, const std::string& provider_name, bool incognito) { - base::DictionaryValue* exception = new base::DictionaryValue(); + auto exception = base::MakeUnique<base::DictionaryValue>(); exception->SetString(kOrigin, pattern.ToString()); exception->SetString(kDisplayName, display_name); exception->SetString(kEmbeddingOrigin, @@ -151,7 +153,7 @@ std::unique_ptr<base::DictionaryValue> GetExceptionForPage( exception->SetString(kSetting, setting_string); exception->SetString(kSource, provider_name); exception->SetBoolean(kIncognito, incognito); - return base::WrapUnique(exception); + return exception; } std::string GetDisplayName( @@ -202,7 +204,7 @@ void GetExceptionsFromHostContentSettingsMap( continue; all_patterns_settings[std::make_pair(i->primary_pattern, i->source)] - [i->secondary_pattern] = i->setting; + [i->secondary_pattern] = i->GetContentSetting(); } // Keep the exceptions sorted by provider so they will be displayed in diff --git a/chromium/chrome/browser/ui/webui/site_settings_helper.h b/chromium/chrome/browser/ui/webui/site_settings_helper.h index bc3b51aaa76..d9662f6e67c 100644 --- a/chromium/chrome/browser/ui/webui/site_settings_helper.h +++ b/chromium/chrome/browser/ui/webui/site_settings_helper.h @@ -45,6 +45,7 @@ extern const char kSetting[]; extern const char kOrigin[]; extern const char kDisplayName[]; extern const char kOriginForFavicon[]; +extern const char kExtensionProviderId[]; extern const char kPolicyProviderId[]; extern const char kSource[]; extern const char kIncognito[]; diff --git a/chromium/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chromium/chrome/browser/ui/webui/snippets_internals_message_handler.cc index 703d28073dc..96cd84ae0dc 100644 --- a/chromium/chrome/browser/ui/webui/snippets_internals_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/snippets_internals_message_handler.cc @@ -382,10 +382,10 @@ void SnippetsInternalsMessageHandler::SendAllContent() { if (remote_suggestions_provider_) { const ntp_snippets::RemoteSuggestionsFetcher* fetcher = remote_suggestions_provider_->suggestions_fetcher_for_debugging(); - SendString("switch-fetch-url", fetcher->fetch_url().spec()); + SendString("switch-fetch-url", fetcher->GetFetchUrlForDebugging().spec()); web_ui()->CallJavascriptFunctionUnsafe( "chrome.SnippetsInternals.receiveJson", - base::Value(fetcher->last_json())); + base::Value(fetcher->GetLastJsonForDebugging())); } std::set<variations::VariationID> ids = SnippetsExperiments(); @@ -482,7 +482,7 @@ void SnippetsInternalsMessageHandler::SendContentSuggestions() { if (remote_suggestions_provider_) { const std::string& status = remote_suggestions_provider_->suggestions_fetcher_for_debugging() - ->last_status(); + ->GetLastStatusForDebugging(); if (!status.empty()) { SendString("remote-status", "Finished: " + status); } diff --git a/chromium/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc b/chromium/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc index f9ca895383e..7ee4e0aab27 100644 --- a/chromium/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc @@ -43,8 +43,8 @@ base::ListValue* AddSection(base::ListValue* parent_list, std::unique_ptr<base::ListValue> section_contents(new base::ListValue); section->SetString("title", title); // Grab a raw pointer to the result before |Pass()|ing it on. - base::ListValue* result = section_contents.get(); - section->Set("data", std::move(section_contents)); + base::ListValue* result = + section->SetList("data", std::move(section_contents)); parent_list->Append(std::move(section)); return result; } diff --git a/chromium/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chromium/chrome/browser/ui/webui/sync_internals_message_handler.cc index 5979034d19c..5bf52b83ea2 100644 --- a/chromium/chrome/browser/ui/webui/sync_internals_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/sync_internals_message_handler.cc @@ -59,16 +59,11 @@ int64_t StringAtIndexToInt64(const base::ListValue* list, int index) { SyncInternalsMessageHandler::SyncInternalsMessageHandler() : SyncInternalsMessageHandler( base::BindRepeating( - &SyncInternalsMessageHandler::BindForSyncServiceProvider, - base::Unretained(this)), - base::BindRepeating( &syncer::sync_ui_util::ConstructAboutInformation)) {} SyncInternalsMessageHandler::SyncInternalsMessageHandler( - SyncServiceProvider sync_service_provider, AboutSyncDataDelegate about_sync_data_delegate) - : sync_service_provider_(std::move(sync_service_provider)), - about_sync_data_delegate_(std::move(about_sync_data_delegate)), + : about_sync_data_delegate_(std::move(about_sync_data_delegate)), weak_ptr_factory_(this) {} SyncInternalsMessageHandler::~SyncInternalsMessageHandler() { @@ -114,6 +109,11 @@ void SyncInternalsMessageHandler::RegisterMessages() { base::Unretained(this))); web_ui()->RegisterMessageCallback( + syncer::sync_ui_util::kSetIncludeSpecifics, + base::Bind(&SyncInternalsMessageHandler::HandleSetIncludeSpecifics, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( syncer::sync_ui_util::kWriteUserEvent, base::Bind(&SyncInternalsMessageHandler::HandleWriteUserEvent, base::Unretained(this))); @@ -132,7 +132,7 @@ void SyncInternalsMessageHandler::HandleRegisterForEvents( // is_registered_ flag protects us from double-registering. This could // happen on a page refresh, where the JavaScript gets re-run but the // message handler remains unchanged. - SyncService* service = sync_service_provider_.Run(); + SyncService* service = GetSyncService(); if (service && !is_registered_) { service->AddObserver(this); service->AddProtocolEventObserver(this); @@ -147,7 +147,7 @@ void SyncInternalsMessageHandler::HandleRegisterForPerTypeCounters( DCHECK(args->empty()); AllowJavascript(); - SyncService* service = sync_service_provider_.Run(); + SyncService* service = GetSyncService(); if (!service) return; @@ -192,7 +192,7 @@ void SyncInternalsMessageHandler::HandleGetAllNodes(const ListValue* args) { bool success = ExtractIntegerValue(args, &request_id); DCHECK(success); - SyncService* service = sync_service_provider_.Run(); + SyncService* service = GetSyncService(); if (service) { // This opens up the possibility of non-javascript code calling us // asynchronously, and potentially at times we're not allowed to call into @@ -213,6 +213,13 @@ void SyncInternalsMessageHandler::HandleRequestUserEventsVisibility( Value(base::FeatureList::IsEnabled(switches::kSyncUserEvents))); } +void SyncInternalsMessageHandler::HandleSetIncludeSpecifics( + const ListValue* args) { + DCHECK_EQ(1U, args->GetSize()); + AllowJavascript(); + include_specifics_ = args->GetList()[0].GetBool(); +} + void SyncInternalsMessageHandler::HandleWriteUserEvent( const base::ListValue* args) { DCHECK_EQ(2U, args->GetSize()); @@ -220,8 +227,7 @@ void SyncInternalsMessageHandler::HandleWriteUserEvent( Profile* profile = Profile::FromWebUI(web_ui()); syncer::UserEventService* user_event_service = - browser_sync::UserEventServiceFactory::GetForProfile( - profile->GetOriginalProfile()); + browser_sync::UserEventServiceFactory::GetForProfile(profile); sync_pb::UserEventSpecifics event_specifics; event_specifics.set_event_time_usec(StringAtIndexToInt64(args, 0)); @@ -242,7 +248,8 @@ void SyncInternalsMessageHandler::OnStateChanged(SyncService* sync) { void SyncInternalsMessageHandler::OnProtocolEvent( const syncer::ProtocolEvent& event) { - std::unique_ptr<DictionaryValue> value(syncer::ProtocolEvent::ToValue(event)); + std::unique_ptr<DictionaryValue> value( + syncer::ProtocolEvent::ToValue(event, include_specifics_)); DispatchEvent(syncer::sync_ui_util::kOnProtocolEvent, *value); } @@ -284,13 +291,13 @@ void SyncInternalsMessageHandler::HandleJsEvent( } void SyncInternalsMessageHandler::SendAboutInfo() { - std::unique_ptr<DictionaryValue> value = about_sync_data_delegate_.Run( - sync_service_provider_.Run(), chrome::GetChannel()); + std::unique_ptr<DictionaryValue> value = + about_sync_data_delegate_.Run(GetSyncService(), chrome::GetChannel()); DispatchEvent(syncer::sync_ui_util::kOnAboutInfoUpdated, *value); } -SyncService* SyncInternalsMessageHandler::BindForSyncServiceProvider() { - return ProfileSyncServiceFactory::GetForProfile( +SyncService* SyncInternalsMessageHandler::GetSyncService() { + return ProfileSyncServiceFactory::GetSyncServiceForBrowserContext( Profile::FromWebUI(web_ui())->GetOriginalProfile()); } @@ -301,7 +308,7 @@ void SyncInternalsMessageHandler::DispatchEvent(const std::string& name, } void SyncInternalsMessageHandler::UnregisterModelNotifications() { - SyncService* service = sync_service_provider_.Run(); + SyncService* service = GetSyncService(); if (!service) return; diff --git a/chromium/chrome/browser/ui/webui/sync_internals_message_handler.h b/chromium/chrome/browser/ui/webui/sync_internals_message_handler.h index 2ef1840b073..4c6f4199743 100644 --- a/chromium/chrome/browser/ui/webui/sync_internals_message_handler.h +++ b/chromium/chrome/browser/ui/webui/sync_internals_message_handler.h @@ -61,6 +61,10 @@ class SyncInternalsMessageHandler : public content::WebUIMessageHandler, // Handler for requests to get UserEvents tab visibility. void HandleRequestUserEventsVisibility(const base::ListValue* args); + // Handler for setting internal state of if specifics should be included in + // protocol events when sent to be displayed. + void HandleSetIncludeSpecifics(const base::ListValue* args); + // Handler for writeUserEvent message. void HandleWriteUserEvent(const base::ListValue* args); @@ -96,16 +100,14 @@ class SyncInternalsMessageHandler : public content::WebUIMessageHandler, std::unique_ptr<base::DictionaryValue> value); protected: - using SyncServiceProvider = base::RepeatingCallback<syncer::SyncService*()>; - using AboutSyncDataDelegate = base::RepeatingCallback<std::unique_ptr<base::DictionaryValue>( syncer::SyncService* service, version_info::Channel channel)>; // Constructor used for unit testing to override dependencies. - SyncInternalsMessageHandler(SyncServiceProvider sync_service_provider, - AboutSyncDataDelegate about_sync_data_delegate); + explicit SyncInternalsMessageHandler( + AboutSyncDataDelegate about_sync_data_delegate); private: // Fetches updated aboutInfo and sends it to the page in the form of an @@ -113,9 +115,8 @@ class SyncInternalsMessageHandler : public content::WebUIMessageHandler, void SendAboutInfo(); // Gets the ProfileSyncService of the underlying original profile. May return - // nullptr (e.g., if sync is disabled on the command line). Shouldn't be - // called directly, but instead through |sync_service_provider_|. - syncer::SyncService* BindForSyncServiceProvider(); + // nullptr (e.g., if sync is disabled on the command line). + syncer::SyncService* GetSyncService(); // Sends a dispatch event to the UI. Javascript must be enabled. void DispatchEvent(const std::string& name, const base::Value& details_value); @@ -133,8 +134,9 @@ class SyncInternalsMessageHandler : public content::WebUIMessageHandler, // ProfileSyncService. bool is_registered_for_counters_ = false; - // An abstraction of who provides the SyncService. - SyncServiceProvider sync_service_provider_; + // Whether specifics should be included when converting protocol events to a + // human readable format. + bool include_specifics_ = false; // An abstraction of who creates the about sync info value map. AboutSyncDataDelegate about_sync_data_delegate_; diff --git a/chromium/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc b/chromium/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc index b1611198114..c0264788d64 100644 --- a/chromium/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc @@ -9,12 +9,15 @@ #include "base/command_line.h" #include "base/memory/ref_counted.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/sync/user_event_service_factory.h" #include "chrome/test/base/testing_profile.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/sync/driver/about_sync_util.h" #include "components/sync/driver/fake_sync_service.h" #include "components/sync/driver/sync_service.h" #include "components/sync/js/js_test_util.h" +#include "components/sync/user_events/fake_user_event_service.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -24,6 +27,7 @@ using base::DictionaryValue; using base::ListValue; using base::Value; +using syncer::FakeUserEventService; using syncer::SyncService; using syncer::SyncServiceObserver; using syncer::TypeDebugInfoObserver; @@ -34,10 +38,8 @@ class TestableSyncInternalsMessageHandler : public SyncInternalsMessageHandler { public: TestableSyncInternalsMessageHandler( content::WebUI* web_ui, - SyncServiceProvider sync_service_provider, AboutSyncDataDelegate about_sync_data_delegate) - : SyncInternalsMessageHandler(std::move(sync_service_provider), - std::move(about_sync_data_delegate)) { + : SyncInternalsMessageHandler(std::move(about_sync_data_delegate)) { set_web_ui(web_ui); } }; @@ -92,6 +94,16 @@ class TestSyncService : public syncer::FakeSyncService { get_all_nodes_callback_; }; +static std::unique_ptr<KeyedService> BuildTestSyncService( + content::BrowserContext* context) { + return base::MakeUnique<TestSyncService>(); +} + +static std::unique_ptr<KeyedService> BuildFakeUserEventService( + content::BrowserContext* context) { + return base::MakeUnique<FakeUserEventService>(); +} + class SyncInternalsMessageHandlerTest : public ::testing::Test { protected: SyncInternalsMessageHandlerTest() { @@ -99,11 +111,14 @@ class SyncInternalsMessageHandlerTest : public ::testing::Test { web_contents_.reset(content::WebContents::Create( content::WebContents::CreateParams(&profile_, site_instance_.get()))); web_ui_.set_web_contents(web_contents_.get()); - test_sync_service_ = base::MakeUnique<TestSyncService>(); + test_sync_service_ = static_cast<TestSyncService*>( + ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, &BuildTestSyncService)); + fake_user_event_service_ = static_cast<FakeUserEventService*>( + browser_sync::UserEventServiceFactory::GetInstance() + ->SetTestingFactoryAndUse(&profile_, &BuildFakeUserEventService)); handler_.reset(new TestableSyncInternalsMessageHandler( &web_ui_, - base::BindRepeating(&SyncInternalsMessageHandlerTest::sync_service, - base::Unretained(this)), base::BindRepeating( &SyncInternalsMessageHandlerTest::ConstructAboutInformation, base::Unretained(this)))); @@ -149,7 +164,13 @@ class SyncInternalsMessageHandlerTest : public ::testing::Test { EXPECT_TRUE(web_ui_.call_data().empty()); } - TestSyncService* test_sync_service() { return test_sync_service_.get(); } + TestingProfile* profile() { return &profile_; } + + TestSyncService* test_sync_service() { return test_sync_service_; } + + FakeUserEventService* fake_user_event_service() { + return fake_user_event_service_; + } TestableSyncInternalsMessageHandler* handler() { return handler_.get(); } @@ -171,19 +192,16 @@ class SyncInternalsMessageHandlerTest : public ::testing::Test { return last_delegate_sync_service_; } - void ResetSyncService() { test_sync_service_.reset(); } - void ResetHandler() { handler_.reset(); } private: - SyncService* sync_service() { return test_sync_service_.get(); } - content::TestBrowserThreadBundle thread_bundle_; TestingProfile profile_; - content::TestWebUI web_ui_; scoped_refptr<content::SiteInstance> site_instance_; std::unique_ptr<content::WebContents> web_contents_; - std::unique_ptr<TestSyncService> test_sync_service_; + content::TestWebUI web_ui_; + TestSyncService* test_sync_service_; + FakeUserEventService* fake_user_event_service_; std::unique_ptr<TestableSyncInternalsMessageHandler> handler_; int about_sync_data_delegate_call_count_ = 0; SyncService* last_delegate_sync_service_ = nullptr; @@ -238,7 +256,8 @@ TEST_F(SyncInternalsMessageHandlerTest, AddRemoveObserversDisallowJavascript) { TEST_F(SyncInternalsMessageHandlerTest, AddRemoveObserversSyncDisabled) { // Simulate completely disabling sync by flag or other mechanism. - ResetSyncService(); + ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile(), + nullptr); ListValue empty_list; handler()->HandleRegisterForEvents(&empty_list); @@ -301,7 +320,8 @@ TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfo) { TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfoSyncDisabled) { // Simulate completely disabling sync by flag or other mechanism. - ResetSyncService(); + ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(profile(), + nullptr); handler()->AllowJavascriptForTesting(); handler()->OnStateChanged(nullptr); @@ -310,4 +330,30 @@ TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfoSyncDisabled) { ValidateAboutInfoCall(); } +TEST_F(SyncInternalsMessageHandlerTest, WriteUserEvent) { + ListValue args; + args.AppendString("1000000000000000000"); + args.AppendString("-1"); + handler()->HandleWriteUserEvent(&args); + + ASSERT_EQ(1u, fake_user_event_service()->GetRecordedUserEvents().size()); + const sync_pb::UserEventSpecifics& event = + *fake_user_event_service()->GetRecordedUserEvents().begin(); + EXPECT_EQ(1000000000000000000, event.event_time_usec()); + EXPECT_EQ(-1, event.navigation_id()); +} + +TEST_F(SyncInternalsMessageHandlerTest, WriteUserEventBadParse) { + ListValue args; + args.AppendString("123abc"); + args.AppendString(""); + handler()->HandleWriteUserEvent(&args); + + ASSERT_EQ(1u, fake_user_event_service()->GetRecordedUserEvents().size()); + const sync_pb::UserEventSpecifics& event = + *fake_user_event_service()->GetRecordedUserEvents().begin(); + EXPECT_EQ(0, event.event_time_usec()); + EXPECT_EQ(0, event.navigation_id()); +} + } // namespace diff --git a/chromium/chrome/browser/ui/webui/sync_setup_browsertest.js b/chromium/chrome/browser/ui/webui/sync_setup_browsertest.js deleted file mode 100644 index 578dfd0b417..00000000000 --- a/chromium/chrome/browser/ui/webui/sync_setup_browsertest.js +++ /dev/null @@ -1,139 +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. - -GEN('#if !defined(OS_CHROMEOS)'); - -/** - * Test fixture for sync setup WebUI testing. - * @constructor - * @extends {testing.Test} - */ -function SyncSetupWebUITest() {} - -SyncSetupWebUITest.prototype = { - __proto__: testing.Test.prototype, - - /** - * Browse to the settings sub-frame. - */ - browsePreload: 'chrome://settings-frame', - - /** @override */ - preLoad: function() { - this.makeAndRegisterMockHandler(['SyncSetupConfigure', - 'SyncSetupShowSetupUI', - 'SyncSetupStartSignIn', - ]); - }, - - /** - * Verifies starting point is not synced. - */ - verifyUnsynced: function() { - assertFalse(BrowserOptions.getInstance().signedIn_); - }, - - /** - * Clicks the "Sign in to Chrome" button. - */ - startSyncing: function() { - var startStopSyncButton = BrowserOptions.getStartStopSyncButton(); - assertNotEquals(null, startStopSyncButton); - startStopSyncButton.click(); - }, -}; - -/** - * Async version of SyncSetupWebUITest. - * @extends {SyncSetupWebUITest} - * @constructor - */ -function SyncSetupWebUITestAsync() {} - -SyncSetupWebUITestAsync.prototype = { - __proto__: SyncSetupWebUITest.prototype, - - /** @override */ - isAsync: true, - - /** - * Verifies that initial state is unsynced and simulates signing in. - * @override - */ - setUp: function() { - SyncSetupWebUITest.prototype.setUp.call(this); - - // For testing, don't wait to execute timeouts. - var oldSetTimeout = setTimeout; - setTimeout = function(fn, timeout) { - oldSetTimeout(fn, 0); - }; - - // Make sure the user is not starting off in the signed in or syncing state. - this.verifyUnsynced(); - - // Handle SyncSetupShowSetupUI by navigating to chrome://settings/syncSetup. - this.mockHandler.expects(once()).SyncSetupShowSetupUI().will(callFunction( - function() { - PageManager.showPageByName('syncSetup'); - })); - }, -}; - -// This test is flaky on Linux bot (crbug.com/579666) and Windows & Mac bots -// (crbug.com/608975). -TEST_F('SyncSetupWebUITestAsync', 'DISABLED_VerifySignIn', function() { - // Handle SyncSetupStartSignIn by displaying the sync setup dialog, verifying - // that a confirmation dialog appears, and clicking OK to dismiss the dialog. - // Note that this test doesn't actually do a gaia sign in. - this.mockHandler.expects(once()).SyncSetupStartSignIn( - [false] /* createSupervisedUser */).will(callFunction(function() { - SyncSetupOverlay.showSyncSetupPage('configure'); - var okButton = $('confirm-everything-ok'); - assertNotEquals(null, okButton); - okButton.click(); - })); - - // The test completes after the sync config is sent out. - this.mockHandler.expects(once()).SyncSetupConfigure(ANYTHING). - will(callFunction(testDone)); - - // Click the "Sign in to Chrome..." button. - this.startSyncing(); -}); - -// This test is flaky on Linux, Windows and Mac bots. See crbug.com/579666, -// crbug.com/638884 and crbug.com/718947. -GEN('#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MACOSX)'); -GEN('#define MAYBE_RestoreSyncDataTypes DISABLED_RestoreSyncDataTypes'); -GEN('#else'); -GEN('#define MAYBE_RestoreSyncDataTypes RestoreSyncDataTypes'); -GEN('#endif // defined(OS_LINUX) || defined(OS_WIN)'); -// Test that switching to and from "Sync everything" saves and restores types. -TEST_F('SyncSetupWebUITestAsync', 'MAYBE_RestoreSyncDataTypes', function() { - this.mockHandler.expects(once()).SyncSetupStartSignIn( - [false] /* createSupervisedUser */).will(callFunction(function() { - SyncSetupOverlay.showSyncSetupPage('configure', {}); - - $('sync-select-datatypes').selectedIndex = 1; - cr.dispatchSimpleEvent($('sync-select-datatypes'), 'change', true); - - $('bookmarks-checkbox').checked = false; - cr.dispatchSimpleEvent($('bookmarks-checkbox'), 'change', true); - - $('sync-select-datatypes').selectedIndex = 0; - cr.dispatchSimpleEvent($('sync-select-datatypes'), 'change', true); - assertTrue($('bookmarks-checkbox').checked); - - $('sync-select-datatypes').selectedIndex = 1; - cr.dispatchSimpleEvent($('sync-select-datatypes'), 'change', true); - assertFalse($('bookmarks-checkbox').checked); - - testDone(); - })); - - this.startSyncing(); -}); - -GEN('#endif // OS_CHROMEOS'); diff --git a/chromium/chrome/browser/ui/webui/system_info_ui.cc b/chromium/chrome/browser/ui/webui/system_info_ui.cc index ebf7121cc53..e478be745df 100644 --- a/chromium/chrome/browser/ui/webui/system_info_ui.cc +++ b/chromium/chrome/browser/ui/webui/system_info_ui.cc @@ -28,6 +28,7 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" +#include "components/feedback/system_logs/system_logs_fetcher.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -42,7 +43,6 @@ using content::WebContents; using content::WebUIMessageHandler; using system_logs::SystemLogsResponse; -using system_logs::AboutSystemLogsFetcher; class SystemInfoUIHTMLSource : public content::URLDataSource{ public: @@ -116,7 +116,8 @@ void SystemInfoUIHTMLSource::StartDataRequest( path_ = path; callback_ = callback; - AboutSystemLogsFetcher* fetcher = new AboutSystemLogsFetcher(); + system_logs::SystemLogsFetcher* fetcher = + system_logs::BuildAboutSystemLogsFetcher(); fetcher->Fetch(base::Bind(&SystemInfoUIHTMLSource::SysInfoComplete, weak_ptr_factory_.GetWeakPtr())); } diff --git a/chromium/chrome/browser/ui/webui/theme_source.cc b/chromium/chrome/browser/ui/webui/theme_source.cc index a48745c145e..529e500958a 100644 --- a/chromium/chrome/browser/ui/webui/theme_source.cc +++ b/chromium/chrome/browser/ui/webui/theme_source.cc @@ -81,8 +81,10 @@ void ThemeSource::StartDataRequest( const content::URLDataSource::GotDataCallback& callback) { // Default scale factor if not specified. float scale = 1.0f; + // All frames by default if not specified. + int frame = -1; std::string parsed_path; - webui::ParsePathAndScale(GetThemeUrl(path), &parsed_path, &scale); + webui::ParsePathAndImageSpec(GetThemeUrl(path), &parsed_path, &scale, &frame); if (IsNewTabCssPath(parsed_path)) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -132,14 +134,20 @@ void ThemeSource::StartDataRequest( const float max_scale = ui::GetScaleForScaleFactor( ResourceBundle::GetSharedInstance().GetMaxScaleFactor()); const float unreasonable_scale = max_scale * 32; - if ((resource_id == -1) || (scale >= unreasonable_scale)) { + // TODO(reveman): Add support frames beyond 0 (crbug.com/750064). + if ((resource_id == -1) || (scale >= unreasonable_scale) || (frame > 0)) { // Either we have no data to send back, or the requested scale is // unreasonably large. This shouldn't happen normally, as chrome://theme/ // URLs are only used by WebUI pages and component extensions. However, the // user can also enter these into the omnibox, so we need to fail // gracefully. callback.Run(nullptr); - } else if ((GetMimeType(path) == "image/png") && (scale > max_scale)) { + } else if ((GetMimeType(path) == "image/png") && + ((scale > max_scale) || (frame != -1))) { + // This will extract and scale frame 0 of animated images. + // TODO(reveman): Support scaling of animated images and avoid scaling and + // re-encode when specific frame is specified (crbug.com/750064). + DCHECK_LE(frame, 0); SendThemeImage(callback, resource_id, scale); } else { SendThemeBitmap(callback, resource_id, scale); diff --git a/chromium/chrome/browser/ui/webui/uber/uber_ui.cc b/chromium/chrome/browser/ui/webui/uber/uber_ui.cc deleted file mode 100644 index 5a8dfc15281..00000000000 --- a/chromium/chrome/browser/ui/webui/uber/uber_ui.cc +++ /dev/null @@ -1,187 +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 "chrome/browser/ui/webui/uber/uber_ui.h" - -#include "base/memory/ptr_util.h" -#include "base/stl_util.h" -#include "build/build_config.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" -#include "chrome/browser/ui/webui/extensions/extensions_ui.h" -#include "chrome/browser/ui/webui/log_web_ui_url.h" -#include "chrome/browser/ui/webui/options/options_ui.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/chrome_manifest_url_handlers.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" -#include "content/public/common/browser_side_navigation_policy.h" - -using content::NavigationController; -using content::NavigationEntry; -using content::RenderFrameHost; -using content::WebContents; - -namespace { - -content::WebUIDataSource* CreateUberHTMLSource() { - content::WebUIDataSource* source = - content::WebUIDataSource::Create(chrome::kChromeUIUberHost); - - source->SetJsonPath("strings.js"); - source->AddResourcePath("uber.js", IDR_UBER_JS); - source->AddResourcePath("uber_utils.js", IDR_UBER_UTILS_JS); - source->SetDefaultResource(IDR_UBER_HTML); - source->OverrideContentSecurityPolicyChildSrc("child-src chrome:;"); - - // Hack alert: continue showing "Loading..." until a real title is set. - source->AddLocalizedString("pageTitle", IDS_TAB_LOADING_TITLE); - - source->AddString("extensionsFrameURL", chrome::kChromeUIExtensionsFrameURL); - source->AddString("extensionsHost", chrome::kChromeUIExtensionsHost); - source->AddString("helpFrameURL", chrome::kChromeUIHelpFrameURL); - source->AddString("helpHost", chrome::kChromeUIHelpHost); - source->AddString("settingsFrameURL", chrome::kChromeUISettingsFrameURL); - source->AddString("settingsHost", chrome::kChromeUISettingsHost); - - return source; -} - -content::WebUIDataSource* CreateUberFrameHTMLSource( - content::BrowserContext* browser_context) { - content::WebUIDataSource* source = - content::WebUIDataSource::Create(chrome::kChromeUIUberFrameHost); - Profile* profile = Profile::FromBrowserContext(browser_context); - - source->SetJsonPath("strings.js"); - source->AddResourcePath("uber_frame.js", IDR_UBER_FRAME_JS); - source->SetDefaultResource(IDR_UBER_FRAME_HTML); - - // TODO(jhawkins): Attempt to get rid of IDS_SHORT_PRODUCT_OS_NAME. -#if defined(OS_CHROMEOS) - source->AddLocalizedString("shortProductName", IDS_SHORT_PRODUCT_OS_NAME); -#else - source->AddLocalizedString("shortProductName", IDS_SHORT_PRODUCT_NAME); -#endif // defined(OS_CHROMEOS) - - source->AddBoolean("hideExtensions", - base::FeatureList::IsEnabled(features::kMaterialDesignExtensions)); - source->AddBoolean("hideSettingsAndHelp", - ::switches::SettingsWindowEnabled() || - base::FeatureList::IsEnabled(features::kMaterialDesignSettings)); - source->AddString("extensionsHost", chrome::kChromeUIExtensionsHost); - source->AddLocalizedString("extensionsDisplayName", - IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE); - source->AddString("helpHost", chrome::kChromeUIHelpHost); - source->AddLocalizedString("helpDisplayName", IDS_ABOUT_TITLE); - source->AddString("settingsHost", chrome::kChromeUISettingsHost); - source->AddLocalizedString("settingsDisplayName", IDS_SETTINGS_TITLE); - - source->DisableDenyXFrameOptions(); - source->OverrideContentSecurityPolicyChildSrc("child-src chrome:;"); - - source->AddBoolean("profileIsGuest", profile->IsGuestSession()); - - return source; -} - -} // namespace - -SubframeLogger::SubframeLogger(content::WebContents* contents) - : WebContentsObserver(contents) {} - -SubframeLogger::~SubframeLogger() {} - -void SubframeLogger::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - if (!navigation_handle->HasCommitted()) - return; - - const GURL& url = navigation_handle->GetURL(); - if (url == chrome::kChromeUIExtensionsFrameURL || - url == chrome::kChromeUIHelpFrameURL || - url == chrome::kChromeUISettingsFrameURL || - url == chrome::kChromeUIUberFrameURL) { - webui::LogWebUIUrl(url); - } -} - -UberUI::UberUI(content::WebUI* web_ui) : WebUIController(web_ui) { - subframe_logger_ = base::MakeUnique<SubframeLogger>(web_ui->GetWebContents()); - content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), - CreateUberHTMLSource()); - - RegisterSubpage(chrome::kChromeUIExtensionsFrameURL, - chrome::kChromeUIExtensionsHost); - RegisterSubpage(chrome::kChromeUIHelpFrameURL, - chrome::kChromeUIHelpHost); - RegisterSubpage(chrome::kChromeUISettingsFrameURL, - chrome::kChromeUISettingsHost); - RegisterSubpage(chrome::kChromeUIUberFrameURL, - chrome::kChromeUIUberHost); -} - -UberUI::~UberUI() { -} - -void UberUI::RegisterSubpage(const std::string& page_url, - const std::string& page_host) { - sub_uis_[page_url] = web_ui()->GetWebContents()->CreateSubframeWebUI( - GURL(page_url), page_host); -} - -content::WebUI* UberUI::GetSubpage(const std::string& page_url) { - if (!base::ContainsKey(sub_uis_, page_url)) - return nullptr; - return sub_uis_[page_url].get(); -} - -void UberUI::RenderFrameCreated(RenderFrameHost* render_frame_host) { - for (auto iter = sub_uis_.begin(); iter != sub_uis_.end(); ++iter) { - iter->second->GetController()->RenderFrameCreated(render_frame_host); - } -} - -bool UberUI::OverrideHandleWebUIMessage(const GURL& source_url, - const std::string& message, - const base::ListValue& args) { - // Find the appropriate subpage and forward the message. - auto subpage = sub_uis_.find(source_url.GetOrigin().spec()); - if (subpage == sub_uis_.end()) { - // The message was sent from the uber page itself. - DCHECK_EQ(std::string(chrome::kChromeUIUberHost), source_url.host()); - return false; - } - - // The message was sent from a subpage. - // TODO(jam) fix this to use interface - // return subpage->second->GetController()->OverrideHandleWebUIMessage( - // source_url, message, args); - subpage->second->ProcessWebUIMessage(source_url, message, args); - return true; -} - -// UberFrameUI - -UberFrameUI::UberFrameUI(content::WebUI* web_ui) : WebUIController(web_ui) { - content::BrowserContext* browser_context = - web_ui->GetWebContents()->GetBrowserContext(); - content::WebUIDataSource::Add(browser_context, - CreateUberFrameHTMLSource(browser_context)); -} - -UberFrameUI::~UberFrameUI() { -} diff --git a/chromium/chrome/browser/ui/webui/uber/uber_ui.h b/chromium/chrome/browser/ui/webui/uber/uber_ui.h deleted file mode 100644 index 8be770897ad..00000000000 --- a/chromium/chrome/browser/ui/webui/uber/uber_ui.h +++ /dev/null @@ -1,66 +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 CHROME_BROWSER_UI_WEBUI_UBER_UBER_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_UBER_UBER_UI_H_ - -#include <string> - -#include "base/macros.h" -#include "base/values.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_ui_controller.h" - -// Logs visits to subframe URLs (e.g. chrome://settings-frame). -class SubframeLogger : public content::WebContentsObserver { - public: - explicit SubframeLogger(content::WebContents* contents); - ~SubframeLogger() override; - - // content::WebContentsObserver implementation. - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; - - private: - DISALLOW_COPY_AND_ASSIGN(SubframeLogger); -}; - -// The WebUI class for the uber page (chrome://chrome). It manages the UI for -// the uber page (navigation bar and so forth) as well as WebUI objects for -// pages that appear in the uber page. -class UberUI : public content::WebUIController { - public: - explicit UberUI(content::WebUI* web_ui); - ~UberUI() override; - - content::WebUI* GetSubpage(const std::string& page_url); - - // WebUIController implementation. - bool OverrideHandleWebUIMessage(const GURL& source_url, - const std::string& message, - const base::ListValue& args) override; - - // We forward these to |sub_uis_|. - void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; - - private: - // Creates and stores a WebUI for the given URL. - void RegisterSubpage(const std::string& page_url, - const std::string& page_host); - - std::unique_ptr<SubframeLogger> subframe_logger_; - - // Map from URL origin to WebUI instance. - std::map<std::string, std::unique_ptr<content::WebUI>> sub_uis_; - - DISALLOW_COPY_AND_ASSIGN(UberUI); -}; - -class UberFrameUI : public content::WebUIController { - public: - explicit UberFrameUI(content::WebUI* web_ui); - ~UberFrameUI() override; -}; - -#endif // CHROME_BROWSER_UI_WEBUI_UBER_UBER_UI_H_ diff --git a/chromium/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc deleted file mode 100644 index 01eca7bb383..00000000000 --- a/chromium/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2015 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 <string> -#include <utility> - -#include "base/command_line.h" -#include "base/macros.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/test_extension_system.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/ui_test_utils.h" -#include "chrome/test/base/web_ui_browser_test.h" -#include "content/public/common/content_switches.h" -#include "content/public/test/browser_test_utils.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/extension.h" -#include "extensions/common/extension_builder.h" - -class UberUIBrowserTest : public WebUIBrowserTest { - public: - UberUIBrowserTest() {} - ~UberUIBrowserTest() override {} - - bool GetJsBool(const char* js) { - bool result = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - GetWebContents(), - std::string("domAutomationController.send(") + js + ");", - &result)); - return result; - } - - void SelectTab(const std::string& name) { - ASSERT_TRUE(content::ExecuteScript( - GetWebContents(), - std::string("var data = {pageId: '") + name + "'};" + - "uber.invokeMethodOnWindow(this, 'changeSelection', data);")); - } - - private: - content::WebContents* GetWebContents() { - return browser()->tab_strip_model()->GetActiveWebContents(); - } - - DISALLOW_COPY_AND_ASSIGN(UberUIBrowserTest); -}; - -IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, EnableMdExtensionsHidesExtensions) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({features::kMaterialDesignExtensions}, - {features::kMaterialDesignSettings}); - - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL)); - SelectTab("settings"); - EXPECT_TRUE(GetJsBool("$('extensions').hidden")); -} - -IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, EnableMdSettingsHidesSettings) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({features::kMaterialDesignSettings}, - {features::kMaterialDesignExtensions}); - - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL)); - SelectTab("extensions"); - EXPECT_TRUE(GetJsBool("$('settings').hidden && $('help').hidden")); -} - -IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, - EnableSettingsWindowHidesSettingsAndHelp) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(features::kMaterialDesignSettings); - - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ::switches::kEnableSettingsWindow); - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL)); - SelectTab("extensions"); - EXPECT_TRUE(GetJsBool("$('settings').hidden && $('help').hidden")); -} diff --git a/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc b/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc index aa60c9c9a5f..ebe1ce21566 100644 --- a/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc +++ b/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.cc @@ -18,10 +18,10 @@ UsbInternalsUI::UsbInternalsUI(content::WebUI* web_ui) source->AddResourcePath("usb_internals.css", IDR_USB_INTERNALS_CSS); source->AddResourcePath("usb_internals.js", IDR_USB_INTERNALS_JS); source->AddResourcePath( - "chrome/browser/ui/webui/usb_internals/usb_internals.mojom", + "chrome/browser/ui/webui/usb_internals/usb_internals.mojom.js", IDR_USB_INTERNALS_MOJO_JS); - source->AddResourcePath("url/mojo/origin.mojom", IDR_ORIGIN_MOJO_JS); - source->AddResourcePath("url/mojo/url.mojom", IDR_URL_MOJO_JS); + source->AddResourcePath("url/mojo/origin.mojom.js", IDR_ORIGIN_MOJO_JS); + source->AddResourcePath("url/mojo/url.mojom.js", IDR_URL_MOJO_JS); source->SetDefaultResource(IDR_USB_INTERNALS_HTML); source->UseGzip(std::unordered_set<std::string>()); @@ -31,7 +31,6 @@ UsbInternalsUI::UsbInternalsUI(content::WebUI* web_ui) UsbInternalsUI::~UsbInternalsUI() {} void UsbInternalsUI::BindUIHandler( - const service_manager::BindSourceInfo& source_info, mojom::UsbInternalsPageHandlerRequest request) { page_handler_.reset(new UsbInternalsPageHandler(std::move(request))); } diff --git a/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h b/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h index 72985ebbf7f..0b0a3436bb7 100644 --- a/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h +++ b/chromium/chrome/browser/ui/webui/usb_internals/usb_internals_ui.h @@ -20,8 +20,7 @@ class UsbInternalsUI private: // MojoWebUIController overrides: - void BindUIHandler(const service_manager::BindSourceInfo& source_info, - mojom::UsbInternalsPageHandlerRequest request) override; + void BindUIHandler(mojom::UsbInternalsPageHandlerRequest request) override; std::unique_ptr<UsbInternalsPageHandler> page_handler_; diff --git a/chromium/chrome/browser/ui/webui/version_handler.cc b/chromium/chrome/browser/ui/webui/version_handler.cc index d95e8dff4ea..e061d1c36f9 100644 --- a/chromium/chrome/browser/ui/webui/version_handler.cc +++ b/chromium/chrome/browser/ui/webui/version_handler.cc @@ -12,6 +12,8 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/plugins/plugin_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/grit/generated_resources.h" @@ -33,7 +35,7 @@ namespace { void GetFilePaths(const base::FilePath& profile_path, base::string16* exec_path_out, base::string16* profile_path_out) { - DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); + base::ThreadRestrictions::AssertIOAllowed(); base::FilePath executable_path = base::MakeAbsoluteFilePath( base::CommandLine::ForCurrentProcess()->GetProgram()); @@ -78,8 +80,8 @@ void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { // OnGotFilePaths. base::string16* exec_path_buffer = new base::string16; base::string16* profile_path_buffer = new base::string16; - content::BrowserThread::PostTaskAndReply( - content::BrowserThread::FILE, FROM_HERE, + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, base::BindOnce(&GetFilePaths, Profile::FromWebUI(web_ui())->GetPath(), base::Unretained(exec_path_buffer), base::Unretained(profile_path_buffer)), diff --git a/chromium/chrome/browser/ui/webui/version_ui.cc b/chromium/chrome/browser/ui/webui/version_ui.cc index 632d0ea50c1..d01a8c85d7e 100644 --- a/chromium/chrome/browser/ui/webui/version_ui.cc +++ b/chromium/chrome/browser/ui/webui/version_ui.cc @@ -14,12 +14,10 @@ #include "chrome/common/channel_info.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/install_static/install_details.h" #include "components/grit/components_resources.h" -#include "components/strings/grit/components_chromium_strings.h" #include "components/strings/grit/components_strings.h" #include "components/version_info/version_info.h" #include "components/version_ui/version_ui_constants.h" @@ -146,7 +144,7 @@ WebUIDataSource* CreateVersionUIDataSource() { #else html_source->AddString(version_ui::kCompiler, "MSVC 2015"); #endif -#elif defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1911 +#elif defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER < 2000 #if BUILDFLAG(PGO_BUILD) html_source->AddString(version_ui::kCompiler, "MSVC 2017 (PGO)"); #else @@ -164,6 +162,8 @@ WebUIDataSource* CreateVersionUIDataSource() { html_source->AddString(version_ui::kUpdateCohortName, l10n_util::GetStringFUTF16( IDS_VERSION_UI_COHORT_NAME, update_cohort_name)); + } else { + html_source->AddString(version_ui::kUpdateCohortName, std::string()); } #endif // defined(OS_WIN) diff --git a/chromium/chrome/browser/ui/webui/voice_search_ui.cc b/chromium/chrome/browser/ui/webui/voice_search_ui.cc index 6e3882b6949..c80ce793747 100644 --- a/chromium/chrome/browser/ui/webui/voice_search_ui.cc +++ b/chromium/chrome/browser/ui/webui/voice_search_ui.cc @@ -16,6 +16,8 @@ #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_service.h" @@ -105,9 +107,8 @@ void AddLineBreak(base::ListValue* list) { } void AddSharedModulePlatformsOnFileThread(base::ListValue* list, - const base::FilePath& path, - base::Closure callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); + const base::FilePath& path) { + base::ThreadRestrictions::AssertIOAllowed(); if (!path.empty()) { // Display available platforms for shared module. @@ -125,10 +126,6 @@ void AddSharedModulePlatformsOnFileThread(base::ListValue* list, files.empty() ? ASCIIToUTF16("undefined") : files); AddLineBreak(list); } - - content::BrowserThread::PostTask(content::BrowserThread::UI, - FROM_HERE, - callback); } //////////////////////////////////////////////////////////////////////////////// @@ -202,12 +199,12 @@ class VoiceSearchDomHandler : public WebUIMessageHandler { path = extension->path(); } base::ListValue* raw_list = list.get(); - content::BrowserThread::PostTask( - content::BrowserThread::FILE, FROM_HERE, - base::Bind(&AddSharedModulePlatformsOnFileThread, raw_list, path, - base::Bind(&VoiceSearchDomHandler::ReturnVoiceSearchInfo, - weak_factory_.GetWeakPtr(), - base::Passed(std::move(list))))); + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, + base::BindOnce(&AddSharedModulePlatformsOnFileThread, raw_list, path), + base::BindOnce(&VoiceSearchDomHandler::ReturnVoiceSearchInfo, + weak_factory_.GetWeakPtr(), + base::Passed(std::move(list)))); } // Adds information regarding the system and chrome version info to list. diff --git a/chromium/chrome/browser/ui/webui/webapks_ui.cc b/chromium/chrome/browser/ui/webui/webapks_ui.cc index d713293024c..bb6b617666e 100644 --- a/chromium/chrome/browser/ui/webui/webapks_ui.cc +++ b/chromium/chrome/browser/ui/webui/webapks_ui.cc @@ -11,7 +11,6 @@ #include "chrome/browser/ui/webui/webapks_handler.h" #include "chrome/common/url_constants.h" #include "chrome/grit/webapks_ui_resources.h" -#include "components/grit/components_resources.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" diff --git a/chromium/chrome/browser/ui/webui/welcome_win10_ui.cc b/chromium/chrome/browser/ui/webui/welcome_win10_ui.cc index 8628e5b9dde..c5741b98c5f 100644 --- a/chromium/chrome/browser/ui/webui/welcome_win10_ui.cc +++ b/chromium/chrome/browser/ui/webui/welcome_win10_ui.cc @@ -18,7 +18,6 @@ #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" -#include "chrome/grit/theme_resources.h" #include "components/prefs/pref_service.h" #include "content/public/browser/web_ui_data_source.h" #include "net/base/url_util.h" |