diff --git a/DEPS b/DEPS index 9553c1d..0663d3bc 100644 --- a/DEPS +++ b/DEPS
@@ -195,11 +195,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'c1c3c6d70d326a27b7b9fa82203ff2db28043be7', + 'skia_revision': 'c4245f475be744ef91f55764b43d9dcaefe63d3b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '26d2954fbe8d1d68f3daf3fc59f1826dd91d6383', + 'v8_revision': 'f8df7e0af9c692d5e3b3aa3aa4bd17aa686d4134', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -207,7 +207,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '9ae6d7f2ee9e12b707483dc9cadd7c3529595016', + 'angle_revision': 'd852ad24adc0c62ecb520835c1a835a42d3495e2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -215,7 +215,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5f4456e3c52fbe17db79da16b1122f21dbcd3582', + 'pdfium_revision': '807e4fa951b9aae0c9355abae7d379b70a5f8677', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -258,7 +258,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '5abddab6695ed03674a936d0fe48ce68bd1efd3e', + 'catapult_revision': '3f714d9026a262760813a0ae24d85bec686e9def', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -266,7 +266,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'c0263ae980bf6d062fac2e520e6046beece610f5', + 'devtools_frontend_revision': '467b0b16324b77b597e69237ae934f80118e55f6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -1542,7 +1542,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f1b37b7a9dad80220a166305ef17a5da9f1fbfe1', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@384ea8475558f5142f755fc4cdb9db0ea7d853b5', 'condition': 'checkout_src_internal', },
diff --git a/ash/accessibility/accessibility_focus_ring_group.cc b/ash/accessibility/accessibility_focus_ring_group.cc index a157cdc..cbbbd78 100644 --- a/ash/accessibility/accessibility_focus_ring_group.cc +++ b/ash/accessibility/accessibility_focus_ring_group.cc
@@ -115,10 +115,8 @@ return; } - double fraction = delta / transition_time; - // Ease-in effect. - fraction = pow(fraction, 0.3); + const double fraction = pow(delta / transition_time, 0.3); // Handle corner case where we're animating but we don't have previous // rings. @@ -129,8 +127,8 @@ previous_focus_rings_[0], focus_rings_[0], fraction)); } else { ash::ComputeOpacity(&(focus_animation_info_), timestamp); - for (size_t i = 0; i < focus_layers_.size(); ++i) - focus_layers_[i]->SetOpacity(focus_animation_info_.opacity); + for (auto& focus_layer : focus_layers_) + focus_layer->SetOpacity(focus_animation_info_.opacity); } }
diff --git a/ash/accessibility/layer_animation_info.cc b/ash/accessibility/layer_animation_info.cc index 70897ef..a19d9aef 100644 --- a/ash/accessibility/layer_animation_info.cc +++ b/ash/accessibility/layer_animation_info.cc
@@ -33,9 +33,7 @@ opacity = 1.0 - (change_delta / (fade_in_time + fade_out_time)); // Layer::SetOpacity will throw an error if we're not within 0...1. - opacity = base::ClampToRange(opacity, 0.0f, 1.0f); - - animation_info->opacity = opacity; + animation_info->opacity = base::ClampToRange(opacity, 0.0f, 1.0f); } } // namespace ash \ No newline at end of file
diff --git a/ash/accessibility/spoken_feedback_enabler.cc b/ash/accessibility/spoken_feedback_enabler.cc index 1a2656ba..ff047db 100644 --- a/ash/accessibility/spoken_feedback_enabler.cc +++ b/ash/accessibility/spoken_feedback_enabler.cc
@@ -33,8 +33,7 @@ void SpokenFeedbackEnabler::OnTimer() { base::TimeTicks now = ui::EventTimeForNow(); - double tick_count_f = (now - start_time_) / kTimerDelay; - int tick_count = base::ClampRound(tick_count_f); + int tick_count = base::ClampRound((now - start_time_) / kTimerDelay); AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller();
diff --git a/ash/accessibility/touch_accessibility_enabler.cc b/ash/accessibility/touch_accessibility_enabler.cc index b413cbe..ec8a1e1 100644 --- a/ash/accessibility/touch_accessibility_enabler.cc +++ b/ash/accessibility/touch_accessibility_enabler.cc
@@ -159,9 +159,8 @@ } void TouchAccessibilityEnabler::OnTimer() { - base::TimeTicks now = Now(); - double tick_count_f = (now - two_finger_start_time_) / kTimerDelay; - int tick_count = base::ClampRound(tick_count_f); + const int tick_count = + base::ClampRound((Now() - two_finger_start_time_) / kTimerDelay); if (tick_count == kTimerTicksOfFirstSoundFeedback) { base::RecordAction(
diff --git a/ash/fast_ink/fast_ink_points.cc b/ash/fast_ink/fast_ink_points.cc index bcd2813..fb1ee72 100644 --- a/ash/fast_ink/fast_ink_points.cc +++ b/ash/fast_ink/fast_ink_points.cc
@@ -95,8 +95,9 @@ float FastInkPoints::GetFadeoutFactor(int index) const { DCHECK(!life_duration_.is_zero()); - DCHECK(0 <= index && index < GetNumberOfPoints()); - base::TimeDelta age = collection_latest_time_ - points_[index].time; + DCHECK_GE(index, 0); + DCHECK_LT(index, GetNumberOfPoints()); + const base::TimeDelta age = collection_latest_time_ - points_[index].time; return std::min(age / life_duration_, 1.0); }
diff --git a/ash/public/cpp/fps_counter.cc b/ash/public/cpp/fps_counter.cc index c205e16..189682c0 100644 --- a/ash/public/cpp/fps_counter.cc +++ b/ash/public/cpp/fps_counter.cc
@@ -35,9 +35,7 @@ base::TimeDelta elapsed = base::TimeTicks::Now() - start_time_; float refresh_rate = compositor_->refresh_rate(); - int expected_frame_number = - std::floor(refresh_rate * elapsed.InMillisecondsF() / - base::Time::kMillisecondsPerSecond); + const int expected_frame_number = (refresh_rate * elapsed).InSeconds(); int actual_frame_number = end_frame_number - start_frame_number_; int smoothness = actual_frame_number < expected_frame_number ? smoothness =
diff --git a/ash/public/cpp/power_utils.cc b/ash/public/cpp/power_utils.cc index 698defb..931230c 100644 --- a/ash/public/cpp/power_utils.cc +++ b/ash/public/cpp/power_utils.cc
@@ -32,9 +32,9 @@ int* minutes) { DCHECK(hours); DCHECK(minutes); - const int total_minutes = base::ClampRound(time.InSecondsF() / 60); - *hours = total_minutes / 60; - *minutes = total_minutes % 60; + *minutes = base::ClampRound(time / base::TimeDelta::FromMinutes(1)); + *hours = *minutes / 60; + *minutes %= 60; } } // namespace power_utils
diff --git a/ash/system/power/power_notification_controller.cc b/ash/system/power/power_notification_controller.cc index 57d3d9e..be46891 100644 --- a/ash/system/power/power_notification_controller.cc +++ b/ash/system/power/power_notification_controller.cc
@@ -200,7 +200,7 @@ // The notification includes a rounded minutes value, so round the estimate // received from the power manager to match. const int remaining_minutes = - base::ClampRound(remaining_time->InSecondsF() / 60.0); + base::ClampRound(*remaining_time / base::TimeDelta::FromMinutes(1)); if (remaining_minutes >= kNoWarningMinutes || PowerStatus::Get()->IsBatteryFull()) {
diff --git a/build/fuchsia/device_target.py b/build/fuchsia/device_target.py index 8e23c67..4723eee 100644 --- a/build/fuchsia/device_target.py +++ b/build/fuchsia/device_target.py
@@ -85,7 +85,7 @@ self._port = port if port else 22 self._system_log_file = system_log_file self._host = host - self._fuchsia_out_dir = os.path.expanduser(fuchsia_out_dir) + self._fuchsia_out_dir = fuchsia_out_dir self._node_name = node_name self._os_check = os_check self._amber_repo = None @@ -98,6 +98,7 @@ raise Exception('Only one of "--fuchsia-out-dir" or "--ssh_config" can ' 'be specified.') + self._fuchsia_out_dir = os.path.expanduser(fuchsia_out_dir) # Use SSH keys from the Fuchsia output directory. self._ssh_config_path = os.path.join(self._fuchsia_out_dir, 'ssh-keys', 'ssh_config')
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 9e15f93..d9420410 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200815.3.1 +0.20200816.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 66548964..d9420410 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200815.2.1 +0.20200816.3.1
diff --git a/build/linux/sysroot_scripts/libwayland-client-symbols b/build/linux/sysroot_scripts/libwayland-client-symbols new file mode 100644 index 0000000..d6bffeb --- /dev/null +++ b/build/linux/sysroot_scripts/libwayland-client-symbols
@@ -0,0 +1,74 @@ +libwayland-client.so.0 libwayland-client0 #MINVER# + wl_array_add@Base 1.4.0 + wl_array_copy@Base 1.4.0 + wl_array_init@Base 1.4.0 + wl_array_release@Base 1.4.0 + wl_buffer_interface@Base 1.4.0 + wl_callback_interface@Base 1.4.0 + wl_compositor_interface@Base 1.4.0 + wl_data_device_interface@Base 1.4.0 + wl_data_device_manager_interface@Base 1.4.0 + wl_data_offer_interface@Base 1.4.0 + wl_data_source_interface@Base 1.4.0 + wl_display_cancel_read@Base 1.4.0 + wl_display_connect@Base 1.4.0 + wl_display_connect_to_fd@Base 1.4.0 + wl_display_create_queue@Base 1.4.0 + wl_display_disconnect@Base 1.4.0 + wl_display_dispatch@Base 1.4.0 + wl_display_dispatch_pending@Base 1.4.0 + wl_display_dispatch_queue@Base 1.4.0 + wl_display_dispatch_queue_pending@Base 1.4.0 + wl_display_flush@Base 1.4.0 + wl_display_get_error@Base 1.4.0 + wl_display_get_fd@Base 1.4.0 + wl_display_get_protocol_error@Base 1.4.0 + wl_display_interface@Base 1.4.0 + wl_display_prepare_read@Base 1.4.0 + wl_display_prepare_read_queue@Base 1.4.0 + wl_display_read_events@Base 1.4.0 + wl_display_roundtrip@Base 1.4.0 + wl_display_roundtrip_queue@Base 1.4.0 + wl_event_queue_destroy@Base 1.4.0 + wl_keyboard_interface@Base 1.4.0 + wl_list_empty@Base 1.4.0 + wl_list_init@Base 1.4.0 + wl_list_insert@Base 1.4.0 + wl_list_insert_list@Base 1.4.0 + wl_list_length@Base 1.4.0 + wl_list_remove@Base 1.4.0 + wl_log_set_handler_client@Base 1.4.0 + wl_output_interface@Base 1.4.0 + wl_pointer_interface@Base 1.4.0 + wl_proxy_add_dispatcher@Base 1.4.0 + wl_proxy_add_listener@Base 1.4.0 + wl_proxy_create@Base 1.4.0 + wl_proxy_create_wrapper@Base 1.4.0 + wl_proxy_destroy@Base 1.4.0 + wl_proxy_get_class@Base 1.4.0 + wl_proxy_get_id@Base 1.4.0 + wl_proxy_get_listener@Base 1.4.0 + wl_proxy_get_tag@Base 1.4.0 + wl_proxy_get_user_data@Base 1.4.0 + wl_proxy_get_version@Base 1.4.0 + wl_proxy_marshal@Base 1.4.0 + wl_proxy_marshal_array@Base 1.4.0 + wl_proxy_marshal_array_constructor@Base 1.4.0 + wl_proxy_marshal_array_constructor_versioned@Base 1.4.0 + wl_proxy_marshal_constructor@Base 1.4.0 + wl_proxy_marshal_constructor_versioned@Base 1.4.0 + wl_proxy_set_queue@Base 1.4.0 + wl_proxy_set_tag@Base 1.4.0 + wl_proxy_set_user_data@Base 1.4.0 + wl_proxy_wrapper_destroy@Base 1.4.0 + wl_region_interface@Base 1.4.0 + wl_registry_interface@Base 1.4.0 + wl_seat_interface@Base 1.4.0 + wl_shell_interface@Base 1.4.0 + wl_shell_surface_interface@Base 1.4.0 + wl_shm_interface@Base 1.4.0 + wl_shm_pool_interface@Base 1.4.0 + wl_subcompositor_interface@Base 1.4.0 + wl_subsurface_interface@Base 1.4.0 + wl_surface_interface@Base 1.4.0 + wl_touch_interface@Base 1.4.0
diff --git a/build/linux/sysroot_scripts/libxkbcommon0-symbols b/build/linux/sysroot_scripts/libxkbcommon0-symbols new file mode 100644 index 0000000..5750fc0 --- /dev/null +++ b/build/linux/sysroot_scripts/libxkbcommon0-symbols
@@ -0,0 +1,93 @@ +libxkbcommon.so.0 libxkbcommon0 #MINVER# + xkb_context_get_log_level@Base 0.4.1 + xkb_context_get_log_verbosity@Base 0.4.1 + xkb_context_get_user_data@Base 0.4.1 + xkb_context_include_path_append@Base 0.4.1 + xkb_context_include_path_append_default@Base 0.4.1 + xkb_context_include_path_clear@Base 0.4.1 + xkb_context_include_path_get@Base 0.4.1 + xkb_context_include_path_reset_defaults@Base 0.4.1 + xkb_context_new@Base 0.4.1 + xkb_context_num_include_paths@Base 0.4.1 + xkb_context_ref@Base 0.4.1 + xkb_context_set_log_fn@Base 0.4.1 + xkb_context_set_log_level@Base 0.4.1 + xkb_context_set_log_verbosity@Base 0.4.1 + xkb_context_set_user_data@Base 0.4.1 + xkb_context_unref@Base 0.4.1 + xkb_key_get_syms@Base 0.4.1 + xkb_key_mod_index_is_consumed@Base 0.4.1 + xkb_key_mod_mask_remove_consumed@Base 0.4.1 + xkb_key_num_groups@Base 0.4.1 + xkb_key_repeats@Base 0.4.1 + xkb_keymap_get_as_string@Base 0.4.1 + xkb_keymap_key_for_each@Base 0.4.1 + xkb_keymap_key_get_syms_by_level@Base 0.4.1 + xkb_keymap_key_repeats@Base 0.4.1 + xkb_keymap_layout_get_index@Base 0.4.1 + xkb_keymap_layout_get_name@Base 0.4.1 + xkb_keymap_led_get_index@Base 0.4.1 + xkb_keymap_led_get_name@Base 0.4.1 + xkb_keymap_max_keycode@Base 0.4.1 + xkb_keymap_min_keycode@Base 0.4.1 + xkb_keymap_mod_get_index@Base 0.4.1 + xkb_keymap_mod_get_name@Base 0.4.1 + xkb_keymap_new_from_buffer@Base 0.4.1 + xkb_keymap_new_from_file@Base 0.4.1 + xkb_keymap_new_from_names@Base 0.4.1 + xkb_keymap_new_from_string@Base 0.4.1 + xkb_keymap_num_layouts@Base 0.4.1 + xkb_keymap_num_layouts_for_key@Base 0.4.1 + xkb_keymap_num_leds@Base 0.4.1 + xkb_keymap_num_levels_for_key@Base 0.4.1 + xkb_keymap_num_mods@Base 0.4.1 + xkb_keymap_ref@Base 0.4.1 + xkb_keymap_unref@Base 0.4.1 + xkb_keysym_from_name@Base 0.4.1 + xkb_keysym_get_name@Base 0.4.1 + xkb_keysym_to_utf32@Base 0.4.1 + xkb_keysym_to_utf8@Base 0.4.1 + xkb_map_get_as_string@Base 0.4.1 + xkb_map_group_get_index@Base 0.4.1 + xkb_map_group_get_name@Base 0.4.1 + xkb_map_led_get_index@Base 0.4.1 + xkb_map_led_get_name@Base 0.4.1 + xkb_map_mod_get_index@Base 0.4.1 + xkb_map_mod_get_name@Base 0.4.1 + xkb_map_new_from_file@Base 0.4.1 + xkb_map_new_from_names@Base 0.4.1 + xkb_map_new_from_string@Base 0.4.1 + xkb_map_num_groups@Base 0.4.1 + xkb_map_num_leds@Base 0.4.1 + xkb_map_num_mods@Base 0.4.1 + xkb_map_ref@Base 0.4.1 + xkb_map_unref@Base 0.4.1 + xkb_state_get_keymap@Base 0.4.1 + xkb_state_get_map@Base 0.4.1 + xkb_state_group_index_is_active@Base 0.4.1 + xkb_state_group_name_is_active@Base 0.4.1 + xkb_state_key_get_consumed_mods@Base 0.4.1 + xkb_state_key_get_layout@Base 0.4.1 + xkb_state_key_get_level@Base 0.4.1 + xkb_state_key_get_one_sym@Base 0.4.1 + xkb_state_key_get_syms@Base 0.4.1 + xkb_state_key_get_utf32@Base 0.4.1 + xkb_state_key_get_utf8@Base 0.4.1 + xkb_state_layout_index_is_active@Base 0.4.1 + xkb_state_layout_name_is_active@Base 0.4.1 + xkb_state_led_index_is_active@Base 0.4.1 + xkb_state_led_name_is_active@Base 0.4.1 + xkb_state_mod_index_is_active@Base 0.4.1 + xkb_state_mod_index_is_consumed@Base 0.4.1 + xkb_state_mod_indices_are_active@Base 0.4.1 + xkb_state_mod_mask_remove_consumed@Base 0.4.1 + xkb_state_mod_name_is_active@Base 0.4.1 + xkb_state_mod_names_are_active@Base 0.4.1 + xkb_state_new@Base 0.4.1 + xkb_state_ref@Base 0.4.1 + xkb_state_serialize_group@Base 0.4.1 + xkb_state_serialize_layout@Base 0.4.1 + xkb_state_serialize_mods@Base 0.4.1 + xkb_state_unref@Base 0.4.1 + xkb_state_update_key@Base 0.4.1 + xkb_state_update_mask@Base 0.4.1
diff --git a/build/linux/sysroot_scripts/sysroot-creator.sh b/build/linux/sysroot_scripts/sysroot-creator.sh index 4b46e995..6aed2153 100644 --- a/build/linux/sysroot_scripts/sysroot-creator.sh +++ b/build/linux/sysroot_scripts/sysroot-creator.sh
@@ -326,16 +326,27 @@ sed -i -e 's|/usr/lib/${arch}-${os}/||g' ${lscripts} sed -i -e 's|/lib/${arch}-${os}/||g' ${lscripts} - # Unversion libdbus symbols. This is required because libdbus-1-3 - # switched from unversioned symbols to versioned ones, and we must - # still support distros using the unversioned library. This hack - # can be removed once support for Ubuntu Trusty and Debian Jessie - # are dropped. + # Unversion libdbus, libxkbcommon, and libwayland-client symbols. + # This is required because libdbus-1-3, libwayland-client0 and + # libxkbcommon0 switched from unversioned symbols to versioned + # ones, and we must still support distros using the unversioned library. + # This hack can be removed once support for Ubuntu Trusty and Debian + # Jessie are dropped. ${strip} -R .gnu.version_d -R .gnu.version \ "${INSTALL_ROOT}/lib/${arch}-${os}/libdbus-1.so.3" cp "${SCRIPT_DIR}/libdbus-1-3-symbols" \ "${INSTALL_ROOT}/debian/libdbus-1-3/DEBIAN/symbols" + ${strip} -R .gnu.version_d -R .gnu.version \ + "${INSTALL_ROOT}/usr/lib/${arch}-${os}/libwayland-client.so.0.3.0" + cp "${SCRIPT_DIR}/libwayland-client-symbols" \ + "${INSTALL_ROOT}/debian/libwayland-client0/DEBIAN/symbols" + + ${strip} -R .gnu.version_d -R .gnu.version \ + "${INSTALL_ROOT}/usr/lib/${arch}-${os}/libxkbcommon.so.0.0.0" + cp "${SCRIPT_DIR}/libxkbcommon0-symbols" \ + "${INSTALL_ROOT}/debian/libxkbcommon0/DEBIAN/symbols" + # Shared objects depending on libdbus-1.so.3 have unsatisfied undefined # versioned symbols. To avoid LLD --no-allow-shlib-undefined errors, rewrite # DT_NEEDED entries from libdbus-1.so.3 to a different string. LLD will
diff --git a/chrome/VERSION b/chrome/VERSION index 40d6444..552f0e9 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=86 MINOR=0 -BUILD=4236 +BUILD=4237 PATCH=0
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index eec87817..9d269f2 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -915,6 +915,7 @@ "java/res/layout/homepage_editor.xml", "java/res/layout/icon_row_menu_footer.xml", "java/res/layout/incognito_description_layout.xml", + "java/res/layout/incognito_interstitial_bottom_sheet_view.xml", "java/res/layout/incognito_toggle_tabs.xml", "java/res/layout/infobar_control_url_ellipsizer.xml", "java/res/layout/infobar_translate_compact_content.xml",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java index 12a9c82..2c637a69 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java
@@ -265,7 +265,12 @@ model.getHeaderModel().addObserver((source, propertyKey) -> { if (propertyKey == AssistantHeaderModel.CHIPS_VISIBLE || propertyKey == AssistantHeaderModel.CHIPS) { - animateChildren(rootView); + // The PostTask is necessary as a workaround for the sticky button occasionally not + // showing, since the chip changes are now issued in the following UI iteration, the + // same needs to be done for the corresponding animations. + // TODO(b/164389932): Figure out a better fix that doesn't require issuing the + // change in the following UI iteration. + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> animateChildren(rootView)); } });
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java index 7afb8db..6558853 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java
@@ -14,6 +14,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.RecyclerView; +import org.chromium.base.task.PostTask; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.AssistantTextUtils; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChipAdapter; @@ -22,6 +23,7 @@ import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.widget.textbubble.TextBubble; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.widget.ViewRectProvider; @@ -134,15 +136,21 @@ } private void maybeShowChips(AssistantHeaderModel model, ViewHolder view) { - if (model.get(AssistantHeaderModel.CHIPS_VISIBLE) - && !model.get(AssistantHeaderModel.CHIPS).isEmpty()) { - view.mChipsContainer.setVisibility(View.VISIBLE); - view.mProfileIconView.setVisibility(View.GONE); - } else { - view.mChipsContainer.setVisibility(View.GONE); - - view.mProfileIconView.setVisibility(View.VISIBLE); - } + // The PostTask is necessary as a workaround for the sticky button occasionally not showing, + // this makes sure that the change happens after any possibly clashing animation currently + // happening. + // TODO(b/164389932): Figure out a better fix that doesn't require issuing the change in the + // following UI iteration. + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { + if (model.get(AssistantHeaderModel.CHIPS_VISIBLE) + && !model.get(AssistantHeaderModel.CHIPS).isEmpty()) { + view.mChipsContainer.setVisibility(View.VISIBLE); + view.mProfileIconView.setVisibility(View.GONE); + } else { + view.mChipsContainer.setVisibility(View.GONE); + view.mProfileIconView.setVisibility(View.VISIBLE); + } + }); } private void setProfileMenuListener(ViewHolder view, @Nullable Runnable feedbackCallback) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index d0419072..00ab7d26 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -1332,7 +1332,13 @@ return TextUtils.join(", ", domainNames); } - private String getDomain(Tab tab) { + @VisibleForTesting + protected static String getDomain(Tab tab) { + // TODO(crbug.com/1116613) Investigate how uninitialized Tabs are appearing + // here. + if (!tab.isInitialized()) { + return ""; + } String domain = UrlUtilities.getDomainAndRegistry(tab.getUrlString(), false); if (domain.isEmpty()) return tab.getUrlString();
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index 1ef890d..cd3b4df5 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -86,6 +86,7 @@ import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; +import org.chromium.chrome.browser.tab.MockTab; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; @@ -2189,6 +2190,13 @@ mCallbackCaptor.getValue().onResult(mFaviconDrawable); } + @Test + public void testGetDomainOnDestroyedTab() { + Tab tab = new MockTab(TAB1_ID, false); + tab.destroy(); + assertEquals("", TabListMediator.getDomain(tab)); + } + private void initAndAssertAllProperties() { List<Tab> tabs = new ArrayList<>(); for (int i = 0; i < mTabModel.getCount(); i++) {
diff --git a/chrome/android/java/res/layout/account_picker_bottom_sheet_view.xml b/chrome/android/java/res/layout/account_picker_bottom_sheet_view.xml index 33f8628..59058fa 100644 --- a/chrome/android/java/res/layout/account_picker_bottom_sheet_view.xml +++ b/chrome/android/java/res/layout/account_picker_bottom_sheet_view.xml
@@ -20,6 +20,7 @@ app:srcCompat="@drawable/drag_handlebar" /> <ImageView + android:id="@+id/account_picker_bottom_sheet_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" @@ -91,4 +92,12 @@ android:layout_marginTop="32dp" android:layout_marginBottom="132dp" android:visibility="gone" /> + + <include + android:id="@+id/incognito_interstitial_bottom_sheet_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" + layout="@layout/incognito_interstitial_bottom_sheet_view"/> + </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/incognito_interstitial_bottom_sheet_view.xml b/chrome/android/java/res/layout/incognito_interstitial_bottom_sheet_view.xml new file mode 100644 index 0000000..0eece5c9d --- /dev/null +++ b/chrome/android/java/res/layout/incognito_interstitial_bottom_sheet_view.xml
@@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:orientation="horizontal"> + + <TextView + android:id="@+id/incognito_interstitial_learn_more" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="112dp" + android:layout_marginEnd="24dp" + android:layout_gravity="center_vertical" + android:text="@string/learn_more" + android:textAppearance="@style/TextAppearance.TextMediumThick.Blue" /> + + <org.chromium.ui.widget.ButtonCompat + android:id="@+id/incognito_interstitial_continue_button" + style="@style/FilledButton.Flat" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="24dp" + android:text="@string/continue_button"/> + +</LinearLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java index 59fec37f..c759e37 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetMediator.java
@@ -78,6 +78,8 @@ */ @Override public void goIncognitoMode() { + mModel.set(AccountPickerBottomSheetProperties.ACCOUNT_PICKER_BOTTOM_SHEET_STATE, + AccountPickerBottomSheetState.INCOGNITO_INTERSTITIAL); mAccountPickerDelegate.goIncognitoMode(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java index 2fcac14..a91c3ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetProperties.java
@@ -28,7 +28,8 @@ @IntDef({AccountPickerBottomSheetState.NO_ACCOUNTS, AccountPickerBottomSheetState.COLLAPSED_ACCOUNT_LIST, AccountPickerBottomSheetState.EXPANDED_ACCOUNT_LIST, - AccountPickerBottomSheetState.SIGNIN_IN_PROGRESS}) + AccountPickerBottomSheetState.SIGNIN_IN_PROGRESS, + AccountPickerBottomSheetState.INCOGNITO_INTERSTITIAL}) @Retention(RetentionPolicy.SOURCE) @interface AccountPickerBottomSheetState { /** @@ -67,6 +68,15 @@ * |Continue as| is clicked. This state does not lead to any other state. */ int SIGNIN_IN_PROGRESS = 3; + + /** + * When the account list is expanded, the user sees the account list of all the accounts + * on device and some additional rows like |Add account to device| and |Go incognito mode|. + * + * This state can only be reached from EXPANDED_ACCOUNT_LIST and would represent that the + * user has clicked the "Go incognito mode" option. + */ + int INCOGNITO_INTERSTITIAL = 4; } // PropertyKeys for the selected account view when the account list is collapsed.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java index 0c172e7..a7755e5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java
@@ -32,6 +32,7 @@ private final TextView mAccountPickerTitle; private final RecyclerView mAccountListView; private final View mSelectedAccountView; + private final View mIncognitoInterstitialView; private final ButtonCompat mContinueAsButton; AccountPickerBottomSheetView(Context context) { @@ -40,6 +41,8 @@ R.layout.account_picker_bottom_sheet_view, null); mAccountPickerTitle = mContentView.findViewById(R.id.account_picker_bottom_sheet_title); mAccountListView = mContentView.findViewById(R.id.account_picker_account_list); + mIncognitoInterstitialView = + mContentView.findViewById(R.id.incognito_interstitial_bottom_sheet_view); mAccountListView.setLayoutManager(new LinearLayoutManager( mAccountListView.getContext(), LinearLayoutManager.VERTICAL, false)); mSelectedAccountView = mContentView.findViewById(R.id.account_picker_selected_account); @@ -126,6 +129,19 @@ .setVisibility(View.VISIBLE); } + void setUpIncognitoInterstitialView() { + // TODO(crbug.com/1103262): Setup the incognito interstitial strings. + ImageView logo = mContentView.findViewById(R.id.account_picker_bottom_sheet_logo); + logo.setImageResource(R.drawable.location_bar_incognito_badge); + + mAccountPickerTitle.setVisibility(View.GONE); + mContentView.findViewById(R.id.account_picker_bottom_sheet_subtitle) + .setVisibility(View.GONE); + mContentView.findViewById(R.id.account_picker_horizontal_divider).setVisibility(View.GONE); + mAccountListView.setVisibility(View.GONE); + mIncognitoInterstitialView.setVisibility(View.VISIBLE); + } + @Override public View getContentView() { return mContentView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetViewBinder.java index 31776a4..20187b1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetViewBinder.java
@@ -56,6 +56,9 @@ case AccountPickerBottomSheetState.SIGNIN_IN_PROGRESS: view.setUpSignInInProgressView(); break; + case AccountPickerBottomSheetState.INCOGNITO_INTERSTITIAL: + view.setUpIncognitoInterstitialView(); + break; default: throw new IllegalArgumentException( "Cannot bind AccountPickerBottomSheetView for the state:"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerProperties.java index 764d02e..e3c3de8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerProperties.java
@@ -49,9 +49,9 @@ private IncognitoAccountRowProperties() {} - static PropertyModel createModel(Runnable runnableIncognitoAccount) { + static PropertyModel createModel(Runnable runnableIncognitoMode) { return new PropertyModel.Builder(ALL_KEYS) - .with(ON_CLICK_LISTENER, runnableIncognitoAccount) + .with(ON_CLICK_LISTENER, runnableIncognitoMode) .build(); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java index bb7c71a..8f58516e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java
@@ -339,6 +339,18 @@ onView(withText(R.string.signin_incognito_mode_secondary)).check(matches(isDisplayed())); onView(withText(R.string.signin_incognito_mode_primary)).perform(click()); verify(mAccountPickerDelegateMock).goIncognitoMode(); + checkIncognitoInterstitialSheet(); + } + + private void checkIncognitoInterstitialSheet() { + onView(withId(R.id.account_picker_bottom_sheet_logo)).check(matches(isDisplayed())); + onView(withId(R.id.account_picker_bottom_sheet_title)).check(matches(not(isDisplayed()))); + onView(withId(R.id.account_picker_bottom_sheet_subtitle)) + .check(matches(not(isDisplayed()))); + onView(withId(R.id.account_picker_horizontal_divider)).check(matches(not(isDisplayed()))); + onView(withId(R.id.account_picker_account_list)).check(matches(not(isDisplayed()))); + + onView(withId(R.id.incognito_interstitial_bottom_sheet_view)).check(matches(isDisplayed())); } private void checkZeroAccountBottomSheet() {
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 0938af9..cb0a127 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5688,6 +5688,15 @@ <message name="IDS_SUGGESTION_ENTER_KEY" desc="This string is the enter key annotation to educate users how to accept a personal information suggestion."> Enter </message> + <message name="IDS_SUGGESTION_EMOJI_SUGGESTED" desc="String announced by screenreader when emoji suggestion pops up."> + Emoji suggested. Press up or down to navigate and enter to insert. + </message> + <message name="IDS_SUGGESTION_EMOJI_CHOSEN" desc="String announced by screenreader when users selected an emoji in the pop-up."> + <ph name="EMOJI_NAME">$1<ex>Party popper</ex></ph>. <ph name="EMOJI_INDEX">$2<ex>5</ex></ph> of <ph name="EMOJI_COUNT">$3<ex>5</ex></ph>. + </message> + <message name="IDS_SUGGESTION_DISMISSED" desc="String announced by screenreader when suggestion pop-up disappears."> + Suggestion dismissed + </message> <!-- Strings for Custom Tab UI --> <message name="IDS_CUSTOM_TABS_ACTION_MENU_ACCESSIBLE_NAME" desc="Accessible name for the overflow menu of the Chrome Custom Tab toolbar.">
diff --git a/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_DISMISSED.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_DISMISSED.png.sha1 new file mode 100644 index 0000000..703bdd6 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_DISMISSED.png.sha1
@@ -0,0 +1 @@ +2f8b8b4390763a991e2c1178f57b5750257c74f8 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_EMOJI_CHOSEN.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_EMOJI_CHOSEN.png.sha1 new file mode 100644 index 0000000..c4681b4 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_EMOJI_CHOSEN.png.sha1
@@ -0,0 +1 @@ +5d2f70d718fddea280e54e37fa6f267ac92cbdda \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_EMOJI_SUGGESTED.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_EMOJI_SUGGESTED.png.sha1 new file mode 100644 index 0000000..703bdd6 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_SUGGESTION_EMOJI_SUGGESTED.png.sha1
@@ -0,0 +1 @@ +2f8b8b4390763a991e2c1178f57b5750257c74f8 \ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index 0001881..ba8dbfd 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -874,6 +874,12 @@ <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_ADD_LANGUAGE" desc="Text for search result item which, when clicked, navigates the user to languages and input settings, with an option to add a new language."> Add languages </message> + <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_ADD_INPUT_METHOD" translateable="false" desc="Text for search result item which, when clicked, navigates the user to input settings, with the option to add input methods (keyboard layouts and input method editors)."> + Add input methods + </message> + <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_SPELL_CHECK" translateable="false" desc="Text for search result item which, when clicked, navigates the user to input settings, with all the options for spell check settings"> + Spell check + </message> <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_METHODS" desc="Text for search result item which, when clicked, navigates the user to input settings, with the option to enable/disable input in supported languages."> Manage input methods </message>
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index cea041cd..314cd596 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -277,6 +277,15 @@ <message name="IDS_OS_SETTINGS_LANGUAGES_OPEN_OPTIONS_PAGE_LABEL" translateable="false" desc="Title for the button to open the options page for a input method (keyboard layout and input method editor)."> Open options page for <ph name="INPUT_METHOD_NAME">$1<ex>US keyboard</ex></ph> </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_ADD_INPUT_METHOD_LABEL" translateable="false" desc="Button under the list of input methods which opens a dialog that lets the user add keyboard layouts and input method editors."> + Add input methods + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_SPELL_CHECK_TITLE" translateable="false" desc="Title for the section containing all the options for spell check settings. The options include picking between using the system's spell check or using Google's web service and a list of the enabled languages which support spell checking."> + Spell check + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_SPELL_CHECK_DISABLED_REASON" translateable="false" desc="Text that indicates to the user that spell check options are disabled because none of the languages they have added have spell check support."> + Spell check isn’t supported for the languages you selected + </message> <message name="IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE" desc="Title for the list of the user's preferred written languages."> Languages </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index df908b1..607d640 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -126,7 +126,6 @@ #include "components/spellcheck/spellcheck_buildflags.h" #include "components/sync/base/sync_base_switches.h" #include "components/sync/driver/sync_driver_switches.h" -#include "components/sync/engine/sync_engine_switches.h" #include "components/tracing/common/tracing_switches.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/translate/core/browser/translate_ranker_impl.h" @@ -1541,23 +1540,10 @@ const FeatureEntry::FeatureParam kTabGridLayoutAndroid_NewTabTile[] = { {"tab_grid_layout_android_new_tab_tile", "NewTabTile"}}; -const FeatureEntry::FeatureParam - kTabGridLayoutAndroid_ThumbnailAspectRatio_2[] = { - {"thumbnail_aspect_ratio", "2.0"}, - {"allow_to_refetch", "true"}}; - -const FeatureEntry::FeatureParam - kTabGridLayoutAndroid_ThumbnailAspectRatio_three_quarter[] = { - {"thumbnail_aspect_ratio", "0.75"}, - {"allow_to_refetch", "true"}}; - -const FeatureEntry::FeatureParam - kTabGridLayoutAndroid_ThumbnailAspectRatio_half[] = { - {"thumbnail_aspect_ratio", "0.5"}, - {"allow_to_refetch", "true"}}; - -const FeatureEntry::FeatureParam kTabGridLayoutAndroid_DisableRefetch[] = { - {"allow_to_refetch", "false"}}; +const FeatureEntry::FeatureParam kTabGridLayoutAndroid_TallNTV[] = { + {"thumbnail_aspect_ratio", "0.85"}, + {"allow_to_refetch", "true"}, + {"tab_grid_layout_android_new_tab", "NewTabVariation"}}; const FeatureEntry::FeatureParam kTabGridLayoutAndroid_SearchChip[] = { {"enable_search_term_chip", "true"}}; @@ -1567,18 +1553,8 @@ base::size(kTabGridLayoutAndroid_NewTabVariation), nullptr}, {"New Tab Tile", kTabGridLayoutAndroid_NewTabTile, base::size(kTabGridLayoutAndroid_NewTabTile), nullptr}, - {"thumbnail aspect ratio - 2:1", - kTabGridLayoutAndroid_ThumbnailAspectRatio_2, - base::size(kTabGridLayoutAndroid_ThumbnailAspectRatio_2), nullptr}, - {"thumbnail aspect ratio - 1:2", - kTabGridLayoutAndroid_ThumbnailAspectRatio_half, - base::size(kTabGridLayoutAndroid_ThumbnailAspectRatio_half), nullptr}, - {"thumbnail aspect ratio - 3:4", - kTabGridLayoutAndroid_ThumbnailAspectRatio_three_quarter, - base::size(kTabGridLayoutAndroid_ThumbnailAspectRatio_three_quarter), - nullptr}, - {"Disable refetch", kTabGridLayoutAndroid_DisableRefetch, - base::size(kTabGridLayoutAndroid_DisableRefetch), nullptr}, + {"Tall NTV", kTabGridLayoutAndroid_TallNTV, + base::size(kTabGridLayoutAndroid_TallNTV), nullptr}, {"Search term chip", kTabGridLayoutAndroid_SearchChip, base::size(kTabGridLayoutAndroid_SearchChip), nullptr}, }; @@ -5434,11 +5410,6 @@ FEATURE_VALUE_TYPE(autofill::features::kAutofillTouchToFill)}, #endif // defined(OS_ANDROID) - {"enable-sync-trusted-vault", - flag_descriptions::kEnableSyncTrustedVaultName, - flag_descriptions::kEnableSyncTrustedVaultDescription, kOsAll, - FEATURE_VALUE_TYPE(switches::kSyncSupportTrustedVaultPassphrase)}, - #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) {"global-media-controls", flag_descriptions::kGlobalMediaControlsName, flag_descriptions::kGlobalMediaControlsDescription,
diff --git a/chrome/browser/apps/app_service/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon_factory.cc index 66dbd088..00e154a 100644 --- a/chrome/browser/apps/app_service/app_icon_factory.cc +++ b/chrome/browser/apps/app_service/app_icon_factory.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/web_applications/components/app_icon_manager.h" #include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "components/favicon/core/favicon_service.h" #include "components/favicon_base/favicon_types.h" @@ -247,6 +248,26 @@ std::move(compressed_data_callback)); } +base::Optional<IconPurpose> GetIconPurpose( + const std::string& web_app_id, + const web_app::AppIconManager& icon_manager, + int icon_size_in_px) { +#if defined(OS_CHROMEOS) + if (base::FeatureList::IsEnabled(features::kAppServiceAdaptiveIcon) && + icon_manager.HasSmallestIcon(web_app_id, {IconPurpose::MASKABLE}, + icon_size_in_px)) { + return base::make_optional(IconPurpose::MASKABLE); + } +#endif + + if (icon_manager.HasSmallestIcon(web_app_id, {IconPurpose::ANY}, + icon_size_in_px)) { + return base::make_optional(IconPurpose::ANY); + } + + return base::nullopt; +} // namespace + // This pipeline is meant to: // * Simplify loading icons, as things like effects and type are common // to all loading. @@ -445,19 +466,27 @@ // constructor. icon_scale_for_compressed_response_ = icon_scale_; - base::Optional<IconPurpose> icon_purpose_to_read; - if (icon_manager.HasSmallestIcon(web_app_id, {IconPurpose::MASKABLE}, - icon_size_in_px_)) { - icon_purpose_to_read = IconPurpose::MASKABLE; - } else if (icon_manager.HasSmallestIcon(web_app_id, {IconPurpose::ANY}, - icon_size_in_px_)) { - icon_purpose_to_read = IconPurpose::ANY; - } + base::Optional<IconPurpose> icon_purpose_to_read = + GetIconPurpose(web_app_id, icon_manager, icon_size_in_px_); + if (!icon_purpose_to_read.has_value()) { MaybeLoadFallbackOrCompleteEmpty(); return; } + // Per https://www.w3.org/TR/appmanifest/#icon-masks, we apply a white + // background in case the maskable icon contains transparent pixels in its + // safe zone, and clear the standard icon effect, apply the mask to the icon + // without shrinking it. + if (icon_purpose_to_read.value() == IconPurpose::MASKABLE) { + icon_effects_ = static_cast<apps::IconEffects>( + icon_effects_ & ~apps::IconEffects::kCrOsStandardIcon); + icon_effects_ = static_cast<apps::IconEffects>( + icon_effects_ | apps::IconEffects::kCrOsStandardBackground); + icon_effects_ = static_cast<apps::IconEffects>( + icon_effects_ | apps::IconEffects::kCrOsStandardMask); + } + switch (icon_type_) { case apps::mojom::IconType::kCompressed: if (icon_effects_ == apps::IconEffects::kNone && @@ -1041,9 +1070,13 @@ } if (icon_effects & IconEffects::kCrOsStandardMask) { - auto mask_image = LoadMaskImage(GetScaleToSize(*image_skia)); - *image_skia = - gfx::ImageSkiaOperations::CreateMaskedImage(*image_skia, mask_image); + if (icon_effects & IconEffects::kCrOsStandardBackground) { + *image_skia = apps::ApplyBackgroundAndMask(*image_skia); + } else { + auto mask_image = LoadMaskImage(GetScaleToSize(*image_skia)); + *image_skia = + gfx::ImageSkiaOperations::CreateMaskedImage(*image_skia, mask_image); + } } if (icon_effects & IconEffects::kCrOsStandardIcon) {
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc index 7bb928f..a01de13 100644 --- a/chrome/browser/apps/app_service/arc_apps.cc +++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/apps/app_service/file_utils.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/arc/session/arc_session_manager.h" #include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_icon.h" @@ -33,6 +34,7 @@ #include "chrome/grit/generated_resources.h" #include "components/arc/app_permissions/arc_app_permissions_bridge.h" #include "components/arc/arc_service_manager.h" +#include "components/arc/arc_util.h" #include "components/arc/intent_helper/intent_constants.h" #include "components/arc/mojom/app_permissions.mojom.h" #include "components/arc/mojom/file_system.mojom.h" @@ -750,46 +752,88 @@ return; } - arc::mojom::ActivityNamePtr activity = arc::mojom::ActivityName::New(); - activity->package_name = app_info->package_name; - activity->activity_name = app_info->activity; + if (app_info->ready) { + arc::mojom::ActivityNamePtr activity = arc::mojom::ActivityName::New(); + activity->package_name = app_info->package_name; + activity->activity_name = app_info->activity; - // At the moment, the only case we have mime_type field set is to share - // files, in this case, convert the file urls to content urls and use - // arc file system instance to launch the app with files. - if (intent->mime_type.has_value()) { - if (!intent->file_urls.has_value()) { - LOG(ERROR) << "Share files failed, share intent is not valid"; + // At the moment, the only case we have mime_type field set is to share + // files, in this case, convert the file urls to content urls and use + // arc file system instance to launch the app with files. + if (intent->mime_type.has_value()) { + if (!intent->file_urls.has_value()) { + LOG(ERROR) << "Share files failed, share intent is not valid"; + return; + } + file_manager::util::ConvertToContentUrls( + apps::GetFileSystemURL(profile_, intent->file_urls.value()), + base::BindOnce(&OnContentUrlResolved, std::move(intent), + std::move(activity))); return; } - file_manager::util::ConvertToContentUrls( - apps::GetFileSystemURL(profile_, intent->file_urls.value()), - base::BindOnce(&OnContentUrlResolved, std::move(intent), - std::move(activity))); + + auto* arc_service_manager = arc::ArcServiceManager::Get(); + arc::mojom::IntentHelperInstance* instance = nullptr; + if (arc_service_manager) { + instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_service_manager->arc_bridge_service()->intent_helper(), + HandleIntent); + } + if (!instance) { + return; + } + + auto arc_intent = CreateArcIntent(std::move(intent)); + + if (!arc_intent) { + LOG(ERROR) << "Launch App failed, launch intent is not valid"; + return; + } + + instance->HandleIntent(std::move(arc_intent), std::move(activity)); + + prefs->SetLastLaunchTime(app_id); return; } - auto* arc_service_manager = arc::ArcServiceManager::Get(); - arc::mojom::IntentHelperInstance* instance = nullptr; - if (arc_service_manager) { - instance = ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), - HandleIntent); + if (arc::IsArcPlayStoreEnabledForProfile(profile_)) { + // Handle the case when default app tries to re-activate OptIn flow. + if (arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile_) && + !arc::ArcSessionManager::Get()->enable_requested() && + prefs->IsDefault(app_id)) { + arc::SetArcPlayStoreEnabledForProfile(profile_, true); + // PlayStore item has special handling for shelf controllers. In order + // to avoid unwanted initial animation for PlayStore item do not create + // deferred launch request when PlayStore item enables Google Play + // Store. + if (app_id == arc::kPlayStoreAppId) { + prefs->SetLastLaunchTime(app_id); + return; + } + } + } else { + if (prefs->IsDefault(app_id)) { + // The setting can fail if the preference is managed. However, the + // caller is responsible to not call this function in such case. DCHECK + // is here to prevent possible mistake. + if (!arc::SetArcPlayStoreEnabledForProfile(profile_, true)) { + return; + } + DCHECK(arc::IsArcPlayStoreEnabledForProfile(profile_)); + + // PlayStore item has special handling for shelf controllers. In order + // to avoid unwanted initial animation for PlayStore item do not create + // deferred launch request when PlayStore item enables Google Play + // Store. + if (app_id == arc::kPlayStoreAppId) { + prefs->SetLastLaunchTime(app_id); + return; + } + } else { + // Only reachable when ARC always starts. + DCHECK(arc::ShouldArcAlwaysStart()); + } } - if (!instance) { - return; - } - - auto arc_intent = CreateArcIntent(std::move(intent)); - - if (!arc_intent) { - LOG(ERROR) << "Launch App failed, launch intent is not valid"; - return; - } - - instance->HandleIntent(std::move(arc_intent), std::move(activity)); - - prefs->SetLastLaunchTime(app_id); } void ArcApps::SetPermission(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/web_apps_chromeos.cc b/chrome/browser/apps/app_service/web_apps_chromeos.cc index b781aca..a0a7df2 100644 --- a/chrome/browser/apps/app_service/web_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/web_apps_chromeos.cc
@@ -393,10 +393,6 @@ icon_effects | IconEffects::kCrOsStandardMask) : static_cast<IconEffects>( icon_effects | IconEffects::kCrOsStandardIcon); - - // TODO(crbug.com/1083331): If the icon is maskable, modify the icon effect, - // don't apply the kResizeAndPad effect to shrink the icon, add the - // kCrOsStandardBackground and kCrOsStandardMask icon effects. } else { icon_effects = static_cast<IconEffects>(icon_effects | IconEffects::kResizeAndPad);
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc index 4f2485d8..621d6f2 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.cc +++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -223,7 +223,7 @@ if (app_id.has_value() && *app_id == installed_app_id && registrar().GetAppUserDisplayMode(*app_id) == blink::mojom::DisplayMode::kStandalone) { - OnInstall(registrar().GetAppDisplayMode(*app_id)); + OnInstall(registrar().GetEffectiveDisplayModeFromManifest(*app_id)); SetInstallableWebAppCheckResult(InstallableWebAppCheckResult::kNo); } }
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc index 1f3f82e..6d158b3 100644 --- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/banners/app_banner_manager_browsertest_base.h" #include "chrome/browser/banners/app_banner_manager_desktop.h" @@ -34,6 +35,7 @@ #include "chrome/common/chrome_features.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "extensions/common/extension.h" @@ -64,8 +66,30 @@ chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); } + AppBannerManagerDesktopBrowserTest( + const AppBannerManagerDesktopBrowserTest&) = delete; + AppBannerManagerDesktopBrowserTest& operator=( + const AppBannerManagerDesktopBrowserTest&) = delete; +}; + +// A dedicated test fixture for DisplayOverride, which is supported +// only for the new web apps mode, and requires a command line switch +// to enable manifest parsing. +class AppBannerManagerDesktopBrowserTest_DisplayOverride + : public AppBannerManagerDesktopBrowserTest { + public: + AppBannerManagerDesktopBrowserTest_DisplayOverride() { + scoped_feature_list_.InitAndEnableFeature( + features::kWebAppManifestDisplayOverride); + } + + AppBannerManagerDesktopBrowserTest_DisplayOverride( + const AppBannerManagerDesktopBrowserTest_DisplayOverride&) = delete; + AppBannerManagerDesktopBrowserTest_DisplayOverride& operator=( + const AppBannerManagerDesktopBrowserTest_DisplayOverride&) = delete; + private: - DISALLOW_COPY_AND_ASSIGN(AppBannerManagerDesktopBrowserTest); + base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest, @@ -328,4 +352,103 @@ EXPECT_TRUE(manager->IsPromptAvailableForTesting()); } +IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest_DisplayOverride, + InstallPromptAfterUserMenuInstall) { + base::HistogramTester tester; + + TestAppBannerManagerDesktop* manager = + TestAppBannerManagerDesktop::FromWebContents( + browser()->tab_strip_model()->GetActiveWebContents()); + + { + base::RunLoop run_loop; + manager->PrepareDone(run_loop.QuitClosure()); + + ui_test_utils::NavigateToURL( + browser(), GetBannerURLWithManifestAndQuery( + "/banners/manifest_display_override.json", "action", + "stash_event")); + run_loop.Run(); + EXPECT_EQ(State::PENDING_PROMPT, manager->state()); + } + + // Install the app via the menu instead of the banner. + chrome::SetAutoAcceptPWAInstallConfirmationForTesting(true); + browser()->command_controller()->ExecuteCommand(IDC_INSTALL_PWA); + manager->AwaitAppInstall(); + chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); + + EXPECT_FALSE(manager->IsPromptAvailableForTesting()); + + tester.ExpectUniqueSample(kInstallDisplayModeHistogram, + blink::mojom::DisplayMode::kMinimalUi, 1); +} + +IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest_DisplayOverride, + WebAppBannerResolvesUserChoice) { + base::HistogramTester tester; + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + auto* manager = TestAppBannerManagerDesktop::FromWebContents(web_contents); + + { + base::RunLoop run_loop; + manager->PrepareDone(run_loop.QuitClosure()); + + ui_test_utils::NavigateToURL( + browser(), + GetBannerURLWithManifestAndQuery( + "/banners/manifest_display_override_display_is_browser.json", + "action", "stash_event")); + run_loop.Run(); + EXPECT_EQ(State::PENDING_PROMPT, manager->state()); + } + + { + // Trigger the installation prompt and wait for installation to occur. + base::RunLoop run_loop; + manager->PrepareDone(run_loop.QuitClosure()); + ExecuteScript(browser(), "callStashedPrompt();", true /* with_gesture */); + run_loop.Run(); + EXPECT_EQ(State::COMPLETE, manager->state()); + } + + // Ensure that the userChoice promise resolves. + const base::string16 title = base::ASCIIToUTF16("Got userChoice: accepted"); + content::TitleWatcher watcher(web_contents, title); + EXPECT_EQ(title, watcher.WaitAndGetTitle()); + + tester.ExpectUniqueSample(kInstallDisplayModeHistogram, + blink::mojom::DisplayMode::kStandalone, 1); +} + +IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest_DisplayOverride, + PolicyAppInstalled_NoPrompt) { + TestAppBannerManagerDesktop* manager = + TestAppBannerManagerDesktop::FromWebContents( + browser()->tab_strip_model()->GetActiveWebContents()); + + // Install web app by policy. + web_app::ExternalInstallOptions options = + web_app::CreateInstallOptions(GetBannerURLWithManifest( + "/banners/manifest_display_override_contains_browser.json")); + options.install_source = web_app::ExternalInstallSource::kExternalPolicy; + options.user_display_mode = web_app::DisplayMode::kBrowser; + web_app::PendingAppManagerInstall(browser()->profile(), options); + + // Run promotability check. + { + base::RunLoop run_loop; + manager->PrepareDone(run_loop.QuitClosure()); + + ui_test_utils::NavigateToURL(browser(), GetBannerURL()); + run_loop.Run(); + EXPECT_EQ(State::COMPLETE, manager->state()); + } + + EXPECT_EQ(AppBannerManager::InstallableWebAppCheckResult::kNoAlreadyInstalled, + manager->GetInstallableWebAppCheckResultForTesting()); + EXPECT_FALSE(manager->IsPromptAvailableForTesting()); +} + } // namespace banners
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 55d07ac..513fedf 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -118,6 +118,7 @@ "//chromeos/components/print_management/mojom", "//chromeos/components/proximity_auth", "//chromeos/components/quick_answers/public/cpp:prefs", + "//chromeos/components/remote_apps/mojom", "//chromeos/components/scanning", "//chromeos/components/smbfs", "//chromeos/components/smbfs/mojom", @@ -2418,12 +2419,15 @@ "release_notes/release_notes_storage.h", "remote_apps/id_generator.cc", "remote_apps/id_generator.h", + "remote_apps/remote_apps_impl.cc", + "remote_apps/remote_apps_impl.h", "remote_apps/remote_apps_manager.cc", "remote_apps/remote_apps_manager.h", "remote_apps/remote_apps_manager_factory.cc", "remote_apps/remote_apps_manager_factory.h", "remote_apps/remote_apps_model.cc", "remote_apps/remote_apps_model.h", + "remote_apps/remote_apps_types.h", "reset/metrics.h", "scanning/lorgnette_scanner_manager.cc", "scanning/lorgnette_scanner_manager.h",
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_browsertest.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_browsertest.cc index 8e5abb7..7f1255a4 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_browsertest.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_browsertest.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" +#include <memory> +#include <utility> + #include "ash/shell.h" #include "base/feature_list.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" @@ -16,8 +19,11 @@ #include "components/arc/session/arc_bridge_service.h" #include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_accessibility_helper_instance.h" +#include "components/exo/buffer.h" +#include "components/exo/client_controlled_accelerators.h" #include "components/exo/shell_surface.h" #include "components/exo/shell_surface_util.h" +#include "components/exo/surface.h" #include "components/exo/test/exo_test_helper.h" #include "components/exo/wm_helper.h" #include "components/exo/wm_helper_chromeos.h" @@ -29,6 +35,12 @@ namespace arc { +struct ArcTestWindow { + std::unique_ptr<exo::Buffer> buffer; + std::unique_ptr<exo::Surface> surface; + std::unique_ptr<exo::ClientControlledShellSurface> shell_surface; +}; + class ArcAccessibilityHelperBridgeBrowserTest : public InProcessBrowserTest { void SetUpCommandLine(base::CommandLine* command_line) override { arc::SetArcAvailableCommandLineForTesting(command_line); @@ -61,6 +73,25 @@ } protected: + // Create and initialize a window for this test, i.e. an Arc++-specific + // version of ExoTestHelper::CreateWindow. + ArcTestWindow MakeTestWindow(std::string name) { + ArcTestWindow ret; + exo::test::ExoTestHelper helper; + ret.surface = std::make_unique<exo::Surface>(); + ret.buffer = std::make_unique<exo::Buffer>( + helper.CreateGpuMemoryBuffer(gfx::Size(640, 480))); + ret.shell_surface = helper.CreateClientControlledShellSurface( + ret.surface.get(), /*is_modal=*/false); + ret.surface->Attach(ret.buffer.get()); + ret.surface->Commit(); + + // Forcefully set task_id for each window. + exo::SetShellApplicationId( + ret.shell_surface->GetWidget()->GetNativeWindow(), std::move(name)); + return ret; + } + std::unique_ptr<FakeAccessibilityHelperInstance> fake_accessibility_helper_instance_; std::unique_ptr<exo::WMHelper> wm_helper_; @@ -72,38 +103,21 @@ fake_accessibility_helper_instance_->filter_type()); EXPECT_FALSE(fake_accessibility_helper_instance_->explore_by_touch_enabled()); - exo::test::ExoTestHelper exo_test_helper; - exo::test::ExoTestWindow test_window_1 = - exo_test_helper.CreateWindow(640, 480, false /* is_modal */); - exo::test::ExoTestWindow test_window_2 = - exo_test_helper.CreateWindow(640, 480, false /* is_modal */); - - // Forcefully set task_id to each window. - exo::SetShellApplicationId( - test_window_1.shell_surface()->GetWidget()->GetNativeWindow(), - "org.chromium.arc.1"); - exo::SetShellApplicationId( - test_window_2.shell_surface()->GetWidget()->GetNativeWindow(), - "org.chromium.arc.2"); + ArcTestWindow test_window_1 = MakeTestWindow("org.chromium.arc.1"); + ArcTestWindow test_window_2 = MakeTestWindow("org.chromium.arc.2"); wm::ActivationClient* activation_client = ash::Shell::Get()->activation_client(); activation_client->ActivateWindow( - test_window_1.shell_surface()->GetWidget()->GetNativeWindow()); - ASSERT_EQ(test_window_1.shell_surface()->GetWidget()->GetNativeWindow(), + test_window_1.shell_surface->GetWidget()->GetNativeWindow()); + ASSERT_EQ(test_window_1.shell_surface->GetWidget()->GetNativeWindow(), activation_client->GetActiveWindow()); ASSERT_FALSE( - test_window_1.shell_surface() - ->GetWidget() - ->GetNativeWindow() - ->GetProperty( - aura::client::kAccessibilityTouchExplorationPassThrough)); + test_window_1.shell_surface->GetWidget()->GetNativeWindow()->GetProperty( + aura::client::kAccessibilityTouchExplorationPassThrough)); ASSERT_FALSE( - test_window_2.shell_surface() - ->GetWidget() - ->GetNativeWindow() - ->GetProperty( - aura::client::kAccessibilityTouchExplorationPassThrough)); + test_window_2.shell_surface->GetWidget()->GetNativeWindow()->GetProperty( + aura::client::kAccessibilityTouchExplorationPassThrough)); chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(true); @@ -113,11 +127,8 @@ // Use ChromeVox by default. Touch exploration pass through is still false. EXPECT_FALSE( - test_window_1.shell_surface() - ->GetWidget() - ->GetNativeWindow() - ->GetProperty( - aura::client::kAccessibilityTouchExplorationPassThrough)); + test_window_1.shell_surface->GetWidget()->GetNativeWindow()->GetProperty( + aura::client::kAccessibilityTouchExplorationPassThrough)); ArcAccessibilityHelperBridge* bridge = ArcAccessibilityHelperBridge::GetForBrowserContext(browser()->profile()); @@ -126,53 +137,38 @@ // (current active window) would become true. bridge->SetNativeChromeVoxArcSupport(false); - EXPECT_TRUE(test_window_1.shell_surface() - ->GetWidget() - ->GetNativeWindow() - ->GetProperty( - aura::client::kAccessibilityTouchExplorationPassThrough)); + EXPECT_TRUE( + test_window_1.shell_surface->GetWidget()->GetNativeWindow()->GetProperty( + aura::client::kAccessibilityTouchExplorationPassThrough)); // Activate test_window_2 and confirm that it still be false. activation_client->ActivateWindow( - test_window_2.shell_surface()->GetWidget()->GetNativeWindow()); - ASSERT_EQ(test_window_2.shell_surface()->GetWidget()->GetNativeWindow(), + test_window_2.shell_surface->GetWidget()->GetNativeWindow()); + ASSERT_EQ(test_window_2.shell_surface->GetWidget()->GetNativeWindow(), activation_client->GetActiveWindow()); EXPECT_FALSE( - test_window_2.shell_surface() - ->GetWidget() - ->GetNativeWindow() - ->GetProperty( - aura::client::kAccessibilityTouchExplorationPassThrough)); + test_window_2.shell_surface->GetWidget()->GetNativeWindow()->GetProperty( + aura::client::kAccessibilityTouchExplorationPassThrough)); EXPECT_TRUE(fake_accessibility_helper_instance_->explore_by_touch_enabled()); } IN_PROC_BROWSER_TEST_F(ArcAccessibilityHelperBridgeBrowserTest, RequestTreeSyncOnWindowIdChange) { - exo::test::ExoTestHelper exo_test_helper; - exo::test::ExoTestWindow test_window_1 = - exo_test_helper.CreateWindow(640, 480, false /* is_modal */); - exo::test::ExoTestWindow test_window_2 = - exo_test_helper.CreateWindow(640, 480, false /* is_modal */); - - exo::SetShellApplicationId( - test_window_1.shell_surface()->GetWidget()->GetNativeWindow(), - "org.chromium.arc.1"); - exo::SetShellApplicationId( - test_window_2.shell_surface()->GetWidget()->GetNativeWindow(), - "org.chromium.arc.2"); + ArcTestWindow test_window_1 = MakeTestWindow("org.chromium.arc.1"); + ArcTestWindow test_window_2 = MakeTestWindow("org.chromium.arc.2"); wm::ActivationClient* activation_client = ash::Shell::Get()->activation_client(); activation_client->ActivateWindow( - test_window_1.shell_surface()->GetWidget()->GetNativeWindow()); + test_window_1.shell_surface->GetWidget()->GetNativeWindow()); chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(true); exo::SetShellClientAccessibilityId( - test_window_1.shell_surface()->GetWidget()->GetNativeWindow(), 10); + test_window_1.shell_surface->GetWidget()->GetNativeWindow(), 10); exo::SetShellClientAccessibilityId( - test_window_2.shell_surface()->GetWidget()->GetNativeWindow(), 20); + test_window_2.shell_surface->GetWidget()->GetNativeWindow(), 20); EXPECT_TRUE( fake_accessibility_helper_instance_->last_requested_tree_window_key() @@ -184,7 +180,7 @@ ->get_window_id()); activation_client->ActivateWindow( - test_window_2.shell_surface()->GetWidget()->GetNativeWindow()); + test_window_2.shell_surface->GetWidget()->GetNativeWindow()); EXPECT_EQ( 20U, fake_accessibility_helper_instance_->last_requested_tree_window_key() @@ -192,7 +188,7 @@ ->get_window_id()); exo::SetShellClientAccessibilityId( - test_window_2.shell_surface()->GetWidget()->GetNativeWindow(), 21); + test_window_2.shell_surface->GetWidget()->GetNativeWindow(), 21); EXPECT_EQ( 21U, fake_accessibility_helper_instance_->last_requested_tree_window_key()
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index a16a803..94131bd 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -143,6 +143,10 @@ RunTestURL("foreground/js/file_transfer_controller_unittest_gen.html"); } +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileTypeFiltersController) { + RunTestURL("foreground/js/file_type_filters_controller_unittest_gen.html"); +} + IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileType) { RunTestURL("common/js/file_type_unittest_gen.html"); }
diff --git a/chrome/browser/chromeos/input_method/emoji_suggester.cc b/chrome/browser/chromeos/input_method/emoji_suggester.cc index 83a734cd..0d6b9e8 100644 --- a/chrome/browser/chromeos/input_method/emoji_suggester.cc +++ b/chrome/browser/chromeos/input_method/emoji_suggester.cc
@@ -18,6 +18,7 @@ #include "base/task/thread_pool.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h" +#include "chrome/grit/generated_resources.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_pref_names.h" #include "chromeos/services/ime/constants.h" @@ -36,11 +37,6 @@ constexpr char kEmojiMapFilePathTemplateName[] = "/emoji/emoji-map%s.csv"; const int kMaxSuggestionIndex = 31; const int kMaxSuggestionSize = kMaxSuggestionIndex + 1; -const char kShowEmojiSuggestionMessage[] = - "Emoji suggested. Press up or down to choose an emoji. Press enter to " - "insert."; -const char kDismissEmojiSuggestionMessage[] = "Emoji suggestion dismissed."; -const char kAnnounceCandidateTemplate[] = "%s. %zu of %zu"; const int kNoneHighlighted = -1; std::string ReadEmojiDataFromFile() { @@ -240,7 +236,8 @@ candidates_ = emoji_map_.at(text); properties_.visible = true; properties_.candidates = candidates_; - properties_.announce_string = kShowEmojiSuggestionMessage; + properties_.announce_string = + l10n_util::GetStringUTF8(IDS_SUGGESTION_EMOJI_SUGGESTED); properties_.show_setting_link = GetPrefValue(kEmojiSuggesterShowSettingCount) < kEmojiSuggesterShowSettingMaxCount; @@ -252,9 +249,9 @@ buttons_.clear(); for (size_t i = 0; i < candidates_.size(); i++) { suggestion_button_.index = i; - suggestion_button_.announce_string = base::StringPrintf( - kAnnounceCandidateTemplate, base::UTF16ToUTF8(candidates_[i]).c_str(), - i + 1, candidates_.size()); + suggestion_button_.announce_string = l10n_util::GetStringFUTF8( + IDS_SUGGESTION_EMOJI_CHOSEN, candidates_[i], base::FormatNumber(i + 1), + base::FormatNumber(candidates_.size())); buttons_.push_back(suggestion_button_); } if (properties_.show_setting_link) { @@ -294,7 +291,8 @@ void EmojiSuggester::DismissSuggestion() { std::string error; properties_.visible = false; - properties_.announce_string = kDismissEmojiSuggestionMessage; + properties_.announce_string = + l10n_util::GetStringUTF8(IDS_SUGGESTION_DISMISSED); suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties_, &error); if (!error.empty()) {
diff --git a/chrome/browser/chromeos/input_method/personal_info_suggester.cc b/chrome/browser/chromeos/input_method/personal_info_suggester.cc index 76cfe2c..cc1673d 100644 --- a/chrome/browser/chromeos/input_method/personal_info_suggester.cc +++ b/chrome/browser/chromeos/input_method/personal_info_suggester.cc
@@ -25,7 +25,6 @@ #include "components/prefs/scoped_user_pref_update.h" #include "components/strings/grit/components_strings.h" #include "third_party/re2/src/re2/re2.h" -#include "ui/base/l10n/l10n_util.h" namespace chromeos { @@ -46,8 +45,22 @@ const char kFirstNameRegex[] = "first name"; const char kLastNameRegex[] = "last name"; -const char kAnnounceAnnotation[] = - "Press down to navigate and enter to insert."; +const char kShowPersonalInfoSuggestionMessage[] = + "Personal info suggested. Press down arrow to access; escape to ignore."; +const char kDismissPersonalInfoSuggestionMessage[] = "Suggestion dismissed."; +const char kAcceptPersonalInfoSuggestionMessage[] = "Suggestion inserted."; + +// The current personal information would only provide one suggestion, so there +// could be only two possible UI: 1. only one suggestion, 2. one suggestion and +// one learn more button, and the suggestion is always before the learn more +// button. So suggestion could be 1 of 1 or 1 of 2 depending on whether the +// learn more button is displayed, but learn more button can only be 2 of 2. +const char kSuggestionMessageTemplate[] = + "Suggestion %s. Button. Menu item 1 of %d. Press enter to insert; escape " + "to dismiss."; +const char kLearnMoreMessage[] = + "Learn more about suggestions. Link. Menu item 2 of 2. Press enter to " + "activate; escape to dismiss."; const int kNoneHighlighted = -1; constexpr base::TimeDelta kTtsShowDelay = @@ -172,7 +185,7 @@ ui::ime::AssistiveWindowType::kPersonalInfoSuggestion; suggestion_button_.index = 0; settings_button_.id = ui::ime::ButtonId::kSmartInputsSettingLink; - settings_button_.announce_string = l10n_util::GetStringUTF8(IDS_LEARN_MORE); + settings_button_.announce_string = kLearnMoreMessage; settings_button_.window_type = ui::ime::AssistiveWindowType::kPersonalInfoSuggestion; } @@ -335,7 +348,9 @@ LOG(ERROR) << "Fail to show suggestion. " << error; } - suggestion_button_.announce_string = base::UTF16ToUTF8(text); + suggestion_button_.announce_string = base::StringPrintf( + kSuggestionMessageTemplate, base::UTF16ToUTF8(text).c_str(), + details.show_setting_link ? 2 : 1); buttons_.clear(); buttons_.push_back(suggestion_button_); if (details.show_setting_link) @@ -349,11 +364,9 @@ IncrementPrefValueTilCapped(kPersonalInfoSuggesterShowSettingCount, kMaxShowSettingCount); tts_handler_->Announce( - // TODO(jiwan): Add translation to other languages when we support more - // than English. - base::StringPrintf("Suggestion %s. %s", base::UTF16ToUTF8(text).c_str(), - show_annotation ? kAnnounceAnnotation : ""), - kTtsShowDelay); + // TODO(jiwan): Add translation to other languages when we support + // more than English. + kShowPersonalInfoSuggestionMessage, kTtsShowDelay); } suggestion_shown_ = true; @@ -398,8 +411,7 @@ IncrementPrefValueTilCapped(kPersonalInfoSuggesterAcceptanceCount, kMaxAcceptanceCount); suggestion_shown_ = false; - tts_handler_->Announce(base::StringPrintf( - "Inserted suggestion %s.", base::UTF16ToUTF8(suggestion_).c_str())); + tts_handler_->Announce(kAcceptPersonalInfoSuggestionMessage); return true; } @@ -413,6 +425,7 @@ } suggestion_shown_ = false; RecordTimeToDismiss(base::TimeTicks::Now() - session_start_); + tts_handler_->Announce(kDismissPersonalInfoSuggestionMessage); } void PersonalInfoSuggester::SetButtonHighlighted(
diff --git a/chrome/browser/chromeos/input_method/personal_info_suggester_unittest.cc b/chrome/browser/chromeos/input_method/personal_info_suggester_unittest.cc index 4a0b6fa..20525528 100644 --- a/chrome/browser/chromeos/input_method/personal_info_suggester_unittest.cc +++ b/chrome/browser/chromeos/input_method/personal_info_suggester_unittest.cc
@@ -464,15 +464,21 @@ tts_handler_->VerifyAnnouncement(""); task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000)); - tts_handler_->VerifyAnnouncement(base::StringPrintf( - "Suggestion %s. Press down to navigate and enter to insert.", - base::UTF16ToUTF8(email_).c_str())); + tts_handler_->VerifyAnnouncement( + "Personal info suggested. Press down arrow to access; escape to ignore."); SendKeyboardEvent("Down"); SendKeyboardEvent("Enter"); task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(200)); - tts_handler_->VerifyAnnouncement(base::StringPrintf( - "Inserted suggestion %s.", base::UTF16ToUTF8(email_).c_str())); + tts_handler_->VerifyAnnouncement("Suggestion inserted."); + + suggester_->Suggest(base::UTF8ToUTF16("my email is ")); + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1500)); + tts_handler_->VerifyAnnouncement( + "Personal info suggested. Press down arrow to access; escape to ignore."); + SendKeyboardEvent("Esc"); + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(200)); + tts_handler_->VerifyAnnouncement("Suggestion dismissed."); } TEST_F(PersonalInfoSuggesterTest, DoNotShowAnnotationAfterMaxAcceptanceCount) { @@ -486,24 +492,6 @@ suggestion_handler_->VerifyShowAnnotation(false); } -TEST_F(PersonalInfoSuggesterTest, DoNotAnnounceAnnotationWhenTabNotShown) { - profile_->set_profile_name(base::UTF16ToUTF8(email_)); - profile_->GetPrefs()->SetBoolean( - ash::prefs::kAccessibilitySpokenFeedbackEnabled, true); - DictionaryPrefUpdate update(profile_->GetPrefs(), - prefs::kAssistiveInputFeatureSettings); - update->SetIntKey(kPersonalInfoSuggesterAcceptanceCount, kMaxAcceptanceCount); - - suggester_->Suggest(base::UTF8ToUTF16("my email is ")); - suggestion_handler_->VerifyShowAnnotation(false); - task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(500)); - tts_handler_->VerifyAnnouncement(""); - - task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000)); - tts_handler_->VerifyAnnouncement( - base::StringPrintf("Suggestion %s. ", base::UTF16ToUTF8(email_).c_str())); -} - TEST_F(PersonalInfoSuggesterTest, ShowSettingLink) { DictionaryPrefUpdate update(profile_->GetPrefs(), prefs::kAssistiveInputFeatureSettings);
diff --git a/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc b/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc index 506abae..d4126031 100644 --- a/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc +++ b/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc
@@ -131,8 +131,9 @@ for (const auto& result : results) { const int relevance = base::ClampToRange(result.relevance, 0, kMaxSearchResultScore); - const GURL icon_url = - result.icon_url ? GURL(*result.icon_url.get()) : GURL(); + + const std::string icon_type = + result.icon_type ? *result.icon_type.get() : std::string(); // Calculate the relevance score by matching the query with the title. // Results with a match score of 0 are discarded. This will also be used to @@ -146,7 +147,7 @@ continue; auto search_result = std::make_unique<app_list::LauncherSearchResult>( - result.item_id, icon_url, relevance, profile_, extension, + result.item_id, icon_type, relevance, profile_, extension, error_reporter->Duplicate()); search_result->UpdateFromMatch(tokenized_title, match); search_results.push_back(std::move(search_result));
diff --git a/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc b/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc index cf1ea6a..81933c5c 100644 --- a/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc +++ b/chrome/browser/chromeos/login/saml/in_session_password_change_manager.cc
@@ -21,6 +21,7 @@ #include "chrome/common/pref_names.h" #include "chromeos/login/auth/user_context.h" #include "components/prefs/pref_service.h" +#include "components/user_manager/known_user.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -409,6 +410,9 @@ DismissExpiryNotification(); PasswordChangeDialog::Dismiss(); ConfirmPasswordChangeDialog::Dismiss(); + // We request a new sync token. It will be updated locally and signal the fact + // of password change to other devices owned by the user. + CreateTokenAsync(); RecordEvent(InSessionPasswordChangeEvent::kFinishPasswordChange); } @@ -422,6 +426,34 @@ } } +void InSessionPasswordChangeManager::OnTokenCreated( + const std::string& sync_token) { + user_manager::known_user::SetPasswordSyncToken(primary_user_->GetAccountId(), + sync_token); +} + +void InSessionPasswordChangeManager::OnTokenFetched( + const std::string& sync_token) { + // Ignored. +} + +void InSessionPasswordChangeManager::OnTokenVerified(bool is_valid) { + // Ignored. +} + +void InSessionPasswordChangeManager::OnApiCallFailed( + PasswordSyncTokenFetcher::ErrorType error_type) { + // TODO(crbug.com/1112896): Error types will be tracked by UMA histograms. + // Going forward we should also consider re-trying token creation depending on + // the error_type. +} + +void InSessionPasswordChangeManager::CreateTokenAsync() { + password_sync_token_fetcher_ = std::make_unique<PasswordSyncTokenFetcher>( + primary_profile_->GetURLLoaderFactory(), primary_profile_, this); + password_sync_token_fetcher_->StartTokenCreate(); +} + // static InSessionPasswordChangeManager* InSessionPasswordChangeManager::GetNullable() { return g_test_instance ? g_test_instance
diff --git a/chrome/browser/chromeos/login/saml/in_session_password_change_manager.h b/chrome/browser/chromeos/login/saml/in_session_password_change_manager.h index 68634f0..fba89ab 100644 --- a/chrome/browser/chromeos/login/saml/in_session_password_change_manager.h +++ b/chrome/browser/chromeos/login/saml/in_session_password_change_manager.h
@@ -12,6 +12,7 @@ #include "base/memory/scoped_refptr.h" #include "base/observer_list.h" #include "base/time/time.h" +#include "chrome/browser/chromeos/login/saml/password_sync_token_fetcher.h" #include "chromeos/login/auth/auth_status_consumer.h" class Profile; @@ -58,8 +59,10 @@ // long as the primary user session exists (but only if the primary user's // InSessionPasswordChange policy is enabled and the kInSessionPasswordChange // feature is enabled). -class InSessionPasswordChangeManager : public AuthStatusConsumer, - public ash::SessionActivationObserver { +class InSessionPasswordChangeManager + : public AuthStatusConsumer, + public ash::SessionActivationObserver, + public PasswordSyncTokenFetcher::Consumer { public: // Events in the in-session SAML password change flow. enum class Event { @@ -154,16 +157,23 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - // AuthStatusConsumer: + // AuthStatusConsumer void OnAuthFailure(const AuthFailure& error) override; void OnPasswordChangeDetected(const UserContext& user_context) override; void OnAuthSuccess(const UserContext& user_context) override; - // ash::SessionActivationObserver: + // ash::SessionActivationObserver void OnSessionActivated(bool activated) override; void OnLockStateChanged(bool locked) override; + // PasswordSyncTokenFetcher::Consumer + void OnTokenCreated(const std::string& sync_token) override; + void OnTokenFetched(const std::string& sync_token) override; + void OnTokenVerified(bool is_valid) override; + void OnApiCallFailed(PasswordSyncTokenFetcher::ErrorType error_type) override; + private: + void CreateTokenAsync(); static InSessionPasswordChangeManager* GetNullable(); void NotifyObservers(Event event); @@ -176,6 +186,7 @@ int urgent_warning_days_; bool renotify_on_unlock_ = false; PasswordSource password_source_ = PasswordSource::PASSWORDS_SCRAPED; + std::unique_ptr<PasswordSyncTokenFetcher> password_sync_token_fetcher_; friend class InSessionPasswordChangeManagerTest;
diff --git a/chrome/browser/chromeos/remote_apps/DEPS b/chrome/browser/chromeos/remote_apps/DEPS index 12a0b7b..5d92f21c 100644 --- a/chrome/browser/chromeos/remote_apps/DEPS +++ b/chrome/browser/chromeos/remote_apps/DEPS
@@ -1,5 +1,5 @@ specific_include_rules = { - "remote_apps_manager_browsertest\.cc": [ + ".*_browsertest\.cc": [ "+ash/app_list", "+ash/shell.h", ],
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_impl.cc b/chrome/browser/chromeos/remote_apps/remote_apps_impl.cc new file mode 100644 index 0000000..e7b9b50 --- /dev/null +++ b/chrome/browser/chromeos/remote_apps/remote_apps_impl.cc
@@ -0,0 +1,121 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/remote_apps/remote_apps_impl.h" + +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/optional.h" +#include "base/stl_util.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_manager.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_manager_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/render_frame_host.h" +#include "extensions/common/extension.h" +#include "extensions/common/features/behavior_feature.h" +#include "extensions/common/features/feature.h" +#include "extensions/common/features/feature_provider.h" + +namespace chromeos { + +namespace { + +constexpr char kErrNotReady[] = "Manager for remote apps is not ready"; +constexpr char kErrFolderIdDoesNotExist[] = "Folder ID provided does not exist"; + +static bool g_bypass_checks_for_testing_ = false; + +} // namespace + +// static +bool RemoteAppsImpl::IsAllowed(content::RenderFrameHost* render_frame_host, + const extensions::Extension* extension) { + if (!render_frame_host || !extension) + return false; + + Profile* profile = + Profile::FromBrowserContext(render_frame_host->GetBrowserContext()); + DCHECK(profile); + // RemoteApps are not available for non-managed guest sessions. + if (!RemoteAppsManagerFactory::GetForProfile(profile)) + return false; + + if (g_bypass_checks_for_testing_) + return true; + + const extensions::Feature* feature = + extensions::FeatureProvider::GetBehaviorFeature( + extensions::behavior_feature::kKeyImprivataInSessionExtension); + DCHECK(feature); + return feature->IsAvailableToExtension(extension).is_available(); +} + +// static +void RemoteAppsImpl::SetBypassChecksForTesting(bool bypass_checks_for_testing) { + g_bypass_checks_for_testing_ = bypass_checks_for_testing; +} + +RemoteAppsImpl::RemoteAppsImpl(RemoteAppsManager* manager) : manager_(manager) { + DCHECK(manager); +} + +RemoteAppsImpl::~RemoteAppsImpl() = default; + +void RemoteAppsImpl::Bind( + mojo::PendingReceiver<remote_apps::mojom::RemoteApps> pending_remote_apps, + mojo::PendingRemote<remote_apps::mojom::RemoteAppLaunchObserver> + pending_observer) { + receivers_.Add(this, std::move(pending_remote_apps)); + app_launch_observers_.Add( + mojo::Remote<remote_apps::mojom::RemoteAppLaunchObserver>( + std::move(pending_observer))); +} + +void RemoteAppsImpl::AddFolder(const std::string& name, + AddFolderCallback callback) { + const std::string& folder_id = manager_->AddFolder(name); + std::move(callback).Run(folder_id, base::nullopt); +} + +void RemoteAppsImpl::AddApp(const std::string& name, + const std::string& folder_id, + const GURL& icon_url, + AddAppCallback callback) { + manager_->AddApp( + name, folder_id, icon_url, + base::BindOnce(&RemoteAppsImpl::OnAppAdded, weak_factory_.GetWeakPtr(), + std::move(callback))); +} + +void RemoteAppsImpl::OnAppLaunched(const std::string& id) { + if (!base::Contains(app_ids_, id)) + return; + for (auto& observer : app_launch_observers_) + observer->OnRemoteAppLaunched(id); +} + +void RemoteAppsImpl::OnAppAdded(AddAppCallback callback, + const std::string& id, + RemoteAppsError error) { + switch (error) { + case RemoteAppsError::kNotReady: + std::move(callback).Run(base::nullopt, kErrNotReady); + return; + case RemoteAppsError::kFolderIdDoesNotExist: + std::move(callback).Run(base::nullopt, kErrFolderIdDoesNotExist); + return; + case RemoteAppsError::kNone: + app_ids_.insert(id); + std::move(callback).Run(id, base::nullopt); + return; + case RemoteAppsError::kAppIdDoesNotExist: + // Only occurs when deleting an app, which is not yet implemented in the + // API. + DCHECK(false); + } +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_impl.h b/chrome/browser/chromeos/remote_apps/remote_apps_impl.h new file mode 100644 index 0000000..3102800 --- /dev/null +++ b/chrome/browser/chromeos/remote_apps/remote_apps_impl.h
@@ -0,0 +1,76 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_REMOTE_APPS_REMOTE_APPS_IMPL_H_ +#define CHROME_BROWSER_CHROMEOS_REMOTE_APPS_REMOTE_APPS_IMPL_H_ + +#include <set> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "base/scoped_observer.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_types.h" +#include "chromeos/components/remote_apps/mojom/remote_apps.mojom.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/remote_set.h" +#include "url/gurl.h" + +namespace content { +class RenderFrameHost; +} + +namespace extensions { +class Extension; +} + +namespace chromeos { + +class RemoteAppsManager; + +// Forwards calls to RemoteAppsManager via mojo. Also keeps track of apps added +// by the extension for |OnAppLaunched()|. +class RemoteAppsImpl : public remote_apps::mojom::RemoteApps { + public: + static bool IsAllowed(content::RenderFrameHost* render_frame_host, + const extensions::Extension* extension); + + static void SetBypassChecksForTesting(bool bypass_checks_for_testing); + + explicit RemoteAppsImpl(RemoteAppsManager* manager); + RemoteAppsImpl(const RemoteAppsImpl&) = delete; + RemoteAppsImpl& operator=(const RemoteAppsImpl&) = delete; + ~RemoteAppsImpl() override; + + void Bind( + mojo::PendingReceiver<remote_apps::mojom::RemoteApps> pending_remote_apps, + mojo::PendingRemote<remote_apps::mojom::RemoteAppLaunchObserver> + pending_observer); + + // remote_apps::mojom::RemoteApps: + void AddFolder(const std::string& name, AddFolderCallback callback) override; + void AddApp(const std::string& name, + const std::string& folder_id, + const GURL& icon_url, + AddAppCallback callback) override; + + void OnAppLaunched(const std::string& id); + + private: + void OnAppAdded(AddAppCallback callback, + const std::string& id, + RemoteAppsError error); + + RemoteAppsManager* manager_ = nullptr; + std::set<std::string> app_ids_; + mojo::ReceiverSet<remote_apps::mojom::RemoteApps> receivers_; + mojo::RemoteSet<remote_apps::mojom::RemoteAppLaunchObserver> + app_launch_observers_; + base::WeakPtrFactory<RemoteAppsImpl> weak_factory_{this}; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_REMOTE_APPS_REMOTE_APPS_IMPL_H_
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_impl_browsertest.cc b/chrome/browser/chromeos/remote_apps/remote_apps_impl_browsertest.cc new file mode 100644 index 0000000..8a79a6da --- /dev/null +++ b/chrome/browser/chromeos/remote_apps/remote_apps_impl_browsertest.cc
@@ -0,0 +1,184 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/remote_apps/remote_apps_impl.h" + +#include <string> +#include <vector> + +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/app_list/model/app_list_item.h" +#include "ash/app_list/model/app_list_model.h" +#include "ash/shell.h" +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/values.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" +#include "chrome/browser/chromeos/login/test/session_manager_state_waiter.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/remote_apps/id_generator.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_manager.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_manager_factory.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_model.h" +#include "chrome/browser/extensions/chrome_test_extension_loader.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "chrome/common/chrome_paths.h" +#include "chromeos/constants/chromeos_switches.h" +#include "components/policy/proto/chrome_device_policy.pb.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" +#include "content/public/test/browser_test.h" +#include "extensions/browser/api/test/test_api.h" +#include "extensions/common/manifest.h" +#include "extensions/common/switches.h" +#include "extensions/test/extension_test_message_listener.h" +#include "extensions/test/result_catcher.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace { + +// ID of extension found at chrome/test/data/remote_apps. +constexpr char kExtensionId[] = "ceddkihciiemhnpnhbndbinppokgoidh"; + +constexpr char kId1[] = "Id 1"; +constexpr char kId2[] = "Id 2"; +constexpr char kId3[] = "Id 3"; + +} // namespace + +class RemoteAppsImplBrowsertest : public policy::DevicePolicyCrosBrowserTest { + public: + RemoteAppsImplBrowsertest() : policy::DevicePolicyCrosBrowserTest() {} + + // DevicePolicyCrosBrowserTest: + void SetUp() override { + app_list::AppListSyncableServiceFactory::SetUseInTesting(true); + RemoteAppsImpl::SetBypassChecksForTesting(true); + DevicePolicyCrosBrowserTest::SetUp(); + } + + // DevicePolicyCrosBrowserTest: + void SetUpCommandLine(base::CommandLine* command_line) override { + DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(chromeos::switches::kLoginManager); + command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); + command_line->AppendSwitchASCII( + extensions::switches::kAllowlistedExtensionID, kExtensionId); + } + + // DevicePolicyCrosBrowserTest: + void SetUpOnMainThread() override { + policy::DevicePolicyCrosBrowserTest::SetUpOnMainThread(); + + SetUpDeviceLocalAccountPolicy(); + WizardController::SkipPostLoginScreensForTesting(); + SessionStateWaiter(session_manager::SessionState::ACTIVE).Wait(); + } + + void SetUpDeviceLocalAccountPolicy() { + enterprise_management::DeviceLocalAccountsProto* const + device_local_accounts = + device_policy()->payload().mutable_device_local_accounts(); + enterprise_management::DeviceLocalAccountInfoProto* const account = + device_local_accounts->add_account(); + account->set_account_id("user@test"); + account->set_type(enterprise_management::DeviceLocalAccountInfoProto:: + ACCOUNT_TYPE_PUBLIC_SESSION); + device_local_accounts->set_auto_login_id("user@test"); + device_local_accounts->set_auto_login_delay(0); + RefreshDevicePolicy(); + } + + void LoadExtensionAndRunTest(const std::string& test_name) { + config_.SetKey("customArg", base::Value(test_name)); + extensions::TestGetConfigFunction::set_test_config_state(&config_); + + base::FilePath test_dir_path; + base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir_path); + base::FilePath extension_path = + test_dir_path.AppendASCII("extensions/remote_apps/extension"); + base::FilePath pem_path = + test_dir_path.AppendASCII("extensions/remote_apps/remote_apps.pem"); + + user_manager::User* user = + user_manager::UserManager::Get()->GetActiveUser(); + Profile* profile = ProfileHelper::Get()->GetProfileByUser(user); + + std::unique_ptr<FakeIdGenerator> id_generator = + std::make_unique<FakeIdGenerator>( + std::vector<std::string>{kId1, kId2, kId3}); + RemoteAppsManagerFactory::GetForProfile(profile) + ->GetModelForTesting() + ->SetIdGeneratorForTesting(std::move(id_generator)); + + extensions::ChromeTestExtensionLoader loader(profile); + loader.set_location(extensions::Manifest::EXTERNAL_POLICY); + loader.set_pack_extension(true); + loader.set_pem_path(pem_path); + ASSERT_TRUE(loader.LoadExtension(extension_path)); + } + + ash::AppListItem* GetAppListItem(const std::string& id) { + ash::AppListControllerImpl* controller = + ash::Shell::Get()->app_list_controller(); + ash::AppListModel* model = controller->GetModel(); + return model->FindItem(id); + } + + private: + base::DictionaryValue config_; + chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; +}; + +IN_PROC_BROWSER_TEST_F(RemoteAppsImplBrowsertest, AddApp) { + extensions::ResultCatcher catcher; + LoadExtensionAndRunTest("AddApp"); + ASSERT_TRUE(catcher.GetNextResult()); + + ash::AppListItem* app = GetAppListItem(kId1); + EXPECT_FALSE(app->is_folder()); + EXPECT_EQ("App 1", app->name()); +} + +IN_PROC_BROWSER_TEST_F(RemoteAppsImplBrowsertest, AddFolderAndApps) { + extensions::ResultCatcher catcher; + LoadExtensionAndRunTest("AddFolderAndApps"); + ASSERT_TRUE(catcher.GetNextResult()); + + ash::AppListItem* folder = GetAppListItem(kId1); + EXPECT_TRUE(folder->is_folder()); + EXPECT_EQ("Folder 1", folder->name()); + EXPECT_EQ(2u, folder->ChildItemCount()); + EXPECT_TRUE(folder->FindChildItem(kId2)); + EXPECT_TRUE(folder->FindChildItem(kId3)); + + ash::AppListItem* app1 = GetAppListItem(kId2); + EXPECT_EQ(kId1, app1->folder_id()); + + ash::AppListItem* app2 = GetAppListItem(kId3); + EXPECT_EQ(kId1, app2->folder_id()); +} + +IN_PROC_BROWSER_TEST_F(RemoteAppsImplBrowsertest, OnRemoteAppLaunched) { + extensions::ResultCatcher catcher; + ExtensionTestMessageListener listener("Remote app added", + /*will_reply=*/false); + listener.set_extension_id(kExtensionId); + LoadExtensionAndRunTest("OnRemoteAppLaunched"); + ASSERT_TRUE(listener.WaitUntilSatisfied()); + + ChromeLauncherController::instance()->LaunchApp( + ash::ShelfID(kId1), ash::ShelfLaunchSource::LAUNCH_FROM_APP_LIST, + /*event_flags=*/0, /*display_id=*/0); + ASSERT_TRUE(catcher.GetNextResult()); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_manager.cc b/chrome/browser/chromeos/remote_apps/remote_apps_manager.cc index ceb25bb..4509fd4 100644 --- a/chrome/browser/chromeos/remote_apps/remote_apps_manager.cc +++ b/chrome/browser/chromeos/remote_apps/remote_apps_manager.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/image_downloader.h" #include "base/bind.h" #include "chrome/browser/apps/app_service/menu_util.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" #include "chrome/browser/ui/app_list/app_list_syncable_service.h" @@ -73,12 +74,13 @@ const GURL& icon_url, AddAppCallback callback) { if (!is_initialized_) { - std::move(callback).Run(std::string(), Error::kNotReady); + std::move(callback).Run(std::string(), RemoteAppsError::kNotReady); return; } if (!folder_id.empty() && !model_->HasFolder(folder_id)) { - std::move(callback).Run(std::string(), Error::kFolderIdDoesNotExist); + std::move(callback).Run(std::string(), + RemoteAppsError::kFolderIdDoesNotExist); return; } @@ -88,15 +90,15 @@ remote_apps_->AddApp(info); } -RemoteAppsManager::Error RemoteAppsManager::DeleteApp(const std::string& id) { +RemoteAppsError RemoteAppsManager::DeleteApp(const std::string& id) { // Check if app was added but |HandleOnAppAdded| has not been called. if (!model_->HasApp(id) || add_app_callback_map_.find(id) != add_app_callback_map_.end()) - return Error::kAppIdDoesNotExist; + return RemoteAppsError::kAppIdDoesNotExist; model_->DeleteApp(id); remote_apps_->DeleteApp(id); - return Error::kNone; + return RemoteAppsError::kNone; } std::string RemoteAppsManager::AddFolder(const std::string& folder_name) { @@ -105,17 +107,16 @@ return folder_info.id; } -RemoteAppsManager::Error RemoteAppsManager::DeleteFolder( - const std::string& folder_id) { +RemoteAppsError RemoteAppsManager::DeleteFolder(const std::string& folder_id) { if (!model_->HasFolder(folder_id)) - return Error::kFolderIdDoesNotExist; + return RemoteAppsError::kFolderIdDoesNotExist; // Move all items out of the folder. Empty folders are automatically deleted. RemoteAppsModel::FolderInfo& folder_info = model_->GetFolderInfo(folder_id); for (const auto& app : folder_info.items) model_updater_->MoveItemToFolder(app, std::string()); model_->DeleteFolder(folder_id); - return Error::kNone; + return RemoteAppsError::kNone; } void RemoteAppsManager::AddObserver(Observer* observer) { @@ -126,8 +127,22 @@ observer_list_.RemoveObserver(observer); } +void RemoteAppsManager::BindInterface( + mojo::PendingReceiver<remote_apps::mojom::RemoteAppsFactory> + pending_remote_apps_factory) { + receivers_.Add(this, std::move(pending_remote_apps_factory)); +} + void RemoteAppsManager::Shutdown() {} +void RemoteAppsManager::Create( + mojo::PendingReceiver<remote_apps::mojom::RemoteApps> pending_remote_apps, + mojo::PendingRemote<remote_apps::mojom::RemoteAppLaunchObserver> + pending_observer) { + remote_apps_impl_.Bind(std::move(pending_remote_apps), + std::move(pending_observer)); +} + const std::map<std::string, RemoteAppsModel::AppInfo>& RemoteAppsManager::GetApps() { return model_->GetAllAppInfo(); @@ -136,6 +151,7 @@ void RemoteAppsManager::LaunchApp(const std::string& id) { for (Observer& observer : observer_list_) observer.OnAppLaunched(id); + remote_apps_impl_.OnAppLaunched(id); } gfx::ImageSkia RemoteAppsManager::GetIcon(const std::string& id) { @@ -214,7 +230,7 @@ auto it = add_app_callback_map_.find(id); DCHECK(it != add_app_callback_map_.end()) << "Missing callback for id: " << id; - std::move(it->second).Run(id, Error::kNone); + std::move(it->second).Run(id, RemoteAppsError::kNone); add_app_callback_map_.erase(it); }
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_manager.h b/chrome/browser/chromeos/remote_apps/remote_apps_manager.h index 0ca73492..78c7efe 100644 --- a/chrome/browser/chromeos/remote_apps/remote_apps_manager.h +++ b/chrome/browser/chromeos/remote_apps/remote_apps_manager.h
@@ -13,11 +13,16 @@ #include "base/observer_list.h" #include "base/scoped_observer.h" #include "chrome/browser/apps/app_service/remote_apps.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_impl.h" #include "chrome/browser/chromeos/remote_apps/remote_apps_model.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_types.h" #include "chrome/browser/ui/app_list/app_list_model_updater_observer.h" #include "chrome/browser/ui/app_list/app_list_syncable_service.h" #include "chrome/browser/ui/app_list/chrome_app_list_model_updater.h" +#include "chromeos/components/remote_apps/mojom/remote_apps.mojom.h" #include "components/keyed_service/core/keyed_service.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" class AppListModelUpdater; class ChromeAppListItem; @@ -33,6 +38,8 @@ namespace chromeos { +class RemoteAppsImpl; + // KeyedService which manages the logic for |AppType::kRemote| in AppService. // This service is only created for Managed Guest Sessions. // The IDs of the added apps and folders are GUIDs generated using @@ -40,16 +47,9 @@ class RemoteAppsManager : public KeyedService, public apps::RemoteApps::Delegate, public app_list::AppListSyncableService::Observer, - public AppListModelUpdaterObserver { + public AppListModelUpdaterObserver, + public remote_apps::mojom::RemoteAppsFactory { public: - enum class Error { - kNone = 0, - kAppIdDoesNotExist, - kFolderIdDoesNotExist, - // Manager has not been initialized. - kNotReady, - }; - class Observer : public base::CheckedObserver { public: ~Observer() override = default; @@ -73,8 +73,12 @@ bool is_initialized() const { return is_initialized_; } + void BindInterface( + mojo::PendingReceiver<remote_apps::mojom::RemoteAppsFactory> + pending_remote_apps_factory); + using AddAppCallback = - base::OnceCallback<void(const std::string& id, Error error)>; + base::OnceCallback<void(const std::string& id, RemoteAppsError error)>; // Adds a app with the given |name|. If |folder_id| is non-empty, the app is // added to the folder with the given ID. The icon of the app is an image @@ -92,7 +96,7 @@ // Deletes the app with id |id|. // Deleting a non-existent app will result in an error. - Error DeleteApp(const std::string& id); + RemoteAppsError DeleteApp(const std::string& id); // Adds a folder with |folder_name|. Note that empty folders are not // shown in the launcher. Returns the ID for the added folder. @@ -101,7 +105,7 @@ // Deletes the folder with id |folder_id|. All items in the folder are moved // to the top-level in the launcher. // Deleting a non-existent folder will result in an error. - Error DeleteFolder(const std::string& folder_id); + RemoteAppsError DeleteFolder(const std::string& folder_id); void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -109,6 +113,12 @@ // KeyedService: void Shutdown() override; + // remote_apps::mojom::RemoteAppsFactory: + void Create( + mojo::PendingReceiver<remote_apps::mojom::RemoteApps> pending_remote_apps, + mojo::PendingRemote<remote_apps::mojom::RemoteAppLaunchObserver> + pending_observer) override; + // apps::RemoteApps::Delegate: const std::map<std::string, RemoteAppsModel::AppInfo>& GetApps() override; void LaunchApp(const std::string& id) override; @@ -146,9 +156,11 @@ app_list::AppListSyncableService* app_list_syncable_service_ = nullptr; AppListModelUpdater* model_updater_ = nullptr; std::unique_ptr<apps::RemoteApps> remote_apps_; + RemoteAppsImpl remote_apps_impl_{this}; std::unique_ptr<RemoteAppsModel> model_; std::unique_ptr<ImageDownloader> image_downloader_; base::ObserverList<Observer> observer_list_; + mojo::ReceiverSet<remote_apps::mojom::RemoteAppsFactory> receivers_; // Map from id to callback. The callback is run after |OnAppUpdate| for the // app has been observed. std::map<std::string, AddAppCallback> add_app_callback_map_;
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc b/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc index d374ae1..a7768cb 100644 --- a/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc +++ b/chrome/browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc
@@ -213,35 +213,34 @@ const GURL& icon_url) { base::RunLoop run_loop; std::string id; - manager_->AddApp( - name, folder_id, icon_url, - base::BindOnce( - [](base::RepeatingClosure closure, std::string* id_arg, - const std::string& id, RemoteAppsManager::Error error) { - ASSERT_EQ(RemoteAppsManager::Error::kNone, error); + manager_->AddApp(name, folder_id, icon_url, + base::BindOnce( + [](base::RepeatingClosure closure, std::string* id_arg, + const std::string& id, RemoteAppsError error) { + ASSERT_EQ(RemoteAppsError::kNone, error); - ash::AppListControllerImpl* controller = - ash::Shell::Get()->app_list_controller(); - ash::AppListModel* model = controller->GetModel(); - ASSERT_TRUE(model->FindItem(id)); - *id_arg = id; + ash::AppListControllerImpl* controller = + ash::Shell::Get()->app_list_controller(); + ash::AppListModel* model = controller->GetModel(); + ASSERT_TRUE(model->FindItem(id)); + *id_arg = id; - closure.Run(); - }, - run_loop.QuitClosure(), &id)); + closure.Run(); + }, + run_loop.QuitClosure(), &id)); run_loop.Run(); return id; } - RemoteAppsManager::Error DeleteApp(const std::string& id) { - RemoteAppsManager::Error error = manager_->DeleteApp(id); + RemoteAppsError DeleteApp(const std::string& id) { + RemoteAppsError error = manager_->DeleteApp(id); // Allow updates to propagate to AppList. base::RunLoop().RunUntilIdle(); return error; } - RemoteAppsManager::Error DeleteFolder(const std::string& id) { - RemoteAppsManager::Error error = manager_->DeleteFolder(id); + RemoteAppsError DeleteFolder(const std::string& id) { + RemoteAppsError error = manager_->DeleteFolder(id); // Allow updates to propagate to AppList. base::RunLoop().RunUntilIdle(); return error; @@ -258,7 +257,7 @@ waiter.Wait(); } - void AddAppAssertError(RemoteAppsManager::Error error, + void AddAppAssertError(RemoteAppsError error, const std::string& name, const std::string& folder_id, const GURL& icon_url) { @@ -266,9 +265,8 @@ manager_->AddApp( name, folder_id, icon_url, base::BindOnce( - [](base::RepeatingClosure closure, - RemoteAppsManager::Error expected_error, const std::string& id, - RemoteAppsManager::Error error) { + [](base::RepeatingClosure closure, RemoteAppsError expected_error, + const std::string& id, RemoteAppsError error) { ASSERT_EQ(expected_error, error); closure.Run(); }, @@ -308,8 +306,8 @@ GURL icon_url("icon_url"); gfx::ImageSkia icon = CreateTestIcon(32, SK_ColorRED); - AddAppAssertError(RemoteAppsManager::Error::kFolderIdDoesNotExist, name, - kMissingId, icon_url); + AddAppAssertError(RemoteAppsError::kFolderIdDoesNotExist, name, kMissingId, + icon_url); } IN_PROC_BROWSER_TEST_F(RemoteAppsManagerBrowsertest, AddAppErrorNotReady) { @@ -318,8 +316,7 @@ gfx::ImageSkia icon = CreateTestIcon(32, SK_ColorRED); manager_->SetIsInitializedForTesting(false); - AddAppAssertError(RemoteAppsManager::Error::kNotReady, name, std::string(), - icon_url); + AddAppAssertError(RemoteAppsError::kNotReady, name, std::string(), icon_url); } IN_PROC_BROWSER_TEST_F(RemoteAppsManagerBrowsertest, DeleteApp) { @@ -327,15 +324,14 @@ AddAppAndWaitForIconChange(kId1, "name", std::string(), GURL("icon_url"), CreateTestIcon(32, SK_ColorRED)); - RemoteAppsManager::Error error = DeleteApp(kId1); + RemoteAppsError error = DeleteApp(kId1); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(RemoteAppsManager::Error::kNone, error); + EXPECT_EQ(RemoteAppsError::kNone, error); EXPECT_FALSE(GetAppListItem(kId1)); } IN_PROC_BROWSER_TEST_F(RemoteAppsManagerBrowsertest, DeleteAppError) { - EXPECT_EQ(RemoteAppsManager::Error::kAppIdDoesNotExist, - DeleteApp(kMissingId)); + EXPECT_EQ(RemoteAppsError::kAppIdDoesNotExist, DeleteApp(kMissingId)); } IN_PROC_BROWSER_TEST_F(RemoteAppsManagerBrowsertest, AddAndDeleteFolder) { @@ -343,12 +339,11 @@ // Empty folder has no AppListItem. EXPECT_FALSE(GetAppListItem(kId1)); - EXPECT_EQ(RemoteAppsManager::Error::kNone, DeleteFolder(kId1)); + EXPECT_EQ(RemoteAppsError::kNone, DeleteFolder(kId1)); } IN_PROC_BROWSER_TEST_F(RemoteAppsManagerBrowsertest, DeleteFolderError) { - EXPECT_EQ(RemoteAppsManager::Error::kFolderIdDoesNotExist, - DeleteFolder(kMissingId)); + EXPECT_EQ(RemoteAppsError::kFolderIdDoesNotExist, DeleteFolder(kMissingId)); } IN_PROC_BROWSER_TEST_F(RemoteAppsManagerBrowsertest, AddFolderAndApp) {
diff --git a/chrome/browser/chromeos/remote_apps/remote_apps_types.h b/chrome/browser/chromeos/remote_apps/remote_apps_types.h new file mode 100644 index 0000000..e3d9f00 --- /dev/null +++ b/chrome/browser/chromeos/remote_apps/remote_apps_types.h
@@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_REMOTE_APPS_REMOTE_APPS_TYPES_H_ +#define CHROME_BROWSER_CHROMEOS_REMOTE_APPS_REMOTE_APPS_TYPES_H_ + +namespace chromeos { + +enum class RemoteAppsError { + kNone = 0, + kAppIdDoesNotExist, + kFolderIdDoesNotExist, + // Manager has not been initialized. + kNotReady, +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_REMOTE_APPS_REMOTE_APPS_TYPES_H_
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 9c7f63d6..8beb72d 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -3663,15 +3663,15 @@ static constexpr const wchar_t* kCrazyFilenames[] = { L"a_file_name.zip", L"\u89c6\u9891\u76f4\u64ad\u56fe\u7247.zip", // chinese chars - L"\u0412\u043e " - L"\u0424\u043b\u043e\u0440\u0438\u0434\u0435\u043e\u0431\u044a" - L"\u044f\u0432\u043b\u0435\u043d\u0440\u0435\u0436\u0438\u043c \u0427" - L"\u041f \u0438\u0437-\u0437\u0430 \u0443\u0442\u0435\u0447\u043a\u0438 " - L"\u043d\u0435\u0444\u0442\u0438.zip", // russian + (L"\u0412\u043e " + L"\u0424\u043b\u043e\u0440\u0438\u0434\u0435\u043e\u0431\u044a" + L"\u044f\u0432\u043b\u0435\u043d\u0440\u0435\u0436\u0438\u043c \u0427" + L"\u041f \u0438\u0437-\u0437\u0430 \u0443\u0442\u0435\u0447\u043a\u0438 " + L"\u043d\u0435\u0444\u0442\u0438.zip"), // russian L"Desocupa\xe7\xe3o est\xe1vel.zip", // arabic: - L"\u0638\u2026\u0638\u02c6\u0637\xa7\u0638\u201a\u0637\xb9 \u0638\u201e" - L"\u0638\u201e\u0637\xb2\u0638\u0679\u0637\xa7\u0637\xb1\u0637\xa9.zip", + (L"\u0638\u2026\u0638\u02c6\u0637\xa7\u0638\u201a\u0637\xb9 \u0638\u201e" + L"\u0638\u201e\u0637\xb2\u0638\u0679\u0637\xa7\u0637\xb1\u0637\xa9.zip"), L"\u05d4\u05e2\u05d3\u05e4\u05d5\u05ea.zip", // hebrew L"\u092d\u093e\u0930\u0924.zip", // hindi L"d\xe9stabilis\xe9.zip", // french @@ -3679,7 +3679,8 @@ L"\u97d3-\u4e2d \uc815\uc0c1, \ucc9c\uc548\ud568 \uc758\uacac.zip", L"jiho....tiho...miho.zip", L"jiho!@#$tiho$%^&-()_+=miho copy.zip", // special chars - L"Wohoo-to hoo+I.zip", L"Picture 1.zip", + L"Wohoo-to hoo+I.zip", + L"Picture 1.zip", L"This is a very very long english sentence with spaces and , and +.zip", };
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 814316e..240e561 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -1028,6 +1028,7 @@ "//chromeos/components/camera_app_ui:mojo_bindings", "//chromeos/components/camera_app_ui/resources:chrome_camera_app", "//chromeos/components/proximity_auth", + "//chromeos/components/remote_apps/mojom", "//chromeos/constants", "//chromeos/cryptohome", "//chromeos/dbus",
diff --git a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc index b872063..a434c9d 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_interface_binders.cc
@@ -18,10 +18,14 @@ #include "extensions/common/permissions/permissions_data.h" #if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/remote_apps/remote_apps_impl.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_manager.h" +#include "chrome/browser/chromeos/remote_apps/remote_apps_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/speech/extension_api/tts_engine_extension_observer.h" #include "chrome/common/extensions/extension_constants.h" #include "chromeos/components/camera_app_ui/camera_app_ui.h" +#include "chromeos/components/remote_apps/mojom/remote_apps.mojom.h" #include "chromeos/services/cfm/public/buildflags/buildflags.h" #include "chromeos/services/media_perception/public/mojom/media_perception.mojom.h" #include "chromeos/services/tts/public/mojom/tts_service.mojom.h" @@ -80,7 +84,20 @@ ->BindTtsStream(std::move(receiver)); } -#endif +void BindRemoteAppsFactory( + content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver<chromeos::remote_apps::mojom::RemoteAppsFactory> + pending_receiver) { + // |remote_apps_manager| will be null in non-managed guest sessions, but this + // is already checked in |RemoteAppsImpl::IsAllowed()|. + chromeos::RemoteAppsManager* remote_apps_manager = + chromeos::RemoteAppsManagerFactory::GetForProfile( + Profile::FromBrowserContext(render_frame_host->GetBrowserContext())); + DCHECK(remote_apps_manager); + remote_apps_manager->BindInterface(std::move(pending_receiver)); +} + +#endif // defined(OS_CHROMEOS) } // namespace void PopulateChromeFrameBindersForExtension( @@ -155,7 +172,12 @@ binder_map->Add<chromeos::tts::mojom::TtsStream>( base::BindRepeating(&BindTtsStream)); } -#endif + + if (chromeos::RemoteAppsImpl::IsAllowed(render_frame_host, extension)) { + binder_map->Add<chromeos::remote_apps::mojom::RemoteAppsFactory>( + base::BindRepeating(&BindRemoteAppsFactory)); + } +#endif // defined(OS_CHROMEOS) } } // namespace extensions
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 8a6f818..888a999c 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2114,11 +2114,6 @@ "expiry_milestone": 86 }, { - "name": "enable-sync-trusted-vault", - "owners": [ "mastiz@chromium.org", "//components/sync/OWNERS" ], - "expiry_milestone": 85 - }, - { "name": "enable-system-webapps", "owners": [ "calamity" ], "expiry_milestone": 78 @@ -3628,12 +3623,12 @@ }, { "name": "pluginvm-show-camera-permissions", - "owners": [ "danielng" ], + "owners": [ "danielng@google.com", "lxj@google.com" ], "expiry_milestone": 87 }, { "name": "pluginvm-show-microphone-permissions", - "owners": [ "dtor" ], + "owners": [ "dtor", "lxj@google.com" ], "expiry_milestone": 87 }, {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 2d52ccb..ebd0cdd7 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -971,11 +971,6 @@ "Enable using server-provided resource loading hints to provide a preview " "over slow network connections."; -const char kEnableSyncTrustedVaultName[] = - "Enable trusted vault sync passphrase type"; -const char kEnableSyncTrustedVaultDescription[] = - "Enables the new, experimental passphrase type for sync data"; - #if BUILDFLAG(ENABLE_TAB_SEARCH) const char kEnableTabSearchName[] = "Enable Tab Search"; const char kEnableTabSearchDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d17ce02..986f950 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -564,9 +564,6 @@ extern const char kEnableSubresourceRedirectName[]; extern const char kEnableSubresourceRedirectDescription[]; -extern const char kEnableSyncTrustedVaultName[]; -extern const char kEnableSyncTrustedVaultDescription[]; - #if BUILDFLAG(ENABLE_TAB_SEARCH) extern const char kEnableTabSearchName[]; extern const char kEnableTabSearchDescription[];
diff --git a/chrome/browser/media/webrtc/media_stream_infobar_browsertest.cc b/chrome/browser/media/webrtc/media_stream_permission_browsertest.cc similarity index 78% rename from chrome/browser/media/webrtc/media_stream_infobar_browsertest.cc rename to chrome/browser/media/webrtc/media_stream_permission_browsertest.cc index 49d5e62..d2f3282 100644 --- a/chrome/browser/media/webrtc/media_stream_infobar_browsertest.cc +++ b/chrome/browser/media/webrtc/media_stream_permission_browsertest.cc
@@ -5,6 +5,7 @@ #include "base/command_line.h" #include "base/files/file_util.h" #include "base/macros.h" +#include "base/run_loop.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/media/webrtc/webrtc_browsertest_base.h" @@ -65,7 +66,9 @@ private: content::WebContents* LoadTestPageInBrowser(Browser* browser) { - EXPECT_TRUE(embedded_test_server()->Start()); + if (!embedded_test_server()->Started()) { + EXPECT_TRUE(embedded_test_server()->Start()); + } // Uses the default server. GURL url = test_page_url(); @@ -76,12 +79,6 @@ return browser->tab_strip_model()->GetActiveWebContents(); } - // Dummy callback for when we deny the current request directly. - static void OnMediaStreamResponse( - const blink::MediaStreamDevices& devices, - blink::mojom::MediaStreamRequestResult result, - std::unique_ptr<content::MediaStreamUI> ui) {} - DISALLOW_COPY_AND_ASSIGN(MediaStreamPermissionTest); }; @@ -169,3 +166,50 @@ EXPECT_TRUE(GetUserMediaWithSpecificConstraintsAndAccept( tab_contents, kAudioOnlyCallConstraints)); } + +IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest, + DenyingPermissionStopsStreamWhenRelevant) { + struct { + std::string constraints; + ContentSettingsType setting_to_clear; + bool should_video_stop; + } kTests[] = { + {kAudioVideoCallConstraints, ContentSettingsType::MEDIASTREAM_CAMERA, + true}, + {kAudioVideoCallConstraints, ContentSettingsType::MEDIASTREAM_MIC, true}, + {kVideoOnlyCallConstraints, ContentSettingsType::MEDIASTREAM_CAMERA, + true}, + {kVideoOnlyCallConstraints, ContentSettingsType::MEDIASTREAM_MIC, false}, + }; + + HostContentSettingsMap* settings_map = + HostContentSettingsMapFactory::GetForProfile(browser()->profile()); + + for (const auto& kTest : kTests) { + content::WebContents* tab_contents = LoadTestPageInTab(); + + EXPECT_TRUE(GetUserMediaWithSpecificConstraintsAndAcceptIfPrompted( + tab_contents, kTest.constraints)); + + StartDetectingVideo(tab_contents, "local-view"); + EXPECT_TRUE(WaitForVideoToPlay(tab_contents)); + + settings_map->ClearSettingsForOneType(kTest.setting_to_clear); + + // Let all the cross-thread tasks do their work. + base::RunLoop().RunUntilIdle(); + + StartDetectingVideo(tab_contents, "local-view"); + + if (kTest.should_video_stop) { + EXPECT_TRUE(WaitForVideoToStop(tab_contents)); + } else { + EXPECT_TRUE(WaitForVideoToPlay(tab_contents)); + } + + // Clean up settings for the following tests. + settings_map->ClearSettingsForOneType(ContentSettingsType::MEDIASTREAM_MIC); + settings_map->ClearSettingsForOneType( + ContentSettingsType::MEDIASTREAM_CAMERA); + } +}
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc index 806b591..27819d1 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc +++ b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc
@@ -473,6 +473,14 @@ return is_video_playing; } +bool WebRtcTestBase::WaitForVideoToStop( + content::WebContents* tab_contents) const { + bool is_video_stopped = + test::PollingWaitUntil("isVideoStopped()", "video-stopped", tab_contents); + EXPECT_TRUE(is_video_stopped); + return is_video_stopped; +} + std::string WebRtcTestBase::GetStreamSize( content::WebContents* tab_contents, const std::string& video_element) const {
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_base.h b/chrome/browser/media/webrtc/webrtc_browsertest_base.h index e85f002..3c98df5 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest_base.h +++ b/chrome/browser/media/webrtc/webrtc_browsertest_base.h
@@ -182,7 +182,11 @@ // make that work). Looks at a 320x240 area of the target video tag. void StartDetectingVideo(content::WebContents* tab_contents, const std::string& video_element) const; + + // Wait for a video to start/stop playing. StartDetectingVideo must have + // been called already. bool WaitForVideoToPlay(content::WebContents* tab_contents) const; + bool WaitForVideoToStop(content::WebContents* tab_contents) const; // Returns the stream size as a string on the format <width>x<height>. std::string GetStreamSize(content::WebContents* tab_contents,
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index b275fd38..d19d141 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -1275,8 +1275,10 @@ // If there is a username and password with prefilled values, overwrite the // password if the username looks like a placeholder value + +// TODO(crbug.com/1116886) Renable this test IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, - PlaceholderPasswordOverwritten) { + DISABLED_PlaceholderPasswordOverwritten) { // Save a credential to the password store. scoped_refptr<password_manager::TestPasswordStore> password_store = static_cast<password_manager::TestPasswordStore*>(
diff --git a/chrome/browser/payments/BUILD.gn b/chrome/browser/payments/BUILD.gn index 210ab7e1..d7c0ffb 100644 --- a/chrome/browser/payments/BUILD.gn +++ b/chrome/browser/payments/BUILD.gn
@@ -7,6 +7,7 @@ sources = [ "abort_payment_handler_browsertest.cc", + "android_payment_app_factory_browsertest.cc", "colocated_payment_manifests_browsertest.cc", "empty_parameters_browsertest.cc", "has_enrolled_instrument_browsertest.cc",
diff --git a/chrome/browser/payments/android_payment_app_factory_browsertest.cc b/chrome/browser/payments/android_payment_app_factory_browsertest.cc new file mode 100644 index 0000000..76af1b1 --- /dev/null +++ b/chrome/browser/payments/android_payment_app_factory_browsertest.cc
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/scoped_feature_list.h" +#include "chrome/test/payments/payment_request_platform_browsertest_base.h" +#include "components/payments/core/features.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace payments { +namespace { + +class AndroidPaymentAppFactoryTest + : public PaymentRequestPlatformBrowserTestBase { + public: + AndroidPaymentAppFactoryTest() { + feature_list_.InitAndEnableFeature(features::kAppStoreBilling); + } + + ~AndroidPaymentAppFactoryTest() override = default; + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(AndroidPaymentAppFactoryTest, SmokeTest) { + NavigateTo("a.com", "/app_store_billing_tests/index.html"); + ASSERT_EQ("success", content::EvalJs(GetActiveWebContents(), + content::JsReplace( + "addSupportedMethod($1)", + "https://play.google.com/billing"))); + ASSERT_EQ("success", + content::EvalJs(GetActiveWebContents(), "createPaymentRequest()")); + ASSERT_EQ("false", + content::EvalJs(GetActiveWebContents(), "canMakePayment()")); +} + +} // namespace +} // namespace payments
diff --git a/chrome/browser/plugins/flash_download_interception_unittest.cc b/chrome/browser/plugins/flash_download_interception_unittest.cc index 809c7385..e9d75556 100644 --- a/chrome/browser/plugins/flash_download_interception_unittest.cc +++ b/chrome/browser/plugins/flash_download_interception_unittest.cc
@@ -58,8 +58,8 @@ "http://adobe.com/go/CA-H-GET-FLASH", "http://adobe.com/go/DE_CH-H-M-A2", "http://adobe.com/go/gntray_dl_getflashplayer_jp", - "http://www.adobe.com/shockwave/download/download.cgi?" - "P1_Prod_Version=ShockwaveFlash", + ("http://www.adobe.com/shockwave/download/download.cgi?" + "P1_Prod_Version=ShockwaveFlash"), }; for (auto* url : flash_intercept_urls) { @@ -81,8 +81,8 @@ // Don't match text within the query or fragment. "http://www.adobe.com/go/non-matching?foo=flashplayer", "http://www.adobe.com/go/non-matching#!foo=flashplayer", - "http://www.adobe.com/shockwave/download/download.cgi?" - "P1_Prod_Version=SomethingElse", + ("http://www.adobe.com/shockwave/download/download.cgi?" + "P1_Prod_Version=SomethingElse"), }; for (auto* url : flash_no_intercept_urls) {
diff --git a/chrome/browser/resources/chromeos/edu_login/browser_proxy.js b/chrome/browser/resources/chromeos/edu_login/browser_proxy.js index 04becb0f..c908d389 100644 --- a/chrome/browser/resources/chromeos/edu_login/browser_proxy.js +++ b/chrome/browser/resources/chromeos/edu_login/browser_proxy.js
@@ -61,6 +61,13 @@ */ completeLogin(credentials, eduLoginParams) {} + /** + * Send 'getAccounts' message to the handler. The promise will be resolved + * with the list of emails of accounts in session. + * @return {Promise<Array<string>>} + */ + getAccounts() {} + /** Send 'dialogClose' message to close the login dialog. */ dialogClose() {} } @@ -110,6 +117,11 @@ } /** @override */ + getAccounts() { + return sendWithPromise('getAccounts'); + } + + /** @override */ dialogClose() { chrome.send('dialogClose'); }
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_signin.js b/chrome/browser/resources/chromeos/edu_login/edu_login_signin.js index 7de6352..823f8a5 100644 --- a/chrome/browser/resources/chromeos/edu_login/edu_login_signin.js +++ b/chrome/browser/resources/chromeos/edu_login/edu_login_signin.js
@@ -85,6 +85,8 @@ this.authExtHost_.addEventListener( 'authCompleted', e => this.onAuthCompleted_( /** @type {!CustomEvent<!AuthCompletedCredentials>} */(e))); + this.authExtHost_.addEventListener( + 'getAccounts', () => this.onGetAccounts_()); }, /** @@ -129,6 +131,13 @@ this.loading_ = true; }, + /** @private */ + onGetAccounts_() { + this.browserProxy_.getAccounts().then(result => { + this.authExtHost_.getAccountsResponse(result); + }); + }, + /** * Loads auth extension. * @param {!AuthParams} data Parameters for auth extension.
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 0f0f457..85fa491 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -207,6 +207,9 @@ 'backButton'(msg) { this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); }, + 'getAccounts'(msg) { + this.dispatchEvent(new Event('getAccounts')); + }, 'showView'(msg) { this.dispatchEvent(new Event('showView')); }, @@ -595,6 +598,14 @@ this.isLoaded_ = true; } + /** + * Called in response to 'getAccounts' event. + * @param {Array<string>} accounts list of emails + */ + getAccountsResponse(accounts) { + this.sendMessageToWebview('accountsListed', accounts); + } + constructInitialFrameUrl_(data) { if (data.doSamlRedirect) { let url = this.idpOrigin_ + SAML_REDIRECTION_PATH; @@ -860,11 +871,22 @@ } /** - * Invoked to send a HTML5 message to the webview element. - * @param {*} payload Payload of the HTML5 message. + * Invoked to send a HTML5 message with attached data to the webview + * element. + * @param {string} messageType Type of the HTML5 message. + * @param {Object=} messageData Data to be attached to the message. */ - sendMessageToWebview(payload) { + sendMessageToWebview(messageType, messageData = null) { const currentUrl = this.webview_.src; + let payload = undefined; + if (messageData) { + payload = {type: messageType, data: messageData}; + } else { + // TODO(crbug.com/1116343): Use new message format when it will be + // available in production. + payload = messageType; + } + this.webview_.contentWindow.postMessage(payload, currentUrl); }
diff --git a/chrome/browser/resources/inline_login/inline_login_app.js b/chrome/browser/resources/inline_login/inline_login_app.js index 985b8b0..7b9d167 100644 --- a/chrome/browser/resources/inline_login/inline_login_app.js +++ b/chrome/browser/resources/inline_login/inline_login_app.js
@@ -105,6 +105,8 @@ /** @type {!CustomEvent<!AuthCompletedCredentials>} */ (e))); this.authExtHost_.addEventListener( 'showIncognito', () => this.onShowIncognito_()); + this.authExtHost_.addEventListener( + 'getAccounts', () => this.onGetAccounts_()); }, /** @@ -156,6 +158,13 @@ this.browserProxy_.showIncognito(); }, + /** @private */ + onGetAccounts_() { + this.browserProxy_.getAccounts().then(result => { + this.authExtHost_.getAccountsResponse(result); + }); + }, + /** * Loads auth extension. * @param {!AuthParams} data Parameters for auth extension.
diff --git a/chrome/browser/resources/inline_login/inline_login_browser_proxy.js b/chrome/browser/resources/inline_login/inline_login_browser_proxy.js index 144423f..91bb37dd 100644 --- a/chrome/browser/resources/inline_login/inline_login_browser_proxy.js +++ b/chrome/browser/resources/inline_login/inline_login_browser_proxy.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {AuthCompletedCredentials} from '../gaia_auth_host/authenticator.m.js'; @@ -46,6 +46,13 @@ /** Send 'showIncognito' message to the handler */ showIncognito() {} + /** + * Send 'getAccounts' message to the handler. The promise will be resolved + * with the list of emails of accounts in session. + * @return {Promise<Array<string>>} + */ + getAccounts() {} + /** Send 'dialogClose' message to close the login dialog. */ dialogClose() {} } @@ -88,6 +95,11 @@ } /** @override */ + getAccounts() { + return sendWithPromise('getAccounts'); + } + + /** @override */ dialogClose() { chrome.send('dialogClose'); }
diff --git a/chrome/browser/resources/settings/autofill_page/password_move_to_account_dialog.html b/chrome/browser/resources/settings/autofill_page/password_move_to_account_dialog.html index 4995387..b26470c 100644 --- a/chrome/browser/resources/settings/autofill_page/password_move_to_account_dialog.html +++ b/chrome/browser/resources/settings/autofill_page/password_move_to_account_dialog.html
@@ -4,6 +4,7 @@ --computer-icon-padding-bottom: 10px; --computer-icon-padding-sides: 8px; --hairline-border: 1px; + --hairline-color : var(--google-grey-200); --outer-icon-size: 48px; } @@ -18,7 +19,7 @@ } settings-avatar-icon { - border: var(--hairline-border) solid var(--google-grey-refresh-100); + border: var(--hairline-border) solid var(--hairline-color); border-radius: 50%; display: flex; flex-shrink: 0; @@ -32,7 +33,7 @@ - var(--computer-icon-padding-bottom)); --iron-icon-width: calc(var(--outer-icon-size) - 2 * var(--hairline-border) - 2 * var(--computer-icon-padding-sides)); - border: var(--hairline-border) solid var(--google-grey-refresh-100); + border: var(--hairline-border) solid var(--hairline-color); border-radius: 50%; flex-shrink: 0; padding-bottom: var(--computer-icon-padding-bottom);
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chrome/browser/resources/settings/autofill_page/passwords_section.html index 61658d2..75ac76d 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.html +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -52,22 +52,27 @@ width: 40px; } + #accountStorageOptInButtonsContainer { + padding-bottom: 16px; + } + #devicePasswordsLink { cursor: pointer; + padding-top: 16px; } #devicePasswordsLinkIcon { - border-color: gray; + border-color: var(--google-grey-200); border-radius: 20px; border-style: solid; border-width: 1px; - height: 19px; + height: 17px; margin-inline-end: 16px; padding-bottom: 10px; padding-inline-end: 8px; padding-inline-start: 8px; padding-top: 11px; - width: 24px; + width: 22px; } </style> <settings-toggle-button id="passwordToggle" @@ -166,7 +171,8 @@ <div slot="body" class="list-frame"> <div hidden$="[[!eligibleForAccountStorage_]]" id="accountStorageButtonsContainer"> - <div class="cr-row first two-line list-item"> + <div class="cr-row first two-line list-item" + id="accountStorageOptInButtonsContainer"> <settings-avatar-icon id="profileIcon"></settings-avatar-icon> <div class="flex cr-padded-text"> <div id="accountStorageOptInBody" @@ -188,7 +194,7 @@ $i18n{optOutAccountStorageLabel} </cr-button> </div> - <div id="devicePasswordsLink" class="cr-row first two-line list-item" + <div id="devicePasswordsLink" class="cr-row two-line list-item" hidden$="[[!shouldShowDevicePasswordsLink_]]" on-click="onDevicePasswordsLinkClicked_"> <iron-icon id="devicePasswordsLinkIcon" icon="cr:computer">
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html index 7dd7dda..d182b48 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html
@@ -1,7 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="input_method_util.html"> <link rel="import" href="languages_metrics_proxy.html"> <link rel="import" href="../os_route.html"> @@ -18,6 +20,10 @@ padding-inline-start: var(--cr-section-padding); } + .bottom-margin { + margin-bottom: var(--cr-section-vertical-margin); + } + .icon-external { margin-inline-end: 0; } @@ -39,6 +45,12 @@ .external-wrapper { display: flex; } + + #addInputMethod { + --iron-icon-fill-color: var(--cr-link-color); + margin-inline-end: 4px; + margin-top: 16px; + } </style> <div route-path="default"> @@ -49,7 +61,7 @@ on-settings-boolean-control-change="onShowImeMenuChange_"> </settings-toggle-button> - <div class="hr"> + <div class="hr bottom-margin"> <h2>$i18n{inputMethodListTitle}</h2> <div class="list-frame vertical-list" id="inputMethodsList"> <template is="dom-repeat" @@ -88,8 +100,21 @@ </template> </div> </template> + <div class="list-item"> + <cr-button id="addInputMethod" on-click="onAddInputMethodClick_"> + <iron-icon icon="cr:add"></iron-icon> + $i18n{addInputMethodLabel} + </cr-button> + </div> </div> </div> + <settings-toggle-button id="enableSpellcheckingToggle" class="hr" + label="$i18n{spellCheckTitle}" + sub-label="[[getSpellCheckSubLabel_(spellCheckLanguages_)]]" + pref="{{prefs.browser.enable_spellchecking}}" + disabled="[[!spellCheckLanguages_.length]]" + on-settings-boolean-control-change="onSpellcheckToggleChange_"> + </settings-toggle-button> </div> </template> <script src="input_page.js"></script>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js index 9c58af17..bd3a273 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
@@ -34,6 +34,16 @@ /** @type {!LanguageHelper} */ languageHelper: Object, + + /** + * @private {!Array<!LanguageState|!ForcedLanguageState>} + */ + spellCheckLanguages_: { + type: Array, + value() { + return []; + }, + }, }, /** @private {?settings.LanguagesMetricsProxy} */ @@ -159,4 +169,28 @@ getOpenOptionsPageLabel_(inputMethodName) { return this.i18n('openOptionsPage', inputMethodName); }, + + /** @private */ + onAddInputMethodClick_() { + this.languagesMetricsProxy_.recordAddInputMethod(); + // TODO(crbug/1113439): Add input methods dialog. + }, + + /** + * @return {string|undefined} + * @private + */ + getSpellCheckSubLabel_() { + return this.spellCheckLanguages_.length ? + undefined : // equivalent to not setting the sublabel in the HTML. + this.i18n('spellCheckDisabledReason'); + }, + + /** + * @param {!Event} e + * @private + */ + onSpellcheckToggleChange_(e) { + this.languagesMetricsProxy_.recordToggleSpellCheck(e.target.checked); + }, });
diff --git a/chrome/browser/ui/app_list/search/common/file_icon_util.cc b/chrome/browser/ui/app_list/search/common/file_icon_util.cc index e55f001..cb9dc2c4 100644 --- a/chrome/browser/ui/app_list/search/common/file_icon_util.cc +++ b/chrome/browser/ui/app_list/search/common/file_icon_util.cc
@@ -7,18 +7,35 @@ #include <string> #include <utility> +#include "ash/public/cpp/app_list/vector_icons/vector_icons.h" #include "base/files/file_path.h" #include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/resource/resource_bundle.h" #include "ui/chromeos/resources/grit/ui_chromeos_resources.h" #include "ui/file_manager/file_manager_resource_util.h" #include "ui/file_manager/grit/file_manager_resources.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" +#include "ui/gfx/paint_vector_icon.h" -#include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader.h" +namespace { + +// Hex color: #796EEE +constexpr SkColor kFiletypeGsiteColor = SkColorSetRGB(121, 110, 238); + +// Hex color: #FF7537 +constexpr SkColor kFiletypePptColor = SkColorSetRGB(255, 117, 55); + +// Hex color: #796EEE +constexpr SkColor kFiletypeSitesColor = SkColorSetRGB(121, 110, 238); + +constexpr int kIconDipSize = 20; + +} // namespace namespace app_list { namespace internal { @@ -129,47 +146,124 @@ } } -int GetResourceIdForIconType(IconType icon) { +IconType GetIconTypeFromString(const std::string& icon_type_string) { + static const base::NoDestructor<std::map<std::string, IconType>> + type_string_to_icon_type({{"archive", IconType::ARCHIVE}, + {"audio", IconType::AUDIO}, + {"chart", IconType::CHART}, + {"excel", IconType::EXCEL}, + {"drive", IconType::DRIVE}, + {"folder", IconType::FOLDER}, + {"gdoc", IconType::GDOC}, + {"gdraw", IconType::GDRAW}, + {"generic", IconType::GENERIC}, + {"gform", IconType::GFORM}, + {"gmap", IconType::GMAP}, + {"gsheet", IconType::GSHEET}, + {"gsite", IconType::GSITE}, + {"gslides", IconType::GSLIDE}, + {"gtable", IconType::GTABLE}, + {"image", IconType::IMAGE}, + {"linux", IconType::LINUX}, + {"pdf", IconType::PDF}, + {"ppt", IconType::PPT}, + {"script", IconType::SCRIPT}, + {"shared", IconType::FOLDER_SHARED}, + {"sites", IconType::SITES}, + {"tini", IconType::TINI}, + {"video", IconType::VIDEO}, + {"word", IconType::WORD}}); + + const auto& icon_it = type_string_to_icon_type->find(icon_type_string); + if (icon_it != type_string_to_icon_type->end()) + return icon_it->second; + return IconType::GENERIC; +} + +gfx::ImageSkia GetVectorIconFromIconType(IconType icon) { // Changes to this map should be reflected in // ui/file_manager/file_manager/common/js/file_type.js. - static const base::NoDestructor<base::flat_map<IconType, int>> - icon_to_2x_resource_id({ - {IconType::ARCHIVE, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_ARCHIVE}, - {IconType::AUDIO, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_AUDIO}, - {IconType::CHART, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_CHART}, - // TODO(crbug.com/1088395): we're missing a generic square drive - // file icon. - {IconType::DRIVE, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GENERIC}, - {IconType::EXCEL, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_EXCEL}, - {IconType::FOLDER, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_FOLDER}, - // TODO(crbug.com/1088395): we're missing a square shared folder icon. - {IconType::FOLDER_SHARED, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_FOLDER}, - {IconType::GDOC, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GDOC}, - {IconType::GDRAW, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GDRAW}, - {IconType::GENERIC, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GENERIC}, - {IconType::GFORM, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GFORM}, - {IconType::GMAP, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GMAP}, - {IconType::GSHEET, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSHEET}, - {IconType::GSITE, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSITE}, - {IconType::GSLIDE, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSLIDES}, - {IconType::GTABLE, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GTABLE}, - {IconType::IMAGE, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_IMAGE}, - {IconType::LINUX, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GENERIC}, - {IconType::PDF, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_PDF}, - {IconType::PPT, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_PPT}, - {IconType::SCRIPT, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_SCRIPT}, - {IconType::SITES, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_SITES}, - {IconType::TINI, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_TINI}, - {IconType::VIDEO, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_VIDEO}, - {IconType::WORD, IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_WORD}, - }); + static const base::NoDestructor<std::map<IconType, gfx::IconDescription>> + icon_type_to_icon_description( + {{IconType::ARCHIVE, + gfx::IconDescription(ash::kFiletypeArchiveIcon, kIconDipSize, + gfx::kGoogleGrey700)}, + {IconType::AUDIO, + gfx::IconDescription(ash::kFiletypeAudioIcon, kIconDipSize, + gfx::kGoogleRed500)}, + {IconType::CHART, + gfx::IconDescription(ash::kFiletypeChartIcon, kIconDipSize, + gfx::kGoogleGreen500)}, + {IconType::DRIVE, + gfx::IconDescription(ash::kFiletypeTeamDriveIcon, kIconDipSize, + gfx::kGoogleGrey700)}, + {IconType::EXCEL, + gfx::IconDescription(ash::kFiletypeExcelIcon, kIconDipSize, + gfx::kGoogleGreen500)}, + {IconType::FOLDER, + gfx::IconDescription(ash::kFiletypeFolderIcon, kIconDipSize, + gfx::kGoogleGrey700)}, + {IconType::FOLDER_SHARED, + gfx::IconDescription(ash::kFiletypeSharedIcon, kIconDipSize, + gfx::kGoogleGrey700)}, + {IconType::GDOC, + gfx::IconDescription(ash::kFiletypeGdocIcon, kIconDipSize, + gfx::kGoogleBlue500)}, + {IconType::GDRAW, + gfx::IconDescription(ash::kFiletypeGdrawIcon, kIconDipSize, + gfx::kGoogleRed500)}, + {IconType::GENERIC, + gfx::IconDescription(ash::kFiletypeGenericIcon, kIconDipSize, + gfx::kGoogleGrey700)}, + {IconType::GFORM, + gfx::IconDescription(ash::kFiletypeGformIcon, kIconDipSize, + gfx::kGoogleGreen500)}, + {IconType::GMAP, + gfx::IconDescription(ash::kFiletypeGmapIcon, kIconDipSize, + gfx::kGoogleRed500)}, + {IconType::GSHEET, + gfx::IconDescription(ash::kFiletypeGsheetIcon, kIconDipSize, + gfx::kGoogleGreen500)}, + {IconType::GSITE, + gfx::IconDescription(ash::kFiletypeGsiteIcon, kIconDipSize, + kFiletypeGsiteColor)}, + {IconType::GSLIDE, + gfx::IconDescription(ash::kFiletypeGslidesIcon, kIconDipSize, + gfx::kGoogleYellow500)}, + {IconType::GTABLE, + gfx::IconDescription(ash::kFiletypeGtableIcon, kIconDipSize, + gfx::kGoogleGreen500)}, + {IconType::IMAGE, + gfx::IconDescription(ash::kFiletypeImageIcon, kIconDipSize, + gfx::kGoogleRed500)}, + {IconType::LINUX, + gfx::IconDescription(ash::kFiletypeLinuxIcon, kIconDipSize, + gfx::kGoogleGrey700)}, + {IconType::PDF, + gfx::IconDescription(ash::kFiletypePdfIcon, kIconDipSize, + gfx::kGoogleRed500)}, + {IconType::PPT, + gfx::IconDescription(ash::kFiletypePptIcon, kIconDipSize, + kFiletypePptColor)}, + {IconType::SCRIPT, + gfx::IconDescription(ash::kFiletypeScriptIcon, kIconDipSize, + gfx::kGoogleBlue500)}, + {IconType::SITES, + gfx::IconDescription(ash::kFiletypeSitesIcon, kIconDipSize, + kFiletypeSitesColor)}, + {IconType::TINI, + gfx::IconDescription(ash::kFiletypeTiniIcon, kIconDipSize, + gfx::kGoogleBlue500)}, + {IconType::VIDEO, + gfx::IconDescription(ash::kFiletypeVideoIcon, kIconDipSize, + gfx::kGoogleRed500)}, + {IconType::WORD, + gfx::IconDescription(ash::kFiletypeWordIcon, kIconDipSize, + gfx::kGoogleBlue500)}}); - const auto& id_it = icon_to_2x_resource_id->find(icon); - DCHECK(id_it != icon_to_2x_resource_id->end()); - return id_it->second; + const auto& id_it = icon_type_to_icon_description->find(icon); + DCHECK(id_it != icon_type_to_icon_description->end()); + return gfx::CreateVectorIcon(id_it->second); } int GetChipResourceIdForIconType(IconType icon) { @@ -210,9 +304,8 @@ } // namespace internal gfx::ImageSkia GetIconForPath(const base::FilePath& filepath) { - return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - internal::GetResourceIdForIconType( - internal::GetIconTypeForPath(filepath))); + return internal::GetVectorIconFromIconType( + internal::GetIconTypeForPath(filepath)); } gfx::ImageSkia GetChipIconForPath(const base::FilePath& filepath) { @@ -221,4 +314,8 @@ internal::GetIconTypeForPath(filepath))); } +gfx::ImageSkia GetIconFromType(const std::string& icon_type) { + return GetVectorIconFromIconType(internal::GetIconTypeFromString(icon_type)); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/common/file_icon_util.h b/chrome/browser/ui/app_list/search/common/file_icon_util.h index 8c4b4fe6..cb846343 100644 --- a/chrome/browser/ui/app_list/search/common/file_icon_util.h +++ b/chrome/browser/ui/app_list/search/common/file_icon_util.h
@@ -40,13 +40,15 @@ WORD, }; +IconType GetIconTypeFromString(const std::string& icon_type_string); IconType GetIconTypeForPath(const base::FilePath& filepath); -int GetResourceIdForIconType(IconType icon); +gfx::ImageSkia GetVectorIconFromIconType(IconType icon); int GetChipResourceIdForIconType(IconType icon); } // namespace internal gfx::ImageSkia GetIconForPath(const base::FilePath& filepath); gfx::ImageSkia GetChipIconForPath(const base::FilePath& filepath); +gfx::ImageSkia GetIconFromType(const std::string& icon_type); } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/common/file_icon_util_unittest.cc b/chrome/browser/ui/app_list/search/common/file_icon_util_unittest.cc index 93685f2..6aad620 100644 --- a/chrome/browser/ui/app_list/search/common/file_icon_util_unittest.cc +++ b/chrome/browser/ui/app_list/search/common/file_icon_util_unittest.cc
@@ -36,26 +36,6 @@ } } -TEST(AppListFileIconUtilTest, GetResourceIdForIconType) { - const std::vector<std::pair<internal::IconType, int>> - icon_type_to_resource_id = { - {internal::IconType::PDF, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_PDF}, - {internal::IconType::PDF, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_PDF}, - {internal::IconType::ARCHIVE, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_ARCHIVE}, - {internal::IconType::GSLIDE, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSLIDES}, - {internal::IconType::GENERIC, - IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GENERIC}}; - - for (const auto& pair : icon_type_to_resource_id) { - EXPECT_EQ(::app_list::internal::GetResourceIdForIconType(pair.first), - pair.second); - } -} - TEST(AppListFileIconUtilTest, GetChipResourceIdForIconType) { const std::vector<std::pair<internal::IconType, int>> icon_type_to_resource_id = {
diff --git a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc index 95a42f6..d62854e 100644 --- a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc +++ b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc
@@ -11,7 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.h" -#include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader_impl.h" +#include "chrome/browser/ui/app_list/search/common/file_icon_util.h" using chromeos::launcher_search_provider::Service; @@ -25,13 +25,14 @@ LauncherSearchResult::LauncherSearchResult( const std::string& item_id, - const GURL& icon_url, + const std::string& icon_type, const int discrete_value_relevance, Profile* profile, const extensions::Extension* extension, std::unique_ptr<chromeos::launcher_search_provider::ErrorReporter> error_reporter) : item_id_(item_id), + icon_type_(icon_type), discrete_value_relevance_(discrete_value_relevance), profile_(profile), extension_(extension) { @@ -39,23 +40,12 @@ DCHECK_LE(discrete_value_relevance, chromeos::launcher_search_provider::kMaxSearchResultScore); - icon_image_loader_ = base::MakeRefCounted<LauncherSearchIconImageLoaderImpl>( - icon_url, profile, extension, - ash::AppListConfig::instance().GetPreferredIconDimension(display_type()), - std::move(error_reporter)); - icon_image_loader_->LoadResources(); - Initialize(); } -LauncherSearchResult::~LauncherSearchResult() { - icon_image_loader_->RemoveObserver(this); -} - std::unique_ptr<LauncherSearchResult> LauncherSearchResult::Duplicate() const { - LauncherSearchResult* duplicated_result = - new LauncherSearchResult(item_id_, discrete_value_relevance_, profile_, - extension_, icon_image_loader_); + LauncherSearchResult* duplicated_result = new LauncherSearchResult( + item_id_, icon_type_, discrete_value_relevance_, profile_, extension_); duplicated_result->set_model_updater(model_updater()); duplicated_result->SetMetadata(CloneMetadata()); return base::WrapUnique(duplicated_result); @@ -70,30 +60,17 @@ return ash::LAUNCHER_SEARCH_PROVIDER_RESULT; } -void LauncherSearchResult::OnIconImageChanged( - LauncherSearchIconImageLoader* image_loader) { - DCHECK_EQ(image_loader, icon_image_loader_.get()); - SetIcon(icon_image_loader_->GetIconImage()); -} - -void LauncherSearchResult::OnBadgeIconImageChanged( - LauncherSearchIconImageLoader* image_loader) { - DCHECK_EQ(image_loader, icon_image_loader_.get()); - // No badging is required. -} - LauncherSearchResult::LauncherSearchResult( const std::string& item_id, + const std::string& icon_type, const int discrete_value_relevance, Profile* profile, - const extensions::Extension* extension, - const scoped_refptr<LauncherSearchIconImageLoader>& icon_image_loader) + const extensions::Extension* extension) : item_id_(item_id), + icon_type_(icon_type), discrete_value_relevance_(discrete_value_relevance), profile_(profile), - extension_(extension), - icon_image_loader_(icon_image_loader) { - DCHECK(icon_image_loader_); + extension_(extension) { Initialize(); } @@ -105,9 +82,7 @@ SetDetails(base::UTF8ToUTF16(extension_->name())); SetResultType(ResultType::kLauncher); - icon_image_loader_->AddObserver(this); - - SetIcon(icon_image_loader_->GetIconImage()); + SetIcon(GetIconFromType(icon_type_)); } std::string LauncherSearchResult::GetSearchResultId() {
diff --git a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h index 792bb9c5..77397e9 100644 --- a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h +++ b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h
@@ -11,44 +11,36 @@ #include "ash/public/cpp/app_list/app_list_metrics.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "chrome/browser/chromeos/launcher_search_provider/error_reporter.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" -#include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader.h" #include "extensions/common/extension.h" -#include "url/gurl.h" namespace app_list { -class LauncherSearchResult : public ChromeSearchResult, - public LauncherSearchIconImageLoader::Observer { +class LauncherSearchResult : public ChromeSearchResult { public: LauncherSearchResult( const std::string& item_id, - const GURL& icon_url, + const std::string& icon_type, const int discrete_value_relevance, Profile* profile, const extensions::Extension* extension, std::unique_ptr<chromeos::launcher_search_provider::ErrorReporter> error_reporter); - ~LauncherSearchResult() override; std::unique_ptr<LauncherSearchResult> Duplicate() const; // ChromeSearchResult overrides: void Open(int event_flags) override; ash::SearchResultType GetSearchResultType() const override; - void OnIconImageChanged(LauncherSearchIconImageLoader* image_loader) override; - void OnBadgeIconImageChanged( - LauncherSearchIconImageLoader* image_loader) override; - private: // Constructor for duplicating a result. - LauncherSearchResult( - const std::string& item_id, - const int discrete_value_relevance, - Profile* profile, - const extensions::Extension* extension, - const scoped_refptr<LauncherSearchIconImageLoader>& icon_image_loader); + LauncherSearchResult(const std::string& item_id, + const std::string& icon_type, + const int discrete_value_relevance, + Profile* profile, + const extensions::Extension* extension); void Initialize(); // Returns search result ID. The search result ID is comprised of the @@ -57,11 +49,11 @@ std::string GetSearchResultId(); const std::string item_id_; + const std::string icon_type_; // Must be between 0 and kMaxSearchResultScore. const int discrete_value_relevance_; Profile* profile_; const extensions::Extension* extension_; - scoped_refptr<LauncherSearchIconImageLoader> icon_image_loader_; DISALLOW_COPY_AND_ASSIGN(LauncherSearchResult); };
diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc index eb2c390..8ff427b 100644 --- a/chrome/browser/ui/app_list/search/mixer.cc +++ b/chrome/browser/ui/app_list/search/mixer.cc
@@ -45,8 +45,8 @@ // Used to group relevant providers together for mixing their results. class Mixer::Group { public: - Group(size_t max_results, double multiplier, double boost) - : max_results_(max_results), multiplier_(multiplier), boost_(boost) {} + Group(size_t max_results, double boost) + : max_results_(max_results), boost_(boost) {} ~Group() {} void AddProvider(SearchProvider* provider) { @@ -64,8 +64,7 @@ // [0.0, 1.0]. Clamp to that range. const double relevance = base::ClampToRange(result->relevance(), 0.0, 1.0); - double boost = boost_; - results_.emplace_back(result.get(), relevance * multiplier_ + boost); + results_.emplace_back(result.get(), relevance + boost_); } } @@ -81,7 +80,6 @@ private: typedef std::vector<SearchProvider*> Providers; const size_t max_results_; - const double multiplier_; const double boost_; Providers providers_; // Not owned. @@ -104,8 +102,8 @@ } } -size_t Mixer::AddGroup(size_t max_results, double multiplier, double boost) { - groups_.push_back(std::make_unique<Group>(max_results, multiplier, boost)); +size_t Mixer::AddGroup(size_t max_results, double boost) { + groups_.push_back(std::make_unique<Group>(max_results, boost)); return groups_.size() - 1; }
diff --git a/chrome/browser/ui/app_list/search/mixer.h b/chrome/browser/ui/app_list/search/mixer.h index 25d91b5..296cee7f 100644 --- a/chrome/browser/ui/app_list/search/mixer.h +++ b/chrome/browser/ui/app_list/search/mixer.h
@@ -34,8 +34,7 @@ // Mixer collects results from providers, sorts them and publishes them to the // SearchResults UI model. The targeted results have 6 slots to hold the -// result. The search controller can specify any number of groups, each with a -// different number of results and priority boost. +// result. class Mixer { public: explicit Mixer(AppListModelUpdater* model_updater); @@ -45,9 +44,8 @@ // chosen from this group (if 0, will allow unlimited results from this // group). If there aren't enough results from all groups, more than // |max_results| may be chosen from this group. Each result in the group will - // have its score multiplied by |multiplier| and added by |boost|. Returns the - // group's group_id. - size_t AddGroup(size_t max_results, double multiplier, double boost); + // have its score increased by |boost|. Returns the group's group_id. + size_t AddGroup(size_t max_results, double boost); // Associates a provider with a mixer group. void AddProviderToGroup(size_t group_id, SearchProvider* provider);
diff --git a/chrome/browser/ui/app_list/search/search_controller.cc b/chrome/browser/ui/app_list/search/search_controller.cc index 4cc10da..eafe9bf 100644 --- a/chrome/browser/ui/app_list/search/search_controller.cc +++ b/chrome/browser/ui/app_list/search/search_controller.cc
@@ -133,10 +133,8 @@ result->InvokeAction(action_index, event_flags); } -size_t SearchController::AddGroup(size_t max_results, - double multiplier, - double boost) { - return mixer_->AddGroup(max_results, multiplier, boost); +size_t SearchController::AddGroup(size_t max_results, double boost) { + return mixer_->AddGroup(max_results, boost); } void SearchController::AddProvider(size_t group_id,
diff --git a/chrome/browser/ui/app_list/search/search_controller.h b/chrome/browser/ui/app_list/search/search_controller.h index 97bea42..cc7770e 100644 --- a/chrome/browser/ui/app_list/search/search_controller.h +++ b/chrome/browser/ui/app_list/search/search_controller.h
@@ -59,7 +59,7 @@ int event_flags); // Adds a new mixer group. See Mixer::AddGroup. - size_t AddGroup(size_t max_results, double multiplier, double boost); + size_t AddGroup(size_t max_results, double boost = 0.0f); // Takes ownership of |provider| and associates it with given mixer group. void AddProvider(size_t group_id, std::unique_ptr<SearchProvider> provider);
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc index 2b4ca05..a0ea622c 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -80,9 +80,7 @@ // TODO(wutao): Need UX spec. constexpr size_t kMaxSettingsShortcutResults = 6; -constexpr float kBoostOfSettingsShortcut = 10.0f; -// Keep in sync with value in search_result_ranker.cc. -constexpr float kBoostOfApps = 8.0f; +constexpr double kAppBoost = 8.0; } // namespace @@ -103,33 +101,34 @@ // a query turns up very few results, the mixer may take more than this // maximum from a particular group. - // For fullscreen app list, Settings shortcuts will show on the very top and - // apps and answer card in the middle and other search results in the bottom. - // So set boost 10.0, 8.0, 5.0, 0.0 respectively. - size_t answer_card_group_id = controller->AddGroup(1, 1.0, 5.0); - size_t apps_group_id = - controller->AddGroup(kMaxAppsGroupResults, 1.0, kBoostOfApps); + // For the fullscreen app list, apps appear above the answer card, which + // appears above other results. Set boosts to |kAppBoost| for apps of all + // kinds, 5.0 for answer card, and otherwise 0.0. + size_t apps_group_id = controller->AddGroup(kMaxAppsGroupResults, kAppBoost); + size_t answer_card_group_id = controller->AddGroup(1, 5.0); + size_t omnibox_group_id = controller->AddGroup( - ash::AppListConfig::instance().max_search_result_list_items(), 1.0, 0.0); + ash::AppListConfig::instance().max_search_result_list_items()); // Add search providers. controller->AddProvider( apps_group_id, std::make_unique<AppSearchProvider>( profile, list_controller, base::DefaultClock::GetInstance(), model_updater)); - controller->AddProvider(omnibox_group_id, std::make_unique<OmniboxProvider>( - profile, list_controller)); if (app_list_features::IsAnswerCardEnabled()) { controller->AddProvider(answer_card_group_id, std::make_unique<AnswerCardSearchProvider>( profile, model_updater, list_controller)); } + controller->AddProvider(omnibox_group_id, std::make_unique<OmniboxProvider>( + profile, list_controller)); + // The Assistant search provider currently only contributes search results // when launcher chip integration is enabled. if (chromeos::assistant::features::IsLauncherChipIntegrationEnabled()) { - size_t assistant_group_id = controller->AddGroup( - kMaxAssistantResults, /*multiplier=*/1.0, kBoostOfApps); + size_t assistant_group_id = + controller->AddGroup(kMaxAssistantResults, kAppBoost); controller->AddProvider(assistant_group_id, std::make_unique<AssistantSearchProvider>()); } @@ -138,7 +137,7 @@ // session and running on Chrome OS. if (!profile->IsGuestSession()) { size_t search_api_group_id = - controller->AddGroup(kMaxLauncherSearchResults, 1.0, 0.0); + controller->AddGroup(kMaxLauncherSearchResults); controller->AddProvider(search_api_group_id, std::make_unique<LauncherSearchProvider>(profile)); } @@ -147,7 +146,7 @@ if (app_list_features::IsAppReinstallZeroStateEnabled() && arc::IsArcAllowedForProfile(profile)) { size_t recommended_app_group_id = - controller->AddGroup(kMaxAppReinstallSearchResults, 1.0, kBoostOfApps); + controller->AddGroup(kMaxAppReinstallSearchResults, kAppBoost); controller->AddProvider(recommended_app_group_id, std::make_unique<ArcAppReinstallSearchProvider>( profile, kMaxAppReinstallSearchResults)); @@ -157,7 +156,7 @@ // Set same boost as apps group since Play store results are placed // with apps. size_t playstore_api_group_id = - controller->AddGroup(kMaxPlayStoreResults, 1.0, kBoostOfApps); + controller->AddGroup(kMaxPlayStoreResults, kAppBoost); controller->AddProvider( playstore_api_group_id, std::make_unique<ArcPlayStoreSearchProvider>(kMaxPlayStoreResults, @@ -166,15 +165,17 @@ if (app_list_features::IsAppDataSearchEnabled()) { size_t app_data_api_group_id = - controller->AddGroup(kMaxAppDataResults, 1.0, kBoostOfApps); + controller->AddGroup(kMaxAppDataResults, kAppBoost); controller->AddProvider(app_data_api_group_id, std::make_unique<ArcAppDataSearchProvider>( kMaxAppDataResults, list_controller)); } + // TODO(crbug.com/1028447): Remove the settings shortcut provider, superseded + // by OsSettingsProvider. if (app_list_features::IsSettingsShortcutSearchEnabled()) { - size_t settings_shortcut_group_id = controller->AddGroup( - kMaxSettingsShortcutResults, 1.0, kBoostOfSettingsShortcut); + size_t settings_shortcut_group_id = + controller->AddGroup(kMaxSettingsShortcutResults); controller->AddProvider( settings_shortcut_group_id, std::make_unique<SettingsShortcutProvider>(profile)); @@ -182,7 +183,7 @@ if (arc::IsArcAllowedForProfile(profile)) { size_t app_shortcut_group_id = - controller->AddGroup(kMaxAppShortcutResults, 1.0, kBoostOfApps); + controller->AddGroup(kMaxAppShortcutResults, kAppBoost); controller->AddProvider( app_shortcut_group_id, std::make_unique<ArcAppShortcutsSearchProvider>( @@ -194,11 +195,11 @@ // scores changed to fit with these providers. if (app_list_features::IsZeroStateMixedTypesRankerEnabled()) { size_t zero_state_files_group_id = - controller->AddGroup(kMaxZeroStateFileResults, 1.0, 0.0); + controller->AddGroup(kMaxZeroStateFileResults); controller->AddProvider(zero_state_files_group_id, std::make_unique<ZeroStateFileProvider>(profile)); size_t drive_quick_access_group_id = - controller->AddGroup(kMaxDriveQuickAccessResults, 1.0, 0.0); + controller->AddGroup(kMaxDriveQuickAccessResults); controller->AddProvider( drive_quick_access_group_id, std::make_unique<DriveQuickAccessProvider>(profile, controller.get())); @@ -206,7 +207,7 @@ if (app_list_features::IsLauncherSettingsSearchEnabled()) { size_t os_settings_search_group_id = - controller->AddGroup(kGenericMaxResults, 1.0, 0.0); + controller->AddGroup(kGenericMaxResults); controller->AddProvider(os_settings_search_group_id, std::make_unique<OsSettingsProvider>(profile)); }
diff --git a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc index 841ef30..e297ac5 100644 --- a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc
@@ -157,10 +157,9 @@ // TODO(warx): when fullscreen app list is default enabled, modify this test // to test answer card/apps group having relevance boost. - size_t apps_group_id = mixer_->AddGroup(kMaxAppsGroupResults, 1.0, 0.0); - size_t omnibox_group_id = mixer_->AddGroup(kMaxOmniboxResults, 1.0, 0.0); - size_t playstore_group_id = - mixer_->AddGroup(kMaxPlaystoreResults, 0.5, 0.0); + size_t apps_group_id = mixer_->AddGroup(kMaxAppsGroupResults, 0.0); + size_t omnibox_group_id = mixer_->AddGroup(kMaxOmniboxResults, 0.0); + size_t playstore_group_id = mixer_->AddGroup(kMaxPlaystoreResults, 0.0); mixer_->AddProviderToGroup(apps_group_id, providers_[0].get()); mixer_->AddProviderToGroup(omnibox_group_id, providers_[1].get()); @@ -210,58 +209,6 @@ DISALLOW_COPY_AND_ASSIGN(MixerTest); }; -TEST_F(MixerTest, Basic) { - CreateMixer(); - - // Note: Some cases in |expected| have vastly more results than others, due to - // the "at least 6" mechanism. If it gets at least 6 results from all - // providers, it stops at 6. If not, it fetches potentially many more results - // from all providers. Not ideal, but currently by design. - struct TestCase { - const size_t app_results; - const size_t omnibox_results; - const size_t playstore_results; - const char* expected; - } kTestCases[] = { - {0, 0, 0, ""}, - {10, 0, 0, "app0,app1,app2,app3,app4,app5,app6,app7,app8,app9"}, - {0, 0, 10, - "playstore0,playstore1,playstore2,playstore3,playstore4,playstore5," - "playstore6,playstore7,playstore8,playstore9"}, - {4, 6, 0, "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3"}, - {4, 6, 2, - "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0," - "playstore1"}, - {10, 10, 10, - "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0," - "playstore1"}, - {0, 10, 0, - "omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6," - "omnibox7,omnibox8,omnibox9"}, - {0, 10, 1, - "omnibox0,omnibox1,omnibox2,omnibox3,playstore0,omnibox4,omnibox5," - "omnibox6,omnibox7,omnibox8,omnibox9"}, - {0, 10, 2, "omnibox0,omnibox1,omnibox2,omnibox3,playstore0,playstore1"}, - {1, 10, 0, - "app0,omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6," - "omnibox7,omnibox8,omnibox9"}, - {2, 10, 0, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3"}, - {2, 10, 1, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,playstore0"}, - {2, 10, 2, - "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,playstore0,playstore1"}, - {2, 0, 2, "app0,app1,playstore0,playstore1"}, - {0, 0, 0, ""}}; - - for (size_t i = 0; i < base::size(kTestCases); ++i) { - app_provider()->set_count(kTestCases[i].app_results); - omnibox_provider()->set_count(kTestCases[i].omnibox_results); - playstore_provider()->set_count(kTestCases[i].playstore_results); - RunQuery(); - - EXPECT_EQ(kTestCases[i].expected, GetResults()) << "Case " << i; - } -} - // Tests that results with display index defined, will be shown in the final // results. TEST_F(MixerTest, ResultsWithDisplayIndex) { @@ -275,8 +222,8 @@ RunQuery(); EXPECT_EQ( - "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,playstore0," - "playstore1", + "app0,omnibox0,playstore0,app1,omnibox1,playstore1,app2,omnibox2,app3," + "omnibox3", GetResults()); // If the last result has display index defined, it will be in the final @@ -285,8 +232,8 @@ RunQuery(); EXPECT_EQ( - "app5,app0,omnibox0,app1,omnibox1,app2,omnibox2,omnibox3,playstore0," - "playstore1", + "app5,app0,omnibox0,playstore0,app1,omnibox1,playstore1,app2,omnibox2," + "omnibox3", GetResults()); }
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc index 2566437..8a43ce8 100644 --- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc +++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "chrome/browser/password_manager/change_password_url_service_factory.h" #include "components/password_manager/core/browser/change_password_url_service.h" +#include "components/password_manager/core/browser/well_known_change_password_state.h" #include "components/password_manager/core/browser/well_known_change_password_util.h" #include "components/password_manager/core/common/password_manager_features.h" #include "content/public/browser/browser_context.h" @@ -116,44 +117,12 @@ void WellKnownChangePasswordNavigationThrottle::FetchNonExistingResource( NavigationHandle* handle) { - auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = - CreateWellKnownNonExistingResourceURL(handle->GetURL()); - resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; - resource_request->load_flags = net::LOAD_DISABLE_CACHE; - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation( - "well_known_path_that_should_not_exist", - R"( - semantics { - sender: "Password Manager" - description: - "Check whether the site supports .well-known 'special' URLs." - "If the website does not support the spec we navigate to the " - "fallback url. See also " -"https://wicg.github.io/change-password-url/response-code-reliability.html#iana" - trigger: - "When the user clicks 'Change password' on " - "chrome://settings/passwords, or when they visit the " - "[ORIGIN]/.well-known/change-password special URL, Chrome makes " - "this additional request. Chrome Password manager shows a button " - "with the link in the password checkup for compromised passwords " - "view (chrome://settings/passwords/check) and in a dialog when the " - "user signs in using compromised credentials." - data: - "The request body is empty. No user data is included." - destination: WEBSITE - } - policy { - cookies_allowed: NO - setting: "This feature cannot be disabled." - policy_exception_justification: "Essential for navigation." - })"); auto url_loader_factory = content::BrowserContext::GetDefaultStoragePartition( handle->GetWebContents()->GetBrowserContext()) ->GetURLLoaderFactoryForBrowserProcess(); - url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), - traffic_annotation); + url_loader_ = + password_manager::CreateResourceRequestToWellKnownNonExistingResourceFor( + handle->GetURL()); // Binding the callback to |this| is safe, because the navigationthrottle // defers if the request is not received yet. Thereby the throttle still exist // when the response arrives.
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc index 414f23e..ae3aac4 100644 --- a/chrome/browser/ui/popup_browsertest.cc +++ b/chrome/browser/ui/popup_browsertest.cc
@@ -165,8 +165,8 @@ "moveTo(screen.availLeft - 50, screen.availTop);", "moveTo(screen.availLeft, screen.availTop + screen.availHeight + 50);", "moveTo(screen.availLeft, screen.availTop - 50);", - "moveTo(screen.availLeft + screen.availWidth + 50, " - "screen.availTop + screen.availHeight + 50);", + ("moveTo(screen.availLeft + screen.availWidth + 50, " + "screen.availTop + screen.availHeight + 50);"), "moveTo(screen.availLeft - 50, screen.availTop - 50);", }; for (auto* const script : kMoveScripts) {
diff --git a/chrome/browser/ui/views/accessibility/caret_browsing_dialog_delegate.cc b/chrome/browser/ui/views/accessibility/caret_browsing_dialog_delegate.cc index d3f7039..b1acbd3 100644 --- a/chrome/browser/ui/views/accessibility/caret_browsing_dialog_delegate.cc +++ b/chrome/browser/ui/views/accessibility/caret_browsing_dialog_delegate.cc
@@ -48,6 +48,7 @@ auto* message_label = AddChildView(std::make_unique<views::Label>( message_text, views::style::CONTEXT_MESSAGE_BOX_BODY_TEXT)); + message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); message_label->SetMultiLine(true); do_not_ask_checkbox_ = AddChildView(std::make_unique<views::Checkbox>(
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom index 7b8cd9c..d984c46b 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -170,6 +170,8 @@ kShowEmojiSuggestions = 1203, kChangeSystemLanguage = 1204, kOfferTranslation = 1205, + kAddInputMethod = 1206, + kSpellCheck = 1207, // Files section. kGoogleDriveConnection = 1300,
diff --git a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc index 3ed74f9c4..49c7f91 100644 --- a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -103,6 +103,18 @@ {.setting = mojom::Setting::kShowInputOptionsInShelf}, {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_INPUT_OPTIONS_SHELF_ALT1, SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_ADD_INPUT_METHOD, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kAddInputMethod}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_SPELL_CHECK, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kSpellCheck}}, }); return *tags; } @@ -264,6 +276,10 @@ {"inputMethodListTitle", IDS_OS_SETTINGS_LANGUAGES_INPUT_METHOD_LIST_TITLE}, {"openOptionsPage", IDS_OS_SETTINGS_LANGUAGES_OPEN_OPTIONS_PAGE_LABEL}, + {"addInputMethodLabel", IDS_OS_SETTINGS_LANGUAGES_ADD_INPUT_METHOD_LABEL}, + {"spellCheckTitle", IDS_OS_SETTINGS_LANGUAGES_SPELL_CHECK_TITLE}, + {"spellCheckDisabledReason", + IDS_OS_SETTINGS_LANGUAGES_SPELL_CHECK_DISABLED_REASON}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); } @@ -389,6 +405,12 @@ IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE, mojom::Subpage::kInput, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, mojom::kInputSubpagePath); + static constexpr mojom::Setting kInputPageSettings[] = { + mojom::Setting::kAddInputMethod, + mojom::Setting::kSpellCheck, + }; + RegisterNestedSettingBulk(mojom::Subpage::kInput, kInputPageSettings, + generator); // Languages and input details. generator->RegisterTopLevelSubpage(
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc index b373cb9..38da9c6 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -22,7 +22,6 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h" #include "chrome/browser/ui/webui/signin/inline_login_handler.h" -#include "chromeos/components/account_manager/account_manager.h" #include "chromeos/components/account_manager/account_manager_factory.h" #include "chromeos/constants/chromeos_features.h" #include "components/signin/public/identity_manager/account_info.h" @@ -38,6 +37,12 @@ constexpr char kCrosAddAccountFlow[] = "crosAddAccount"; constexpr char kCrosAddAccountEduFlow[] = "crosAddAccountEdu"; +std::string AnonymizeAccountEmail(const std::string& email) { + std::string result; + base::Base64Encode(crypto::SHA256HashString(email), &result); + return result + "@example.com"; +} + bool GaiaActionButtonsEnabled() { return base::FeatureList::IsEnabled(chromeos::features::kGaiaActionButtons); } @@ -252,6 +257,10 @@ base::BindRepeating( &InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "getAccounts", + base::BindRepeating(&InlineLoginHandlerChromeOS::GetAccountsInSession, + base::Unretained(this))); } void InlineLoginHandlerChromeOS::SetExtraInitParams( @@ -347,4 +356,36 @@ close_dialog_closure_.Run(); } +void InlineLoginHandlerChromeOS::GetAccountsInSession( + const base::ListValue* args) { + const std::string& callback_id = args->GetList()[0].GetString(); + const Profile* profile = Profile::FromWebUI(web_ui()); + chromeos::AccountManager* account_manager = + g_browser_process->platform_part() + ->GetAccountManagerFactory() + ->GetAccountManager(profile->GetPath().value()); + + account_manager->GetAccounts( + base::BindOnce(&InlineLoginHandlerChromeOS::OnGetAccounts, + weak_factory_.GetWeakPtr(), callback_id)); +} + +void InlineLoginHandlerChromeOS::OnGetAccounts( + const std::string& callback_id, + const std::vector<AccountManager::Account>& accounts) { + base::ListValue account_emails; + for (const auto& account : accounts) { + if (account.key.account_type == + account_manager::AccountType::ACCOUNT_TYPE_ACTIVE_DIRECTORY) { + // Don't send Active Directory account email to Gaia. + account_emails.Append(AnonymizeAccountEmail(account.raw_email)); + } else { + account_emails.Append(account.raw_email); + } + } + + ResolveJavascriptCallback(base::Value(callback_id), + std::move(account_emails)); +} + } // namespace chromeos
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h index 727ffe1..1c8fc0d 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "chrome/browser/ui/webui/signin/inline_login_handler.h" +#include "chromeos/components/account_manager/account_manager.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_auth_fetcher.h" @@ -36,8 +37,12 @@ private: void ShowIncognitoAndCloseDialog(const base::ListValue* args); + void GetAccountsInSession(const base::ListValue* args); + void OnGetAccounts(const std::string& callback_id, + const std::vector<AccountManager::Account>& accounts); base::RepeatingClosure close_dialog_closure_; + base::WeakPtrFactory<InlineLoginHandlerChromeOS> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(InlineLoginHandlerChromeOS); };
diff --git a/chrome/browser/web_applications/components/app_icon_manager.h b/chrome/browser/web_applications/components/app_icon_manager.h index ff65c92..d345409 100644 --- a/chrome/browser/web_applications/components/app_icon_manager.h +++ b/chrome/browser/web_applications/components/app_icon_manager.h
@@ -11,6 +11,7 @@ #include "base/callback_forward.h" #include "base/macros.h" +#include "base/optional.h" #include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/common/web_application_info.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -47,11 +48,21 @@ const AppId& app_id, IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const = 0; - // Returns whether there is a downloaded icon matching |icon_size_in_px| for - // any of the given |purposes|. + struct IconSizeAndPurpose { + SquareSizePx size_px = 0; + IconPurpose purpose = IconPurpose::ANY; + }; + // For each of |purposes|, in the given order, looks for an icon with size at + // least |min_icon_size|. Returns information on the first icon found. + virtual base::Optional<IconSizeAndPurpose> FindIconMatchBigger( + const AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size) const = 0; + // Returns whether there is a downloaded icon of at least |min_size| for any + // of the given |purposes|. virtual bool HasSmallestIcon(const AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx min_icon_size) const = 0; + SquareSizePx min_size) const = 0; using ReadIconsCallback = base::OnceCallback<void(std::map<SquareSizePx, SkBitmap> icon_bitmaps)>; @@ -83,9 +94,9 @@ using ReadIconWithPurposeCallback = base::OnceCallback<void(IconPurpose, const SkBitmap&)>; - // For each of |purposes|, in the given order, finds the smallest icon with - // size at least |icon_size_in_px|. Returns the first icon found, as a bitmap. - // Returns empty SkBitmap in |callback| if IO error. + // For each of |purposes|, in the given order, looks for an icon with size at + // least |min_icon_size|. Returns the first icon found, as a bitmap. Returns + // an empty SkBitmap in |callback| if IO error. virtual void ReadSmallestIcon(const AppId& app_id, const std::vector<IconPurpose>& purposes, SquareSizePx min_icon_size, @@ -99,9 +110,9 @@ using ReadCompressedIconWithPurposeCallback = base::OnceCallback<void(IconPurpose, std::vector<uint8_t> data)>; - // For each of |purposes|, in the given order, finds the smallest icon with - // size at least |icon_size_in_px|. Returns the first icon found, compressed - // as PNG. Returns empty |data| in |callback| if IO error. + // For each of |purposes|, in the given order, looks for an icon with size at + // least |min_icon_size|. Returns the first icon found, compressed as PNG. + // Returns empty |data| in |callback| if IO error. virtual void ReadSmallestCompressedIcon( const AppId& app_id, const std::vector<IconPurpose>& purposes,
diff --git a/chrome/browser/web_applications/components/web_app_install_utils.cc b/chrome/browser/web_applications/components/web_app_install_utils.cc index f9b063d..62dd216 100644 --- a/chrome/browser/web_applications/components/web_app_install_utils.cc +++ b/chrome/browser/web_applications/components/web_app_install_utils.cc
@@ -77,7 +77,7 @@ // Populate |web_app_info|'s shortcuts_menu_item_infos vector using the // blink::Manifest's shortcuts vector. std::vector<WebApplicationShortcutsMenuItemInfo> -UpdateShortcutInfosFromManifest( +UpdateShortcutsMenuItemInfosFromManifest( const std::vector<blink::Manifest::ShortcutItem>& shortcuts) { std::vector<WebApplicationShortcutsMenuItemInfo> web_app_shortcut_infos; int num_shortcut_icons = 0; @@ -216,7 +216,7 @@ base::FeatureList::IsEnabled( features::kDesktopPWAsAppIconShortcutsMenu)) { web_app_info->shortcuts_menu_item_infos = - UpdateShortcutInfosFromManifest(manifest.shortcuts); + UpdateShortcutsMenuItemInfosFromManifest(manifest.shortcuts); } }
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc index 67f82f91..d1fece74 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc
@@ -16,7 +16,6 @@ #include "base/task/thread_pool.h" #include "chrome/browser/extensions/menu_manager.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_registrar.h" #include "chrome/browser/web_applications/extensions/bookmark_app_util.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/image_loader.h" @@ -202,23 +201,34 @@ return true; } +base::Optional<web_app::AppIconManager::IconSizeAndPurpose> +BookmarkAppIconManager::FindIconMatchBigger( + const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size) const { + const Extension* app = GetBookmarkApp(profile_, app_id); + if (!app) + return base::nullopt; + // Legacy bookmark apps handle IconPurpose::ANY icons only. + if (!base::Contains(purposes, IconPurpose::ANY)) + return base::nullopt; + + const ExtensionIconSet& icons = IconsInfo::GetIcons(app); + const std::string& path = icons.Get(min_size, ExtensionIconSet::MATCH_BIGGER); + // Returns 0 if path is empty or not found. + int found_icon_size = icons.GetIconSizeFromPath(path); + + if (found_icon_size == 0) + return base::nullopt; + + return IconSizeAndPurpose{found_icon_size, IconPurpose::ANY}; +} + bool BookmarkAppIconManager::HasSmallestIcon( const web_app::AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx icon_size_in_px) const { - const Extension* app = GetBookmarkApp(profile_, app_id); - if (!app) - return false; - // Legacy bookmark apps handle IconPurpose::ANY icons only. - if (!base::Contains(purposes, IconPurpose::ANY)) - return false; - - const ExtensionIconSet& icons = IconsInfo::GetIcons(app); - - const std::string& path = - icons.Get(icon_size_in_px, ExtensionIconSet::MATCH_BIGGER); - - return !path.empty(); + SquareSizePx min_size) const { + return FindIconMatchBigger(app_id, purposes, min_size).has_value(); } void BookmarkAppIconManager::ReadIcons(
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h index b6bc5ec8..c63741f94 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h
@@ -28,9 +28,13 @@ const web_app::AppId& app_id, IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const override; + base::Optional<IconSizeAndPurpose> FindIconMatchBigger( + const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size) const override; bool HasSmallestIcon(const web_app::AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx icon_size_in_px) const override; + SquareSizePx min_size) const override; void ReadIcons(const web_app::AppId& app_id, IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px,
diff --git a/chrome/browser/web_applications/web_app_database_unittest.cc b/chrome/browser/web_applications/web_app_database_unittest.cc index 9bb4f64e..1409ec9 100644 --- a/chrome/browser/web_applications/web_app_database_unittest.cc +++ b/chrome/browser/web_applications/web_app_database_unittest.cc
@@ -116,9 +116,8 @@ return protocol_handlers; } - static std::vector<WebApplicationShortcutsMenuItemInfo> CreateShortcutInfos( - const std::string& base_url, - uint32_t suffix) { + static std::vector<WebApplicationShortcutsMenuItemInfo> + CreateShortcutsMenuItemInfos(const std::string& base_url, uint32_t suffix) { std::vector<WebApplicationShortcutsMenuItemInfo> shortcuts_menu_item_infos; for (unsigned int i = 0; i < 3; ++i) { std::string suffix_str = @@ -261,7 +260,7 @@ app->SetAdditionalSearchTerms(std::move(additional_search_terms)); app->SetShortcutsMenuItemInfos( - CreateShortcutInfos(base_url, random.next_uint())); + CreateShortcutsMenuItemInfos(base_url, random.next_uint())); app->SetDownloadedShortcutsMenuIconsSizes( CreateDownloadedShortcutsMenuIconsSizes());
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc index 86c98c7..210e825 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.cc +++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -569,12 +569,34 @@ icon_sizes_in_px); } +base::Optional<AppIconManager::IconSizeAndPurpose> +WebAppIconManager::FindIconMatchBigger(const AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size) const { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + const WebApp* web_app = registrar_.GetAppById(app_id); + if (!web_app) + return base::nullopt; + + // Must iterate through purposes in order given. + for (IconPurpose purpose : purposes) { + const std::vector<SquareSizePx>& sizes = + web_app->downloaded_icon_sizes(purpose); + DCHECK(base::STLIsSorted(sizes)); + for (SquareSizePx size : sizes) { + if (size >= min_size) + return IconSizeAndPurpose{size, purpose}; + } + } + + return base::nullopt; +} + bool WebAppIconManager::HasSmallestIcon( const AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx min_size_in_px) const { - return FindDownloadedIconMatchBigger(app_id, purposes, min_size_in_px) - .has_value(); + SquareSizePx min_size) const { + return FindIconMatchBigger(app_id, purposes, min_size).has_value(); } void WebAppIconManager::ReadIcons(const AppId& app_id, @@ -638,8 +660,8 @@ ReadIconWithPurposeCallback callback) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::Optional<WebAppIconManager::SizeAndPurpose> best_icon = - FindDownloadedIconMatchBigger(app_id, purposes, min_size_in_px); + base::Optional<IconSizeAndPurpose> best_icon = + FindIconMatchBigger(app_id, purposes, min_size_in_px); DCHECK(best_icon.has_value()); IconId icon_id(app_id, best_icon->purpose, best_icon->size_px); ReadIconCallback wrapped = base::BindOnce( @@ -659,8 +681,8 @@ ReadCompressedIconWithPurposeCallback callback) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::Optional<WebAppIconManager::SizeAndPurpose> best_icon = - FindDownloadedIconMatchBigger(app_id, purposes, min_size_in_px); + base::Optional<IconSizeAndPurpose> best_icon = + FindIconMatchBigger(app_id, purposes, min_size_in_px); DCHECK(best_icon.has_value()); IconId icon_id(app_id, best_icon->purpose, best_icon->size_px); ReadCompressedIconCallback wrapped = @@ -693,11 +715,10 @@ IconPurpose purpose, SquareSizePx desired_icon_size, ReadIconsCallback callback) const { - base::Optional<SizeAndPurpose> best_icon = - FindDownloadedIconMatchBigger(app_id, {purpose}, desired_icon_size); + base::Optional<IconSizeAndPurpose> best_icon = + FindIconMatchBigger(app_id, {purpose}, desired_icon_size); if (!best_icon) { - best_icon = - FindDownloadedIconMatchSmaller(app_id, {purpose}, desired_icon_size); + best_icon = FindIconMatchSmaller(app_id, {purpose}, desired_icon_size); } if (!best_icon) { @@ -719,35 +740,11 @@ favicon_read_callback_ = std::move(callback); } -base::Optional<WebAppIconManager::SizeAndPurpose> -WebAppIconManager::FindDownloadedIconMatchBigger( +base::Optional<AppIconManager::IconSizeAndPurpose> +WebAppIconManager::FindIconMatchSmaller( const AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx desired_size) const { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - const WebApp* web_app = registrar_.GetAppById(app_id); - if (!web_app) - return base::nullopt; - - // Must iterate through purposes in order given. - for (IconPurpose purpose : purposes) { - const std::vector<SquareSizePx>& sizes = - web_app->downloaded_icon_sizes(purpose); - DCHECK(base::STLIsSorted(sizes)); - for (SquareSizePx size : sizes) { - if (size >= desired_size) - return WebAppIconManager::SizeAndPurpose{size, purpose}; - } - } - - return base::nullopt; -} - -base::Optional<WebAppIconManager::SizeAndPurpose> -WebAppIconManager::FindDownloadedIconMatchSmaller( - const AppId& app_id, - const std::vector<IconPurpose>& purposes, - SquareSizePx desired_size) const { + SquareSizePx max_size) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const WebApp* web_app = registrar_.GetAppById(app_id); if (!web_app) @@ -759,8 +756,8 @@ web_app->downloaded_icon_sizes(purpose); DCHECK(base::STLIsSorted(sizes)); for (SquareSizePx size : base::Reversed(sizes)) { - if (size <= desired_size) - return WebAppIconManager::SizeAndPurpose{size, purpose}; + if (size <= max_size) + return IconSizeAndPurpose{size, purpose}; } }
diff --git a/chrome/browser/web_applications/web_app_icon_manager.h b/chrome/browser/web_applications/web_app_icon_manager.h index d41824c..e9b1854 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.h +++ b/chrome/browser/web_applications/web_app_icon_manager.h
@@ -57,9 +57,13 @@ const AppId& app_id, IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const override; + base::Optional<IconSizeAndPurpose> FindIconMatchBigger( + const AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size) const override; bool HasSmallestIcon(const AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx min_size_in_px) const override; + SquareSizePx min_size) const override; void ReadIcons(const AppId& app_id, IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes, @@ -96,18 +100,10 @@ void SetFaviconReadCallbackForTesting(FaviconReadCallback callback); private: - struct SizeAndPurpose { - SquareSizePx size_px = 0; - IconPurpose purpose = IconPurpose::ANY; - }; - base::Optional<WebAppIconManager::SizeAndPurpose> - FindDownloadedIconMatchBigger(const AppId& app_id, - const std::vector<IconPurpose>& purposes, - SquareSizePx desired_size) const; - base::Optional<SizeAndPurpose> FindDownloadedIconMatchSmaller( + base::Optional<IconSizeAndPurpose> FindIconMatchSmaller( const AppId& app_id, const std::vector<IconPurpose>& purposes, - SquareSizePx desired_size) const; + SquareSizePx max_size) const; void ReadFavicon(const AppId& app_id); void OnReadFavicon(const AppId& app_id, const SkBitmap&);
diff --git a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc index b483598..c429aec 100644 --- a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc
@@ -36,6 +36,12 @@ namespace web_app { +namespace { + +using IconSizeAndPurpose = AppIconManager::IconSizeAndPurpose; + +} // namespace + class WebAppIconManagerTest : public WebAppTest { void SetUp() override { WebAppTest::SetUp(); @@ -131,6 +137,41 @@ return downloaded_shortcuts_menu_icons_sizes; } + struct PurposeAndBitmap { + IconPurpose purpose; + SkBitmap bitmap; + }; + PurposeAndBitmap ReadSmallestIcon(const AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_icon_size) { + PurposeAndBitmap result; + base::RunLoop run_loop; + icon_manager().ReadSmallestIcon( + app_id, purposes, min_icon_size, + base::BindLambdaForTesting( + [&](IconPurpose purpose, const SkBitmap& bitmap) { + result.purpose = purpose; + result.bitmap = bitmap; + run_loop.Quit(); + })); + run_loop.Run(); + return result; + } + + SkBitmap ReadSmallestIconAny(const AppId& app_id, + SquareSizePx min_icon_size) { + SkBitmap result; + base::RunLoop run_loop; + icon_manager().ReadSmallestIconAny( + app_id, min_icon_size, + base::BindLambdaForTesting([&](const SkBitmap& bitmap) { + result = bitmap; + run_loop.Quit(); + })); + run_loop.Run(); + return result; + } + struct PurposeAndData { IconPurpose purpose; std::vector<uint8_t> data; @@ -658,6 +699,11 @@ } } +// Simple struct doesn't have an operator==. +bool operator==(const IconSizeAndPurpose& a, const IconSizeAndPurpose& b) { + return a.size_px == b.size_px && a.purpose == b.purpose; +} + TEST_F(WebAppIconManagerTest, FindSmallest) { auto web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); @@ -665,49 +711,79 @@ const std::vector<int> sizes_px{10, 60, 50, 20, 30}; const std::vector<SkColor> colors{SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA}; - WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); + // Pretend we only have one size of maskable icon. + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, {20}); controller().RegisterApp(std::move(web_app)); EXPECT_FALSE(icon_manager().HasSmallestIcon(app_id, {IconPurpose::ANY}, 70)); + EXPECT_EQ(base::nullopt, + icon_manager().FindIconMatchBigger(app_id, {IconPurpose::ANY}, 70)); + EXPECT_FALSE(icon_manager().HasSmallestIcon( app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 70)); + EXPECT_EQ(base::nullopt, + icon_manager().FindIconMatchBigger( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 70)); + EXPECT_FALSE( icon_manager().HasSmallestIcon(app_id, {IconPurpose::MASKABLE}, 40)); + EXPECT_EQ(base::nullopt, icon_manager().FindIconMatchBigger( + app_id, {IconPurpose::MASKABLE}, 40)); EXPECT_TRUE(icon_manager().HasSmallestIcon( app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, 40)); + EXPECT_EQ((IconSizeAndPurpose{50, IconPurpose::ANY}), + icon_manager() + .FindIconMatchBigger( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, 40) + .value()); + EXPECT_TRUE(icon_manager().HasSmallestIcon( app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 20)); + EXPECT_EQ((IconSizeAndPurpose{20, IconPurpose::ANY}), + icon_manager() + .FindIconMatchBigger( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 20) + .value()); + + EXPECT_TRUE(icon_manager().HasSmallestIcon( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, 10)); + EXPECT_EQ((IconSizeAndPurpose{20, IconPurpose::MASKABLE}), + icon_manager() + .FindIconMatchBigger( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, 10) + .value()); { - base::RunLoop run_loop; - EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, {IconPurpose::ANY}, 40)); - icon_manager().ReadSmallestIconAny( - app_id, 40, base::BindLambdaForTesting([&](const SkBitmap& bitmap) { - EXPECT_FALSE(bitmap.empty()); - EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); - run_loop.Quit(); - })); - - run_loop.Run(); + SkBitmap bitmap = ReadSmallestIconAny(app_id, 40); + EXPECT_FALSE(bitmap.empty()); + EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); } - { - base::RunLoop run_loop; - EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, {IconPurpose::ANY}, 20)); - icon_manager().ReadSmallestIconAny( - app_id, 20, base::BindLambdaForTesting([&](const SkBitmap& bitmap) { - EXPECT_FALSE(bitmap.empty()); - EXPECT_EQ(SK_ColorBLUE, bitmap.getColor(0, 0)); - run_loop.Quit(); - })); - - run_loop.Run(); + SkBitmap bitmap = ReadSmallestIconAny(app_id, 20); + EXPECT_FALSE(bitmap.empty()); + EXPECT_EQ(SK_ColorBLUE, bitmap.getColor(0, 0)); + } + { + PurposeAndBitmap result = + ReadSmallestIcon(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 20); + EXPECT_FALSE(result.bitmap.empty()); + EXPECT_EQ(IconPurpose::ANY, result.purpose); + EXPECT_EQ(SK_ColorBLUE, result.bitmap.getColor(0, 0)); + } + { + PurposeAndBitmap result = + ReadSmallestIcon(app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, 20); + EXPECT_FALSE(result.bitmap.empty()); + EXPECT_EQ(IconPurpose::MASKABLE, result.purpose); + EXPECT_EQ(SK_ColorBLUE, result.bitmap.getColor(0, 0)); } }
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.cc b/chrome/browser/web_applications/web_app_shortcut_manager.cc index 8004ff7..17879460 100644 --- a/chrome/browser/web_applications/web_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/web_app_shortcut_manager.cc
@@ -54,6 +54,9 @@ app->downloaded_icon_sizes(IconPurpose::ANY), GetDesiredIconSizesForShortcut()); + // Optimistic check to help debug low-frequency crash. + // TODO(crbug.com/1113276): Make this a DCHECK before hitting stable. + CHECK(icon_manager_); if (!icon_sizes_in_px.empty()) { icon_manager_->ReadIcons(app_id, IconPurpose::ANY, icon_sizes_in_px, base::BindOnce(&WebAppShortcutManager::OnIconsRead,
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index af0f2a7..92243517 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1597514130-fe0a8d516b962baead2578c487739528f5924993.profdata +chrome-mac-master-1597574780-11032f77f0853e1d71f33728c0242d630bf5af1f.profdata
diff --git a/chrome/common/extensions/api/launcher_search_provider.idl b/chrome/common/extensions/api/launcher_search_provider.idl index 5f59f72..2521a83 100644 --- a/chrome/common/extensions/api/launcher_search_provider.idl +++ b/chrome/common/extensions/api/launcher_search_provider.idl
@@ -11,8 +11,8 @@ dictionary SearchResult { DOMString itemId; DOMString title; - // If iconUrl is not provided, app/extension icon is used automatically. - DOMString? iconUrl; + // If iconType is not provided, a generic icon is used automatically. + DOMString? iconType; // Relevance ranges from 0 to 4. 0 is the lowest relevance, 4 is highest. long relevance; };
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index acd11f1..cbf9a60c3 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -38,6 +38,7 @@ ] if (is_chromeos) { deps += [ + "//chromeos/components/remote_apps/mojom:mojom_js", "//chromeos/services/ime/public/mojom:mojom_js", "//chromeos/services/tts/public/mojom:mojom_js", ]
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc index 8515cff..4f5a719 100644 --- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc +++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -178,6 +178,14 @@ source_map->RegisterSource("chromeos.tts.mojom.tts_stream.mojom", IDR_TTS_STREAM_MOJOM_JS); source_map->RegisterSource("chromeos.tts.stream", IDR_TTS_STREAM_BINDINGS_JS); + + // Imprivata API. + source_map->RegisterSource("chromeos.remote_apps.mojom-lite", + IDR_REMOTE_APPS_MOJOM_LITE_JS); + source_map->RegisterSource("chromeos.remote_apps", + IDR_REMOTE_APPS_BINDINGS_JS); + source_map->RegisterSource("url/mojom/url.mojom-lite", + IDR_MOJO_URL_MOJOM_LITE_JS); #endif // defined(OS_CHROMEOS) source_map->RegisterSource(
diff --git a/chrome/renderer/resources/extensions/remote_apps/OWNERS b/chrome/renderer/resources/extensions/remote_apps/OWNERS new file mode 100644 index 0000000..fc0c3ac --- /dev/null +++ b/chrome/renderer/resources/extensions/remote_apps/OWNERS
@@ -0,0 +1,2 @@ +hendrich@chromium.org +jityao@google.com
diff --git a/chrome/renderer/resources/extensions/remote_apps/remote_apps_bindings.js b/chrome/renderer/resources/extensions/remote_apps/remote_apps_bindings.js new file mode 100644 index 0000000..4c5ee06 --- /dev/null +++ b/chrome/renderer/resources/extensions/remote_apps/remote_apps_bindings.js
@@ -0,0 +1,61 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) { + loadScript('mojo_bindings_lite'); +} + +loadScript('url/mojom/url.mojom-lite'); +loadScript('chromeos.remote_apps.mojom-lite'); + +class RemoteAppsAdapter { + constructor() { + const factory = chromeos.remoteApps.mojom.RemoteAppsFactory.getRemote(); + + this.remoteApps_ = new chromeos.remoteApps.mojom.RemoteAppsRemote(); + this.callbackRouter_ = + new chromeos.remoteApps.mojom.RemoteAppLaunchObserverCallbackRouter(); + factory.create( + this.remoteApps_.$.bindNewPipeAndPassReceiver(), + this.callbackRouter_.$.bindNewPipeAndPassRemote()); + } + + /** + * Adds a folder to the launcher. Note that empty folders are not shown in + * the launcher. + * @param {string} name name of the added folder + * @return {!Promise<!{folderId: string, error: string}>} ID for the added + * folder + */ + addFolder(name) { + return this.remoteApps_.addFolder(name); + } + + /** + * Adds an app to the launcher. + * @param {string} name name of the added app + * @param {string} folderId Id of the parent folder. An empty string + * indicates the app does not have a parent folder. + * @param {string} iconUrl URL to an image representing the app's icon + * @return {!Promise<!{appId: string, error: string}>} ID for the + * added app. + */ + addApp(name, folderId, iconUrl) { + return this.remoteApps_.addApp(name, folderId, {url: iconUrl}); + } + + /** + * Adds a callback for remote app launch events. + * @param {function(string)} callback called when a remote app is launched + * with the app ID as argument. + * @return {!Promise<void>} + */ + addRemoteAppLaunchObserver(callback) { + return this.callbackRouter_.onRemoteAppLaunched.addListener(callback); + } +} + +exports.$set('returnValue', new RemoteAppsAdapter());
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd index cadb90c..a0574ab 100644 --- a/chrome/renderer/resources/renderer_resources.grd +++ b/chrome/renderer/resources/renderer_resources.grd
@@ -63,10 +63,15 @@ <!-- ChromeOS IME Mojo service and bindings. --> <include name="IDR_IME_SERVICE_BINDINGS_JS" file="extensions\chromeos_ime_service_bindings.js" type="BINDATA" /> - <include name="IDR_IME_SERVICE_MOJOM_JS" file="${mojom_root}\chromeos/services/ime/public/mojom/input_engine.mojom.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_IME_SERVICE_MOJOM_JS" file="${mojom_root}\chromeos\services\ime\public\mojom\input_engine.mojom.js" use_base_dir="false" type="BINDATA" /> + + <!-- Remote Apps bindings. --> + <include name="IDR_REMOTE_APPS_BINDINGS_JS" file="extensions\remote_apps\remote_apps_bindings.js" type="BINDATA" /> + <include name="IDR_REMOTE_APPS_MOJOM_LITE_JS" file="${mojom_root}\chromeos\components\remote_apps\mojom\remote_apps.mojom-lite.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_MOJO_URL_MOJOM_LITE_JS" file="${mojom_root}\url\mojom\url.mojom-lite.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_TTS_STREAM_BINDINGS_JS" file="extensions\chromeos_tts_stream_bindings.js" type="BINDATA" /> - <include name="IDR_TTS_STREAM_MOJOM_JS" file="${mojom_root}\chromeos/services/tts/public/mojom/tts_service.mojom.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_TTS_STREAM_MOJOM_JS" file="${mojom_root}\chromeos\services\tts\public\mojom\tts_service.mojom.js" use_base_dir="false" type="BINDATA" /> </if> <!-- Media Router Mojo service and bindings. --> <include name="IDR_MEDIA_CONTROLLER_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojom\media_controller.mojom.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4eba90e..dbb58d7 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -970,7 +970,7 @@ "../browser/media/test_license_server_config.h", "../browser/media/unified_autoplay_browsertest.cc", "../browser/media/webrtc/media_stream_devices_controller_browsertest.cc", - "../browser/media/webrtc/media_stream_infobar_browsertest.cc", + "../browser/media/webrtc/media_stream_permission_browsertest.cc", "../browser/media/webrtc/test_stats_dictionary.cc", "../browser/media/webrtc/test_stats_dictionary.h", "../browser/media/webrtc/test_stats_dictionary_unittest.cc", @@ -2490,6 +2490,7 @@ "../browser/chromeos/printing/test_printer_configurer.cc", "../browser/chromeos/printing/test_printer_configurer.h", "../browser/chromeos/profiles/profile_helper_browsertest.cc", + "../browser/chromeos/remote_apps/remote_apps_impl_browsertest.cc", "../browser/chromeos/remote_apps/remote_apps_manager_browsertest.cc", "../browser/chromeos/shutdown_policy_browsertest.cc", "../browser/chromeos/startup_settings_cache_browsertest.cc",
diff --git a/chrome/test/data/extensions/remote_apps/extension/manifest.json b/chrome/test/data/extensions/remote_apps/extension/manifest.json new file mode 100644 index 0000000..e73a462 --- /dev/null +++ b/chrome/test/data/extensions/remote_apps/extension/manifest.json
@@ -0,0 +1,9 @@ +{ + "name": "Remote Apps", + "version": "0.1", + "manifest_version": 2, + "description": "Browser test for Remote Apps Mojo Private API", + "background": { + "scripts": ["test.js"] + } +}
diff --git a/chrome/test/data/extensions/remote_apps/extension/test.js b/chrome/test/data/extensions/remote_apps/extension/test.js new file mode 100644 index 0000000..ef350b7 --- /dev/null +++ b/chrome/test/data/extensions/remote_apps/extension/test.js
@@ -0,0 +1,66 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let api; + +const testCases = [ + async function AddApp() { + const result1 = await api.addApp('App 1', '', ''); + chrome.test.assertFalse(!!result1.error); + chrome.test.assertEq('Id 1', result1.appId); + + const result2 = await api.addApp('App 2', 'missing', ''); + chrome.test.assertEq('Folder ID provided does not exist', result2.error); + + chrome.test.succeed(); + }, + async function AddFolderAndApps() { + const result1 = await api.addFolder('Folder 1'); + const folderId = result1.folderId; + chrome.test.assertFalse(!!result1.error); + chrome.test.assertEq('Id 1', folderId); + + const result2 = await api.addApp('App 1', folderId, ''); + chrome.test.assertFalse(!!result2.error); + chrome.test.assertEq('Id 2', result2.appId); + + const result3 = await api.addApp('App 2', folderId, ''); + chrome.test.assertFalse(!!result3.error); + chrome.test.assertEq('Id 3', result3.appId); + + chrome.test.succeed(); + }, + async function OnRemoteAppLaunched() { + let actualId = ''; + await new Promise(async (resolve) => { + await api.addRemoteAppLaunchObserver(id => { + actualId = id; + resolve(); + }); + await api.addApp('App 1', '', ''); + chrome.test.sendMessage('Remote app added'); + }); + + chrome.test.assertEq('Id 1', actualId); + chrome.test.succeed(); + }, +]; + +chrome.test.getConfig(async (config) => { + try { + api = await chrome.mojoPrivate.requireAsync('chromeos.remote_apps'); + } catch (e) { + chrome.test.notifyFail('Could not get mojoPrivate bindings: ' + e.message); + return; + } + + const testName = config.customArg; + const testCase = testCases.find((f) => f.name === testName); + if (!testCase) { + chrome.test.notifyFail('Test case \'' + testName + '\' not found'); + return; + } + + chrome.test.runTests([testCase]); +});
diff --git a/chrome/test/data/extensions/remote_apps/remote_apps.pem b/chrome/test/data/extensions/remote_apps/remote_apps.pem new file mode 100644 index 0000000..2285fbc7 --- /dev/null +++ b/chrome/test/data/extensions/remote_apps/remote_apps.pem
@@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDrhtzVny69zwz3 +F0n517RrPaeuiXF9f7TXf+K+xrL3p0NDTrP6pj5A9tV2rbhCrMqEd6ub5WRhl7Y8 +JlnWcAs6UikeJaQU7uSSVXxw2/ZJdEgTrcjL6DvfyyGpWf33TQn8yHVHpqiRxXr5 +NV2ciA0Vv8abNgbi5EUQrM+yKXi3FrCGBewXNoffA8tUV3jYEdHEJirE3y1s65r9 +xD9RMfPlGt6lV63EOGy+Ti88YldKPB6HiRHD9GmIH3BPkan9YGlmb4RBWLfoUNZS +jrrUAlQzkUaWLyqTYHZqtpNHaKClCAX6DNAodgchzd+YNWW/Ysev6et6IkAO5dbl +v4gxEkAPAgMBAAECggEAKiKv6kW2mn1qr9/KO7jDzbWzhG2RUKbipvT5jzDD/rs9 +NNLlLu/DzmJ6UOeGQeNgva8dE+BHg5AdKYig5NSZpZ7iPUL1pksQuD8z6orndj+n +z2F1PUl4QLK5/G6dmTr+kOsZ1C40FRQTynaqHyFV2fC7qrPRKpE06+VGqPRzZKmC +HjeLUTevBgOYmVB/bRn1uc7yZN2YpuDoJ9BtU1HopyqVFVxTvJorsCAYD+94hS6I ++lKzW+X1U0JDGjTRaRZqHaOc7kgKJswD1B6xVKv58ZO4mRhmKbKtaKRF3IVLz9vb +RyoClY2Qrn57hOMSgKyh+jxN8jpiW76bTHOi2GofVQKBgQD6PhSHzqpDAVVg+ivR +JykRjfVtG5mOAYPB4PAZX+8KuKXxtFuh9xN98zJiB/EaqJNP0Kcnd09enkqHN4Cm +D8WEBzjokIxJQf55+DzeVtC1DkCAzuWdfXeJDjOQ/e447L9xeo0ms9ivjsWpl2T+ +p6jfx7nk1N1cPZUGyIso0m1oVQKBgQDw8huFWKEM4K5TXMF9Z/keoS/q6uVoeSkB +335S/iZMEmnv8eG46y4ID30Mg4E4gye9U4Jc6wauorQYm1lOpfVlYxsVh7TaMFLk +mQ+jUWttIeURye3qn3t9YCSsIdKydNUrkkJd4nCCr31rPSQhRWa5PQUVjtOqI4B/ +siafBDo60wKBgQCpC6by1zlNamkyyc0vzTSBF1TkD/D7bSqEnl+TxKrGo1X2odAE +6dPREajHcHX/fEGHeXxxvLdxQ501GtldVOoo9ngLIxqhomM2Iet8h0kWBjqsyRdz +/H3zqBRNrjxvV/87uX4A1x1Z+yisGAmxvbDm+xUo8GNZHIC/xFm9iek+wQKBgDQj +0DzM7x0ASfkUK3Ld2xT7wIjPiBFRlsQm/wkqolL38SDRcQ05J17rKx5YHtCB4Umh +FqbQ3UNRRjPE+lCArVfhWG0STtqgdm+th6rJ5btaCF4PGoMZO/nnokf1kci4a6Dg +J6h1Ze+B1lwsgPMKN66CO+VsYPWCdT4s6RqkKY2tAoGBAOiyRyW3RfpdGO36mv7p +r7qZ++tH+ZnTZ6CAp/+MTcx0XpCUnmSOGt0fU83TI9ujBeVJSoafg2MB/Th5UX11 +RkN67zkTqeyej5scAzoTB+FD4+/zcrCfLze30dLCvtGp/IdwyLv9X+Yd4uxPIugm +CGqT0AcAo852wwzRPS/7eB6J +-----END PRIVATE KEY-----
diff --git a/chrome/test/data/webrtc/video_detector.js b/chrome/test/data/webrtc/video_detector.js index 4c96610..cab940ad 100644 --- a/chrome/test/data/webrtc/video_detector.js +++ b/chrome/test/data/webrtc/video_detector.js
@@ -79,6 +79,25 @@ } /** + * Checks if the video has stopped + * + * @return {string} video-stopped or video-not-stopped. + */ +function isVideoStopped() { + // Video is considered to be stopped if the last 5 fingerprints are the same. + // We only check for rough equality though to account for rounding errors. + if (gFingerprints.length < 5) + returnToTest('video-not-stopped'); + + if (allElementsRoughlyEqualTo_(gFingerprints.slice(-5), + gFingerprints[gFingerprints.length - 1])) { + returnToTest('video-stopped'); + } + + returnToTest('video-not-stopped'); +} + +/** * Queries for the stream size (not necessarily the size at which the video tag * is rendered). *
diff --git a/chrome/test/data/webui/chromeos/edu_login/edu_login_signin_test.js b/chrome/test/data/webui/chromeos/edu_login/edu_login_signin_test.js index 03e56aa..8a6911d 100644 --- a/chrome/test/data/webui/chromeos/edu_login/edu_login_signin_test.js +++ b/chrome/test/data/webui/chromeos/edu_login/edu_login_signin_test.js
@@ -11,7 +11,7 @@ import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {TestEduAccountLoginBrowserProxy} from './edu_login_test_util.js'; +import {getFakeAccountsList, TestEduAccountLoginBrowserProxy} from './edu_login_test_util.js'; window.edu_login_signin_tests = {}; edu_login_signin_tests.suiteName = 'EduLoginSigninTest'; @@ -45,6 +45,10 @@ this.loadCalls = 0; /** @type {Number} */ this.resetStatesCalls = 0; + /** @type {number} */ + this.getAccountsResponseCalls = 0; + /** @type {Array<string>} */ + this.getAccountsResponseResult = null; } /** @@ -60,6 +64,14 @@ resetStates() { this.resetStatesCalls++; } + + /** + * @param {Array<string>} accounts list of emails. + */ + getAccountsResponse(accounts) { + this.getAccountsResponseCalls++; + this.getAccountsResponseResult = accounts; + } } setup(function() { @@ -119,6 +131,15 @@ assertEquals(fakeCredentials, result[0]); assertDeepEquals(fakeLoginParams, result[1]); }); + + testAuthenticator.dispatchEvent(new Event('getAccounts')); + assertEquals(1, testBrowserProxy.getCallCount('getAccounts')); + testBrowserProxy.whenCalled('getAccounts').then(function() { + assertEquals(1, testAuthenticator.getAccountsResponseCalls); + assertDeepEquals( + getFakeAccountsList(), + testAuthenticator.getAccountsResponseResult); + }); }); test(assert(edu_login_signin_tests.TestNames.GoBackInWebview), function() {
diff --git a/chrome/test/data/webui/chromeos/edu_login/edu_login_test_util.js b/chrome/test/data/webui/chromeos/edu_login/edu_login_test_util.js index 0e14524..cb43dd4d 100644 --- a/chrome/test/data/webui/chromeos/edu_login/edu_login_test_util.js +++ b/chrome/test/data/webui/chromeos/edu_login/edu_login_test_util.js
@@ -29,6 +29,11 @@ ]; } +/** @return {!Array<string>} */ +export function getFakeAccountsList() { + return ['test@gmail.com', 'test2@gmail.com', 'test3@gmail.com']; +} + /** @implements {EduAccountLoginBrowserProxy} */ export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy { constructor() { @@ -40,6 +45,7 @@ 'authExtensionReady', 'switchToFullTab', 'completeLogin', + 'getAccounts', 'dialogClose', ]); @@ -107,6 +113,12 @@ } /** @override */ + getAccounts() { + this.methodCalled('getAccounts'); + return Promise.resolve(getFakeAccountsList()); + } + + /** @override */ dialogClose() { this.methodCalled('dialogClose'); }
diff --git a/chrome/test/data/webui/inline_login/inline_login_test.js b/chrome/test/data/webui/inline_login/inline_login_test.js index 63fc5177..11aa9b50 100644 --- a/chrome/test/data/webui/inline_login/inline_login_test.js +++ b/chrome/test/data/webui/inline_login/inline_login_test.js
@@ -10,8 +10,9 @@ import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; -import {TestAuthenticator, TestInlineLoginBrowserProxy} from './inline_login_test_util.js'; +import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; + +import {getFakeAccountsList, TestAuthenticator, TestInlineLoginBrowserProxy} from './inline_login_test_util.js'; window.inline_login_test = {}; inline_login_test.suiteName = 'InlineLoginTest'; @@ -97,6 +98,14 @@ testAuthenticator.dispatchEvent(new Event('showIncognito')); assertEquals(1, testBrowserProxy.getCallCount('showIncognito')); + + testAuthenticator.dispatchEvent(new Event('getAccounts')); + assertEquals(1, testBrowserProxy.getCallCount('getAccounts')); + testBrowserProxy.whenCalled('getAccounts').then(function() { + assertEquals(1, testAuthenticator.getAccountsResponseCalls); + assertDeepEquals( + getFakeAccountsList(), testAuthenticator.getAccountsResponseResult); + }); }); test(assert(inline_login_test.TestNames.BackButton), () => {
diff --git a/chrome/test/data/webui/inline_login/inline_login_test_util.js b/chrome/test/data/webui/inline_login/inline_login_test_util.js index caaa3ab..3691ea1 100644 --- a/chrome/test/data/webui/inline_login/inline_login_test_util.js +++ b/chrome/test/data/webui/inline_login/inline_login_test_util.js
@@ -8,6 +8,11 @@ import {TestBrowserProxy} from '../test_browser_proxy.m.js'; +/** @return {!Array<string>} */ +export function getFakeAccountsList() { + return ['test@gmail.com', 'test2@gmail.com', 'test3@gmail.com']; +} + export class TestAuthenticator extends EventTarget { constructor() { super(); @@ -17,6 +22,10 @@ this.data = null; /** @type {number} */ this.loadCalls = 0; + /** @type {number} */ + this.getAccountsResponseCalls = 0; + /** @type {Array<string>} */ + this.getAccountsResponseResult = null; } /** @@ -28,6 +37,14 @@ this.authMode = authMode; this.data = data; } + + /** + * @param {Array<string>} accounts list of emails. + */ + getAccountsResponse(accounts) { + this.getAccountsResponseCalls++; + this.getAccountsResponseResult = accounts; + } } /** @implements {InlineLoginBrowserProxy} */ @@ -41,6 +58,7 @@ 'lstFetchResults', 'metricsHandler:recordAction', 'showIncognito', + 'getAccounts', 'dialogClose', ]); } @@ -81,6 +99,12 @@ } /** @override */ + getAccounts() { + this.methodCalled('getAccounts'); + return Promise.resolve(getFakeAccountsList()); + } + + /** @override */ dialogClose() { this.methodCalled('dialogClose'); }
diff --git a/chrome/test/data/webui/settings/chromeos/input_page_test.js b/chrome/test/data/webui/settings/chromeos/input_page_test.js index 4ddbcc0..7bae917 100644 --- a/chrome/test/data/webui/settings/chromeos/input_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/input_page_test.js
@@ -71,7 +71,8 @@ // The test input methods should appear. const items = inputMethodsList.querySelectorAll('.list-item'); - assertEquals(2, items.length); // Two items for input methods + // Two items for input methods and one item for add input methods. + assertEquals(3, items.length); assertEquals( 'US keyboard', items[0].querySelector('.display-name').textContent.trim()); @@ -116,5 +117,12 @@ assertTrue( await metricsProxy.whenCalled('recordToggleShowInputOptionsOnShelf')); }); + + test('when adding input methods', async () => { + inputPage.$$('#addInputMethod').click(); + Polymer.dom.flush(); + + await metricsProxy.whenCalled('recordAddInputMethod'); + }); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js b/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js index 74c48c16..2c943c6d 100644 --- a/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js +++ b/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js
@@ -20,6 +20,7 @@ 'recordManageInputMethods', 'recordToggleShowInputOptionsOnShelf', 'recordToggleTranslate', + 'recordAddInputMethod', ]); } @@ -47,6 +48,11 @@ recordToggleTranslate(value) { this.methodCalled('recordToggleTranslate', value); } + + /** @override */ + recordAddInputMethod(value) { + this.methodCalled('recordAddInputMethod', value); + } } // #cr_define_end return {
diff --git a/chromecast/base/metrics/cast_metrics_helper.cc b/chromecast/base/metrics/cast_metrics_helper.cc index fb51287..54c3ae1 100644 --- a/chromecast/base/metrics/cast_metrics_helper.cc +++ b/chromecast/base/metrics/cast_metrics_helper.cc
@@ -294,7 +294,7 @@ base::Value CastMetricsHelper::CreateEventBase(const std::string& name) { base::Value cast_event(base::Value::Type::DICTIONARY); cast_event.SetKey("name", base::Value(name)); - const double time = (Now() - base::TimeTicks()).InMicroseconds(); + const double time = (Now() - base::TimeTicks()).InMicrosecondsF(); cast_event.SetKey("time", base::Value(time)); return cast_event; }
diff --git a/chromecast/graphics/accessibility/accessibility_focus_ring_controller.cc b/chromecast/graphics/accessibility/accessibility_focus_ring_controller.cc index 8ccbee7..e465ee2f 100644 --- a/chromecast/graphics/accessibility/accessibility_focus_ring_controller.cc +++ b/chromecast/graphics/accessibility/accessibility_focus_ring_controller.cc
@@ -435,10 +435,8 @@ return; } - double fraction = delta / transition_time; - // Ease-in effect. - fraction = pow(fraction, 0.3); + const double fraction = pow(delta / transition_time, 0.3); // Handle corner case where we're animating but we don't have previous // rings. @@ -480,9 +478,7 @@ opacity = 1.0 - (change_delta / (fade_in_time + fade_out_time)); // Layer::SetOpacity will throw an error if we're not within 0...1. - opacity = base::ClampToRange(opacity, 0.0f, 1.0f); - - animation_info->opacity = opacity; + animation_info->opacity = base::ClampToRange(opacity, 0.0f, 1.0f); } void AccessibilityFocusRingController::AnimateCaretRing(
diff --git a/chromeos/components/media_app_ui/media_app_ui.cc b/chromeos/components/media_app_ui/media_app_ui.cc index 00e8781..4f246db 100644 --- a/chromeos/components/media_app_ui/media_app_ui.cc +++ b/chromeos/components/media_app_ui/media_app_ui.cc
@@ -82,10 +82,15 @@ auto* allowlist = WebUIAllowlist::GetOrCreate(browser_context); const url::Origin host_origin = url::Origin::Create(GURL(kChromeUIMediaAppURL)); - allowlist->RegisterAutoGrantedPermission( - host_origin, ContentSettingsType::FILE_SYSTEM_READ_GUARD); - allowlist->RegisterAutoGrantedPermission( - host_origin, ContentSettingsType::FILE_SYSTEM_WRITE_GUARD); + allowlist->RegisterAutoGrantedPermissions( + host_origin, { + ContentSettingsType::COOKIES, + ContentSettingsType::FILE_SYSTEM_READ_GUARD, + ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, + ContentSettingsType::IMAGES, + ContentSettingsType::JAVASCRIPT, + ContentSettingsType::SOUND, + }); content::WebUIDataSource* untrusted_source = CreateMediaAppUntrustedDataSource(delegate_.get());
diff --git a/chromeos/components/remote_apps/mojom/BUILD.gn b/chromeos/components/remote_apps/mojom/BUILD.gn new file mode 100644 index 0000000..f91de8a --- /dev/null +++ b/chromeos/components/remote_apps/mojom/BUILD.gn
@@ -0,0 +1,10 @@ +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("mojom") { + sources = [ "remote_apps.mojom" ] + + public_deps = [ + "//mojo/public/mojom/base", + "//url/mojom:url_mojom_gurl", + ] +}
diff --git a/chromeos/components/remote_apps/mojom/OWNERS b/chromeos/components/remote_apps/mojom/OWNERS new file mode 100644 index 0000000..08850f4 --- /dev/null +++ b/chromeos/components/remote_apps/mojom/OWNERS
@@ -0,0 +1,2 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/components/remote_apps/mojom/remote_apps.mojom b/chromeos/components/remote_apps/mojom/remote_apps.mojom new file mode 100644 index 0000000..594fffe --- /dev/null +++ b/chromeos/components/remote_apps/mojom/remote_apps.mojom
@@ -0,0 +1,50 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module chromeos.remote_apps.mojom; + +import "url/mojom/url.mojom"; + +// Interface for communication between an extension and the Remote Apps +// Manager. +interface RemoteApps { + // Adds a Remote Apps folder to the launcher. Empty folders are not shown in + // the launcher. + // + // Input parameters: + // - |name|: the name of the folder. + // + // Output parameters: + // - |folder_id|: the ID of the newly added folder. + // - |error|: A string describing the error if any. + AddFolder(string name) => (string? folder_id, string? error); + + // Adds a Remote Apps app to the launcher. + // + // Input parameters: + // - |name|: the name of the app. + // - |folder_id|: the ID of the parent folder. An empty string indicates the + // app has no parent folder. + // - |icon_url|: a URL pointing to an image which represents the app's icon. + // + // Output parameters: + // - |app_id|: the ID of the newly added app. + // - |error|: A string describing the error if any. + AddApp(string name, string folder_id, url.mojom.Url icon_url) => + (string? app_id, string? error); +}; + +// Factory for creating an instance of RemoteApps. +interface RemoteAppsFactory { + // Creates an instance of RemoteApps. + Create(pending_receiver<RemoteApps> remote_apps, + pending_remote<RemoteAppLaunchObserver> observer); +}; + +// A RemoteAppLaunchObserver gets notifications when a remote app is launched. +interface RemoteAppLaunchObserver { + // Invoked when a remote app is launched. |app_id| is the ID of the app which + // was launched. + OnRemoteAppLaunched(string app_id); +};
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc index 833b0de..36fbbf8 100644 --- a/components/autofill/core/browser/autofill_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -8622,6 +8622,72 @@ EXPECT_EQ(0, personal_data_.num_times_save_upi_id_called()); } +// Tests the vote generation for the address enhancement types. +TEST_F(AutofillManagerTest, PossibleFieldTypesForEnhancementVotes) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAutofillAddressEnhancementVotes); + + std::vector<AutofillProfile> profiles = {AutofillProfile()}; + profiles[0].SetRawInfo(ADDRESS_HOME_STREET_NAME, + base::ASCIIToUTF16("StreetName")); + profiles[0].SetRawInfo(ADDRESS_HOME_HOUSE_NUMBER, + base::ASCIIToUTF16("HouseNumber")); + profiles[0].SetRawInfo(ADDRESS_HOME_PREMISE_NAME, + base::ASCIIToUTF16("Premise")); + profiles[0].SetRawInfo(ADDRESS_HOME_SUBPREMISE, + base::ASCIIToUTF16("Subpremise")); + + FormData form; + FormFieldData field1; + test::CreateTestFormField("somelabel", "someid", "StreetName", "text", + &field1); + form.fields.push_back(field1); + test::CreateTestFormField("somelabel", "someid", "HouseNumber", "text", + &field1); + form.fields.push_back(field1); + test::CreateTestFormField("somelabel", "someid", "Premise", "text", &field1); + form.fields.push_back(field1); + test::CreateTestFormField("somelabel", "someid", "Subpremise", "text", + &field1); + form.fields.push_back(field1); + + FormStructure form_structure(form); + + AutofillManager::DeterminePossibleFieldTypesForUploadForTest( + profiles, {}, base::string16(), "en-us", &form_structure); + + ASSERT_EQ(4U, form_structure.field_count()); + + EXPECT_EQ(form_structure.field(0)->possible_types(), + ServerFieldTypeSet({ADDRESS_HOME_STREET_NAME})); + EXPECT_EQ(form_structure.field(1)->possible_types(), + ServerFieldTypeSet({ADDRESS_HOME_HOUSE_NUMBER})); + EXPECT_EQ(form_structure.field(2)->possible_types(), + ServerFieldTypeSet({ADDRESS_HOME_PREMISE_NAME})); + EXPECT_EQ(form_structure.field(3)->possible_types(), + ServerFieldTypeSet({ADDRESS_HOME_SUBPREMISE})); + + // Disable the feature and verify that no possible types are detected. + scoped_feature_list.Reset(); + scoped_feature_list.InitAndDisableFeature( + features::kAutofillAddressEnhancementVotes); + + AutofillManager::DeterminePossibleFieldTypesForUploadForTest( + profiles, {}, base::string16(), "en-us", &form_structure); + + ASSERT_EQ(4U, form_structure.field_count()); + + EXPECT_EQ(form_structure.field(0)->possible_types(), + ServerFieldTypeSet({UNKNOWN_TYPE})); + EXPECT_EQ(form_structure.field(1)->possible_types(), + ServerFieldTypeSet({UNKNOWN_TYPE})); + EXPECT_EQ(form_structure.field(2)->possible_types(), + ServerFieldTypeSet({UNKNOWN_TYPE})); + EXPECT_EQ(form_structure.field(3)->possible_types(), + ServerFieldTypeSet({UNKNOWN_TYPE})); +} + // AutofillManagerTest with kAutofillDisabledMixedForms feature enabled. class AutofillManagerTestWithMixedForms : public AutofillManagerTest { protected:
diff --git a/components/autofill/core/browser/data_model/address.cc b/components/autofill/core/browser/data_model/address.cc index 3b471eb..113a69c3 100644 --- a/components/autofill/core/browser/data_model/address.cc +++ b/components/autofill/core/browser/data_model/address.cc
@@ -30,36 +30,29 @@ using structured_address::VerificationStatus; -Address::Address() {} +Address::Address() = default; -Address::Address(const Address& address) { - *this = address; -} +Address::Address(const Address& address) = default; -Address::~Address() {} +Address::~Address() = default; -Address& Address::operator=(const Address& address) { - if (this == &address) - return *this; - - street_address_ = address.street_address_; - dependent_locality_ = address.dependent_locality_; - city_ = address.city_; - state_ = address.state_; - country_code_ = address.country_code_; - zip_code_ = address.zip_code_; - sorting_code_ = address.sorting_code_; - return *this; -} +Address& Address::operator=(const Address& address) = default; bool Address::operator==(const Address& other) const { if (this == &other) return true; + // Note that the structured address tokens are not evaluated for profile + // comparison. return street_address_ == other.street_address_ && dependent_locality_ == other.dependent_locality_ && city_ == other.city_ && state_ == other.state_ && zip_code_ == other.zip_code_ && sorting_code_ == other.sorting_code_ && - country_code_ == other.country_code_; + country_code_ == other.country_code_ && + street_name_ == other.street_name_ && + dependent_street_name_ == other.dependent_street_name_ && + house_number_ == other.house_number_ && + premise_name_ == other.premise_name_ && + subpremise_ == other.subpremise_; } base::string16 Address::GetRawInfo(ServerFieldType type) const {
diff --git a/components/autofill/core/browser/data_model/autofill_profile_comparator.cc b/components/autofill/core/browser/data_model/autofill_profile_comparator.cc index 9d025eec9..292152d 100644 --- a/components/autofill/core/browser/data_model/autofill_profile_comparator.cc +++ b/components/autofill/core/browser/data_model/autofill_profile_comparator.cc
@@ -188,6 +188,25 @@ return iter_.get(); } +// Copies the address line information and structured tokens from |source| to +// |target|. +void CopyAddressLineInformationFromProfile(const AutofillProfile& source, + Address* target) { + ServerFieldTypeSet types_to_copy; + if (base::FeatureList::IsEnabled( + features::kAutofillAddressEnhancementVotes)) { + types_to_copy = { + ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_STREET_NAME, + ADDRESS_HOME_DEPENDENT_STREET_NAME, ADDRESS_HOME_HOUSE_NUMBER, + ADDRESS_HOME_PREMISE_NAME, ADDRESS_HOME_SUBPREMISE}; + } else { + types_to_copy = {ADDRESS_HOME_STREET_ADDRESS}; + } + + for (const auto& type : types_to_copy) + target->SetRawInfo(type, source.GetRawInfo(type)); +} + } // namespace AutofillProfileComparator::AutofillProfileComparator( @@ -791,17 +810,17 @@ const base::string16& address2 = p2.GetInfo(kStreetAddress, app_locale_); // If one of the addresses is empty then use the other. if (address1.empty()) { - address->SetInfo(kStreetAddress, address2, app_locale_); + CopyAddressLineInformationFromProfile(p2, address); } else if (address2.empty()) { - address->SetInfo(kStreetAddress, address1, app_locale_); + CopyAddressLineInformationFromProfile(p1, address); } else { // Prefer the multi-line address if one is multi-line and the other isn't. bool address1_multiline = ContainsNewline(address1); bool address2_multiline = ContainsNewline(address2); if (address1_multiline && !address2_multiline) { - address->SetInfo(kStreetAddress, address1, app_locale_); + CopyAddressLineInformationFromProfile(p1, address); } else if (address2_multiline && !address1_multiline) { - address->SetInfo(kStreetAddress, address2, app_locale_); + CopyAddressLineInformationFromProfile(p2, address); } else { // Prefer the one with more tokens if they're both single-line or both // multi-line addresses, making sure to apply address normalization and @@ -812,19 +831,20 @@ switch (result) { case SAME_TOKENS: // They have the same set of unique tokens. Let's pick the one that's - // longer. - address->SetInfo( - kStreetAddress, - (p2.use_date() > p1.use_date() ? address2 : address1), - app_locale_); + // newer. + if (p2.use_date() > p1.use_date()) { + CopyAddressLineInformationFromProfile(p2, address); + } else { + CopyAddressLineInformationFromProfile(p1, address); + } break; case S1_CONTAINS_S2: // address1 has more unique tokens than address2. - address->SetInfo(kStreetAddress, address1, app_locale_); + CopyAddressLineInformationFromProfile(p1, address); break; case S2_CONTAINS_S1: // address2 has more unique tokens than address1. - address->SetInfo(kStreetAddress, address2, app_locale_); + CopyAddressLineInformationFromProfile(p2, address); break; case DIFFERENT_TOKENS: default:
diff --git a/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc b/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc index 88cc560..02c6844 100644 --- a/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc +++ b/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc
@@ -59,8 +59,9 @@ const char kLocale[] = "en-US"; -class AutofillProfileComparatorTest : public testing::Test, - public testing::WithParamInterface<bool> { +class AutofillProfileComparatorTest + : public testing::Test, + public testing::WithParamInterface<std::tuple<bool, bool>> { public: // Expose the protected methods of autofill::AutofillProfileComparator for // testing. @@ -288,6 +289,29 @@ actual.GetInfo(AutofillType(ADDRESS_HOME_ZIP), kLocale)); EXPECT_EQ(expected.GetInfo(AutofillType(ADDRESS_HOME_COUNTRY), kLocale), actual.GetInfo(AutofillType(ADDRESS_HOME_COUNTRY), kLocale)); + + EXPECT_EQ(expected.GetInfo(AutofillType(autofill::ADDRESS_HOME_STREET_NAME), + kLocale), + actual.GetInfo(AutofillType(autofill::ADDRESS_HOME_STREET_NAME), + kLocale)); + EXPECT_EQ(expected.GetInfo( + AutofillType(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME), + kLocale), + actual.GetInfo( + AutofillType(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME), + kLocale)); + EXPECT_EQ(expected.GetInfo( + AutofillType(autofill::ADDRESS_HOME_HOUSE_NUMBER), kLocale), + actual.GetInfo(AutofillType(autofill::ADDRESS_HOME_HOUSE_NUMBER), + kLocale)); + EXPECT_EQ(expected.GetInfo( + AutofillType(autofill::ADDRESS_HOME_PREMISE_NAME), kLocale), + actual.GetInfo(AutofillType(autofill::ADDRESS_HOME_PREMISE_NAME), + kLocale)); + EXPECT_EQ(expected.GetInfo(AutofillType(autofill::ADDRESS_HOME_SUBPREMISE), + kLocale), + actual.GetInfo(AutofillType(autofill::ADDRESS_HOME_SUBPREMISE), + kLocale)); } AutofillProfileComparator comparator_{kLocale}; @@ -296,17 +320,36 @@ void SetUp() override { InitializeFeatures(); } void InitializeFeatures() { - structured_names_enabled_ = GetParam(); + structured_names_enabled_ = std::get<0>(GetParam()); + address_enhancement_votes_enabled_ = std::get<1>(GetParam()); + + std::vector<base::Feature> enabled_features; + std::vector<base::Feature> disabled_features; + if (structured_names_enabled_) { - scoped_features_.InitAndEnableFeature( + enabled_features.push_back( autofill::features::kAutofillEnableSupportForMoreStructureInNames); } else { - scoped_features_.InitAndDisableFeature( + disabled_features.push_back( autofill::features::kAutofillEnableSupportForMoreStructureInNames); } + + if (address_enhancement_votes_enabled_) { + enabled_features.push_back( + autofill::features::kAutofillAddressEnhancementVotes); + } else { + disabled_features.push_back( + autofill::features::kAutofillAddressEnhancementVotes); + } + scoped_features_.InitWithFeatures(enabled_features, disabled_features); } bool StructuredNames() const { return structured_names_enabled_; } + bool AddressEnhancementVotes() const { + return address_enhancement_votes_enabled_; + } + + bool address_enhancement_votes_enabled_; bool structured_names_enabled_; base::test::ScopedFeatureList scoped_features_; @@ -1167,9 +1210,33 @@ TEST_P(AutofillProfileComparatorTest, MergeAddressesMostUniqueTokens) { AutofillProfile p1 = CreateProfileWithAddress( "1 Some Street", "Unit 3", "Carver", "CA - California", "90210", "US"); + + p1.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber")); + p1.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise")); + AutofillProfile p2 = CreateProfileWithAddress( "1 Some Other Street", "Unit 3", "Carver City", "ca", "90210-1234", "us"); + p2.set_use_date(p1.use_date() + base::TimeDelta::FromMinutes(1)); + p2.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise2")); + Address expected; expected.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("1 Some Other Street")); expected.SetRawInfo(ADDRESS_HOME_LINE2, UTF8ToUTF16("Unit 3")); @@ -1178,6 +1245,78 @@ expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("90210-1234")); expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("US")); + // If address enhancement votes are enabled, it is expecfted that the + // substructure from p2 since it is a superset of p1. + // Otherwise the fields are expected to be empty after the merge process. + if (AddressEnhancementVotes()) { + expected.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName2")); + expected.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName2")); + expected.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber2")); + expected.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName2")); + expected.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise2")); + } + MergeAddressesAndExpect(p1, p2, expected); + MergeAddressesAndExpect(p2, p1, expected); +} + +TEST_P(AutofillProfileComparatorTest, MergeAddressesWithStructure) { + AutofillProfile p1 = CreateProfileWithAddress( + "6543 CH BACON", "APP 3", "MONTRÉAL", "QUÉBEC", "HHH999", "ca"); + + p1.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber")); + p1.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise")); + + AutofillProfile p2 = CreateProfileWithAddress( + "6543, Bacon Rd", "", "Montreal", "QC", "hhh 999", "CA"); + p2.set_use_date(p1.use_date() + base::TimeDelta::FromMinutes(1)); + p2.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise2")); + + Address expected; + expected.SetRawInfo(ADDRESS_HOME_LINE1, UTF8ToUTF16("6543 CH BACON")); + expected.SetRawInfo(ADDRESS_HOME_LINE2, UTF8ToUTF16("APP 3")); + expected.SetRawInfo(ADDRESS_HOME_CITY, UTF8ToUTF16("Montreal")); + expected.SetRawInfo(ADDRESS_HOME_STATE, UTF8ToUTF16("QC")); + expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("hhh 999")); + expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("CA")); + + // If address enhancement votes are enabled, it is expecfted that the + // substructure from p1 is used since it is most recent. + // Otherwise the fields are expected to be empty after the merge process. + if (AddressEnhancementVotes()) { + expected.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName")); + expected.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName")); + expected.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber")); + expected.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName")); + expected.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise")); + } + MergeAddressesAndExpect(p1, p2, expected); MergeAddressesAndExpect(p2, p1, expected); } @@ -1185,8 +1324,31 @@ TEST_P(AutofillProfileComparatorTest, MergeAddressesWithRewrite) { AutofillProfile p1 = CreateProfileWithAddress( "6543 CH BACON", "APP 3", "MONTRÉAL", "QUÉBEC", "HHH999", "ca"); + + p1.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber")); + p1.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName")); + p1.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise")); + AutofillProfile p2 = CreateProfileWithAddress( "6543, Bacon Rd", "", "Montreal", "QC", "hhh 999", "CA"); + p2.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName2")); + p2.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise2")); + p2.set_use_date(p1.use_date() + base::TimeDelta::FromMinutes(1)); Address expected; @@ -1197,6 +1359,21 @@ expected.SetRawInfo(ADDRESS_HOME_ZIP, UTF8ToUTF16("hhh 999")); expected.SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16("CA")); + // If address enhancement votes are enabled, it is expecfted that the + // substructure from p1 is used since it has more tokens. + if (AddressEnhancementVotes()) { + expected.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, + base::UTF8ToUTF16("StreetName")); + expected.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_STREET_NAME, + base::UTF8ToUTF16("DependentStreetName")); + expected.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, + base::UTF8ToUTF16("HouseNumber")); + expected.SetRawInfo(autofill::ADDRESS_HOME_PREMISE_NAME, + base::UTF8ToUTF16("PremiseName")); + expected.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, + base::UTF8ToUTF16("Subpremise")); + } + MergeAddressesAndExpect(p1, p2, expected); MergeAddressesAndExpect(p2, p1, expected); } @@ -1233,4 +1410,6 @@ INSTANTIATE_TEST_SUITE_P( All, AutofillProfileComparatorTest, - testing::Bool()); // Test with and without structured names. + testing::Combine(testing::Bool(), + testing::Bool())); // Test with and without structured + // names and address enhancement votes.
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 85760cd..b35ae47e 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -903,6 +903,7 @@ form->UpdateAutofillCount(); form->RationalizeRepeatedFields(form_interactions_ukm_logger); form->RationalizeFieldTypePredictions(); + form->OverrideServerPredictionsWithHeuristics(); form->IdentifySections(false); } @@ -1860,6 +1861,25 @@ } } +void FormStructure::OverrideServerPredictionsWithHeuristics() { + if (!base::FeatureList::IsEnabled( + features::kAutofillEnableSupportForMoreStructureInNames)) { + return; + } + for (const auto& field : fields_) { + // If the heuristic type is |LAST_NAME_SECOND| or |LAST_NAME_FIRST| + // unconditionally use this prediction. + switch (field->heuristic_type()) { + case NAME_LAST_SECOND: + case NAME_LAST_FIRST: + field->SetTypeTo(AutofillType(field->heuristic_type())); + break; + default: { + }; + } + } +} + void FormStructure::RationalizeRepeatedFields( AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) { // The type of every field whose index is in
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index a0f583e..db20768 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -211,6 +211,10 @@ // the fields that are considered composing a first complete phone number. void RationalizePhoneNumbersInSection(std::string section); + // Overrides server predictions with specific heuristic predictions: + // * NAME_LAST_SECOND heuristic predictions are unconditionally used. + void OverrideServerPredictionsWithHeuristics(); + const AutofillField* field(size_t index) const; AutofillField* field(size_t index); size_t field_count() const;
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index f5e7a3ae..de7e79d1 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -5197,6 +5197,88 @@ EXPECT_EQ(0U, form_structure2.PossibleValues(ADDRESS_BILLING_COUNTRY).size()); } +// Test the heuristic predictions the NAME_LAST_SECOND override server +// predictions. +TEST_F(FormStructureTest, + ParseQueryResponse_HeuristicsOverrideSpanishLastNameTypes) { + base::test::ScopedFeatureList scoped_feature; + scoped_feature.InitAndEnableFeature( + features::kAutofillEnableSupportForMoreStructureInNames); + + FormData form_data; + FormFieldData field; + form_data.url = GURL("http://foo.com"); + field.form_control_type = "text"; + + // First name field. + field.label = ASCIIToUTF16("Nombre"); + field.name = ASCIIToUTF16("Nombre"); + form_data.fields.push_back(field); + + // First last name field. + // Should be identified by local heuristics. + field.label = ASCIIToUTF16("Apellido Paterno"); + field.name = ASCIIToUTF16("apellido_paterno"); + form_data.fields.push_back(field); + + // Second last name field. + // Should be identified by local heuristics. + field.label = ASCIIToUTF16("Apellido Materno"); + field.name = ASCIIToUTF16("apellido materno"); + form_data.fields.push_back(field); + + FormStructure form(form_data); + form.DetermineHeuristicTypes(); + + // Setup the query response. + AutofillQueryResponseContents response; + std::string response_string; + response.add_field()->set_overall_type_prediction(NAME_FIRST); + // Simulate a NAME_LAST classification for the two last name fields. + response.add_field()->set_overall_type_prediction(NAME_LAST); + response.add_field()->set_overall_type_prediction(NAME_LAST); + ASSERT_TRUE(response.SerializeToString(&response_string)); + + // Parse the response and update the field type predictions. + std::vector<FormStructure*> forms{&form}; + FormStructure::ParseQueryResponse(response_string, forms, + test::GetEncodedSignatures(forms), nullptr); + ASSERT_EQ(form.field_count(), 3U); + + // Validate the heuristic and server predictions. + EXPECT_EQ(NAME_LAST_FIRST, form.field(1)->heuristic_type()); + EXPECT_EQ(NAME_LAST_SECOND, form.field(2)->heuristic_type()); + EXPECT_EQ(NAME_LAST, form.field(1)->server_type()); + EXPECT_EQ(NAME_LAST, form.field(2)->server_type()); + + // Validate that the heuristic prediction wins for the two last name fields. + EXPECT_EQ(form.field(0)->Type().GetStorableType(), NAME_FIRST); + EXPECT_EQ(form.field(1)->Type().GetStorableType(), NAME_LAST_FIRST); + EXPECT_EQ(form.field(2)->Type().GetStorableType(), NAME_LAST_SECOND); + + // Now disable the feature and process the query again. + scoped_feature.Reset(); + scoped_feature.InitAndDisableFeature( + features::kAutofillEnableSupportForMoreStructureInNames); + + std::vector<FormStructure*> forms2{&form}; + FormStructure::ParseQueryResponse( + response_string, forms2, test::GetEncodedSignatures(forms2), nullptr); + ASSERT_EQ(form.field_count(), 3U); + + // Validate the heuristic and server predictions. + EXPECT_EQ(NAME_LAST_FIRST, form.field(1)->heuristic_type()); + EXPECT_EQ(NAME_LAST_SECOND, form.field(2)->heuristic_type()); + EXPECT_EQ(NAME_LAST, form.field(1)->server_type()); + EXPECT_EQ(NAME_LAST, form.field(2)->server_type()); + + // Validate that the heuristic prediction does not win for the two last name + // fields. + EXPECT_EQ(form.field(0)->Type().GetStorableType(), NAME_FIRST); + EXPECT_EQ(form.field(1)->Type().GetStorableType(), NAME_LAST); + EXPECT_EQ(form.field(2)->Type().GetStorableType(), NAME_LAST); +} + // Tests proper resolution heuristic, server and html field types when the // server returns NO_SERVER_DATA, UNKNOWN_TYPE, and a valid type. TEST_F(FormStructureTest, ParseQueryResponse_TooManyTypes) {
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 7d24dc6..01203468 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -42,15 +42,6 @@ // message. static constexpr int kAutostartInitialProgress = 5; -// Parameter that allows setting the color of the overlay. -const char kOverlayColorParameterName[] = "OVERLAY_COLORS"; - -// Parameter that contains the current session username. Should be synced with -// |SESSION_USERNAME_PARAMETER| from -// .../password_manager/PasswordChangeLauncher.java -// TODO(b/151401974): Eliminate duplicate parameter definitions. -const char kPasswordChangeUsernameParameterName[] = "PASSWORD_CHANGE_USERNAME"; - // Experiment for toggling the new progress bar. const char kProgressBarExperiment[] = "4400697"; @@ -1027,7 +1018,7 @@ SetDetails(std::move(details)); const base::Optional<std::string> overlay_color = - trigger_context_->GetParameter(kOverlayColorParameterName); + trigger_context_->GetOverlayColors(); if (overlay_color) { std::unique_ptr<OverlayColors> colors = std::make_unique<OverlayColors>(); std::vector<std::string> color_strings = @@ -1045,7 +1036,7 @@ SetOverlayColors(std::move(colors)); } const base::Optional<std::string> password_change_username = - trigger_context_->GetParameter(kPasswordChangeUsernameParameterName); + trigger_context_->GetPasswordChangeUsername(); if (password_change_username) { DCHECK( GetCurrentURL().is_valid()); // At least |deeplink_url_| must be set.
diff --git a/components/autofill_assistant/browser/trigger_context.cc b/components/autofill_assistant/browser/trigger_context.cc index ae904963..83c3a03 100644 --- a/components/autofill_assistant/browser/trigger_context.cc +++ b/components/autofill_assistant/browser/trigger_context.cc
@@ -7,6 +7,15 @@ namespace autofill_assistant { +// Parameter that allows setting the color of the overlay. +const char kOverlayColorParameterName[] = "OVERLAY_COLORS"; + +// Parameter that contains the current session username. Should be synced with +// |SESSION_USERNAME_PARAMETER| from +// .../password_manager/PasswordChangeLauncher.java +// TODO(b/151401974): Eliminate duplicate parameter definitions. +const char kPasswordChangeUsernameParameterName[] = "PASSWORD_CHANGE_USERNAME"; + // static std::unique_ptr<TriggerContext> TriggerContext::CreateEmpty() { return std::make_unique<TriggerContextImpl>(); @@ -28,6 +37,14 @@ TriggerContext::TriggerContext() {} TriggerContext::~TriggerContext() {} +base::Optional<std::string> TriggerContext::GetOverlayColors() const { + return GetParameter(kOverlayColorParameterName); +} + +base::Optional<std::string> TriggerContext::GetPasswordChangeUsername() const { + return GetParameter(kPasswordChangeUsernameParameterName); +} + TriggerContextImpl::TriggerContextImpl() {} TriggerContextImpl::TriggerContextImpl(
diff --git a/components/autofill_assistant/browser/trigger_context.h b/components/autofill_assistant/browser/trigger_context.h index 5c6695f..cb201d3 100644 --- a/components/autofill_assistant/browser/trigger_context.h +++ b/components/autofill_assistant/browser/trigger_context.h
@@ -44,6 +44,10 @@ virtual base::Optional<std::string> GetParameter( const std::string& name) const = 0; + // Getters for specific parameters. + base::Optional<std::string> GetOverlayColors() const; + base::Optional<std::string> GetPasswordChangeUsername() const; + // Returns a comma-separated set of experiment ids. virtual std::string experiment_ids() const = 0;
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 0a235698..0f401cba 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -1028,6 +1028,9 @@ void ClientControlledShellSurface::InitializeWindowState( ash::WindowState* window_state) { + // Set the relevant window properties for Arc apps. + SetArcAppType(window_state->window()); + // Allow the client to request bounds that do not fill the entire work area // when maximized, or the entire display when fullscreen. window_state->set_allow_set_bounds_direct(true);
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 3f02840d..1a71e2bf 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -962,7 +962,6 @@ SetShellApplicationId(window, application_id_); SetShellStartupId(window, startup_id_); SetShellMainSurface(window, root_surface()); - SetArcAppType(window); // Start tracking changes to window bounds and window state. window->AddObserver(this);
diff --git a/components/feed/core/common/user_classifier.cc b/components/feed/core/common/user_classifier.cc index e286833..e6ec9ff9 100644 --- a/components/feed/core/common/user_classifier.cc +++ b/components/feed/core/common/user_classifier.cc
@@ -285,7 +285,7 @@ base::TimeDelta since_last_time = clock_->Now() - pref_service_->GetTime(GetLastTimeKey(event)); - return since_last_time.InSecondsF() / 3600; + return since_last_time / base::TimeDelta::FromHours(1); } bool UserClassifier::HasLastTime(Event event) const {
diff --git a/components/media_message_center/media_controls_progress_view.cc b/components/media_message_center/media_controls_progress_view.cc index ebc6769e..f180c19e 100644 --- a/components/media_message_center/media_controls_progress_view.cc +++ b/components/media_message_center/media_controls_progress_view.cc
@@ -91,7 +91,7 @@ base::TimeDelta current_position = media_position.GetPosition(); base::TimeDelta duration = media_position.duration(); - double progress = current_position.InSecondsF() / duration.InSecondsF(); + double progress = current_position / duration; SetBarProgress(progress); // Time formatting can't yet represent durations greater than 24 hours in
diff --git a/components/ntp_snippets/user_classifier.cc b/components/ntp_snippets/user_classifier.cc index d9f4ea23..e38e8b56 100644 --- a/components/ntp_snippets/user_classifier.cc +++ b/components/ntp_snippets/user_classifier.cc
@@ -361,7 +361,7 @@ base::TimeDelta since_last_time = clock_->Now() - DeserializeTime(pref_service_->GetInt64( kLastTimeKeys[static_cast<int>(metric)])); - return since_last_time.InSecondsF() / 3600; + return since_last_time / base::TimeDelta::FromHours(1); } bool UserClassifier::HasLastTime(Metric metric) const {
diff --git a/components/omnibox/browser/omnibox_popup_model.cc b/components/omnibox/browser/omnibox_popup_model.cc index 7657098..09918a0c 100644 --- a/components/omnibox/browser/omnibox_popup_model.cc +++ b/components/omnibox/browser/omnibox_popup_model.cc
@@ -48,7 +48,8 @@ } bool OmniboxPopupModel::Selection::IsChangeToKeyword(Selection from) const { - return state == KEYWORD_MODE && from.state != KEYWORD_MODE; + return (state == KEYWORD_MODE || state == FOCUSED_BUTTON_KEYWORD) && + !(from.state == KEYWORD_MODE || from.state == FOCUSED_BUTTON_KEYWORD); } bool OmniboxPopupModel::Selection::IsButtonFocused() const {
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc index 68051c1..c246dfff 100644 --- a/components/omnibox/browser/shortcuts_provider.cc +++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -386,8 +386,7 @@ base::TimeDelta time_passed = base::Time::Now() - shortcut.last_access_time; // Clamp to 0 in case time jumps backwards (e.g. due to DST). double decay_exponent = - std::max(0.0, kLn2 * static_cast<double>(time_passed.InMicroseconds()) / - base::Time::kMicrosecondsPerWeek); + std::max(0.0, kLn2 * time_passed / base::TimeDelta::FromDays(7)); // We modulate the decay factor based on how many times the shortcut has been // used. Newly created shortcuts decay at full speed; otherwise, decaying by
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 67004b9..0a652d1c 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -243,6 +243,8 @@ "ui/saved_passwords_presenter.h", "votes_uploader.cc", "votes_uploader.h", + "well_known_change_password_state.cc", + "well_known_change_password_state.h", "well_known_change_password_util.cc", "well_known_change_password_util.h", ] @@ -631,6 +633,7 @@ "ui/saved_passwords_presenter_unittest.cc", "vote_uploads_test_matchers.h", "votes_uploader_unittest.cc", + "well_known_change_password_state_unittest.cc", "well_known_change_password_util_unittest.cc", ] if (is_android) {
diff --git a/components/password_manager/core/browser/well_known_change_password_state.cc b/components/password_manager/core/browser/well_known_change_password_state.cc new file mode 100644 index 0000000..4151c8a --- /dev/null +++ b/components/password_manager/core/browser/well_known_change_password_state.cc
@@ -0,0 +1,109 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/password_manager/core/browser/well_known_change_password_state.h" + +#include "components/password_manager/core/browser/well_known_change_password_util.h" +#include "net/base/load_flags.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" + +using password_manager::WellKnownChangePasswordState; +using password_manager::WellKnownChangePasswordStateDelegate; + +namespace password_manager { + +std::unique_ptr<network::SimpleURLLoader> +CreateResourceRequestToWellKnownNonExistingResourceFor(const GURL& url) { + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = CreateWellKnownNonExistingResourceURL(url); + resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + resource_request->load_flags = net::LOAD_DISABLE_CACHE; + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation( + "well_known_path_that_should_not_exist", + R"( + semantics { + sender: "Password Manager" + description: + "Check whether the site supports .well-known 'special' URLs." + "If the website does not support the spec we navigate to the " + "fallback url. See also " +"https://wicg.github.io/change-password-url/response-code-reliability.html#iana" + trigger: + "When the user clicks 'Change password' on " + "chrome://settings/passwords, or when they visit the " + "[ORIGIN]/.well-known/change-password special URL, Chrome makes " + "this additional request. Chrome Password manager shows a button " + "with the link in the password checkup for compromised passwords " + "view (chrome://settings/passwords/check) and in a dialog when the " + "user signs in using compromised credentials." + data: + "The request body is empty. No user data is included." + destination: WEBSITE + } + policy { + cookies_allowed: NO + setting: "This feature cannot be disabled." + policy_exception_justification: "Essential for navigation." + })"); + return network::SimpleURLLoader::Create(std::move(resource_request), + traffic_annotation); +} + +WellKnownChangePasswordState::WellKnownChangePasswordState( + WellKnownChangePasswordStateDelegate* delegate) + : delegate_(delegate) {} + +WellKnownChangePasswordState::~WellKnownChangePasswordState() = default; + +void WellKnownChangePasswordState::FetchNonExistingResource( + network::SharedURLLoaderFactory* url_loader_factory, + const GURL& url) { + url_loader_ = CreateResourceRequestToWellKnownNonExistingResourceFor(url); + // Binding the callback to |this| is safe, because the State exists until + // OnProcessingFinished is called which can only be called after the response + // arrives. + url_loader_->DownloadHeadersOnly( + url_loader_factory, + base::BindOnce( + &WellKnownChangePasswordState::FetchNonExistingResourceCallback, + base::Unretained(this))); +} + +void WellKnownChangePasswordState::SetChangePasswordResponseCode( + int status_code) { + change_password_response_code_ = status_code; + ContinueProcessing(); +} + +void WellKnownChangePasswordState::FetchNonExistingResourceCallback( + scoped_refptr<net::HttpResponseHeaders> headers) { + non_existing_resource_response_code_ = + headers ? headers->response_code() : -1; + ContinueProcessing(); +} + +void WellKnownChangePasswordState::ContinueProcessing() { + if (!BothRequestsFinished()) + return; + delegate_->OnProcessingFinished(SupportsChangePasswordUrl()); +} + +bool WellKnownChangePasswordState::BothRequestsFinished() const { + return non_existing_resource_response_code_ != 0 && + change_password_response_code_ != 0; +} + +bool WellKnownChangePasswordState::SupportsChangePasswordUrl() const { + DCHECK(BothRequestsFinished()); + return 200 <= change_password_response_code_ && + change_password_response_code_ < 300 && + non_existing_resource_response_code_ == net::HTTP_NOT_FOUND; +} + +} // namespace password_manager \ No newline at end of file
diff --git a/components/password_manager/core/browser/well_known_change_password_state.h b/components/password_manager/core/browser/well_known_change_password_state.h new file mode 100644 index 0000000..d2cb148 --- /dev/null +++ b/components/password_manager/core/browser/well_known_change_password_state.h
@@ -0,0 +1,70 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_WELL_KNOWN_CHANGE_PASSWORD_STATE_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_WELL_KNOWN_CHANGE_PASSWORD_STATE_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "url/gurl.h" + +namespace network { +class SharedURLLoaderFactory; +} + +namespace password_manager { + +// Creates a SimpleURLLoader for a request to the non existing resource path for +// a given |origin|. +// TODO(crbug.com/927473): move method to anonymous namespace when State is +// integrated in NavigationThrottle. +std::unique_ptr<network::SimpleURLLoader> +CreateResourceRequestToWellKnownNonExistingResourceFor(const GURL& url); + +// A delegate that is notified when the processing is done and its known if +// .well-known/change-password is supported. +class WellKnownChangePasswordStateDelegate { + public: + virtual ~WellKnownChangePasswordStateDelegate() = default; + virtual void OnProcessingFinished(bool is_supported) = 0; +}; + +// Processes if .well-known/change-password is supported by a site. +class WellKnownChangePasswordState { + public: + explicit WellKnownChangePasswordState( + password_manager::WellKnownChangePasswordStateDelegate* delegate); + ~WellKnownChangePasswordState(); + // Request the status code from a path that is expected to return 404. + void FetchNonExistingResource( + network::SharedURLLoaderFactory* url_loader_factory, + const GURL& origin); + // The request to .well-known/change-password is not made by this State. To + // get the response code for the request the owner of the state has to call + // this method to tell the state. + void SetChangePasswordResponseCode(int status_code); + + private: + // Callback for the request to the "not exist" path. + void FetchNonExistingResourceCallback( + scoped_refptr<net::HttpResponseHeaders> headers); + // Function is called when both requests are finished. Decides to continue or + // redirect to homepage. + void ContinueProcessing(); + // Checks if both requests are finished. + bool BothRequestsFinished() const; + // Checks the status codes and returns if change password is supported. + bool SupportsChangePasswordUrl() const; + + WellKnownChangePasswordStateDelegate* delegate_ = nullptr; + int non_existing_resource_response_code_ = 0; + int change_password_response_code_ = 0; + std::unique_ptr<network::SimpleURLLoader> url_loader_; +}; + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_WELL_KNOWN_CHANGE_PASSWORD_STATE_H_
diff --git a/components/password_manager/core/browser/well_known_change_password_state_unittest.cc b/components/password_manager/core/browser/well_known_change_password_state_unittest.cc new file mode 100644 index 0000000..fcb0c4e --- /dev/null +++ b/components/password_manager/core/browser/well_known_change_password_state_unittest.cc
@@ -0,0 +1,159 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/password_manager/core/browser/well_known_change_password_state.h" + +#include "base/task/post_task.h" +#include "base/test/task_environment.h" +#include "components/password_manager/core/browser/well_known_change_password_util.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "services/network/test/test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace password_manager { + +// To simulate different arrivals of the response codes, a delay for the +// response is added. +struct ResponseDelayParams { + int change_password_delay; + int not_exist_delay; +}; + +constexpr char kOrigin[] = "foo.bar"; + +class MockWellKnownChangePasswordStateDelegate + : public WellKnownChangePasswordStateDelegate { + public: + MockWellKnownChangePasswordStateDelegate() = default; + ~MockWellKnownChangePasswordStateDelegate() override = default; + + MOCK_METHOD(void, OnProcessingFinished, (bool), (override)); +}; + +class WellKnownChangePasswordStateTest + : public testing::Test, + public testing::WithParamInterface<ResponseDelayParams> { + public: + WellKnownChangePasswordStateTest() { + state_.FetchNonExistingResource(test_shared_loader_factory_.get(), + GURL(kOrigin)); + } + // Mocking and sending the response for the non_existing request with status + // code |status| after a time delay |delay|. + void RespondeToNonExistingRequest(net::HttpStatusCode status, int delay); + // Mocking and setting the response for the change_password request with + // status code |status| after a time delay |delay|. + void RespondeToChangePasswordRequest(net::HttpStatusCode status, int delay); + + MockWellKnownChangePasswordStateDelegate* delegate() { return &delegate_; } + + // Wait until all PostTasks are processed. + void FastForwardPostTasks() { + task_environment_.FastForwardUntilNoTasksRemain(); + } + + private: + base::test::SingleThreadTaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + MockWellKnownChangePasswordStateDelegate delegate_; + WellKnownChangePasswordState state_{&delegate_}; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_ = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_); +}; + +void WellKnownChangePasswordStateTest::RespondeToNonExistingRequest( + net::HttpStatusCode status, + int delay) { + EXPECT_EQ(test_url_loader_factory_.NumPending(), 1); + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](net::HttpStatusCode status, + network::TestURLLoaderFactory* factory) { + factory->SimulateResponseForPendingRequest( + CreateWellKnownNonExistingResourceURL(GURL(kOrigin)), + network::URLLoaderCompletionStatus(net::OK), + network::CreateURLResponseHead(status), ""); + }, + status, &test_url_loader_factory_), + base::TimeDelta::FromMilliseconds(delay)); +} + +void WellKnownChangePasswordStateTest::RespondeToChangePasswordRequest( + net::HttpStatusCode status, + int delay) { + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + &WellKnownChangePasswordState::SetChangePasswordResponseCode, + base::Unretained(&state_), status), + base::TimeDelta::FromMilliseconds(delay)); +} + +TEST_P(WellKnownChangePasswordStateTest, Support_Ok) { + ResponseDelayParams params = GetParam(); + + EXPECT_CALL(*delegate(), OnProcessingFinished(true)); + + RespondeToChangePasswordRequest(net::HTTP_OK, params.change_password_delay); + RespondeToNonExistingRequest(net::HTTP_NOT_FOUND, params.not_exist_delay); + FastForwardPostTasks(); +} + +TEST_P(WellKnownChangePasswordStateTest, Support_PartialContent) { + ResponseDelayParams params = GetParam(); + + EXPECT_CALL(*delegate(), OnProcessingFinished(true)); + + RespondeToChangePasswordRequest(net::HTTP_PARTIAL_CONTENT, + params.change_password_delay); + RespondeToNonExistingRequest(net::HTTP_NOT_FOUND, params.not_exist_delay); + FastForwardPostTasks(); +} + +TEST_P(WellKnownChangePasswordStateTest, NoSupport_NotFound) { + ResponseDelayParams params = GetParam(); + + EXPECT_CALL(*delegate(), OnProcessingFinished(false)); + + RespondeToChangePasswordRequest(net::HTTP_NOT_FOUND, + params.change_password_delay); + RespondeToNonExistingRequest(net::HTTP_NOT_FOUND, params.not_exist_delay); + FastForwardPostTasks(); +} + +TEST_P(WellKnownChangePasswordStateTest, NoSupport_Ok) { + ResponseDelayParams params = GetParam(); + + EXPECT_CALL(*delegate(), OnProcessingFinished(false)); + + RespondeToChangePasswordRequest(net::HTTP_OK, params.change_password_delay); + RespondeToNonExistingRequest(net::HTTP_OK, params.not_exist_delay); + FastForwardPostTasks(); +} + +// Expect no support because the State should not handle redirects. +TEST_P(WellKnownChangePasswordStateTest, NoSupport_Redirect) { + ResponseDelayParams params = GetParam(); + + EXPECT_CALL(*delegate(), OnProcessingFinished(false)); + + RespondeToChangePasswordRequest(net::HTTP_PERMANENT_REDIRECT, + params.change_password_delay); + RespondeToNonExistingRequest(net::HTTP_NOT_FOUND, params.not_exist_delay); + FastForwardPostTasks(); +} + +constexpr ResponseDelayParams kDelayParams[] = {{0, 1}, {1, 0}}; + +INSTANTIATE_TEST_SUITE_P(All, + WellKnownChangePasswordStateTest, + ::testing::ValuesIn(kDelayParams)); + +} // namespace password_manager
diff --git a/components/payments/content/BUILD.gn b/components/payments/content/BUILD.gn index 47fa732..269f94b8 100644 --- a/components/payments/content/BUILD.gn +++ b/components/payments/content/BUILD.gn
@@ -157,6 +157,7 @@ sources = [ "android_app_communication_test_support.h", "android_app_communication_unittest.cc", + "android_payment_app_factory_unittest.cc", "android_payment_app_unittest.cc", "payment_method_manifest_table_unittest.cc", "service_worker_payment_app_finder_unittest.cc",
diff --git a/components/payments/content/android_payment_app_factory.cc b/components/payments/content/android_payment_app_factory.cc index 52cc539..f0888a01 100644 --- a/components/payments/content/android_payment_app_factory.cc +++ b/components/payments/content/android_payment_app_factory.cc
@@ -4,12 +4,28 @@ #include "components/payments/content/android_payment_app_factory.h" +#include <map> +#include <memory> +#include <set> +#include <string> #include <utility> +#include <vector> +#include "base/bind.h" #include "base/memory/weak_ptr.h" +#include "base/stl_util.h" #include "base/supports_user_data.h" +#include "components/payments/content/android_app_communication.h" +#include "components/payments/content/android_payment_app.h" +#include "components/payments/content/payment_request_spec.h" +#include "components/payments/core/android_app_description.h" +#include "components/payments/core/android_app_description_tools.h" +#include "components/payments/core/method_strings.h" +#include "components/payments/core/native_error_strings.h" +#include "components/payments/core/payment_request_data_util.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_document_host_user_data.h" #include "content/public/browser/web_contents.h" namespace payments { @@ -34,17 +50,81 @@ AppFinder(const AppFinder& other) = delete; AppFinder& operator=(const AppFinder& other) = delete; - void FindApps(base::WeakPtr<PaymentAppFactory::Delegate> delegate) { + void FindApps(base::WeakPtr<AndroidAppCommunication> communication, + base::WeakPtr<PaymentAppFactory::Delegate> delegate) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_EQ(nullptr, delegate_.get()); DCHECK_NE(nullptr, delegate.get()); + DCHECK_EQ(nullptr, communication_.get()); + DCHECK_NE(nullptr, communication.get()); + DCHECK(delegate->GetSpec()->details().id.has_value()); delegate_ = delegate; + communication_ = communication; + + std::string twa_package_name = delegate_->GetTwaPackageName(); + std::set<std::string> twa_payment_method_names = { + methods::kGooglePlayBilling, + }; + if (twa_package_name.empty() || + base::STLSetIntersection<std::set<std::string>>( + delegate_->GetSpec()->payment_method_identifiers_set(), + twa_payment_method_names) + .empty()) { + OnDoneCreatingPaymentApps(); + return; + } + + communication_->GetAppDescriptions( + twa_package_name, base::BindOnce(&AppFinder::OnGetAppDescriptions, + weak_ptr_factory_.GetWeakPtr())); + } + + private: + void OnGetAppDescriptions( + const base::Optional<std::string>& error_message, + std::vector<std::unique_ptr<AndroidAppDescription>> app_descriptions) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // The browser could be shutting down. + if (!communication_ || !delegate_) + return; + + if (error_message.has_value()) { + delegate_->OnPaymentAppCreationError(error_message.value()); + OnDoneCreatingPaymentApps(); + return; + } + + std::vector<std::unique_ptr<AndroidAppDescription>> single_activity_apps; + for (size_t i = 0; i < app_descriptions.size(); ++i) { + auto app = std::move(app_descriptions[i]); + SplitPotentiallyMultipleActivities(std::move(app), &single_activity_apps); + } + + for (size_t i = 0; i < single_activity_apps.size(); ++i) { + auto app = std::move(single_activity_apps[i]); + + const std::string& default_method = + app->activities.front()->default_payment_method; + DCHECK_EQ(methods::kGooglePlayBilling, default_method); + + std::set<std::string> supported_payment_methods = {default_method}; + + delegate_->OnPaymentAppCreated(std::make_unique<AndroidPaymentApp>( + base::STLSetIntersection<std::set<std::string>>( + delegate_->GetSpec()->payment_method_identifiers_set(), + supported_payment_methods), + data_util::FilterStringifiedMethodData( + delegate_->GetSpec()->stringified_method_data(), + supported_payment_methods), + delegate_->GetTopOrigin(), delegate_->GetFrameOrigin(), + delegate_->GetSpec()->details().id.value(), std::move(app), + communication_)); + } OnDoneCreatingPaymentApps(); } - private: void OnDoneCreatingPaymentApps() { if (delegate_) delegate_->OnDoneCreatingPaymentApps(); @@ -54,20 +134,25 @@ base::SupportsUserData* owner_; base::WeakPtr<PaymentAppFactory::Delegate> delegate_; + base::WeakPtr<AndroidAppCommunication> communication_; base::WeakPtrFactory<AppFinder> weak_ptr_factory_{this}; }; } // namespace -AndroidPaymentAppFactory::AndroidPaymentAppFactory() - : PaymentAppFactory(PaymentApp::Type::NATIVE_MOBILE_APP) {} +AndroidPaymentAppFactory::AndroidPaymentAppFactory( + base::WeakPtr<AndroidAppCommunication> communication) + : PaymentAppFactory(PaymentApp::Type::NATIVE_MOBILE_APP), + communication_(communication) { + DCHECK(communication_); +} AndroidPaymentAppFactory::~AndroidPaymentAppFactory() = default; void AndroidPaymentAppFactory::Create(base::WeakPtr<Delegate> delegate) { auto app_finder = AppFinder::CreateAndSetOwnedBy(delegate->GetWebContents()); - app_finder->FindApps(delegate); + app_finder->FindApps(communication_, delegate); } } // namespace payments
diff --git a/components/payments/content/android_payment_app_factory.h b/components/payments/content/android_payment_app_factory.h index 0c8e8149..09b4df5 100644 --- a/components/payments/content/android_payment_app_factory.h +++ b/components/payments/content/android_payment_app_factory.h
@@ -5,14 +5,20 @@ #ifndef COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_APP_FACTORY_H_ #define COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_APP_FACTORY_H_ +#include "base/memory/weak_ptr.h" #include "components/payments/content/payment_app_factory.h" namespace payments { +class AndroidAppCommunication; + // Retrieves Android payment apps. class AndroidPaymentAppFactory : public PaymentAppFactory { public: - AndroidPaymentAppFactory(); + // The given |communication| is used for communication with Android payment + // apps. + explicit AndroidPaymentAppFactory( + base::WeakPtr<AndroidAppCommunication> communication); ~AndroidPaymentAppFactory() override; AndroidPaymentAppFactory(const AndroidPaymentAppFactory& other) = delete; @@ -21,6 +27,9 @@ // PaymentAppFactory: void Create(base::WeakPtr<Delegate> delegate) override; + + private: + base::WeakPtr<AndroidAppCommunication> communication_; }; } // namespace payments
diff --git a/components/payments/content/android_payment_app_factory_unittest.cc b/components/payments/content/android_payment_app_factory_unittest.cc new file mode 100644 index 0000000..70223e18 --- /dev/null +++ b/components/payments/content/android_payment_app_factory_unittest.cc
@@ -0,0 +1,367 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/payments/content/android_payment_app_factory.h" + +#include <utility> + +#include "base/memory/weak_ptr.h" +#include "base/stl_util.h" +#include "components/payments/content/android_app_communication.h" +#include "components/payments/content/android_app_communication_test_support.h" +#include "components/payments/content/payment_app_factory.h" +#include "components/payments/content/payment_manifest_web_data_service.h" +#include "components/payments/content/payment_request_spec.h" +#include "components/payments/core/android_app_description.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/test_web_contents_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace payments { +namespace { + +// A mock delegate for payment app factories. +class MockPaymentAppFactoryDelegate : public PaymentAppFactory::Delegate { + public: + explicit MockPaymentAppFactoryDelegate(content::BrowserContext* context) + : web_contents_(web_contents_factory_.CreateWebContents(context)), + top_origin_("https://top-origin.test"), + frame_origin_("https://frame-origin.test") { + SetRequestedPaymentMethod("https://play.google.com/billing"); + } + + ~MockPaymentAppFactoryDelegate() override = default; + + void SetRequestedPaymentMethod(const std::string& method) { + auto details = mojom::PaymentDetails::New(); + details->id = "id"; + + std::vector<mojom::PaymentMethodDataPtr> methods; + methods.emplace_back(mojom::PaymentMethodData::New()); + methods.back()->supported_method = method; + methods.back()->stringified_data = "{}"; + + spec_ = std::make_unique<PaymentRequestSpec>( + mojom::PaymentOptions::New(), std::move(details), std::move(methods), + /*observer=*/nullptr, /*app_locale=*/"en-US"); + } + + // PaymentAppFactory::Delegate implementation: + content::WebContents* GetWebContents() override { return web_contents_; } + const GURL& GetTopOrigin() override { return top_origin_; } + const GURL& GetFrameOrigin() override { return frame_origin_; } + MOCK_METHOD0(GetFrameSecurityOrigin, const url::Origin&()); + MOCK_CONST_METHOD0(GetInitiatorRenderFrameHost, content::RenderFrameHost*()); + MOCK_CONST_METHOD0(GetMethodData, + const std::vector<mojom::PaymentMethodDataPtr>&()); + MOCK_CONST_METHOD0(GetPaymentManifestWebDataService, + scoped_refptr<PaymentManifestWebDataService>()); + MOCK_METHOD0(MayCrawlForInstallablePaymentApps, bool()); + MOCK_CONST_METHOD0(IsOffTheRecord, bool()); + PaymentRequestSpec* GetSpec() const override { return spec_.get(); } + MOCK_CONST_METHOD0(GetTwaPackageName, std::string()); + MOCK_METHOD0(ShowProcessingSpinner, void()); + MOCK_METHOD0(GetBillingProfiles, + const std::vector<autofill::AutofillProfile*>&()); + MOCK_METHOD0(IsRequestedAutofillDataAvailable, bool()); + MOCK_CONST_METHOD0(GetPaymentRequestDelegate, + ContentPaymentRequestDelegate*()); + MOCK_METHOD1(OnPaymentAppCreated, void(std::unique_ptr<PaymentApp> app)); + MOCK_METHOD1(OnPaymentAppCreationError, + void(const std::string& error_message)); + MOCK_CONST_METHOD0(SkipCreatingNativePaymentApps, bool()); + MOCK_METHOD0(OnDoneCreatingPaymentApps, void()); + + base::WeakPtr<PaymentAppFactory::Delegate> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + content::TestWebContentsFactory web_contents_factory_; + content::WebContents* web_contents_; + GURL top_origin_; + GURL frame_origin_; + std::unique_ptr<PaymentRequestSpec> spec_; + base::WeakPtrFactory<PaymentAppFactory::Delegate> weak_ptr_factory_{this}; +}; + +// The scaffolding for testing the Android payment app factory. +class AndroidPaymentAppFactoryTest : public testing::Test { + public: + AndroidPaymentAppFactoryTest() + : support_(AndroidAppCommunicationTestSupport::Create()), + delegate_(support_->context()), + factory_(GetCommunication(support_->context())) {} + + std::unique_ptr<AndroidAppCommunicationTestSupport> support_; + MockPaymentAppFactoryDelegate delegate_; + AndroidPaymentAppFactory factory_; + + private: + // Returns the Android app communication that can be used in unit tests. + static base::WeakPtr<AndroidAppCommunication> GetCommunication( + content::BrowserContext* context) { + base::WeakPtr<AndroidAppCommunication> communication = + AndroidAppCommunication::GetForBrowserContext(context); + communication->SetForTesting(); + return communication; + } +}; + +// The payment app factory should return an error if it's unable to invoke +// Aneroid payment apps on a platform that supports such apps, e.g, when ARC is +// disabled on Chrome OS. +TEST_F(AndroidPaymentAppFactoryTest, FactoryReturnsErrorWithoutArc) { + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.example.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + + EXPECT_CALL(delegate_, + OnPaymentAppCreationError("Unable to invoke Android apps.")) + .Times(support_->AreAndroidAppsSupportedOnThisPlatform() ? 1 : 0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(testing::_)).Times(0); + support_->ExpectNoListOfPaymentAppsQuery(); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// The payment app factory should not return any errors when there're no Android +// payment apps available. +TEST_F(AndroidPaymentAppFactoryTest, NoErrorsWhenNoApps) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.example.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(testing::_)).Times(0); + support_->ExpectQueryListOfPaymentAppsAndRespond({}); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// The |arg| is of type std::unique_ptr<PaymentApp>. +MATCHER_P3(PaymentAppMatches, type, package, method, "") { + return arg->type() == type && arg->GetId() == package && + base::Contains(arg->GetAppMethodNames(), method); +} + +// The payment app factory should return the TWA payment app when running in TWA +// mode. +TEST_F(AndroidPaymentAppFactoryTest, FindTheTwaPaymentAppInTwaMode) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.twa.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + + EXPECT_CALL(delegate_, OnPaymentAppCreated(PaymentAppMatches( + PaymentApp::Type::NATIVE_MOBILE_APP, "com.twa.app", + "https://play.google.com/billing"))) + .Times(support_->AreAndroidAppsSupportedOnThisPlatform() ? 1 : 0); + + std::vector<std::unique_ptr<AndroidAppDescription>> apps; + apps.emplace_back(std::make_unique<AndroidAppDescription>()); + apps.back()->package = "com.twa.app"; + apps.back()->service_names.push_back("com.twa.app.Service"); + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.twa.app.Activity"; + apps.back()->activities.back()->default_payment_method = + "https://play.google.com/billing"; + support_->ExpectQueryListOfPaymentAppsAndRespond(std::move(apps)); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// The payment app factory should return the correct TWA payment app out of two +// installed payment apps, when running in TWA mode. +TEST_F(AndroidPaymentAppFactoryTest, FindTheCorrectTwaAppInTwaMode) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.correct-twa.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + + EXPECT_CALL(delegate_, + OnPaymentAppCreated(PaymentAppMatches( + PaymentApp::Type::NATIVE_MOBILE_APP, "com.correct-twa.app", + "https://play.google.com/billing"))) + .Times(support_->AreAndroidAppsSupportedOnThisPlatform() ? 1 : 0); + EXPECT_CALL(delegate_, + OnPaymentAppCreated(PaymentAppMatches( + PaymentApp::Type::NATIVE_MOBILE_APP, "com.different.app", + "https://play.google.com/billing"))) + .Times(0); + + std::vector<std::unique_ptr<AndroidAppDescription>> apps; + apps.emplace_back(std::make_unique<AndroidAppDescription>()); + apps.back()->package = "com.correct-twa.app"; + apps.back()->service_names.push_back("com.correct-twa.app.Service"); + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.correct-twa.app.Activity"; + apps.back()->activities.back()->default_payment_method = + "https://play.google.com/billing"; + + apps.emplace_back(std::make_unique<AndroidAppDescription>()); + apps.back()->package = "com.different.app"; + apps.back()->service_names.push_back("com.different.app.Service"); + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.different.app.Activity"; + apps.back()->activities.back()->default_payment_method = + "https://play.google.com/billing"; + + support_->ExpectQueryListOfPaymentAppsAndRespond(std::move(apps)); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// The payment app factory does not return non-TWA payment apps when running in +// TWA mode. +TEST_F(AndroidPaymentAppFactoryTest, IgnoreNonTwaAppsInTwaMode) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.twa.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(testing::_)).Times(0); + + std::vector<std::unique_ptr<AndroidAppDescription>> apps; + apps.emplace_back(std::make_unique<AndroidAppDescription>()); + apps.back()->package = "com.non-twa.app"; + apps.back()->service_names.push_back("com.non-twa.app.Service"); + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.non-twa.app.Activity"; + apps.back()->activities.back()->default_payment_method = + "https://play.google.com/billing"; + support_->ExpectQueryListOfPaymentAppsAndRespond(std::move(apps)); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// The payment app factory does not return any payment apps when not running +// inside of TWA. +TEST_F(AndroidPaymentAppFactoryTest, DoNotLookForAppsWhenOutsideOfTwaMode) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(testing::_)).Times(0); + support_->ExpectNoListOfPaymentAppsQuery(); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// The Android payment app factory works only with TWA specific payment methods. +TEST_F(AndroidPaymentAppFactoryTest, DoNotLookForAppsForNonTwaMethod) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + // "https://example.test" is not a TWA specific payment method. + delegate_.SetRequestedPaymentMethod("https://example.test"); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.example.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(testing::_)).Times(0); + support_->ExpectNoListOfPaymentAppsQuery(); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// If the TWA supports a non-TWA-specific payment method, then it should be +// ignored. +TEST_F(AndroidPaymentAppFactoryTest, IgnoreNonTwaMethodInTheTwa) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.twa.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(testing::_)).Times(0); + + std::vector<std::unique_ptr<AndroidAppDescription>> apps; + apps.emplace_back(std::make_unique<AndroidAppDescription>()); + apps.back()->package = "com.twa.app"; + apps.back()->service_names.push_back("com.twa.app.Service"); + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.twa.app.Activity"; + apps.back()->activities.back()->default_payment_method = + "https://example.test"; + support_->ExpectQueryListOfPaymentAppsAndRespond(std::move(apps)); + + factory_.Create(delegate_.GetWeakPtr()); +} + +// If the TWA supports both a TWA-specific and a non-TWA-specific payment +// method, then only the TWA-specific payment method activity should be +// returned. +TEST_F(AndroidPaymentAppFactoryTest, + FindOnlyActivitiesWithTwaSpecificMethodName) { + // Enable invoking Android payment apps on those platforms that support it. + auto scoped_initialization_ = support_->CreateScopedInitialization(); + + EXPECT_CALL(delegate_, GetTwaPackageName()) + .WillRepeatedly(testing::Return("com.twa.app")); + EXPECT_CALL(delegate_, OnDoneCreatingPaymentApps()); + EXPECT_CALL(delegate_, OnPaymentAppCreationError(testing::_)).Times(0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(PaymentAppMatches( + PaymentApp::Type::NATIVE_MOBILE_APP, "com.twa.app", + "https://play.google.com/billing"))) + .Times(support_->AreAndroidAppsSupportedOnThisPlatform() ? 1 : 0); + EXPECT_CALL(delegate_, OnPaymentAppCreated(PaymentAppMatches( + PaymentApp::Type::NATIVE_MOBILE_APP, "com.twa.app", + "https://example.test"))) + .Times(0); + + std::vector<std::unique_ptr<AndroidAppDescription>> apps; + apps.emplace_back(std::make_unique<AndroidAppDescription>()); + apps.back()->package = "com.twa.app"; + apps.back()->service_names.push_back("com.twa.app.Service"); + + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.twa.app.ActivityOne"; + apps.back()->activities.back()->default_payment_method = + "https://play.google.com/billing"; + + apps.back()->activities.emplace_back( + std::make_unique<AndroidActivityDescription>()); + apps.back()->activities.back()->name = "com.twa.app.ActivityTwo"; + apps.back()->activities.back()->default_payment_method = + "https://example.test"; + + support_->ExpectQueryListOfPaymentAppsAndRespond(std::move(apps)); + + factory_.Create(delegate_.GetWeakPtr()); +} + +} // namespace +} // namespace payments
diff --git a/components/payments/content/payment_app_service.cc b/components/payments/content/payment_app_service.cc index 94c35c9..74b89137 100644 --- a/components/payments/content/payment_app_service.cc +++ b/components/payments/content/payment_app_service.cc
@@ -5,6 +5,7 @@ #include "components/payments/content/payment_app_service.h" #include "base/feature_list.h" +#include "components/payments/content/android_app_communication.h" #include "components/payments/content/android_payment_app_factory.h" #include "components/payments/content/autofill_payment_app_factory.h" #include "components/payments/content/payment_app.h" @@ -15,7 +16,7 @@ namespace payments { -PaymentAppService::PaymentAppService() { +PaymentAppService::PaymentAppService(content::BrowserContext* context) { factories_.emplace_back(std::make_unique<AutofillPaymentAppFactory>()); if (base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps)) { @@ -27,7 +28,8 @@ // apps. (Currently it works only on Chrome OS with app store billing payment // methods.) if (PaymentsExperimentalFeatures::IsEnabled(features::kAppStoreBilling)) { - factories_.emplace_back(std::make_unique<AndroidPaymentAppFactory>()); + factories_.emplace_back(std::make_unique<AndroidPaymentAppFactory>( + AndroidAppCommunication::GetForBrowserContext(context))); } }
diff --git a/components/payments/content/payment_app_service.h b/components/payments/content/payment_app_service.h index a26ce3e..40f1c18 100644 --- a/components/payments/content/payment_app_service.h +++ b/components/payments/content/payment_app_service.h
@@ -14,12 +14,17 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/payments/content/payment_app_factory.h" +namespace content { +class BrowserContext; +} // namespace content + namespace payments { // Retrieves payment apps of all types. class PaymentAppService : public KeyedService { public: - PaymentAppService(); + // The |context| pointer is not being saved. + explicit PaymentAppService(content::BrowserContext* context); ~PaymentAppService() override; // Returns the number of payment app factories, which is the number of times
diff --git a/components/payments/content/payment_app_service_factory.cc b/components/payments/content/payment_app_service_factory.cc index 3fb5f94..686ac505 100644 --- a/components/payments/content/payment_app_service_factory.cc +++ b/components/payments/content/payment_app_service_factory.cc
@@ -43,7 +43,7 @@ KeyedService* PaymentAppServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - return new PaymentAppService(); + return new PaymentAppService(context); } content::BrowserContext* PaymentAppServiceFactory::GetBrowserContextToUse(
diff --git a/components/payments/content/payment_request_state_unittest.cc b/components/payments/content/payment_request_state_unittest.cc index 6cfc72c6d..1f910a9 100644 --- a/components/payments/content/payment_request_state_unittest.cc +++ b/components/payments/content/payment_request_state_unittest.cc
@@ -78,7 +78,7 @@ std::move(options), std::move(details), std::move(method_data), /*observer=*/nullptr, "en-US"); PaymentAppServiceFactory::SetForTesting( - std::make_unique<PaymentAppService>()); + std::make_unique<PaymentAppService>(/*context=*/nullptr)); state_ = std::make_unique<PaymentRequestState>( /*web_contents=*/nullptr, /*render_frame_host=*/nullptr, GURL("https://example.com"),
diff --git a/components/performance_manager/graph/policies/tab_loading_frame_navigation_policy_unittest.cc b/components/performance_manager/graph/policies/tab_loading_frame_navigation_policy_unittest.cc index 262cf8ed..1027ffe 100644 --- a/components/performance_manager/graph/policies/tab_loading_frame_navigation_policy_unittest.cc +++ b/components/performance_manager/graph/policies/tab_loading_frame_navigation_policy_unittest.cc
@@ -165,8 +165,7 @@ double GetRelativeTime() { base::TimeTicks now = task_environment()->GetMockTickClock()->NowTicks(); base::TimeDelta elapsed = now - start_; - double relative = - elapsed.InSecondsF() / policy_->GetMaxTimeoutForTesting().InSecondsF(); + double relative = elapsed / policy_->GetMaxTimeoutForTesting(); return relative; }
diff --git a/components/services/app_service/public/cpp/app_update_unittest.cc b/components/services/app_service/public/cpp/app_update_unittest.cc index 2d8984bd..4b5bdb4 100644 --- a/components/services/app_service/public/cpp/app_update_unittest.cc +++ b/components/services/app_service/public/cpp/app_update_unittest.cc
@@ -714,17 +714,15 @@ auto scheme_condition = apps_util::MakeCondition(apps::mojom::ConditionType::kScheme, std::move(scheme_condition_values)); - intent_filter->conditions.push_back(std::move(scheme_condition)); std::vector<apps::mojom::ConditionValuePtr> host_condition_values; host_condition_values.push_back(apps_util::MakeConditionValue( "www.google.com", apps::mojom::PatternMatchType::kNone)); auto host_condition = apps_util::MakeCondition( apps::mojom::ConditionType::kHost, std::move(host_condition_values)); - intent_filter->conditions.push_back(std::move(host_condition)); - intent_filter->conditions.push_back(scheme_condition.Clone()); - intent_filter->conditions.push_back(host_condition.Clone()); + intent_filter->conditions.push_back(std::move(scheme_condition)); + intent_filter->conditions.push_back(std::move(host_condition)); state->intent_filters.push_back(intent_filter.Clone()); expect_intent_filters_.push_back(intent_filter.Clone());
diff --git a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc index dbb5f85..9716fa95 100644 --- a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
@@ -1996,7 +1996,7 @@ for (int i = 0; i < 10000; ++i) { base::Time result = ComputeLastPollOnStart(last_poll, poll_interval, now); base::TimeDelta delay = result + poll_interval - now; - double fraction = delay.InSeconds() * 1.0 / poll_interval.InSeconds(); + double fraction = delay / poll_interval; if (fraction > 0.005) { found_delay_greater_than_5_permille = true; } else {
diff --git a/components/test/data/payments/app_store_billing_tests/index.js b/components/test/data/payments/app_store_billing_tests/index.js index 91917f0..5e7f528c 100644 --- a/components/test/data/payments/app_store_billing_tests/index.js +++ b/components/test/data/payments/app_store_billing_tests/index.js
@@ -70,6 +70,21 @@ } /** + * Check whether payments can be made. + * @return {string} - "true", "false", or an error message. + */ +async function canMakePayment() { // eslint-disable-line no-unused-vars + info('canMakePayment'); + try { + const result = await request.canMakePayment(); + return (result ? 'true' : 'false'); + } catch (e) { + info('canMakePayment error: ' + e.toString()); + return e.toString(); + } +} + +/** * Show the payment sheet. * @return {string} - a message indicating whether the operation is successful. */
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 95266be9..2bc03a5 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -1315,7 +1315,8 @@ // The subscription to the notification of the changing of the render // process's blocked state. - std::unique_ptr<base::CallbackList<void(bool)>::Subscription> + std::unique_ptr< + RenderProcessHost::BlockStateChangedCallbackList::Subscription> render_process_blocked_state_changed_subscription_; // The headers used for the request. The value of this comes from
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc index f510f16..9667209 100644 --- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -3609,7 +3609,6 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, CheckIsCurrentBeforeAndAfterUnload) { IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess()); - std::string onunload_script = "window.onunload = function(){ while(1);}"; GURL url_ab(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b)")); GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html")); @@ -3638,11 +3637,6 @@ EXPECT_FALSE(rfh_a->IsCurrent()); EXPECT_FALSE(rfh_b->IsCurrent()); EXPECT_TRUE(rfh_c->IsCurrent()); - - // 6) Resume deletion on rfh_b and run detach on rfh_b to delete its frame. - EXPECT_FALSE(delete_rfh_b.deleted()); - rfh_b->DetachForTesting(); - EXPECT_TRUE(delete_rfh_b.deleted()); } // Test the LifecycleState is updated correctly for the main frame during
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index e31ae09d..f659e68 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -33,6 +33,7 @@ #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h" #include "content/browser/media/media_devices_permission_checker.h" +#include "content/browser/permissions/permission_controller_impl.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h" #include "content/browser/renderer_host/media/audio_service_listener.h" #include "content/browser/renderer_host/media/in_process_video_capture_provider.h" @@ -667,6 +668,10 @@ std::string tab_capture_device_id; + int audio_subscription_id = PermissionControllerImpl::kNoPendingOperation; + + int video_subscription_id = PermissionControllerImpl::kNoPendingOperation; + private: std::vector<MediaRequestState> state_; std::unique_ptr<MediaStreamRequest> ui_request_; @@ -1319,7 +1324,18 @@ for (auto request_it = requests_.begin(); request_it != requests_.end(); ++request_it) { if (request_it->first == label) { + // Clean up permission controller subscription. + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&MediaStreamManager:: + UnsubscribeFromPermissionControllerOnUIThread, + request_it->second->requesting_process_id, + request_it->second->requesting_frame_id, + request_it->second->audio_subscription_id, + request_it->second->video_subscription_id)); + requests_.erase(request_it); + return; } } @@ -1762,6 +1778,19 @@ NOTREACHED(); } + // Subscribe to follow permission changes in order to close streams when the + // user denies mic/camera. + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop. + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + &MediaStreamManager::SubscribeToPermissionControllerOnUIThread, + base::Unretained(this), label, request->requesting_process_id, + request->requesting_frame_id, request->requester_id, + request->page_request_id, audio_devices.size() > 0, + video_devices.size() > 0, request->salt_and_origin.origin.GetURL())); + // It is safe to bind base::Unretained(this) because MediaStreamManager is // owned by BrowserMainLoop and so outlives the IO thread. GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( @@ -2614,4 +2643,144 @@ } } +// static +PermissionControllerImpl* MediaStreamManager::GetPermissionController( + int requesting_process_id, + int requesting_frame_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + RenderFrameHost* rfh = + RenderFrameHost::FromID(requesting_process_id, requesting_frame_id); + if (!rfh) + return nullptr; + + return PermissionControllerImpl::FromBrowserContext(rfh->GetBrowserContext()); +} + +void MediaStreamManager::SubscribeToPermissionControllerOnUIThread( + const std::string& label, + int requesting_process_id, + int requesting_frame_id, + int requester_id, + int page_request_id, + bool is_audio_request, + bool is_video_request, + const GURL& origin) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + PermissionControllerImpl* controller = + GetPermissionController(requesting_process_id, requesting_frame_id); + if (!controller) + return; + + int audio_subscription_id = PermissionControllerImpl::kNoPendingOperation; + int video_subscription_id = PermissionControllerImpl::kNoPendingOperation; + + if (is_audio_request) { + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop. + audio_subscription_id = controller->SubscribePermissionStatusChange( + PermissionType::AUDIO_CAPTURE, + RenderFrameHost::FromID(requesting_process_id, requesting_frame_id), + origin, + base::BindRepeating(&MediaStreamManager::PermissionChangedCallback, + base::Unretained(this), requesting_process_id, + requesting_frame_id, requester_id, + page_request_id)); + } + + if (is_video_request) { + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop. + video_subscription_id = controller->SubscribePermissionStatusChange( + PermissionType::VIDEO_CAPTURE, + RenderFrameHost::FromID(requesting_process_id, requesting_frame_id), + origin, + base::BindRepeating(&MediaStreamManager::PermissionChangedCallback, + base::Unretained(this), requesting_process_id, + requesting_frame_id, requester_id, + page_request_id)); + } + + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop. + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&MediaStreamManager::SetPermissionSubscriptionIDs, + base::Unretained(this), label, requesting_process_id, + requesting_frame_id, audio_subscription_id, + video_subscription_id)); +} + +void MediaStreamManager::SetPermissionSubscriptionIDs( + const std::string& label, + int requesting_process_id, + int requesting_frame_id, + int audio_subscription_id, + int video_subscription_id) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + DeviceRequest* const request = FindRequest(label); + if (!request) { + // Something happened with the request while the permission subscription was + // created, unsubscribe to clean up. + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop. + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + &MediaStreamManager::UnsubscribeFromPermissionControllerOnUIThread, + requesting_process_id, requesting_frame_id, audio_subscription_id, + video_subscription_id)); + + return; + } + + request->audio_subscription_id = audio_subscription_id; + request->video_subscription_id = video_subscription_id; +} + +// static +void MediaStreamManager::UnsubscribeFromPermissionControllerOnUIThread( + int requesting_process_id, + int requesting_frame_id, + int audio_subscription_id, + int video_subscription_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + PermissionControllerImpl* controller = + GetPermissionController(requesting_process_id, requesting_frame_id); + if (!controller) + return; + + controller->UnsubscribePermissionStatusChange(audio_subscription_id); + controller->UnsubscribePermissionStatusChange(video_subscription_id); +} + +void MediaStreamManager::PermissionChangedCallback( + int requesting_process_id, + int requesting_frame_id, + int requester_id, + int page_request_id, + blink::mojom::PermissionStatus status) { + if (status == blink::mojom::PermissionStatus::GRANTED) + return; + + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + // It is safe to bind base::Unretained(this) because MediaStreamManager is + // owned by BrowserMainLoop. + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&MediaStreamManager::PermissionChangedCallback, + base::Unretained(this), requesting_process_id, + requesting_frame_id, requester_id, page_request_id, + status)); + + return; + } + + CancelRequest(requesting_process_id, requesting_frame_id, requester_id, + page_request_id); +} + } // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h index 4d1e4877..045e5f5 100644 --- a/content/browser/renderer_host/media/media_stream_manager.h +++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -55,6 +55,7 @@ #include "third_party/blink/public/common/mediastream/media_stream_controls.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" namespace media { class AudioSystem; @@ -72,6 +73,7 @@ class MediaStreamUIProxy; class VideoCaptureManager; class VideoCaptureProvider; +class PermissionControllerImpl; // MediaStreamManager is used to generate and close new media devices, not to // start the media flow. The classes requesting new media streams are answered @@ -534,6 +536,48 @@ // Activate the specified tab and bring it to the front. void ActivateTabOnUIThread(const DesktopMediaID source); + // Get the permission controller for a particular RFH. Must be called on the + // UI thread. + static PermissionControllerImpl* GetPermissionController( + int requesting_process_id, + int requesting_frame_id); + + // Subscribe to the permission controller in order to monitor camera/mic + // permission updates for a particular DeviceRequest. All the additional + // information is needed because `FindRequest` can't be called on the UI + // thread. + void SubscribeToPermissionControllerOnUIThread(const std::string& label, + int requesting_process_id, + int requesting_frame_id, + int requester_id, + int page_request_id, + bool is_audio_request, + bool is_video_request, + const GURL& origin); + + // Store the subscription ids on a DeviceRequest in order to allow + // unsubscribing when the request is deleted. + void SetPermissionSubscriptionIDs(const std::string& label, + int requesting_process_id, + int requesting_frame_id, + int audio_subscription_id, + int video_subscription_id); + + // Unsubscribe from following permission updates for the two specified + // subscription IDs. Called when a request is deleted. + static void UnsubscribeFromPermissionControllerOnUIThread( + int requesting_process_id, + int requesting_frame_id, + int audio_subscription_id, + int video_subscription_id); + + // Callback that the PermissionController calls when a permission is updated. + void PermissionChangedCallback(int requesting_process_id, + int requesting_frame_id, + int requester_id, + int page_request_id, + blink::mojom::PermissionStatus status); + media::AudioSystem* const audio_system_; // not owned scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_; scoped_refptr<VideoCaptureManager> video_capture_manager_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index f3aab35..b8a3489 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3763,9 +3763,9 @@ return is_blocked_; } -std::unique_ptr<base::CallbackList<void(bool)>::Subscription> +std::unique_ptr<RenderProcessHost::BlockStateChangedCallbackList::Subscription> RenderProcessHostImpl::RegisterBlockStateChangedCallback( - const base::RepeatingCallback<void(bool)>& cb) { + const BlockStateChangedCallback& cb) { return blocked_state_changed_callback_list_.Add(cb); }
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index e372136..7ee16a2 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -213,7 +213,7 @@ bool IsBlocked() override; std::unique_ptr<base::CallbackList<void(bool)>::Subscription> RegisterBlockStateChangedCallback( - const base::RepeatingCallback<void(bool)>& cb) override; + const BlockStateChangedCallback& cb) override; void Cleanup() override; void AddPendingView() override; void RemovePendingView() override; @@ -1107,7 +1107,7 @@ bool is_blocked_; // The clients who want to know when the blocked state has changed. - base::CallbackList<void(bool)> blocked_state_changed_callback_list_; + BlockStateChangedCallbackList blocked_state_changed_callback_list_; // Records the last time we regarded the child process active. base::TimeTicks child_process_activity_time_;
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index ec4696ba..69f8a41 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -1246,7 +1246,8 @@ base::OneShotTimer input_event_ack_timeout_; base::TimeTicks input_event_ack_start_time_; - std::unique_ptr<base::CallbackList<void(bool)>::Subscription> + std::unique_ptr< + RenderProcessHost::BlockStateChangedCallbackList::Subscription> render_process_blocked_state_changed_subscription_; std::unique_ptr<TimeoutMonitor> new_content_rendering_timeout_;
diff --git a/content/common/page_state_serialization.cc b/content/common/page_state_serialization.cc index 1d92376..1be78a3 100644 --- a/content/common/page_state_serialization.cc +++ b/content/common/page_state_serialization.cc
@@ -710,6 +710,7 @@ break; case network::mojom::DataElementType::kRawFile: case network::mojom::DataElementType::kChunkedDataPipe: + case network::mojom::DataElementType::kReadOnceStream: case network::mojom::DataElementType::kUnknown: NOTREACHED(); continue;
diff --git a/content/common/widget_messages.h b/content/common/widget_messages.h index 43dd821..a542ee4 100644 --- a/content/common/widget_messages.h +++ b/content/common/widget_messages.h
@@ -71,12 +71,6 @@ IPC_MESSAGE_ROUTED1(WidgetMsg_SetViewportIntersection, blink::ViewportIntersectionState /* intersection_state */) - -// Sent by the browser to synchronize with the next compositor frame by -// requesting an ACK be queued. Used only for tests. -IPC_MESSAGE_ROUTED1(WidgetMsg_WaitForNextFrameForTests, - int /* main_frame_thread_observer_routing_id */) - // // Renderer -> Browser Messages. // @@ -105,7 +99,4 @@ // Close message. IPC_MESSAGE_CONTROL1(WidgetHostMsg_Close_ACK, int /* old_route_id */) -// Sent in reply to WidgetMsg_WaitForNextFrameForTests. -IPC_MESSAGE_ROUTED0(WidgetHostMsg_WaitForNextFrameForTests_ACK) - #endif // CONTENT_COMMON_WIDGET_MESSAGES_H_
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 8f613aa..cf488c3 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -284,9 +284,10 @@ virtual void SetBlocked(bool blocked) = 0; virtual bool IsBlocked() = 0; - virtual std::unique_ptr<base::CallbackList<void(bool)>::Subscription> - RegisterBlockStateChangedCallback( - const base::RepeatingCallback<void(bool)>& cb) = 0; + using BlockStateChangedCallbackList = base::RepeatingCallbackList<void(bool)>; + using BlockStateChangedCallback = BlockStateChangedCallbackList::CallbackType; + virtual std::unique_ptr<BlockStateChangedCallbackList::Subscription> + RegisterBlockStateChangedCallback(const BlockStateChangedCallback& cb) = 0; // Schedules the host for deletion and removes it from the all_hosts list. virtual void Cleanup() = 0;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index ac9260776..ce67fb60 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -2641,40 +2641,25 @@ MainThreadFrameObserver::MainThreadFrameObserver( RenderWidgetHost* render_widget_host) : render_widget_host_(render_widget_host), - routing_id_(render_widget_host_->GetProcess()->GetNextRoutingID()) { - // TODO(lfg): We should look into adding a way to observe RenderWidgetHost - // messages similarly to what WebContentsObserver can do with RFH and RVW. - render_widget_host_->GetProcess()->AddRoute(routing_id_, this); -} + routing_id_(render_widget_host_->GetProcess()->GetNextRoutingID()) {} -MainThreadFrameObserver::~MainThreadFrameObserver() { - render_widget_host_->GetProcess()->RemoveRoute(routing_id_); -} +MainThreadFrameObserver::~MainThreadFrameObserver() = default; void MainThreadFrameObserver::Wait() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - render_widget_host_->Send(new WidgetMsg_WaitForNextFrameForTests( - render_widget_host_->GetRoutingID(), routing_id_)); + static_cast<RenderWidgetHostImpl*>(render_widget_host_) + ->InsertVisualStateCallback(base::BindOnce(&MainThreadFrameObserver::Quit, + base::Unretained(this))); base::RunLoop run_loop; quit_closure_ = run_loop.QuitClosure(); run_loop.Run(); } -void MainThreadFrameObserver::Quit() { +void MainThreadFrameObserver::Quit(bool) { if (quit_closure_) std::move(quit_closure_).Run(); } -bool MainThreadFrameObserver::OnMessageReceived(const IPC::Message& msg) { - if (msg.type() == WidgetHostMsg_WaitForNextFrameForTests_ACK::ID && - msg.routing_id() == routing_id_) { - GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&MainThreadFrameObserver::Quit, base::Unretained(this))); - } - return true; -} - InputMsgWatcher::InputMsgWatcher(RenderWidgetHost* render_widget_host, blink::WebInputEvent::Type type) : render_widget_host_(render_widget_host),
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index a4164d5..853008a1 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -1313,20 +1313,17 @@ // So while the ACK can arrive before a CompositorFrame submission occurs. The // processing does not occur until after the FrameToken for that frame // submission arrives to the main thread. -class MainThreadFrameObserver : public IPC::Listener { +class MainThreadFrameObserver { public: explicit MainThreadFrameObserver(RenderWidgetHost* render_widget_host); - ~MainThreadFrameObserver() override; + ~MainThreadFrameObserver(); // Synchronizes the browser main thread with the renderer main thread and impl // thread. void Wait(); - // Overridden IPC::Listener methods. - bool OnMessageReceived(const IPC::Message& msg) override; - private: - void Quit(); + void Quit(bool); RenderWidgetHost* render_widget_host_; base::OnceClosure quit_closure_;
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index d8f2b4f3..7e10cc4 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -261,9 +261,9 @@ return false; } -std::unique_ptr<base::CallbackList<void(bool)>::Subscription> +std::unique_ptr<RenderProcessHost::BlockStateChangedCallbackList::Subscription> MockRenderProcessHost::RegisterBlockStateChangedCallback( - const base::RepeatingCallback<void(bool)>& cb) { + const BlockStateChangedCallback& cb) { return nullptr; }
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 11e468e..994e712 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -112,9 +112,9 @@ bool IsInitializedAndNotDead() override; void SetBlocked(bool blocked) override; bool IsBlocked() override; - std::unique_ptr<base::CallbackList<void(bool)>::Subscription> + std::unique_ptr<BlockStateChangedCallbackList::Subscription> RegisterBlockStateChangedCallback( - const base::RepeatingCallback<void(bool)>& cb) override; + const BlockStateChangedCallback& cb) override; void Cleanup() override; void AddPendingView() override; void RemovePendingView() override;
diff --git a/content/renderer/loader/web_url_request_util.cc b/content/renderer/loader/web_url_request_util.cc index 3bcd58f..155d9a4b 100644 --- a/content/renderer/loader/web_url_request_util.cc +++ b/content/renderer/loader/web_url_request_util.cc
@@ -147,6 +147,7 @@ case network::mojom::DataElementType::kUnknown: case network::mojom::DataElementType::kRawFile: case network::mojom::DataElementType::kChunkedDataPipe: + case network::mojom::DataElementType::kReadOnceStream: NOTREACHED(); break; }
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 0c637e3b..7e336ad 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -434,8 +434,6 @@ IPC_MESSAGE_HANDLER(WidgetMsg_SetBounds_ACK, OnRequestSetBoundsAck) IPC_MESSAGE_HANDLER(WidgetMsg_SetViewportIntersection, OnSetViewportIntersection) - IPC_MESSAGE_HANDLER(WidgetMsg_WaitForNextFrameForTests, - OnWaitNextFrameForTests) IPC_MESSAGE_HANDLER(DragMsg_TargetDragEnter, OnDragTargetDragEnter) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -1523,13 +1521,6 @@ render_frames_.RemoveObserver(frame); } -void RenderWidget::OnWaitNextFrameForTests( - int main_frame_thread_observer_routing_id) { - // Sends an ACK to the browser process during the next compositor frame. - QueueMessage(std::make_unique<WidgetHostMsg_WaitForNextFrameForTests_ACK>( - main_frame_thread_observer_routing_id)); -} - const blink::ScreenInfo& RenderWidget::GetOriginalScreenInfo() const { if (device_emulator_) return device_emulator_->original_screen_info();
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 49d12393..5e8bf6f 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -454,7 +454,6 @@ const gfx::PointF& screen_point, blink::WebDragOperation drag_operation); void OnOrientationChange(); - void OnWaitNextFrameForTests(int routing_id); // Sets the "hidden" state of this widget. All modification of is_hidden_ // should use this method so that we can properly inform the RenderThread of
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 778d3609..f0760bc 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -368,7 +368,7 @@ "dependencies": ["manifest:mime_types_handler"], "contexts": ["blessed_extension"] }, - "mojoPrivate": { + "mojoPrivate": [{ "contexts": ["blessed_extension"], "channel": "stable", "extension_types": ["platform_app", "extension"], @@ -378,7 +378,13 @@ "B41E7F08E1179CC03CBD1F49E57CF353A40ADE07", // Chrome Camera App Dev "A3E3DE9E9F16B41D4A2FAD106BD6CA76B94A0C94" // Chrome Camera App Stable ] - }, + }, { + "contexts": ["blessed_extension"], + "dependencies": ["behavior:imprivata_in_session_extension"], + "extension_types": ["extension"], + "location": "policy", + "platforms": ["chromeos"] + }], "networking.config": { "dependencies": ["permission:networking.config"], "contexts": ["blessed_extension"]
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 4c828e8..c7ca3b8 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -752,6 +752,7 @@ {"keep_alive", IDR_KEEP_ALIVE_JS}, {"mojo_bindings", IDR_MOJO_MOJO_BINDINGS_JS}, + {"mojo_bindings_lite", IDR_MOJO_MOJO_BINDINGS_LITE_JS}, {"extensions/common/mojom/keep_alive.mojom", IDR_KEEP_ALIVE_MOJOM_JS}, // Custom bindings.
diff --git a/fuchsia/engine/browser/accessibility_bridge.cc b/fuchsia/engine/browser/accessibility_bridge.cc index d2b9ec5..a7d4106 100644 --- a/fuchsia/engine/browser/accessibility_bridge.cc +++ b/fuchsia/engine/browser/accessibility_bridge.cc
@@ -27,7 +27,7 @@ } // namespace AccessibilityBridge::AccessibilityBridge( - fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager, + fuchsia::accessibility::semantics::SemanticsManager* semantics_manager, fuchsia::ui::views::ViewRef view_ref, content::WebContents* web_contents, base::OnceCallback<void(zx_status_t)> on_error_callback)
diff --git a/fuchsia/engine/browser/accessibility_bridge.h b/fuchsia/engine/browser/accessibility_bridge.h index 1528651..8165b12 100644 --- a/fuchsia/engine/browser/accessibility_bridge.h +++ b/fuchsia/engine/browser/accessibility_bridge.h
@@ -38,9 +38,10 @@ public fuchsia::accessibility::semantics::SemanticListener, public ui::AXTreeObserver { public: + // |semantics_manager| is used during construction to register the instance. // |web_contents| is required to exist for the duration of |this|. AccessibilityBridge( - fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager, + fuchsia::accessibility::semantics::SemanticsManager* semantics_manager, fuchsia::ui::views::ViewRef view_ref, content::WebContents* web_contents, base::OnceCallback<void(zx_status_t)> on_error_callback);
diff --git a/fuchsia/engine/browser/accessibility_bridge_browsertest.cc b/fuchsia/engine/browser/accessibility_bridge_browsertest.cc index c26862f..5375922c 100644 --- a/fuchsia/engine/browser/accessibility_bridge_browsertest.cc +++ b/fuchsia/engine/browser/accessibility_bridge_browsertest.cc
@@ -45,7 +45,7 @@ class AccessibilityBridgeTest : public cr_fuchsia::WebEngineBrowserTest { public: - AccessibilityBridgeTest() : semantics_manager_binding_(&semantics_manager_) { + AccessibilityBridgeTest() { cr_fuchsia::WebEngineBrowserTest::set_test_server_root( base::FilePath(cr_fuchsia::kTestServerRoot)); } @@ -64,15 +64,10 @@ } void SetUpOnMainThread() override { - fuchsia::accessibility::semantics::SemanticsManagerPtr - semantics_manager_ptr; - semantics_manager_binding_.Bind(semantics_manager_ptr.NewRequest()); - frame_ptr_ = cr_fuchsia::WebEngineBrowserTest::CreateFrame(&navigation_listener_); frame_impl_ = context_impl()->GetFrameImplForTest(&frame_ptr_); - frame_impl_->set_semantics_manager_for_test( - std::move(semantics_manager_ptr)); + frame_impl_->set_semantics_manager_for_test(&semantics_manager_); frame_ptr_->EnableHeadlessRendering(); semantics_manager_.WaitUntilViewRegistered(); @@ -88,8 +83,6 @@ fuchsia::web::FramePtr frame_ptr_; FrameImpl* frame_impl_; FakeSemanticsManager semantics_manager_; - fidl::Binding<fuchsia::accessibility::semantics::SemanticsManager> - semantics_manager_binding_; cr_fuchsia::TestNavigationListener navigation_listener_; fuchsia::web::NavigationControllerPtr navigation_controller_; };
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index c409ac62..258cbf2d 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -552,19 +552,20 @@ view_ref_pair.view_ref = std::move(view_ref); InitWindowTreeHost(std::move(view_token), std::move(view_ref_pair)); - fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager = - semantics_manager_for_test_ - ? std::move(semantics_manager_for_test_) - : base::ComponentContextForProcess() - ->svc() - ->Connect< - fuchsia::accessibility::semantics::SemanticsManager>(); + fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager; + if (!semantics_manager_for_test_) { + semantics_manager = + base::ComponentContextForProcess() + ->svc() + ->Connect<fuchsia::accessibility::semantics::SemanticsManager>(); + } // If the SemanticTree owned by |accessibility_bridge_| is disconnected, it // will cause |this| to be closed. accessibility_bridge_ = std::make_unique<AccessibilityBridge>( - std::move(semantics_manager), window_tree_host_->CreateViewRef(), - web_contents_.get(), + semantics_manager_for_test_ ? semantics_manager_for_test_ + : semantics_manager.get(), + window_tree_host_->CreateViewRef(), web_contents_.get(), base::BindOnce(&FrameImpl::CloseAndDestroyFrame, base::Unretained(this))); } @@ -768,8 +769,8 @@ gfx::Rect bounds(kHeadlessWindowSize); if (semantics_manager_for_test_) { accessibility_bridge_ = std::make_unique<AccessibilityBridge>( - std::move(semantics_manager_for_test_), - window_tree_host_->CreateViewRef(), web_contents_.get(), + semantics_manager_for_test_, window_tree_host_->CreateViewRef(), + web_contents_.get(), base::BindOnce(&FrameImpl::CloseAndDestroyFrame, base::Unretained(this)));
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index b79fcb186..7e18f926a 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -79,9 +79,8 @@ return accessibility_bridge_.get(); } void set_semantics_manager_for_test( - fuchsia::accessibility::semantics::SemanticsManagerPtr - semantics_manager) { - semantics_manager_for_test_ = std::move(semantics_manager); + fuchsia::accessibility::semantics::SemanticsManager* semantics_manager) { + semantics_manager_for_test_ = semantics_manager; } CastStreamingSessionClient* cast_streaming_session_client_for_test() { return cast_streaming_session_client_.get(); @@ -246,7 +245,7 @@ FrameLayoutManager* layout_manager_ = nullptr; std::unique_ptr<AccessibilityBridge> accessibility_bridge_; - fuchsia::accessibility::semantics::SemanticsManagerPtr + fuchsia::accessibility::semantics::SemanticsManager* semantics_manager_for_test_; EventFilter event_filter_;
diff --git a/fuchsia/engine/browser/frame_impl_browsertest.cc b/fuchsia/engine/browser/frame_impl_browsertest.cc index 449b8c0..d0e88da 100644 --- a/fuchsia/engine/browser/frame_impl_browsertest.cc +++ b/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -118,11 +118,47 @@ return WebEngineBrowserTest::CreateFrame(&navigation_listener_); } + // Dummy SemanticsManager to satisfy tests that call CreateView(). + FakeSemanticsManager fake_semantics_manager_; + cr_fuchsia::TestNavigationListener navigation_listener_; DISALLOW_COPY_AND_ASSIGN(FrameImplTest); }; +std::string GetDocumentVisibilityState(fuchsia::web::Frame* frame) { + auto visibility = base::MakeRefCounted<base::RefCountedData<std::string>>(); + base::RunLoop loop; + frame->ExecuteJavaScript( + {"*"}, + cr_fuchsia::MemBufferFromString("document.visibilityState;", "test"), + [visibility, quit_loop = loop.QuitClosure()]( + fuchsia::web::Frame_ExecuteJavaScript_Result result) { + ASSERT_TRUE(result.is_response()); + visibility->data = StringFromMemBufferOrDie(result.response().result); + quit_loop.Run(); + }); + loop.Run(); + return visibility->data; +} + +// Verifies that Frames are initially "hidden". +IN_PROC_BROWSER_TEST_F(FrameImplTest, VisibilityState) { + fuchsia::web::FramePtr frame = CreateFrame(); + + fuchsia::web::NavigationControllerPtr controller; + frame->GetNavigationController(controller.NewRequest()); + + // Navigate to a page and wait for it to finish loading. + ASSERT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse( + controller.get(), fuchsia::web::LoadUrlParams(), url::kAboutBlankURL)); + navigation_listener_.RunUntilUrlAndTitleEquals(GURL(url::kAboutBlankURL), + url::kAboutBlankURL); + + // Query the document.visibilityState before creating a View. + EXPECT_EQ(GetDocumentVisibilityState(frame.get()), "\"hidden\""); +} + void VerifyCanGoBackAndForward(fuchsia::web::NavigationController* controller, bool can_go_back_expected, bool can_go_forward_expected) { @@ -240,20 +276,13 @@ EXPECT_TRUE(frame); FrameImpl* frame_impl = context_impl()->GetFrameImplForTest(&frame); - // Sets up a FakeSemanticsManager to be used when an AccessibilityBridge is - // created. This prevents the remote handle from being dropped, which causes - // the Frame to be torn down. - FakeSemanticsManager semantics_manager; - fidl::Binding<fuchsia::accessibility::semantics::SemanticsManager> - semantics_manager_binding(&semantics_manager); - fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager_ptr; - semantics_manager_binding.Bind(semantics_manager_ptr.NewRequest()); - frame_impl->set_semantics_manager_for_test(std::move(semantics_manager_ptr)); + // CreateView() will cause the AccessibilityBridge to be created. + frame_impl->set_semantics_manager_for_test(&fake_semantics_manager_); auto view_tokens = scenic::ViewTokenPair::New(); - frame->CreateView(std::move(view_tokens.view_token)); base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(frame_impl->has_view_for_test()); base::RunLoop run_loop; frame.set_error_handler([&run_loop](zx_status_t status) { @@ -1481,19 +1510,12 @@ ASSERT_TRUE(frame_impl); EXPECT_FALSE(frame_impl->has_view_for_test()); + // CreateView() will cause the AccessibilityBridge to be created. + frame_impl->set_semantics_manager_for_test(&fake_semantics_manager_); + fuchsia::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - // Sets up a FakeSemanticsManager to be used when an AccessibilityBridge is - // created. This prevents the remote handle from being dropped, which causes - // the Frame to be torn down. - FakeSemanticsManager semantics_manager; - fidl::Binding<fuchsia::accessibility::semantics::SemanticsManager> - semantics_manager_binding(&semantics_manager); - fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager_ptr; - semantics_manager_binding.Bind(semantics_manager_ptr.NewRequest()); - frame_impl->set_semantics_manager_for_test(std::move(semantics_manager_ptr)); - // Verify that the Frame can navigate, prior to the View being created. const GURL page1_url(embedded_test_server()->GetURL(kPage1Path)); EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse( @@ -1501,11 +1523,8 @@ navigation_listener_.RunUntilUrlAndTitleEquals(page1_url, kPage1Title); // Request a View from the Frame, and pump the loop to process the request. - zx::eventpair owner_token, frame_token; - ASSERT_EQ(zx::eventpair::create(0, &owner_token, &frame_token), ZX_OK); - fuchsia::ui::views::ViewToken view_token; - view_token.value = std::move(frame_token); - frame->CreateView(std::move(view_token)); + auto view_tokens = scenic::ViewTokenPair::New(); + frame->CreateView(std::move(view_tokens.view_token)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(frame_impl->has_view_for_test()); @@ -1515,17 +1534,9 @@ controller.get(), fuchsia::web::LoadUrlParams(), page2_url.spec())); navigation_listener_.RunUntilUrlAndTitleEquals(page2_url, kPage2Title); - // Create another FakeSemanticsManager for a second call to CreateView. - fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager_ptr2; - semantics_manager_binding.Bind(semantics_manager_ptr2.NewRequest()); - frame_impl->set_semantics_manager_for_test(std::move(semantics_manager_ptr2)); - // Create new View tokens and request a new view. - zx::eventpair owner_token2, frame_token2; - ASSERT_EQ(zx::eventpair::create(0, &owner_token2, &frame_token2), ZX_OK); - fuchsia::ui::views::ViewToken view_token2; - view_token2.value = std::move(frame_token2); - frame->CreateView(std::move(view_token2)); + auto view_tokens2 = scenic::ViewTokenPair::New(); + frame->CreateView(std::move(view_tokens2.view_token)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(frame_impl->has_view_for_test());
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 13b700a4..8905ba3 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -17335,7 +17335,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17401,7 +17401,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17423,7 +17423,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17445,7 +17445,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17467,7 +17467,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17555,7 +17555,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17577,7 +17577,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17599,7 +17599,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17665,7 +17665,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17687,7 +17687,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17826,7 +17826,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17849,7 +17849,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17959,7 +17959,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17981,7 +17981,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18091,7 +18091,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18157,7 +18157,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?staging\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18314,7 +18314,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18337,7 +18337,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18360,7 +18360,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18383,7 +18383,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18452,7 +18452,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18475,7 +18475,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18546,7 +18546,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" + properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 36000 caches { name: "xcode_ios_11e146" @@ -18571,7 +18571,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" + properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 36000 caches { name: "xcode_ios_11e146" @@ -18690,7 +18690,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18713,7 +18713,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18736,7 +18736,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18759,7 +18759,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18869,7 +18869,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18891,7 +18891,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\"}" execution_timeout_secs: 36000 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/subprojects/goma/goma.star b/infra/config/subprojects/goma/goma.star index 58feba0..6e7df0a1b 100644 --- a/infra/config/subprojects/goma/goma.star +++ b/infra/config/subprojects/goma/goma.star
@@ -155,6 +155,7 @@ goma_backend = goma_backend, mastername = "chromium.goma.fyi", os = os, + goma_use_luci_auth = True, **kwargs ) @@ -315,6 +316,7 @@ goma_backend = goma_backend, mastername = "chromium.goma.fyi", os = os, + goma_use_luci_auth = True, **kwargs ) @@ -383,12 +385,19 @@ os = os.MAC_DEFAULT, ) -def goma_builder(*, name, builderless = False, os = os.LINUX_DEFAULT, **kwargs): +def goma_builder( + *, + name, + builderless = False, + os = os.LINUX_DEFAULT, + goma_use_luci_auth = True, + **kwargs): return builder( name = name, builderless = builderless, mastername = "chromium.goma", os = os, + goma_use_luci_auth = goma_use_luci_auth, **kwargs ) @@ -401,14 +410,12 @@ name = "Chromium Android ARM 32-bit Goma RBE ToT", goma_backend = goma.backend.RBE_TOT, goma_enable_ats = False, - goma_use_luci_auth = True, ) goma_builder( name = "Chromium Android ARM 32-bit Goma RBE ToT (ATS)", goma_backend = goma.backend.RBE_TOT, goma_enable_ats = True, - goma_use_luci_auth = True, ) goma_builder( @@ -433,28 +440,33 @@ goma_builder( name = "Chromium Linux Goma Staging", + goma_use_luci_auth = False, ) goma_builder( name = "Chromium Linux Goma RBE ToT", goma_backend = goma.backend.RBE_TOT, goma_enable_ats = False, - goma_use_luci_auth = True, ) goma_builder( name = "Chromium Linux Goma RBE ToT (ATS)", goma_backend = goma.backend.RBE_TOT, goma_enable_ats = True, - goma_use_luci_auth = True, ) -def goma_mac_builder(*, name, os = os.MAC_DEFAULT, **kwargs): +def goma_mac_builder( + *, + name, + os = os.MAC_DEFAULT, + goma_use_luci_auth = True, + **kwargs): return goma_builder( name = name, cores = 4, goma_jobs = goma.jobs.J80, os = os, + goma_use_luci_auth = goma_use_luci_auth, **kwargs ) @@ -462,7 +474,6 @@ name = "Chromium iOS Goma RBE ToT", caches = [xcode_cache.x11e146], goma_backend = goma.backend.RBE_TOT, - goma_use_luci_auth = True, os = os.MAC_10_14, properties = { "xcode_build_version": "11e146", @@ -487,18 +498,25 @@ goma_mac_builder( name = "Chromium Mac Goma RBE ToT", goma_backend = goma.backend.RBE_TOT, - goma_use_luci_auth = True, ) goma_mac_builder( name = "Chromium Mac Goma Staging", + goma_use_luci_auth = False, ) -def goma_windows_builder(*, name, goma_enable_ats = True, cores = 32, **kwargs): +def goma_windows_builder( + *, + name, + goma_enable_ats = True, + goma_use_luci_auth = True, + cores = 32, + **kwargs): return goma_builder( name = name, cores = cores, goma_enable_ats = goma_enable_ats, + goma_use_luci_auth = goma_use_luci_auth, os = os.WINDOWS_DEFAULT, **kwargs ) @@ -516,11 +534,11 @@ goma_windows_builder( name = "Chromium Win Goma RBE ToT", goma_backend = goma.backend.RBE_TOT, - goma_use_luci_auth = True, ) goma_windows_builder( name = "CrWinGomaStaging", cores = 8, goma_enable_ats = False, + goma_use_luci_auth = False, )
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index c17988f..37e15e36 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -51,7 +51,6 @@ #include "components/strings/grit/components_strings.h" #include "components/sync/base/sync_base_switches.h" #include "components/sync/driver/sync_driver_switches.h" -#include "components/sync/engine/sync_engine_switches.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/ukm/ios/features.h" #include "ios/chrome/browser/browsing_data/browsing_data_features.h" @@ -450,10 +449,6 @@ flag_descriptions::kAutofillPruneSuggestionsName, flag_descriptions::kAutofillPruneSuggestionsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(autofill::features::kAutofillPruneSuggestions)}, - {"enable-sync-trusted-vault", - flag_descriptions::kEnableSyncTrustedVaultName, - flag_descriptions::kEnableSyncTrustedVaultDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(switches::kSyncSupportTrustedVaultPassphrase)}, {"collections-card-presentation-style", flag_descriptions::kCollectionsCardPresentationStyleName, flag_descriptions::kCollectionsCardPresentationStyleDescription,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index dc867c02..ac18e50 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -259,11 +259,6 @@ const char kEnablePersistentDownloadsDescription[] = "Enables the new, experimental implementation of persistent downloads"; -const char kEnableSyncTrustedVaultName[] = - "Enable trusted vault sync passphrase type"; -const char kEnableSyncTrustedVaultDescription[] = - "Enables the new, experimental passphrase type for sync data"; - const char kExpandedTabStripName[] = "Enable expanded tabstrip"; const char kExpandedTabStripDescription[] = "Enables the new expanded tabstrip. Activated by swiping down the tabstrip"
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 1d1b418..e4bab0b 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -218,9 +218,6 @@ extern const char kEnablePersistentDownloadsName[]; extern const char kEnablePersistentDownloadsDescription[]; -extern const char kEnableSyncTrustedVaultName[]; -extern const char kEnableSyncTrustedVaultDescription[]; - // Title and description for the flag to enable an expanded tab strip. extern const char kExpandedTabStripName[]; extern const char kExpandedTabStripDescription[];
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm index 662878e0..f64db3f 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm
@@ -238,7 +238,15 @@ // Tests that the Address View Controller is dismissed when tapping the outside // the popover on iPad. -- (void)testIPadTappingOutsidePopOverDismissAddressController { +// TODO(crbug.com/1116887) Flaky on iOS simulator +#if TARGET_IPHONE_SIMULATOR +#define MAYBE_testIPadTappingOutsidePopOverDismissAddressController \ + DISABLED_testIPadTappingOutsidePopOverDismissAddressController +#else +#define MAYBE_testIPadTappingOutsidePopOverDismissAddressController \ + testIPadTappingOutsidePopOverDismissAddressController +#endif +- (void)MAYBE_testIPadTappingOutsidePopOverDismissAddressController { if (![ChromeEarlGrey isIPadIdiom]) { EARL_GREY_TEST_SKIPPED(@"Test is not applicable for iPhone"); }
diff --git a/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm b/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm index ac9f9d41..29eb66c 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_check_cell.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/settings/cells/settings_check_cell.h" #include "base/check.h" +#include "base/ios/ios_util.h" #include "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" @@ -101,7 +102,15 @@ _trailingImageView.hidden = YES; [contentView addSubview:_trailingImageView]; // |activityIndictor| attributes. - _activityIndicator = [[UIActivityIndicatorView alloc] init]; + if (base::ios::IsRunningOnIOS13OrLater()) { + // Creates default activity indicator. Color depends on appearance. + _activityIndicator = [[UIActivityIndicatorView alloc] init]; + } else { + // For iOS 12 and lower the color should be always gray otherwise + // indicator is not visible. + _activityIndicator = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + } _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; _activityIndicator.hidden = YES; [contentView addSubview:_activityIndicator];
diff --git a/ios/chrome/browser/ui/settings/cells/settings_check_item.mm b/ios/chrome/browser/ui/settings/cells/settings_check_item.mm index 5d5cb07..b18c4340 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_check_item.mm +++ b/ios/chrome/browser/ui/settings/cells/settings_check_item.mm
@@ -29,7 +29,6 @@ [super configureCell:cell withStyler:styler]; cell.textLabel.text = self.text; cell.detailTextLabel.text = self.detailText; - cell.selectionStyle = UITableViewCellSelectionStyleNone; if (self.enabled) { [cell setInfoButtonHidden:self.infoButtonHidden]; [cell setLeadingImage:self.leadingImage
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm index 8c50090..73753ab 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -266,8 +266,6 @@ cell.selectionStyle = UITableViewCellSelectionStyleNone; - // TODO:(crbug.com/1075494) - Add action to Show/Hide password when user tap - // eye icon. NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; switch (itemType) { case ItemTypePassword: { @@ -280,9 +278,11 @@ forControlEvents:UIControlEventTouchUpInside]; return textFieldCell; } + case ItemTypeChangePasswordButton: + cell.selectionStyle = UITableViewCellSelectionStyleDefault; + break; case ItemTypeWebsite: case ItemTypeUsername: - case ItemTypeChangePasswordButton: case ItemTypeChangePasswordRecommendation: break; }
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm index 0c2a5a6..6a84b78 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm
@@ -1382,8 +1382,17 @@ - (BOOL)tableView:(UITableView*)tableView shouldHighlightRowAtIndexPath:(NSIndexPath*)indexPath { - return [self.tableViewModel sectionIdentifierForSection:indexPath.section] != - SectionIdentifierSavePasswordsSwitch; + NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; + switch (itemType) { + case ItemTypeSavePasswordsSwitch: + return NO; + case ItemTypePasswordCheckStatus: + return self.passwordCheckState == PasswordCheckStateUnSafe; + case ItemTypeCheckForProblemsButton: + return self.passwordCheckState != PasswordCheckStateRunning && + self.passwordCheckState != PasswordCheckStateDisabled; + } + return YES; } - (UIView*)tableView:(UITableView*)tableView
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc index 4818406..06e29d46 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.cc +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -97,19 +97,6 @@ ClearDecodeTaskQueue(DecodeStatus::ABORTED); weak_this_factory_.InvalidateWeakPtrs(); - - // Destroy explicitly to DCHECK() that |vaapi_wrapper_| references are held - // inside the accelerator in |decoder_|, by the |allocated_va_surfaces_| and - // of course by this class. To clear |allocated_va_surfaces_| we have to first - // DestroyContext(). - decoder_ = nullptr; - if (vaapi_wrapper_) { - vaapi_wrapper_->DestroyContext(); - allocated_va_surfaces_.clear(); - - DCHECK(vaapi_wrapper_->HasOneRef()); - vaapi_wrapper_ = nullptr; - } } void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config, @@ -137,9 +124,6 @@ DVLOGF(3) << "Reinitializing decoder"; decoder_ = nullptr; - // To clear |allocated_va_surfaces_| we have to first DestroyContext(). - vaapi_wrapper_->DestroyContext(); - allocated_va_surfaces_.clear(); vaapi_wrapper_ = nullptr; decoder_delegate_ = nullptr; SetState(State::kUninitialized); @@ -316,29 +300,22 @@ return nullptr; } - DCHECK(frame->GetGpuMemoryBuffer()); - const gfx::GpuMemoryBufferId frame_id = frame->GetGpuMemoryBuffer()->GetId(); - scoped_refptr<VASurface> va_surface; + scoped_refptr<gfx::NativePixmap> pixmap = + CreateNativePixmapDmaBuf(frame.get()); + if (!pixmap) { + LOG(ERROR) << "Failed to create NativePixmap from VideoFrame"; + SetState(State::kError); + return nullptr; + } - if (!base::Contains(allocated_va_surfaces_, frame_id)) { - scoped_refptr<gfx::NativePixmap> pixmap = - CreateNativePixmapDmaBuf(frame.get()); - if (!pixmap) { - LOG(ERROR) << "Failed to create NativePixmap from VideoFrame"; - SetState(State::kError); - return nullptr; - } + // Create VASurface from the native pixmap. + scoped_refptr<VASurface> va_surface = + vaapi_wrapper_->CreateVASurfaceForPixmap(std::move(pixmap)); - va_surface = vaapi_wrapper_->CreateVASurfaceForPixmap(std::move(pixmap)); - if (!va_surface || va_surface->id() == VA_INVALID_ID) { - LOG(ERROR) << "Failed to create VASurface from VideoFrame"; - SetState(State::kError); - return nullptr; - } - - allocated_va_surfaces_[frame_id] = va_surface; - } else { - va_surface = allocated_va_surfaces_[frame_id]; + if (!va_surface || va_surface->id() == VA_INVALID_ID) { + LOG(ERROR) << "Failed to create VASurface from VideoFrame"; + SetState(State::kError); + return nullptr; } // Store the mapping between surface and video frame, so we know which video @@ -350,12 +327,14 @@ output_frames_[surface_id] = frame; // When the decoder is done using the frame for output or reference, it will - // drop its reference to the surface. We can then safely remove the associated - // video frame from |output_frames_|. To be notified when this happens we wrap - // the surface in another surface with ReleaseVideoFrame() as destruction - // observer. - VASurface::ReleaseCB release_frame_cb = - base::BindOnce(&VaapiVideoDecoder::ReleaseVideoFrame, weak_this_); + // drop its reference to the surface. We can then safely destroy the surface + // and remove the associated video frame from |output_frames_|. To be notified + // when this happens we wrap the surface in another surface that calls + // ReleaseFrame() on destruction. The |va_surface| object is bound to the + // destruction callback to keep it alive, since the associated VAAPI surface + // will be automatically destroyed when we drop the reference. + VASurface::ReleaseCB release_frame_cb = base::BindOnce( + &VaapiVideoDecoder::ReleaseFrame, weak_this_, std::move(va_surface)); return new VASurface(surface_id, frame->layout().coded_size(), GetVaFormatForVideoCodecProfile(profile_), @@ -437,11 +416,7 @@ } // All pending decode operations will be completed before triggering a - // resolution change, so we can safely DestroyContext() here; that, in turn, - // allows for clearing the |allocated_va_surfaces_|. - vaapi_wrapper_->DestroyContext(); - allocated_va_surfaces_.clear(); - + // resolution change, so we can safely destroy the context here. if (profile_ != decoder_->GetProfile()) { // When a profile is changed, we need to re-initialize VaapiWrapper. profile_ = decoder_->GetProfile(); @@ -454,6 +429,8 @@ } decoder_delegate_->set_vaapi_wrapper(new_vaapi_wrapper.get()); vaapi_wrapper_ = std::move(new_vaapi_wrapper); + } else { + vaapi_wrapper_->DestroyContext(); } vaapi_wrapper_->CreateContext(pic_size); @@ -470,7 +447,9 @@ } } -void VaapiVideoDecoder::ReleaseVideoFrame(VASurfaceID surface_id) { +void VaapiVideoDecoder::ReleaseFrame(scoped_refptr<VASurface> va_surface, + VASurfaceID surface_id) { + DCHECK_EQ(va_surface->id(), surface_id); DVLOGF(4); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h index bece6d3ec..9390bdc 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.h +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -15,7 +15,6 @@ #include "base/containers/mru_cache.h" #include "base/containers/queue.h" -#include "base/containers/small_map.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" @@ -30,7 +29,6 @@ #include "media/video/supported_video_decoder_config.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -#include "ui/gfx/gpu_memory_buffer.h" namespace media { @@ -105,11 +103,13 @@ void ClearDecodeTaskQueue(DecodeStatus status); // Releases the local reference to the VideoFrame associated with the - // specified |surface_id|. This is called when |decoder_| has outputted the - // VideoFrame and stopped using it as a reference frame. Note that this - // doesn't mean the frame can be reused immediately, as it might still be used - // by the client. - void ReleaseVideoFrame(VASurfaceID surface_id); + // specified |surface_id| on the decoder thread. This is called when the last + // reference to the associated VASurface has been released, which happens when + // |decoder_| outputted the video frame, or stopped using it as a reference + // frame. Note that this doesn't mean the frame can be reused immediately, as + // it might still be used by the client. + void ReleaseFrame(scoped_refptr<VASurface> va_surface, + VASurfaceID surface_id); // Callback for |frame_pool_| to notify of available resources. void NotifyFrameAvailable(); @@ -159,15 +159,6 @@ // The list of frames currently used as output buffers or reference frames. std::map<VASurfaceID, scoped_refptr<VideoFrame>> output_frames_; - // VASurfaces are created via importing |frame_pool_| resources into libva in - // CreateSurface(). The following map keeps those VASurfaces for reuse - // according to the expectations of libva vaDestroySurfaces(): "Surfaces can - // only be destroyed after all contexts using these surfaces have been - // destroyed." - // TODO(crbug.com/1040291): remove this keep-alive when using SharedImages. - base::small_map<std::map<gfx::GpuMemoryBufferId, scoped_refptr<VASurface>>> - allocated_va_surfaces_; - // Platform and codec specific video decoder. std::unique_ptr<AcceleratedVideoDecoder> decoder_; scoped_refptr<VaapiWrapper> vaapi_wrapper_;
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 7358258..0f1842f4 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -13,6 +13,7 @@ #include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/load_flags.h" +#include "net/http/http_util.h" #include "services/network/cors/cors_url_loader.h" #include "services/network/cors/preflight_controller.h" #include "services/network/crash_keys.h" @@ -461,6 +462,13 @@ return false; } + if (!net::HttpUtil::IsToken(request.method)) { + // Callers are expected to ensure that |method| follows RFC 7230. + mojo::ReportBadMessage( + "CorsURLLoaderFactory: invalid characters in method"); + return false; + } + // TODO(yhirano): If the request mode is "no-cors", the redirect mode should // be "follow". return true;
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index 766cb2c8..effc524 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -466,6 +466,28 @@ DISALLOW_COPY_AND_ASSIGN(BadMessageTestHelper); }; +TEST_F(CorsURLLoaderTest, NoCorsWithInvalidMethod) { + ResourceRequest request; + request.mode = mojom::RequestMode::kNoCors; + request.credentials_mode = mojom::CredentialsMode::kInclude; + request.url = GURL("http://example.com/"); + request.request_initiator = base::nullopt; + request.method = "GET\r\nHost: other.example.com"; + + BadMessageTestHelper bad_message_helper; + CreateLoaderAndStart(request); + RunUntilComplete(); + + EXPECT_FALSE(IsNetworkLoaderStarted()); + EXPECT_FALSE(client().has_received_redirect()); + EXPECT_FALSE(client().has_received_response()); + EXPECT_TRUE(client().has_received_completion()); + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, client().completion_status().error_code); + EXPECT_THAT(bad_message_helper.bad_message_reports(), + ::testing::ElementsAre( + "CorsURLLoaderFactory: invalid characters in method")); +} + TEST_F(CorsURLLoaderTest, SameOriginWithoutInitiator) { ResourceRequest request; request.mode = mojom::RequestMode::kSameOrigin;
diff --git a/services/network/public/cpp/data_element.cc b/services/network/public/cpp/data_element.cc index 9a95984..4a09cb87 100644 --- a/services/network/public/cpp/data_element.cc +++ b/services/network/public/cpp/data_element.cc
@@ -77,6 +77,13 @@ chunked_data_pipe_getter_ = std::move(chunked_data_pipe_getter); } +void DataElement::SetToReadOnceStream( + mojo::PendingRemote<mojom::ChunkedDataPipeGetter> + chunked_data_pipe_getter) { + type_ = mojom::DataElementType::kReadOnceStream; + chunked_data_pipe_getter_ = std::move(chunked_data_pipe_getter); +} + base::File DataElement::ReleaseFile() { return std::move(file_); } @@ -103,7 +110,9 @@ mojo::PendingRemote<mojom::ChunkedDataPipeGetter> DataElement::ReleaseChunkedDataPipeGetter() { - DCHECK_EQ(mojom::DataElementType::kChunkedDataPipe, type_); + DCHECK(type_ == mojom::DataElementType::kChunkedDataPipe || + type_ == mojom::DataElementType::kReadOnceStream) + << type_; return std::move(chunked_data_pipe_getter_); } @@ -138,6 +147,9 @@ case mojom::DataElementType::kChunkedDataPipe: *os << "TYPE_CHUNKED_DATA_PIPE"; break; + case mojom::DataElementType::kReadOnceStream: + *os << "TYPE_READ_ONCE_STREAM"; + break; case mojom::DataElementType::kUnknown: *os << "TYPE_UNKNOWN"; break; @@ -164,6 +176,8 @@ return false; case mojom::DataElementType::kChunkedDataPipe: return false; + case mojom::DataElementType::kReadOnceStream: + return false; case mojom::DataElementType::kUnknown: NOTREACHED(); return false;
diff --git a/services/network/public/cpp/data_element.h b/services/network/public/cpp/data_element.h index 26d0f4fc..ed2eed4a 100644 --- a/services/network/public/cpp/data_element.h +++ b/services/network/public/cpp/data_element.h
@@ -169,6 +169,10 @@ // server known to support chunked uploads. void SetToChunkedDataPipe(mojo::PendingRemote<mojom::ChunkedDataPipeGetter> chunked_data_pipe_getter); + // Almost same as above except |chunked_data_pipe_getter| is read only once + // and you must talk with a server supporting chunked upload. + void SetToReadOnceStream(mojo::PendingRemote<mojom::ChunkedDataPipeGetter> + chunked_data_pipe_getter); // Takes ownership of the File, if this is of TYPE_RAW_FILE. The file is open // for reading (asynchronous reading on Windows).
diff --git a/services/network/public/cpp/network_ipc_param_traits.cc b/services/network/public/cpp/network_ipc_param_traits.cc index ad07a680..e0f982d4 100644 --- a/services/network/public/cpp/network_ipc_param_traits.cc +++ b/services/network/public/cpp/network_ipc_param_traits.cc
@@ -57,6 +57,7 @@ .release()); break; } + case network::mojom::DataElementType::kReadOnceStream: case network::mojom::DataElementType::kUnknown: { NOTREACHED(); break; @@ -148,6 +149,7 @@ r->SetToChunkedDataPipe(std::move(chunked_data_pipe_getter)); return true; } + case network::mojom::DataElementType::kReadOnceStream: case network::mojom::DataElementType::kUnknown: { NOTREACHED(); return false;
diff --git a/services/network/public/cpp/resource_request_body.cc b/services/network/public/cpp/resource_request_body.cc index a865aeb..8797143 100644 --- a/services/network/public/cpp/resource_request_body.cc +++ b/services/network/public/cpp/resource_request_body.cc
@@ -21,9 +21,15 @@ return result; } +bool ResourceRequestBody::EnableToAppendElement() const { + return elements_.empty() || + (elements_.front().type() != + mojom::DataElementType::kChunkedDataPipe && + elements_.front().type() != mojom::DataElementType::kReadOnceStream); +} + void ResourceRequestBody::AppendBytes(std::vector<uint8_t> bytes) { - DCHECK(elements_.empty() || - elements_.front().type() != mojom::DataElementType::kChunkedDataPipe); + DCHECK(EnableToAppendElement()); if (bytes.size() > 0) { elements_.push_back(DataElement()); @@ -44,8 +50,7 @@ uint64_t offset, uint64_t length, const base::Time& expected_modification_time) { - DCHECK(elements_.empty() || - elements_.front().type() != mojom::DataElementType::kChunkedDataPipe); + DCHECK(EnableToAppendElement()); elements_.push_back(DataElement()); elements_.back().SetToFilePathRange(file_path, offset, length, @@ -58,8 +63,7 @@ uint64_t offset, uint64_t length, const base::Time& expected_modification_time) { - DCHECK(elements_.empty() || - elements_.front().type() != mojom::DataElementType::kChunkedDataPipe); + DCHECK(EnableToAppendElement()); elements_.push_back(DataElement()); elements_.back().SetToFileRange(std::move(file), file_path, offset, length, @@ -71,8 +75,7 @@ } void ResourceRequestBody::AppendBlob(const std::string& uuid, uint64_t length) { - DCHECK(elements_.empty() || - elements_.front().type() != mojom::DataElementType::kChunkedDataPipe); + DCHECK(EnableToAppendElement()); elements_.push_back(DataElement()); elements_.back().SetToBlobRange(uuid, 0 /* offset */, length); @@ -80,8 +83,7 @@ void ResourceRequestBody::AppendDataPipe( mojo::PendingRemote<mojom::DataPipeGetter> data_pipe_getter) { - DCHECK(elements_.empty() || - elements_.front().type() != mojom::DataElementType::kChunkedDataPipe); + DCHECK(EnableToAppendElement()); elements_.push_back(DataElement()); elements_.back().SetToDataPipe(std::move(data_pipe_getter)); @@ -96,6 +98,15 @@ elements_.back().SetToChunkedDataPipe(std::move(chunked_data_pipe_getter)); } +void ResourceRequestBody::SetToReadOnceStream( + mojo::PendingRemote<mojom::ChunkedDataPipeGetter> + chunked_data_pipe_getter) { + DCHECK(elements_.empty()); + + elements_.push_back(DataElement()); + elements_.back().SetToReadOnceStream(std::move(chunked_data_pipe_getter)); +} + std::vector<base::FilePath> ResourceRequestBody::GetReferencedFiles() const { std::vector<base::FilePath> result; for (const auto& element : *elements()) {
diff --git a/services/network/public/cpp/resource_request_body.h b/services/network/public/cpp/resource_request_body.h index 2634327f..e3679f2 100644 --- a/services/network/public/cpp/resource_request_body.h +++ b/services/network/public/cpp/resource_request_body.h
@@ -80,6 +80,10 @@ // support chunked uploads. void SetToChunkedDataPipe(mojo::PendingRemote<mojom::ChunkedDataPipeGetter> chunked_data_pipe_getter); + // Almost same as above except |chunked_data_pipe_getter| is read only once + // and you must talk with a server supporting chunked upload. + void SetToReadOnceStream(mojo::PendingRemote<mojom::ChunkedDataPipeGetter> + chunked_data_pipe_getter); void SetAllowHTTP1ForStreamingUpload(bool allow) { allow_http1_for_streaming_upload_ = allow; } @@ -118,6 +122,8 @@ scoped_refptr<network::ResourceRequestBody>>; ~ResourceRequestBody(); + bool EnableToAppendElement() const; + std::vector<DataElement> elements_; int64_t identifier_;
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index 4751e5ea..f3daedb 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -327,7 +327,8 @@ } static mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter> chunked_data_pipe_getter(const network::DataElement& element) { - if (element.type_ != network::mojom::DataElementType::kChunkedDataPipe) + if (element.type_ != network::mojom::DataElementType::kChunkedDataPipe && + element.type_ != network::mojom::DataElementType::kReadOnceStream) return mojo::NullRemote(); return const_cast<network::DataElement&>(element) .ReleaseChunkedDataPipeGetter();
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom index 9e48b6f..12dd49ad 100644 --- a/services/network/public/mojom/url_loader.mojom +++ b/services/network/public/mojom/url_loader.mojom
@@ -62,6 +62,7 @@ // Only used for Upload with Network Service as of now: kDataPipe, kChunkedDataPipe, + kReadOnceStream, kRawFile, // Used for Upload when Network Service is disabled:
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index c209506..c89d6749 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -210,12 +210,14 @@ std::vector<base::File>& opened_files, base::SequencedTaskRunner* file_task_runner) { // In the case of a chunked upload, there will just be one element. - if (body->elements()->size() == 1 && - body->elements()->begin()->type() == - network::mojom::DataElementType::kChunkedDataPipe) { - return std::make_unique<ChunkedDataPipeUploadDataStream>( - body, const_cast<DataElement&>(body->elements()->front()) - .ReleaseChunkedDataPipeGetter()); + if (body->elements()->size() == 1) { + network::mojom::DataElementType type = body->elements()->begin()->type(); + if (type == network::mojom::DataElementType::kChunkedDataPipe || + type == network::mojom::DataElementType::kReadOnceStream) { + return std::make_unique<ChunkedDataPipeUploadDataStream>( + body, + body->elements_mutable()->begin()->ReleaseChunkedDataPipeGetter()); + } } auto opened_file = opened_files.begin(); @@ -244,7 +246,8 @@ body, element.CloneDataPipeGetter())); break; } - case network::mojom::DataElementType::kChunkedDataPipe: { + case network::mojom::DataElementType::kChunkedDataPipe: + case network::mojom::DataElementType::kReadOnceStream: { // This shouldn't happen, as the traits logic should ensure that if // there's a chunked pipe, there's one and only one element. NOTREACHED(); @@ -1095,22 +1098,13 @@ // static bool URLLoader::HasFetchStreamingUploadBody(const ResourceRequest* request) { - // Follows blink::mojom::ResourceType::kXhr. - const int kXhr = 13; - if (request->resource_type != kXhr) - return false; const ResourceRequestBody* request_body = request->request_body.get(); if (!request_body) return false; const std::vector<DataElement>* elements = request_body->elements(); - if (elements->size() == 0u) + if (elements->size() != 1u) return false; - // https://fetch.spec.whatwg.org/#concept-bodyinit-extract - // Body's source is null means the body is not extracted from ReadableStream. - // See blink::PopulateResourceRequest() for actual construction. - if (elements->size() > 1u) - return false; - return elements->at(0).type() == mojom::DataElementType::kChunkedDataPipe; + return elements->front().type() == mojom::DataElementType::kReadOnceStream; } void URLLoader::OnAuthRequired(net::URLRequest* url_request,
diff --git a/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h b/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h index c99ea3b..ebe9098 100644 --- a/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h +++ b/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h
@@ -79,7 +79,7 @@ } static mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter> chunked_data_pipe_getter(const network::DataElement& element) { - if (element.type_ != network::mojom::DataElementType::kChunkedDataPipe) + if (element.type_ != network::mojom::DataElementType::kReadOnceStream) return mojo::NullRemote(); return const_cast<network::DataElement&>(element) .ReleaseChunkedDataPipeGetter();
diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni index 8802716c..e8a85748 100644 --- a/third_party/blink/renderer/bindings/bindings.gni +++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -7,12 +7,6 @@ import("//third_party/blink/renderer/bindings/modules/v8/v8.gni") -declare_args() { - # If this variable is set true, we use a new code generator to generate code - # of IDL dictionaries. See https://crbug.com/839389 for the details. - use_blink_v8_binding_new_idl_dictionary = false -} - bindings_core_v8_files = get_path_info([ "core/v8/active_script_wrappable.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 942e6bb..feda0b5 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -334,7 +334,7 @@ if (GetMicrotasksScopeDepth(isolate, microtask_queue) > kMaxRecursionDepth) return ThrowStackOverflowExceptionIfNeeded(isolate, microtask_queue); - CHECK(!context->ContextLifecycleObserverList().IsIteratingOverObservers()); + CHECK(!context->ContextLifecycleObserverSet().IsIteratingOverObservers()); // Run the script and keep track of the current recursion depth. v8::MaybeLocal<v8::Value> result; @@ -472,7 +472,7 @@ if (depth >= kMaxRecursionDepth) return ThrowStackOverflowExceptionIfNeeded(isolate, microtask_queue); - CHECK(!context->ContextLifecycleObserverList().IsIteratingOverObservers()); + CHECK(!context->ContextLifecycleObserverSet().IsIteratingOverObservers()); if (ScriptForbiddenScope::IsScriptForbidden()) { ThrowScriptForbiddenException(isolate); @@ -525,7 +525,7 @@ if (depth >= kMaxRecursionDepth) return ThrowStackOverflowExceptionIfNeeded(isolate, microtask_queue); - CHECK(!context->ContextLifecycleObserverList().IsIteratingOverObservers()); + CHECK(!context->ContextLifecycleObserverSet().IsIteratingOverObservers()); if (ScriptForbiddenScope::IsScriptForbidden()) { ThrowScriptForbiddenException(isolate);
diff --git a/third_party/blink/renderer/config.gni b/third_party/blink/renderer/config.gni index e2b18ed..9be37ad 100644 --- a/third_party/blink/renderer/config.gni +++ b/third_party/blink/renderer/config.gni
@@ -41,6 +41,10 @@ support_webgl2_compute_context = !is_android # If true, the new implementation (experimental) of Blink-V8 bindings + # (of IDL dictionary) is used. + use_blink_v8_binding_new_idl_dictionary = false + + # If true, the new implementation (experimental) of Blink-V8 bindings # (of IDL interface) is used. use_blink_v8_binding_new_idl_interface = true } @@ -65,6 +69,10 @@ feature_defines_list += [ "WTF_USE_WEBAUDIO_PFFFT=1" ] } +if (use_blink_v8_binding_new_idl_dictionary) { + feature_defines_list += [ "USE_BLINK_V8_BINDING_NEW_IDL_DICTIONARY" ] +} + if (use_blink_v8_binding_new_idl_interface) { feature_defines_list += [ "USE_BLINK_V8_BINDING_NEW_IDL_INTERFACE" ] }
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index 6d26a233..c797d4e 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -1992,15 +1992,13 @@ playback_rate_); } - AnimationTimeDelta result = - playback_rate_ > 0 - ? content_->TimeToForwardsEffectChange() / playback_rate_ - : content_->TimeToReverseEffectChange() / -playback_rate_; + if (!HasActiveAnimationsOnCompositor() && + (content_->GetPhase() == Timing::kPhaseActive)) + return AnimationTimeDelta(); - return !HasActiveAnimationsOnCompositor() && - content_->GetPhase() == Timing::kPhaseActive - ? AnimationTimeDelta() - : result; + return (playback_rate_ > 0) + ? (content_->TimeToForwardsEffectChange() / playback_rate_) + : (content_->TimeToReverseEffectChange() / -playback_rate_); } void Animation::cancel() {
diff --git a/third_party/blink/renderer/core/animation/animation_time_delta.h b/third_party/blink/renderer/core/animation/animation_time_delta.h index 0f0c00b..9c330f3 100644 --- a/third_party/blink/renderer/core/animation/animation_time_delta.h +++ b/third_party/blink/renderer/core/animation/animation_time_delta.h
@@ -76,8 +76,8 @@ AnimationTimeDelta operator*(T a) const { return AnimationTimeDelta(delta_ * a); } - template <typename V> - AnimationTimeDelta& operator*=(V a) { + template <typename T> + AnimationTimeDelta& operator*=(T a) { return *this = (*this * a); } template <typename T>
diff --git a/third_party/blink/renderer/core/animation/timing_calculations.h b/third_party/blink/renderer/core/animation/timing_calculations.h index 731b461..f39fdc7b 100644 --- a/third_party/blink/renderer/core/animation/timing_calculations.h +++ b/third_party/blink/renderer/core/animation/timing_calculations.h
@@ -174,8 +174,7 @@ // through the current iteration that ignores transformations to the time // introduced by the playback direction or timing functions applied to the // effect. -// https://drafts.csswg.org/web-animations/#calculating-the-simple-iteration -// -progress +// https://drafts.csswg.org/web-animations/#calculating-the-simple-iteration-progress static inline base::Optional<double> CalculateSimpleIterationProgress( Timing::Phase phase, base::Optional<double> overall_progress,
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index bf288e600..33c232f 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -3171,12 +3171,12 @@ GetFrame()->GetEventHandlerRegistry().DocumentDetached(*this); // Signal destruction to mutation observers. - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [](SynchronousMutationObserver* observer) { observer->ContextDestroyed(); - observer->ObserverListWillBeCleared(); + observer->ObserverSetWillBeCleared(); }); - synchronous_mutation_observer_list_.Clear(); + synchronous_mutation_observer_set_.Clear(); cookie_jar_ = nullptr; // Not accessible after navigated away. fetcher_->ClearContext(); @@ -5388,7 +5388,7 @@ for (Range* range : ranges) range->UpdateOwnerDocumentIfNeeded(); } - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->DidMoveTreeToNewDocument(root); }); @@ -5407,7 +5407,7 @@ ni->NodeWillBeRemoved(n); } - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->NodeChildrenWillBeRemoved(container); }); @@ -5428,7 +5428,7 @@ range->FixupRemovedNodeAcrossShadowBoundary(n); } - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->NodeWillBeRemoved(n); }); @@ -5444,7 +5444,7 @@ unsigned offset, unsigned old_length, unsigned new_length) { - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->DidUpdateCharacterData(character_data, offset, old_length, new_length); @@ -5452,7 +5452,7 @@ } void Document::NotifyChangeChildren(const ContainerNode& container) { - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->DidChangeChildren(container); }); @@ -5482,7 +5482,7 @@ range->DidMergeTextNodes(node_to_be_removed_with_index, old_length); } - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->DidMergeTextNodes(merged_node, node_to_be_removed_with_index, old_length); @@ -5495,7 +5495,7 @@ for (Range* range : ranges_) range->DidSplitTextNode(old_node); - synchronous_mutation_observer_list_.ForEachObserver( + synchronous_mutation_observer_set_.ForEachObserver( [&](SynchronousMutationObserver* observer) { observer->DidSplitTextNode(old_node); }); @@ -8143,7 +8143,7 @@ visitor->Trace(computed_node_mapping_); visitor->Trace(mime_handler_view_before_unload_event_listener_); visitor->Trace(cookie_jar_); - visitor->Trace(synchronous_mutation_observer_list_); + visitor->Trace(synchronous_mutation_observer_set_); visitor->Trace(element_explicitly_set_attr_elements_map_); visitor->Trace(display_lock_document_state_); visitor->Trace(font_preload_manager_);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index a40b925..1d08f4c 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -66,7 +66,7 @@ #include "third_party/blink/renderer/core/loader/font_preload_manager.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -1609,9 +1609,9 @@ void CancelPendingJavaScriptUrls(); - HeapObserverList<SynchronousMutationObserver>& - SynchronousMutationObserverList() { - return synchronous_mutation_observer_list_; + HeapObserverSet<SynchronousMutationObserver>& + SynchronousMutationObserverSet() { + return synchronous_mutation_observer_set_; } void NotifyUpdateCharacterData(CharacterData* character_data, @@ -2135,8 +2135,8 @@ HeapHashMap<WeakMember<Element>, Member<ExplicitlySetAttrElementsMap>> element_explicitly_set_attr_elements_map_; - HeapObserverList<SynchronousMutationObserver> - synchronous_mutation_observer_list_; + HeapObserverSet<SynchronousMutationObserver> + synchronous_mutation_observer_set_; Member<DisplayLockDocumentState> display_lock_document_state_;
diff --git a/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc b/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc index 7deddd69..156a0e88 100644 --- a/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc +++ b/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc
@@ -8,7 +8,7 @@ namespace blink { -void SynchronousMutationObserver::ObserverListWillBeCleared() { +void SynchronousMutationObserver::ObserverSetWillBeCleared() { document_ = nullptr; } @@ -17,12 +17,12 @@ return; if (document_) - document_->SynchronousMutationObserverList().RemoveObserver(this); + document_->SynchronousMutationObserverSet().RemoveObserver(this); document_ = document; if (document_) - document_->SynchronousMutationObserverList().AddObserver(this); + document_->SynchronousMutationObserverSet().AddObserver(this); } void SynchronousMutationObserver::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h b/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h index 82a35ed8..e574de51 100644 --- a/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h +++ b/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h
@@ -76,7 +76,7 @@ virtual void ContextDestroyed() {} // Call before clearing an observer list. - void ObserverListWillBeCleared(); + void ObserverSetWillBeCleared(); Document* GetDocument() const { return document_; } void SetDocument(Document*);
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc index 29da30b4..2ec6885 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -119,7 +119,7 @@ if (lifecycle_state_ == state) return; lifecycle_state_ = state; - context_lifecycle_observer_list_.ForEachObserver( + context_lifecycle_observer_set_.ForEachObserver( [&](ContextLifecycleObserver* observer) { if (!observer->IsExecutionContextLifecycleObserver()) return; @@ -141,30 +141,30 @@ void ExecutionContext::NotifyContextDestroyed() { is_context_destroyed_ = true; - context_lifecycle_observer_list_.ForEachObserver( + context_lifecycle_observer_set_.ForEachObserver( [](ContextLifecycleObserver* observer) { observer->ContextDestroyed(); - observer->ObserverListWillBeCleared(); + observer->ObserverSetWillBeCleared(); }); - context_lifecycle_observer_list_.Clear(); + context_lifecycle_observer_set_.Clear(); } void ExecutionContext::AddContextLifecycleObserver( ContextLifecycleObserver* observer) { - context_lifecycle_observer_list_.AddObserver(observer); + context_lifecycle_observer_set_.AddObserver(observer); } void ExecutionContext::RemoveContextLifecycleObserver( ContextLifecycleObserver* observer) { - DCHECK(context_lifecycle_observer_list_.HasObserver(observer)); - context_lifecycle_observer_list_.RemoveObserver(observer); + DCHECK(context_lifecycle_observer_set_.HasObserver(observer)); + context_lifecycle_observer_set_.RemoveObserver(observer); } unsigned ExecutionContext::ContextLifecycleStateObserverCountForTesting() const { - DCHECK(!context_lifecycle_observer_list_.IsIteratingOverObservers()); + DCHECK(!context_lifecycle_observer_set_.IsIteratingOverObservers()); unsigned lifecycle_state_observers = 0; - context_lifecycle_observer_list_.ForEachObserver( + context_lifecycle_observer_set_.ForEachObserver( [&](ContextLifecycleObserver* observer) { if (!observer->IsExecutionContextLifecycleObserver()) return; @@ -391,7 +391,7 @@ visitor->Trace(pending_exceptions_); visitor->Trace(csp_delegate_); visitor->Trace(timers_); - visitor->Trace(context_lifecycle_observer_list_); + visitor->Trace(context_lifecycle_observer_set_); visitor->Trace(origin_trial_context_); ContextLifecycleNotifier::Trace(visitor); ConsoleLogger::Trace(visitor);
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h index e1264a3..f1ff5a6 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.h +++ b/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -49,7 +49,7 @@ #include "third_party/blink/renderer/core/frame/dom_timer_coordinator.h" #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/console_logger.h" #include "third_party/blink/renderer/platform/loader/fetch/https_state.h" @@ -368,8 +368,8 @@ void AddContextLifecycleObserver(ContextLifecycleObserver*) override; void RemoveContextLifecycleObserver(ContextLifecycleObserver*) override; - HeapObserverList<ContextLifecycleObserver>& ContextLifecycleObserverList() { - return context_lifecycle_observer_list_; + HeapObserverSet<ContextLifecycleObserver>& ContextLifecycleObserverSet() { + return context_lifecycle_observer_set_; } unsigned ContextLifecycleStateObserverCountForTesting() const; @@ -439,7 +439,7 @@ DOMTimerCoordinator timers_; - HeapObserverList<ContextLifecycleObserver> context_lifecycle_observer_list_; + HeapObserverSet<ContextLifecycleObserver> context_lifecycle_observer_set_; // Counter that keeps track of how many window interaction calls are allowed // for this ExecutionContext. Callers are expected to call
diff --git a/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc b/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc index 25ae020..262c2900 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc
@@ -57,7 +57,7 @@ #endif if (ExecutionContext* context = GetExecutionContext()) { #if DCHECK_IS_ON() - DCHECK(context->ContextLifecycleObserverList().HasObserver(this)); + DCHECK(context->ContextLifecycleObserverSet().HasObserver(this)); #endif mojom::blink::FrameLifecycleState pause_state = context->ContextPauseState();
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.cc b/third_party/blink/renderer/core/frame/pausable_script_executor.cc index 2e7dcdc..88785f8 100644 --- a/third_party/blink/renderer/core/frame/pausable_script_executor.cc +++ b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -255,9 +255,9 @@ void PausableScriptExecutor::Dispose() { // Remove object as a ExecutionContextLifecycleObserver. // TODO(keishi): Remove IsIteratingOverObservers() check when - // HeapObserverList() supports removal while iterating. + // HeapObserverSet() supports removal while iterating. if (!GetExecutionContext() - ->ContextLifecycleObserverList() + ->ContextLifecycleObserverSet() .IsIteratingOverObservers()) { SetExecutionContext(nullptr); }
diff --git a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc index 78163e2..f53e8aa 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
@@ -278,9 +278,9 @@ void AutoplayUmaHelper::MaybeUnregisterContextDestroyedObserver() { // TODO(keishi): Remove IsIteratingOverObservers() check when - // HeapObserverList() supports removal while iterating. + // HeapObserverSet() supports removal while iterating. if (!ShouldListenToContextDestroyed() && !GetExecutionContext() - ->ContextLifecycleObserverList() + ->ContextLifecycleObserverSet() .IsIteratingOverObservers()) { SetExecutionContext(nullptr); }
diff --git a/third_party/blink/renderer/core/layout/layout_progress.cc b/third_party/blink/renderer/core/layout/layout_progress.cc index de62561..e49c4dfb 100644 --- a/third_party/blink/renderer/core/layout/layout_progress.cc +++ b/third_party/blink/renderer/core/layout/layout_progress.cc
@@ -62,7 +62,8 @@ double LayoutProgress::AnimationProgress() const { if (!animating_) return 0; - base::TimeDelta elapsed = base::TimeTicks::Now() - animation_start_time_; + const base::TimeDelta elapsed = + base::TimeTicks::Now() - animation_start_time_; return (elapsed % animation_duration_) / animation_duration_; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc index 15ce9116..6364c6a 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -146,24 +146,19 @@ } NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutChildren() { - scoped_refptr<const NGBlockBreakToken> legend_break_token; scoped_refptr<const NGBlockBreakToken> content_break_token; bool has_seen_all_children = false; if (const auto* token = BreakToken()) { const auto child_tokens = token->ChildBreakTokens(); if (wtf_size_t break_token_count = child_tokens.size()) { - DCHECK_LE(break_token_count, 2u); - for (wtf_size_t break_token_idx = 0; break_token_idx < break_token_count; - break_token_idx++) { - scoped_refptr<const NGBlockBreakToken> child_token = - To<NGBlockBreakToken>(child_tokens[break_token_idx]); - if (child_token && child_token->InputNode().IsRenderedLegend()) { - DCHECK_EQ(break_token_idx, 0u); - legend_break_token = child_token; - } else { - content_break_token = child_token; - } + scoped_refptr<const NGBlockBreakToken> child_token = + To<NGBlockBreakToken>(child_tokens[0]); + if (child_token) { + DCHECK(!child_token->InputNode().IsRenderedLegend()); + content_break_token = child_token; } + // There shouldn't be any additional break tokens. + DCHECK_EQ(child_tokens.size(), 1u); } if (token->HasSeenAllChildren()) { container_builder_.SetHasSeenAllChildren(); @@ -172,14 +167,8 @@ } NGBlockNode legend = Node().GetRenderedLegend(); - bool legend_needs_layout = - legend && (legend_break_token || !IsResumingLayout(BreakToken())); - - if (legend_needs_layout) { - NGBreakStatus break_status = LayoutLegend(legend, legend_break_token); - if (break_status != NGBreakStatus::kContinue) - return break_status; - + if (legend && !IsResumingLayout(BreakToken())) { + LayoutLegend(legend); // The legend may eat from the available content box block size. Calculate // the minimum block size needed to encompass the legend. if (!Node().ShouldApplySizeContainment()) { @@ -231,11 +220,6 @@ // all live inside an anonymous child box of the fieldset container. auto fieldset_content = Node().GetFieldsetContent(); if (fieldset_content && (content_break_token || !has_seen_all_children)) { - if (ConstraintSpace().HasBlockFragmentation() && legend_broke_ && - IsFragmentainerOutOfSpace(ConstraintSpace().FragmentainerOffsetAtBfc() + - intrinsic_block_size_)) - return NGBreakStatus::kContinue; - NGBreakStatus break_status = LayoutFieldsetContent(fieldset_content, content_break_token, adjusted_padding_box_size, !!legend); @@ -253,9 +237,7 @@ return NGBreakStatus::kContinue; } -NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutLegend( - NGBlockNode& legend, - scoped_refptr<const NGBlockBreakToken> legend_break_token) { +void NGFieldsetLayoutAlgorithm::LayoutLegend(NGBlockNode& legend) { // Lay out the legend. While the fieldset container normally ignores its // padding, the legend is laid out within what would have been the content // box had the fieldset been a regular block with no weirdness. @@ -265,101 +247,47 @@ legend.Style(), percentage_size.inline_size, ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction()); - if (legend_break_token) - legend_margins.block_start = LayoutUnit(); - - scoped_refptr<const NGLayoutResult> result; - scoped_refptr<const NGLayoutResult> previous_result; LayoutUnit block_offset; - do { - auto legend_space = CreateConstraintSpaceForLegend( - legend, ChildAvailableSize(), percentage_size, block_offset); - result = legend.Layout(legend_space, legend_break_token.get()); + auto legend_space = CreateConstraintSpaceForLegend( + legend, ChildAvailableSize(), percentage_size); + scoped_refptr<const NGLayoutResult> result = + legend.Layout(legend_space, BreakToken()); - // TODO(layout-dev): Handle abortions caused by block fragmentation. - DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess); + // TODO(layout-dev): Handle abortions caused by block fragmentation. + DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess); - if (ConstraintSpace().HasBlockFragmentation()) { - NGBreakStatus break_status = BreakBeforeChildIfNeeded( - ConstraintSpace(), legend, *result.get(), - ConstraintSpace().FragmentainerOffsetAtBfc() + block_offset, - /*has_container_separation*/ false, &container_builder_); - if (break_status != NGBreakStatus::kContinue) - return break_status; - EBreakBetween break_after = JoinFragmentainerBreakValues( - result->FinalBreakAfter(), legend.Style().BreakAfter()); - container_builder_.SetPreviousBreakAfter(break_after); - } + const auto& physical_fragment = result->PhysicalFragment(); - const auto& physical_fragment = result->PhysicalFragment(); - legend_broke_ = physical_fragment.BreakToken(); + LayoutUnit legend_border_box_block_size = + NGFragment(writing_mode_, physical_fragment).BlockSize(); + LayoutUnit legend_margin_box_block_size = legend_margins.block_start + + legend_border_box_block_size + + legend_margins.block_end; - // We have already adjusted the legend block offset, no need to adjust - // again. - if (block_offset != LayoutUnit()) { - // If adjusting the block_offset caused the legend to break, revert back - // to the previous result. - if (legend_broke_) { - result = std::move(previous_result); - block_offset = LayoutUnit(); - } - break; - } + LayoutUnit space_left = borders_.block_start - legend_border_box_block_size; + if (space_left > LayoutUnit()) { + // https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements + // * The element is expected to be positioned in the block-flow direction + // such that its border box is centered over the border on the + // block-start side of the fieldset element. + block_offset += space_left / 2; + } + // If the border is smaller than the block end offset of the legend margin + // box, intrinsic_block_size_ should now be based on the the block end + // offset of the legend margin box instead of the border. + LayoutUnit legend_margin_end_offset = + block_offset + legend_margin_box_block_size - legend_margins.block_start; + if (legend_margin_end_offset > borders_.block_start) { + intrinsic_block_size_ = legend_margin_end_offset; - LayoutUnit legend_border_box_block_size = - NGFragment(writing_mode_, physical_fragment).BlockSize(); - LayoutUnit legend_margin_box_block_size = - legend_margins.block_start + legend_border_box_block_size; + is_legend_past_border_ = true; - LayoutUnit block_end_margin = legend_margins.block_end; - if (ConstraintSpace().HasKnownFragmentainerBlockSize()) { - block_end_margin = AdjustedMarginAfterFinalChildFragment( - ConstraintSpace(), legend_margin_box_block_size, block_end_margin); - } - legend_margin_box_block_size += block_end_margin; - - LayoutUnit space_left = borders_.block_start - legend_border_box_block_size; - if (space_left > LayoutUnit()) { - // Don't adjust the block-start offset of the legend if the legend broke. - if (legend_break_token || legend_broke_) - break; - - // https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements - // * The element is expected to be positioned in the block-flow direction - // such that its border box is centered over the border on the - // block-start side of the fieldset element. - block_offset += space_left / 2; - if (ConstraintSpace().HasBlockFragmentation()) { - // Save the previous result in case adjusting the block_offset causes - // the legend to break. - previous_result = std::move(result); - continue; - } - } - // If the border is smaller than the block end offset of the legend margin - // box, intrinsic_block_size_ should now be based on the the block end - // offset of the legend margin box instead of the border. - LayoutUnit legend_margin_end_offset = block_offset + - legend_margin_box_block_size - - legend_margins.block_start; - if (legend_margin_end_offset > borders_.block_start) { - intrinsic_block_size_ = legend_margin_end_offset; - - is_legend_past_border_ = true; - - // Don't adjust the block-start offset of the fragment border if it broke. - if (BreakToken() || (ConstraintSpace().HasKnownFragmentainerBlockSize() && - legend_margin_end_offset > - ConstraintSpace().FragmentainerBlockSize())) - break; - // If the legend is larger than the width of the fieldset block-start - // border, the actual padding edge of the fieldset will be moved - // accordingly. This will be the block-start offset for the fieldset - // contents anonymous box. - borders_.block_start = legend_margin_end_offset; - } - break; - } while (true); + // If the legend is larger than the width of the fieldset block-start + // border, the actual padding edge of the fieldset will be moved + // accordingly. This will be the block-start offset for the fieldset + // contents anonymous box. + borders_.block_start = legend_margin_end_offset; + } // If the margin box of the legend is at least as tall as the fieldset // block-start border width, it will start at the block-start border edge @@ -375,7 +303,6 @@ LogicalOffset legend_offset = {legend_inline_start, block_offset}; container_builder_.AddResult(*result, legend_offset); - return NGBreakStatus::kContinue; } LayoutUnit NGFieldsetLayoutAlgorithm::ComputeLegendInlineOffset( @@ -488,8 +415,7 @@ NGFieldsetLayoutAlgorithm::CreateConstraintSpaceForLegend( NGBlockNode legend, LogicalSize available_size, - LogicalSize percentage_size, - LayoutUnit block_offset) { + LogicalSize percentage_size) { NGConstraintSpaceBuilder builder( ConstraintSpace(), legend.Style().GetWritingMode(), /* is_new_fc */ true); SetOrthogonalFallbackInlineSizeIfNeeded(Style(), legend, &builder); @@ -498,12 +424,6 @@ builder.SetPercentageResolutionSize(percentage_size); builder.SetIsShrinkToFit(legend.Style().LogicalWidth().IsAuto()); builder.SetTextDirection(legend.Style().Direction()); - - if (ConstraintSpace().HasBlockFragmentation()) { - SetupSpaceBuilderForFragmentation(ConstraintSpace(), legend, block_offset, - &builder, /* is_new_fc */ true); - builder.SetEarlyBreakAppeal(container_builder_.BreakAppeal()); - } return builder.ToConstraintSpace(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h index 76c61a3..d861135 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
@@ -37,9 +37,7 @@ private: NGBreakStatus LayoutChildren(); - NGBreakStatus LayoutLegend( - NGBlockNode& legend, - scoped_refptr<const NGBlockBreakToken> legend_break_token); + void LayoutLegend(NGBlockNode& legend); NGBreakStatus LayoutFieldsetContent( NGBlockNode& fieldset_content, scoped_refptr<const NGBlockBreakToken> content_break_token, @@ -49,13 +47,11 @@ const NGConstraintSpace CreateConstraintSpaceForLegend( NGBlockNode legend, LogicalSize available_size, - LogicalSize percentage_size, - LayoutUnit block_offset); + LogicalSize percentage_size); const NGConstraintSpace CreateConstraintSpaceForFieldsetContent( NGBlockNode fieldset_content, LogicalSize padding_box_size, LayoutUnit block_offset); - bool IsFragmentainerOutOfSpace(LayoutUnit block_offset) const; const WritingMode writing_mode_; @@ -76,10 +72,6 @@ // fragments. LayoutUnit consumed_border_block_start_; - // If true, this indicates that the legend broke during the current layout - // pass. - bool legend_broke_ = false; - // If true, the legend is taller than the block-start border, so that it // sticks below it, allowing for a class C breakpoint [1] before any fieldset // content.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc index 3937652a..a46b3a7 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
@@ -781,8 +781,8 @@ EXPECT_EQ(expectation, dump); } -// Tests that a fieldset with auto height will fragment when its legend reaches -// the fragmentation line. +// Tests that a fieldset with auto height will not fragment when its legend +// reaches the fragmentation line. TEST_F(NGFieldsetLayoutAlgorithmTest, LegendFragmentationAutoHeight) { SetBodyInnerHTML(R"HTML( <style> @@ -811,20 +811,12 @@ ASSERT_TRUE(fragment->BreakToken()); String dump = DumpFragmentTree(fragment.get()); + // TODO(crbug.com/1097012): The height of the outermost fragment here should + // be 500, not 490, but the fragmentation machinery gets confused by the + // fieldset padding. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 -)DUMP"; - EXPECT_EQ(expectation, dump); - - fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( - node, space, fragment->BreakToken()); - ASSERT_TRUE(fragment->BreakToken()); - - dump = DumpFragmentTree(fragment.get()); - expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 + offset:unplaced size:176x490 + offset:13,0 size:50x500 )DUMP"; EXPECT_EQ(expectation, dump); @@ -834,14 +826,13 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x123 - offset:13,0 size:50x100 - offset:3,100 size:170x20 + offset:unplaced size:176x23 + offset:3,0 size:170x20 )DUMP"; EXPECT_EQ(expectation, dump); } -// Tests that a fieldset with a set height will fragment when its legend +// Tests that a fieldset with a set height will not fragment when its legend // reaches the fragmentation line. The used height should also be extended to // encompass the legend. TEST_F(NGFieldsetLayoutAlgorithmTest, LegendFragmentation) { @@ -872,20 +863,12 @@ ASSERT_TRUE(fragment->BreakToken()); String dump = DumpFragmentTree(fragment.get()); + // TODO(crbug.com/1097012): The height of the outermost fragment here should + // be 500, not 490, but the fragmentation machinery gets confused by the + // fieldset padding. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 -)DUMP"; - EXPECT_EQ(expectation, dump); - - fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( - node, space, fragment->BreakToken()); - ASSERT_TRUE(fragment->BreakToken()); - - dump = DumpFragmentTree(fragment.get()); - expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 + offset:unplaced size:176x490 + offset:13,0 size:50x500 )DUMP"; EXPECT_EQ(expectation, dump); @@ -894,16 +877,19 @@ ASSERT_FALSE(fragment->BreakToken()); dump = DumpFragmentTree(fragment.get()); + // TODO(crbug.com/1097012): The height of the outermost fragment here should + // be 23, not 0, but the fragmentation machinery gets confused by the + // fieldset padding. expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x123 - offset:13,0 size:50x100 - offset:3,100 size:170x20 + offset:unplaced size:176x0 + offset:3,0 size:170x20 )DUMP"; EXPECT_EQ(expectation, dump); } -// Tests that a fieldset with auto height will fragment when its legend/content -// reaches the fragmentation line. +// Tests that a fieldset with auto height will not fragment when its legend +// reaches the fragmentation line. The content of the fieldset should fragment +// when it reaches the fragmentation line. TEST_F(NGFieldsetLayoutAlgorithmTest, LegendAndContentFragmentationAutoHeight) { SetBodyInnerHTML(R"HTML( <style> @@ -936,36 +922,26 @@ ASSERT_TRUE(fragment->BreakToken()); String dump = DumpFragmentTree(fragment.get()); + // TODO(crbug.com/1097012): The height of the outermost fragment here should + // be 500, not 490, but the fragmentation machinery gets confused by the + // fieldset padding. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 + offset:unplaced size:176x490 + offset:13,0 size:50x500 )DUMP"; EXPECT_EQ(expectation, dump); fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( node, space, fragment->BreakToken()); ASSERT_TRUE(fragment->BreakToken()); - - dump = DumpFragmentTree(fragment.get()); - expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 -)DUMP"; - EXPECT_EQ(expectation, dump); - - fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( - node, space, fragment->BreakToken()); - ASSERT_TRUE(fragment->BreakToken()); - - dump = DumpFragmentTree(fragment.get()); // TODO(crbug.com/1097012): The height of the outermost fragment here should // be 200, not 190, but the fragmentation machinery gets confused by the // fieldset padding. + dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:176x190 - offset:13,0 size:50x100 - offset:3,100 size:170x100 - offset:10,10 size:100x90 + offset:3,0 size:170x200 + offset:10,10 size:100x190 )DUMP"; EXPECT_EQ(expectation, dump); @@ -975,14 +951,15 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x123 - offset:3,0 size:170x120 - offset:10,0 size:100x110 + offset:unplaced size:176x23 + offset:3,0 size:170x20 + offset:10,0 size:100x10 )DUMP"; EXPECT_EQ(expectation, dump); } -// Tests that a fieldset with a set height will fragment when its legend/content +// Tests that a fieldset with a set height will fragment when its legend reaches +// the fragmentation line. The content of the fieldset should fragment when it // reaches the fragmentation line. TEST_F(NGFieldsetLayoutAlgorithmTest, LegendAndContentFragmentation) { SetBodyInnerHTML(R"HTML( @@ -1016,45 +993,34 @@ ASSERT_TRUE(fragment->BreakToken()); String dump = DumpFragmentTree(fragment.get()); + // TODO(crbug.com/1097012): The height of the outermost fragment here should + // be 500, not 490, but the fragmentation machinery gets confused by the + // fieldset padding. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 + offset:unplaced size:176x490 + offset:13,0 size:50x500 )DUMP"; EXPECT_EQ(expectation, dump); fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( node, space, fragment->BreakToken()); ASSERT_TRUE(fragment->BreakToken()); - dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x200 - offset:13,0 size:50x200 -)DUMP"; - EXPECT_EQ(expectation, dump); - - fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( - node, space, fragment->BreakToken()); - ASSERT_TRUE(fragment->BreakToken()); - - dump = DumpFragmentTree(fragment.get()); - expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:176x123 - offset:13,0 size:50x100 - offset:3,100 size:170x20 - offset:10,10 size:100x90 + offset:unplaced size:176x0 + offset:3,0 size:170x20 + offset:10,10 size:100x190 )DUMP"; EXPECT_EQ(expectation, dump); fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( node, space, fragment->BreakToken()); ASSERT_FALSE(fragment->BreakToken()); - dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:176x0 offset:3,0 size:170x0 - offset:10,0 size:100x110 + offset:10,0 size:100x10 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1070,7 +1036,7 @@ <div style="width:55px; height:150px;"></div> </legend> <div style="width:44px; height:150px;"></div> - </div> + </fieldset> )HTML"); LayoutUnit kFragmentainerSpaceAvailable(100); @@ -1089,7 +1055,7 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x100 offset:0,0 size:55x30 - offset:0,0 size:55x100 + offset:0,0 size:55x150 offset:0,30 size:1000x70 offset:0,0 size:44x70 )DUMP"; @@ -1102,8 +1068,6 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x80 - offset:0,0 size:55x0 - offset:0,0 size:55x50 offset:0,0 size:1000x80 offset:0,0 size:44x80 )DUMP"; @@ -1195,30 +1159,18 @@ scoped_refptr<const NGPhysicalBoxFragment> fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space); - ASSERT_TRUE(fragment->BreakToken()); + ASSERT_FALSE(fragment->BreakToken()); String dump = DumpFragmentTree(fragment.get()); String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:100x100 offset:0,0 size:75x60 - offset:0,0 size:50x100 + offset:0,0 size:50x120 + offset:0,120 size:40x20 offset:0,60 size:100x40 offset:0,0 size:85x10 )DUMP"; EXPECT_EQ(expectation, dump); - - fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm( - node, space, fragment->BreakToken()); - ASSERT_FALSE(fragment->BreakToken()); - - dump = DumpFragmentTree(fragment.get()); - expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:100x0 - offset:0,0 size:75x0 - offset:0,0 size:50x20 - offset:0,20 size:40x20 -)DUMP"; - EXPECT_EQ(expectation, dump); } TEST_F(NGFieldsetLayoutAlgorithmTest, OverflowedFieldsetContent) { @@ -1258,7 +1210,7 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:100x100 offset:0,0 size:75x10 - offset:0,0 size:50x100 + offset:0,0 size:50x220 offset:0,10 size:100x90 offset:0,0 size:85x10 offset:0,10 size:65x10 @@ -1273,8 +1225,6 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:100x0 - offset:0,0 size:75x0 - offset:0,0 size:50x100 offset:0,0 size:100x0 offset:0,0 size:65x0 offset:0,0 size:51x100 @@ -1288,8 +1238,6 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:100x0 - offset:0,0 size:75x0 - offset:0,0 size:50x20 offset:0,0 size:100x0 offset:0,0 size:65x0 offset:0,0 size:51x40 @@ -1442,8 +1390,10 @@ String dump = DumpFragmentTree(fragment.get()); String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:1000x100 + offset:unplaced size:1000x110 offset:0,0 size:20x50 + offset:0,50 size:100x60 + offset:0,0 size:10x60 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1453,10 +1403,9 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:1000x60 - offset:0,0 size:100x60 - offset:0,0 size:10x60 - offset:0,60 size:100x0 + offset:unplaced size:1000x0 + offset:0,0 size:100x0 + offset:0,0 size:100x0 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1530,7 +1479,7 @@ <div id="container"> <div style="width:20px; height:90px;"></div> <fieldset id="fieldset"> - <legend id="legend" style="break-before:avoid; break-inside:avoid"></legend> + <legend id="legend" style="break-before:avoid;"></legend> </fieldset> </div> )HTML"); @@ -1549,8 +1498,10 @@ String dump = DumpFragmentTree(fragment.get()); String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:1000x100 + offset:unplaced size:1000x125 offset:0,0 size:20x90 + offset:0,90 size:120x35 + offset:20,0 size:10x25 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1560,10 +1511,9 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:1000x45 - offset:0,0 size:120x45 - offset:20,0 size:10x25 - offset:10,35 size:100x0 + offset:unplaced size:1000x10 + offset:0,0 size:120x10 + offset:10,0 size:100x0 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1659,6 +1609,8 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x100 offset:0,0 size:20x50 + offset:0,50 size:100x50 + offset:0,0 size:10x50 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1668,10 +1620,9 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:1000x75 - offset:0,0 size:100x75 - offset:0,0 size:10x50 - offset:0,50 size:100x25 + offset:unplaced size:1000x25 + offset:0,0 size:100x25 + offset:0,0 size:100x25 offset:0,0 size:15x25 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1710,8 +1661,11 @@ ASSERT_TRUE(fragment->BreakToken()); String dump = DumpFragmentTree(fragment.get()); + // TODO(crbug.com/1097012): The height of the outermost fragment here should + // be 100, not 110, but the fragmentation machinery gets confused + // and includes the margin bottom. String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:100x100 + offset:unplaced size:100x110 offset:0,0 size:0x90 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1763,7 +1717,7 @@ String dump = DumpFragmentTree(fragment.get()); String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:220x60 - offset:60,0 size:10x40 + offset:60,5 size:10x50 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1774,7 +1728,6 @@ dump = DumpFragmentTree(fragment.get()); expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:220x10 - offset:60,0 size:10x10 offset:60,0 size:100x10 )DUMP"; EXPECT_EQ(expectation, dump);
diff --git a/third_party/blink/renderer/core/loader/private/prerender_handle.cc b/third_party/blink/renderer/core/loader/private/prerender_handle.cc index a853a8c..51b6fd76 100644 --- a/third_party/blink/renderer/core/loader/private/prerender_handle.cc +++ b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
@@ -104,7 +104,7 @@ PrerenderHandle::~PrerenderHandle() = default; void PrerenderHandle::Dispose() { - if (remote_handle_.is_bound()) + if (remote_handle_.is_bound() && !GetExecutionContext()->IsContextDestroyed()) remote_handle_->Abandon(); Detach(); }
diff --git a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc index 382ca30..047e741 100644 --- a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc +++ b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
@@ -322,9 +322,9 @@ void Dispose() { parent_ = nullptr; // TODO(keishi): Remove IsIteratingOverObservers() check when - // HeapObserverList() supports removal while iterating. + // HeapObserverSet() supports removal while iterating. if (!GetExecutionContext() - ->ContextLifecycleObserverList() + ->ContextLifecycleObserverSet() .IsIteratingOverObservers()) { SetExecutionContext(nullptr); }
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 9639965..1b35bb8 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -531,7 +531,7 @@ if (is_initial_state) return; - page_visibility_observer_list_.ForEachObserver( + page_visibility_observer_set_.ForEachObserver( [](PageVisibilityObserver* observer) { observer->PageVisibilityChanged(); }); @@ -896,7 +896,7 @@ visitor->Trace(focus_controller_); visitor->Trace(context_menu_controller_); visitor->Trace(page_scale_constraints_set_); - visitor->Trace(page_visibility_observer_list_); + visitor->Trace(page_visibility_observer_set_); visitor->Trace(pointer_lock_controller_); visitor->Trace(scrolling_coordinator_); visitor->Trace(browser_controls_); @@ -963,11 +963,11 @@ if (agent_metrics_collector_) agent_metrics_collector_->ReportMetrics(); - page_visibility_observer_list_.ForEachObserver( + page_visibility_observer_set_.ForEachObserver( [](PageVisibilityObserver* observer) { - observer->ObserverListWillBeCleared(); + observer->ObserverSetWillBeCleared(); }); - page_visibility_observer_list_.Clear(); + page_visibility_observer_set_.Clear(); page_scheduler_.reset(); }
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index 4671cf99..b136f3b8 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -40,7 +40,7 @@ #include "third_party/blink/renderer/core/page/viewport_description.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h" #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -350,8 +350,8 @@ return history_navigation_virtual_time_pauser_; } - HeapObserverList<PageVisibilityObserver>& PageVisibilityObserverList() { - return page_visibility_observer_list_; + HeapObserverSet<PageVisibilityObserver>& PageVisibilityObserverSet() { + return page_visibility_observer_set_; } static void PrepareForLeakDetection(); @@ -393,7 +393,7 @@ const Member<FocusController> focus_controller_; const Member<ContextMenuController> context_menu_controller_; const Member<PageScaleConstraintsSet> page_scale_constraints_set_; - HeapObserverList<PageVisibilityObserver> page_visibility_observer_list_; + HeapObserverSet<PageVisibilityObserver> page_visibility_observer_set_; const Member<PointerLockController> pointer_lock_controller_; Member<ScrollingCoordinator> scrolling_coordinator_; const Member<BrowserControls> browser_controls_;
diff --git a/third_party/blink/renderer/core/page/page_visibility_observer.cc b/third_party/blink/renderer/core/page/page_visibility_observer.cc index 9ad5f41..886d217 100644 --- a/third_party/blink/renderer/core/page/page_visibility_observer.cc +++ b/third_party/blink/renderer/core/page/page_visibility_observer.cc
@@ -12,7 +12,7 @@ SetPage(page); } -void PageVisibilityObserver::ObserverListWillBeCleared() { +void PageVisibilityObserver::ObserverSetWillBeCleared() { page_ = nullptr; } @@ -21,12 +21,12 @@ return; if (page_) - page_->PageVisibilityObserverList().RemoveObserver(this); + page_->PageVisibilityObserverSet().RemoveObserver(this); page_ = page; if (page_) - page_->PageVisibilityObserverList().AddObserver(this); + page_->PageVisibilityObserverSet().AddObserver(this); } void PageVisibilityObserver::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/page/page_visibility_observer.h b/third_party/blink/renderer/core/page/page_visibility_observer.h index 26aee047..5c8b5912ea 100644 --- a/third_party/blink/renderer/core/page/page_visibility_observer.h +++ b/third_party/blink/renderer/core/page/page_visibility_observer.h
@@ -39,7 +39,7 @@ virtual void PageVisibilityChanged() = 0; // Call before clearing an observer list. - void ObserverListWillBeCleared(); + void ObserverSetWillBeCleared(); Page* GetPage() const { return page_; } void SetPage(Page*);
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc index 1f73e42..7cfbc8e 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.cc +++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -860,6 +860,12 @@ script_state, engine_->controller_[branch]); } } + + // TODO(ricea): Implement https://github.com/whatwg/streams/pull/1045 so + // this step can be numbered correctly. + // Resolve |cancelPromise| with undefined. + engine_->cancel_promise_->ResolveWithUndefined(script_state); + // 3. Set closed to true. engine_->closed_ = true; @@ -1068,6 +1074,11 @@ // [[readableStreamController]], r). ReadableStreamDefaultController::Error(GetScriptState(), engine_->controller_[1], r); + + // TODO(ricea): Implement https://github.com/whatwg/streams/pull/1045 so + // this step can be numbered correctly. + // Resolve |cancelPromise| with undefined. + engine_->cancel_promise_->ResolveWithUndefined(GetScriptState()); } void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h b/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h index 1dcec7fa..50b4eb6 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h +++ b/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h
@@ -69,8 +69,6 @@ image, container_size_without_zoom, zoom, url)); } - bool IsSVGImageForContainer() const override { return true; } - IntSize Size() const override; FloatSize SizeAsFloat(RespectImageOrientationEnum) const override;
diff --git a/third_party/blink/renderer/modules/vibration/vibration_controller.cc b/third_party/blink/renderer/modules/vibration/vibration_controller.cc index 25162ef..df723d0d9 100644 --- a/third_party/blink/renderer/modules/vibration/vibration_controller.cc +++ b/third_party/blink/renderer/modules/vibration/vibration_controller.cc
@@ -181,6 +181,11 @@ void VibrationController::ContextDestroyed() { Cancel(); + + // If the document context was destroyed, never call the mojo service again. + // TODO(crbug.com/1116948): Remove this line once vibration_manager_ switches + // to kForceWithContextObserver. + vibration_manager_.reset(); } void VibrationController::PageVisibilityChanged() {
diff --git a/third_party/blink/renderer/modules/vibration/vibration_controller.h b/third_party/blink/renderer/modules/vibration/vibration_controller.h index 5828c6d..7d739da 100644 --- a/third_party/blink/renderer/modules/vibration/vibration_controller.h +++ b/third_party/blink/renderer/modules/vibration/vibration_controller.h
@@ -74,7 +74,14 @@ // Remote to VibrationManager mojo interface. This is reset in // |contextDestroyed| and must not be called or recreated after it is reset. - HeapMojoRemote<device::mojom::blink::VibrationManager> vibration_manager_; + // + // TODO(crbug.com/1116948): Remove kForceWithoutContextObserver parameter + // after hooking disconnect handler in js is implemented in + // MojoInterfaceInterceptor. + // See: third_party/blink/web_tests/vibration/vibration-iframe.html + HeapMojoRemote<device::mojom::blink::VibrationManager, + HeapMojoWrapperMode::kForceWithoutContextObserver> + vibration_manager_; // Timer for calling |doVibrate| after a delay. It is safe to call // |startOneshot| when the timer is already running: it may affect the time
diff --git a/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc b/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc index 1cce7bb..705c03ab 100644 --- a/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc +++ b/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
@@ -223,11 +223,10 @@ // stricter. static_assert(kCoarseResolution >= base::TimeDelta::FromSecondsD( TimeClamper::kResolutionSeconds), - "kCoarseResolutionInSeconds should be at least " - "as coarse as other clock resolutions"); - double clamped_time = time.FloorToMultiple(kCoarseResolution).InSecondsF(); + "kCoarseResolution should be at least as coarse as other clock " + "resolutions"); - return clamped_time; + return time.FloorToMultiple(kCoarseResolution).InSecondsF(); } int VideoFrameCallbackRequesterImpl::requestVideoFrameCallback(
diff --git a/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc b/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc index cf79960..c8b7a2c 100644 --- a/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc +++ b/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc
@@ -153,8 +153,8 @@ EXPECT_NE(processing_time.InSecondsF(), metadata->processingDuration()); } - double last_now() { return now_; } - bool was_invoked() { return was_invoked_; } + double last_now() const { return now_; } + bool was_invoked() const { return was_invoked_; } private: void VerifyTicksClamping(base::TimeTicks reference, @@ -167,11 +167,10 @@ } double TicksToClampedMillisecondsF(base::TimeTicks ticks) { - constexpr double kSecondsToMillis = 1000.0; return Performance::ClampTimeResolution( timing_.MonotonicTimeToZeroBasedDocumentTime(ticks) .InSecondsF()) * - kSecondsToMillis; + base::Time::kMillisecondsPerSecond; } double TicksToMillisecondsF(base::TimeTicks ticks) { @@ -180,12 +179,8 @@ } static double ClampElapsedProcessingTime(base::TimeDelta time) { - constexpr auto kProcessingTimeResolution = - base::TimeDelta::FromMicroseconds(100); - double clamped_time = - time.FloorToMultiple(kProcessingTimeResolution).InSecondsF(); - - return clamped_time; + return time.FloorToMultiple(base::TimeDelta::FromMicroseconds(100)) + .InSecondsF(); } double now_; @@ -344,7 +339,7 @@ EXPECT_CALL(*media_player(), GetVideoFramePresentationMetadata()) .WillOnce(Return(ByMove(MetadataHelper::CopyDefaultMedatada()))); - double now_ms = + const double now_ms = timing.MonotonicTimeToZeroBasedDocumentTime(base::TimeTicks::Now()) .InMillisecondsF();
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc index 8d3bba71..b97d72fd 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -289,7 +289,9 @@ } std::string codec_str = config->codec().Utf8(); - std::string profile_str = config->profile().Utf8(); + std::string profile_str; + if (config->hasProfile()) + profile_str = config->profile().Utf8(); auto codec_type = media::StringToVideoCodec(codec_str); if (codec_type == media::kUnknownVideoCodec) { HandleError(DOMExceptionCode::kNotFoundError, "Unknown codec type");
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index c0b7fd4..2f42d33 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1136,7 +1136,7 @@ "graphics/video_frame_submitter.h", "graphics/web_graphics_context_3d_provider_wrapper.cc", "graphics/web_graphics_context_3d_provider_wrapper.h", - "heap_observer_list.h", + "heap_observer_set.h", "image-decoders/bmp/bmp_image_decoder.cc", "image-decoders/bmp/bmp_image_decoder.h", "image-decoders/bmp/bmp_image_reader.cc", @@ -1935,7 +1935,7 @@ "graphics/placeholder_image_test.cc", "graphics/static_bitmap_image_test.cc", "graphics/video_frame_submitter_test.cc", - "heap_observer_list_test.cc", + "heap_observer_set_test.cc", "image-decoders/bmp/bmp_image_decoder_test.cc", "image-decoders/fast_shared_buffer_reader_test.cc", "image-decoders/gif/gif_image_decoder_test.cc",
diff --git a/third_party/blink/renderer/platform/context_lifecycle_observer.cc b/third_party/blink/renderer/platform/context_lifecycle_observer.cc index e0b406f..9beb179 100644 --- a/third_party/blink/renderer/platform/context_lifecycle_observer.cc +++ b/third_party/blink/renderer/platform/context_lifecycle_observer.cc
@@ -8,7 +8,7 @@ namespace blink { -void ContextLifecycleObserver::ObserverListWillBeCleared() { +void ContextLifecycleObserver::ObserverSetWillBeCleared() { notifier_ = nullptr; }
diff --git a/third_party/blink/renderer/platform/context_lifecycle_observer.h b/third_party/blink/renderer/platform/context_lifecycle_observer.h index b4a4198..bc034a9 100644 --- a/third_party/blink/renderer/platform/context_lifecycle_observer.h +++ b/third_party/blink/renderer/platform/context_lifecycle_observer.h
@@ -18,7 +18,7 @@ virtual void ContextDestroyed() = 0; // Call before clearing an observer list. - void ObserverListWillBeCleared(); + void ObserverSetWillBeCleared(); ContextLifecycleNotifier* GetContextLifecycleNotifier() const { return notifier_;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc index 6684ac6..d81d3a73 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -46,6 +46,8 @@ #endif // DCHECK_IS_ON() const size_t kMaxCacheSize = 1024u; +const int kMinImageLength = 8; +const int kMaxImageLength = 100; // TODO(gilmanmh): If grayscaling images in dark mode proves popular among // users, consider experimenting with different grayscale algorithms. @@ -88,9 +90,7 @@ DarkModeFilter::DarkModeFilter() : text_classifier_(nullptr), background_classifier_(nullptr), - bitmap_image_classifier_(nullptr), - svg_image_classifier_(nullptr), - gradient_generated_image_classifier_(nullptr), + image_classifier_(nullptr), color_filter_(nullptr), image_filter_(nullptr), inverted_color_cache_(new DarkModeInvertedColorCache()) { @@ -131,11 +131,7 @@ DarkModeColorClassifier::MakeTextColorClassifier(settings_); background_classifier_ = DarkModeColorClassifier::MakeBackgroundColorClassifier(settings_); - bitmap_image_classifier_ = - DarkModeImageClassifier::MakeBitmapImageClassifier(); - svg_image_classifier_ = DarkModeImageClassifier::MakeSVGImageClassifier(); - gradient_generated_image_classifier_ = - DarkModeImageClassifier::MakeGradientGeneratedImageClassifier(); + image_classifier_ = std::make_unique<DarkModeImageClassifier>(); } SkColor DarkModeFilter::InvertColorIfNeeded(SkColor color, ElementRole role) { @@ -152,22 +148,42 @@ return color; } +bool DarkModeFilter::AnalyzeShouldApplyToImage(const SkRect& src, + const SkRect& dst) { + if (settings().image_policy == DarkModeImagePolicy::kFilterNone) + return false; + + if (settings().image_policy == DarkModeImagePolicy::kFilterAll) + return true; + + // Images being drawn from very smaller |src| rect, i.e. one of the dimensions + // is very small, can be used for the border around the content or showing + // separator. Consider these images irrespective of size of the rect being + // drawn to. Classifying them will not be too costly. + if (src.width() <= kMinImageLength || src.height() <= kMinImageLength) + return true; + + // Do not consider images being drawn into bigger rect as these images are not + // meant for icons or representing smaller widgets. These images are + // considered as photos which should be untouched. + return (dst.width() <= kMaxImageLength && dst.height() <= kMaxImageLength); +} + void DarkModeFilter::ApplyToImageFlagsIfNeeded(const SkRect& src, const SkRect& dst, const PaintImage& paint_image, - cc::PaintFlags* flags, - ElementRole element_role) { + cc::PaintFlags* flags) { // The construction of |paint_image| is expensive, so ensure // IsDarkModeActive() is checked prior to calling this function. // See: https://crbug.com/1094781. DCHECK(IsDarkModeActive()); - if (!image_filter_ || - !ShouldApplyToImage(settings(), src, dst, paint_image, element_role)) { + if (!image_filter_ || !AnalyzeShouldApplyToImage(src, dst)) return; - } - flags->setColorFilter(image_filter_); + if (ClassifyImage(settings(), src, dst, paint_image) == + DarkModeClassification::kApplyFilter) + flags->setColorFilter(image_filter_); } base::Optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded( @@ -235,38 +251,21 @@ return inverted_color_cache_->size(); } -bool DarkModeFilter::ShouldApplyToImage(const DarkModeSettings& settings, - const SkRect& src, - const SkRect& dst, - const PaintImage& paint_image, - ElementRole role) { +DarkModeClassification DarkModeFilter::ClassifyImage( + const DarkModeSettings& settings, + const SkRect& src, + const SkRect& dst, + const PaintImage& paint_image) { switch (settings.image_policy) { - case DarkModeImagePolicy::kFilterSmart: { - DarkModeImageClassifier* classifier; - - switch (role) { - case ElementRole::kBitmapImage: - classifier = bitmap_image_classifier_.get(); - break; - case ElementRole::kSVGImage: - classifier = svg_image_classifier_.get(); - break; - case ElementRole::kGradientGeneratedImage: - classifier = gradient_generated_image_classifier_.get(); - break; - default: - return false; - } - - DarkModeClassification result = - classifier->Classify(paint_image, src, dst); - return result == DarkModeClassification::kApplyFilter; - } + case DarkModeImagePolicy::kFilterSmart: + return image_classifier_->Classify(paint_image, src, dst); case DarkModeImagePolicy::kFilterNone: - return false; + return DarkModeClassification::kDoNotApplyFilter; case DarkModeImagePolicy::kFilterAll: - return true; + return DarkModeClassification::kApplyFilter; } + + NOTREACHED(); } ScopedDarkModeElementRoleOverride::ScopedDarkModeElementRoleOverride(
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h index be66288..41a5fe8 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h +++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -10,6 +10,7 @@ #include "cc/paint/paint_flags.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" +#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_image.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -40,28 +41,24 @@ // TODO(gilmanmh): Add a role for shadows. In general, we don't want to // invert shadows, but we may need to do some other kind of processing for // them. - enum class ElementRole { - kText, - kListSymbol, - kBackground, - kSVG, - kUnhandledImage, - kBitmapImage, - kSVGImage, - kGradientGeneratedImage - }; + enum class ElementRole { kText, kListSymbol, kBackground, kSVG }; SkColor InvertColorIfNeeded(SkColor color, ElementRole element_role); base::Optional<cc::PaintFlags> ApplyToFlagsIfNeeded( const cc::PaintFlags& flags, ElementRole element_role); - // |image| and |flags| must not be null. + // Decides whether to apply dark mode or not based on |src| and |dst|. True + // means dark mode should be applied. For applying the dark mode color filter + // to the image call ApplyToImageFlagsIfNeeded(). + bool AnalyzeShouldApplyToImage(const SkRect& src, const SkRect& dst); + + // Sets dark mode color filter on the flags based on the classification done + // on |paint_image|. |flags| must not be null. void ApplyToImageFlagsIfNeeded(const SkRect& src, const SkRect& dst, const PaintImage& paint_image, - cc::PaintFlags* flags, - ElementRole element_role); + cc::PaintFlags* flags); SkColorFilter* GetImageFilterForTesting() { return image_filter_.get(); } size_t GetInvertedColorCacheSizeForTesting(); @@ -72,17 +69,14 @@ DarkModeSettings settings_; bool ShouldApplyToColor(SkColor color, ElementRole role); - bool ShouldApplyToImage(const DarkModeSettings& settings, - const SkRect& src, - const SkRect& dst, - const PaintImage& paint_image, - ElementRole role); + DarkModeClassification ClassifyImage(const DarkModeSettings& settings, + const SkRect& src, + const SkRect& dst, + const PaintImage& paint_image); std::unique_ptr<DarkModeColorClassifier> text_classifier_; std::unique_ptr<DarkModeColorClassifier> background_classifier_; - std::unique_ptr<DarkModeImageClassifier> bitmap_image_classifier_; - std::unique_ptr<DarkModeImageClassifier> svg_image_classifier_; - std::unique_ptr<DarkModeImageClassifier> gradient_generated_image_classifier_; + std::unique_ptr<DarkModeImageClassifier> image_classifier_; std::unique_ptr<DarkModeColorFilter> color_filter_; sk_sp<SkColorFilter> image_filter_;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc index da272d2..68b6a14 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
@@ -114,5 +114,41 @@ EXPECT_EQ(2u, filter.GetInvertedColorCacheSizeForTesting()); } +TEST(DarkModeFilterTest, AnalyzeShouldApplyToImage) { + DarkModeFilter filter; + DarkModeSettings settings; + settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting; + settings.image_policy = DarkModeImagePolicy::kFilterSmart; + filter.UpdateSettings(settings); + + // |dst| is smaller than threshold size. + EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(100, 100), + SkRect::MakeWH(100, 100))); + + // |dst| is smaller than threshold size, even |src| is larger. + EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(200, 200), + SkRect::MakeWH(100, 100))); + + // |dst| is smaller than threshold size, |src| is smaller. + EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 20), + SkRect::MakeWH(100, 100))); + + // |src| having very smaller width, even |dst| is larger than threshold size. + EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(5, 200), + SkRect::MakeWH(5, 200))); + + // |src| having very smaller height, even |dst| is larger than threshold size. + EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(200, 5), + SkRect::MakeWH(200, 5))); + + // |dst| is larger than threshold size. + EXPECT_FALSE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 20), + SkRect::MakeWH(200, 200))); + + // |dst| is larger than threshold size. + EXPECT_FALSE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 200), + SkRect::MakeWH(20, 200))); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc index 092acd4..653be20 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc
@@ -37,37 +37,6 @@ const int kMaxBlocks = 10; const float kMinOpaquePixelPercentageForForeground = 0.2; -const int kMinImageSizeForClassification1D = 24; -const int kMaxImageSizeForClassification1D = 100; - -class DarkModeBitmapImageClassifier : public DarkModeImageClassifier { - DarkModeClassification DoInitialClassification(const SkRect& dst) override { - if (dst.width() < kMinImageSizeForClassification1D || - dst.height() < kMinImageSizeForClassification1D) - return DarkModeClassification::kApplyFilter; - - if (dst.width() > kMaxImageSizeForClassification1D || - dst.height() > kMaxImageSizeForClassification1D) { - return DarkModeClassification::kDoNotApplyFilter; - } - - return DarkModeClassification::kNotClassified; - } -}; - -class DarkModeSVGImageClassifier : public DarkModeImageClassifier { - DarkModeClassification DoInitialClassification(const SkRect& dst) override { - return DarkModeClassification::kNotClassified; - } -}; - -class DarkModeGradientGeneratedImageClassifier - : public DarkModeImageClassifier { - DarkModeClassification DoInitialClassification(const SkRect& dst) override { - return DarkModeClassification::kApplyFilter; - } -}; - // DarkModeImageClassificationCache - Implements classification caches for // different paint image ids. The classification result for the given |src| // rect is added to cache identified by |image_id| and result for the same @@ -137,21 +106,6 @@ DarkModeImageClassifier::~DarkModeImageClassifier() = default; -std::unique_ptr<DarkModeImageClassifier> -DarkModeImageClassifier::MakeBitmapImageClassifier() { - return std::make_unique<DarkModeBitmapImageClassifier>(); -} - -std::unique_ptr<DarkModeImageClassifier> -DarkModeImageClassifier::MakeSVGImageClassifier() { - return std::make_unique<DarkModeSVGImageClassifier>(); -} - -std::unique_ptr<DarkModeImageClassifier> -DarkModeImageClassifier::MakeGradientGeneratedImageClassifier() { - return std::make_unique<DarkModeGradientGeneratedImageClassifier>(); -} - DarkModeClassification DarkModeImageClassifier::Classify( const PaintImage& paint_image, const SkRect& src, @@ -163,7 +117,6 @@ if (result != DarkModeClassification::kNotClassified) return result; - result = DoInitialClassification(dst); if (result != DarkModeClassification::kNotClassified) { cache->Add(image_id, src, result); return result;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h index 73045d72..50d53f3 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h
@@ -25,12 +25,8 @@ // results is not threadsafe. So it can be used only in blink main thread. class PLATFORM_EXPORT DarkModeImageClassifier { public: - virtual ~DarkModeImageClassifier(); - - static std::unique_ptr<DarkModeImageClassifier> MakeBitmapImageClassifier(); - static std::unique_ptr<DarkModeImageClassifier> MakeSVGImageClassifier(); - static std::unique_ptr<DarkModeImageClassifier> - MakeGradientGeneratedImageClassifier(); + DarkModeImageClassifier(); + ~DarkModeImageClassifier(); struct Features { // True if the image is in color, false if it is grayscale. @@ -56,11 +52,6 @@ // Removes cache identified by given |image_id|. static void RemoveCache(PaintImage::Id image_id); - protected: - DarkModeImageClassifier(); - - virtual DarkModeClassification DoInitialClassification(const SkRect& dst) = 0; - private: DarkModeClassification ClassifyWithFeatures(const Features& features); DarkModeClassification ClassifyUsingDecisionTree(const Features& features);
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc index 1a2ee13..709fb62 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc
@@ -22,8 +22,7 @@ class DarkModeImageClassifierTest : public testing::Test { public: DarkModeImageClassifierTest() { - dark_mode_image_classifier_ = - DarkModeImageClassifier::MakeBitmapImageClassifier(); + dark_mode_image_classifier_ = std::make_unique<DarkModeImageClassifier>(); } // Loads the image from |file_name|.
diff --git a/third_party/blink/renderer/platform/graphics/gradient_generated_image.h b/third_party/blink/renderer/platform/graphics/gradient_generated_image.h index 589bb5c3..1467cd05 100644 --- a/third_party/blink/renderer/platform/graphics/gradient_generated_image.h +++ b/third_party/blink/renderer/platform/graphics/gradient_generated_image.h
@@ -43,8 +43,6 @@ ~GradientGeneratedImage() override = default; - bool IsGradientGeneratedImage() const override { return true; } - bool ApplyShader(PaintFlags&, const SkMatrix&) override; protected:
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index f3df15b..562d39c 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -62,25 +62,6 @@ namespace blink { -namespace { -DarkModeFilter::ElementRole GetElementRoleForImage(Image* image) { - DCHECK(image); - - if (image->IsBitmapImage()) - return DarkModeFilter::ElementRole::kBitmapImage; - - if (image->IsSVGImage() || image->IsSVGImageForContainer()) - return DarkModeFilter::ElementRole::kSVGImage; - - if (image->IsGradientGeneratedImage()) - return DarkModeFilter::ElementRole::kGradientGeneratedImage; - - // TODO(prashant.n): Check if remaining image types need to be treated - // separately. - return DarkModeFilter::ElementRole::kUnhandledImage; -} -} // namespace - // Helper class that copies |flags| only when dark mode is enabled. // // TODO(gilmanmh): Investigate removing const from |flags| in the calling @@ -890,10 +871,10 @@ image_flags.setFilterQuality(ComputeFilterQuality(image, dest, src)); // Do not classify the image if the element has any CSS filters. - if (!has_filter_property && dark_mode_filter_.IsDarkModeActive()) { + if (!has_filter_property && dark_mode_filter_.IsDarkModeActive() && + dark_mode_filter_.AnalyzeShouldApplyToImage(src, dest)) { dark_mode_filter_.ApplyToImageFlagsIfNeeded( - src, dest, image->PaintImageForCurrentFrame(), &image_flags, - GetElementRoleForImage(image)); + src, dest, image->PaintImageForCurrentFrame(), &image_flags); } image->Draw(canvas_, image_flags, dest, src, should_respect_image_orientation, @@ -931,10 +912,11 @@ image_flags.setFilterQuality( ComputeFilterQuality(image, dest.Rect(), src_rect)); - if (dark_mode_filter_.IsDarkModeActive()) { + if (dark_mode_filter_.IsDarkModeActive() && + dark_mode_filter_.AnalyzeShouldApplyToImage(src_rect, dest.Rect())) { dark_mode_filter_.ApplyToImageFlagsIfNeeded( - src_rect, dest.Rect(), image->PaintImageForCurrentFrame(), &image_flags, - GetElementRoleForImage(image)); + src_rect, dest.Rect(), image->PaintImageForCurrentFrame(), + &image_flags); } bool use_shader = (visible_src == src_rect) &&
diff --git a/third_party/blink/renderer/platform/graphics/image.h b/third_party/blink/renderer/platform/graphics/image.h index bb5e190..0ab24e7 100644 --- a/third_party/blink/renderer/platform/graphics/image.h +++ b/third_party/blink/renderer/platform/graphics/image.h
@@ -87,11 +87,9 @@ InterpolationQuality = kInterpolationNone); virtual bool IsSVGImage() const { return false; } - virtual bool IsSVGImageForContainer() const { return false; } virtual bool IsBitmapImage() const { return false; } virtual bool IsStaticBitmapImage() const { return false; } virtual bool IsPlaceholderImage() const { return false; } - virtual bool IsGradientGeneratedImage() const { return false; } virtual bool CurrentFrameKnownToBeOpaque() = 0;
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc index 49eaf08..97590b9 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -200,12 +200,6 @@ return foreground_marking_time() + background_marking_time(); } -double ThreadHeapStatsCollector::Event::marking_time_in_bytes_per_second() - const { - return marked_bytes ? marking_time().InMillisecondsF() / 1000 / marked_bytes - : 0.0; -} - base::TimeDelta ThreadHeapStatsCollector::Event::gc_cycle_time() const { // Note that scopes added here also have to have a proper BlinkGCInV8Scope // scope if they are nested in a V8 scope.
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h index 081f4f0..344d439 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -265,9 +265,6 @@ // Overall time spent sweeping the heap. base::TimeDelta sweeping_time() const; - // Marking speed in bytes/s. - double marking_time_in_bytes_per_second() const; - // Marked bytes collected during sweeping. size_t unique_id = -1; size_t marked_bytes = 0;
diff --git a/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc b/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc index 2b5a7685..948cc8df 100644 --- a/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc +++ b/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h" +#include "base/numerics/ranges.h" + namespace blink { constexpr double MarkingSchedulingOracle::kEstimatedMarkingTimeMs; @@ -51,10 +53,8 @@ base::TimeDelta MarkingSchedulingOracle::GetMinimumStepDuration() { DCHECK_LT(0u, incrementally_marked_bytes_); DCHECK(!incremental_marking_time_so_far_.is_zero()); - base::TimeDelta minimum_duration = incremental_marking_time_so_far_ * - kMinimumMarkedBytesInStep / - incrementally_marked_bytes_; - return minimum_duration; + return incremental_marking_time_so_far_ * kMinimumMarkedBytesInStep / + incrementally_marked_bytes_; } base::TimeDelta MarkingSchedulingOracle::GetNextIncrementalStepDurationForTask( @@ -84,14 +84,12 @@ // up" by marking (|expected_marked_bytes| - |actual_marked_bytes|). // Assuming constant marking speed, duration of the next incremental step // should be as follows: - double marking_time_to_catch_up_in_ms = - (expected_marked_bytes - actual_marked_bytes) * - incremental_marking_time_so_far_.InMillisecondsF() / + const base::TimeDelta marking_time_to_catch_up = + incremental_marking_time_so_far_ * + (expected_marked_bytes - actual_marked_bytes) / incrementally_marked_bytes_; - return std::min( - kMaximumIncrementalMarkingStepDuration, - std::max(minimum_duration, base::TimeDelta::FromMillisecondsD( - marking_time_to_catch_up_in_ms))); + return base::ClampToRange(marking_time_to_catch_up, minimum_duration, + kMaximumIncrementalMarkingStepDuration); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc b/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc index 5ee689e..5e421f2 100644 --- a/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc +++ b/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc
@@ -364,20 +364,6 @@ stats_collector.previous().atomic_pause_time()); } -TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) { - ThreadHeapStatsCollector stats_collector; - stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting, - true /* is_forced_gc */); - stats_collector.IncreaseScopeTime( - ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure, - base::TimeDelta::FromSeconds(1)); - stats_collector.NotifyMarkingCompleted(1000); - stats_collector.NotifySweepingCompleted(); - EXPECT_DOUBLE_EQ( - .001, stats_collector.previous().marking_time_in_bytes_per_second()); -} - TEST(ThreadHeapStatsCollectorTest, EventSweepingTime) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
diff --git a/third_party/blink/renderer/platform/heap/test/write_barrier_perftest.cc b/third_party/blink/renderer/platform/heap/test/write_barrier_perftest.cc index 5c2c187..bc61502 100644 --- a/third_party/blink/renderer/platform/heap/test/write_barrier_perftest.cc +++ b/third_party/blink/renderer/platform/heap/test/write_barrier_perftest.cc
@@ -77,12 +77,10 @@ // Reporting. auto reporter = SetUpReporter("member_write_performance"); - reporter.AddResult( - kMetricWritesDuringGcRunsPerS, - static_cast<double>(kNumElements) / during_gc_duration.InSecondsF()); - reporter.AddResult( - kMetricWritesOutsideGcRunsPerS, - static_cast<double>(kNumElements) / outside_gc_duration.InSecondsF()); + reporter.AddResult(kMetricWritesDuringGcRunsPerS, + kNumElements / during_gc_duration.InSecondsF()); + reporter.AddResult(kMetricWritesOutsideGcRunsPerS, + kNumElements / outside_gc_duration.InSecondsF()); reporter.AddResult(kMetricRelativeSpeedDifferenceUnitless, during_gc_duration / outside_gc_duration); }
diff --git a/third_party/blink/renderer/platform/heap_observer_list.h b/third_party/blink/renderer/platform/heap_observer_set.h similarity index 83% rename from third_party/blink/renderer/platform/heap_observer_list.h rename to third_party/blink/renderer/platform/heap_observer_set.h index ac3baf9..87e7db7 100644 --- a/third_party/blink/renderer/platform/heap_observer_list.h +++ b/third_party/blink/renderer/platform/heap_observer_set.h
@@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_LIST_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_LIST_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_SET_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_SET_H_ #include "base/auto_reset.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { -// A list of observers. Ensures list is not mutated while iterating. Observers +// A set of observers. Ensures list is not mutated while iterating. Observers // are not retained. template <class ObserverType> -class PLATFORM_EXPORT HeapObserverList { +class PLATFORM_EXPORT HeapObserverSet { DISALLOW_NEW(); public: @@ -49,7 +49,8 @@ observers_.clear(); } - // Safely iterate over the registered lifecycle observers. + // Safely iterate over the registered lifecycle observers in an unpredictable + // order. // // Adding or removing observers is not allowed during iteration. The callable // will only be called synchronously inside ForEachObserver(). @@ -69,7 +70,7 @@ void Trace(Visitor* visitor) const { visitor->Trace(observers_); } private: - using ObserverSet = HeapLinkedHashSet<WeakMember<ObserverType>>; + using ObserverSet = HeapHashSet<WeakMember<ObserverType>>; // TODO(keishi): Clean up iteration state once transition from // LifecycleObserver is complete. @@ -88,4 +89,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_LIST_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_SET_H_
diff --git a/third_party/blink/renderer/platform/heap_observer_list_test.cc b/third_party/blink/renderer/platform/heap_observer_set_test.cc similarity index 69% rename from third_party/blink/renderer/platform/heap_observer_list_test.cc rename to third_party/blink/renderer/platform/heap_observer_set_test.cc index 225ac271..04c5b14 100644 --- a/third_party/blink/renderer/platform/heap_observer_list_test.cc +++ b/third_party/blink/renderer/platform/heap_observer_set_test.cc
@@ -24,7 +24,7 @@ * */ -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" @@ -37,12 +37,12 @@ public: TestingNotifier() = default; - HeapObserverList<TestingObserver>& ObserverList() { return observer_list_; } + HeapObserverSet<TestingObserver>& ObserverList() { return observer_list_; } void Trace(Visitor* visitor) const { visitor->Trace(observer_list_); } private: - HeapObserverList<TestingObserver> observer_list_; + HeapObserverSet<TestingObserver> observer_list_; }; class TestingObserver final : public GarbageCollected<TestingObserver> { @@ -56,12 +56,12 @@ int count_ = 0; }; -void Notify(HeapObserverList<TestingObserver>& observer_list) { +void Notify(HeapObserverSet<TestingObserver>& observer_list) { observer_list.ForEachObserver( [](TestingObserver* observer) { observer->OnNotification(); }); } -TEST(HeapObserverListTest, AddRemove) { +TEST(HeapObserverSetTest, AddRemove) { Persistent<TestingNotifier> notifier = MakeGarbageCollected<TestingNotifier>(); Persistent<TestingObserver> observer = @@ -79,7 +79,7 @@ EXPECT_EQ(observer->Count(), 1); } -TEST(HeapObserverListTest, HasObserver) { +TEST(HeapObserverSetTest, HasObserver) { Persistent<TestingNotifier> notifier = MakeGarbageCollected<TestingNotifier>(); Persistent<TestingObserver> observer = @@ -94,7 +94,7 @@ EXPECT_FALSE(notifier->ObserverList().HasObserver(observer.Get())); } -TEST(HeapObserverListTest, GarbageCollect) { +TEST(HeapObserverSetTest, GarbageCollect) { Persistent<TestingNotifier> notifier = MakeGarbageCollected<TestingNotifier>(); Persistent<TestingObserver> observer = @@ -111,7 +111,7 @@ EXPECT_EQ(weak_ref.Get(), nullptr); } -TEST(HeapObserverListTest, IsIteratingOverObservers) { +TEST(HeapObserverSetTest, IsIteratingOverObservers) { Persistent<TestingNotifier> notifier = MakeGarbageCollected<TestingNotifier>(); Persistent<TestingObserver> observer = @@ -124,42 +124,4 @@ }); } -TEST(HeapObserverListTest, ForEachObserverOrder) { - Persistent<TestingNotifier> notifier = - MakeGarbageCollected<TestingNotifier>(); - Persistent<TestingObserver> observer1 = - MakeGarbageCollected<TestingObserver>(); - Persistent<TestingObserver> observer2 = - MakeGarbageCollected<TestingObserver>(); - - HeapVector<Member<TestingObserver>> seen_observers; - - notifier->ObserverList().AddObserver(observer1); - notifier->ObserverList().AddObserver(observer2); - notifier->ObserverList().ForEachObserver( - [&](TestingObserver* observer) { seen_observers.push_back(observer); }); - - ASSERT_EQ(2u, seen_observers.size()); - EXPECT_EQ(observer1.Get(), seen_observers[0].Get()); - EXPECT_EQ(observer2.Get(), seen_observers[1].Get()); - - seen_observers.clear(); - - notifier->ObserverList().RemoveObserver(observer1); - notifier->ObserverList().AddObserver(observer1); - notifier->ObserverList().ForEachObserver( - [&](TestingObserver* observer) { seen_observers.push_back(observer); }); - - ASSERT_EQ(2u, seen_observers.size()); - EXPECT_EQ(observer2.Get(), seen_observers[0].Get()); - EXPECT_EQ(observer1.Get(), seen_observers[1].Get()); - - seen_observers.clear(); - - notifier->ObserverList().Clear(); - notifier->ObserverList().ForEachObserver( - [&](TestingObserver* observer) { seen_observers.push_back(observer); }); - ASSERT_EQ(0u, seen_observers.size()); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc b/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc index eb6cdc3..2a1a5050 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_api_request_body_mojom_traits.cc
@@ -28,7 +28,7 @@ if (mutable_body.StreamBody()) { auto out = blink::mojom::blink::FetchAPIDataElement::New(); - out->type = network::mojom::DataElementType::kChunkedDataPipe; + out->type = network::mojom::DataElementType::kReadOnceStream; out->chunked_data_pipe_getter = mutable_body.TakeStreamBody(); out_elements.push_back(std::move(out)); return out_elements; @@ -105,7 +105,7 @@ if (!view.ReadType(&type)) { return false; } - if (type == network::mojom::DataElementType::kChunkedDataPipe) { + if (type == network::mojom::DataElementType::kReadOnceStream) { auto chunked_data_pipe_getter = view.TakeChunkedDataPipeGetter< mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>>(); *out = blink::ResourceRequestBody(std::move(chunked_data_pipe_getter)); @@ -162,6 +162,7 @@ case network::mojom::DataElementType::kBlob: case network::mojom::DataElementType::kUnknown: case network::mojom::DataElementType::kChunkedDataPipe: + case network::mojom::DataElementType::kReadOnceStream: case network::mojom::DataElementType::kRawFile: NOTREACHED(); return false;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc index 3f3a945..b1050ec 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
@@ -358,7 +358,7 @@ dest->request_body = base::MakeRefCounted<network::ResourceRequestBody>(); mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter> network_stream_body(stream_body.PassPipe(), 0u); - dest->request_body->SetToChunkedDataPipe(std::move(network_stream_body)); + dest->request_body->SetToReadOnceStream(std::move(network_stream_body)); dest->request_body->SetAllowHTTP1ForStreamingUpload( src.AllowHTTP1ForStreamingUpload()); }
diff --git a/third_party/blink/renderer/platform/mojo/DEPS b/third_party/blink/renderer/platform/mojo/DEPS index 2748153..5a7db27e 100644 --- a/third_party/blink/renderer/platform/mojo/DEPS +++ b/third_party/blink/renderer/platform/mojo/DEPS
@@ -22,7 +22,7 @@ "+third_party/blink/renderer/platform/wtf", "+third_party/blink/renderer/platform/context_lifecycle_observer.h", "+third_party/blink/renderer/platform/context_lifecycle_notifier.h", - "+third_party/blink/renderer/platform/heap_observer_list.h", + "+third_party/blink/renderer/platform/heap_observer_set.h", "+third_party/blink/renderer/platform/heap", ]
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc index ce48d2e..3dc9d88 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set_test.cc
@@ -15,7 +15,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace blink { @@ -49,7 +49,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; template <HeapMojoWrapperMode Mode>
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc index 7972a26..95811f1 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace blink { @@ -41,7 +41,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; template <HeapMojoWrapperMode Mode>
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc index 349c21b..f8b016d 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_test.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace blink { @@ -41,7 +41,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; class ServiceImpl : public sample::blink::Service {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc index 56c1394..c7fb431 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc
@@ -15,7 +15,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace blink { @@ -48,7 +48,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; template <HeapMojoWrapperMode Mode, typename ContextType>
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc index f2a4475..94390be 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" @@ -45,7 +45,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; template <HeapMojoWrapperMode Mode>
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc index 7547cb9..97b764b5 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/features.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" @@ -45,7 +45,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; class ServiceImpl : public sample::blink::Service {
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc index d9b2821..f3fe302 100644 --- a/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc +++ b/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/context_lifecycle_notifier.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/heap_observer_list.h" +#include "third_party/blink/renderer/platform/heap_observer_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace blink { @@ -43,7 +43,7 @@ } private: - HeapObserverList<ContextLifecycleObserver> observers_; + HeapObserverSet<ContextLifecycleObserver> observers_; }; template <HeapMojoWrapperMode Mode>
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier.cc b/third_party/blink/renderer/platform/network/network_state_notifier.cc index 6c865ac5..32328e8 100644 --- a/third_party/blink/renderer/platform/network/network_state_notifier.cc +++ b/third_party/blink/renderer/platform/network/network_state_notifier.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include <memory> + #include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator_params.h" #include "third_party/blink/public/common/client_hints/client_hints.h" @@ -430,23 +431,19 @@ uint32_t NetworkStateNotifier::RoundRtt( const String& host, const base::Optional<base::TimeDelta>& rtt) const { - // Limit the size of the buckets and the maximum reported value to reduce - // fingerprinting. - static const auto kGranularity = base::TimeDelta::FromMilliseconds(50); - static const auto kMaxRtt = base::TimeDelta::FromSeconds(3); - if (!rtt.has_value()) { // RTT is unavailable. So, return the fastest value. return 0; } - base::TimeDelta modified_rtt = rtt.value(); - modified_rtt *= GetRandomMultiplier(host); - modified_rtt = std::min(modified_rtt, kMaxRtt); + // Limit the maximum reported value and the granularity to reduce + // fingerprinting. + constexpr auto kMaxRtt = base::TimeDelta::FromSeconds(3); + constexpr auto kGranularity = base::TimeDelta::FromMilliseconds(50); - DCHECK_LE(base::TimeDelta(), modified_rtt); - DCHECK_GE(kMaxRtt, modified_rtt); - + const base::TimeDelta modified_rtt = + std::min(rtt.value() * GetRandomMultiplier(host), kMaxRtt); + DCHECK_GE(modified_rtt, base::TimeDelta()); return static_cast<uint32_t>( modified_rtt.RoundToMultiple(kGranularity).InMilliseconds()); }
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc index 6b81b51..9022792 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc
@@ -183,17 +183,16 @@ scoped_refptr<Hyphenation> Hyphenation::PlatformGetHyphenation( const AtomicString& locale) { - scoped_refptr<HyphenationMinikin> hyphenation( - base::AdoptRef(new HyphenationMinikin)); - if (hyphenation->OpenDictionary(locale.LowerASCII())) - return hyphenation; - hyphenation = nullptr; - DEFINE_STATIC_LOCAL(LocaleMap, locale_fallback, (CreateLocaleFallbackMap())); const auto& it = locale_fallback.find(locale); if (it != locale_fallback.end()) return LayoutLocale::Get(it->value)->GetHyphenation(); + scoped_refptr<HyphenationMinikin> hyphenation( + base::AdoptRef(new HyphenationMinikin)); + if (hyphenation->OpenDictionary(locale.LowerASCII())) + return hyphenation; + return nullptr; }
diff --git a/third_party/blink/renderer/platform/timer_perf_test.cc b/third_party/blink/renderer/platform/timer_perf_test.cc index 796af13a..5df1e5dc 100644 --- a/third_party/blink/renderer/platform/timer_perf_test.cc +++ b/third_party/blink/renderer/platform/timer_perf_test.cc
@@ -57,7 +57,7 @@ test::EnterRunLoop(); - double posting_time = (post_end - post_start).InMicroseconds(); + double posting_time = (post_end - post_start).InMicrosecondsF(); double posting_time_us_per_call = posting_time / static_cast<double>(kNumIterations); LOG(INFO) << "TimerBase::startOneShot cost (us/call) " @@ -99,13 +99,13 @@ test::EnterRunLoop(); - double posting_time = (post_end - post_start).InMicroseconds(); + double posting_time = (post_end - post_start).InMicrosecondsF(); double posting_time_us_per_call = posting_time / static_cast<double>(kNumIterations); LOG(INFO) << "TimerBase::startOneShot cost (us/call) " << posting_time_us_per_call << " (total " << posting_time << " us)"; - double cancel_time = (cancel_end - cancel_start).InMicroseconds(); + double cancel_time = (cancel_end - cancel_start).InMicrosecondsF(); double cancel_time_us_per_call = cancel_time / static_cast<double>(kNumIterations); LOG(INFO) << "TimerBase::stop cost (us/call) " << cancel_time_us_per_call
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 0df20be..76f29eb 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2689,18 +2689,6 @@ # ====== New tests from wpt-importer added here ====== crbug.com/626703 external/wpt/dom/events/Event-dispatch-click.html [ Timeout ] -crbug.com/626703 [ Linux ] external/wpt/streams/readable-streams/tee.any.serviceworker.html [ Timeout ] -crbug.com/626703 [ Mac ] external/wpt/streams/readable-streams/tee.any.serviceworker.html [ Timeout ] -crbug.com/626703 [ Win ] external/wpt/streams/readable-streams/tee.any.serviceworker.html [ Timeout ] -crbug.com/626703 [ Linux ] external/wpt/streams/readable-streams/tee.any.sharedworker.html [ Timeout ] -crbug.com/626703 [ Mac ] external/wpt/streams/readable-streams/tee.any.sharedworker.html [ Timeout ] -crbug.com/626703 [ Win ] external/wpt/streams/readable-streams/tee.any.sharedworker.html [ Timeout ] -crbug.com/626703 [ Linux ] external/wpt/streams/readable-streams/tee.any.html [ Timeout ] -crbug.com/626703 [ Mac ] external/wpt/streams/readable-streams/tee.any.html [ Timeout ] -crbug.com/626703 [ Win ] external/wpt/streams/readable-streams/tee.any.html [ Timeout ] -crbug.com/626703 [ Linux ] external/wpt/streams/readable-streams/tee.any.worker.html [ Timeout ] -crbug.com/626703 [ Mac ] external/wpt/streams/readable-streams/tee.any.worker.html [ Timeout ] -crbug.com/626703 [ Win ] external/wpt/streams/readable-streams/tee.any.worker.html [ Timeout ] crbug.com/626703 [ Linux ] external/wpt/input-events/input-events-get-target-ranges-backspace.tentative.html [ Timeout ] crbug.com/626703 [ Mac ] external/wpt/input-events/input-events-get-target-ranges-backspace.tentative.html [ Timeout ] crbug.com/626703 [ Win ] external/wpt/input-events/input-events-get-target-ranges-backspace.tentative.html [ Timeout ] @@ -6750,3 +6738,6 @@ # Sheriff 2020-08-14 crbug.com/1116681 [ Mac ] fast/frames/iframe-scaling-with-scroll.html [ Pass Failure ] + +# Sheriff 2020-08-17 +crbug.com/1069546 [ Mac ] compositing/layer-creation/overflow-scroll-overlap.html [ Pass Failure ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 94870592..97cfc52 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -184083,11 +184083,11 @@ [] ], "range-percent-intrinsic-size-2-ref.html": [ - "9a6e9287d96089912d00684166494e5dcb902b40", + "d98c8220164bcb92ada82f9799ba4da0e6425ea7", [] ], "range-percent-intrinsic-size-2a-ref.html": [ - "9aab2aede09aaaea2acb3fd5e3e98a6e70286fb3", + "11afa34a654ec071c00971b11a2261ff95397904", [] ], "slice-intrinsic-size-ref.html": [ @@ -219400,16 +219400,6 @@ [] ] }, - "mpadded": { - "mpadded-001-expected.txt": [ - "f652024378226e188c8f1ef011e64a059d2ea432", - [] - ], - "mpadded-003-expected.txt": [ - "2b658e2389a02b7c7cd17ccfb17c002ef832d2c8", - [] - ] - }, "mrow": { "dynamic-mrow-like-001-ref.html": [ "2f823ba9550d1c5a2cac2fe5b4b3bc5867a1be75", @@ -238690,6 +238680,12 @@ ] } }, + "webcodecs": { + "pattern.png": [ + "85676f29ff5806a32ac6713e601fdcb71dd03777", + [] + ] + }, "webdriver": { "META.yml": [ "a397b497c32234d3889c738f51b96a3ba3b2a96f", @@ -356831,7 +356827,7 @@ ] ], "mpadded-002.html": [ - "d376bd3da1f60d3f4c7e7b9294095e35598f853a", + "a5f77523e15ae745b57c1a355274554802dfc8cb", [ null, {} @@ -388369,7 +388365,7 @@ ] ], "bad-underlying-sinks.any.js": [ - "cf04e01b0c0c4daa0b193e46fee6583c0ed7cba1", + "0bfc036246a8709bd14117b252c1d186b8d8df0d", [ null, { @@ -402583,6 +402579,13 @@ ] }, "webcodecs": { + "video-encoder.html": [ + "ce03f058f78ec551afc8024203f633e64cb1a29f", + [ + null, + {} + ] + ], "video-track-reader.html": [ "087e0bb935b6033876c9b7eed10274bab02d8910", [
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any-expected.txt index 7fb3f0f..6b0a4ca 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any-expected.txt
@@ -12,6 +12,8 @@ PASS ReadableStream teeing: erroring a teed stream should error both branches PASS ReadableStream teeing: closing the original should immediately close the branches PASS ReadableStream teeing: erroring the original should immediately error the branches +PASS ReadableStream teeing: canceling branch1 should finish when branch2 reads until end of stream +PASS ReadableStream teeing: canceling branch1 should finish when original stream errors PASS ReadableStreamTee should not use a modified ReadableStream constructor from the global object FAIL ReadableStreamTee should not pull more chunks than can fit in the branch queue assert_array_equals: pull should only be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2 PASS ReadableStreamTee should only pull enough to fill the emptiest queue
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.serviceworker-expected.txt index 7fb3f0f..6b0a4ca 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.serviceworker-expected.txt
@@ -12,6 +12,8 @@ PASS ReadableStream teeing: erroring a teed stream should error both branches PASS ReadableStream teeing: closing the original should immediately close the branches PASS ReadableStream teeing: erroring the original should immediately error the branches +PASS ReadableStream teeing: canceling branch1 should finish when branch2 reads until end of stream +PASS ReadableStream teeing: canceling branch1 should finish when original stream errors PASS ReadableStreamTee should not use a modified ReadableStream constructor from the global object FAIL ReadableStreamTee should not pull more chunks than can fit in the branch queue assert_array_equals: pull should only be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2 PASS ReadableStreamTee should only pull enough to fill the emptiest queue
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.sharedworker-expected.txt index 7fb3f0f..6b0a4ca 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.sharedworker-expected.txt
@@ -12,6 +12,8 @@ PASS ReadableStream teeing: erroring a teed stream should error both branches PASS ReadableStream teeing: closing the original should immediately close the branches PASS ReadableStream teeing: erroring the original should immediately error the branches +PASS ReadableStream teeing: canceling branch1 should finish when branch2 reads until end of stream +PASS ReadableStream teeing: canceling branch1 should finish when original stream errors PASS ReadableStreamTee should not use a modified ReadableStream constructor from the global object FAIL ReadableStreamTee should not pull more chunks than can fit in the branch queue assert_array_equals: pull should only be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2 PASS ReadableStreamTee should only pull enough to fill the emptiest queue
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.worker-expected.txt index 7fb3f0f..6b0a4ca 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.worker-expected.txt
@@ -12,6 +12,8 @@ PASS ReadableStream teeing: erroring a teed stream should error both branches PASS ReadableStream teeing: closing the original should immediately close the branches PASS ReadableStream teeing: erroring the original should immediately error the branches +PASS ReadableStream teeing: canceling branch1 should finish when branch2 reads until end of stream +PASS ReadableStream teeing: canceling branch1 should finish when original stream errors PASS ReadableStreamTee should not use a modified ReadableStream constructor from the global object FAIL ReadableStreamTee should not pull more chunks than can fit in the branch queue assert_array_equals: pull should only be called once lengths differ, expected array ["pull"] length 1, got ["pull", "pull"] length 2 PASS ReadableStreamTee should only pull enough to fill the emptiest queue
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js index cf04e01..0bfc036 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js
@@ -159,6 +159,24 @@ test(() => { assert_throws_js(TypeError, () => new WritableStream({ + start: 'test' + }), 'constructor should throw'); +}, 'start: non-function start method'); + +test(() => { + assert_throws_js(TypeError, () => new WritableStream({ + write: 'test' + }), 'constructor should throw'); +}, 'write: non-function write method'); + +test(() => { + assert_throws_js(TypeError, () => new WritableStream({ + close: 'test' + }), 'constructor should throw'); +}, 'close: non-function close method'); + +test(() => { + assert_throws_js(TypeError, () => new WritableStream({ abort: { apply() {} } }), 'constructor should throw'); }, 'abort: non-function abort method with .apply');
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-format-style-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-format-style-expected.txt deleted file mode 100644 index 5d9bc538..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-format-style-expected.txt +++ /dev/null
@@ -1,53 +0,0 @@ -CONSOLE MESSAGE: line 14: %cBlue!. color: blue; -CONSOLE MESSAGE: line 15: %cBlue! %cRed! color: blue; color: red; -CONSOLE MESSAGE: line 16: %cBlue! -%cRed! color: blue; color: red; -CONSOLE MESSAGE: line 17: %cwww.google.com color: blue -CONSOLE WARNING: line 18: %cwww.google.com color: blue; background: blue -CONSOLE ERROR: line 19: %cwww.google.com color: blue; background: blue -CONSOLE MESSAGE: line 20: [30m1[31m2[90m3[91m4[40m5[41m6[100m7[101m8 -CONSOLE MESSAGE: line 21: [30m%d[31m%f[90m%s[91m%d[40m%f[41m%s[100m%d[101m%f 1 1.1 a 2 2.2 b 3 3.3 -Tests that console logging dumps properly styled messages. - -console-format-style.js:14 Blue!. -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: blue; -console-format-style.js:15 Blue! Red! -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: blue; -Styled text #1: contain: paint; display: inline-block; max-width: 100%; color: red; -console-format-style.js:16 Blue!Red! -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: blue; -Styled text #1: NO STYLES DEFINED -Styled text #2: contain: paint; display: inline-block; max-width: 100%; color: blue; -Styled text #3: contain: paint; display: inline-block; max-width: 100%; color: red; -console-format-style.js:17 www.google.com -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: blue; -Styled text #1: -webkit-text-stroke: 0px !important; text-decoration: underline !important; color: rgb(84, 84, 84) !important; background-color: rgb(255, 255, 255) !important; -console-format-style.js:18 www.google.com -onload @ console-format-style.js:18 -(anonymous) @ console-format-style.js:22 -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: blue; background: blue; -Styled text #1: -webkit-text-stroke: 0px !important; text-decoration: underline !important; color: rgb(84, 84, 84) !important; background-color: rgb(255, 251, 229) !important; -console-format-style.js:19 www.google.com -onload @ console-format-style.js:19 -(anonymous) @ console-format-style.js:22 -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: blue; background: blue; -Styled text #1: -webkit-text-stroke: 0px !important; text-decoration: underline !important; color: rgb(84, 84, 84) !important; background-color: rgb(255, 240, 240) !important; -console-format-style.js:20 12345678 -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: black; -Styled text #1: contain: paint; display: inline-block; max-width: 100%; color: red; -Styled text #2: contain: paint; display: inline-block; max-width: 100%; color: darkgray; -Styled text #3: contain: paint; display: inline-block; max-width: 100%; -Styled text #4: contain: paint; display: inline-block; max-width: 100%; background: black; -Styled text #5: contain: paint; display: inline-block; max-width: 100%; background: red; -Styled text #6: contain: paint; display: inline-block; max-width: 100%; background: darkgray; -Styled text #7: contain: paint; display: inline-block; max-width: 100%; -console-format-style.js:21 11.1a22.2b33.3 -Styled text #0: contain: paint; display: inline-block; max-width: 100%; color: black; -Styled text #1: contain: paint; display: inline-block; max-width: 100%; color: red; -Styled text #2: contain: paint; display: inline-block; max-width: 100%; color: darkgray; -Styled text #3: contain: paint; display: inline-block; max-width: 100%; -Styled text #4: contain: paint; display: inline-block; max-width: 100%; background: black; -Styled text #5: contain: paint; display: inline-block; max-width: 100%; background: red; -Styled text #6: contain: paint; display: inline-block; max-width: 100%; background: darkgray; -Styled text #7: contain: paint; display: inline-block; max-width: 100%; -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-group-click-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-group-click-expected.txt deleted file mode 100644 index 81d900c..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-group-click-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -CONSOLE MESSAGE: line 12: group with object [object Object] -CONSOLE MESSAGE: line 13: Message inside group -CONSOLE MESSAGE: line 14: console.groupEnd -Tests that clicks on console.group target the appropriate element. - - -Before -console-group-click.js:12 group with object {x: 1} - -Click on the group -console-group-click.js:12 group with object {x: 1} -console-group-click.js:13 Message inside group - -Click on the object -console-group-click.js:12 group with object {x: 1}x: 1__proto__: Object -console-group-click.js:13 Message inside group -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-link-to-snippet-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-link-to-snippet-expected.txt deleted file mode 100644 index 01f147a..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-link-to-snippet-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -CONSOLE MESSAGE: line 1: 239 -CONSOLE ERROR: line 2: 42 -CONSOLE ERROR: line 3: 0 -CONSOLE ERROR: line 4: false -CONSOLE ERROR: line 5: null -Test that link to snippet works. - - -Running: testConsoleLogAndReturnMessageLocation -name1:1 239 -name1:1 42 - -Running: testSnippetSyntaxError -Line Message was added: snippet:///name2 Error 'Uncaught SyntaxError: Unexpected token '}'':1:1 -name2:2 Uncaught SyntaxError: Unexpected token '}' - -Running: testConsoleErrorHighlight -Line Message was added: snippet:///name3 Error '42':1:8 -Line Message was added: snippet:///name3 Error '-0':2:8 -Line Message was added: snippet:///name3 Error 'false':3:8 -Line Message was added: snippet:///name3 Error 'null':4:8 -name3:2 42 -(anonymous) @ name3:2 -name3:3 -0 -(anonymous) @ name3:3 -name3:4 false -(anonymous) @ name3:4 -name3:5 null -(anonymous) @ name3:5 -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-linkify-relative-links-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-linkify-relative-links-expected.txt deleted file mode 100644 index 6082bf1..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-linkify-relative-links-expected.txt +++ /dev/null
@@ -1,23 +0,0 @@ -CONSOLE MESSAGE: line 10: Error with relative links - at (foo1.js:10:50) - at (//foo2.js:10:50) - at (/foo3.js:10:50) - at (../foo4.js:10:50) - at (./foo5.js:10:50) - at (./bar/foo6.js:10:50) -Test that logging an error in console would linkify relative URLs - -console-linkify-relative-links.js:10 Error with relative links - at (foo1.js:10) - at (foo2.js:10) - at (:8000/foo3.js:10) - at (:8000/devtools/foo4.js:10) - at (foo5.js:10) - at (bar/foo6.js:10) -Link: foo1.js:10, href: http://127.0.0.1:8000/devtools/resources/foo1.js -Link: foo2.js:10, href: http://foo2.js -Link: :8000/foo3.js:10, href: http://127.0.0.1:8000/foo3.js -Link: :8000/devtools/foo4.js:10, href: http://127.0.0.1:8000/devtools/foo4.js -Link: foo5.js:10, href: http://127.0.0.1:8000/devtools/resources/foo5.js -Link: bar/foo6.js:10, href: http://127.0.0.1:8000/devtools/resources/bar/foo6.js -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-log-wrapped-in-framework-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-log-wrapped-in-framework-expected.txt deleted file mode 100644 index 6d42fb9..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-log-wrapped-in-framework-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -CONSOLE MESSAGE: line 13: direct console.log() -CONSOLE MESSAGE: line 7: framework log -Tests console.log() anchor location when the skip-stack-frames feature is enabled. - -console-log-wrapped-in-framework.js:13 direct console.log() -console-log-wrapped-in-framework.js:14 framework log -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-message-contains-async-stack-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-message-contains-async-stack-expected.txt deleted file mode 100644 index 8d44c715..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-message-contains-async-stack-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -CONSOLE ERROR: line 1: Uncaught SyntaxError: Unexpected end of input -Tests exception message with empty stack in console contains async stack trace. - -VM:1 Uncaught SyntaxError: Unexpected end of input -setTimeout (async) -(anonymous) @ console-message-cont…s-async-stack.js:14 -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-table-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-table-expected.txt deleted file mode 100644 index 25b819c..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-table-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -CONSOLE MESSAGE: [object Object],[object Object],[object Object],[object Object] -CONSOLE MESSAGE: [object Object],[object Object],[object Object],[object Object] -Tests that console.table is properly rendered on tables with more than 20 columns(maxColumnsToRender). - -HEADER (index) | b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8 | b9 | b10 | b11 | b12 | b13 | b14 | a0 | a1 | a2 | a3 | a4 | -ROW "b0" | "b1" | "b2" | "b3" | "b4" | "b5" | "b6" | "b7" | "b8" | "b9" | "b10" | "b11" | "b12" | "b13" | "b14" | -ROW "b0" | "b1" | "b2" | "b3" | "b4" | "b5" | "b6" | "b7" | "b8" | "b9" | "b10" | "b11" | "b12" | "b13" | "b14" | "a0" | "a1" | "a2" | "a3" | "a4" | -ROW "b0" | "b1" | "b2" | "b3" | "b4" | "b5" | "b6" | "b7" | "b8" | "b9" | "b10" | "b11" | "b12" | "b13" | "b14" | -ROW "b0" | "b1" | "b2" | "b3" | "b4" | "b5" | "b6" | "b7" | "b8" | "b9" | "b10" | "b11" | "b12" | "b13" | "b14" | "a0" | "a1" | "a2" | "a3" | "a4" | -HEADER (index) | a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7 | a8 | a9 | a10 | a11 | a12 | a13 | a14 | b0 | b1 | b2 | b3 | b4 | -ROW "a0" | "a1" | "a2" | "a3" | "a4" | "a5" | "a6" | "a7" | "a8" | "a9" | "a10" | "a11" | "a12" | "a13" | "a14" | "b0" | "b1" | "b2" | "b3" | "b4" | -ROW "b0" | "b1" | "b2" | "b3" | "b4" | -ROW "a0" | "a1" | "a2" | "a3" | "a4" | "a5" | "a6" | "a7" | "a8" | "a9" | "a10" | "a11" | "a12" | "a13" | "a14" | "b0" | "b1" | "b2" | "b3" | "b4" | -ROW "b0" | "b1" | "b2" | "b3" | "b4" | -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-trace-in-eval-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-trace-in-eval-expected.txt deleted file mode 100644 index 7af7cab..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/console-trace-in-eval-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -CONSOLE MESSAGE: line 5: console.trace -Tests that when console.trace is called in eval'ed script ending with //# sourceURL=url it will dump a stack trace that will have the url as the script source. Bug 47252. - -evalURL.js:5 console.trace -b @ evalURL.js:5 -a @ evalURL.js:10 -evalSource @ evalURL.js:13 -eval @ evalURL.js:14 -(anonymous) @ console-trace-in-eval.js:29 -setTimeout (async) -doEvalSource @ console-trace-in-eval.js:28 -(anonymous) @ console-trace-in-eval.js:39 -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/viewport-testing/console-key-expand-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/viewport-testing/console-key-expand-expected.txt deleted file mode 100644 index 26e2811e..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/console/viewport-testing/console-key-expand-expected.txt +++ /dev/null
@@ -1,342 +0,0 @@ -CONSOLE WARNING: line 26: warning -CONSOLE MESSAGE: line 35: group -CONSOLE MESSAGE: line 35: log child -CONSOLE MESSAGE: line 51: before -CONSOLE MESSAGE: line 51: text [object Object] [object Object] -CONSOLE MESSAGE: line 51: after -CONSOLE MESSAGE: line 74: before -CONSOLE MESSAGE: line 74: text [object Object] [object Object] -CONSOLE MESSAGE: line 74: after -CONSOLE MESSAGE: line 117: before -CONSOLE WARNING: line 117: warning [object Object] -CONSOLE MESSAGE: line 117: after -CONSOLE MESSAGE: line 167: before -CONSOLE MESSAGE: line 167: [object HTMLDivElement] -CONSOLE MESSAGE: line 167: after -CONSOLE MESSAGE: line 181: before -CONSOLE MESSAGE: line 181: [object Object] -CONSOLE MESSAGE: line 199: [object Object] -CONSOLE MESSAGE: line 199: after -CONSOLE MESSAGE: line 226: [object Object] -Tests that console artifacts can be expanded, collapsed via keyboard. - - -Running: testExpandingTraces -Evaluating: console.warn("warning") -Message count: 1 - -Force selecting index 0 -Viewport virtual selection: 0 -Is trace expanded: NO - -ArrowRight: -Viewport virtual selection: 0 -Is trace expanded: YES - -ArrowLeft: -Viewport virtual selection: 0 -Is trace expanded: NO - -Running: testExpandingGroups -Evaluating: console.group("group"); console.log("log child"); -Message count: 2 - -Force selecting index 0 -Viewport virtual selection: 0 -Is group expanded: YES -console-key-expand.js:35 group -console-key-expand.js:35 log child - -ArrowLeft: -Viewport virtual selection: 0 -Is group expanded: NO -console-key-expand.js:35 group - -ArrowRight: -Viewport virtual selection: 0 -Is group expanded: YES -console-key-expand.js:35 group -console-key-expand.js:35 log child - -Running: testNavigateBetweenObjectsAndLogs -Evaluating: console.log("before");console.log("text", obj1, obj2);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:51 text {x: 1} {y: 2} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowDown: -Viewport virtual selection: 1 -activeElement: SPAN.devtools-link -active text: console-key-expand.js:51 - -ArrowDown: -Viewport virtual selection: 2 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:51 after - -ArrowUp: -Viewport virtual selection: 1 -activeElement: SPAN.devtools-link -active text: console-key-expand.js:51 - -ArrowUp: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowLeft: -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:51 text {x: 1} {y: 2} - -Running: testExpandingObjects -Evaluating: console.log("before");console.log("text", obj1, obj2);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:74 text {x: 1} {y: 2} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {x: 1} - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.selected -active text: x: 1 - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {y: 2} - -ArrowDown: - -ArrowDown: - -ArrowDown: -Viewport virtual selection: 2 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:74 after - -ArrowUp: - -ArrowUp: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.expanded.selected -active text: {y: 2} - -ArrowLeft: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowLeft: -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:74 text {x: 1}x: 1 {y: 2}y: 2 - -Running: testExpandingObjectInTrace -Evaluating: console.log("before");console.warn("warning", obj1);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -Has object: collapsed -Is trace expanded: NO -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1} -(anonymous) @ console-key-expand.js:117 - -ArrowRight: -Viewport virtual selection: 1 -Has object: collapsed -Is trace expanded: YES -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1} -(anonymous) @ console-key-expand.js:117 - -ArrowRight: -Viewport virtual selection: 1 -Has object: collapsed -Is trace expanded: YES -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowRight: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {x: 1} - -ArrowDown: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: LI.selected -active text: x: 1 - -ArrowDown: - -ArrowDown: - -ArrowDown: -Viewport virtual selection: 2 -Has object: expanded -Is trace expanded: YES -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:117 after - -ArrowUp: - -ArrowUp: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: SPAN.devtools-link -active text: console-key-expand.js:117 - -ArrowUp: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: LI.parent.object-properties-section-root-element.expanded.selected -active text: {x: 1} - -ArrowUp: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1}x: 1 -(anonymous) @ console-key-expand.js:117 - -ArrowLeft: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: NO -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1}x: 1 -(anonymous) @ console-key-expand.js:117 - -ArrowLeft: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: NO -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1}x: 1 -(anonymous) @ console-key-expand.js:117 - -Running: testExpandingElement -Evaluating: console.log("before");console.log(el);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:167 <div>​…​</div>​ - -ArrowDown: - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.parent.selected -active text: <div>​…​</div>​ - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.selected.expanded -active text: <div>​ - -Running: testShiftTabShouldSelectLastObject -Evaluating: console.log("before");console.log(obj1); -Message count: 2 -Setting focus in prompt: - -Shift+Tab: - -ArrowUp: -Viewport virtual selection: 1 -Has object: collapsed -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowRight: -Viewport virtual selection: 1 -Has object: expanded -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {x: 1} - -Running: testArrowUpToFirstVisibleMessageShouldSelectLastObject -Evaluating: console.log(obj1);console.log("after"); -Message count: 2 -Setting focus in prompt: - -Shift+Tab: - -ArrowUp: -Viewport virtual selection: 1 -Has object: collapsed -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:199 after - -ArrowUp: - -ArrowUp: -Viewport virtual selection: 0 -Has object: collapsed -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -Running: testFocusLastChildInBigObjectShouldScrollIntoView -Evaluating: console.log(bigObj); -Message count: 1 -Setting focus in prompt: - -Shift+Tab: - -ArrowUp: - -ArrowRight: - -Tab: -Viewport virtual selection: -1 -Has object: expanded -activeElement: TEXTAREA - -Shift+Tab: - -ArrowUp: -Viewport virtual selection: 0 -Has object: expanded -activeElement: LI.parent.object-properties-section-root-element.expanded.selected -active text: {a0: 0, a1: 1, a2: 2, a3: 3, a4: 4, …} -Is at bottom: false, should stick: false -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/extensions/extensions-reload-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/extensions/extensions-reload-expected.txt deleted file mode 100644 index 24bdb25d..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/extensions/extensions-reload-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -CONSOLE MESSAGE: 42 -Tests that webInspector.inspectedWindow.reload() successfully injects and preprocesses user's code upon reload - -Started extension. -Running tests... -RUNNING TEST: extension_testReloadInjectsCode -Page reloaded. -Page reloaded. -With injected code: foo = 42 -Without injected code: foo = undefined -RUNNING TEST: extension_testReloadInjectsCodeWithMessage -Page reloaded. -Source received: -console.log(42) -All tests done. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/indexeddb/resources-panel-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/indexeddb/resources-panel-expected.txt deleted file mode 100644 index 864b6cb2e..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/indexeddb/resources-panel-expected.txt +++ /dev/null
@@ -1,35 +0,0 @@ -CONSOLE MESSAGE: line 49: InspectorTest.IndexedDB_callback1 -CONSOLE MESSAGE: line 49: InspectorTest.IndexedDB_callback2 -CONSOLE MESSAGE: line 49: InspectorTest.IndexedDB_callback3 -Tests IndexedDB tree element on resources panel. - -Expanded IndexedDB tree element. -Dumping IndexedDB tree: - (empty) -Creating database. -Created database. -Refreshing. -Refreshed. -Dumping IndexedDB tree: - database: testDatabase - http://127.0.0.1:8000 - Object store: testObjectStore - Index: testIndexName -Navigating to another security origin. -Navigated to another security origin. -Dumping IndexedDB tree: - (empty) -Navigating back. -Navigated back. -Refreshing. -Refreshed. -Dumping IndexedDB tree: - database: testDatabase - http://127.0.0.1:8000 - Object store: testObjectStore - Index: testIndexName -Deleting database. -Deleted database. -Refreshing. -Refreshed. -Dumping IndexedDB tree: - (empty) -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/search/search-ignore-binary-files-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/search/search-ignore-binary-files-expected.txt deleted file mode 100644 index aa63e1b..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/search/search-ignore-binary-files-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -CONSOLE ERROR: line 6: Uncaught (in promise) ReferenceError: TestRunner is not defined -Verify that search doesn't search in binary resources. - -Search result #1: uiSourceCode.url = http://127.0.0.1:8000/devtools/search/search-ignore-binary-files.js - search match #1: lineNumber = 17, lineContent = ' var searchConfig = new Search.SearchConfig('sources.search-in-files', 'AAAAAAA', true, false);' -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/sources/debugger/debugger-scope-resolve-this-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/sources/debugger/debugger-scope-resolve-this-expected.txt deleted file mode 100644 index b0c0af8..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/http/tests/devtools/sources/debugger/debugger-scope-resolve-this-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -CONSOLE MESSAGE: line 7: [object Object] -Tests resolving this object name via source maps. - -Set timer for test function. -Script execution paused. - -Scope variables sidebar pane: -Local - this: Foo {} -Closure (Foo.bar) -WindowGlobal - <section collapsed> -Script execution resumed. -
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 69be957..e081650a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -52697,6 +52697,8 @@ <int value="1203" label="Show Emoji Suggestions"/> <int value="1204" label="Change System Language"/> <int value="1205" label="Offer Translation"/> + <int value="1206" label="Add Input Method"/> + <int value="1207" label="Spell Check"/> <int value="1300" label="Google Drive Connection"/> <int value="1400" label="Add Printer"/> <int value="1401" label="Saved Printers"/>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index b866834a..6f27d27 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -353,7 +353,7 @@ <item id="webstore_install_helper" hash_code="25921771" type="0" content_hash_code="10206361" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_install_helper.cc"/> <item id="webstore_installer" hash_code="18764319" type="0" content_hash_code="70871152" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_installer.cc"/> <item id="webui_content_scripts_download" hash_code="100545943" type="0" content_hash_code="119898059" os_list="linux,windows" file_path="extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.cc"/> - <item id="well_known_path_that_should_not_exist" hash_code="134618785" type="0" content_hash_code="55913167" os_list="linux,windows" file_path="chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc"/> + <item id="well_known_path_that_should_not_exist" hash_code="134618785" type="0" content_hash_code="55913167" os_list="linux,windows" file_path="components/password_manager/core/browser/well_known_change_password_state.cc"/> <item id="worker_script_load" hash_code="72087791" type="0" content_hash_code="24889169" os_list="linux,windows" file_path="content/browser/worker_host/worker_script_fetcher.cc"/> <item id="xmpp_signal_strategy" hash_code="88906454" type="0" deprecated="2019-07-16" content_hash_code="88958321" file_path=""/> </annotations>
diff --git a/ui/android/edge_effect.cc b/ui/android/edge_effect.cc index 81d220b..bc09abc4 100644 --- a/ui/android/edge_effect.cc +++ b/ui/android/edge_effect.cc
@@ -204,9 +204,8 @@ if (IsFinished()) return false; - const base::TimeDelta dt = current_time - start_time_; - const double t = std::min(dt / duration_, 1.); - const float interp = static_cast<float>(Damp(t, 1.)); + const double t = std::min((current_time - start_time_) / duration_, 1.0); + const float interp = static_cast<float>(Damp(t, 1.0)); glow_alpha_ = Lerp(glow_alpha_start_, glow_alpha_finish_, interp); glow_scale_y_ = Lerp(glow_scale_y_start_, glow_scale_y_finish_, interp); @@ -222,8 +221,8 @@ glow_alpha_start_ = glow_alpha_; glow_scale_y_start_ = glow_scale_y_; - glow_alpha_finish_ = 0.f; - glow_scale_y_finish_ = 0.f; + glow_alpha_finish_ = 0.0f; + glow_scale_y_finish_ = 0.0f; break; case STATE_PULL: state_ = STATE_PULL_DECAY; @@ -234,8 +233,8 @@ glow_scale_y_start_ = glow_scale_y_; // After pull, the glow should fade to nothing. - glow_alpha_finish_ = 0.f; - glow_scale_y_finish_ = 0.f; + glow_alpha_finish_ = 0.0f; + glow_scale_y_finish_ = 0.0f; break; case STATE_PULL_DECAY: state_ = STATE_RECEDE;
diff --git a/ui/base/prediction/linear_resampling.cc b/ui/base/prediction/linear_resampling.cc index d066205..850e99c 100644 --- a/ui/base/prediction/linear_resampling.cc +++ b/ui/base/prediction/linear_resampling.cc
@@ -13,19 +13,16 @@ namespace { // Minimum time difference between last two consecutive events before attempting // to resample. -constexpr base::TimeDelta kResampleMinDelta = - base::TimeDelta::FromMilliseconds(2); +constexpr auto kResampleMinDelta = base::TimeDelta::FromMilliseconds(2); // Maximum time to predict forward from the last event, to avoid predicting too // far into the future. This time is further bounded by 50% of the last time // delta. -constexpr base::TimeDelta kResampleMaxPrediction = - base::TimeDelta::FromMilliseconds(8); +constexpr auto kResampleMaxPrediction = base::TimeDelta::FromMilliseconds(8); // Align events to a few milliseconds before frame_time. This is to make the // resampling either doing interpolation or extrapolating a closer future time // so that resampled result is more accurate and has less noise. This adds some // latency during resampling but a few ms should be fine. -constexpr base::TimeDelta kResampleLatency = - base::TimeDelta::FromMilliseconds(5); +constexpr auto kResampleLatency = base::TimeDelta::FromMilliseconds(5); // Get position at |sample_time| by linear interpolate/extrapolate a and b. inline gfx::PointF lerp(const InputPredictor::InputData& a,
diff --git a/ui/compositor/layer_animator_unittest.cc b/ui/compositor/layer_animator_unittest.cc index 1aa05fd..1aa2631 100644 --- a/ui/compositor/layer_animator_unittest.cc +++ b/ui/compositor/layer_animator_unittest.cc
@@ -1210,7 +1210,7 @@ // should be enormous. Arbitrarily choosing 1 minute as the threshold, // though a much smaller value would probably have sufficed. delta = base::TimeTicks::Now() - animator->last_step_time(); - EXPECT_GT(60.0, delta.InSecondsF()); + EXPECT_LT(delta, base::TimeDelta::FromMinutes(1)); } //------------------------------------------------------- @@ -3503,17 +3503,15 @@ Layer root; compositor->SetRootLayer(&root); - constexpr base::TimeDelta kAnimationDuration = - base::TimeDelta::FromMilliseconds(50); + constexpr auto kAnimationDuration = base::TimeDelta::FromMilliseconds(50); // Draw enough frames so that missing the start frame number would cause the // reporter to always report 100% smoothness. 4 times of the expected // animation frames because somehow the refresh rate changes from 60fps to // 200fps when reporting. - const float frame_interval = - base::Time::kMillisecondsPerSecond / compositor->refresh_rate(); const int kStartFrameNumber = - base::ClampFloor(kAnimationDuration.InMillisecondsF() / frame_interval) * + base::ClampFloor(kAnimationDuration.InSecondsF() * + compositor->refresh_rate()) * 4; while (compositor->activated_frame_count() < kStartFrameNumber) { compositor->ScheduleFullRedraw();
diff --git a/ui/events/gestures/physics_based_fling_curve.cc b/ui/events/gestures/physics_based_fling_curve.cc index 74b1942..d480d7c4 100644 --- a/ui/events/gestures/physics_based_fling_curve.cc +++ b/ui/events/gestures/physics_based_fling_curve.cc
@@ -4,6 +4,8 @@ #include "ui/events/gestures/physics_based_fling_curve.h" +#include <cmath> + namespace { // These constants are defined based on UX experiment. @@ -15,8 +17,8 @@ const float kMaxCurveDurationForFling = 2.0f; const float kDefaultPhysicalDeceleration = 2.7559e-5f; // inch/ms^2. -inline gfx::Vector2dF GetPositionAtTime(const gfx::Vector2dF& end_point, - double progress) { +inline gfx::Vector2dF GetPositionAtValue(const gfx::Vector2dF& end_point, + double progress) { return gfx::ScaleVector2d(end_point, progress); } @@ -27,12 +29,9 @@ } float GetOffset(float velocity, float deceleration, float duration) { - float position = + const float position = (std::abs(velocity) - deceleration * duration * 0.5) * duration; - if (velocity < 0.0f) - return -position; - - return position; + return std::copysign(position, velocity); } gfx::Vector2dF GetDecelerationInPixelsPerMs2( @@ -101,7 +100,8 @@ bezier_(p1_.x(), p1_.y(), p2_.x(), p2_.y()), previous_time_delta_(base::TimeDelta()) { DCHECK(!velocity.IsZero()); - CHECK(!std::isnan(velocity.x()) && !std::isnan(velocity.y())); + DCHECK(!std::isnan(velocity.x())); + DCHECK(!std::isnan(velocity.y())); } PhysicsBasedFlingCurve::~PhysicsBasedFlingCurve() = default; @@ -111,38 +111,33 @@ gfx::Vector2dF* velocity) { DCHECK(offset); DCHECK(velocity); - base::TimeDelta elapsed_time = time - start_timestamp_; + + const base::TimeDelta elapsed_time = time - start_timestamp_; if (elapsed_time < base::TimeDelta()) { *offset = gfx::Vector2dF(); *velocity = gfx::Vector2dF(); return true; } - bool still_active = true; - double x = elapsed_time / curve_duration_; - if (x < 1.0f) { - double progress = bezier_.Solve(x); - *offset = GetPositionAtTime(distance_, progress); + const double x = elapsed_time / curve_duration_; + const bool still_active = x < 1.0f; + if (still_active) { + const double progress = bezier_.Solve(x); + *offset = GetPositionAtValue(distance_, progress); *velocity = GetVelocityAtTime(*offset, prev_offset_, elapsed_time - previous_time_delta_); prev_offset_ = *offset; previous_time_delta_ = elapsed_time; - still_active = true; } else { - // At the end of animation, we should have travel distance equal to - // distance_ + // At the end of animation, we should have traveled a distance equal to + // |distance_|. *offset = distance_; *velocity = gfx::Vector2dF(); - still_active = false; } return still_active; } -// This method calculate the curve duration and generate the control points for -// bezier curve based on velocity and |distance_|. It calculate the slope based -// on the input velocity (initial velocity), curve duration and |distance_|. -// Slope is then used to configure the value of control points for curve. base::TimeDelta PhysicsBasedFlingCurve::CalculateDurationAndConfigureControlPoints( const gfx::Vector2dF& velocity) {
diff --git a/ui/events/gestures/physics_based_fling_curve.h b/ui/events/gestures/physics_based_fling_curve.h index 392d834..c467ecf 100644 --- a/ui/events/gestures/physics_based_fling_curve.h +++ b/ui/events/gestures/physics_based_fling_curve.h
@@ -52,6 +52,9 @@ // increases the upper bound of the scroll distance for a fling. constexpr static int kDefaultBoundsMultiplier = 3; + // Calculates the curve duration and generates the control points for a bezier + // curve. The slope is based on the input initial |velocity|, calculated curve + // duration, and |distance_|. Returns the duration. base::TimeDelta CalculateDurationAndConfigureControlPoints( const gfx::Vector2dF& velocity);
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index ce95db8..dd1cf2a 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -107,12 +107,9 @@ // Touchscreen: use TouchEventConverterEvdev. if (devinfo.HasTouchscreen()) { - std::unique_ptr<TouchEventConverterEvdev> converter( - new TouchEventConverterEvdev(std::move(fd), params.path, params.id, - devinfo, params.shared_palm_state, - params.dispatcher)); - converter->Initialize(devinfo); - return std::move(converter); + return TouchEventConverterEvdev::Create( + std::move(fd), params.path, params.id, devinfo, + params.shared_palm_state, params.dispatcher); } // Graphics tablet
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc index afab037..3daca1f 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -138,6 +138,27 @@ TouchEventConverterEvdev::~TouchEventConverterEvdev() { } +// static +std::unique_ptr<TouchEventConverterEvdev> TouchEventConverterEvdev::Create( + base::ScopedFD fd, + base::FilePath path, + int id, + const EventDeviceInfo& devinfo, + SharedPalmDetectionFilterState* shared_palm_state, + DeviceEventDispatcherEvdev* dispatcher) { + auto converter = std::make_unique<TouchEventConverterEvdev>( + std::move(fd), std::move(path), id, devinfo, shared_palm_state, + dispatcher); + converter->Initialize(devinfo); + if (!converter->GetTouchscreenSize().GetCheckedArea().IsValid()) { + LOG(WARNING) << "Ignoring touchscreen \"" << converter->input_device().name + << "\" reporting invalid size " + << converter->GetTouchscreenSize().ToString(); + return nullptr; + } + return converter; +} + void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { has_mt_ = info.HasMultitouch(); has_pen_ = info.HasKeyEvent(BTN_TOOL_PEN);
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h index 82da9b0..276d71e 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.h +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -50,6 +50,14 @@ DeviceEventDispatcherEvdev* dispatcher); ~TouchEventConverterEvdev() override; + static std::unique_ptr<TouchEventConverterEvdev> Create( + base::ScopedFD fd, + base::FilePath path, + int id, + const EventDeviceInfo& devinfo, + SharedPalmDetectionFilterState* shared_palm_state, + DeviceEventDispatcherEvdev* dispatcher); + // EventConverterEvdev: bool HasTouchscreen() const override; bool HasPen() const override;
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index 5d59d971..4b74359 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -13,6 +13,7 @@ #include <vector> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" @@ -2290,4 +2291,18 @@ EXPECT_FLOAT_EQ(14.f, in_progress_event.major); EXPECT_FLOAT_EQ(11.f, in_progress_event.minor); } + +// b/162596241 +TEST_F(TouchEventConverterEvdevTest, InvalidDimensions) { + EventDeviceInfo devinfo; + input_absinfo absinfo = {}; + absinfo.maximum = 1 << 16; + devinfo.SetAbsInfo(ABS_X, absinfo); + devinfo.SetAbsInfo(ABS_MT_POSITION_X, absinfo); + devinfo.SetAbsInfo(ABS_Y, absinfo); + devinfo.SetAbsInfo(ABS_MT_POSITION_Y, absinfo); + EXPECT_FALSE( + TouchEventConverterEvdev::Create({}, base::FilePath(kTestDevicePath), 0, + devinfo, shared_palm_state(), nullptr)); +} } // namespace ui
diff --git a/ui/file_manager/file_manager/background/js/launcher_search.js b/ui/file_manager/file_manager/background/js/launcher_search.js index c87b256..ed06659 100644 --- a/ui/file_manager/file_manager/background/js/launcher_search.js +++ b/ui/file_manager/file_manager/background/js/launcher_search.js
@@ -320,17 +320,12 @@ createSearchResult_(entry) { // TODO(yawano): Use filetype_folder_shared.png for a shared // folder. - // TODO(yawano): Add archive launcher filetype icon. let icon = FileType.getIcon(entry); - if (icon === 'UNKNOWN' || icon === 'archive') { + + if (icon === 'UNKNOWN') { icon = 'generic'; } - const useHighDpiIcon = window.devicePixelRatio > 1.0; - const iconUrl = chrome.runtime.getURL( - 'foreground/images/launcher_filetypes/' + - (useHighDpiIcon ? '2x/' : '') + 'launcher_filetype_' + icon + '.png'); - // Hide extensions for hosted files. const title = FileType.isHosted(entry) ? entry.name.substr( @@ -340,7 +335,7 @@ return { itemId: entry.toURL(), title: title, - iconUrl: iconUrl, + iconType: icon, // Relevance is set as 2 for all results as a temporary // implementation. 2 is the middle value. // TODO(yawano): Implement practical relevance calculation.
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index 066c882..5d4a99c 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1409,6 +1409,14 @@ }; /** + * Returns true if filters in Recents view is enabled. + * @return {boolean} + */ +util.isRecentsFilterEnabled = () => { + return loadTimeData.getBoolean('FILTERS_IN_RECENTS_ENABLED'); +}; + +/** * Returns true when FilesZipMount feature is enabled. * TODO(crbug.com/912236) Remove once transition to new ZIP system is finished. * @return {boolean}
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 1239b66..62d63bc 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1403,6 +1403,15 @@ color: rgb(168, 168, 168); } +body.files-ng .dialog-footer cr-button[disabled], +body.files-ng .dialog-footer cr-button[disabled]:hover, +body.files-ng .dialog-footer button[disabled], +body.files-ng .dialog-footer button[disabled]:hover { + background-color: + var(--cros-button-background-color-primary-disabled); + color: var(--cros-button-label-color-primary-disabled); +} + body:not(.files-ng) .dialog-footer .primary, body:not(.files-ng) .dialog-footer .primary:hover { background-color: rgb(51, 103, 214); @@ -3697,6 +3706,37 @@ z-index: 520; } +/* File type filter buttons in Recents view. + TODO(fukino): The style is temporary. Revisit it before the feature is + shipped. */ +#file-type-filter-container { + display: flex; + font-size: 13px; + height: 30x; + margin-top: 5px; +} + +.file-type-filter-button { + align-items: center; + border: 1px solid rgba(0, 0, 0, 15%); + border-radius: 20px; + box-sizing: border-box; + color: var(--google-grey-700); + cursor: pointer; + display: flex; + font-weight: 500; + height: 32px; + margin-inline-end: 3px; + margin-inline-start: 3px; + padding: 0 10px; +} + +.file-type-filter-button.active { + background-color: var(--google-blue-50); + border: 1px solid transparent; + color: var(--google-blue-600); +} + /* * Preventing FOUC */
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_archive.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_archive.png deleted file mode 100644 index a7e0336..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_archive.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_audio.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_audio.png deleted file mode 100644 index ab4e881..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_audio.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_chart.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_chart.png deleted file mode 100644 index 81f2671..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_chart.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_excel.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_excel.png deleted file mode 100644 index 711f385..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_excel.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_folder.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_folder.png deleted file mode 100644 index ff90fa0..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_folder.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdoc.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdoc.png deleted file mode 100644 index 3455f4b..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdoc.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdraw.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdraw.png deleted file mode 100644 index 9ff4fbb..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdraw.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_generic.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_generic.png deleted file mode 100644 index 2c66a9d3f..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_generic.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gform.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gform.png deleted file mode 100644 index 250b238..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gform.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gmap.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gmap.png deleted file mode 100644 index ac91a69..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gmap.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsheet.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsheet.png deleted file mode 100644 index 300f038..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsheet.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsite.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsite.png deleted file mode 100644 index 5931e788..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsite.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gslides.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gslides.png deleted file mode 100644 index bb7b70c..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gslides.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gtable.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gtable.png deleted file mode 100644 index d1c49764..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gtable.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_image.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_image.png deleted file mode 100644 index b371d67..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_image.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_pdf.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_pdf.png deleted file mode 100644 index 599c208..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_pdf.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_ppt.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_ppt.png deleted file mode 100644 index 5de1dbe..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_ppt.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_script.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_script.png deleted file mode 100644 index 639a1b5..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_script.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_shared.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_shared.png deleted file mode 100644 index c18c88c..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_shared.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_sites.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_sites.png deleted file mode 100644 index fe0a4cf..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_sites.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_tini.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_tini.png deleted file mode 100644 index 4f01d0b..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_tini.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_video.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_video.png deleted file mode 100644 index 1c9afd3..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_video.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_word.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_word.png deleted file mode 100644 index 6eebc26..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_word.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_archive.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_archive.png deleted file mode 100644 index a782879..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_archive.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_audio.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_audio.png deleted file mode 100644 index 085e4b4..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_audio.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_chart.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_chart.png deleted file mode 100644 index 4474ade1..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_chart.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_excel.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_excel.png deleted file mode 100644 index c8cf7538..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_excel.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_folder.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_folder.png deleted file mode 100644 index 947a5eb..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_folder.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdoc.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdoc.png deleted file mode 100644 index 8955353a..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdoc.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdraw.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdraw.png deleted file mode 100644 index 8320816..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdraw.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_generic.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_generic.png deleted file mode 100644 index ca220760..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_generic.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gform.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gform.png deleted file mode 100644 index 2a11534..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gform.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gmap.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gmap.png deleted file mode 100644 index 028a2f6e..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gmap.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsheet.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsheet.png deleted file mode 100644 index 9a7ccb0..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsheet.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsite.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsite.png deleted file mode 100644 index a0c8d5be..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsite.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gslides.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gslides.png deleted file mode 100644 index 97d0e5e..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gslides.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gtable.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gtable.png deleted file mode 100644 index dbf0320..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_gtable.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_image.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_image.png deleted file mode 100644 index a0012c76..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_image.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_pdf.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_pdf.png deleted file mode 100644 index 76548fd..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_pdf.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_ppt.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_ppt.png deleted file mode 100644 index f698bba..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_ppt.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_script.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_script.png deleted file mode 100644 index 3f34037..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_script.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_shared.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_shared.png deleted file mode 100644 index 497bbfd..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_shared.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_sites.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_sites.png deleted file mode 100644 index bbb8b179..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_sites.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_tini.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_tini.png deleted file mode 100644 index d93e6dd..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_tini.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_video.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_video.png deleted file mode 100644 index f76e9c5..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_video.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_word.png b/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_word.png deleted file mode 100644 index c0c3a3f..0000000 --- a/ui/file_manager/file_manager/foreground/images/launcher_filetypes/launcher_filetype_word.png +++ /dev/null Binary files differ
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index 338795f9..9225f7db 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -45,6 +45,7 @@ ":file_selection", ":file_tasks", ":file_transfer_controller", + ":file_type_filters_controller", ":file_watcher", ":folder_shortcuts_data_model", ":gear_menu_controller", @@ -358,6 +359,7 @@ ":empty_folder_controller", ":file_selection", ":file_transfer_controller", + ":file_type_filters_controller", ":folder_shortcuts_data_model", ":gear_menu_controller", ":import_controller", @@ -488,6 +490,20 @@ ] } +js_library("file_type_filters_controller") { + deps = [ + ":directory_model", + "//ui/file_manager/file_manager/common/js:files_app_entry_types", + ] +} + +js_unittest("file_type_filters_controller_unittest") { + deps = [ + ":file_type_filters_controller", + "//ui/webui/resources/js:webui_resource_test", + ] +} + js_library("file_watcher") { deps = [ "//ui/file_manager/base/js:volume_manager_types", @@ -847,6 +863,7 @@ ":file_manager_commands_unittest", ":file_tasks_unittest", ":file_transfer_controller_unittest", + ":file_type_filters_controller_unittest", ":import_controller_unittest", ":list_thumbnail_loader_unittest", ":navigation_list_model_unittest",
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index 21617c72..145ef44 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -259,6 +259,9 @@ /** @private {?QuickViewController} */ this.quickViewController_ = null; + /** @private {?FileTypeFiltersController} */ + this.fileTypeFiltersController_ = null; + /** * Records histograms of directory-changed event. * @private {?NavigationUma} @@ -327,6 +330,12 @@ * @private {?NavigationModelFakeItem} */ this.fakeDriveItem_ = null; + + /** + * A fake entry for Recents. + * @private {?FakeEntry} + */ + this.recentEntry_ = null; } /** @@ -1051,6 +1060,10 @@ this.launchParams_.showAndroidPickerApps, this.launchParams_.includeAllFiles, this.launchParams_.typeList); + this.recentEntry_ = new FakeEntry( + str('RECENT_ROOT_LABEL'), VolumeManagerCommon.RootType.RECENT, + this.getSourceRestriction_()); + assert(this.launchParams_); this.selectionHandler_ = new FileSelectionHandler( assert(this.directoryModel_), assert(this.fileOperationManager_), @@ -1121,6 +1134,13 @@ this.metadataModel_, this.volumeManager_, this.fileFilter_, this.namingController_, this.selectionHandler_, this.launchParams_); + // Create file-type filter controller. + if (util.isRecentsFilterEnabled()) { + this.fileTypeFiltersController_ = new FileTypeFiltersController( + this.ui_.fileTypeFilterContainer, this.directoryModel_, + this.recentEntry_); + } + return directoryTreePromise; } @@ -1144,10 +1164,7 @@ !DialogType.isFolderDialog(this.launchParams_.type) ? new NavigationModelFakeItem( str('RECENT_ROOT_LABEL'), NavigationModelItemType.RECENT, - new FakeEntry( - str('RECENT_ROOT_LABEL'), - VolumeManagerCommon.RootType.RECENT, - this.getSourceRestriction_())) : + assert(this.recentEntry_)) : null, assert(this.directoryModel_), assert(this.androidAppListModel_));
diff --git a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js new file mode 100644 index 0000000..01846fa --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js
@@ -0,0 +1,125 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * This class controls wires file-type filter UI and the filter settings in + * Recents view. + */ +class FileTypeFiltersController { + /** + * @param {!HTMLElement} fileTypeFilterContainer + * @param {!DirectoryModel} directoryModel + * @param {!FakeEntry} recentEntry + */ + constructor(fileTypeFilterContainer, directoryModel, recentEntry) { + /** + * @private {!HTMLElement} + * @const + */ + this.container_ = fileTypeFilterContainer; + + /** + * @private {!DirectoryModel} + * @const + */ + this.directoryModel_ = directoryModel; + + /** + * @private {!FakeEntry} + * @const + */ + this.recentEntry_ = recentEntry; + + /** + * @private {!HTMLElement} + * @const + */ + this.audioFilterButton_ = + this.createFilterButton_(str('MEDIA_VIEW_AUDIO_ROOT_LABEL')); + + /** + * @private {!HTMLElement} + * @const + */ + this.imageFilterButton_ = + this.createFilterButton_(str('MEDIA_VIEW_IMAGES_ROOT_LABEL')); + + /** + * @private {!HTMLElement} + * @const + */ + this.videoFilterButton_ = + this.createFilterButton_(str('MEDIA_VIEW_VIDEOS_ROOT_LABEL')); + + this.directoryModel_.addEventListener( + 'directory-changed', this.onCurrentDirectoryChanged_.bind(this)); + } + + /** + * Creates filter button's UI element. + * @param {string} label Label of the filter button. + * @private + */ + createFilterButton_(label) { + const button = util.createChild(this.container_, 'file-type-filter-button'); + button.textContent = label; + button.onclick = this.onFilterButtonClicked_.bind(this); + return button; + } + + /** + * Updates the UI when the current directory changes. + * @param {!Event} event Event. + * @private + */ + onCurrentDirectoryChanged_(event) { + // We show filter buttons only in Recents view at this moment. + this.container_.hidden = !(event.newDirEntry == this.recentEntry_); + // Reset the filter buttons' active state on leaving Recents view. + if (event.previousDirEntry == this.recentEntry_ && + event.newDirEntry != this.recentEntry_) { + this.audioFilterButton_.classList.toggle('active', false); + this.imageFilterButton_.classList.toggle('active', false); + this.videoFilterButton_.classList.toggle('active', false); + } + } + + /** + * Updates the UI when one of the filter buttons is clicked. + * @param {Event} event Event. + * @private + */ + onFilterButtonClicked_(event) { + // Toggle active state of clicked filter. When one filter button is clicked, + // other filter buttons should become inactive. + this.audioFilterButton_.classList.toggle( + 'active', event.target == this.audioFilterButton_ ? undefined : false); + this.imageFilterButton_.classList.toggle( + 'active', event.target == this.imageFilterButton_ ? undefined : false); + this.videoFilterButton_.classList.toggle( + 'active', event.target == this.videoFilterButton_ ? undefined : false); + this.refreshRecentView_(); + } + + /** + * Refreshes the current directory based on the filter settings. + * @private + */ + refreshRecentView_() { + // Update the Recent entry's setting based on the 'active' state of + // filter buttons. + let fileType = chrome.fileManagerPrivate.RecentFileType.ALL; + if (this.audioFilterButton_.classList.contains('active')) { + fileType = chrome.fileManagerPrivate.RecentFileType.AUDIO; + } else if (this.imageFilterButton_.classList.contains('active')) { + fileType = chrome.fileManagerPrivate.RecentFileType.IMAGE; + } else if (this.videoFilterButton_.classList.contains('active')) { + fileType = chrome.fileManagerPrivate.RecentFileType.VIDEO; + } + this.recentEntry_.recentFileType = fileType; + // Refresh current directory with the updated Recent setting. + // We don't need to invalidate the cached metadata for this rescan. + this.directoryModel_.rescan(false); + } +}
diff --git a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js new file mode 100644 index 0000000..ef28d317a --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js
@@ -0,0 +1,217 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @type {!HTMLElement} + */ +let container; + +/** + * @type {!DirectoryModel} + */ +let directoryModel; + +/** + * @type {!FakeEntry} + */ +let recentEntry; + +/** + * @type {!EntryList} + */ +let myFilesEntry; + +/** + * @type {!FileTypeFiltersController} + */ +let fileTypeFiltersController; + +function setUp() { + // Mock loadTimeData strings. + window.loadTimeData.data = { + MEDIA_VIEW_AUDIO_ROOT_LABEL: 'Audio', + MEDIA_VIEW_IMAGES_ROOT_LABEL: 'Images', + MEDIA_VIEW_VIDEOS_ROOT_LABEL: 'Videos', + }; + + class MockDirectoryModel extends cr.EventTarget { + constructor() { + super(); + + this.currentDirEntry = null; + window.isRescanCalled = false; + } + + rescan(refresh) { + window.isRescanCalled = true; + } + + changeDirectoryEntry(dirEntry) { + // Change the directory model's current directory to |dirEntry|. + const previousDirEntry = this.currentDirEntry; + this.currentDirEntry = dirEntry; + + // Emit 'directory-changed' event synchronously to simplify testing. + const event = new Event('directory-changed'); + event.previousDirEntry = previousDirEntry; + event.newDirEntry = this.currentDirEntry; + this.dispatchEvent(event); + } + + static create() { + const model = /** @type {!Object} */ (new MockDirectoryModel()); + return /** @type {!DirectoryModel} */ (model); + } + } + + // Create FileTypeFiltersController instance with dependencies. + container = /** @type {!HTMLInputElement} */ (document.createElement('div')); + directoryModel = MockDirectoryModel.create(); + recentEntry = new FakeEntry( + 'Recent', VolumeManagerCommon.RootType.RECENT, + chrome.fileManagerPrivate.SourceRestriction.ANY_SOURCE); + fileTypeFiltersController = + new FileTypeFiltersController(container, directoryModel, recentEntry); + + // Create a directory entry which is not Recents to simulate directory change. + myFilesEntry = + new EntryList('My Files', VolumeManagerCommon.RootType.MY_FILES); +} + +/** + * Tests that creating FileTypeFiltersController generates three buttons in the + * given container element. + */ +function testCreatedButtonLabels() { + const buttons = container.children; + assertEquals(buttons.length, 3); + + assertEquals(buttons[0].textContent, 'Audio'); + assertEquals(buttons[1].textContent, 'Images'); + assertEquals(buttons[2].textContent, 'Videos'); +} + +/** + * Tests that initial states of all buttons inside container are inactive. + */ +function testButtonInitialActiveState() { + const buttons = container.children; + assertEquals(buttons.length, 3); + + assertFalse(buttons[0].classList.contains('active')); + assertFalse(buttons[0].classList.contains('active')); + assertFalse(buttons[0].classList.contains('active')); +} + +/** + * Tests that click events toggle button state (inactive -> active -> inactive). + */ +function testButtonToggleState() { + const buttons = container.children; + assertEquals(buttons.length, 3); + + assertFalse(buttons[0].classList.contains('active')); + buttons[0].click(); + assertTrue(buttons[0].classList.contains('active')); + buttons[0].click(); + assertFalse(buttons[0].classList.contains('active')); +} + +/** + * Tests that only one button can be inactive. + * If button_1 is clicked then button_0 is active, button_0 becomes inactive and + * button_1 becomes active. + */ +function testOnlyOneButtonCanActive() { + const buttons = container.children; + assertEquals(buttons.length, 3); + + assertFalse(buttons[0].classList.contains('active')); + buttons[0].click(); + assertTrue(buttons[0].classList.contains('active')); + assertFalse(buttons[1].classList.contains('active')); + assertFalse(buttons[2].classList.contains('active')); + + buttons[1].click(); + assertFalse(buttons[0].classList.contains('active')); + assertTrue(buttons[1].classList.contains('active')); + assertFalse(buttons[2].classList.contains('active')); + + buttons[2].click(); + assertFalse(buttons[0].classList.contains('active')); + assertFalse(buttons[1].classList.contains('active')); + assertTrue(buttons[2].classList.contains('active')); +} + +/** + * Tests that container element is visible only when the current directory is + * Recents view. + */ +function testContainerIsShownOnlyInRecents() { + container.hidden = true; + directoryModel.changeDirectoryEntry(recentEntry); + assertFalse(container.hidden); + directoryModel.changeDirectoryEntry(myFilesEntry); + assertTrue(container.hidden); +} + +/** + * Tests that button's active state is reset to inactive when the user leaves + * Recents view. + */ +function testActiveButtonIsResetOnLeavingRecents() { + const buttons = container.children; + assertEquals(buttons.length, 3); + + directoryModel.changeDirectoryEntry(recentEntry); + + buttons[0].click(); + assertTrue(buttons[0].classList.contains('active')); + assertFalse(buttons[1].classList.contains('active')); + assertFalse(buttons[2].classList.contains('active')); + + directoryModel.changeDirectoryEntry(myFilesEntry); + assertFalse(buttons[0].classList.contains('active')); + assertFalse(buttons[1].classList.contains('active')); + assertFalse(buttons[2].classList.contains('active')); +} + +/** + * Tests that the active state of each button is reflected to the Recent entry's + * recentFileType property, and DirectoryModel.rescan() is called after the + * Recent entry's property is modified. + */ +function testAppliedFilters() { + const buttons = container.children; + assertEquals(buttons.length, 3); + + directoryModel.changeDirectoryEntry(recentEntry); + + buttons[0].click(); + assertEquals( + recentEntry.recentFileType, + chrome.fileManagerPrivate.RecentFileType.AUDIO); + assertTrue(window.isRescanCalled); + window.isRescanCalled = false; + + buttons[1].click(); + assertEquals( + recentEntry.recentFileType, + chrome.fileManagerPrivate.RecentFileType.IMAGE); + assertTrue(window.isRescanCalled); + window.isRescanCalled = false; + + buttons[2].click(); + assertEquals( + recentEntry.recentFileType, + chrome.fileManagerPrivate.RecentFileType.VIDEO); + assertTrue(window.isRescanCalled); + window.isRescanCalled = false; + + buttons[2].click(); + assertEquals( + recentEntry.recentFileType, chrome.fileManagerPrivate.RecentFileType.ALL); + assertTrue(window.isRescanCalled); + window.isRescanCalled = false; +}
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js index 42df2a4..78375ce8 100644 --- a/ui/file_manager/file_manager/foreground/js/main_scripts.js +++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -122,6 +122,7 @@ // <include src="file_selection.js"> // <include src="file_tasks.js"> // <include src="file_transfer_controller.js"> +// <include src="file_type_filters_controller.js"> // <include src="file_watcher.js"> // <include src="folder_shortcuts_data_model.js"> // <include src="sort_menu_controller.js">
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js index 23e8c9e..9242a9c 100644 --- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js +++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -565,7 +565,7 @@ if (this.recentModelItem_) { this.navigationItems_.push(this.recentModelItem_); - if (util.isUnifiedMediaViewEnabled()) { + if (util.isUnifiedMediaViewEnabled() && !util.isRecentsFilterEnabled()) { // Unified Media View (Images, Videos and Audio). this.navigationItems_.push(createFilteredRecentModelItem( str('MEDIA_VIEW_AUDIO_ROOT_LABEL'),
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index 90725d6..8422e61 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -374,6 +374,13 @@ /** @type {!FilesToast} */ (document.querySelector('files-toast')); /** + * Container of file-type filter buttons. + * @const {!HTMLElement} + */ + this.fileTypeFilterContainer = + queryRequiredElement('#file-type-filter-container', this.element); + + /** * A hidden div that can be used to announce text to screen * reader/ChromeVox. * @private {!HTMLElement}
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index 2802fa3a..01e6acd8 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -533,6 +533,7 @@ </div> <div class="downloads-warning" hidden></div> <files-message id='files-message' hidden></files-message> + <div id="file-type-filter-container" hidden></div> <div id="list-container" role="main"> <div id="more-actions-info" hidden>$i18n{SEE_MENU_FOR_ACTIONS}</div> <div id="sort-column-asc" hidden>$i18n{COLUMN_ASC_SORT_MESSAGE}</div>
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd index 32c3ade..09c49296 100644 --- a/ui/file_manager/file_manager_resources.grd +++ b/ui/file_manager/file_manager_resources.grd
@@ -100,52 +100,6 @@ <include name="IDR_FILE_MANAGER_GALLERY_ICON_192" file="gallery/images/icon192.png" type="BINDATA" /> <include name="IDR_FILE_MANAGER_GALLERY_ICON_256" file="gallery/images/icon256.png" type="BINDATA" /> - <!-- Resources used for file type icon in launcher search result. --> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_AUDIO" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_audio.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_ARCHIVE" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_archive.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_CHART" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_chart.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_EXCEL" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_excel.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_FOLDER" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_folder.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GDOC" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdoc.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GDRAW" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gdraw.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GENERIC" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_generic.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GFORM" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gform.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GMAP" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gmap.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GSHEET" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsheet.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GSITE" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gsite.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GSLIDES" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gslides.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_GTABLE" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_gtable.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_IMAGE" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_image.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_PDF" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_pdf.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_PPT" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_ppt.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_SCRIPT" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_script.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_SITES" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_sites.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_TINI" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_tini.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_VIDEO" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_video.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_WORD" file="file_manager/foreground/images/launcher_filetypes/launcher_filetype_word.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_AUDIO" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_audio.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_ARCHIVE" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_archive.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_CHART" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_chart.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_EXCEL" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_excel.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_FOLDER" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_folder.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GDOC" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdoc.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GDRAW" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gdraw.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GENERIC" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_generic.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GFORM" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gform.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GMAP" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gmap.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSHEET" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsheet.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSITE" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gsite.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GSLIDES" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gslides.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_GTABLE" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_gtable.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_IMAGE" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_image.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_PDF" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_pdf.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_PPT" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_ppt.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_SCRIPT" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_script.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_SITES" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_sites.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_TINI" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_tini.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_VIDEO" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_video.png" type="BINDATA" /> - <include name="IDR_FILE_MANAGER_IMG_LAUNCHER_FILETYPE_2X_WORD" file="file_manager/foreground/images/launcher_filetypes/2x/launcher_filetype_word.png" type="BINDATA" /> - <!-- Resources used for non-flattened HTML files. --> <include name="IDR_FILE_MANAGER_DRIVE_WELCOME_STYLE" file="file_manager/foreground/css/drive_welcome.css" type="BINDATA" /> <include name="IDR_FILE_MANAGER_IMG_UI_CLOUDS" file="file_manager/foreground/images/files/ui/clouds.png" type="BINDATA" />
diff --git a/ui/gfx/animation/linear_animation.cc b/ui/gfx/animation/linear_animation.cc index f17a3f3..3d8d29e 100644 --- a/ui/gfx/animation/linear_animation.cc +++ b/ui/gfx/animation/linear_animation.cc
@@ -45,8 +45,7 @@ void LinearAnimation::SetCurrentValue(double new_value) { new_value = base::ClampToRange(new_value, 0.0, 1.0); - base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds( - static_cast<int64_t>(duration_.InMicroseconds() * (new_value - state_))); + const base::TimeDelta time_delta = duration_ * (new_value - state_); SetStartTime(start_time() - time_delta); state_ = new_value; } @@ -72,18 +71,13 @@ ? animation_duration_scale : 1.0; }(); - duration_ = duration * duration_scale_factor; - if (duration_ < timer_interval()) - duration_ = timer_interval(); + duration_ = std::max(duration * duration_scale_factor, timer_interval()); if (is_animating()) SetStartTime(container()->last_tick_time()); } void LinearAnimation::Step(base::TimeTicks time_now) { - base::TimeDelta elapsed_time = time_now - start_time(); - state_ = elapsed_time / duration_; - if (state_ >= 1.0) - state_ = 1.0; + state_ = std::min((time_now - start_time()) / duration_, 1.0); AnimateToState(state_);
diff --git a/ui/gfx/paint_throbber.cc b/ui/gfx/paint_throbber.cc index 8b02c44..e6f6f208 100644 --- a/ui/gfx/paint_throbber.cc +++ b/ui/gfx/paint_throbber.cc
@@ -95,12 +95,12 @@ // The sweep angle ranges from -270 to 270 over 1333ms. CSS // animation timing functions apply in between key frames, so we have to // break up the 1333ms into two keyframes (-270 to 0, then 0 to 270). - const double arc_progress = (elapsed_time % kArcTime) / kArcTime; + const double elapsed_ratio = elapsed_time / kArcTime; + const int64_t sweep_frame = base::ClampFloor<int64_t>(elapsed_ratio); + const double arc_progress = elapsed_ratio - sweep_frame; // This tween is equivalent to cubic-bezier(0.4, 0.0, 0.2, 1). double sweep = kMaxArcSize * Tween::CalculateValue(Tween::FAST_OUT_SLOW_IN, arc_progress); - const int64_t sweep_frame = - base::ClampFloor<int64_t>(elapsed_time / kArcTime); if (sweep_frame % 2 == 0) sweep -= kMaxArcSize; @@ -160,13 +160,13 @@ if (waiting_state->arc_time_offset.is_zero()) { for (int64_t arc_ms = 0; arc_ms <= kArcTime.InMillisecondsRoundedUp(); ++arc_ms) { - double arc_size_progress = - std::min(1.0, arc_ms / kArcTime.InMillisecondsF()); + const base::TimeDelta arc_time = + std::min(base::TimeDelta::FromMilliseconds(arc_ms), kArcTime); if (kMaxArcSize * Tween::CalculateValue(Tween::FAST_OUT_SLOW_IN, - arc_size_progress) >= + arc_time / kArcTime) >= waiting_sweep) { // Add kArcTime to sidestep the |sweep_keyframe == 0| offset below. - waiting_state->arc_time_offset = kArcTime * (arc_size_progress + 1); + waiting_state->arc_time_offset = kArcTime + arc_time; break; } }
diff --git a/ui/gfx/skia_vector_animation.cc b/ui/gfx/skia_vector_animation.cc index a39ea1d..63966d00 100644 --- a/ui/gfx/skia_vector_animation.cc +++ b/ui/gfx/skia_vector_animation.cc
@@ -82,8 +82,7 @@ } base::TimeDelta SkiaVectorAnimation::GetAnimationDuration() const { - return base::TimeDelta::FromMilliseconds( - std::floor(SkScalarToFloat(skottie_->duration()) * 1000.f)); + return base::TimeDelta::FromSecondsD(skottie_->duration()); } gfx::Size SkiaVectorAnimation::GetOriginalSize() const { @@ -148,13 +147,11 @@ DCHECK(timer_control_); return timer_control_->GetNormalizedEndOffset(); case PlayState::kPaused: - if (timer_control_) { - return timer_control_->GetNormalizedCurrentCycleProgress(); - } else { - // It may be that the timer hasn't been initialized which may happen if - // the animation was paused while it was in |kScheculePlay| state. - return scheduled_start_offset_ / GetAnimationDuration(); - } + // It may be that the timer hasn't been initialized, which may happen if + // the animation was paused while it was in the kSchedulePlay state. + return timer_control_ + ? timer_control_->GetNormalizedCurrentCycleProgress() + : (scheduled_start_offset_ / GetAnimationDuration()); case PlayState::kSchedulePlay: case PlayState::kPlaying: case PlayState::kScheduleResume:
diff --git a/ui/gfx/skia_vector_animation.h b/ui/gfx/skia_vector_animation.h index 69f1dcf..8c5d252 100644 --- a/ui/gfx/skia_vector_animation.h +++ b/ui/gfx/skia_vector_animation.h
@@ -185,7 +185,7 @@ // Time duration from 0 which marks the beginning of a cycle. const base::TimeDelta start_offset_; - // Time duration from 0 which marks the end of a cycle. + // Time duration from 0 which marks the end of a cycle. const base::TimeDelta end_offset_; // Time duration for one cycle. This is essentially a cache of the
diff --git a/ui/gfx/skia_vector_animation_unittest.cc b/ui/gfx/skia_vector_animation_unittest.cc index 6b2607d..c8209263 100644 --- a/ui/gfx/skia_vector_animation_unittest.cc +++ b/ui/gfx/skia_vector_animation_unittest.cc
@@ -151,7 +151,7 @@ return test_clock_.NowTicks() - ticks; } - const base::TimeTicks NowTicks() const { return test_clock_.NowTicks(); } + base::TimeTicks NowTicks() const { return test_clock_.NowTicks(); } double GetTimerStartOffset() const { return animation_->timer_control_->GetNormalizedStartOffset(); @@ -276,7 +276,7 @@ kAdvance / kAnimationDuration); animation_->Stop(); - EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0.f); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0.0f); EXPECT_TRUE(IsStopped()); } @@ -410,7 +410,7 @@ EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0); - EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.f); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.0f); EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration); @@ -552,7 +552,6 @@ } TEST_F(SkiaVectorAnimationTest, PlayThrobbingAnimation) { - TestAnimationObserver observer; animation_->SetAnimationObserver(&observer); @@ -570,7 +569,7 @@ EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 0); EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0); - EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.f); + EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.0f); EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration); @@ -588,7 +587,7 @@ EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAnimationDuration - kAdvance); animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize()); - EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 1.f); + EXPECT_FLOAT_EQ(animation_->GetCurrentProgress(), 1.0f); EXPECT_TRUE(IsPlaying()); EXPECT_FALSE(observer.animation_cycle_ended()); @@ -777,10 +776,9 @@ EXPECT_TRUE(IsPlaying()); } +// Test to see if the race condition is handled correctly. It may happen that we +// pause the video before it even starts playing. TEST_F(SkiaVectorAnimationTest, PauseBeforePlay) { - // Test to see if the race condition is handled correctly. It may happen that - // we pause the video before it even starts playing. - TestAnimationObserver observer; animation_->SetAnimationObserver(&observer); @@ -810,38 +808,32 @@ } TEST_F(SkiaVectorAnimationTest, PaintTest) { - std::unique_ptr<gfx::Canvas> canvas(new gfx::Canvas( - gfx::Size(kAnimationWidth, kAnimationHeight), 1.f, false)); + gfx::Canvas canvas(gfx::Size(kAnimationWidth, kAnimationHeight), 1.f, false); AdvanceClock(base::TimeDelta::FromMilliseconds(300)); animation_->Start(SkiaVectorAnimation::Style::kLinear); - animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); + animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize()); AdvanceClock(base::TimeDelta::FromMilliseconds(50)); - animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); - SkBitmap bitmap = canvas->GetBitmap(); - IsAllSameColor(SK_ColorGREEN, bitmap); + animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize()); + IsAllSameColor(SK_ColorGREEN, canvas.GetBitmap()); AdvanceClock(base::TimeDelta::FromMilliseconds(2450)); - animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); - bitmap = canvas->GetBitmap(); - IsAllSameColor(SK_ColorGREEN, bitmap); + animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize()); + IsAllSameColor(SK_ColorGREEN, canvas.GetBitmap()); AdvanceClock(base::TimeDelta::FromMilliseconds(50)); - animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); - bitmap = canvas->GetBitmap(); - IsAllSameColor(SK_ColorBLUE, bitmap); + animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize()); + IsAllSameColor(SK_ColorBLUE, canvas.GetBitmap()); AdvanceClock(base::TimeDelta::FromMilliseconds(1000)); - animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); - bitmap = canvas->GetBitmap(); - IsAllSameColor(SK_ColorBLUE, bitmap); + animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize()); + IsAllSameColor(SK_ColorBLUE, canvas.GetBitmap()); AdvanceClock(base::TimeDelta::FromMilliseconds(1400)); - animation_->Paint(canvas.get(), NowTicks(), animation_->GetOriginalSize()); - bitmap = canvas->GetBitmap(); - IsAllSameColor(SK_ColorBLUE, bitmap); + animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize()); + IsAllSameColor(SK_ColorBLUE, canvas.GetBitmap()); } } // namespace gfx
diff --git a/ui/touch_selection/touch_handle.cc b/ui/touch_selection/touch_handle.cc index 2443b22..579f998 100644 --- a/ui/touch_selection/touch_handle.cc +++ b/ui/touch_selection/touch_handle.cc
@@ -21,17 +21,17 @@ // Maximum amount of travel for a fade sequence. This avoids handle "ghosting" // when the handle is moving rapidly while the fade is active. -const double kFadeDistanceSquared = 20.f * 20.f; +constexpr double kFadeDistanceSquared = 20.0f * 20.0f; // Avoid using an empty touch rect, as it may fail the intersection test event // if it lies within the other rect's bounds. -const float kMinTouchMajorForHitTesting = 1.f; +constexpr float kMinTouchMajorForHitTesting = 1.0f; // The maximum touch size to use when computing whether a touch point is // targetting a touch handle. This is necessary for devices that misreport // touch radii, preventing inappropriately largely touch sizes from completely // breaking handle dragging behavior. -const float kMaxTouchMajorForHitTesting = 36.f; +constexpr float kMaxTouchMajorForHitTesting = 36.0f; // Note that the intersection region is boundary *exclusive*. bool RectIntersectsCircle(const gfx::RectF& rect, @@ -236,18 +236,17 @@ DCHECK(enabled_); - float time_u = 1.f - (fade_end_time_ - frame_time) / kFadeDuration; - float position_u = (focus_bottom_ - fade_start_position_).LengthSquared() / - kFadeDistanceSquared; - float u = std::max(time_u, position_u); - SetAlpha(is_visible_ ? u : 1.f - u); + const float time_u = 1.0f - (fade_end_time_ - frame_time) / kFadeDuration; + const float position_u = + (focus_bottom_ - fade_start_position_).LengthSquared() / + kFadeDistanceSquared; + const float u = std::max(time_u, position_u); + SetAlpha(is_visible_ ? u : 1.0f - u); - if (u >= 1.f) { + if (u >= 1) EndFade(); - return false; - } - return true; + return u < 1; } gfx::RectF TouchHandle::GetVisibleBounds() const {
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index beb2c3e..afbbc32 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -2984,10 +2984,9 @@ InitTextfield(); ui::CompositionText composition; composition.text = UTF8ToUTF16("abc123"); - ui::TextInputClient* client = textfield_; - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); uint32_t composed_text_length = - client->ConfirmCompositionText(/* keep_selection */ false); + textfield_->ConfirmCompositionText(/* keep_selection */ false); EXPECT_EQ(composed_text_length, static_cast<uint32_t>(6)); } @@ -2996,10 +2995,9 @@ InitTextfield(); ui::CompositionText composition; composition.text = UTF8ToUTF16(""); - ui::TextInputClient* client = textfield_; - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); uint32_t composed_text_length = - client->ConfirmCompositionText(/* keep_selection */ false); + textfield_->ConfirmCompositionText(/* keep_selection */ false); EXPECT_EQ(composed_text_length, static_cast<uint32_t>(0)); } @@ -3009,31 +3007,32 @@ ui::CompositionText composition; composition.text = UTF8ToUTF16("abc123"); const uint32_t char_count = static_cast<uint32_t>(composition.text.length()); - ui::TextInputClient* client = textfield_; // Compare the composition character bounds with surrounding cursor bounds. for (uint32_t i = 0; i < char_count; ++i) { composition.selection = gfx::Range(i); - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); gfx::Point cursor_origin = GetCursorBounds().origin(); views::View::ConvertPointToScreen(textfield_, &cursor_origin); composition.selection = gfx::Range(i + 1); - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); gfx::Point next_cursor_bottom_left = GetCursorBounds().bottom_left(); views::View::ConvertPointToScreen(textfield_, &next_cursor_bottom_left); gfx::Rect character; - EXPECT_TRUE(client->GetCompositionCharacterBounds(i, &character)); + EXPECT_TRUE(textfield_->GetCompositionCharacterBounds(i, &character)); EXPECT_EQ(character.origin(), cursor_origin) << " i=" << i; EXPECT_EQ(character.bottom_right(), next_cursor_bottom_left) << " i=" << i; } // Return false if the index is out of range. gfx::Rect rect; - EXPECT_FALSE(client->GetCompositionCharacterBounds(char_count, &rect)); - EXPECT_FALSE(client->GetCompositionCharacterBounds(char_count + 1, &rect)); - EXPECT_FALSE(client->GetCompositionCharacterBounds(char_count + 100, &rect)); + EXPECT_FALSE(textfield_->GetCompositionCharacterBounds(char_count, &rect)); + EXPECT_FALSE( + textfield_->GetCompositionCharacterBounds(char_count + 1, &rect)); + EXPECT_FALSE( + textfield_->GetCompositionCharacterBounds(char_count + 100, &rect)); } TEST_F(TextfieldTest, GetCompositionCharacterBounds_ComplexText) { @@ -3059,13 +3058,12 @@ ui::CompositionText composition; composition.text.assign(kUtf16Chars, kUtf16Chars + kUtf16CharsCount); - ui::TextInputClient* client = textfield_; - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); // Make sure GetCompositionCharacterBounds never fails for index. gfx::Rect rects[kUtf16CharsCount]; for (uint32_t i = 0; i < kUtf16CharsCount; ++i) - EXPECT_TRUE(client->GetCompositionCharacterBounds(i, &rects[i])); + EXPECT_TRUE(textfield_->GetCompositionCharacterBounds(i, &rects[i])); // Here we might expect the following results but it actually depends on how // Uniscribe or HarfBuzz treats them with given font. @@ -3077,90 +3075,85 @@ #if defined(OS_CHROMEOS) TEST_F(TextfieldTest, SetAutocorrectRangeText) { InitTextfield(); - ui::TextInputClient* client = textfield_; ui::CompositionText composition; composition.text = UTF8ToUTF16("Initial txt"); - client->SetCompositionText(composition); - client->SetAutocorrectRange(ASCIIToUTF16("text replacement"), - gfx::Range(8, 11)); + textfield_->SetCompositionText(composition); + textfield_->SetAutocorrectRange(ASCIIToUTF16("text replacement"), + gfx::Range(8, 11)); - gfx::Range autocorrect_range = client->GetAutocorrectRange(); + gfx::Range autocorrect_range = textfield_->GetAutocorrectRange(); EXPECT_EQ(autocorrect_range, gfx::Range(8, 24)); base::string16 text; - client->GetTextFromRange(gfx::Range(0, 24), &text); + textfield_->GetTextFromRange(gfx::Range(0, 24), &text); EXPECT_EQ(text, UTF8ToUTF16("Initial text replacement")); } TEST_F(TextfieldTest, SetAutocorrectRangeExplicitlySet) { InitTextfield(); - ui::TextInputClient* client = textfield_; - client->InsertText(UTF8ToUTF16("Initial txt")); - client->SetAutocorrectRange(ASCIIToUTF16("text replacement"), - gfx::Range(8, 11)); + textfield_->InsertText(UTF8ToUTF16("Initial txt")); + textfield_->SetAutocorrectRange(ASCIIToUTF16("text replacement"), + gfx::Range(8, 11)); - gfx::Range autocorrectRange = client->GetAutocorrectRange(); + gfx::Range autocorrectRange = textfield_->GetAutocorrectRange(); EXPECT_EQ(autocorrectRange, gfx::Range(8, 24)); base::string16 text; - client->GetTextFromRange(gfx::Range(0, 24), &text); + textfield_->GetTextFromRange(gfx::Range(0, 24), &text); EXPECT_EQ(text, UTF8ToUTF16("Initial text replacement")); } TEST_F(TextfieldTest, DoesNotSetAutocorrectRangeWhenRangeGivenIsInvalid) { InitTextfield(); - ui::TextInputClient* client = textfield_; ui::CompositionText composition; composition.text = UTF8ToUTF16("Initial"); - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); - EXPECT_FALSE(client->SetAutocorrectRange(ASCIIToUTF16("text replacement"), - gfx::Range(8, 11))); - EXPECT_EQ(gfx::Range(0, 0), client->GetAutocorrectRange()); + EXPECT_FALSE(textfield_->SetAutocorrectRange(ASCIIToUTF16("text replacement"), + gfx::Range(8, 11))); + EXPECT_EQ(gfx::Range(0, 0), textfield_->GetAutocorrectRange()); gfx::Range range; - client->GetTextRange(&range); + textfield_->GetTextRange(&range); base::string16 text; - client->GetTextFromRange(range, &text); + textfield_->GetTextFromRange(range, &text); EXPECT_EQ(composition.text, text); } TEST_F(TextfieldTest, ClearsAutocorrectRangeWhenSetAutocorrectRangeWithEmptyText) { InitTextfield(); - ui::TextInputClient* client = textfield_; ui::CompositionText composition; composition.text = UTF8ToUTF16("Initial"); - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); EXPECT_TRUE( - client->SetAutocorrectRange(base::EmptyString16(), gfx::Range(0, 2))); - EXPECT_EQ(gfx::Range(0, 0), client->GetAutocorrectRange()); + textfield_->SetAutocorrectRange(base::EmptyString16(), gfx::Range(0, 2))); + EXPECT_EQ(gfx::Range(0, 0), textfield_->GetAutocorrectRange()); gfx::Range range; - client->GetTextRange(&range); + textfield_->GetTextRange(&range); base::string16 text; - client->GetTextFromRange(range, &text); + textfield_->GetTextFromRange(range, &text); EXPECT_EQ(composition.text, text); } TEST_F(TextfieldTest, ClearsAutocorrectRangeWhenSetAutocorrectRangeWithEmptyRange) { InitTextfield(); - ui::TextInputClient* client = textfield_; ui::CompositionText composition; composition.text = UTF8ToUTF16("Initial"); - client->SetCompositionText(composition); + textfield_->SetCompositionText(composition); EXPECT_TRUE( - client->SetAutocorrectRange(UTF8ToUTF16("Test"), gfx::Range(0, 0))); - EXPECT_EQ(gfx::Range(0, 0), client->GetAutocorrectRange()); + textfield_->SetAutocorrectRange(UTF8ToUTF16("Test"), gfx::Range(0, 0))); + EXPECT_EQ(gfx::Range(0, 0), textfield_->GetAutocorrectRange()); gfx::Range range; - client->GetTextRange(&range); + textfield_->GetTextRange(&range); base::string16 text; - client->GetTextFromRange(range, &text); + textfield_->GetTextFromRange(range, &text); EXPECT_EQ(composition.text, text); }