diff --git a/AUTHORS b/AUTHORS index 0c29cc8..ce3d7cf 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -384,7 +384,6 @@ Jihun Brent Kim <devgrapher@gmail.com> Jin Yang <jin.a.yang@intel.com> Jincheol Jo <jincheol.jo@navercorp.com> -Jinglong Zuo <zuojinglong@xiaomi.com> Jingwei Liu <kingweiliu@gmail.com> Jingyi Wei <wjywbs@gmail.com> Jinho Bang <jinho.bang@samsung.com>
diff --git a/BUILD.gn b/BUILD.gn index 9dec8407e..8e3a525 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -949,7 +949,6 @@ if (is_fuchsia) { data_deps += [ "//content/shell:content_shell_fuchsia", - "//build/fuchsia/layout_test_proxy:layout_test_proxy_runner", ] }
diff --git a/DEPS b/DEPS index cb7f18d2..bd8b7f3 100644 --- a/DEPS +++ b/DEPS
@@ -100,7 +100,7 @@ # 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': 'e3f3bcb29041e7e926c0a6542bfb85d98b8667da', + 'v8_revision': '9c5f77a1382ee3825f708aba48f5675fb55c84e1', # 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. @@ -120,7 +120,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': 'ad18d2fba9dd5833a2e34bfe90c8e3c9a485e805', + 'pdfium_revision': '95061379c9453b941783398826acff674d2bbfd7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -156,7 +156,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': '4a13b64861dc64457f225a772233438ae35f311d', + 'catapult_revision': '0675e8b8e369f603bbcfc9a992af876d8476e344', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -523,7 +523,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '7c3ff1311a4568e3d369c35560ff77b6b2bdef96', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd3f2c8e7834616e48fbe7cef9286029361b043c5', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -968,7 +968,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '7c0541da63f571512c49758cbc0767117997a270', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'b4e0e50a2bbf9361bea22f58002ad4c76a719fed', # commit position 21742 + Var('webrtc_git') + '/src.git' + '@' + '7f0a069550922031f740eb1a67b18cd06b579199', # commit position 21742 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/aw_contents_statics.cc b/android_webview/browser/aw_contents_statics.cc index b1f7b4f7..081c02f5 100644 --- a/android_webview/browser/aw_contents_statics.cc +++ b/android_webview/browser/aw_contents_statics.cc
@@ -41,7 +41,7 @@ void NotifyClientCertificatesChanged() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - net::CertDatabase::GetInstance()->OnAndroidKeyStoreChanged(); + net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); } void SafeBrowsingWhitelistAssigned(const JavaRef<jobject>& callback,
diff --git a/android_webview/browser/aw_field_trial_creator.cc b/android_webview/browser/aw_field_trial_creator.cc index c5e2044..1f81d4d 100644 --- a/android_webview/browser/aw_field_trial_creator.cc +++ b/android_webview/browser/aw_field_trial_creator.cc
@@ -37,6 +37,19 @@ new variations::SHA1EntropyProvider(client_id)); } +// This experiment is for testing and doesn't control any features. Log it so QA +// can check whether variations is working. +// TODO(crbug/841623): Remove this after launch. +void LogTestExperiment() { + static const char* const test_name = "First-WebView-Experiment"; + base::FieldTrial* test_trial = base::FieldTrialList::Find(test_name); + if (test_trial) { + LOG(INFO) << test_name << " found, group=" << test_trial->group_name(); + } else { + LOG(INFO) << test_name << " not found"; + } +} + } // anonymous namespace AwFieldTrialCreator::AwFieldTrialCreator() @@ -108,6 +121,8 @@ std::vector<std::string>(), CreateLowEntropyProvider(client_id), std::make_unique<base::FeatureList>(), aw_field_trials_.get(), &ignored_safe_seed_manager); + + LogTestExperiment(); } } // namespace android_webview
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 19abaed..2bdd9c5 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1208,6 +1208,7 @@ public_deps = [ "//ash/public/cpp", "//ash/public/cpp/vector_icons", + "//ash/resources", "//ash/resources/vector_icons", "//ash/strings", "//ash/wayland", @@ -1830,6 +1831,7 @@ "//ash/public/cpp", "//ash/public/cpp:unit_tests", "//ash/public/cpp/vector_icons", + "//ash/resources", "//ash/resources/vector_icons", "//ash/strings", "//ash/touch_hud", @@ -2128,6 +2130,7 @@ "//ash/components/fast_ink", "//ash/public/cpp", "//ash/public/interfaces:test_interfaces", + "//ash/resources", "//base", "//base:i18n", "//base/test:test_support", @@ -2229,6 +2232,7 @@ output = "$root_out_dir/ash_service_resources.pak" sources = [ "$root_gen_dir/ash/components/resources/ash_components_resources_100_percent.pak", + "$root_gen_dir/ash/resources/ash_resources_100_percent.pak", "$root_gen_dir/ash/strings/ash_strings_en-US.pak", "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_100_percent.pak", "$root_gen_dir/ui/chromeos/strings/ui_chromeos_strings_en-US.pak", @@ -2239,6 +2243,7 @@ ] deps = [ "//ash/components/resources", + "//ash/resources", "//ash/strings", "//ui/chromeos/resources", "//ui/chromeos/strings", @@ -2253,12 +2258,14 @@ output = "$root_out_dir/ash_service_resources_200.pak" sources = [ "$root_gen_dir/ash/components/resources/ash_components_resources_200_percent.pak", + "$root_gen_dir/ash/resources/ash_resources_200_percent.pak", "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_200_percent.pak", "$root_gen_dir/ui/resources/ui_resources_200_percent.pak", "$root_gen_dir/ui/views/resources/views_resources_200_percent.pak", ] deps = [ "//ash/components/resources", + "//ash/resources", "//ui/chromeos/resources", "//ui/resources", "//ui/views/resources",
diff --git a/ash/display/resolution_notification_controller.cc b/ash/display/resolution_notification_controller.cc index 7d31f4e..22e7bb2 100644 --- a/ash/display/resolution_notification_controller.cc +++ b/ash/display/resolution_notification_controller.cc
@@ -6,7 +6,7 @@ #include <utility> -#include "ash/resources/vector_icons/vector_icons.h" +#include "ash/resources/grit/ash_resources.h" #include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/time_format.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" @@ -220,22 +221,17 @@ base::UTF8ToUTF16( change_info_->current_resolution.size().ToString())); - std::unique_ptr<Notification> notification = - Notification::CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId, message, - timeout_message, gfx::Image(), - base::string16(), // display_source - GURL(), - message_center::NotifierId( - message_center::NotifierId::SYSTEM_COMPONENT, - kNotifierDisplayResolutionChange), - data, - base::MakeRefCounted<message_center::ThunkNotificationDelegate>( - weak_factory_.GetWeakPtr()), - kNotificationScreenIcon, - message_center::SystemNotificationWarningLevel::NORMAL); - notification->set_priority(message_center::SYSTEM_PRIORITY); - + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + auto notification = std::make_unique<Notification>( + message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId, message, + timeout_message, bundle.GetImageNamed(IDR_AURA_NOTIFICATION_DISPLAY), + base::string16() /* display_source */, GURL(), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + kNotifierDisplayResolutionChange), + data, + base::MakeRefCounted<message_center::ThunkNotificationDelegate>( + weak_factory_.GetWeakPtr())); + notification->SetSystemPriority(); message_center->AddNotification(std::move(notification)); }
diff --git a/ash/frame/caption_buttons/frame_caption_button.cc b/ash/frame/caption_buttons/frame_caption_button.cc index d357ba7..5001aad 100644 --- a/ash/frame/caption_buttons/frame_caption_button.cc +++ b/ash/frame/caption_buttons/frame_caption_button.cc
@@ -220,7 +220,13 @@ } void FrameCaptionButton::SetBackgroundColor(SkColor background_color) { + if (background_color_ == background_color) + return; + background_color_ = background_color; + // Refresh the icon since the color may have changed. + if (icon_definition_) + SetImage(icon_, ANIMATE_NO, *icon_definition_); UpdateInkDropBaseColor(); }
diff --git a/ash/frame/caption_buttons/frame_caption_button.h b/ash/frame/caption_buttons/frame_caption_button.h index cb94faa6..5bed667 100644 --- a/ash/frame/caption_buttons/frame_caption_button.h +++ b/ash/frame/caption_buttons/frame_caption_button.h
@@ -73,6 +73,8 @@ paint_as_active_ = paint_as_active; } + bool paint_as_active() { return paint_as_active_; } + CaptionButtonIcon icon() const { return icon_; } const gfx::VectorIcon* icon_definition_for_test() const {
diff --git a/ash/frame/custom_frame_header.cc b/ash/frame/custom_frame_header.cc index d47f98f..89b710d 100644 --- a/ash/frame/custom_frame_header.cc +++ b/ash/frame/custom_frame_header.cc
@@ -141,6 +141,15 @@ appearance_provider_ = appearance_provider; is_incognito_ = incognito; caption_button_container_ = caption_button_container; + + caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_MINIMIZE, + kWindowControlMinimizeIcon); + caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_CLOSE, + kWindowControlCloseIcon); + caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_LEFT_SNAPPED, + kWindowControlLeftSnappedIcon); + caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, + kWindowControlRightSnappedIcon); } int CustomFrameHeader::GetMinimumHeaderWidth() const { @@ -216,6 +225,7 @@ void CustomFrameHeader::OnShowStateChanged(ui::WindowShowState show_state) { if (show_state == ui::SHOW_STATE_MINIMIZED) return; + // Call LayoutHeaderInternal() instead of LayoutHeader() here because // |show_state| shouldn't cause |painted_height_| change. LayoutHeaderInternal(); @@ -249,7 +259,19 @@ // CustomFrameHeader, private: void CustomFrameHeader::LayoutHeaderInternal() { - UpdateCaptionButtons(); + caption_button_container_->SetButtonImage( + CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, + GetWidget()->IsMaximized() || GetWidget()->IsFullscreen() + ? kWindowControlRestoreIcon + : kWindowControlMaximizeIcon); + + const AshLayoutSize button_size_type = + GetWidget()->IsMaximized() || GetWidget()->IsFullscreen() || + appearance_provider_->IsTabletMode() + ? AshLayoutSize::kBrowserCaptionMaximized + : AshLayoutSize::kBrowserCaptionRestored; + caption_button_container_->SetButtonSize(GetAshLayoutSize(button_size_type)); + const gfx::Size caption_button_container_size = caption_button_container_->GetPreferredSize(); caption_button_container_->SetBounds( @@ -307,35 +329,6 @@ gfx::Canvas::NO_SUBPIXEL_RENDERING); } -void CustomFrameHeader::UpdateCaptionButtons() { - // When |frame_| minimized, avoid tablet mode toggling to update caption - // buttons as it would cause mismatch beteen window state and size button. - if (GetWidget()->IsMinimized()) - return; - caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_MINIMIZE, - kWindowControlMinimizeIcon); - caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_CLOSE, - kWindowControlCloseIcon); - caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_LEFT_SNAPPED, - kWindowControlLeftSnappedIcon); - caption_button_container_->SetButtonImage(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, - kWindowControlRightSnappedIcon); - - const bool is_maximized_or_fullscreen = - GetWidget()->IsMaximized() || GetWidget()->IsFullscreen(); - const AshLayoutSize button_size_type = - is_maximized_or_fullscreen || appearance_provider_->IsTabletMode() - ? AshLayoutSize::kBrowserCaptionMaximized - : AshLayoutSize::kBrowserCaptionRestored; - const gfx::VectorIcon* const size_icon = is_maximized_or_fullscreen - ? &kWindowControlRestoreIcon - : &kWindowControlMaximizeIcon; - - caption_button_container_->SetButtonImage( - CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, *size_icon); - caption_button_container_->SetButtonSize(GetAshLayoutSize(button_size_type)); -} - gfx::Rect CustomFrameHeader::GetPaintedBounds() const { return gfx::Rect(view_->width(), painted_height_); }
diff --git a/ash/frame/custom_frame_header.h b/ash/frame/custom_frame_header.h index 8eaa05b..561d3732 100644 --- a/ash/frame/custom_frame_header.h +++ b/ash/frame/custom_frame_header.h
@@ -82,10 +82,6 @@ // Paints the title bar, primarily the title string. void PaintTitleBar(gfx::Canvas* canvas); - // Updates the size and icons used for the minimize, restore, and close - // buttons. - void UpdateCaptionButtons(); - // Returns bounds of the region in |view_| which is painted with the header // images. The region is assumed to start at the top left corner of |view_| // and to have the same width as |view_|.
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index adc097f..373155c2 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -37,9 +37,6 @@ const base::Feature kLockScreenNotifications{"LockScreenNotifications", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kModeSpecificPowerButton{"ModeSpecificPowerButton", - base::FEATURE_ENABLED_BY_DEFAULT}; - bool IsDisplayMoveWindowAccelsEnabled() { return base::FeatureList::IsEnabled(kDisplayMoveWindowAccels); } @@ -70,9 +67,5 @@ return base::FeatureList::IsEnabled(kLockScreenNotifications); } -bool IsModeSpecificPowerButtonEnabled() { - return base::FeatureList::IsEnabled(kModeSpecificPowerButton); -} - } // namespace features } // namespace ash
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index 764849d..14c226a 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -55,11 +55,6 @@ // Enables notifications on the lock screen. ASH_PUBLIC_EXPORT extern const base::Feature kLockScreenNotifications; -// Enables mode-specific power button behavior. -// TODO(derat): Remove this after we make a decision about whether to enable it -// by default: https://crbug.com/819276 -ASH_PUBLIC_EXPORT extern const base::Feature kModeSpecificPowerButton; - ASH_PUBLIC_EXPORT bool IsDisplayMoveWindowAccelsEnabled(); ASH_PUBLIC_EXPORT bool IsDockedMagnifierEnabled(); @@ -74,8 +69,6 @@ ASH_PUBLIC_EXPORT bool IsLockScreenNotificationsEnabled(); -ASH_PUBLIC_EXPORT bool IsModeSpecificPowerButtonEnabled(); - } // namespace features } // namespace ash
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc index 79c94b0..b494e79 100644 --- a/ash/public/cpp/ash_switches.cc +++ b/ash/public/cpp/ash_switches.cc
@@ -122,10 +122,6 @@ // instead of displaying an interactive animation. const char kAuraLegacyPowerButton[] = "aura-legacy-power-button"; -// Forces non-tablet-style power button behavior even if the device has a -// convertible form factor. -const char kForceClamshellPowerButton[] = "force-clamshell-power-button"; - // Whether this device has an internal stylus. const char kHasInternalStylus[] = "has-internal-stylus";
diff --git a/ash/public/cpp/ash_switches.h b/ash/public/cpp/ash_switches.h index 0b198ed6..4bd63cbc 100644 --- a/ash/public/cpp/ash_switches.h +++ b/ash/public/cpp/ash_switches.h
@@ -53,7 +53,6 @@ ASH_PUBLIC_EXPORT extern const char kAshSidebarEnabled[]; ASH_PUBLIC_EXPORT extern const char kAshTouchHud[]; ASH_PUBLIC_EXPORT extern const char kAuraLegacyPowerButton[]; -ASH_PUBLIC_EXPORT extern const char kForceClamshellPowerButton[]; ASH_PUBLIC_EXPORT extern const char kHasInternalStylus[]; ASH_PUBLIC_EXPORT extern const char kShowTaps[]; ASH_PUBLIC_EXPORT extern const char kShowViewsLogin[];
diff --git a/ash/resources/BUILD.gn b/ash/resources/BUILD.gn index 630351a..625e6dc 100644 --- a/ash/resources/BUILD.gn +++ b/ash/resources/BUILD.gn
@@ -9,6 +9,15 @@ assert(is_chromeos) assert(enable_hidpi) +grit("resources") { + source = "ash_resources.grd" + outputs = [ + "grit/ash_resources.h", + "ash_resources_100_percent.pak", + "ash_resources_200_percent.pak", + ] +} + # Repacks resources needed for ash_unittests, etc. at a given scale. # TODO(msw): Use ui_test.pak instead of its pieces? (no 200% support?) template("ash_test_resources") { @@ -20,6 +29,7 @@ sources = [ "$root_gen_dir/ash/components/resources/ash_components_resources_${percent}_percent.pak", "$root_gen_dir/ash/public/cpp/resources/ash_public_unscaled_resources.pak", + "$root_gen_dir/ash/resources/ash_resources_${percent}_percent.pak", "$root_gen_dir/ui/app_list/resources/app_list_resources_${percent}_percent.pak", "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_${percent}_percent.pak", "$root_gen_dir/ui/resources/ui_resources_${percent}_percent.pak", @@ -40,6 +50,7 @@ deps = [ "//ash/components/resources", "//ash/public/cpp/resources:ash_public_unscaled_resources", + "//ash/resources", "//mojo/public/js:resources", "//ui/app_list/resources", "//ui/chromeos/resources",
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd new file mode 100644 index 0000000..1edf3c9 --- /dev/null +++ b/ash/resources/ash_resources.grd
@@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/ash_resources.h" type="rc_header" context="default_100_percent"> + <emit emit_type='prepend'></emit> + </output> + <output filename="ash_resources_100_percent.pak" type="data_package" context="default_100_percent" /> + <output filename="ash_resources_200_percent.pak" type="data_package" context="default_200_percent" /> + </outputs> + <release seq="1"> + <structures fallback_to_low_resolution="true"> + <!-- KEEP THESE IN ALPHABETICAL ORDER! DO NOT ADD TO RANDOM PLACES JUST + BECAUSE YOUR RESOURCES ARE FUNCTIONALLY RELATED OR FALL UNDER THE + SAME CONDITIONALS. --> + + <structure type="chrome_scaled_image" name="IDR_AURA_NOTIFICATION_DISPLAY" file="cros/notification/display_notification_icon.png" /> + </structures> + </release> +</grit>
diff --git a/ash/resources/default_100_percent/cros/notification/display_notification_icon.png b/ash/resources/default_100_percent/cros/notification/display_notification_icon.png new file mode 100644 index 0000000..e49d82a2 --- /dev/null +++ b/ash/resources/default_100_percent/cros/notification/display_notification_icon.png Binary files differ
diff --git a/ash/resources/default_200_percent/cros/notification/display_notification_icon.png b/ash/resources/default_200_percent/cros/notification/display_notification_icon.png new file mode 100644 index 0000000..832e974f --- /dev/null +++ b/ash/resources/default_200_percent/cros/notification/display_notification_icon.png Binary files differ
diff --git a/ash/system/bluetooth/bluetooth_notification_controller.cc b/ash/system/bluetooth/bluetooth_notification_controller.cc index c517b81b..58e6b82 100644 --- a/ash/system/bluetooth/bluetooth_notification_controller.cc +++ b/ash/system/bluetooth/bluetooth_notification_controller.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "base/bind.h"
diff --git a/ash/system/locale/locale_notification_controller.cc b/ash/system/locale/locale_notification_controller.cc index 8c2a573..bb84369c 100644 --- a/ash/system/locale/locale_notification_controller.cc +++ b/ash/system/locale/locale_notification_controller.cc
@@ -8,6 +8,7 @@ #include <utility> #include "ash/public/cpp/vector_icons/vector_icons.h" +#include "ash/resources/grit/ash_resources.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/system_tray_notifier.h" #include "base/strings/string16.h"
diff --git a/ash/system/message_center/notification_tray.cc b/ash/system/message_center/notification_tray.cc index 66ee5a3..8c3fe8c 100644 --- a/ash/system/message_center/notification_tray.cc +++ b/ash/system/message_center/notification_tray.cc
@@ -189,6 +189,16 @@ private: // gfx::AnimationDelegate: void AnimationProgressed(const gfx::Animation* animation) override { + // After HideAndDelete() has been called and |this| is responsible for + // deleting itself, but |tray_| has been deleted before the animation + // reached its end, |this| will be parentless. It's ok to stop the animation + // (deleting |this|). See https://crbug.com/841768 + if (!parent()) { + DCHECK(delete_after_animation_); + animation_->Stop(); + return; + } + gfx::Transform transform; if (tray_->shelf()->IsHorizontalAlignment()) { transform.Translate(0, animation->CurrentValueBetween( @@ -202,6 +212,7 @@ layer()->SetTransform(transform); PreferredSizeChanged(); } + void AnimationEnded(const gfx::Animation* animation) override { if (animation->GetCurrentValue() < 0.1) views::View::SetVisible(false);
diff --git a/ash/system/power/battery_notification.cc b/ash/system/power/battery_notification.cc index 75d9066..6202550 100644 --- a/ash/system/power/battery_notification.cc +++ b/ash/system/power/battery_notification.cc
@@ -5,6 +5,7 @@ #include "ash/system/power/battery_notification.h" #include "ash/public/cpp/power_utils.h" +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/power/power_status.h"
diff --git a/ash/system/power/dual_role_notification.cc b/ash/system/power/dual_role_notification.cc index a27e009..9f6b204 100644 --- a/ash/system/power/dual_role_notification.cc +++ b/ash/system/power/dual_role_notification.cc
@@ -6,6 +6,7 @@ #include <set> +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h"
diff --git a/ash/system/power/peripheral_battery_notifier.cc b/ash/system/power/peripheral_battery_notifier.cc index f3850e7..f1b9023 100644 --- a/ash/system/power/peripheral_battery_notifier.cc +++ b/ash/system/power/peripheral_battery_notifier.cc
@@ -6,6 +6,7 @@ #include <vector> +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h"
diff --git a/ash/system/power/power_button_controller.cc b/ash/system/power/power_button_controller.cc index fbd0033..a75a504 100644 --- a/ash/system/power/power_button_controller.cc +++ b/ash/system/power/power_button_controller.cc
@@ -211,7 +211,7 @@ const base::TimeTicks& timestamp) { if (down) { force_off_on_button_up_ = false; - if (ShouldTurnScreenOffForTap()) { + if (in_tablet_mode_) { force_off_on_button_up_ = true; // When the system resumes in response to the power button being pressed, @@ -242,7 +242,7 @@ return; } - if (!ShouldTurnScreenOffForTap()) { + if (!in_tablet_mode_) { StartPowerMenuAnimation(); } else { base::TimeDelta timeout = screen_off_when_power_button_down_ @@ -268,7 +268,7 @@ pre_shutdown_timer_.Stop(); const bool menu_was_opened = IsMenuOpened(); - if (!ShouldTurnScreenOffForTap()) { + if (!in_tablet_mode_) { // Cancel the menu animation if it's still ongoing when the button is // released on a laptop-mode device. if (menu_was_opened && !show_menu_animation_done_) { @@ -407,27 +407,17 @@ if (!result.has_value()) return; - // Turn screen off if tapping the power button (except - // |force_clamshell_power_button_|) and power button screenshot accelerator - // are enabled on devices that have a tablet mode switch. - if (result->tablet_mode == + if (result->tablet_mode != chromeos::PowerManagerClient::TabletMode::UNSUPPORTED) { - return; + has_tablet_mode_switch_ = true; + InitTabletPowerButtonMembers(); } - - has_tablet_mode_switch_ = true; - InitTabletPowerButtonMembers(); } void PowerButtonController::OnAccelerometerUpdated( scoped_refptr<const chromeos::AccelerometerUpdate> update) { - // Turn screen off if tapping the power button (except - // |force_clamshell_power_button_|) and power button screenshot accelerator - // are enabled on devices that can enter tablet mode, which must have a tablet - // mode switch or report accelerometer data before user actions. - if (has_tablet_mode_switch_ || !observe_accelerometer_events_) - return; - InitTabletPowerButtonMembers(); + if (!has_tablet_mode_switch_ && observe_accelerometer_events_) + InitTabletPowerButtonMembers(); } void PowerButtonController::OnBacklightsForcedOffChanged(bool forced_off) { @@ -460,12 +450,6 @@ lock_button_down_ = false; } -bool PowerButtonController::ShouldTurnScreenOffForTap() const { - return features::IsModeSpecificPowerButtonEnabled() - ? in_tablet_mode_ - : default_turn_screen_off_for_tap_; -} - void PowerButtonController::StopTimersAndDismissMenu() { pre_shutdown_timer_.Stop(); power_button_menu_timer_.Stop(); @@ -503,16 +487,11 @@ ? ButtonType::LEGACY : ButtonType::NORMAL; observe_accelerometer_events_ = cl->HasSwitch(switches::kAshEnableTabletMode); - force_clamshell_power_button_ = - cl->HasSwitch(switches::kForceClamshellPowerButton); ParsePowerButtonPositionSwitch(); } void PowerButtonController::InitTabletPowerButtonMembers() { - if (!force_clamshell_power_button_) - default_turn_screen_off_for_tap_ = true; - if (!screenshot_controller_) { screenshot_controller_ = std::make_unique<PowerButtonScreenshotController>(tick_clock_);
diff --git a/ash/system/power/power_button_controller.h b/ash/system/power/power_button_controller.h index 0a19026..9e78275 100644 --- a/ash/system/power/power_button_controller.h +++ b/ash/system/power/power_button_controller.h
@@ -126,8 +126,8 @@ void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; void SuspendDone(const base::TimeDelta& sleep_duration) override; - // Initializes |default_turn_screen_off_for_tap_| and |screenshot_controller_| - // according to the tablet mode switch in |result|. + // Initializes |screenshot_controller_| according to the tablet mode switch in + // |result|. void OnGetSwitchStates( base::Optional<chromeos::PowerManagerClient::SwitchStates> result); @@ -153,10 +153,6 @@ class ActiveWindowWidgetController; friend class PowerButtonControllerTestApi; - // Returns true if the screen should be turned off in response to the power - // button being tapped. - bool ShouldTurnScreenOffForTap() const; - // Stops |power_button_menu_timer_|, |shutdown_timer_| and dismisses the power // button menu. void StopTimersAndDismissMenu(); @@ -173,8 +169,8 @@ // current command line. void ProcessCommandLine(); - // Initializes tablet power button behavior related members - // |default_turn_screen_off_for_tap_| and |screenshot_controller_|. + // Initializes tablet power button behavior related member + // |screenshot_controller_|. void InitTabletPowerButtonMembers(); // Locks the screen if the "Show lock screen when waking from sleep" pref is @@ -225,11 +221,6 @@ // True if the device has tablet mode switch. bool has_tablet_mode_switch_ = false; - // True if we should turn screen off when the power button is tapped. - // This may be overridden by a feature; use ShouldTurnScreenOffForTap() to - // get the actual desired behavior. - bool default_turn_screen_off_for_tap_ = false; - // True if the screen was off when the power button was pressed. bool screen_off_when_power_button_down_ = false;
diff --git a/ash/system/power/power_button_controller_test_api.cc b/ash/system/power/power_button_controller_test_api.cc index bb50db71..4bb27c7 100644 --- a/ash/system/power/power_button_controller_test_api.cc +++ b/ash/system/power/power_button_controller_test_api.cc
@@ -93,11 +93,6 @@ controller_->backlights_forced_off_setter_, controller_->tick_clock_); } -void PowerButtonControllerTestApi::SetTurnScreenOffForTap( - bool turn_screen_off_for_tap) { - controller_->default_turn_screen_off_for_tap_ = turn_screen_off_for_tap; -} - void PowerButtonControllerTestApi::SetShowMenuAnimationDone( bool show_menu_animation_done) { controller_->show_menu_animation_done_ = show_menu_animation_done;
diff --git a/ash/system/power/power_button_controller_test_api.h b/ash/system/power/power_button_controller_test_api.h index 4d4c14f..000f23b 100644 --- a/ash/system/power/power_button_controller_test_api.h +++ b/ash/system/power/power_button_controller_test_api.h
@@ -67,8 +67,6 @@ void SetTickClock(const base::TickClock* tick_clock); - void SetTurnScreenOffForTap(bool turn_screen_off_for_tap); - void SetShowMenuAnimationDone(bool show_menu_animation_done); private:
diff --git a/ash/system/power/power_button_controller_unittest.cc b/ash/system/power/power_button_controller_unittest.cc index 8776299..ed7ac33 100644 --- a/ash/system/power/power_button_controller_unittest.cc +++ b/ash/system/power/power_button_controller_unittest.cc
@@ -278,24 +278,6 @@ // Should turn screen on if screen is off. AdvanceClockToAvoidIgnoring(); TappingPowerButtonWhenScreenIsIdleOff(); - - // Should not turn screen off if clamshell-like power button behavior is - // requested. - AdvanceClockToAvoidIgnoring(); - ForceClamshellPowerButton(); - SetTabletModeSwitchState(PowerManagerClient::TabletMode::ON); - AdvanceClockToAvoidIgnoring(); - EXPECT_FALSE(power_manager_client_->backlights_forced_off()); - PressPowerButton(); - power_button_test_api_->SetShowMenuAnimationDone(false); - // Forced clamshell power button device should start showing menu animation - // immediately as pressing the power button. - EXPECT_TRUE(power_button_test_api_->IsMenuOpened()); - ReleasePowerButton(); - EXPECT_FALSE(power_manager_client_->backlights_forced_off()); - // Forced clamshell power button device should start dismissing menu animation - // immediately as releasing the power button. - EXPECT_FALSE(power_button_test_api_->IsMenuOpened()); } // Tests that power button taps turn the screen off while in tablet mode but not
diff --git a/ash/system/power/power_button_test_base.cc b/ash/system/power/power_button_test_base.cc index 352110f..4f51a11 100644 --- a/ash/system/power/power_button_test_base.cc +++ b/ash/system/power/power_button_test_base.cc
@@ -67,9 +67,7 @@ if (initial_tablet_mode_switch_state != chromeos::PowerManagerClient::TabletMode::UNSUPPORTED) { SetTabletModeSwitchState(initial_tablet_mode_switch_state); - screenshot_controller_ = power_button_test_api_->GetScreenshotController(); } else { - power_button_test_api_->SetTurnScreenOffForTap(false); screenshot_controller_ = nullptr; } } @@ -84,12 +82,6 @@ screenshot_controller_ = power_button_test_api_->GetScreenshotController(); } -void PowerButtonTestBase::ForceClamshellPowerButton() { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kForceClamshellPowerButton); - ResetPowerButtonController(); -} - void PowerButtonTestBase::PressPowerButton() { power_button_controller_->PowerButtonEventReceived(true, tick_clock_.NowTicks());
diff --git a/ash/system/power/power_button_test_base.h b/ash/system/power/power_button_test_base.h index f96c3fe..783f755 100644 --- a/ash/system/power/power_button_test_base.h +++ b/ash/system/power/power_button_test_base.h
@@ -55,10 +55,6 @@ void SetTabletModeSwitchState( chromeos::PowerManagerClient::TabletMode tablet_mode_switch_state); - // Sets the flag for forcing clamshell-like power button behavior and resets - // |power_button_controller_|. - void ForceClamshellPowerButton(); - // Simulates a power button press. void PressPowerButton();
diff --git a/ash/system/power/tray_power.cc b/ash/system/power/tray_power.cc index 630e6d8..df245179 100644 --- a/ash/system/power/tray_power.cc +++ b/ash/system/power/tray_power.cc
@@ -8,7 +8,7 @@ #include "ash/accessibility/accessibility_delegate.h" #include "ash/public/cpp/ash_switches.h" - +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/date/date_view.h"
diff --git a/ash/system/screen_layout_observer.cc b/ash/system/screen_layout_observer.cc index 78aae21..b4b96a3 100644 --- a/ash/system/screen_layout_observer.cc +++ b/ash/system/screen_layout_observer.cc
@@ -11,6 +11,7 @@ #include "ash/display/screen_orientation_controller.h" #include "ash/metrics/user_metrics_action.h" #include "ash/metrics/user_metrics_recorder.h" +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" #include "ash/shell.h"
diff --git a/ash/system/screen_security/screen_capture_tray_item.cc b/ash/system/screen_security/screen_capture_tray_item.cc index 61616d8..472194a9 100644 --- a/ash/system/screen_security/screen_capture_tray_item.cc +++ b/ash/system/screen_security/screen_capture_tray_item.cc
@@ -9,7 +9,7 @@ #include "ash/metrics/user_metrics_action.h" #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/ash_features.h" - +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h"
diff --git a/ash/system/screen_security/screen_share_tray_item.cc b/ash/system/screen_security/screen_share_tray_item.cc index eed0520c..38ee086 100644 --- a/ash/system/screen_security/screen_share_tray_item.cc +++ b/ash/system/screen_security/screen_share_tray_item.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "ash/resources/grit/ash_resources.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h"
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc index ad0fd94..a007d60b 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -635,24 +635,6 @@ EXPECT_TRUE(controller.IsTabletModeWindowManagerEnabled()); } -// Verify when the force clamshell mode flag is turned on, opening the lid past -// 180 degrees or setting tablet mode to true will no turn on tablet mode. -TEST_F(TabletModeControllerTest, ForceClamshellModeTest) { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kAshUiMode, switches::kAshUiModeClamshell); - tablet_mode_controller()->OnShellInitialized(); - EXPECT_EQ(TabletModeController::UiMode::CLAMSHELL, forced_ui_mode()); - EXPECT_FALSE(IsTabletModeStarted()); - - OpenLidToAngle(300.0f); - EXPECT_FALSE(IsTabletModeStarted()); - EXPECT_FALSE(AreEventsBlocked()); - - SetTabletMode(true); - EXPECT_FALSE(IsTabletModeStarted()); - EXPECT_FALSE(AreEventsBlocked()); -} - // Verify when the force touch view mode flag is turned on, tablet mode is on // initially, and opening the lid to less than 180 degress or setting tablet // mode to off will not turn off tablet mode.
diff --git a/base/BUILD.gn b/base/BUILD.gn index f56fd47..9104990 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -54,6 +54,14 @@ # LockImpl::PriorityInheritanceAvailable() in lock_impl_posix.cc for the # platform requirements to safely enable priority inheritance. enable_mutex_priority_inheritance = false + + # Determines whether libevent should be dep. + dep_libevent = !is_fuchsia && !is_win && !(is_nacl && !is_nacl_nonsfi) +} + +declare_args() { + # Determines whether message_pump_libevent should be used. + use_libevent = dep_libevent && !is_ios } if (is_android) { @@ -1409,11 +1417,6 @@ "//third_party/fuchsia-sdk:svc", "//third_party/fuchsia-sdk:zx", ] - } else { - sources += [ - "message_loop/message_pump_libevent.cc", - "message_loop/message_pump_libevent.h", - ] } # NaCl. @@ -1483,8 +1486,6 @@ "files/file_util_posix.cc", "json/json_file_value_serializer.cc", "json/json_file_value_serializer.h", - "message_loop/message_pump_libevent.cc", - "message_loop/message_pump_libevent.h", "posix/unix_domain_socket.cc", "process/kill_posix.cc", "process/launch.cc", @@ -1557,7 +1558,6 @@ "file_descriptor_store.h", "memory/shared_memory_helper.cc", "memory/shared_memory_helper.h", - "message_loop/message_pump_libevent.cc", "strings/string16.cc", ] @@ -1587,9 +1587,6 @@ ":base_win_linker_flags", "//tools/win/DebugVisualizers:chrome", ] - } else if ((!is_nacl && !is_fuchsia) || is_nacl_nonsfi) { - # Non-Windows. - deps += [ "//base/third_party/libevent" ] } # Desktop Mac. @@ -1685,8 +1682,6 @@ "files/file_path_watcher_kqueue.h", "memory/discardable_shared_memory.cc", "memory/discardable_shared_memory.h", - "message_loop/message_pump_libevent.cc", - "message_loop/message_pump_libevent.h", "process/kill.cc", "process/kill.h", "process/kill_posix.cc", @@ -1747,6 +1742,17 @@ set_sources_assignment_filter(sources_assignment_filter) } + if (dep_libevent) { + deps += [ "//base/third_party/libevent" ] + } + + if (use_libevent) { + sources += [ + "message_loop/message_pump_libevent.cc", + "message_loop/message_pump_libevent.h", + ] + } + # Android and MacOS have their own custom shared memory handle # implementations. e.g. due to supporting both POSIX and native handles. if (is_posix && !is_android && !is_mac) { @@ -2124,7 +2130,6 @@ sources = [ "fuchsia/test.fidl", ] - namespace = "base" } } @@ -2597,7 +2602,7 @@ sources -= [ "message_loop/message_pump_glib_unittest.cc" ] } - if (is_posix && !is_ios) { + if (use_libevent) { sources += [ "message_loop/message_pump_libevent_unittest.cc" ] deps += [ "//base/third_party/libevent" ] }
diff --git a/base/message_loop/message_loop_current.cc b/base/message_loop/message_loop_current.cc index 502b424..0255a770 100644 --- a/base/message_loop/message_loop_current.cc +++ b/base/message_loop/message_loop_current.cc
@@ -154,7 +154,7 @@ #endif // defined(OS_ANDROID) } -#if defined(USE_OZONE) && !defined(OS_FUCHSIA) +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) && !defined(OS_WIN) bool MessageLoopCurrentForUI::WatchFileDescriptor( int fd, bool persistent,
diff --git a/base/message_loop/message_loop_current.h b/base/message_loop/message_loop_current.h index cf30bae0..2bbad5d 100644 --- a/base/message_loop/message_loop_current.h +++ b/base/message_loop/message_loop_current.h
@@ -210,7 +210,7 @@ MessageLoopCurrentForUI* operator->() { return this; } -#if defined(USE_OZONE) && !defined(OS_FUCHSIA) +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) && !defined(OS_WIN) // Please see MessagePumpLibevent for definition. static_assert(std::is_same<MessagePumpForUI, MessagePumpLibevent>::value, "MessageLoopCurrentForUI::WatchFileDescriptor is not supported "
diff --git a/base/trace_event/trace_event_etw_export_win.cc b/base/trace_event/trace_event_etw_export_win.cc index ff8d2ff..993a222 100644 --- a/base/trace_event/trace_event_etw_export_win.cc +++ b/base/trace_event/trace_event_etw_export_win.cc
@@ -69,7 +69,7 @@ "gpu", // 0x20 "input", // 0x40 "netlog", // 0x80 - "renderer.scheduler", // 0x100 + "sequence_manager", // 0x100 "toplevel", // 0x200 "v8", // 0x400 "disabled-by-default-cc.debug", // 0x800
diff --git a/build/android/gradle/AndroidManifest.xml b/build/android/gradle/AndroidManifest.xml new file mode 100644 index 0000000..f3e50e0 --- /dev/null +++ b/build/android/gradle/AndroidManifest.xml
@@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2018 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. +--> + +<!-- + This is a dummy manifest which is required by Android Studio's _all target. + No <uses-sdk> is allowed due to https://crbug.com/841529. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.dummy"> +</manifest>
diff --git a/build/android/gradle/android.jinja b/build/android/gradle/android.jinja index 658955d..9a10875 100644 --- a/build/android/gradle/android.jinja +++ b/build/android/gradle/android.jinja
@@ -78,6 +78,14 @@ {% endif %} } +{% if native is defined %} + externalNativeBuild { + cmake { + path "CMakeLists.txt" + } + } +{% endif %} + defaultConfig { vectorDrawables.useSupportLibrary = true }
diff --git a/build/android/gradle/cmake.jinja b/build/android/gradle/cmake.jinja new file mode 100644 index 0000000..3b9c19a --- /dev/null +++ b/build/android/gradle/cmake.jinja
@@ -0,0 +1,26 @@ +{# Copyright 2018 The Chromium Authors. All rights reserved. #} +{# Use of this source code is governed by a BSD-style license that can be #} +{# found in the LICENSE file. #} +# Generated by //build/android/generate_gradle.py + +cmake_minimum_required(VERSION 3.4.1) + +project(chrome C CXX) + +{% for name, target in native.targets.iteritems() %} +{% if target.sources is defined %} +add_library("{{ name }}" +{% for path in target.sources %} + {{ path }} +{% endfor %} +) +{% endif %} +{% endfor %} + +{% if native.includes is defined %} +include_directories( +{% for path in native.includes %} + {{ path }} +{% endfor %} +) +{% endif %}
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py index cb05d60..d8dff95 100755 --- a/build/android/gradle/generate_gradle.py +++ b/build/android/gradle/generate_gradle.py
@@ -9,6 +9,7 @@ import codecs import collections import glob +import json import logging import os import re @@ -32,13 +33,15 @@ import find_depot_tools # pylint: disable=import-error _DEFAULT_ANDROID_MANIFEST_PATH = os.path.join( - host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'AndroidManifest.xml') + host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'gradle', + 'AndroidManifest.xml') _FILE_DIR = os.path.dirname(__file__) _SRCJARS_SUBDIR = 'extracted-srcjars' _JNI_LIBS_SUBDIR = 'symlinked-libs' _ARMEABI_SUBDIR = 'armeabi' _RES_SUBDIR = 'extracted-res' _GRADLE_BUILD_FILE = 'build.gradle' +_CMAKE_FILE = 'CMakeLists.txt' # This needs to come first alphabetically among all modules. _MODULE_ALL = '_all' _SRC_INTERNAL = os.path.join( @@ -110,6 +113,17 @@ return dict(l.rstrip().split('=', 1) for l in f if '=' in l) +def _RunGnGen(output_dir, args): + cmd = [ + os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn'), + 'gen', + output_dir, + ] + cmd.extend(args) + logging.info('Running: %r', cmd) + subprocess.check_call(cmd) + + def _RunNinja(output_dir, args, j): cmd = [ os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'ninja'), @@ -596,8 +610,38 @@ 'testing/' in path) -def _GenerateModuleAll(gradle_output_dir, generator, build_vars, - source_properties, jinja_processor): +# Example: //chrome/android:monochrome +def _GetNative(relative_func, target_names): + out_dir = constants.GetOutDirectory() + with open(os.path.join(out_dir, 'project.json'), 'r') as project_file: + projects = json.load(project_file) + project_targets = projects['targets'] + root_dir = projects['build_settings']['root_path'] + targets = {} + includes = set() + def process_paths(paths): + # Ignores leading // + return relative_func( + sorted(os.path.join(root_dir, path[2:]) for path in paths)) + for target_name in target_names: + target = project_targets[target_name] + includes.update(target.get('include_dirs', [])) + sources = target.get('sources', []) + if sources: + # CMake does not like forward slashes or colons for the target name. + filtered_name = target_name.replace('/', '.').replace(':', '-') + targets[filtered_name] = { + 'sources': process_paths(sources), + } + return { + 'targets': targets, + 'includes': process_paths(includes), + } + + +def _GenerateModuleAll( + gradle_output_dir, generator, build_vars, source_properties, + jinja_processor, native_targets): """Returns the data for a pseudo build.gradle of all dirs. See //docs/android_studio.md for more details.""" @@ -623,10 +667,17 @@ 'java_dirs': Relativize(test_java_dirs), 'java_excludes': ['**/*.java'], }] + if native_targets: + variables['native'] = _GetNative( + relative_func=Relativize, target_names=native_targets) data = jinja_processor.Render( _TemplatePath(target_type.split('_')[0]), variables) _WriteFile( os.path.join(gradle_output_dir, _MODULE_ALL, _GRADLE_BUILD_FILE), data) + if native_targets: + cmake_data = jinja_processor.Render(_TemplatePath('cmake'), variables) + _WriteFile( + os.path.join(gradle_output_dir, _MODULE_ALL, _CMAKE_FILE), cmake_data) def _GenerateRootGradle(jinja_processor, channel): @@ -752,6 +803,11 @@ parser.add_argument('-j', default=1000 if os.path.exists(_SRC_INTERNAL) else 50, help='Value for number of parallel jobs for ninja') + parser.add_argument('--native-target', + dest='native_targets', + action='append', + help='GN native targets to generate for. May be ' + 'repeated.') version_group = parser.add_mutually_exclusive_group() version_group.add_argument('--beta', action='store_true', @@ -805,11 +861,15 @@ targets_from_args.update(args.extra_targets) if args.all: - # Run GN gen if necessary (faster than running "gn gen" in the no-op case). - _RunNinja(constants.GetOutDirectory(), ['build.ninja'], args.j) + if args.native_targets: + _RunGnGen(output_dir, ['--ide=json']) + else: + # Faster than running "gn gen" in the no-op case. + _RunNinja(constants.GetOutDirectory(), ['build.ninja'], args.j) # Query ninja for all __build_config targets. targets = _QueryForAllGnTargets(output_dir) else: + assert not args.native_targets, 'Native editing requires --all.' targets = [re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets_from_args] @@ -866,7 +926,7 @@ project_entries.append((_MODULE_ALL, _MODULE_ALL)) _GenerateModuleAll( _gradle_output_dir, generator, build_vars, source_properties, - jinja_processor) + jinja_processor, args.native_targets) _WriteFile(os.path.join(generator.project_dir, _GRADLE_BUILD_FILE), _GenerateRootGradle(jinja_processor, channel))
diff --git a/build/android/gradle/root.jinja b/build/android/gradle/root.jinja index a3c0db9..d5c5e56 100644 --- a/build/android/gradle/root.jinja +++ b/build/android/gradle/root.jinja
@@ -5,14 +5,12 @@ buildscript { repositories { + google() jcenter() - maven { - url 'https://maven.google.com' - } } dependencies { {% if channel == 'canary' %} - classpath "com.android.tools.build:gradle:3.2.0-alpha04" + classpath "com.android.tools.build:gradle:3.2.0-alpha14" {% elif channel == 'beta' %} classpath "com.android.tools.build:gradle:3.1.0-beta4" {% else %}
diff --git a/build/fuchsia/layout_test_proxy/BUILD.gn b/build/fuchsia/layout_test_proxy/BUILD.gn deleted file mode 100644 index 43ed152..0000000 --- a/build/fuchsia/layout_test_proxy/BUILD.gn +++ /dev/null
@@ -1,27 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -assert(is_fuchsia) - -import("//testing/test.gni") - -# Binary used to proxy TCP connections from a Fuchsia process. Potentially SSH -# can be used to forward TCP, but this feature is currently broken on Fuchsia, -# see ZX-1555. layout_test_proxy can be removed once that issue with sshd is -# fixed and layout tests are updated to use SSH. -executable("layout_test_proxy") { - testonly = true - sources = [ - "layout_test_proxy.cc", - ] - deps = [ - "//net", - "//net:test_support", - ] -} - -fuchsia_executable_runner("layout_test_proxy_runner") { - testonly = true - exe_target = ":layout_test_proxy" -}
diff --git a/build/fuchsia/layout_test_proxy/DEPS b/build/fuchsia/layout_test_proxy/DEPS deleted file mode 100644 index b2f6f8e..0000000 --- a/build/fuchsia/layout_test_proxy/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+net", -] \ No newline at end of file
diff --git a/build/fuchsia/layout_test_proxy/layout_test_proxy.cc b/build/fuchsia/layout_test_proxy/layout_test_proxy.cc deleted file mode 100644 index 1d14df99..0000000 --- a/build/fuchsia/layout_test_proxy/layout_test_proxy.cc +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/command_line.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "net/base/ip_endpoint.h" -#include "net/test/tcp_socket_proxy.h" - -const char kPortsSwitch[] = "ports"; -const char kRemoteAddressSwitch[] = "remote-address"; - -int main(int argc, char** argv) { - base::CommandLine::Init(argc, argv); - - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - - if (!command_line->HasSwitch(kPortsSwitch)) { - LOG(ERROR) << "--" << kPortsSwitch << " was not specified."; - return 1; - } - - std::vector<std::string> ports_strings = - base::SplitString(command_line->GetSwitchValueASCII(kPortsSwitch), ",", - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - if (ports_strings.empty()) { - LOG(ERROR) << "At least one port must be specified with --" << kPortsSwitch; - return 1; - } - - std::vector<int> ports; - for (auto& port_string : ports_strings) { - int port; - if (!base::StringToInt(port_string, &port) || port <= 0 || port > 65535) { - LOG(ERROR) << "Invalid value specified for --" << kPortsSwitch << ": " - << port_string; - return 1; - } - ports.push_back(port); - } - - if (!command_line->HasSwitch(kRemoteAddressSwitch)) { - LOG(ERROR) << "--" << kRemoteAddressSwitch << " was not specified."; - return 1; - } - - std::string remote_address_str = - command_line->GetSwitchValueASCII(kRemoteAddressSwitch); - net::IPAddress remote_address; - if (!remote_address.AssignFromIPLiteral(remote_address_str)) { - LOG(ERROR) << "Invalid value specified for --" << kRemoteAddressSwitch - << ": " << remote_address_str; - return 1; - } - - base::MessageLoopForIO message_loop; - - std::vector<std::unique_ptr<net::TcpSocketProxy>> proxies; - - for (int port : ports) { - auto test_server_proxy = - std::make_unique<net::TcpSocketProxy>(message_loop.task_runner()); - if (!test_server_proxy->Initialize(port)) { - LOG(ERROR) << "Can't bind proxy to port " << port; - return 1; - } - LOG(INFO) << "Listening on port " << test_server_proxy->local_port(); - test_server_proxy->Start(net::IPEndPoint(remote_address, port)); - proxies.push_back(std::move(test_server_proxy)); - } - - // Run the message loop indefinitely. - base::RunLoop().Run(); - - return 0; -} \ No newline at end of file
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1 index 5411f6d..c08436a 100644 --- a/build/fuchsia/sdk.sha1 +++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@ -4538a17f3a0240b4fb27b809239f03c6d4184431 \ No newline at end of file +dcd8c3f6050ecca8c59ff841203587e903c115ea \ No newline at end of file
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index 380cedc..e5d6c1f 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -49,15 +49,12 @@ return display_item_list; } -class OopPixelTestBase : public testing::Test { +class OopPixelTest : public testing::Test { public: - virtual bool UseRasterDecoder() = 0; - void SetUp() override { raster_context_provider_ = base::MakeRefCounted<TestInProcessContextProvider>( - /*enable_oop_rasterization=*/true, - /*enable_gles2_interface=*/!UseRasterDecoder()); + /*enable_oop_rasterization=*/true); const int raster_max_texture_size = raster_context_provider_->ContextCapabilities().max_texture_size; oop_image_cache_.reset(new GpuImageDecodeCache( @@ -66,8 +63,7 @@ gles2_context_provider_ = base::MakeRefCounted<TestInProcessContextProvider>( - /*enable_oop_rasterization=*/false, - /*enable_gles2_interface=*/true); + /*enable_oop_rasterization=*/false); const int gles2_max_texture_size = raster_context_provider_->ContextCapabilities().max_texture_size; gpu_image_cache_.reset(new GpuImageDecodeCache( @@ -309,18 +305,10 @@ int color_space_id_ = 0; }; -class OopPixelTest : public OopPixelTestBase, - public ::testing::WithParamInterface<bool> { +class OopImagePixelTest : public OopPixelTest, + public ::testing::WithParamInterface<bool> { public: - bool UseRasterDecoder() final { return GetParam(); } -}; - -class OopImagePixelTest - : public OopPixelTestBase, - public ::testing::WithParamInterface<std::tuple<bool, bool>> { - public: - bool UseRasterDecoder() final { return std::get<0>(GetParam()); } - bool UseTooLargeImage() { return std::get<1>(GetParam()); } + bool UseTooLargeImage() { return GetParam(); } gfx::Size GetImageSize() { const int kMaxSize = 20000; DCHECK_GT(kMaxSize, gles2_context_provider_->GrContext()->maxTextureSize()); @@ -328,7 +316,7 @@ } }; -TEST_P(OopPixelTest, DrawColor) { +TEST_F(OopPixelTest, DrawColor) { gfx::Rect rect(10, 10); auto display_item_list = base::MakeRefCounted<DisplayItemList>(); display_item_list->StartPaint(); @@ -350,7 +338,7 @@ ExpectEquals(actual_gpu, expected, "gpu"); } -TEST_P(OopPixelTest, DrawColorWithTargetColorSpace) { +TEST_F(OopPixelTest, DrawColorWithTargetColorSpace) { gfx::Rect rect(10, 10); auto display_item_list = base::MakeRefCounted<DisplayItemList>(); display_item_list->StartPaint(); @@ -371,7 +359,7 @@ EXPECT_EQ(SkColorSetARGB(255, 38, 15, 221), expected.getColor(0, 0)); } -TEST_P(OopPixelTest, DrawRect) { +TEST_F(OopPixelTest, DrawRect) { gfx::Rect rect(10, 10); auto color_paint = [](int r, int g, int b) { PaintFlags flags; @@ -566,7 +554,7 @@ ExpectEquals(actual, expected); } -TEST_P(OopPixelTest, Preclear) { +TEST_F(OopPixelTest, Preclear) { gfx::Rect rect(10, 10); auto display_item_list = base::MakeRefCounted<DisplayItemList>(); display_item_list->Finalize(); @@ -587,7 +575,7 @@ ExpectEquals(actual, expected); } -TEST_P(OopPixelTest, ClearingOpaqueCorner) { +TEST_F(OopPixelTest, ClearingOpaqueCorner) { // Verify that clears work properly for both the right and bottom sides // of an opaque corner tile. @@ -629,7 +617,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingOpaqueCornerExactEdge) { +TEST_F(OopPixelTest, ClearingOpaqueCornerExactEdge) { // Verify that clears work properly for both the right and bottom sides // of an opaque corner tile whose content rect exactly lines up with // the edge of the resource. @@ -672,7 +660,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingOpaqueCornerPartialRaster) { +TEST_F(OopPixelTest, ClearingOpaqueCornerPartialRaster) { // Verify that clears do nothing on an opaque corner tile whose // partial raster rect doesn't intersect the edge of the content. @@ -709,7 +697,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingOpaqueRightEdge) { +TEST_F(OopPixelTest, ClearingOpaqueRightEdge) { // Verify that a tile that intersects the right edge of content // but not the bottom only clears the right pixels. @@ -748,7 +736,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingOpaqueBottomEdge) { +TEST_F(OopPixelTest, ClearingOpaqueBottomEdge) { // Verify that a tile that intersects the bottom edge of content // but not the right only clears the bottom pixels. @@ -789,7 +777,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingOpaqueInternal) { +TEST_F(OopPixelTest, ClearingOpaqueInternal) { // Verify that an internal opaque tile does no clearing. RasterOptions options; @@ -827,7 +815,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingTransparentCorner) { +TEST_F(OopPixelTest, ClearingTransparentCorner) { RasterOptions options; gfx::Point arbitrary_offset(5, 8); options.resource_size = gfx::Size(10, 10); @@ -863,7 +851,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingTransparentInternalTile) { +TEST_F(OopPixelTest, ClearingTransparentInternalTile) { // Content rect much larger than full raster rect or playback rect. // This should still clear the tile. RasterOptions options; @@ -900,7 +888,7 @@ ExpectEquals(gpu_result, bitmap, "gpu"); } -TEST_P(OopPixelTest, ClearingTransparentCornerPartialRaster) { +TEST_F(OopPixelTest, ClearingTransparentCornerPartialRaster) { RasterOptions options; options.resource_size = gfx::Size(10, 10); gfx::Point arbitrary_offset(30, 12); @@ -943,7 +931,7 @@ // Test various bitmap and playback rects in the raster options, to verify // that in process (RasterSource) and out of process (GLES2Implementation) // raster behave identically. -TEST_P(OopPixelTest, DrawRectBasicRasterOptions) { +TEST_F(OopPixelTest, DrawRectBasicRasterOptions) { PaintFlags flags; flags.setColor(SkColorSetARGB(255, 250, 10, 20)); gfx::Rect draw_rect(3, 1, 8, 9); @@ -976,7 +964,7 @@ } } -TEST_P(OopPixelTest, DrawRectScaleTransformOptions) { +TEST_F(OopPixelTest, DrawRectScaleTransformOptions) { PaintFlags flags; // Use powers of two here to make floating point blending consistent. flags.setColor(SkColorSetARGB(128, 64, 128, 32)); @@ -1007,7 +995,7 @@ ExpectEquals(actual, expected); } -TEST_P(OopPixelTest, DrawRectQueryMiddleOfDisplayList) { +TEST_F(OopPixelTest, DrawRectQueryMiddleOfDisplayList) { auto display_item_list = base::MakeRefCounted<DisplayItemList>(); std::vector<SkColor> colors = { SkColorSetARGB(255, 0, 0, 255), SkColorSetARGB(255, 0, 255, 0), @@ -1040,7 +1028,7 @@ ExpectEquals(actual, expected); } -TEST_P(OopPixelTest, DrawRectColorSpace) { +TEST_F(OopPixelTest, DrawRectColorSpace) { RasterOptions options; options.resource_size = gfx::Size(100, 100); options.content_size = options.resource_size; @@ -1085,7 +1073,7 @@ return builder.TakeTextBlob(); } -TEST_P(OopPixelTest, DrawTextBlob) { +TEST_F(OopPixelTest, DrawTextBlob) { RasterOptions options; options.resource_size = gfx::Size(100, 100); options.content_size = options.resource_size; @@ -1107,12 +1095,7 @@ ExpectEquals(actual, expected); } -INSTANTIATE_TEST_CASE_P(P, OopPixelTest, ::testing::Bool()); - -INSTANTIATE_TEST_CASE_P(P, - OopImagePixelTest, - ::testing::Combine(::testing::Bool(), - ::testing::Bool())); +INSTANTIATE_TEST_CASE_P(P, OopImagePixelTest, ::testing::Bool()); } // namespace } // namespace cc
diff --git a/cc/paint/transfer_cache_unittest.cc b/cc/paint/transfer_cache_unittest.cc index 8685b37..d8fb589 100644 --- a/cc/paint/transfer_cache_unittest.cc +++ b/cc/paint/transfer_cache_unittest.cc
@@ -27,12 +27,10 @@ namespace cc { namespace { -class TransferCacheTest : public testing::TestWithParam<bool> { +class TransferCacheTest : public testing::Test { public: TransferCacheTest() : test_client_entry_(std::vector<uint8_t>(100)) {} - bool UseRasterDecoder() { return GetParam(); } - void SetUp() override { gpu::ContextCreationAttribs attribs; attribs.alpha_size = -1; @@ -45,7 +43,7 @@ // Enable OOP rasterization. attribs.enable_oop_rasterization = true; attribs.enable_raster_interface = true; - attribs.enable_gles2_interface = !UseRasterDecoder(); + attribs.enable_gles2_interface = false; context_ = std::make_unique<gpu::RasterInProcessContext>(); auto result = context_->Initialize( @@ -91,9 +89,7 @@ ClientRawMemoryTransferCacheEntry test_client_entry_; }; -INSTANTIATE_TEST_CASE_P(Service, TransferCacheTest, ::testing::Bool()); - -TEST_P(TransferCacheTest, Basic) { +TEST_F(TransferCacheTest, Basic) { auto* service_cache = ServiceTransferCache(); auto* context_support = ContextSupport(); @@ -121,7 +117,7 @@ EXPECT_EQ(nullptr, service_cache->GetEntry(entry.Type(), entry.Id())); } -TEST_P(TransferCacheTest, Eviction) { +TEST_F(TransferCacheTest, Eviction) { auto* service_cache = ServiceTransferCache(); auto* context_support = ContextSupport(); @@ -147,7 +143,7 @@ entry.UnsafeType(), entry.Id())); } -TEST_P(TransferCacheTest, RawMemoryTransfer) { +TEST_F(TransferCacheTest, RawMemoryTransfer) { auto* service_cache = ServiceTransferCache(); // Create an entry with some initialized data. @@ -171,7 +167,7 @@ EXPECT_EQ(data, service_data); } -TEST_P(TransferCacheTest, ImageMemoryTransfer) { +TEST_F(TransferCacheTest, ImageMemoryTransfer) { // TODO(ericrk): This test doesn't work on Android. crbug.com/777628 #if defined(OS_ANDROID) return;
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc index 3b0941a..e5340ff6 100644 --- a/cc/raster/raster_buffer_provider_perftest.cc +++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -87,7 +87,7 @@ capabilities_.sync_query = true; raster_context_ = std::make_unique<gpu::raster::RasterImplementationGLES>( - context_gl_.get(), &support_, nullptr, capabilities_); + context_gl_.get(), nullptr, capabilities_); } // viz::ContextProvider implementation.
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 5f94532..1730005 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -46,11 +46,9 @@ scoped_refptr<TestInProcessContextProvider> worker_context_provider; if (test_type_ == PIXEL_TEST_GL) { compositor_context_provider = new TestInProcessContextProvider( - /*enable_oop_rasterization=*/false, - /*supports_gles2_interface=*/true); + /*enable_oop_rasterization=*/false); worker_context_provider = new TestInProcessContextProvider( - /*enable_oop_rasterization=*/false, - /*supports_gles2_interface=*/true); + /*enable_oop_rasterization=*/false); } static constexpr bool disable_display_vsync = false; bool synchronous_composite = @@ -80,8 +78,7 @@ // compositor. auto display_context_provider = base::MakeRefCounted<TestInProcessContextProvider>( - /*enable_oop_rasterization=*/false, - /*support_gles2_interface=*/true); + /*enable_oop_rasterization=*/false); display_context_provider->BindToCurrentThread(); bool flipped_output_surface = false;
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index 6dd3be2..dcdfb848 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc
@@ -194,8 +194,7 @@ enable_pixel_output_ = std::make_unique<gl::DisableNullDrawGLBindings>(); auto context_provider = base::MakeRefCounted<TestInProcessContextProvider>( - /*enable_oop_rasterization=*/false, - /*support_gles2_interface=*/true); + /*enable_oop_rasterization=*/false); output_surface_ = std::make_unique<PixelTestOutputSurface>( std::move(context_provider), flipped_output_surface); output_surface_->BindToClient(output_surface_client_.get()); @@ -205,8 +204,7 @@ output_surface_->context_provider(), shared_bitmap_manager_.get()); child_context_provider_ = base::MakeRefCounted<TestInProcessContextProvider>( - /*enable_oop_rasterization=*/false, - /*support_gles2_interface=*/true); + /*enable_oop_rasterization=*/false); child_context_provider_->BindToCurrentThread(); child_resource_provider_ = std::make_unique<LayerTreeResourceProvider>( child_context_provider_.get(), true, settings_.resource_settings);
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc index f4b8793..c5dfb836d 100644 --- a/cc/test/test_in_process_context_provider.cc +++ b/cc/test/test_in_process_context_provider.cc
@@ -25,7 +25,6 @@ #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" #include "ui/gfx/native_widget_types.h" - namespace cc { namespace { @@ -64,16 +63,13 @@ } TestInProcessContextProvider::TestInProcessContextProvider( - bool enable_oop_rasterization, - bool support_gles2_interface) { + bool enable_oop_rasterization) { if (enable_oop_rasterization) { gpu::ContextCreationAttribs attribs; attribs.bind_generates_resource = false; attribs.enable_oop_rasterization = true; attribs.enable_raster_interface = true; - // TODO(crbug.com/834313): Remove this once we start tearing down OOP-R in - // GLES2Decoder. - attribs.enable_gles2_interface = support_gles2_interface; + attribs.enable_gles2_interface = false; raster_context_.reset(new gpu::RasterInProcessContext); auto result = raster_context_->Initialize( @@ -96,7 +92,6 @@ raster_implementation_gles2_ = std::make_unique<gpu::raster::RasterImplementationGLES>( gles2_context_->GetImplementation(), - gles2_context_->GetImplementation(), gles2_context_->GetImplementation()->command_buffer(), gles2_context_->GetCapabilities()); }
diff --git a/cc/test/test_in_process_context_provider.h b/cc/test/test_in_process_context_provider.h index 605a2b07..0daece7 100644 --- a/cc/test/test_in_process_context_provider.h +++ b/cc/test/test_in_process_context_provider.h
@@ -37,10 +37,7 @@ public viz::ContextProvider, public viz::RasterContextProvider { public: - // TODO(backer): Once we only support OOP-R on Raster{Implementation,Decoder}, - // fold these two options into one. - TestInProcessContextProvider(bool enable_oop_rasterization, - bool support_gles2_interface); + explicit TestInProcessContextProvider(bool enable_oop_rasterization); // viz::ContextProvider / viz::RasterContextProvider implementation. void AddRef() const override;
diff --git a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc index f4f4735..b251df56 100644 --- a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc +++ b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -150,8 +150,7 @@ background->AddChild(layer); scoped_refptr<TestInProcessContextProvider> context( - new TestInProcessContextProvider(/*enable_oop_rasterization=*/false, - /*support_gles2_interface=*/true)); + new TestInProcessContextProvider(/*enable_oop_rasterization=*/false)); context->BindToCurrentThread(); int max_texture_size = 0; context->ContextGL()->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 47204ff..1482c16a 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -6326,10 +6326,6 @@ : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {} void BeginTest() override { - // Test terminates when a main frame is no longer expected so request that - // this message is actually sent. - layer_tree_host()->RequestBeginMainFrameNotExpected(true); - PostSetNeedsCommitToMainThread(); } @@ -6344,27 +6340,20 @@ did_finish_impl_frame_count_++; EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_); - // Request a number of commits to cause multiple impl frames. We expect to - // get one more impl frames than the number of commits requested because - // after a commit it takes one frame to become idle. - if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1) - PostSetNeedsCommitToMainThread(); + // Trigger a new impl frame until we are done testing. + if (did_finish_impl_frame_count_ < kExpectedNumImplFrames) + PostSetNeedsRedrawToMainThread(); + else + EndTest(); } - void BeginMainFrameNotExpectedSoon() override { EndTest(); } - void AfterTest() override { EXPECT_GT(will_begin_impl_frame_count_, 0); EXPECT_GT(did_finish_impl_frame_count_, 0); EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_); - // TODO(mithro): Figure out why the multithread version of this test - // sometimes has one more frame then expected. Possibly related to - // http://crbug.com/443185 - if (!HasImplThread()) { - EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames); - EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames); - } + EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames); + EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames); } private:
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc index edc62a8..fcc9524 100644 --- a/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -1049,63 +1049,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestCreatesTexture); -class LayerTreeHostCopyRequestTestProvideTexture - : public LayerTreeHostCopyRequestTestCountTextures { - protected: - void BeginTest() override { - external_context_provider_ = viz::TestContextProvider::Create(); - EXPECT_EQ(external_context_provider_->BindToCurrentThread(), - gpu::ContextResult::kSuccess); - LayerTreeHostCopyRequestTestCountTextures::BeginTest(); - } - - void CopyOutputCallback(std::unique_ptr<viz::CopyOutputResult> result) { - EXPECT_FALSE(result->IsEmpty()); - EXPECT_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE); - ASSERT_NE(nullptr, result->GetTextureResult()); - - std::unique_ptr<viz::SingleReleaseCallback> release_callback = - result->TakeTextureOwnership(); - ASSERT_TRUE(release_callback); - release_callback->Run(gpu::SyncToken(), false); - } - - void RequestCopy(Layer* layer) override { - // Request a copy to a provided texture. This should not create a new - // texture. - std::unique_ptr<viz::CopyOutputRequest> request = - std::make_unique<viz::CopyOutputRequest>( - viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE, - base::BindOnce( - &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback, - base::Unretained(this))); - - gpu::gles2::GLES2Interface* gl = external_context_provider_->ContextGL(); - gpu::Mailbox mailbox; - gl->GenMailboxCHROMIUM(mailbox.name); - - gl->GenSyncTokenCHROMIUM(sync_token_.GetData()); - - request->SetMailbox(mailbox, sync_token_); - EXPECT_TRUE(request->has_mailbox()); - - copy_layer_->RequestCopyOfOutput(std::move(request)); - } - - void AfterTest() override { - // Expect the compositor to have waited for the sync point provided with the - // mailbox. - EXPECT_EQ(sync_token_, waited_sync_token_after_readback_); - // Except the copy to have *not* made another texture. - EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_); - } - - scoped_refptr<viz::TestContextProvider> external_context_provider_; - gpu::SyncToken sync_token_; -}; - -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestProvideTexture); - class LayerTreeHostCopyRequestTestDestroyBeforeCopy : public LayerTreeHostCopyRequestTest { protected:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index bb8add1c..3ee6cbc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -162,13 +162,7 @@ public static final String CCT_POST_MESSAGE_API = "CCTPostMessageAPI"; public static final String CCT_REDIRECT_PRECONNECT = "CCTRedirectPreconnect"; public static final String CHROME_DUPLEX = "ChromeDuplex"; - // TODO(mdjones): Remove CHROME_HOME completely. - public static final String CHROME_HOME = "ChromeHome"; - public static final String CHROME_HOME_DROP_ALL_BUT_FIRST_THUMBNAIL = - "ChromeHomeDropAllButFirstThumbnail"; - public static final String CHROME_HOME_PERSISTENT_IPH = "ChromeHomePersistentIph"; - public static final String CHROME_HOME_PULL_TO_REFRESH_IPH_AT_TOP = - "ChromeHomePullToRefreshIphAtTop"; + // TODO(mdjones): Remove CHROME_HOME_SWIPE_VELOCITY_FEATURE or rename. public static final String CHROME_HOME_SWIPE_VELOCITY_FEATURE = "ChromeHomeSwipeLogicVelocity"; public static final String CHROME_MEMEX = "ChromeMemex"; public static final String CHROME_MODERN_DESIGN = "ChromeModernDesign";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index bcd442a..0c8702f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -9,6 +9,7 @@ import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.compositor.TitleCache; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.components.VirtualView; @@ -414,6 +415,7 @@ if (mScrollDirection == ScrollDirection.UNKNOWN) return; if (mOverviewLayout != null && mScrollDirection == ScrollDirection.DOWN) { + RecordUserAction.record("MobileToolbarSwipeOpenStackView"); startShowing(mOverviewLayout, true); } else if (mToolbarSwipeLayout != null && (mScrollDirection == ScrollDirection.LEFT
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java index e2c3edc..fd26014 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayout.java
@@ -6,6 +6,7 @@ import android.content.Context; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost; import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -138,4 +139,17 @@ if (mStacks.size() == 2 && !mStacks.get(1).isDisplayable()) return SWIPE_MODE_SEND_TO_STACK; return super.computeInputMode(time, x, y, dx, dy); } + + @Override + public void setActiveStackState(int stackIndex) { + if (stackIndex != getTabStackIndex(Tab.INVALID_TAB_ID)) { + if (stackIndex == NORMAL_STACK_INDEX) { + RecordUserAction.record("MobileStackViewNormalMode"); + } else { + RecordUserAction.record("MobileStackViewIncognitoMode"); + } + } + + super.setActiveStackState(stackIndex); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java index aa473773..c90c03d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java
@@ -28,6 +28,9 @@ import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; +import org.chromium.content_public.browser.GestureListenerManager; +import org.chromium.content_public.browser.GestureStateListener; +import org.chromium.content_public.browser.RenderCoordinates; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.widget.ViewRectProvider; @@ -41,6 +44,9 @@ */ class ContextualSuggestionsMediator implements EnabledStateMonitor.Observer, FetchHelper.Delegate, ListMenuButton.Delegate { + private static final float INVALID_PERCENTAGE = -1f; + private static boolean sOverrideBrowserControlsHiddenForTesting; + private final Profile mProfile; private final TabModelSelector mTabModelSelector; private final ContextualSuggestionsCoordinator mCoordinator; @@ -48,6 +54,7 @@ private final ChromeFullscreenManager mFullscreenManager; private final View mIphParentView; private final EnabledStateMonitor mEnabledStateMonitor; + private final GestureStateListener mGestureStateListener; private final Handler mHandler = new Handler(); private @Nullable ContextualSuggestionsSource mSuggestionsSource; @@ -55,13 +62,16 @@ private @Nullable String mCurrentRequestUrl; private @Nullable BottomSheetObserver mSheetObserver; private @Nullable TextBubble mHelpBubble; + private @Nullable WebContents mCurrentWebContents; private boolean mDidSuggestionsShowForTab; private boolean mHasRecordedPeekEventForTab; + private boolean mHasReachedTargetScrollPercentage; private boolean mHasPeekDelayPassed; private boolean mUpdateRemainingCountOnNextPeek; private float mRemainingPeekCount; + private float mTargetScrollPercentage = INVALID_PERCENTAGE; /** Whether the content sheet is observed to be opened for the first time. */ private boolean mHasSheetBeenOpened; @@ -92,6 +102,25 @@ ContextualSuggestionsDependencyFactory.getInstance().createEnabledStateMonitor( this); + mGestureStateListener = new GestureStateListener() { + @Override + public void onScrollOffsetOrExtentChanged(int scrollOffsetY, int scrollExtentY) { + if (mHasReachedTargetScrollPercentage) return; + + final RenderCoordinates coordinates = + RenderCoordinates.fromWebContents(mCurrentWebContents); + // Use rounded percentage to avoid the approximated percentage not reaching 100%. + float percentage = Math.round((float) coordinates.getScrollYPixInt() + / coordinates.getMaxVerticalScrollPixInt() * 100f) / 100f; + + if (Float.compare(mTargetScrollPercentage, INVALID_PERCENTAGE) != 0 + && Float.compare(percentage, mTargetScrollPercentage) >= 0) { + mHasReachedTargetScrollPercentage = true; + maybeShowContentInSheet(); + } + } + }; + fullscreenManager.addListener(new FullscreenListener() { @Override public void onContentOffsetChanged(float offset) {} @@ -99,13 +128,7 @@ @Override public void onControlsOffsetChanged( float topOffset, float bottomOffset, boolean needsAnimate) { - // When the controls scroll completely off-screen, the suggestions are "shown" but - // remain hidden since their offset from the bottom of the screen is determined by - // the top controls. - if (!mDidSuggestionsShowForTab && mModel.hasSuggestions() - && areBrowserControlsHidden() && mSuggestionsSource != null) { - showContentInSheet(); - } + maybeShowContentInSheet(); } @Override @@ -131,6 +154,12 @@ } if (mHelpBubble != null) mHelpBubble.dismiss(); + + if (mCurrentWebContents != null) { + GestureListenerManager.fromWebContents(mCurrentWebContents) + .removeListener(mGestureStateListener); + mCurrentWebContents = null; + } } /** Called when accessibility mode changes. */ @@ -142,8 +171,9 @@ * @return Whether the browser controls are currently completely hidden. */ private boolean areBrowserControlsHidden() { - return MathUtils.areFloatsEqual(-mFullscreenManager.getTopControlOffset(), - mFullscreenManager.getTopControlsHeight()); + return sOverrideBrowserControlsHiddenForTesting + || MathUtils.areFloatsEqual(-mFullscreenManager.getTopControlOffset(), + mFullscreenManager.getTopControlsHeight()); } @Override @@ -184,7 +214,11 @@ reportEvent(ContextualSuggestionsEvent.FETCH_REQUESTED); mCurrentRequestUrl = url; mSuggestionsSource.fetchSuggestions(url, (suggestionsResult) -> { - if (mSuggestionsSource == null) return; + if (mTabModelSelector.getCurrentTab() == null + || mTabModelSelector.getCurrentTab().getWebContents() == null + || mSuggestionsSource == null) { + return; + } assert mFetchHelper != null; // Avoiding double fetches causing suggestions for incorrect context. @@ -194,21 +228,31 @@ PeekConditions peekConditions = suggestionsResult.getPeekConditions(); mRemainingPeekCount = peekConditions.getMaximumNumberOfPeeks(); + mTargetScrollPercentage = peekConditions.getPageScrollPercentage(); long remainingDelay = mFetchHelper.getFetchTimeBaselineMillis(mTabModelSelector.getCurrentTab()) + Math.round(peekConditions.getMinimumSecondsOnPage() * 1000) - SystemClock.uptimeMillis(); - Runnable runnable = () -> mHasPeekDelayPassed = true; + + assert mCurrentWebContents == null + : "The current web contents should be cleared before suggestions are requested."; + mCurrentWebContents = mTabModelSelector.getCurrentTab().getWebContents(); + GestureListenerManager.fromWebContents(mCurrentWebContents) + .addListener(mGestureStateListener); if (remainingDelay <= 0) { // Don't postDelayed if the minimum delay has passed so that the suggestions may - // be shown through the following #showContentInSheet() call. - runnable.run(); + // be shown through the following call to show contents in the bottom sheet. + mHasPeekDelayPassed = true; } else { - // Once delay expires, the bottom sheet can be peeked the next time the browser - // controls are fully hidden and reshown. Note that this triggering is handled by + // Once delay expires, the bottom sheet can be peeked if the browser controls are + // already hidden, or the next time the browser controls are fully hidden and + // reshown. Note that this triggering on the latter case is handled by // FullscreenListener#onControlsOffsetChanged() in this class. - mHandler.postDelayed(runnable, remainingDelay); + mHandler.postDelayed(() -> { + mHasPeekDelayPassed = true; + maybeShowContentInSheet(); + }, remainingDelay); } if (clusters.size() > 0 && clusters.get(0).getSuggestions().size() > 0) { @@ -216,7 +260,7 @@ generateClusterList(clusters), suggestionsResult.getPeekText()); // If the controls are already off-screen, show the suggestions immediately so they // are available on reverse scroll. - if (areBrowserControlsHidden()) showContentInSheet(); + maybeShowContentInSheet(); } }); } @@ -261,12 +305,23 @@ */ private void clearSuggestions() { // TODO(twellington): Does this signal need to go back to FetchHelper? + + // Call remove suggestions before clearing model state so that views don't respond to model + // changes while suggestions are hiding. See https://crbug.com/840579. + if (mSheetObserver != null) { + mCoordinator.removeBottomSheetObserver(mSheetObserver); + mSheetObserver = null; + } + mCoordinator.removeSuggestions(); + mDidSuggestionsShowForTab = false; mHasRecordedPeekEventForTab = false; mHasSheetBeenOpened = false; mHandler.removeCallbacksAndMessages(null); + mHasReachedTargetScrollPercentage = false; mHasPeekDelayPassed = false; mUpdateRemainingCountOnNextPeek = false; + mTargetScrollPercentage = INVALID_PERCENTAGE; mRemainingPeekCount = 0f; mModel.setClusterList(new ClusterList(Collections.emptyList())); mModel.setCloseButtonOnClickListener(null); @@ -275,16 +330,17 @@ mModel.setMenuButtonDelegate(null); mModel.setDefaultToolbarClickListener(null); mModel.setTitle(null); - mCoordinator.removeSuggestions(); mCurrentRequestUrl = ""; if (mSuggestionsSource != null) mSuggestionsSource.clearState(); - if (mSheetObserver != null) { - mCoordinator.removeBottomSheetObserver(mSheetObserver); - } - if (mHelpBubble != null) mHelpBubble.dismiss(); + + if (mCurrentWebContents != null) { + GestureListenerManager.fromWebContents(mCurrentWebContents) + .removeListener(mGestureStateListener); + mCurrentWebContents = null; + } } private void preloadContentInSheet(ClusterList clusters, String title) { @@ -309,8 +365,15 @@ mCoordinator.preloadContentInSheet(); } - private void showContentInSheet() { - if (!mHasPeekDelayPassed || !hasRemainingPeek()) return; + private void maybeShowContentInSheet() { + // When the controls scroll completely off-screen, the suggestions are "shown" but + // remain hidden since their offset from the bottom of the screen is determined by + // the top controls. + if (mDidSuggestionsShowForTab || !mModel.hasSuggestions() || mSuggestionsSource == null + || !areBrowserControlsHidden() || !mHasReachedTargetScrollPercentage + || !mHasPeekDelayPassed || !hasRemainingPeek()) { + return; + } mDidSuggestionsShowForTab = true; mUpdateRemainingCountOnNextPeek = true; @@ -426,13 +489,24 @@ } @VisibleForTesting - void showContentInSheetForTesting(boolean disablePeekDelay) { + void showContentInSheetForTesting(boolean disableScrollPercentage, boolean disablePeekDelay) { + if (disableScrollPercentage) mHasReachedTargetScrollPercentage = true; if (disablePeekDelay) mHasPeekDelayPassed = true; - showContentInSheet(); + maybeShowContentInSheet(); } @VisibleForTesting TextBubble getHelpBubbleForTesting() { return mHelpBubble; } + + @VisibleForTesting + void setTargetScrollPercentageForTesting(float percentage) { + mTargetScrollPercentage = percentage; + } + + @VisibleForTesting + static void setOverrideBrowserControlsHiddenForTesting(boolean override) { + sOverrideBrowserControlsHiddenForTesting = override; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java index 9819928..924cc1b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java
@@ -169,27 +169,35 @@ /** * Show the specified dialog. If another dialog is currently showing, the specified dialog will - * be added to the pending dialog list. + * be added to the end of the pending dialog list of the specified type. * @param dialog The dialog to be shown or added to pending list. * @param dialogType The type of the dialog to be shown. */ public void showDialog(ModalDialogView dialog, @ModalDialogType int dialogType) { + showDialog(dialog, dialogType, false); + } + + /** + * Show the specified dialog. If another dialog is currently showing, the specified dialog will + * be added to the pending dialog list. If showNext is set to true, the dialog will be added + * to the top of the pending list of its type, otherwise it will be added to the end. + * @param dialog The dialog to be shown or added to pending list. + * @param dialogType The type of the dialog to be shown. + * @param showAsNext Whether the specified dialog should be set highest priority of its type. + */ + public void showDialog( + ModalDialogView dialog, @ModalDialogType int dialogType, boolean showAsNext) { List<ModalDialogView> dialogs = mPendingDialogs.get(dialogType); if (dialogs == null) mPendingDialogs.put(dialogType, dialogs = new ArrayList<>()); - if (mSuspendedTypes.contains(dialogType)) { - dialogs.add(dialog); + // Put the new dialog in pending list if the dialog type is suspended or the current dialog + // is of higher priority. + if (mSuspendedTypes.contains(dialogType) || (isShowing() && mCurrentType <= dialogType)) { + dialogs.add(showAsNext ? 0 : dialogs.size(), dialog); return; } - if (isShowing()) { - // Put the new dialog in pending list if the current dialog is of higher priority. - if (mCurrentType <= dialogType) { - dialogs.add(dialog); - return; - } - suspendCurrentDialog(); - } + if (isShowing()) suspendCurrentDialog(); assert !isShowing(); dialog.prepareBeforeShow();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java index f0d824ee..b4a1a6d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java
@@ -531,9 +531,7 @@ Resources res = context.getResources(); // Record whether it's known whether notifications can be shown to the user at all. - RecordHistogram.recordEnumeratedHistogram("Notifications.AppNotificationStatus", - NotificationSystemStatusUtil.determineAppNotificationStatus(context), - NotificationSystemStatusUtil.APP_NOTIFICATIONS_STATUS_BOUNDARY); + NotificationSystemStatusUtil.recordAppNotificationStatusHistogram(context); PendingIntent clickIntent = makePendingIntent(context, NotificationConstants.ACTION_CLICK_NOTIFICATION, notificationId, origin, scopeUrl,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java index 2e7189b..04670ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java
@@ -5,12 +5,11 @@ package org.chromium.chrome.browser.notifications; import android.annotation.TargetApi; -import android.app.AppOpsManager; import android.content.Context; import android.os.Build; +import android.support.v4.app.NotificationManagerCompat; -import java.lang.reflect.Field; -import java.lang.reflect.Method; +import org.chromium.base.metrics.RecordHistogram; /** * Utility for determining whether the user has disabled all of Chrome's notifications using the @@ -23,65 +22,37 @@ */ public class NotificationSystemStatusUtil { /** Status codes returned by {@link determineAppNotificationsEnabled}. **/ - public static final int APP_NOTIFICATIONS_STATUS_UNDETERMINABLE = 0; - public static final int APP_NOTIFICATIONS_STATUS_EXCEPTION = 1; - public static final int APP_NOTIFICATIONS_STATUS_ENABLED = 2; - public static final int APP_NOTIFICATIONS_STATUS_DISABLED = 3; + private static final int APP_NOTIFICATIONS_STATUS_UNDETERMINABLE = 0; + private static final int APP_NOTIFICATIONS_STATUS_ENABLED = 2; + private static final int APP_NOTIFICATIONS_STATUS_DISABLED = 3; /** Must be set to the maximum value of the above values, plus one. **/ - public static final int APP_NOTIFICATIONS_STATUS_BOUNDARY = 4; - - /** Method name on the AppOpsManager class to check for a setting's value. **/ - private static final String CHECK_OP_NO_THROW = "checkOpNoThrow"; - - /** The POST_NOTIFICATION operation understood by the AppOpsManager. **/ - private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"; + private static final int APP_NOTIFICATIONS_STATUS_BOUNDARY = 4; /** - * Determines whether notifications are enabled for the app represented by |context|. + * Determines whether notifications are enabled for the app represented by |context| and updates + * the histogram "Notifications.AppNotiicationStatus". * Notifications may be disabled because either the user, or a management tool, has explicitly * disallowed the Chrome App to display notifications. * - * This check requires Android KitKat or later. Earlier versions will return an INDETERMINABLE - * status. When an exception occurs, an EXCEPTION status will be returned instead. + * This check requires Android KitKat or later. Earlier versions will log an INDETERMINABLE + * status. * * @param context The context to check of whether it can show notifications. - * @return One of the APP_NOTIFICATION_STATUS_* constants defined in this class. */ @TargetApi(Build.VERSION_CODES.KITKAT) - static int determineAppNotificationStatus(Context context) { + static void recordAppNotificationStatusHistogram(Context context) { + int histogramValue; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - return APP_NOTIFICATIONS_STATUS_UNDETERMINABLE; + histogramValue = APP_NOTIFICATIONS_STATUS_UNDETERMINABLE; + } else { + NotificationManagerCompat manager = NotificationManagerCompat.from(context); + histogramValue = manager.areNotificationsEnabled() ? APP_NOTIFICATIONS_STATUS_ENABLED + : APP_NOTIFICATIONS_STATUS_DISABLED; } - final String packageName = context.getPackageName(); - final int uid = context.getApplicationInfo().uid; - final AppOpsManager appOpsManager = - (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); - - try { - Class appOpsManagerClass = Class.forName(AppOpsManager.class.getName()); - - @SuppressWarnings("unchecked") - final Method checkOpNoThrowMethod = - appOpsManagerClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, - String.class); - - final Field opPostNotificationField = - appOpsManagerClass.getDeclaredField(OP_POST_NOTIFICATION); - - int value = (int) opPostNotificationField.get(Integer.class); - int status = (int) checkOpNoThrowMethod.invoke(appOpsManager, value, uid, packageName); - - return status == AppOpsManager.MODE_ALLOWED - ? APP_NOTIFICATIONS_STATUS_ENABLED : APP_NOTIFICATIONS_STATUS_DISABLED; - - } catch (RuntimeException e) { - } catch (Exception e) { - // Silently fail here, since this is just collecting statistics. The histogram includes - // a count for thrown exceptions, if that proves to be significant we can revisit. - } - - return APP_NOTIFICATIONS_STATUS_EXCEPTION; + RecordHistogram.recordEnumeratedHistogram("Notifications.AppNotificationStatus", + histogramValue, APP_NOTIFICATIONS_STATUS_BOUNDARY); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/BitmapHttpRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/BitmapHttpRequest.java deleted file mode 100644 index 6ed1ad3..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/BitmapHttpRequest.java +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -package org.chromium.chrome.browser.physicalweb; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; - -/** - * A class that represents an HTTP request for an image. - * The response is a Bitmap. - */ -class BitmapHttpRequest extends HttpRequest<Bitmap> { - /** - * Construct a bitmap HTTP request. - * @param url The url to make this HTTP request to. - * @param userAgent The string to set as the User-Agent request header. - * @param acceptLanguage The string to set as the Accept-Language request header. - * @param callback The callback run when the HTTP response is received. - * The callback can be called with a null bitmap if the image - * couldn't be decoded. - * @throws MalformedURLException on invalid url - */ - public BitmapHttpRequest(String url, String userAgent, String acceptLanguage, - RequestCallback callback) - throws MalformedURLException { - super(url, userAgent, acceptLanguage, callback); - } - - /** - * The callback that gets run after the request is made. - */ - public interface RequestCallback extends HttpRequest.HttpRequestCallback<Bitmap> {} - - /** - * Helper method to make an HTTP request. - * @param urlConnection The HTTP connection. - */ - @Override - public void writeToUrlConnection(HttpURLConnection urlConnection) throws IOException {} - - /** - * Helper method to read an HTTP response. - * @param is The InputStream. - * @return The decoded image. - */ - @Override - protected Bitmap readInputStream(InputStream is) throws IOException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len; - while ((len = is.read(buffer)) != -1) { - os.write(buffer, 0, len); - } - byte[] bitmapData = os.toByteArray(); - return BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length); - } -} -
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/HttpRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/HttpRequest.java deleted file mode 100644 index c306a70..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/HttpRequest.java +++ /dev/null
@@ -1,133 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -package org.chromium.chrome.browser.physicalweb; - -import org.chromium.base.ThreadUtils; - -import org.chromium.chrome.browser.UrlConstants; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * This class represents an HTTP request. - * This is to be used as a base class for more specific request classes. - * @param <T> The type representing the request payload. - */ -abstract class HttpRequest<T> implements Runnable { - // HTTP request header field names - private static final String USER_AGENT_HEADER_NAME = "User-Agent"; - private static final String ACCEPT_LANGUAGE_HEADER_NAME = "Accept-Language"; - - private final URL mUrl; - private final String mUserAgent; - private final String mAcceptLanguage; - private final HttpRequestCallback<T> mCallback; - - /** - * Construct a Request object. - * @param url The URL to make an HTTP request to. - * @param userAgent The string to set as the User-Agent request header. - * @param acceptLanguage The string to set as the Accept-Language request header. - * @param callback The callback run when the HTTP response is received. - * The callback will be run on the main thread. - * @throws MalformedURLException on invalid url - */ - public HttpRequest(String url, String userAgent, String acceptLanguage, - HttpRequestCallback<T> callback) - throws MalformedURLException { - mUrl = new URL(url); - mUserAgent = userAgent; - mAcceptLanguage = acceptLanguage; - if (!mUrl.getProtocol().equals(UrlConstants.HTTP_SCHEME) - && !mUrl.getProtocol().equals(UrlConstants.HTTPS_SCHEME)) { - throw new MalformedURLException("This is not a http or https URL: " + url); - } - mCallback = callback; - } - - /** - * The callback that gets run after the request is made. - */ - public interface HttpRequestCallback<T> { - /** - * The callback run on a valid response. - * @param result The result object. - */ - void onResponse(T result); - - /** - * The callback run on an Exception. - * @param httpResponseCode The HTTP response code. This will be 0 if no - * response was received. - * @param e The encountered Exception. - */ - void onError(int httpResponseCode, Exception e); - } - - /** - * Make the HTTP request and parse the HTTP response. - */ - @Override - public void run() { - // Setup some values - HttpURLConnection urlConnection = null; - T result = null; - InputStream inputStream = null; - int responseCode = 0; - IOException ioException = null; - - // Make the request - try { - urlConnection = (HttpURLConnection) mUrl.openConnection(); - urlConnection.setRequestProperty(USER_AGENT_HEADER_NAME, mUserAgent); - urlConnection.setRequestProperty(ACCEPT_LANGUAGE_HEADER_NAME, mAcceptLanguage); - writeToUrlConnection(urlConnection); - responseCode = urlConnection.getResponseCode(); - inputStream = new BufferedInputStream(urlConnection.getInputStream()); - result = readInputStream(inputStream); - } catch (IOException e) { - ioException = e; - } finally { - if (urlConnection != null) { - urlConnection.disconnect(); - } - } - - // Invoke the callback on the main thread. - final Exception finalException = ioException; - final T finalResult = result; - final int finalResponseCode = responseCode; - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - if (finalException == null) { - mCallback.onResponse(finalResult); - } else { - mCallback.onError(finalResponseCode, finalException); - } - } - }); - } - - /** - * Helper method to make an HTTP request. - * @param urlConnection The HTTP connection. - * @throws IOException on error - */ - protected abstract void writeToUrlConnection(HttpURLConnection urlConnection) - throws IOException; - - /** - * Helper method to read an HTTP response. - * @param is The InputStream. - * @return An object representing the HTTP response. - * @throws IOException on error - */ - protected abstract T readInputStream(InputStream is) throws IOException; -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/JsonObjectHttpRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/JsonObjectHttpRequest.java deleted file mode 100644 index 57997fa..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/JsonObjectHttpRequest.java +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -package org.chromium.chrome.browser.physicalweb; - -import org.json.JSONException; -import org.json.JSONObject; - -import org.chromium.base.ApiCompatibilityUtils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; - -/** - * A class that represents an HTTP request for a JSON object. - * Both the request payload and the response are JSON objects. - */ -class JsonObjectHttpRequest extends HttpRequest<JSONObject> { - private final JSONObject mJsonObject; - - /** - * Construct a JSON object request. - * @param url The url to make this HTTP request to. - * @param userAgent The string to set as the User-Agent request header. - * @param acceptLanguage The string to set as the Accept-Language request header. - * @param jsonObject The JSON payload. - * @param callback The callback run when the HTTP response is received. - * @throws MalformedURLException on invalid url - */ - public JsonObjectHttpRequest(String url, String userAgent, String acceptLanguage, - JSONObject jsonObject, RequestCallback callback) - throws MalformedURLException { - super(url, userAgent, acceptLanguage, callback); - mJsonObject = jsonObject; - } - - /** - * The callback that gets run after the request is made. - */ - public interface RequestCallback extends HttpRequest.HttpRequestCallback<JSONObject> {} - - /** - * Helper method to make an HTTP request. - * @param urlConnection The HTTP connection. - */ - @Override - public void writeToUrlConnection(HttpURLConnection urlConnection) throws IOException { - urlConnection.setDoOutput(true); - urlConnection.setRequestProperty("Content-Type", "application/json"); - urlConnection.setRequestProperty("Accept", "application/json"); - urlConnection.setRequestMethod("POST"); - OutputStream os = urlConnection.getOutputStream(); - os.write(ApiCompatibilityUtils.getBytesUtf8(mJsonObject.toString())); - os.close(); - } - - /** - * Helper method to read an HTTP response. - * @param is The InputStream. - * @return An object representing the HTTP response. - */ - @Override - protected JSONObject readInputStream(InputStream is) throws IOException { - String jsonString = readStreamToString(is); - JSONObject jsonObject; - try { - return new JSONObject(jsonString); - } catch (JSONException error) { - throw new IOException(error.toString()); - } - } - - private static String readStreamToString(InputStream is) throws IOException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len; - while ((len = is.read(buffer)) != -1) { - os.write(buffer, 0, len); - } - return os.toString("UTF-8"); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClient.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClient.java deleted file mode 100644 index d11562d..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClient.java +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.physicalweb; - -import android.graphics.Bitmap; - -import java.util.Collection; - -/** - * This class sends requests to the Physical Web Service. - */ -interface PwsClient { - /** - * Callback that is run after the PWS sends a response to a resolve-scan request. - */ - interface ResolveScanCallback { - /** - * Handle newly returned PwsResults. - * @param pwsResults The results returned by the PWS. - */ - public void onPwsResults(Collection<PwsResult> pwsResults); - } - - /** - * Callback that is run after receiving the response to an icon fetch request. - */ - interface FetchIconCallback { - /** - * Handle newly returned favicon Bitmaps. - * @param iconUrl The favicon URL. - * @param iconBitmap The icon image data. - */ - public void onIconReceived(String iconUrl, Bitmap iconBitmap); - } - - /** - * Send an HTTP request to the PWS to resolve a set of URLs. - * @param broadcastUrls The URLs to resolve. - * @param resolveScanCallback The callback to be run when the response is received. - */ - void resolve(Collection<UrlInfo> broadcastUrls, ResolveScanCallback resolveScanCallback); - - /** - * Send an HTTP request to fetch a favicon. - * @param iconUrl The URL of the favicon. - * @param fetchIconCallback The callback to be run when the icon is received. - */ - void fetchIcon(String iconUrl, FetchIconCallback fetchIconCallback); -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java deleted file mode 100644 index fe2cb02..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java +++ /dev/null
@@ -1,314 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.physicalweb; - -import android.content.Context; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.os.Build; -import android.text.TextUtils; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import org.chromium.base.ContextUtils; -import org.chromium.base.LocaleUtils; -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.GoogleAPIKeys; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeVersionInfo; -import org.chromium.chrome.browser.physicalweb.PwsClient.FetchIconCallback; -import org.chromium.chrome.browser.physicalweb.PwsClient.ResolveScanCallback; - -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Formatter; -import java.util.HashSet; -import java.util.Locale; - -/** - * This class sends requests to the Physical Web Service. - */ -class PwsClientImpl implements PwsClient { - private static final String TAG = "PhysicalWeb"; - private static final String ENDPOINT_URL = - "https://physicalweb.googleapis.com/v1alpha1/urls:resolve"; - - // Format strings for creating the User-Agent string. It should somewhat resemble the Chrome for - // Android User-Agent but doesn't need to match perfectly as this value will only be seen by the - // Physical Web metadata service and favicon fetcher. - // The WebKit version is not accessible from here so it is reported as 0.0. - private static final String USER_AGENT_FORMAT = - "Mozilla/5.0 (%s) AppleWebKit/0.0 (KHTML, like Gecko) %s Safari/0.0"; - private static final String OS_INFO_FORMAT = "Linux; Android %s; %s Build/%s"; - private static final String PRODUCT_FORMAT = "Chrome/%s Mobile"; - - // HTTP request header strings, lazily initialized. - private static String sUserAgent; - private static String sAcceptLanguage; - - // Cached locale string. When the default locale changes, recreate the Accept-Language header. - private static String sDefaultLocale; - - public PwsClientImpl() {} - - private String getApiKey() { - if (ChromeVersionInfo.isStableBuild()) { - return GoogleAPIKeys.GOOGLE_API_KEY; - } else { - return GoogleAPIKeys.GOOGLE_API_KEY_PHYSICAL_WEB_TEST; - } - } - - private static JSONObject createResolveScanPayload(Collection<UrlInfo> urls) - throws JSONException { - // Encode the urls. - JSONArray objects = new JSONArray(); - for (UrlInfo urlInfo : urls) { - JSONObject obj = new JSONObject(); - obj.put("url", urlInfo.getUrl()); - objects.put(obj); - } - - // Organize the data into a single object. - JSONObject jsonObject = new JSONObject(); - jsonObject.put("urls", objects); - return jsonObject; - } - - private static Collection<PwsResult> parseResolveScanResponse(JSONObject result) { - // Get the metadata array. - Collection<PwsResult> pwsResults = new ArrayList<>(); - JSONArray metadata = result.optJSONArray("results"); - if (metadata == null) { - // There are no valid results. - return pwsResults; - } - - // Loop through the metadata for each url. - for (int i = 0; i < metadata.length(); i++) { - try { - pwsResults.add(PwsResult.jsonDeserialize(metadata.getJSONObject(i))); - } catch (JSONException e) { - Log.e(TAG, "PWS returned invalid data", e); - continue; - } - } - return pwsResults; - } - - /** - * Send an HTTP request to the PWS to resolve a set of URLs. - * @param broadcastUrls The URLs to resolve. - * @param resolveScanCallback The callback to be run when the response is received. - */ - @Override - public void resolve(final Collection<UrlInfo> broadcastUrls, - final ResolveScanCallback resolveScanCallback) { - // Create the response callback. - JsonObjectHttpRequest.RequestCallback requestCallback = - new JsonObjectHttpRequest.RequestCallback() { - @Override - public void onResponse(JSONObject result) { - ThreadUtils.assertOnUiThread(); - Collection<PwsResult> pwsResults = parseResolveScanResponse(result); - resolveScanCallback.onPwsResults(pwsResults); - } - - @Override - public void onError(int responseCode, Exception e) { - ThreadUtils.assertOnUiThread(); - String httpErr = ""; - if (responseCode > 0) { - httpErr = ", HTTP " + responseCode; - } - Log.e(TAG, "Error making request to PWS%s", httpErr); - resolveScanCallback.onPwsResults(new ArrayList<PwsResult>()); - } - }; - - // Create the request. - HttpRequest request = null; - try { - JSONObject payload = createResolveScanPayload(broadcastUrls); - String url = ENDPOINT_URL + "?key=" + getApiKey(); - request = new JsonObjectHttpRequest( - url, getUserAgent(), updateAcceptLanguage(), payload, requestCallback); - } catch (MalformedURLException e) { - Log.e(TAG, "Error creating PWS HTTP request", e); - return; - } catch (JSONException e) { - Log.e(TAG, "Error creating PWS JSON payload", e); - return; - } - // The callback will be called on the main thread. - AsyncTask.THREAD_POOL_EXECUTOR.execute(request); - } - - /** - * Send an HTTP request to fetch a favicon. - * @param iconUrl The URL of the favicon. - * @param fetchIconCallback The callback to be run when the icon is received. - */ - @Override - public void fetchIcon(final String iconUrl, - final FetchIconCallback fetchIconCallback) { - // Create the response callback. - BitmapHttpRequest.RequestCallback requestCallback = - new BitmapHttpRequest.RequestCallback() { - @Override - public void onResponse(Bitmap iconBitmap) { - fetchIconCallback.onIconReceived(iconUrl, iconBitmap); - } - - @Override - public void onError(int responseCode, Exception e) { - ThreadUtils.assertOnUiThread(); - String httpErr = ""; - if (responseCode > 0) { - httpErr = ", HTTP " + responseCode; - } - Log.e(TAG, "Error requesting icon%s", httpErr); - } - }; - - // Create the request. - BitmapHttpRequest request = null; - try { - request = new BitmapHttpRequest( - iconUrl, getUserAgent(), updateAcceptLanguage(), requestCallback); - } catch (MalformedURLException e) { - Log.e(TAG, "Error creating icon request", e); - return; - } - // The callback will be called on the main thread. - AsyncTask.THREAD_POOL_EXECUTOR.execute(request); - } - - /** - * Recreate the Chrome for Android User-Agent string as closely as possible without calling any - * native code. - * @return A User-Agent string - */ - @VisibleForTesting - String getUserAgent() { - if (sUserAgent == null) { - // Build the OS info string. - // eg: Linux; Android 5.1.1; Nexus 4 Build/LMY48T - String osInfo = String.format(OS_INFO_FORMAT, Build.VERSION.RELEASE, Build.MODEL, - Build.ID); - - // Build the product string. - // eg: Chrome/50.0.2661.89 Mobile - String product = String.format(PRODUCT_FORMAT, ChromeVersionInfo.getProductVersion()); - - // Build the User-Agent string. - // eg: Mozilla/5.0 (Linux; Android 5.1.1; Nexus 4 Build/LMY48T) AppleWebKit/0.0 (KHTML, - // like Gecko) Chrome/50.0.2661.89 Mobile Safari/0.0 - sUserAgent = String.format(USER_AGENT_FORMAT, osInfo, product); - } - return sUserAgent; - } - - /** - * Update an Accept-Language string based on the current default locales and make a string of - * an Accept-Language header with q-values. - * @return An Accept-Language string made of an Accept-Language header with q-values. - */ - @VisibleForTesting - String updateAcceptLanguage() { - String localeString = LocaleUtils.getDefaultLocaleListString(); - if (sDefaultLocale == null || !sDefaultLocale.equals(localeString)) { - Context context = ContextUtils.getApplicationContext(); - String acceptLanguages = context.getResources().getString(R.string.accept_languages); - acceptLanguages = prependToAcceptLanguagesIfNecessary(localeString, acceptLanguages); - sAcceptLanguage = generateAcceptLanguageHeader(acceptLanguages); - sDefaultLocale = localeString; - } - return sAcceptLanguage; - } - - /** - * Get the language code for the default locales and prepend it to the Accept-Language string - * if it isn't already present. The logic should match PrependToAcceptLanguagesIfNecessary in - * chrome/browser/android/preferences/pref_service_bridge.cc - * @param locales A comma separated string that represents a list of default locales. - * @param acceptLanguages The default language list for the language of the user's locales. - * @return An updated language list. - */ - @VisibleForTesting - static String prependToAcceptLanguagesIfNecessary(String locales, String acceptLanguages) { - String localeStrings = locales + "," + acceptLanguages; - String[] localeList = localeStrings.split(","); - - ArrayList<Locale> uniqueList = new ArrayList<>(); - for (String localeString : localeList) { - Locale locale = LocaleUtils.forLanguageTag(localeString); - if (uniqueList.contains(locale) || locale.getLanguage().isEmpty()) { - continue; - } - uniqueList.add(locale); - } - - // If language is not in the accept languages list, also add language code. - // A language code should only be inserted after the last languageTag that - // contains that language. - // This will work with the IDS_ACCEPT_LANGUAGE localized strings bundled - // with Chrome but may fail on arbitrary lists of language tags due to - // differences in case and whitespace. - HashSet<String> seenLanguages = new HashSet<>(); - ArrayList<String> outputList = new ArrayList<>(); - for (int i = uniqueList.size() - 1; i >= 0; i--) { - Locale localeAdd = uniqueList.get(i); - String languageAdd = localeAdd.getLanguage(); - String countryAdd = localeAdd.getCountry(); - - if (!seenLanguages.contains(languageAdd)) { - seenLanguages.add(languageAdd); - outputList.add(languageAdd); - } - if (!countryAdd.isEmpty()) { - outputList.add(LocaleUtils.toLanguageTag(localeAdd)); - } - } - Collections.reverse(outputList); - return TextUtils.join(",", outputList); - } - - /** - * Given a list of comma-delimited language codes in decreasing order of preference, insert - * q-values to represent the relative quality/precedence of each language. The logic should - * match GenerateAcceptLanguageHeader in net/http/http_util.cc. - * @param languageList A comma-delimited list of language codes containing no whitespace. - * @return An Accept-Language header with q-values. - */ - @VisibleForTesting - static String generateAcceptLanguageHeader(String languageList) { - // We use integers for qvalue and qvalue decrement that are 10 times larger than actual - // values to avoid a problem with comparing two floating point numbers. - int kQvalueDecrement10 = 2; - int qvalue10 = 10; - String[] parts = languageList.split(","); - Formatter langListWithQ = new Formatter(); - for (String language : parts) { - if (qvalue10 == 10) { - // q=1.0 is implicit - langListWithQ.format("%s", language); - } else { - langListWithQ.format(",%s;q=0.%d", language, qvalue10); - } - // It does not make sense to have 'q=0'. - if (qvalue10 > kQvalueDecrement10) { - qvalue10 -= kQvalueDecrement10; - } - } - return langListWithQ.toString(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java deleted file mode 100644 index 8db0ade1..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -package org.chromium.chrome.browser.physicalweb; - -import org.chromium.base.Log; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.MalformedURLException; -import java.net.URL; - -/** - * A result from the Physical Web Server. - * - * This represents metadata about a URL retrieved from from a PWS response. It does not - * necessarily represent one response as a single PWS response may include metadata about multiple - * URLs. - */ -class PwsResult { - private static final String TAG = "PhysicalWeb"; - private static final String PAGE_INFO_KEY = "pageInfo"; - private static final String REQUEST_URL_KEY = "scannedUrl"; - private static final String SITE_URL_KEY = "resolvedUrl"; - private static final String ICON_KEY = "icon"; - private static final String TITLE_KEY = "title"; - private static final String DESCRIPTION_KEY = "description"; - private static final String GROUP_ID_KEY = "groupId"; - - /** - * The URL that was set in the request to the PWS. - */ - public final String requestUrl; - - /** - * The destination URL that the requestUrl redirects to. - */ - public final String siteUrl; - - /** - * The URL for the destination's favicon. - */ - public final String iconUrl; - - /** - * The title of the web page. - */ - public final String title; - - /** - * The description of the webpage. - */ - public final String description; - - /** - * The group id as determined by the PWS. - * This value is useful for associating multiple URLs that refer to similar content in the same - * bucket. - */ - public final String groupId; - - /** - * Construct a PwsResult. - */ - PwsResult(String requestUrl, String siteUrl, String iconUrl, String title, String description, - String groupId) { - this.requestUrl = requestUrl; - this.siteUrl = siteUrl; - this.iconUrl = iconUrl; - this.title = title; - this.description = description; - - String groupIdToSet = groupId; - if (groupId == null) { - try { - groupIdToSet = new URL(siteUrl).getHost() + title; - } catch (MalformedURLException e) { - Log.e(TAG, "PwsResult created with a malformed URL", e); - groupIdToSet = siteUrl + title; - } - } - this.groupId = groupIdToSet; - } - - /** - * Creates a JSON object that represents this data structure. - * @return a JSON serialization of this data structure. - * @throws JSONException if the values cannot be deserialized. - */ - public JSONObject jsonSerialize() throws JSONException { - return new JSONObject() - .put(REQUEST_URL_KEY, requestUrl) - .put(SITE_URL_KEY, siteUrl) - .put(PAGE_INFO_KEY, new JSONObject() - .put(ICON_KEY, iconUrl) - .put(TITLE_KEY, title) - .put(DESCRIPTION_KEY, description) - .put(GROUP_ID_KEY, groupId)); - } - - /** - * Populates a PwsResult with data from a given JSON object. - * @param jsonObject a serialized PwsResult. - * @return The PwsResult represented by the serialized object. - * @throws JSONException if the values cannot be serialized. - */ - public static PwsResult jsonDeserialize(JSONObject jsonObject) throws JSONException { - JSONObject pageInfo = jsonObject.getJSONObject(PAGE_INFO_KEY); - return new PwsResult( - jsonObject.getString(REQUEST_URL_KEY), - jsonObject.getString(SITE_URL_KEY), - pageInfo.optString(ICON_KEY, null), - pageInfo.optString(TITLE_KEY, ""), - pageInfo.optString(DESCRIPTION_KEY, null), - pageInfo.optString(GROUP_ID_KEY, null)); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlInfo.java deleted file mode 100644 index a90ab33..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlInfo.java +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.physicalweb; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Locale; - -/** - * This class represents a scanned URL and information associated with that URL. - */ -class UrlInfo { - private static final String URL_KEY = "url"; - private static final String DISTANCE_KEY = "distance"; - private static final String FIRST_SEEN_TIMESTAMP_KEY = "first_seen_timestamp"; - private static final String DEVICE_ADDRESS_KEY = "device_address"; - private static final String HAS_BEEN_DISPLAYED_KEY = "has_been_displayed"; - private final String mUrl; - private final long mFirstSeenTimestamp; - private double mDistance; - private String mDeviceAddress; - private boolean mHasBeenDisplayed; - - public UrlInfo(String url, double distance, long firstSeenTimestamp) { - mUrl = url; - mDistance = distance; - mFirstSeenTimestamp = firstSeenTimestamp; - mDeviceAddress = null; - mHasBeenDisplayed = false; - } - - /** - * Constructs a simple UrlInfo with only a URL. - */ - public UrlInfo(String url) { - this(url, -1.0, System.currentTimeMillis()); - } - - /** - * Gets the URL represented by this object. - * @param The URL. - */ - public String getUrl() { - return mUrl; - } - - /** - * Sets the distance of the URL from the scanner in meters. - * @param distance The estimated distance of the URL from the scanner in meters. - */ - public UrlInfo setDistance(double distance) { - mDistance = distance; - return this; - } - - /** - * Gets the distance of the URL from the scanner in meters. - * @return The estimated distance of the URL from the scanner in meters. - */ - public double getDistance() { - return mDistance; - } - - /** - * Gets the timestamp of when the URL was first scanned. - * This timestamp is recorded using System.currentTimeMillis(). - * @return The first seen timestamp. - */ - public long getFirstSeenTimestamp() { - return mFirstSeenTimestamp; - } - - /** - * Sets the device address for the BLE beacon that last emitted this URL. - * @param deviceAddress the new device address, matching the - * BluetoothAdapter.checkBluetoothAddress format. - */ - public UrlInfo setDeviceAddress(String deviceAddress) { - mDeviceAddress = deviceAddress; - return this; - } - - /** - * Gets the device address for the BLE beacon that last emitted this URL. - * @return The device address. - */ - public String getDeviceAddress() { - return mDeviceAddress; - } - - /** - * Marks this URL as having been displayed to the user. - */ - public UrlInfo setHasBeenDisplayed() { - mHasBeenDisplayed = true; - return this; - } - - /** - * Tells if we've displayed this URL. - * @return Whether we've displayed this URL. - */ - public boolean hasBeenDisplayed() { - return mHasBeenDisplayed; - } - - /** - * Creates a JSON object that represents this data structure. - * @return a JSON serialization of this data structure. - * @throws JSONException if the values cannot be deserialized. - */ - public JSONObject jsonSerialize() throws JSONException { - return new JSONObject() - .put(URL_KEY, mUrl) - .put(DISTANCE_KEY, mDistance) - .put(FIRST_SEEN_TIMESTAMP_KEY, mFirstSeenTimestamp) - .put(DEVICE_ADDRESS_KEY, mDeviceAddress) - .put(HAS_BEEN_DISPLAYED_KEY, mHasBeenDisplayed); - } - - /** - * Populates a UrlInfo with data from a given JSON object. - * @param jsonObject a serialized UrlInfo. - * @return The UrlInfo represented by the serialized object. - * @throws JSONException if the values cannot be serialized. - */ - public static UrlInfo jsonDeserialize(JSONObject jsonObject) throws JSONException { - UrlInfo urlInfo = new UrlInfo(jsonObject.getString(URL_KEY), - jsonObject.getDouble(DISTANCE_KEY), jsonObject.getLong(FIRST_SEEN_TIMESTAMP_KEY)) - .setDeviceAddress(jsonObject.optString(DEVICE_ADDRESS_KEY)); - if (jsonObject.optBoolean(HAS_BEEN_DISPLAYED_KEY, false)) { - urlInfo.setHasBeenDisplayed(); - } - return urlInfo; - } - - /** - * Represents the UrlInfo as a String. - */ - @Override - public String toString() { - return String.format(Locale.getDefault(), "%s %f %d %b", mUrl, mDistance, - mFirstSeenTimestamp, mHasBeenDisplayed); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java index a0587d3..f2f97f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java
@@ -13,6 +13,9 @@ import org.chromium.chrome.browser.preferences.autofill.AutofillAndPaymentsPreferences; import org.chromium.chrome.browser.preferences.password.SavePasswordsPreferences; import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataTabsFragment; +import org.chromium.content_public.browser.WebContents; + +import java.lang.ref.WeakReference; /** * A utility class for launching Chrome Settings. @@ -62,8 +65,11 @@ } @CalledByNative - private static void showAutofillSettings() { - launchSettingsPage(ContextUtils.getApplicationContext(), + private static void showAutofillSettings(WebContents webContents) { + WeakReference<Activity> currentActivity = + webContents.getTopLevelNativeWindow().getActivity(); + + launchSettingsPage(currentActivity.get(), AutofillAndPaymentsPreferences.class.getName()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSection.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSection.java index d449844..f597db9b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSection.java
@@ -10,14 +10,12 @@ import org.chromium.base.ContextUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ntp.ContextMenuManager; import org.chromium.chrome.browser.ntp.cards.ItemViewType; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.ntp.cards.NodeVisitor; import org.chromium.chrome.browser.ntp.cards.OptionalLeaf; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; -import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.widget.displaystyle.UiConfig; /** @@ -30,16 +28,6 @@ */ private static final int MAX_TILE_COLUMNS = 4; - /** - * Experiment parameter for the maximum number of tile suggestion rows to show. - */ - private static final String PARAM_CHROME_HOME_MAX_TILE_ROWS = "chrome_home_max_tile_rows"; - - /** - * Experiment parameter for the number of tile title lines to show. - */ - private static final String PARAM_CHROME_HOME_TILE_TITLE_LINES = "chrome_home_tile_title_lines"; - private final TileGroup mTileGroup; private final TileRenderer mTileRenderer; @@ -110,17 +98,11 @@ } private static int getMaxTileRows() { - int defaultValue = 2; - if (!FeatureUtilities.isChromeHomeEnabled()) return defaultValue; - return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( - ChromeFeatureList.CHROME_HOME, PARAM_CHROME_HOME_MAX_TILE_ROWS, defaultValue); + return 2; } private static int getTileTitleLines() { - int defaultValue = 1; - if (!FeatureUtilities.isChromeHomeEnabled()) return defaultValue; - return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( - ChromeFeatureList.CHROME_HOME, PARAM_CHROME_HOME_TILE_TITLE_LINES, defaultValue); + return 1; } @LayoutRes
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java index 1ab1579..4260f906 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java
@@ -63,6 +63,7 @@ TabBrowserControlsOffsetHelper(Tab tab) { mTab = tab; VrShellDelegate.registerVrModeObserver(this); + if (VrShellDelegate.isInVr()) onEnterVr(); } /** @@ -258,7 +259,11 @@ @Override public void onExitVr() { mIsInVr = false; + // Call resetPositions() to clear the VR-specific overrides for controls height. resetPositions(); + // Show the Controls explicitly because under some situations, like when we're showing a + // Native Page, the renderer won't send any new offsets. + showAndroidControls(false); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java index d99f165..bd6d093 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
@@ -155,6 +155,7 @@ * @return Options that a VR-specific Chrome activity should be launched with. */ public static Bundle getVrIntentOptions(Context context) { + if (!VrShellDelegate.isVrEnabled()) return null; // These options are used to start the Activity with a custom animation to keep it hidden // for a few hundred milliseconds - enough time for us to draw the first black view. // The animation is sufficient to hide the 2D screenshot but not to the 2D UI while the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 71e6063..71f2252 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -788,6 +788,8 @@ */ public static VrClassesWrapper getVrClassesWrapper() { if (sVrClassesWrapper == null) sVrClassesWrapper = createVrClassesWrapper(); + // Disable VR on standalone VR devices (https://crbug.com/841850). + if (sVrClassesWrapper != null && sVrClassesWrapper.bootsToVr()) return null; return sVrClassesWrapper; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 3058f71..1741830 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -577,7 +577,14 @@ public void onWindowFocusChanged(boolean focused) { // This handles the case where we open 2D popups in 2D-in-VR. We lose window focus, but stay // resumed, so we have to listen for focus gain to know when the popup was closed. - if (focused) VrShellDelegate.setVrModeEnabled(mActivity, true); + // This also handles the case where we're launched via intent and turn VR mode on with + // a popup open. We'll lose window focus when the popup 'gets shown' and know to turn VR + // mode off. + // TODO(asimjour): Focus is a bad signal. We should listen for windows being created and + // destroyed if possible. + if (VrShellDelegate.getVrClassesWrapper().bootsToVr()) { + VrShellDelegate.setVrModeEnabled(mActivity, focused); + } } @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 00163757..0151197 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -1160,7 +1160,7 @@ float offsetWithBrowserControls = getCurrentOffsetPx() - getOffsetFromBrowserControls(); // Do not send events for states less than the hidden state unless 0 has not been sent. - if (offsetWithBrowserControls < getSheetHeightForState(SHEET_STATE_HIDDEN) + if (offsetWithBrowserControls <= getSheetHeightForState(SHEET_STATE_HIDDEN) && mLastOffsetRatioSent <= 0) { return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java index 42dde8c..d02f41a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetController.java
@@ -173,6 +173,7 @@ @Override public void onTransitionPeekToHalf(float transitionFraction) { + if (!mBottomSheet.isSheetOpen()) return; fadingBackgroundView.setViewAlpha(transitionFraction); } @@ -395,7 +396,7 @@ // TODO(mdjones): Replace usages of bottom sheet with a model in line with MVC. // TODO(mdjones): It would probably be useful to expose an observer method that notifies // objects when all content requests are cleared. - hideContent(mBottomSheet.getCurrentSheetContent(), true); + hideContent(mBottomSheet.getCurrentSheetContent(), false); mWasShownForCurrentTab = false; mIsSuppressed = false; }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 0764133..60dcc68 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -939,7 +939,6 @@ "java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java", "java/src/org/chromium/chrome/browser/permissions/PermissionDialogView.java", "java/src/org/chromium/chrome/browser/permissions/PermissionUmaUtil.java", - "java/src/org/chromium/chrome/browser/physicalweb/BitmapHttpRequest.java", "java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java", "java/src/org/chromium/chrome/browser/photo_picker/BitmapUtils.java", "java/src/org/chromium/chrome/browser/photo_picker/DecoderService.java", @@ -953,14 +952,8 @@ "java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapView.java", "java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java", "java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java", - "java/src/org/chromium/chrome/browser/physicalweb/HttpRequest.java", - "java/src/org/chromium/chrome/browser/physicalweb/JsonObjectHttpRequest.java", "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWeb.java", "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebUma.java", - "java/src/org/chromium/chrome/browser/physicalweb/PwsClient.java", - "java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java", - "java/src/org/chromium/chrome/browser/physicalweb/PwsResult.java", - "java/src/org/chromium/chrome/browser/physicalweb/UrlInfo.java", "java/src/org/chromium/chrome/browser/physicalweb/Utils.java", "java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java", "java/src/org/chromium/chrome/browser/preferences/AboutChromePreferences.java", @@ -1751,7 +1744,6 @@ "javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageUnitTest.java", "javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java", - "javatests/src/org/chromium/chrome/browser/physicalweb/MockPwsClient.java", "javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java", "javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java", "javatests/src/org/chromium/chrome/browser/payments/CurrencyFormatterTest.java", @@ -2068,9 +2060,6 @@ "junit/src/org/chromium/chrome/browser/payments/AutofillContactTest.java", "junit/src/org/chromium/chrome/browser/payments/AutofillContactUnitTest.java", "junit/src/org/chromium/chrome/browser/payments/PaymentManifestVerifierTest.java", - "junit/src/org/chromium/chrome/browser/physicalweb/PwsClientImplTest.java", - "junit/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java", - "junit/src/org/chromium/chrome/browser/physicalweb/UrlInfoTest.java", "junit/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java", "junit/src/org/chromium/chrome/browser/preferences/password/DialogManagerTest.java", "junit/src/org/chromium/chrome/browser/preferences/password/EnsureAsyncPostingRule.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java index 1134fd13..fc3fe7c9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
@@ -9,7 +9,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.core.IsCollectionContaining.hasItems; -import static org.junit.Assert.assertFalse; import android.support.test.filters.SmallTest; @@ -20,15 +19,13 @@ import org.chromium.base.CommandLine; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.browser.ChromeHome; +import org.chromium.chrome.test.util.browser.ChromeModernDesign; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; -import org.chromium.ui.base.DeviceFormFactor; import java.util.Arrays; import java.util.List; @@ -40,7 +37,7 @@ @CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) public class FeaturesAnnotationsTest { @Rule - public TestRule mChromeHomeProcessor = new ChromeHome.Processor(); + public TestRule mChromeHomeProcessor = new ChromeModernDesign.Processor(); @Rule public TestRule mFeaturesProcessor = new Features.InstrumentationProcessor(); @@ -69,21 +66,22 @@ } /** - * Tests the compatibility between {@link EnableFeatures} and other rules. {@link ChromeHome} - * here explicitly calls {@link Features#enable(String...)}, so its feature should also be added - * to the set of registered flags. + * Tests the compatibility between {@link EnableFeatures} and other rules. + * {@link @ChromeModernDesign} here explicitly calls {@link Features#enable(String...)}, so + * its feature should also be added to the set of registered flags. */ - @DisabledTest(message = "https://crbug.com/805160") @Test @SmallTest - @ChromeHome.Enable + @ChromeModernDesign.Enable @EnableFeatures("One") public void testFeaturesIncludeValuesSetFromOtherRules() throws InterruptedException { mActivityRule.startMainActivityOnBlankPage(); List<String> finalEnabledList = getArgsList(true); - assertThat(finalEnabledList, hasItems("One", ChromeFeatureList.CHROME_HOME)); - assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME)); + assertThat(finalEnabledList, hasItems("One", ChromeFeatureList.CHROME_MODERN_DESIGN)); + assertTrue(ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_MODERN_DESIGN)); + assertTrue("ChromeModernDesign should be enabled.", + FeatureUtilities.isChromeModernDesignEnabled()); } /** @@ -123,15 +121,6 @@ assertThat(finalEnabledList.size(), equalTo(4)); } - @DisabledTest(message = "https://crbug.com/805160") - @Test - @SmallTest - @ChromeHome.Enable - public void testChromeHomeSkipping() { - assertFalse("The test should only run on phones.", DeviceFormFactor.isTablet()); - assertTrue("ChromeHome should be enabled.", FeatureUtilities.isChromeHomeEnabled()); - } - private static List<String> getArgsList(boolean enabled) { String switchName = enabled ? "enable-features" : "disable-features"; return Arrays.asList(CommandLine.getInstance().getSwitchValue(switchName).split(","));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java index a7ba337..3ff7b03 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java
@@ -63,7 +63,10 @@ import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.TestWebContentsObserver; +import org.chromium.content_public.browser.GestureListenerManager; +import org.chromium.content_public.browser.GestureStateListener; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.WebContents; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.ui.test.util.UiRestriction; @@ -118,6 +121,7 @@ mFakeSource = new FakeContextualSuggestionsSource(); mContextualSuggestionsDeps.getFactory().suggestionsSource = mFakeSource; FetchHelper.setDisableDelayForTesting(true); + ContextualSuggestionsMediator.setOverrideBrowserControlsHiddenForTesting(true); FakeEnabledStateMonitor stateMonitor = new FakeEnabledStateMonitor(); mContextualSuggestionsDeps.getFactory().enabledStateMonitor = new FakeEnabledStateMonitor(); @@ -147,6 +151,7 @@ public void tearDown() { mTestServer.stopAndDestroyServer(); FetchHelper.setDisableDelayForTesting(false); + ContextualSuggestionsMediator.setOverrideBrowserControlsHiddenForTesting(false); } @Test @@ -171,7 +176,7 @@ assertEquals("RecyclerView should be empty.", 0, recyclerView.getChildCount()); ThreadUtils.runOnUiThreadBlocking(() -> { - mMediator.showContentInSheetForTesting(true); + mMediator.showContentInSheetForTesting(true, true); mBottomSheet.endAnimations(); }); @@ -190,6 +195,8 @@ @MediumTest @Feature({"ContextualSuggestions"}) public void testScrollPageToTrigger() throws InterruptedException, TimeoutException { + ContextualSuggestionsMediator.setOverrideBrowserControlsHiddenForTesting(false); + mMediator.setTargetScrollPercentageForTesting(0f); assertEquals("Sheet should be hidden.", BottomSheet.SHEET_STATE_HIDDEN, mBottomSheet.getSheetState()); @@ -427,7 +434,7 @@ mModel2.getClusterList().getItemCount()); ThreadUtils.runOnUiThreadBlocking(() -> { - mMediator2.showContentInSheetForTesting(true); + mMediator2.showContentInSheetForTesting(true, true); mBottomSheet2.endAnimations(); ContextualSuggestionsBottomSheetContent content1 = @@ -538,6 +545,53 @@ @Test @MediumTest @Feature({"ContextualSuggestions"}) + public void testPeekWithPageScrollPercentage() throws Exception { + CallbackHelper scrollChangedCallback = new CallbackHelper(); + GestureStateListener gestureStateListener = new GestureStateListener() { + @Override + public void onScrollOffsetOrExtentChanged(int scrollOffsetY, int scrollExtentY) { + scrollChangedCallback.notifyCalled(); + } + }; + WebContents webContents = mActivityTestRule.getWebContents(); + GestureListenerManager.fromWebContents(webContents).addListener(gestureStateListener); + View view = webContents.getViewAndroidDelegate().getContainerView(); + + // Verify that suggestions are not shown before scroll. + ThreadUtils.runOnUiThreadBlocking( + () -> mMediator.showContentInSheetForTesting(false, true)); + assertEquals("Bottom sheet should be hidden before scroll.", BottomSheet.SHEET_STATE_HIDDEN, + mBottomSheet.getSheetState()); + + // Scroll the page to 30% and verify that the suggestions are not shown. The pixel to scroll + // is hard coded (approximately) based on the html height of the TEST_PAGE. + int callCount = scrollChangedCallback.getCallCount(); + ThreadUtils.runOnUiThreadBlocking(() -> view.scrollBy(0, 3000)); + scrollChangedCallback.waitForCallback(callCount); + + // Simulate call to show content without browser controls being hidden. + ThreadUtils.runOnUiThreadBlocking( + () -> mMediator.showContentInSheetForTesting(false, true)); + assertEquals("Bottom sheet should be hidden on 30% scroll percentage.", + BottomSheet.SHEET_STATE_HIDDEN, mBottomSheet.getSheetState()); + + // Scroll the page to approximately 60% and verify that the suggestions are shown. + callCount = scrollChangedCallback.getCallCount(); + ThreadUtils.runOnUiThreadBlocking(() -> view.scrollBy(0, 3000)); + scrollChangedCallback.waitForCallback(callCount); + + // Simulate call to show content without browser controls being hidden. + ThreadUtils.runOnUiThreadBlocking( + () -> mMediator.showContentInSheetForTesting(false, true)); + assertEquals("Bottom sheet should be shown on >=50% scroll percentage.", + BottomSheet.SHEET_STATE_PEEK, mBottomSheet.getSheetState()); + + GestureListenerManager.fromWebContents(webContents).removeListener(gestureStateListener); + } + + @Test + @MediumTest + @Feature({"ContextualSuggestions"}) public void testPeekDelay() throws Exception { // Close the suggestions from setUp(). ThreadUtils.runOnUiThreadBlocking(() -> { @@ -550,12 +604,12 @@ FetchHelper.setFetchTimeBaselineMillisForTesting(startTime); ThreadUtils.runOnUiThreadBlocking( () -> mMediator.requestSuggestions("http://www.testurl.com")); - assertTrue("Bottom sheet should be hidden before delay.", - mBottomSheet.getSheetState() == BottomSheet.SHEET_STATE_HIDDEN); + assertEquals("Bottom sheet should be hidden before delay.", BottomSheet.SHEET_STATE_HIDDEN, + mBottomSheet.getSheetState()); // Simulate user scroll by calling showContentInSheet until the sheet is peeked. CriteriaHelper.pollUiThread(() -> { - mMediator.showContentInSheetForTesting(false); + mMediator.showContentInSheetForTesting(true, false); mBottomSheet.endAnimations(); return mBottomSheet.getSheetState() == BottomSheet.SHEET_STATE_PEEK; }); @@ -606,7 +660,7 @@ mModel.getClusterList().getItemCount()); ThreadUtils.runOnUiThreadBlocking(() -> { - mMediator.showContentInSheetForTesting(true); + mMediator.showContentInSheetForTesting(true, true); mBottomSheet.endAnimations(); assertEquals("Sheet should be peeked.", BottomSheet.SHEET_STATE_PEEK,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java index 70519ba9..a23ca58 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java
@@ -28,6 +28,7 @@ final static String TEST_TOOLBAR_TITLE = "More about capybaras"; // There should be 6 items in the cluster list - 5 articles and one cluster title. final static Integer TOTAL_ITEM_COUNT = 6; + final static float TEST_PEEK_TARGET_PERCENTAGE = .5f; final static int TEST_PEEK_COUNT = 3; final static int TEST_PEEK_DELAY_SECONDS = 2; @@ -135,7 +136,8 @@ cluster2.getSuggestions().add(article5); ContextualSuggestionsResult result = new ContextualSuggestionsResult(TEST_TOOLBAR_TITLE); - result.setPeekConditions(new PeekConditions(0f, TEST_PEEK_DELAY_SECONDS, TEST_PEEK_COUNT)); + result.setPeekConditions(new PeekConditions( + TEST_PEEK_TARGET_PERCENTAGE, TEST_PEEK_DELAY_SECONDS, TEST_PEEK_COUNT)); result.getClusters().add(cluster1); result.getClusters().add(cluster2);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java index 4ddbc673..c253860 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java
@@ -258,13 +258,13 @@ checkBrowserControls(false); checkCurrentPresenter(null); - // Insert a tab modal dialog and two app modal dialogs for showing. + // Insert two tab modal dialogs and two app modal dialogs for showing. showDialog(0, ModalDialogManager.TAB_MODAL); showDialog(1, ModalDialogManager.TAB_MODAL); showDialog(2, ModalDialogManager.APP_MODAL); showDialog(3, ModalDialogManager.APP_MODAL); - // The first inserted app modal dialog show be shown. + // The first inserted app modal dialog is shown. checkPendingSize(ModalDialogManager.APP_MODAL, 1); checkPendingSize(ModalDialogManager.TAB_MODAL, 2); onView(withText("2")).check(matches(isDisplayed())); @@ -304,6 +304,59 @@ @Test @SmallTest + public void testShow_ShowDialogAsNext() throws Exception { + // Initially there are no dialogs in the pending list. Browser controls are not restricted. + checkPendingSize(ModalDialogManager.APP_MODAL, 0); + checkPendingSize(ModalDialogManager.TAB_MODAL, 0); + checkBrowserControls(false); + checkCurrentPresenter(null); + + // Insert a tab modal dialog and a app modal dialog for showing. + showDialog(0, ModalDialogManager.TAB_MODAL); + showDialog(1, ModalDialogManager.TAB_MODAL); + showDialog(2, ModalDialogManager.APP_MODAL); + + // The first inserted app modal dialog is shown. + checkPendingSize(ModalDialogManager.APP_MODAL, 0); + checkPendingSize(ModalDialogManager.TAB_MODAL, 2); + onView(withText("2")).check(matches(isDisplayed())); + onView(withId(R.id.tab_modal_dialog_container)).check(doesNotExist()); + checkCurrentPresenter(ModalDialogManager.APP_MODAL); + + // Show a tab modal dialog as the next dialog to be shown. Verify that the app modal dialog + // is still showing. + showDialogAsNext(3, ModalDialogManager.TAB_MODAL); + checkPendingSize(ModalDialogManager.APP_MODAL, 0); + checkPendingSize(ModalDialogManager.TAB_MODAL, 3); + onView(withText("2")).check(matches(isDisplayed())); + onView(withId(R.id.tab_modal_dialog_container)).check(doesNotExist()); + checkCurrentPresenter(ModalDialogManager.APP_MODAL); + + // Dismiss the dialog by clicking OK. The third tab modal dialog should be shown. + onView(withText(R.string.ok)).perform(click()); + checkPendingSize(ModalDialogManager.APP_MODAL, 0); + checkPendingSize(ModalDialogManager.TAB_MODAL, 2); + onView(withId(R.id.tab_modal_dialog_container)) + .check(matches(allOf(hasDescendant(withText("3")), + not(hasDescendant(withText("0"))), not(hasDescendant(withText("1"))), + not(hasDescendant(withText("2")))))); + checkBrowserControls(true); + checkCurrentPresenter(ModalDialogManager.TAB_MODAL); + + // Dismiss the dialog by clicking OK. The first tab modal dialog should be shown. + onView(withText(R.string.ok)).perform(click()); + checkPendingSize(ModalDialogManager.APP_MODAL, 0); + checkPendingSize(ModalDialogManager.TAB_MODAL, 1); + onView(withId(R.id.tab_modal_dialog_container)) + .check(matches(allOf(hasDescendant(withText("0")), + not(hasDescendant(withText("1"))), not(hasDescendant(withText("2"))), + not(hasDescendant(withText("3")))))); + checkBrowserControls(true); + checkCurrentPresenter(ModalDialogManager.TAB_MODAL); + } + + @Test + @SmallTest @DisabledTest(message = "crbug.com/812066") public void testShow_UrlBarFocused() throws Exception { // Show a dialog. The dialog should be shown on top of the toolbar. @@ -658,12 +711,17 @@ private void showDialog( final int index, final @ModalDialogManager.ModalDialogType int dialogType) { ThreadUtils.runOnUiThreadBlocking( - () -> { mManager.showDialog(mModalDialogViews[index], dialogType); }); + () -> mManager.showDialog(mModalDialogViews[index], dialogType)); + } + + private void showDialogAsNext( + final int index, final @ModalDialogManager.ModalDialogType int dialogType) { + ThreadUtils.runOnUiThreadBlocking( + () -> mManager.showDialog(mModalDialogViews[index], dialogType, true)); } private void dismissDialog(final int index) { - ThreadUtils.runOnUiThreadBlocking( - () -> { mManager.dismissDialog(mModalDialogViews[index]); }); + ThreadUtils.runOnUiThreadBlocking(() -> mManager.dismissDialog(mModalDialogViews[index])); } private void checkPendingSize(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java index 10f8e59..53d9bc41 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java
@@ -729,6 +729,9 @@ assertThat(actionTester.toString(), getNotificationActions(actionTester), Matchers.contains( "Notifications.Persistent.Shown", "Notifications.Persistent.Clicked")); + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting( + "Notifications.AppNotificationStatus")); } /**
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index 697eeff3..e1a8b75 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -81,7 +81,6 @@ import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.CategoryInfoBuilder; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; import org.chromium.components.signin.AccountManagerFacade; @@ -103,10 +102,9 @@ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE, shadows = {CustomShadowAsyncTask.class}) -@DisableFeatures({ChromeFeatureList.CHROME_HOME, - ChromeFeatureList.CONTENT_SUGGESTIONS_SCROLL_TO_LOAD, - ChromeFeatureList.NTP_ARTICLE_SUGGESTIONS_EXPANDABLE_HEADER, - ChromeFeatureList.SIMPLIFIED_NTP, ChromeFeatureList.CHROME_DUPLEX}) +@DisableFeatures({ChromeFeatureList.CONTENT_SUGGESTIONS_SCROLL_TO_LOAD, + ChromeFeatureList.NTP_ARTICLE_SUGGESTIONS_EXPANDABLE_HEADER, + ChromeFeatureList.SIMPLIFIED_NTP, ChromeFeatureList.CHROME_DUPLEX}) public class NewTabPageAdapterTest { @Rule @@ -1016,10 +1014,9 @@ assertEquals(0, preferenceManager.getNewTabPageSigninPromoSuppressionPeriodStart()); } - @Ignore // Disabled for new Chrome Home, see: https://crbug.com/805160 + @Ignore // Disabled for new Chrome Home, see: https://crbug.com/805160, re-enable for Modern @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.CHROME_HOME) public void testSigninPromoModern() { when(mMockSigninManager.isSignInAllowed()).thenReturn(true); when(mMockSigninManager.isSignedInOnNative()).thenReturn(false); @@ -1176,10 +1173,9 @@ mAdapter.getFirstPositionForType(ItemViewType.ALL_DISMISSED)); } - @Ignore // Disabled for new Chrome Home, see: https://crbug.com/805160 + @Ignore // Disabled for new Chrome Home, see: https://crbug.com/805160, re-enable for Modern @Test @Feature({"Ntp"}) - @EnableFeatures(ChromeFeatureList.CHROME_HOME) public void testAllDismissedModern() { when(mUiDelegate.isVisible()).thenReturn(true);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/PwsClientImplTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/PwsClientImplTest.java deleted file mode 100644 index de1a965..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/PwsClientImplTest.java +++ /dev/null
@@ -1,193 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.physicalweb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.content.res.Resources; -import android.text.TextUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; -import org.robolectric.annotation.Implementation; -import org.robolectric.annotation.Implements; -import org.robolectric.shadows.ShadowResources; - -import org.chromium.base.LocaleUtils; -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.R; - -import java.util.Locale; - -/** - * Tests for {@link PwsClientImpl}. - */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class PwsClientImplTest { - private static final String ACCEPT_LANGUAGES = "en-US,en"; - PwsClientImpl mPwsClientImpl; - - /** - * Robolectric shadow to mock out calls to {@link Resources#getString}. - */ - @Implements(Resources.class) - public static class AcceptLanguageShadowResources extends ShadowResources { - public static final Resources sResources = mock(Resources.class); - - @Implementation - public CharSequence getText(int id) { - return sResources.getText(id); - } - } - - @Before - public void setUp() throws Exception { - mPwsClientImpl = new PwsClientImpl(); - } - - @Test - public void testUserAgentNonEmpty() { - assertFalse(TextUtils.isEmpty(mPwsClientImpl.getUserAgent())); - } - - @Test - @Config(shadows = AcceptLanguageShadowResources.class) - public void testLanguageTagIsIncludedInAcceptLanguageHeader() { - when(AcceptLanguageShadowResources.sResources.getText(R.string.accept_languages)) - .thenReturn(ACCEPT_LANGUAGES); - String defaultLocaleString = LocaleUtils.getDefaultLocaleString(); - String[] languageTags = defaultLocaleString.split(","); - - // Ensure Accept-Language contains the full language tag. - String acceptLanguage = mPwsClientImpl.updateAcceptLanguage(); - for (String tag : languageTags) { - assertTrue(acceptLanguage.contains(tag)); - // Ensure Accept-Language also contains the language code by itself. - String languageCode; - if (tag.length() == 2 || tag.length() == 3) { - languageCode = tag; - } else if (tag.charAt(2) == '-') { - languageCode = tag.substring(0, 2); - } else { // length of the language code is 3. - languageCode = tag.substring(0, 3); - } - assertTrue(acceptLanguage.startsWith(languageCode + ",") - || acceptLanguage.contains(languageCode + ";") - || acceptLanguage.equals(languageCode)); - } - } - - @Test - public void testLanguageTagIsPrepended() { - Locale locale = new Locale("en", "GB"); - String defaultLocale = LocaleUtils.toLanguageTag(locale); - String languageList = "fr-CA,fr-FR,fr"; - - // Should prepend the language tag "en-GB" as well as the language code "en". - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(defaultLocale, languageList); - assertEquals("en-GB,en,fr-CA,fr-FR,fr", languageListWithTag); - } - - @Test - public void testLanguageOnlyTagIsPrepended() { - Locale locale = new Locale("mas"); - String defaultLocale = LocaleUtils.toLanguageTag(locale); - String languageList = "fr-CA,fr-FR,fr"; - - // Should prepend the language code only language tag "aaa". - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(defaultLocale, languageList); - assertEquals("mas,fr-CA,fr-FR,fr", languageListWithTag); - } - - @Test - public void testSpecialLengthCountryCodeIsPrepended() { - Locale locale = new Locale("es", "005"); - String defaultLocale = LocaleUtils.toLanguageTag(locale); - String languageList = "fr-CA,fr-FR,fr"; - - // Should prepend the language tag "aa-AAA" as well as the language code "aa". - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(defaultLocale, languageList); - assertEquals("es-005,es,fr-CA,fr-FR,fr", languageListWithTag); - } - - @Test - public void testMultipleLanguageTagIsPrepended() { - String locale = "jp-JP,is-IS"; - String languageList = "en-US,en"; - - // Should prepend the language tag "aa-AA" as well as the language code "aa". - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(locale, languageList); - assertEquals("jp-JP,jp,is-IS,is,en-US,en", languageListWithTag); - - // Make sure the language code is only inserted after the last languageTag that - // contains that language. - locale = "jp-JP,fr-CA,fr-FR"; - languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(locale, languageList); - assertEquals("jp-JP,jp,fr-CA,fr-FR,fr,en-US,en", languageListWithTag); - } - - @Test - public void testLanguageTagIsPrependedWhenListContainsLanguageCode() { - Locale locale = new Locale("fr", "FR"); - String defaultLocale = LocaleUtils.toLanguageTag(locale); - String languageList = "fr-CA,fr"; - - // Should prepend the language tag "xx-XX" but not the language code "xx" as it's already - // included at the end of the list. - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(defaultLocale, languageList); - assertEquals("fr-FR,fr-CA,fr", languageListWithTag); - } - - @Test - public void testLanguageTagNotPrependedWhenUnnecessary() { - Locale locale = new Locale("fr", "CA"); - String defaultLocale = LocaleUtils.toLanguageTag(locale); - String languageList = "fr-CA,fr-FR,fr"; - - // Language list should be unmodified since the tag is already present. - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(defaultLocale, languageList); - assertEquals(languageList, languageListWithTag); - } - - @Test - public void testMultiLanguageTagNotPrependedWhenUnnecessary() { - String locale = "fr-FR,is-IS"; - String languageList = "fr-FR,is-IS,fr,is"; - - // Language list should be unmodified since the tag is already present. However, the order - // changes because a language-code-only language tag is acceptable now. - String languageListWithTag = - PwsClientImpl.prependToAcceptLanguagesIfNecessary(locale, languageList); - assertEquals(languageList, languageListWithTag); - } - - @Test - public void testAcceptLanguageQvalues() { - String languageList = "en-US,en-GB,en,jp-JP,jp"; - - // Should insert q-values for each item except the first which implicitly has q=1.0. - String acceptLanguage = PwsClientImpl.generateAcceptLanguageHeader(languageList); - assertEquals("en-US,en-GB;q=0.8,en;q=0.6,jp-JP;q=0.4,jp;q=0.2", acceptLanguage); - - // When there are six or more items, the q-value should not go below 0.2. - languageList = "mas,es,en,jp,ch,fr"; - acceptLanguage = PwsClientImpl.generateAcceptLanguageHeader(languageList); - assertEquals("mas,es;q=0.8,en;q=0.6,jp;q=0.4,ch;q=0.2,fr;q=0.2", acceptLanguage); - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java deleted file mode 100644 index 93b9215..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.physicalweb; - -import static org.junit.Assert.assertEquals; - -import org.json.JSONException; -import org.json.JSONObject; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.BlockJUnit4ClassRunner; - -/** - * Tests for {@link PwsResult}. - */ -@RunWith(BlockJUnit4ClassRunner.class) -public class PwsResultTest { - PwsResult mReferencePwsResult = null; - JSONObject mReferenceJsonObject = null; - - @Before - public void setUp() throws Exception { - mReferencePwsResult = new PwsResult("https://shorturl.com", "https://longurl.com", - "https://longurl.com/favicon.ico", "This is a page", "Pages are the best", - "group1"); - // Because we can't print JSON sorted by keys, the order is important here. - mReferenceJsonObject = new JSONObject("{" - + " \"scannedUrl\": \"https://shorturl.com\"," - + " \"resolvedUrl\": \"https://longurl.com\"," - + " \"pageInfo\": {" - + " \"icon\": \"https://longurl.com/favicon.ico\"," - + " \"title\": \"This is a page\"," - + " \"description\": \"Pages are the best\"," - + " \"groupId\": \"group1\"" - + " }" - + "}"); - } - - @Test - public void testJsonSerializeWorks() throws JSONException { - assertEquals( - mReferenceJsonObject.toString(), mReferencePwsResult.jsonSerialize().toString()); - } - - @Test - public void testJsonDeserializeWorks() throws JSONException { - PwsResult pwsResult = PwsResult.jsonDeserialize(mReferenceJsonObject); - assertEquals(mReferencePwsResult.requestUrl, pwsResult.requestUrl); - assertEquals(mReferencePwsResult.siteUrl, pwsResult.siteUrl); - assertEquals(mReferencePwsResult.iconUrl, pwsResult.iconUrl); - assertEquals(mReferencePwsResult.title, pwsResult.title); - assertEquals(mReferencePwsResult.description, pwsResult.description); - assertEquals(mReferencePwsResult.groupId, pwsResult.groupId); - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/UrlInfoTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/UrlInfoTest.java deleted file mode 100644 index e49ae56..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/physicalweb/UrlInfoTest.java +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.physicalweb; - -import static org.junit.Assert.assertEquals; - -import org.json.JSONException; -import org.json.JSONObject; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.BlockJUnit4ClassRunner; - -/** - * Tests for {@link UrlInfo}. - */ -@RunWith(BlockJUnit4ClassRunner.class) -public class UrlInfoTest { - private static final String URL = "https://example.com"; - private static final double EPSILON = .001; - UrlInfo mReferenceUrlInfo = null; - JSONObject mReferenceJsonObject = null; - - @Before - public void setUp() throws JSONException { - mReferenceUrlInfo = new UrlInfo(URL, 99.5, 42) - .setHasBeenDisplayed() - .setDeviceAddress("00:11:22:33:AA:BB"); - // Because we can't print JSON sorted by keys, the order is important here. - mReferenceJsonObject = new JSONObject("{" - + " \"url\": \"" + URL + "\"," - + " \"distance\": 99.5," - + " \"first_seen_timestamp\": 42," - + " \"device_address\": \"00:11:22:33:AA:BB\"," - + " \"has_been_displayed\": true" - + "}"); - } - - @Test - public void testJsonSerializeWorks() throws JSONException { - assertEquals(mReferenceJsonObject.toString(), mReferenceUrlInfo.jsonSerialize().toString()); - } - - @Test - public void testJsonDeserializeWorks() throws JSONException { - UrlInfo urlInfo = UrlInfo.jsonDeserialize(mReferenceJsonObject); - assertEquals(mReferenceUrlInfo.getUrl(), urlInfo.getUrl()); - assertEquals(mReferenceUrlInfo.getDistance(), urlInfo.getDistance(), EPSILON); - assertEquals(mReferenceUrlInfo.getFirstSeenTimestamp(), urlInfo.getFirstSeenTimestamp()); - assertEquals(mReferenceUrlInfo.getDeviceAddress(), urlInfo.getDeviceAddress()); - assertEquals(mReferenceUrlInfo.hasBeenDisplayed(), urlInfo.hasBeenDisplayed()); - } -}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0eeacab..cac10a78 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -2226,16 +2226,13 @@ Pop-ups were blocked on this page. </message> <message name="IDS_BLOCKED_POPUPS_TITLE" desc="Bubble title when a page is not allowed to display popups."> - Pop-ups blocked + Pop-ups blocked: </message> - <message name="IDS_BLOCKED_POPUPS_MESSAGE" desc="Bubble info header text when a page is not allowed to display popups. This appears above a list of popup titles."> - The following pop-ups were blocked on this page: + <message name="IDS_BLOCKED_POPUPS_REDIRECTS_UNBLOCK" desc="Radio button choice to unblock a site from showing popups and redirects, displayed in bubble when a page tries to display popups or redirects."> + Always allow pop-ups and redirects from <ph name="HOST">$1<ex>mail.google.com</ex></ph> </message> - <message name="IDS_BLOCKED_POPUPS_UNBLOCK" desc="Radio button choice to unblock a site from showing popups, displayed in bubble when a page tries to display popups."> - Always allow pop-ups from <ph name="HOST">$1<ex>mail.google.com</ex></ph> - </message> - <message name="IDS_BLOCKED_POPUPS_NO_ACTION" desc="Radio button choice to continue blocking a site from showing popups, displayed in bubble when a page tries to display popups."> - Continue blocking pop-ups + <message name="IDS_BLOCKED_POPUPS_REDIRECTS_NO_ACTION" desc="Radio button choice to continue blocking a site from showing popups and redirects, displayed in bubble when a page tries to display popups or redirects."> + Continue blocking </message> <message name="IDS_BLOCKED_POPUPS_LINK" desc="Link to popups section of content blocking management dialog, displayed in bubble when a page tries to display popups."> Manage pop-up blocking... @@ -5508,18 +5505,6 @@ <message name="IDS_MEDIA_MENU_NO_DEVICE_TITLE" desc="The title of the media select menu if there is no microphone or camera available on the machine"> None available </message> - <message name="IDS_POPUP_TAB_LABEL" desc="Label for Pop-up Windows tab on Content Settings dialog"> - Pop-ups - </message> - <message name="IDS_POPUP_HEADER" desc="Header for popup exception management page on Content Settings dialog"> - Pop-up exceptions - </message> - <message name="IDS_POPUP_ALLOW_RADIO" desc="A radio button in the Content Settings dialog for allowing pop-up windows in the browser."> - Allow all sites to show pop-ups - </message> - <message name="IDS_POPUP_BLOCK_RADIO" desc="A radio button in the Content Settings dialog for preventing showing pop-up windows on any sites."> - Do not allow any site to show pop-ups (recommended) - </message> <if expr="is_android"> <message name="IDS_POPUPS_BLOCKED_INFOBAR_BUTTON_SHOW" desc="Pop-up Blocking Show Button [CHAR-LIMIT=32]"> Always show @@ -10488,7 +10473,7 @@ <if expr="not is_android"> <!-- Android strings are declared in android_chrome_strings.grd. --> <message name="IDS_REDIRECT_BLOCKED_MESSAGE" desc="The message stating that a redirect (noun) was blocked on this page. This will be followed on a separate line with the address the user was being redirected to."> - Redirect blocked to site + Redirect blocked: </message> <if expr="use_titlecase"> <message name="IDS_REDIRECT_BLOCKED_GOT_IT" desc="In Title Case: The text of the OK button for the blocked redirect dialog.">
diff --git a/chrome/app/nibs/ContentBlockedPopups.xib b/chrome/app/nibs/ContentBlockedPopups.xib index 4a1b0b0..b243b33 100644 --- a/chrome/app/nibs/ContentBlockedPopups.xib +++ b/chrome/app/nibs/ContentBlockedPopups.xib
@@ -87,11 +87,11 @@ </buttonCell> <cells> <column> - <buttonCell type="radio" title="^IDS_BLOCKED_POPUPS_UNBLOCK" imagePosition="left" alignment="left" controlSize="small" tag="1" inset="2" id="10"> + <buttonCell type="radio" title="^IDS_BLOCKED_POPUPS_REDIRECTS_UNBLOCK" imagePosition="left" alignment="left" controlSize="small" tag="1" inset="2" id="10"> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <font key="font" metaFont="smallSystem"/> </buttonCell> - <buttonCell type="radio" title="^IDS_BLOCKED_POPUPS_NO_ACTION" imagePosition="left" alignment="left" controlSize="small" state="on" tag="2" inset="2" id="11"> + <buttonCell type="radio" title="^IDS_BLOCKED_POPUPS_REDIRECTS_NO_ACTION" imagePosition="left" alignment="left" controlSize="small" state="on" tag="2" inset="2" id="11"> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <font key="font" metaFont="smallSystem"/> </buttonCell>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 4999301..85eb15a 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -2637,8 +2637,8 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_PDF_DOWNLOAD_PDFS" desc="Label for downloading PDF documents instead of automatically opening them in Chrome."> Download PDF files instead of automatically opening them in Chrome </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_POPUPS" desc="Label for the popups site settings."> - Popups + <message name="IDS_SETTINGS_SITE_SETTINGS_POPUPS" desc="Label for the pop-ups and redirects site settings."> + Pop-ups and redirects </message> <message name="IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT" desc="Label for the protected content site settings."> Protected content
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 80b379e..0b6c312 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2637,6 +2637,8 @@ "resource_coordinator/discard_metrics_lifecycle_unit_observer.cc", "resource_coordinator/discard_metrics_lifecycle_unit_observer.h", "resource_coordinator/discard_reason.h", + "resource_coordinator/leveldb_site_characteristics_database.cc", + "resource_coordinator/leveldb_site_characteristics_database.h", "resource_coordinator/lifecycle_unit.cc", "resource_coordinator/lifecycle_unit.h", "resource_coordinator/lifecycle_unit_base.cc", @@ -2655,9 +2657,15 @@ "resource_coordinator/local_site_characteristics_data_store.h", "resource_coordinator/local_site_characteristics_data_writer.cc", "resource_coordinator/local_site_characteristics_data_writer.h", + "resource_coordinator/local_site_characteristics_database.h", "resource_coordinator/local_site_characteristics_feature_usage.h", + "resource_coordinator/local_site_characteristics_non_recording_data_store.cc", + "resource_coordinator/local_site_characteristics_non_recording_data_store.h", + "resource_coordinator/local_site_characteristics_noop_data_writer.cc", + "resource_coordinator/local_site_characteristics_noop_data_writer.h", "resource_coordinator/site_characteristics_data_reader.h", "resource_coordinator/site_characteristics_data_store.h", + "resource_coordinator/site_characteristics_data_writer.h", "resource_coordinator/tab_activity_watcher.cc", "resource_coordinator/tab_activity_watcher.h", "resource_coordinator/tab_features.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2375e9f..3411b7a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1871,29 +1871,12 @@ {"enable-chrome-duplex", flag_descriptions::kChromeDuplexName, flag_descriptions::kChromeDuplexDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kChromeDuplexFeature)}, - {"enable-chrome-home-bottom-sheet-inactivity-expansion", - flag_descriptions::kChromeHomeInactivitySheetExpansionName, - flag_descriptions::kChromeHomeInactivitySheetExpansionDescription, - kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kChromeHomeInactivitySheetExpansion)}, {"chrome-home-swipe-logic", flag_descriptions::kChromeHomeSwipeLogicName, flag_descriptions::kChromeHomeSwipeLogicDescription, kOsAndroid, MULTI_VALUE_TYPE(kChromeHomeSwipeLogicChoices)}, - {"enable-chrome-home-persistent-iph", - flag_descriptions::kChromeHomePersistentIphName, - flag_descriptions::kChromeHomePersistentIphDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kChromeHomePersistentIph)}, - {"enable-chrome-home-pull-to-refresh-iph-at-top", - flag_descriptions::kChromeHomePullToRefreshIphAtTopName, - flag_descriptions::kChromeHomePullToRefreshIphAtTopDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kChromeHomePullToRefreshIphAtTop)}, {"enable-chrome-memex", flag_descriptions::kChromeMemexName, flag_descriptions::kChromeMemexDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kChromeMemexFeature)}, - {"enable-chrome-home-survey", - flag_descriptions::kChromeHomeEnableSurveyName, - flag_descriptions::kChromeHomeEnableSurveyDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kChromeHomeSurvey)}, {"enable-chrome-modern-design", flag_descriptions::kChromeModernDesignName, flag_descriptions::kChromeModernDesignDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kChromeModernDesign)}, @@ -2237,6 +2220,9 @@ {"vr-browsing-in-custom-tab", flag_descriptions::kVrBrowsingInCustomTabName, flag_descriptions::kVrBrowsingInCustomTabDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kVrBrowsingInCustomTab)}, + {"vr-browsing-tabs-view", flag_descriptions::kVrBrowsingTabsViewName, + flag_descriptions::kVrBrowsingTabsViewDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kVrBrowsingTabsView)}, {"vr-icon-in-daydream-home", flag_descriptions::kVrIconInDaydreamHomeName, flag_descriptions::kVrIconInDaydreamHomeDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kVrIconInDaydreamHome)}, @@ -2926,7 +2912,7 @@ kEnableAutofillCreditCardUploadGooglePayOnAndroidBrandingDescription, kOsAndroid, FEATURE_VALUE_TYPE( - autofill::features::kAutofillUpstreamUseGooglePayOnAndroidBranding)}, + autofill::features::kAutofillUpstreamUseGooglePayBrandingOnMobile)}, {"enable-autofill-credit-card-upload-send-detected-values", flag_descriptions::kEnableAutofillCreditCardUploadSendDetectedValuesName, flag_descriptions:: @@ -3573,11 +3559,6 @@ flag_descriptions::kAshEnablePersistentWindowBoundsName, flag_descriptions::kAshEnablePersistentWindowBoundsDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kPersistentWindowBounds)}, - - {"ash-enable-mode-specific-power-button", - flag_descriptions::kAshEnableModeSpecificPowerButtonName, - flag_descriptions::kAshEnableModeSpecificPowerButtonDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kModeSpecificPowerButton)}, #endif // OS_CHROMEOS {"clipboard-content-setting",
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index a14b35a..5c15f6621 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -70,9 +70,6 @@ &kCCTPostMessageAPI, &kCCTRedirectPreconnect, &kChromeDuplexFeature, - &kChromeHomeInactivitySheetExpansion, - &kChromeHomePersistentIph, - &kChromeHomePullToRefreshIphAtTop, &kChromeHomeSwipeLogic, &kChromeHomeSwipeLogicVelocity, &kChromeSmartSelection, @@ -200,18 +197,6 @@ const base::Feature kChromeDuplexFeature{"ChromeDuplex", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kChromeHomeInactivitySheetExpansion{ - "ChromeHomeInactivitySheetExpansion", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kChromeHomePersistentIph{"ChromeHomePersistentIph", - base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kChromeHomePullToRefreshIphAtTop{ - "ChromeHomePullToRefreshIphAtTop", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kChromeHomeSurvey{"ChromeHomeSurvey", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kChromeHomeSwipeLogic{"ChromeHomeSwipeLogic", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -386,6 +371,9 @@ const base::Feature kVrBrowsingNativeAndroidUi{ "VrBrowsingNativeAndroidUi", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kVrBrowsingTabsView{"VrBrowsingTabsView", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kVrIconInDaydreamHome{"VrIconInDaydreamHome", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index b24bba6e..1c101234 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -23,10 +23,6 @@ extern const base::Feature kCCTPostMessageAPI; extern const base::Feature kCCTRedirectPreconnect; extern const base::Feature kChromeDuplexFeature; -extern const base::Feature kChromeHomeInactivitySheetExpansion; -extern const base::Feature kChromeHomePersistentIph; -extern const base::Feature kChromeHomePullToRefreshIphAtTop; -extern const base::Feature kChromeHomeSurvey; extern const base::Feature kChromeHomeSwipeLogic; extern const base::Feature kChromeHomeSwipeLogicVelocity; extern const base::Feature kChromeMemexFeature; @@ -83,6 +79,7 @@ extern const base::Feature kVrBrowsingFeedback; extern const base::Feature kVrBrowsingInCustomTab; extern const base::Feature kVrBrowsingNativeAndroidUi; +extern const base::Feature kVrBrowsingTabsView; extern const base::Feature kVrIconInDaydreamHome; extern const base::Feature kWebVrAutopresentFromIntent; extern const base::Feature kWebVrCardboardSupport;
diff --git a/chrome/browser/android/preferences/preferences_launcher.cc b/chrome/browser/android/preferences/preferences_launcher.cc index c2c139a..36b0817 100644 --- a/chrome/browser/android/preferences/preferences_launcher.cc +++ b/chrome/browser/android/preferences/preferences_launcher.cc
@@ -12,9 +12,10 @@ namespace chrome { namespace android { -void PreferencesLauncher::ShowAutofillSettings() { +void PreferencesLauncher::ShowAutofillSettings( + content::WebContents* web_contents) { Java_PreferencesLauncher_showAutofillSettings( - base::android::AttachCurrentThread()); + base::android::AttachCurrentThread(), web_contents->GetJavaWebContents()); } void PreferencesLauncher::ShowPasswordSettings() {
diff --git a/chrome/browser/android/preferences/preferences_launcher.h b/chrome/browser/android/preferences/preferences_launcher.h index 80e8091..1c3b14bf 100644 --- a/chrome/browser/android/preferences/preferences_launcher.h +++ b/chrome/browser/android/preferences/preferences_launcher.h
@@ -7,13 +7,17 @@ #include "base/macros.h" +namespace content { +class WebContents; +} + namespace chrome { namespace android { class PreferencesLauncher { public: // Opens the autofill settings page. - static void ShowAutofillSettings(); + static void ShowAutofillSettings(content::WebContents* web_contents); // Opens the password settings page. static void ShowPasswordSettings();
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index 0d6629d..399313b 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -18,6 +18,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "base/values.h" +#include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/android/vr/android_ui_gesture_target.h" #include "chrome/browser/android/vr/autocomplete_controller.h" @@ -1350,6 +1351,8 @@ base::FeatureList::IsEnabled(features::kVrBrowsingExperimentalRendering); ui_initial_state.assets_supported = AssetsLoader::AssetsSupported(); ui_initial_state.is_standalone_vr_device = is_standalone_vr_device; + ui_initial_state.create_tabs_view = + base::FeatureList::IsEnabled(chrome::android::kVrBrowsingTabsView); return reinterpret_cast<intptr_t>(new VrShell( env, obj, ui_initial_state,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 8163a71..e967ceab 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -276,6 +276,7 @@ #include "sandbox/win/src/sandbox_policy.h" #elif defined(OS_MACOSX) #include "chrome/browser/chrome_browser_main_mac.h" +#include "services/audio/public/mojom/constants.mojom.h" #include "services/video_capture/public/mojom/constants.mojom.h" #elif defined(OS_CHROMEOS) #include "ash/public/interfaces/constants.mojom.h" @@ -2099,9 +2100,11 @@ #endif // BUILDFLAG(ENABLE_MUS) #if defined(OS_MACOSX) - // On Mac, the video-capture service requires a CFRunLoop, provided by a UI - // message loop, to run AVFoundation code. See https://crbug.com/834581 - if (identity.name() == video_capture::mojom::kServiceName) + // On Mac, the video-capture and audio services require a CFRunLoop, provided + // by a UI message loop, to run AVFoundation and CoreAudio code. + // See https://crbug.com/834581 + if (identity.name() == video_capture::mojom::kServiceName || + identity.name() == audio::mojom::kServiceName) command_line->AppendSwitch(switches::kMessageLoopTypeUi); #endif }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 1cb4bcd..d9e30c7 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -21,6 +21,7 @@ configs += [ "//build/config/compiler:wexit_time_destructors" ] public_deps = [ + "//ash/resources", "//ash/strings", "//chrome:extra_resources", "//chrome:resources", @@ -2179,6 +2180,7 @@ ":attestation_proto", ":test_support", "//ash", + "//ash/resources", "//base", "//chrome/common", "//chromeos/components/tether:test_support",
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index de58edd4..8912413b 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -170,7 +170,6 @@ ash::switches::kAshEnablePaletteOnAllDisplays, ash::switches::kAshTouchHud, ash::switches::kAuraLegacyPowerButton, - ash::switches::kForceClamshellPowerButton, ash::switches::kShowTaps, ash::switches::kShowViewsLogin, ash::switches::kShowWebUiLock,
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc index 3ef1e3e..357573f 100644 --- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc +++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -267,7 +267,7 @@ power_initial = power_limit; } - client_ = std::make_unique<policy::AutoEnrollmentClient>( + client_ = policy::AutoEnrollmentClient::CreateForFRE( base::Bind(&AutoEnrollmentController::UpdateState, weak_ptr_factory_.GetWeakPtr()), service, g_browser_process->local_state(),
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 800602b..0a1b368 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -814,8 +814,8 @@ protected: WizardControllerDeviceStateTest() : install_attributes_(ScopedStubInstallAttributes::CreateUnset()) { - fake_statistics_provider_.SetMachineStatistic(system::kSerialNumberKey, - "test"); + fake_statistics_provider_.SetMachineStatistic( + system::kSerialNumberKeyForTest, "test"); fake_statistics_provider_.SetMachineStatistic(system::kActivateDateKey, "2000-01"); }
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client.cc b/chrome/browser/chromeos/policy/auto_enrollment_client.cc index 790fcdf..dbdd947 100644 --- a/chrome/browser/chromeos/policy/auto_enrollment_client.cc +++ b/chrome/browser/chromeos/policy/auto_enrollment_client.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/optional.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/policy/server_backed_device_state.h" #include "chrome/common/chrome_content_client.h" @@ -34,6 +35,9 @@ namespace { +using EnrollmentCheckType = + em::DeviceAutoEnrollmentRequest::EnrollmentCheckType; + // UMA histogram names. const char kUMAProtocolTime[] = "Enterprise.AutoEnrollmentProtocolTime"; const char kUMAExtraTime[] = "Enterprise.AutoEnrollmentExtraTime"; @@ -62,7 +66,7 @@ dict->Remove(pref_path, NULL); } -// Converts a restore mode enum value from the DM protocol into the +// Converts a restore mode enum value from the DM protocol for FRE into the // corresponding prefs string constant. std::string ConvertRestoreMode( em::DeviceStateRetrievalResponse::RestoreMode restore_mode) { @@ -84,33 +88,278 @@ return std::string(); } +// Converts an initial enrollment mode enum value from the DM protocol for +// initial enrollment into the corresponding prefs string constant. Note that we +// use the |kDeviceStateRestoreMode*| constants on the client for simplicity, +// because every initial enrollment mode has a matching restore mode (but not +// vice versa). +std::string ConvertInitialEnrollmentMode( + em::DeviceInitialEnrollmentStateResponse::InitialEnrollmentMode + initial_enrollment_mode) { + switch (initial_enrollment_mode) { + case em::DeviceInitialEnrollmentStateResponse::INITIAL_ENROLLMENT_MODE_NONE: + return std::string(); + case em::DeviceInitialEnrollmentStateResponse:: + INITIAL_ENROLLMENT_MODE_ENROLLMENT_ENFORCED: + return kDeviceStateRestoreModeReEnrollmentEnforced; + } +} + } // namespace -AutoEnrollmentClient::AutoEnrollmentClient( - const ProgressCallback& callback, - DeviceManagementService* service, +// Subclasses of this class provide an identifier and specify the identifier +// set for the DeviceAutoEnrollmentRequest, +class AutoEnrollmentClient::DeviceIdentifierProvider { + public: + virtual ~DeviceIdentifierProvider() {} + + // Should return the EnrollmentCheckType to be used in the + // DeviceAutoEnrollmentRequest. This specifies the identifier set used on + // the server. + virtual enterprise_management::DeviceAutoEnrollmentRequest:: + EnrollmentCheckType + GetEnrollmentCheckType() const = 0; + + // Should return the hash of this device's identifier. The + // DeviceAutoEnrollmentRequest exchange will check if this hash is in the + // server-side identifier set specified by |GetEnrollmentCheckType()| + virtual const std::string& GetIdHash() const = 0; +}; + +// Subclasses of this class generate the request to download the device state +// (after determining that there is server-side device state) and parse the +// response. +class AutoEnrollmentClient::StateDownloadMessageProcessor { + public: + virtual ~StateDownloadMessageProcessor() {} + + // Returns the request job type. This must match the request filled in + // |FillRequest|. + virtual DeviceManagementRequestJob::JobType GetJobType() const = 0; + + // Fills the specific request type in |request|. + virtual void FillRequest( + enterprise_management::DeviceManagementRequest* request) = 0; + + // Parses the |response|. If it is valid, extracts |restore_mode|, + // |management_domain| and |disabled_message| and returns true. Otherwise, + // returns false. + virtual bool ParseResponse( + const enterprise_management::DeviceManagementResponse& response, + std::string* restore_mode, + base::Optional<std::string>* management_domain, + base::Optional<std::string>* disabled_message) = 0; +}; + +namespace { + +// Provides device identifier for Forced Re-Enrollment (FRE), where the +// server-backed state key is used. +class DeviceIdentifierProviderFRE + : public AutoEnrollmentClient::DeviceIdentifierProvider { + public: + explicit DeviceIdentifierProviderFRE( + const std::string& server_backed_state_key) { + CHECK(!server_backed_state_key.empty()); + server_backed_state_key_hash_ = + crypto::SHA256HashString(server_backed_state_key); + } + + EnrollmentCheckType GetEnrollmentCheckType() const override { + return em::DeviceAutoEnrollmentRequest::ENROLLMENT_CHECK_TYPE_FRE; + } + + const std::string& GetIdHash() const override { + return server_backed_state_key_hash_; + } + + private: + // SHA-256 digest of the stable identifier. + std::string server_backed_state_key_hash_; +}; + +// Provides device identifier for Forced Initial Enrollment, where the brand +// code and serial number is used. +class DeviceIdentifierProviderInitialEnrollment + : public AutoEnrollmentClient::DeviceIdentifierProvider { + public: + DeviceIdentifierProviderInitialEnrollment( + const std::string& device_serial_number, + const std::string& device_brand_code) { + CHECK(!device_serial_number.empty()); + CHECK(!device_brand_code.empty()); + // The hash for initial enrollment is the first 8 bytes of + // SHA256(<brnad_code>_<serial_number>). + id_hash_ = + crypto::SHA256HashString(device_brand_code + "_" + device_serial_number) + .substr(0, 8); + } + + EnrollmentCheckType GetEnrollmentCheckType() const override { + return em::DeviceAutoEnrollmentRequest:: + ENROLLMENT_CHECK_TYPE_FORCED_ENROLLMENT; + } + + const std::string& GetIdHash() const override { return id_hash_; } + + private: + // 8-byte Hash built from serial number and brand code passed to the + // constructor. + std::string id_hash_; +}; + +// Handles DeviceStateRetrievalRequest / DeviceStateRetrievalResponse for +// Forced Re-Enrollment (FRE). +class StateDownloadMessageProcessorFRE + : public AutoEnrollmentClient::StateDownloadMessageProcessor { + public: + explicit StateDownloadMessageProcessorFRE( + const std::string& server_backed_state_key) + : server_backed_state_key_(server_backed_state_key) {} + + DeviceManagementRequestJob::JobType GetJobType() const override { + return DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL; + } + + void FillRequest(em::DeviceManagementRequest* request) override { + request->mutable_device_state_retrieval_request() + ->set_server_backed_state_key(server_backed_state_key_); + } + + bool ParseResponse(const em::DeviceManagementResponse& response, + std::string* restore_mode, + base::Optional<std::string>* management_domain, + base::Optional<std::string>* disabled_message) override { + if (!response.has_device_state_retrieval_response()) { + LOG(ERROR) << "Server failed to provide auto-enrollment response."; + return false; + } + const em::DeviceStateRetrievalResponse& state_response = + response.device_state_retrieval_response(); + *restore_mode = ConvertRestoreMode(state_response.restore_mode()); + if (state_response.has_management_domain()) + *management_domain = state_response.management_domain(); + else + management_domain->reset(); + + if (state_response.has_disabled_state()) + *disabled_message = state_response.disabled_state().message(); + else + disabled_message->reset(); + + // Logging as "WARNING" to make sure it's preserved in the logs. + LOG(WARNING) << "Received restore_mode=" << state_response.restore_mode(); + + return true; + } + + private: + // Stable state key. + std::string server_backed_state_key_; +}; + +// Handles DeviceInitialEnrollmentStateRequest / +// DeviceInitialEnrollmentStateResponse for Forced Initial Enrollment. +class StateDownloadMessageProcessorInitialEnrollment + : public AutoEnrollmentClient::StateDownloadMessageProcessor { + public: + StateDownloadMessageProcessorInitialEnrollment( + const std::string& device_serial_number, + const std::string& device_brand_code) + : device_serial_number_(device_serial_number), + device_brand_code_(device_brand_code) {} + + DeviceManagementRequestJob::JobType GetJobType() const override { + return DeviceManagementRequestJob::TYPE_INITIAL_ENROLLMENT_STATE_RETRIEVAL; + } + + void FillRequest(em::DeviceManagementRequest* request) override { + auto* inner_request = + request->mutable_device_initial_enrollment_state_request(); + inner_request->set_brand_code(device_brand_code_); + inner_request->set_serial_number(device_serial_number_); + } + + bool ParseResponse(const em::DeviceManagementResponse& response, + std::string* restore_mode, + base::Optional<std::string>* management_domain, + base::Optional<std::string>* disabled_message) override { + if (!response.has_device_initial_enrollment_state_response()) { + LOG(ERROR) << "Server failed to provide initial enrollment response."; + return false; + } + + const em::DeviceInitialEnrollmentStateResponse& state_response = + response.device_initial_enrollment_state_response(); + if (state_response.has_initial_enrollment_mode()) { + *restore_mode = ConvertInitialEnrollmentMode( + state_response.initial_enrollment_mode()); + } else { + // Unknown initial enrollment mode - treat as no enrollment. + *restore_mode = std::string(); + } + + if (state_response.has_management_domain()) + *management_domain = state_response.management_domain(); + else + management_domain->reset(); + + // Device disabling is not supported in initial forced enrollment. + disabled_message->reset(); + + // Logging as "WARNING" to make sure it's preserved in the logs. + LOG(WARNING) << "Received initial_enrollment_mode=" + << state_response.initial_enrollment_mode(); + + return true; + } + + private: + // Serial number of the device. + std::string device_serial_number_; + // 4-character brand code of the device. + std::string device_brand_code_; +}; + +} // namespace + +// static +std::unique_ptr<AutoEnrollmentClient> AutoEnrollmentClient::CreateForFRE( + const ProgressCallback& progress_callback, + DeviceManagementService* device_management_service, PrefService* local_state, scoped_refptr<net::URLRequestContextGetter> system_request_context, const std::string& server_backed_state_key, int power_initial, - int power_limit) - : progress_callback_(callback), - state_(AUTO_ENROLLMENT_STATE_IDLE), - has_server_state_(false), - device_state_available_(false), - device_id_(base::GenerateGUID()), - server_backed_state_key_(server_backed_state_key), - current_power_(power_initial), - power_limit_(power_limit), - modulus_updates_received_(0), - device_management_service_(service), - local_state_(local_state), - request_context_(system_request_context) { - DCHECK_LE(current_power_, power_limit_); - DCHECK(!progress_callback_.is_null()); - CHECK(!server_backed_state_key_.empty()); - server_backed_state_key_hash_ = - crypto::SHA256HashString(server_backed_state_key_); + int power_limit) { + return base::WrapUnique(new AutoEnrollmentClient( + progress_callback, device_management_service, local_state, + system_request_context, + std::make_unique<DeviceIdentifierProviderFRE>(server_backed_state_key), + std::make_unique<StateDownloadMessageProcessorFRE>( + server_backed_state_key), + power_initial, power_limit)); +} + +// static +std::unique_ptr<AutoEnrollmentClient> +AutoEnrollmentClient::CreateForInitialEnrollment( + const ProgressCallback& progress_callback, + DeviceManagementService* device_management_service, + PrefService* local_state, + scoped_refptr<net::URLRequestContextGetter> system_request_context, + const std::string& device_serial_number, + const std::string& device_brand_code, + int power_initial, + int power_limit) { + return base::WrapUnique(new AutoEnrollmentClient( + progress_callback, device_management_service, local_state, + system_request_context, + std::make_unique<DeviceIdentifierProviderInitialEnrollment>( + device_serial_number, device_brand_code), + std::make_unique<StateDownloadMessageProcessorInitialEnrollment>( + device_serial_number, device_brand_code), + power_initial, power_limit)); } AutoEnrollmentClient::~AutoEnrollmentClient() { @@ -164,6 +413,34 @@ } } +AutoEnrollmentClient::AutoEnrollmentClient( + const ProgressCallback& callback, + DeviceManagementService* service, + PrefService* local_state, + scoped_refptr<net::URLRequestContextGetter> system_request_context, + std::unique_ptr<DeviceIdentifierProvider> device_identifier_provider, + std::unique_ptr<StateDownloadMessageProcessor> + state_download_message_processor, + int power_initial, + int power_limit) + : progress_callback_(callback), + state_(AUTO_ENROLLMENT_STATE_IDLE), + has_server_state_(false), + device_state_available_(false), + device_id_(base::GenerateGUID()), + current_power_(power_initial), + power_limit_(power_limit), + modulus_updates_received_(0), + device_management_service_(service), + local_state_(local_state), + request_context_(system_request_context), + device_identifier_provider_(std::move(device_identifier_provider)), + state_download_message_processor_( + std::move(state_download_message_processor)) { + DCHECK_LE(current_power_, power_limit_); + DCHECK(!progress_callback_.is_null()); +} + bool AutoEnrollmentClient::GetCachedDecision() { const PrefService::Preference* has_server_state_pref = local_state_->FindPreference(prefs::kShouldAutoEnroll); @@ -241,11 +518,16 @@ } void AutoEnrollmentClient::SendBucketDownloadRequest() { - // Only power-of-2 moduli are supported for now. These are computed by taking - // the lower |current_power_| bits of the hash. + std::string id_hash = device_identifier_provider_->GetIdHash(); + // Currently AutoEnrollmentClient supports working with hashes that are at + // least 8 bytes long. If this is reduced, the computation of the remainder + // must also be adapted to handle the case of a shorter hash gracefully. + DCHECK_GE(id_hash.size(), 8u); + uint64_t remainder = 0; + const size_t last_byte_index = id_hash.size() - 1; for (int i = 0; 8 * i < current_power_; ++i) { - uint64_t byte = server_backed_state_key_hash_[31 - i] & 0xff; + uint64_t byte = id_hash[last_byte_index - i] & 0xff; remainder = remainder | (byte << (8 * i)); } remainder = remainder & ((UINT64_C(1) << current_power_) - 1); @@ -262,6 +544,8 @@ request_job_->GetRequest()->mutable_auto_enrollment_request(); request->set_remainder(remainder); request->set_modulus(INT64_C(1) << current_power_); + request->set_enrollment_check_type( + device_identifier_provider_->GetEnrollmentCheckType()); request_job_->Start( base::Bind(&AutoEnrollmentClient::HandleRequestCompletion, base::Unretained(this), @@ -271,15 +555,10 @@ void AutoEnrollmentClient::SendDeviceStateRequest() { ReportProgress(AUTO_ENROLLMENT_STATE_PENDING); - VLOG(1) << "State request for key: " << server_backed_state_key_; - request_job_.reset( - device_management_service_->CreateJob( - DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL, - request_context_.get())); + request_job_.reset(device_management_service_->CreateJob( + state_download_message_processor_->GetJobType(), request_context_.get())); request_job_->SetClientID(device_id_); - em::DeviceStateRetrievalRequest* request = - request_job_->GetRequest()->mutable_device_state_retrieval_request(); - request->set_server_backed_state_key(server_backed_state_key_); + state_download_message_processor_->FillRequest(request_job_->GetRequest()); request_job_->Start( base::Bind(&AutoEnrollmentClient::HandleRequestCompletion, base::Unretained(this), @@ -377,45 +656,41 @@ bool AutoEnrollmentClient::OnDeviceStateRequestCompletion( DeviceManagementStatus status, int net_error, - const enterprise_management::DeviceManagementResponse& response) { - bool progress = false; - if (!response.has_device_state_retrieval_response()) { - LOG(ERROR) << "Server failed to provide auto-enrollment response."; - } else { - const em::DeviceStateRetrievalResponse& state_response = - response.device_state_retrieval_response(); - { - DictionaryPrefUpdate dict(local_state_, prefs::kServerBackedDeviceState); - UpdateDict( - dict.Get(), kDeviceStateManagementDomain, - state_response.has_management_domain(), - std::make_unique<base::Value>(state_response.management_domain())); + const em::DeviceManagementResponse& response) { + std::string restore_mode; + base::Optional<std::string> management_domain; + base::Optional<std::string> disabled_message; - std::string restore_mode = - ConvertRestoreMode(state_response.restore_mode()); - UpdateDict(dict.Get(), kDeviceStateRestoreMode, !restore_mode.empty(), - std::make_unique<base::Value>(restore_mode)); + bool progress = state_download_message_processor_->ParseResponse( + response, &restore_mode, &management_domain, &disabled_message); + if (!progress) + return false; - UpdateDict(dict.Get(), kDeviceStateDisabledMessage, - state_response.has_disabled_state(), - std::make_unique<base::Value>( - state_response.disabled_state().message())); + { + DictionaryPrefUpdate dict(local_state_, prefs::kServerBackedDeviceState); + UpdateDict(dict.Get(), kDeviceStateManagementDomain, + management_domain.has_value(), + std::make_unique<base::Value>( + management_domain.value_or(std::string()))); - // Logging as "WARNING" to make sure it's preserved in the logs. - LOG(WARNING) << "Received restore_mode=" << state_response.restore_mode(); - } - local_state_->CommitPendingWrite(); - device_state_available_ = true; - progress = true; + UpdateDict(dict.Get(), kDeviceStateRestoreMode, !restore_mode.empty(), + std::make_unique<base::Value>(restore_mode)); + + UpdateDict(dict.Get(), kDeviceStateDisabledMessage, + disabled_message.has_value(), + std::make_unique<base::Value>( + disabled_message.value_or(std::string()))); } - - return progress; + local_state_->CommitPendingWrite(); + device_state_available_ = true; + return true; } bool AutoEnrollmentClient::IsIdHashInProtobuf( const google::protobuf::RepeatedPtrField<std::string>& hashes) { + std::string id_hash = device_identifier_provider_->GetIdHash(); for (int i = 0; i < hashes.size(); ++i) { - if (hashes.Get(i) == server_backed_state_key_hash_) + if (hashes.Get(i) == id_hash) return true; } return false;
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client.h b/chrome/browser/chromeos/policy/auto_enrollment_client.h index 36800d9..1d267df3 100644 --- a/chrome/browser/chromeos/policy/auto_enrollment_client.h +++ b/chrome/browser/chromeos/policy/auto_enrollment_client.h
@@ -13,6 +13,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/time/time.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "net/base/network_change_notifier.h" @@ -31,8 +32,8 @@ namespace policy { -class DeviceManagementRequestJob; class DeviceManagementService; +class DeviceManagementRequestJob; // Indicates the current state of the auto-enrollment check. (Numeric values // are just to make reading of log files easier.) @@ -64,15 +65,24 @@ // and the max is 2^62 (when the moduli are restricted to powers-of-2). static const int kMaximumPower = 62; + // Subclasses of this class provide an identifier and specify the identifier + // set for the DeviceAutoEnrollmentRequest, + class DeviceIdentifierProvider; + + // Subclasses of this class generate the request to download the device state + // (after determining that there is server-side device state) and parse the + // response. + class StateDownloadMessageProcessor; + // Used for signaling progress to a consumer. - typedef base::Callback<void(AutoEnrollmentState)> ProgressCallback; + typedef base::RepeatingCallback<void(AutoEnrollmentState)> ProgressCallback; // |progress_callback| will be invoked whenever some significant event happens // as part of the protocol, after Start() is invoked. // The result of the protocol will be cached in |local_state|. // |power_initial| and |power_limit| are exponents of power-of-2 values which // will be the initial modulus and the maximum modulus used by this client. - AutoEnrollmentClient( + static std::unique_ptr<AutoEnrollmentClient> CreateForFRE( const ProgressCallback& progress_callback, DeviceManagementService* device_management_service, PrefService* local_state, @@ -80,6 +90,22 @@ const std::string& server_backed_state_key, int power_initial, int power_limit); + + // |progress_callback| will be invoked whenever some significant event happens + // as part of the protocol, after Start() is invoked. + // The result of the protocol will be cached in |local_state|. + // |power_initial| and |power_limit| are exponents of power-of-2 values which + // will be the initial modulus and the maximum modulus used by this client. + static std::unique_ptr<AutoEnrollmentClient> CreateForInitialEnrollment( + const ProgressCallback& progress_callback, + DeviceManagementService* device_management_service, + PrefService* local_state, + scoped_refptr<net::URLRequestContextGetter> system_request_context, + const std::string& device_serial_number, + const std::string& device_brand_code, + int power_initial, + int power_limit); + ~AutoEnrollmentClient() override; // Registers preferences in local state. @@ -116,6 +142,17 @@ int, const enterprise_management::DeviceManagementResponse&); + AutoEnrollmentClient( + const ProgressCallback& progress_callback, + DeviceManagementService* device_management_service, + PrefService* local_state, + scoped_refptr<net::URLRequestContextGetter> system_request_context, + std::unique_ptr<DeviceIdentifierProvider> device_identifier_provider, + std::unique_ptr<StateDownloadMessageProcessor> + state_download_message_processor, + int power_initial, + int power_limit); + // Tries to load the result of a previous execution of the protocol from // local state. Returns true if that decision has been made and is valid. bool GetCachedDecision(); @@ -157,7 +194,8 @@ int net_error, const enterprise_management::DeviceManagementResponse& response); - // Returns true if |server_backed_state_key_hash_| is contained in |hashes|. + // Returns true if the identifier hash provided by + // |device_identifier_provider_| is contained in |hashes|. bool IsIdHashInProtobuf( const google::protobuf::RepeatedPtrField<std::string>& hashes); @@ -181,10 +219,6 @@ // Randomly generated device id for the auto-enrollment requests. std::string device_id_; - // Stable state key and its SHA-256 digest. - std::string server_backed_state_key_; - std::string server_backed_state_key_hash_; - // Power-of-2 modulus to try next. int current_power_; @@ -206,6 +240,14 @@ // The request context to use to perform the auto enrollment request. scoped_refptr<net::URLRequestContextGetter> request_context_; + // Specifies the identifier set and the hash of the device's current + // identifier. + std::unique_ptr<DeviceIdentifierProvider> device_identifier_provider_; + + // Fills and parses state retrieval request / response. + std::unique_ptr<StateDownloadMessageProcessor> + state_download_message_processor_; + // Times used to determine the duration of the protocol, and the extra time // needed to complete after the signin was complete. // If |time_start_| is not null, the protocol is still running.
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc b/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc index 0b83cd4..b7f56a5 100644 --- a/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc +++ b/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc
@@ -41,12 +41,22 @@ "\xb3\x4a\x5e\xff\x73\x7e\x92\xd9\xf8\x6e\x72\x44\xd0\x97\xc3\xe6"; const char kDisabledMessage[] = "This device has been disabled."; +const char kSerialNumber[] = "SN123456"; +const char kBrandCode[] = "AABC"; +const char kInitialEnrollmentIdHash[] = "\x30\x18\xb7\x0f\x76\x09\xc5\xc7"; + +const int kInitialEnrollmentIdHashLength = 8; + using ::testing::InSequence; using ::testing::Mock; using ::testing::SaveArg; using ::testing::_; -class AutoEnrollmentClientTest : public testing::Test { +enum class AutoEnrollmentProtocol { kFRE, kInitialEnrollment }; + +class AutoEnrollmentClientTest + : public testing::Test, + public ::testing::WithParamInterface<AutoEnrollmentProtocol> { protected: AutoEnrollmentClientTest() : scoped_testing_local_state_( @@ -55,7 +65,7 @@ state_(AUTO_ENROLLMENT_STATE_PENDING) {} void SetUp() override { - CreateClient(kStateKey, 4, 8); + CreateClient(4, 8); ASSERT_FALSE(local_state_->GetUserPref(prefs::kShouldAutoEnroll)); ASSERT_FALSE(local_state_->GetUserPref(prefs::kAutoEnrollmentPowerLimit)); } @@ -65,19 +75,25 @@ base::RunLoop().RunUntilIdle(); } - void CreateClient(const std::string& state_key, - int power_initial, - int power_limit) { + void CreateClient(int power_initial, int power_limit) { state_ = AUTO_ENROLLMENT_STATE_PENDING; service_.reset(new MockDeviceManagementService()); EXPECT_CALL(*service_, StartJob(_, _, _, _, _, _)) .WillRepeatedly(SaveArg<5>(&last_request_)); - client_.reset(new AutoEnrollmentClient( - base::Bind(&AutoEnrollmentClientTest::ProgressCallback, - base::Unretained(this)), - service_.get(), local_state_, new net::TestURLRequestContextGetter( - base::ThreadTaskRunnerHandle::Get()), - state_key, power_initial, power_limit)); + auto progress_callback = base::BindRepeating( + &AutoEnrollmentClientTest::ProgressCallback, base::Unretained(this)); + auto* url_request_context_getter = new net::TestURLRequestContextGetter( + base::ThreadTaskRunnerHandle::Get()); + if (GetParam() == AutoEnrollmentProtocol::kFRE) { + client_ = AutoEnrollmentClient::CreateForFRE( + progress_callback, service_.get(), local_state_, + url_request_context_getter, kStateKey, power_initial, power_limit); + } else { + client_ = AutoEnrollmentClient::CreateForInitialEnrollment( + progress_callback, service_.get(), local_state_, + url_request_context_getter, kSerialNumber, kBrandCode, power_initial, + power_limit); + } } void ProgressCallback(AutoEnrollmentState state) { @@ -100,23 +116,75 @@ if (with_hashes) { for (int i = 0; i < 10; ++i) { std::string state_key = base::StringPrintf("state_key %d", i); - std::string hash = crypto::SHA256HashString(state_key); + std::string hash_full = crypto::SHA256HashString(state_key); + std::string hash = + GetParam() == AutoEnrollmentProtocol::kFRE + ? hash_full + : hash_full.substr(0, kInitialEnrollmentIdHashLength); enrollment_response->mutable_hash()->Add()->assign(hash); } } if (with_id_hash) { - enrollment_response->mutable_hash()->Add()->assign(kStateKeyHash, - crypto::kSHA256Length); + if (GetParam() == AutoEnrollmentProtocol::kFRE) { + enrollment_response->mutable_hash()->Add()->assign( + kStateKeyHash, crypto::kSHA256Length); + } else { + enrollment_response->mutable_hash()->Add()->assign( + kInitialEnrollmentIdHash, kInitialEnrollmentIdHashLength); + } } EXPECT_CALL(*service_, CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, _)) .WillOnce(service_->SucceedJob(response)); } + em::DeviceInitialEnrollmentStateResponse::InitialEnrollmentMode + MapRestoreModeToInitialEnrollmentMode( + em::DeviceStateRetrievalResponse::RestoreMode restore_mode) { + using DeviceStateRetrieval = em::DeviceStateRetrievalResponse; + using DeviceInitialEnrollmentState = + em::DeviceInitialEnrollmentStateResponse; + + switch (restore_mode) { + case DeviceStateRetrieval::RESTORE_MODE_NONE: + return DeviceInitialEnrollmentState::INITIAL_ENROLLMENT_MODE_NONE; + case DeviceStateRetrieval::RESTORE_MODE_REENROLLMENT_REQUESTED: + return DeviceInitialEnrollmentState::INITIAL_ENROLLMENT_MODE_NONE; + case DeviceStateRetrieval::RESTORE_MODE_REENROLLMENT_ENFORCED: + return DeviceInitialEnrollmentState:: + INITIAL_ENROLLMENT_MODE_ENROLLMENT_ENFORCED; + case DeviceStateRetrieval::RESTORE_MODE_DISABLED: + return DeviceInitialEnrollmentState::INITIAL_ENROLLMENT_MODE_NONE; + case DeviceStateRetrieval::RESTORE_MODE_REENROLLMENT_ZERO_TOUCH: + return DeviceInitialEnrollmentState::INITIAL_ENROLLMENT_MODE_NONE; + } + } + void ServerWillSendState( const std::string& management_domain, em::DeviceStateRetrievalResponse::RestoreMode restore_mode, const std::string& device_disabled_message) { + if (GetParam() == AutoEnrollmentProtocol::kFRE) { + ServerWillSendFREState(management_domain, restore_mode, + device_disabled_message); + } else { + ServerWillSendInitialEnrollmentState( + management_domain, + MapRestoreModeToInitialEnrollmentMode(restore_mode)); + } + } + + DeviceManagementRequestJob::JobType GetStateRetrievalJobType() { + return GetParam() == AutoEnrollmentProtocol::kFRE + ? DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL + : DeviceManagementRequestJob:: + TYPE_INITIAL_ENROLLMENT_STATE_RETRIEVAL; + } + + void ServerWillSendFREState( + const std::string& management_domain, + em::DeviceStateRetrievalResponse::RestoreMode restore_mode, + const std::string& device_disabled_message) { em::DeviceManagementResponse response; em::DeviceStateRetrievalResponse* state_response = response.mutable_device_state_retrieval_response(); @@ -124,9 +192,20 @@ state_response->set_management_domain(management_domain); state_response->mutable_disabled_state()->set_message( device_disabled_message); - EXPECT_CALL( - *service_, - CreateJob(DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL, _)) + EXPECT_CALL(*service_, CreateJob(GetStateRetrievalJobType(), _)) + .WillOnce(service_->SucceedJob(response)); + } + + void ServerWillSendInitialEnrollmentState( + const std::string& management_domain, + em::DeviceInitialEnrollmentStateResponse::InitialEnrollmentMode + initial_enrollment_mode) { + em::DeviceManagementResponse response; + em::DeviceInitialEnrollmentStateResponse* state_response = + response.mutable_device_initial_enrollment_state_response(); + state_response->set_initial_enrollment_mode(initial_enrollment_mode); + state_response->set_management_domain(management_domain); + EXPECT_CALL(*service_, CreateJob(GetStateRetrievalJobType(), _)) .WillOnce(service_->SucceedJob(response)); } @@ -178,9 +257,14 @@ } std::string actual_disabled_message; - EXPECT_TRUE(state_dict->GetString(kDeviceStateDisabledMessage, - &actual_disabled_message)); - EXPECT_EQ(expected_disabled_message, actual_disabled_message); + if (GetParam() == AutoEnrollmentProtocol::kFRE) { + EXPECT_TRUE(state_dict->GetString(kDeviceStateDisabledMessage, + &actual_disabled_message)); + EXPECT_EQ(expected_disabled_message, actual_disabled_message); + } else { + EXPECT_FALSE(state_dict->GetString(kDeviceStateDisabledMessage, + &actual_disabled_message)); + } } const em::DeviceAutoEnrollmentRequest& auto_enrollment_request() { @@ -199,7 +283,7 @@ DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentClientTest); }; -TEST_F(AutoEnrollmentClientTest, NetworkFailure) { +TEST_P(AutoEnrollmentClientTest, NetworkFailure) { ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_); @@ -207,7 +291,7 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, EmptyReply) { +TEST_P(AutoEnrollmentClientTest, EmptyReply) { ServerWillReply(-1, false, false); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); @@ -215,7 +299,7 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, ClientUploadsRightBits) { +TEST_P(AutoEnrollmentClientTest, ClientUploadsRightBits) { ServerWillReply(-1, false, false); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); @@ -223,12 +307,17 @@ EXPECT_TRUE(auto_enrollment_request().has_remainder()); EXPECT_TRUE(auto_enrollment_request().has_modulus()); EXPECT_EQ(16, auto_enrollment_request().modulus()); - EXPECT_EQ(kStateKeyHash[31] & 0xf, auto_enrollment_request().remainder()); + if (GetParam() == AutoEnrollmentProtocol::kFRE) { + EXPECT_EQ(kStateKeyHash[31] & 0xf, auto_enrollment_request().remainder()); + } else { + EXPECT_EQ(kInitialEnrollmentIdHash[7] & 0xf, + auto_enrollment_request().remainder()); + } VerifyCachedResult(false, 8); EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, AskForMoreThenFail) { +TEST_P(AutoEnrollmentClientTest, AskForMoreThenFail) { InSequence sequence; ServerWillReply(32, false, false); ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE); @@ -238,7 +327,7 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, AskForMoreThenEvenMore) { +TEST_P(AutoEnrollmentClientTest, AskForMoreThenEvenMore) { InSequence sequence; ServerWillReply(32, false, false); ServerWillReply(64, false, false); @@ -248,7 +337,7 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, AskForLess) { +TEST_P(AutoEnrollmentClientTest, AskForLess) { InSequence sequence; ServerWillReply(8, false, false); ServerWillReply(-1, true, true); @@ -264,7 +353,7 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, AskForSame) { +TEST_P(AutoEnrollmentClientTest, AskForSame) { InSequence sequence; ServerWillReply(16, false, false); ServerWillReply(-1, true, true); @@ -280,7 +369,7 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, AskForSameTwice) { +TEST_P(AutoEnrollmentClientTest, AskForSameTwice) { InSequence sequence; ServerWillReply(16, false, false); ServerWillReply(16, false, false); @@ -290,7 +379,7 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, AskForTooMuch) { +TEST_P(AutoEnrollmentClientTest, AskForTooMuch) { ServerWillReply(512, false, false); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_); @@ -298,7 +387,7 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, AskNonPowerOf2) { +TEST_P(AutoEnrollmentClientTest, AskNonPowerOf2) { InSequence sequence; ServerWillReply(100, false, false); ServerWillReply(-1, false, false); @@ -307,12 +396,17 @@ EXPECT_TRUE(auto_enrollment_request().has_remainder()); EXPECT_TRUE(auto_enrollment_request().has_modulus()); EXPECT_EQ(128, auto_enrollment_request().modulus()); - EXPECT_EQ(kStateKeyHash[31] & 0x7f, auto_enrollment_request().remainder()); + if (GetParam() == AutoEnrollmentProtocol::kFRE) { + EXPECT_EQ(kStateKeyHash[31] & 0x7f, auto_enrollment_request().remainder()); + } else { + EXPECT_EQ(kInitialEnrollmentIdHash[7] & 0x7f, + auto_enrollment_request().remainder()); + } VerifyCachedResult(false, 8); EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, ConsumerDevice) { +TEST_P(AutoEnrollmentClientTest, ConsumerDevice) { ServerWillReply(-1, true, false); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); @@ -325,7 +419,7 @@ EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); } -TEST_F(AutoEnrollmentClientTest, ForcedReEnrollment) { +TEST_P(AutoEnrollmentClientTest, ForcedReEnrollment) { ServerWillReply(-1, true, true); ServerWillSendState( "example.com", @@ -344,7 +438,11 @@ EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_); } -TEST_F(AutoEnrollmentClientTest, ForcedReEnrollmentZeroTouch) { +TEST_P(AutoEnrollmentClientTest, ForcedReEnrollmentZeroTouch) { + // Zero-Touch is currently not supported in the initial-enrollment exchange. + if (GetParam() == AutoEnrollmentProtocol::kInitialEnrollment) + return; + ServerWillReply(-1, true, true); ServerWillSendState( "example.com", @@ -363,7 +461,12 @@ EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ZERO_TOUCH, state_); } -TEST_F(AutoEnrollmentClientTest, RequestedReEnrollment) { +TEST_P(AutoEnrollmentClientTest, RequestedReEnrollment) { + // Requesting re-enrollment is currently not supported in the + // initial-enrollment exchange. + if (GetParam() == AutoEnrollmentProtocol::kInitialEnrollment) + return; + ServerWillReply(-1, true, true); ServerWillSendState( "example.com", @@ -377,12 +480,15 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, DeviceDisabled) { +TEST_P(AutoEnrollmentClientTest, DeviceDisabled) { + // Disabling is currently not supported in the initial-enrollment exchange. + if (GetParam() == AutoEnrollmentProtocol::kInitialEnrollment) + return; + ServerWillReply(-1, true, true); - ServerWillSendState( - "example.com", - em::DeviceStateRetrievalResponse::RESTORE_MODE_DISABLED, - kDisabledMessage); + ServerWillSendState("example.com", + em::DeviceStateRetrievalResponse::RESTORE_MODE_DISABLED, + kDisabledMessage); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); VerifyCachedResult(true, 8); @@ -391,8 +497,8 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, NoBitsUploaded) { - CreateClient(kStateKey, 0, 0); +TEST_P(AutoEnrollmentClientTest, NoBitsUploaded) { + CreateClient(0, 0); ServerWillReply(-1, false, false); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); @@ -404,10 +510,12 @@ EXPECT_FALSE(HasServerBackedState()); } -TEST_F(AutoEnrollmentClientTest, ManyBitsUploaded) { - int64_t bottom62 = INT64_C(0x386e7244d097c3e6); +TEST_P(AutoEnrollmentClientTest, ManyBitsUploaded) { + int64_t bottom62 = GetParam() == AutoEnrollmentProtocol::kFRE + ? INT64_C(0x386e7244d097c3e6) + : INT64_C(0x3018b70f7609c5c7); for (int i = 0; i <= 62; ++i) { - CreateClient(kStateKey, i, i); + CreateClient(i, i); ServerWillReply(-1, false, false); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_); @@ -421,8 +529,8 @@ } } -TEST_F(AutoEnrollmentClientTest, MoreThan32BitsUploaded) { - CreateClient(kStateKey, 10, 37); +TEST_P(AutoEnrollmentClientTest, MoreThan32BitsUploaded) { + CreateClient(10, 37); InSequence sequence; ServerWillReply(INT64_C(1) << 37, false, false); ServerWillReply(-1, true, true); @@ -438,7 +546,7 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, ReuseCachedDecision) { +TEST_P(AutoEnrollmentClientTest, ReuseCachedDecision) { // No bucket download requests should be issued. EXPECT_CALL(*service_, CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, _)) @@ -463,12 +571,12 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, RetryIfPowerLargerThanCached) { +TEST_P(AutoEnrollmentClientTest, RetryIfPowerLargerThanCached) { local_state_->SetUserPref(prefs::kShouldAutoEnroll, std::make_unique<base::Value>(false)); local_state_->SetUserPref(prefs::kAutoEnrollmentPowerLimit, std::make_unique<base::Value>(8)); - CreateClient(kStateKey, 5, 10); + CreateClient(5, 10); ServerWillReply(-1, true, true); ServerWillSendState( "example.com", @@ -481,7 +589,7 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, NetworkChangeRetryAfterErrors) { +TEST_P(AutoEnrollmentClientTest, NetworkChangeRetryAfterErrors) { ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE); client_->Start(); // Don't invoke the callback if there was a network failure. @@ -518,7 +626,7 @@ kDisabledMessage); } -TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonWithPendingRequest) { +TEST_P(AutoEnrollmentClientTest, CancelAndDeleteSoonWithPendingRequest) { MockDeviceManagementJob* job = NULL; ServerWillReplyAsync(&job); EXPECT_FALSE(job); @@ -539,7 +647,7 @@ EXPECT_EQ(AUTO_ENROLLMENT_STATE_PENDING, state_); } -TEST_F(AutoEnrollmentClientTest, NetworkChangedAfterCancelAndDeleteSoon) { +TEST_P(AutoEnrollmentClientTest, NetworkChangedAfterCancelAndDeleteSoon) { MockDeviceManagementJob* job = NULL; ServerWillReplyAsync(&job); EXPECT_FALSE(job); @@ -569,7 +677,7 @@ EXPECT_EQ(AUTO_ENROLLMENT_STATE_PENDING, state_); } -TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonAfterCompletion) { +TEST_P(AutoEnrollmentClientTest, CancelAndDeleteSoonAfterCompletion) { ServerWillReply(-1, true, true); ServerWillSendState( "example.com", @@ -588,7 +696,7 @@ EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting()); } -TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonAfterNetworkFailure) { +TEST_P(AutoEnrollmentClientTest, CancelAndDeleteSoonAfterNetworkFailure) { ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE); client_->Start(); EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_); @@ -600,7 +708,7 @@ EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting()); } -TEST_F(AutoEnrollmentClientTest, NetworkFailureThenRequireUpdatedModulus) { +TEST_P(AutoEnrollmentClientTest, NetworkFailureThenRequireUpdatedModulus) { // This test verifies that if the first request fails due to a network // problem then the second request will correctly handle an updated // modulus request from the server. @@ -637,5 +745,13 @@ Mock::VerifyAndClearExpectations(service_.get()); } +INSTANTIATE_TEST_CASE_P(FRE, + AutoEnrollmentClientTest, + testing::Values(AutoEnrollmentProtocol::kFRE)); +INSTANTIATE_TEST_CASE_P( + InitialEnrollment, + AutoEnrollmentClientTest, + testing::Values(AutoEnrollmentProtocol::kInitialEnrollment)); + } // namespace } // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc index d4c79c0..c0f5fbd 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc
@@ -50,7 +50,7 @@ &statistics_provider_) { RegisterLocalState(local_state_.registry()); statistics_provider_.SetMachineStatistic( - chromeos::system::kSerialNumberKey, "fake-serial"); + chromeos::system::kSerialNumberKeyForTest, "fake-serial"); statistics_provider_.SetMachineStatistic( chromeos::system::kHardwareClassKey, "fake-hardware"); }
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc index a1d832eb..8ecf4c6 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -120,7 +120,7 @@ state_keys_broker_(&fake_session_manager_client_), store_(NULL) { fake_statistics_provider_.SetMachineStatistic( - chromeos::system::kSerialNumberKey, "test_sn"); + chromeos::system::kSerialNumberKeyForTest, "test_sn"); fake_statistics_provider_.SetMachineStatistic( chromeos::system::kHardwareClassKey, "test_hw"); std::vector<std::string> state_keys;
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc index a5c1bbb..14aeda3 100644 --- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc +++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -239,7 +239,7 @@ void SetUp() override { fake_statistics_provider_.SetMachineStatistic( - chromeos::system::kSerialNumberKey, kFakeSerialNumber); + chromeos::system::kSerialNumberKeyForTest, kFakeSerialNumber); EXPECT_CALL(provider_, IsInitializationComplete(_)) .WillRepeatedly(Return(false));
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc index 4ee9b0b..c923b2d6 100644 --- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc +++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
@@ -84,7 +84,7 @@ public: EnterpriseDeviceAttributesTest() { fake_statistics_provider_.SetMachineStatistic( - chromeos::system::kSerialNumberKey, kSerialNumber); + chromeos::system::kSerialNumberKeyForTest, kSerialNumber); set_exit_when_last_browser_closes(false); set_chromeos_user_ = false; }
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 7ee175d..21ba554e 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -74,18 +74,6 @@ namespace extensions { -namespace { - -// Used in histograms; do not change order. -enum OffStoreInstallDecision { - OnStoreInstall, - OffStoreInstallAllowed, - OffStoreInstallDisallowed, - NumOffStoreInstallDecision -}; - -} // namespace - // static scoped_refptr<CrxInstaller> CrxInstaller::CreateSilent( ExtensionService* frontend) { @@ -395,34 +383,17 @@ l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_NOT_ENABLED)); } - if (install_cause_ == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) { - // TODO(devlin): It appears that these histograms are never logged. We - // should either add them to histograms.xml or delete them. - const char kHistogramName[] = "Extensions.OffStoreInstallDecisionHard"; - if (is_gallery_install()) { - UMA_HISTOGRAM_ENUMERATION(kHistogramName, - OffStoreInstallDecision::OnStoreInstall, - NumOffStoreInstallDecision); - } else if (off_store_install_allow_reason_ != OffStoreInstallDisallowed) { - UMA_HISTOGRAM_ENUMERATION(kHistogramName, - OffStoreInstallDecision::OffStoreInstallAllowed, - NumOffStoreInstallDecision); - UMA_HISTOGRAM_ENUMERATION("Extensions.OffStoreInstallAllowReason", - off_store_install_allow_reason_, - NumOffStoreInstallAllowReasons); - } else { - UMA_HISTOGRAM_ENUMERATION( - kHistogramName, OffStoreInstallDecision::OffStoreInstallDisallowed, - NumOffStoreInstallDecision); - // Don't delete source in this case so that the user can install - // manually if they want. - delete_source_ = false; - did_handle_successfully_ = false; + if (install_cause_ == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD && + !is_gallery_install() && + off_store_install_allow_reason_ == OffStoreInstallDisallowed) { + // Don't delete source in this case so that the user can install + // manually if they want. + delete_source_ = false; + did_handle_successfully_ = false; - return CrxInstallError( - CrxInstallError::ERROR_OFF_STORE, - l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE)); - } + return CrxInstallError( + CrxInstallError::ERROR_OFF_STORE, + l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE)); } if (extension_->is_app()) {
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc index 9620496e..08fc33b 100644 --- a/chrome/browser/extensions/extension_service_sync_unittest.cc +++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/extensions/extension_sync_data.h" #include "chrome/browser/extensions/extension_sync_service.h" #include "chrome/browser/extensions/extension_util.h" -#include "chrome/browser/extensions/scripting_permissions_modifier.h" #include "chrome/browser/extensions/test_blacklist.h" #include "chrome/browser/extensions/updater/extension_updater.h" #include "chrome/browser/sync/profile_sync_service_factory.h" @@ -78,7 +77,6 @@ using extensions::ExtensionSystem; using extensions::Manifest; using extensions::PermissionSet; -using extensions::ScriptingPermissionsModifier; using extensions::WebstorePrivateIsPendingCustodianApprovalFunction; using syncer::SyncChange; using syncer::SyncChangeList; @@ -101,9 +99,8 @@ bool incognito_enabled = false; bool remote_install = false; bool installed_by_custodian = false; - base::Optional<bool> has_all_urls; return ExtensionSyncData(extension, enabled, disable_reasons, - incognito_enabled, remote_install, has_all_urls, + incognito_enabled, remote_install, installed_by_custodian); } @@ -112,10 +109,9 @@ bool incognito_enabled = false; bool remote_install = false; bool installed_by_custodian = false; - base::Optional<bool> has_all_urls; return ExtensionSyncData( extension, enabled, extensions::disable_reason::DISABLE_NONE, - incognito_enabled, remote_install, has_all_urls, installed_by_custodian); + incognito_enabled, remote_install, installed_by_custodian); } SyncChangeList MakeSyncChangeList(const std::string& id, @@ -371,7 +367,7 @@ // Then sync data arrives telling us to disable |good0|. ExtensionSyncData disable_good_crx( *extension, false, extensions::disable_reason::DISABLE_USER_ACTION, false, - false, base::nullopt, false); + false, false); SyncChangeList list( 1, disable_good_crx.GetSyncChange(SyncChange::ACTION_UPDATE)); extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); @@ -565,10 +561,10 @@ // Now sync data comes in that says to disable good0 and enable good2. ExtensionSyncData disable_good0( *extension0, false, extensions::disable_reason::DISABLE_USER_ACTION, - false, false, base::nullopt, false); + false, false, false); ExtensionSyncData enable_good2(*extension2, true, extensions::disable_reason::DISABLE_NONE, - false, false, base::nullopt, false); + false, false, false); syncer::SyncDataList sync_data; sync_data.push_back(disable_good0.GetSyncData()); sync_data.push_back(enable_good2.GetSyncData()); @@ -620,7 +616,7 @@ // Disable the extension. ExtensionSyncData data(*extension, false, extensions::disable_reason::DISABLE_USER_ACTION, - false, false, base::nullopt, false); + false, false, false); SyncChangeList list(1, data.GetSyncChange(SyncChange::ACTION_UPDATE)); extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); @@ -635,7 +631,7 @@ // Set incognito enabled to true. ExtensionSyncData data(*extension, false, extensions::disable_reason::DISABLE_NONE, true, - false, base::nullopt, false); + false, false); SyncChangeList list(1, data.GetSyncChange(SyncChange::ACTION_UPDATE)); extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); @@ -652,7 +648,7 @@ *extension, false, extensions::disable_reason::DISABLE_USER_ACTION | extensions::disable_reason::DISABLE_PERMISSIONS_INCREASE, - false, false, base::nullopt, false); + false, false, false); SyncChangeList list(1, data.GetSyncChange(SyncChange::ACTION_UPDATE)); extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); @@ -669,7 +665,7 @@ *extension, false, extensions::disable_reason::DISABLE_USER_ACTION | extensions::disable_reason::DISABLE_PERMISSIONS_INCREASE, - false, false, base::nullopt, false); + false, false, false); SyncChangeList list(1, data.GetSyncChange(SyncChange::ACTION_DELETE)); extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); @@ -700,7 +696,6 @@ EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled()); EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()), data->incognito_enabled()); - EXPECT_EQ(base::nullopt, data->all_urls_enabled()); EXPECT_EQ(data->version(), extension->version()); EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension), data->update_url()); @@ -808,7 +803,6 @@ EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled()); EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()), data->incognito_enabled()); - EXPECT_EQ(base::nullopt, data->all_urls_enabled()); EXPECT_EQ(data->version(), extension->version()); EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension), data->update_url()); @@ -851,7 +845,6 @@ ASSERT_TRUE(data.get()); EXPECT_TRUE(data->enabled()); EXPECT_FALSE(data->incognito_enabled()); - EXPECT_EQ(base::nullopt, data->all_urls_enabled()); } service()->DisableExtension(good_crx, @@ -865,14 +858,9 @@ ASSERT_TRUE(data.get()); EXPECT_FALSE(data->enabled()); EXPECT_FALSE(data->incognito_enabled()); - EXPECT_EQ(base::nullopt, data->all_urls_enabled()); } extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true); - ScriptingPermissionsModifier permissions_modifier( - profile(), registry()->GetExtensionById( - good_crx, extensions::ExtensionRegistry::EVERYTHING)); - permissions_modifier.SetAllowedOnAllUrls(false); { syncer::SyncDataList list = extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); @@ -882,11 +870,9 @@ ASSERT_TRUE(data.get()); EXPECT_FALSE(data->enabled()); EXPECT_TRUE(data->incognito_enabled()); - EXPECT_EQ(base::Optional<bool>(false), data->all_urls_enabled()); } service()->EnableExtension(good_crx); - permissions_modifier.SetAllowedOnAllUrls(true); { syncer::SyncDataList list = extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); @@ -896,7 +882,6 @@ ASSERT_TRUE(data.get()); EXPECT_TRUE(data->enabled()); EXPECT_TRUE(data->incognito_enabled()); - EXPECT_EQ(base::Optional<bool>(true), data->all_urls_enabled()); } } @@ -1146,19 +1131,6 @@ InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); - // Returns a ScriptingPermissionsModifier for the extension. We use this - // because various parts of this test reload the extension, making keeping a - // ptr to it inviable. - auto get_permissions_modifier = [this]() { - const Extension* extension = registry()->GetExtensionById( - good_crx, extensions::ExtensionRegistry::EVERYTHING); - return std::make_unique<ScriptingPermissionsModifier>(profile(), extension); - }; - EXPECT_FALSE(get_permissions_modifier()->HasSetAllowedOnAllUrls()); - const bool kDefaultAllowedScripting = - ScriptingPermissionsModifier::DefaultAllowedOnAllUrls(); - EXPECT_EQ(kDefaultAllowedScripting, - get_permissions_modifier()->IsAllowedOnAllUrls()); sync_pb::EntitySpecifics specifics; sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); @@ -1174,9 +1146,6 @@ extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); - EXPECT_FALSE(get_permissions_modifier()->HasSetAllowedOnAllUrls()); - EXPECT_EQ(kDefaultAllowedScripting, - get_permissions_modifier()->IsAllowedOnAllUrls()); } { @@ -1205,29 +1174,12 @@ { ext_specifics->set_enabled(true); - ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting); SyncChangeList list = MakeSyncChangeList(good_crx, specifics, SyncChange::ACTION_UPDATE); extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); - EXPECT_TRUE(get_permissions_modifier()->HasSetAllowedOnAllUrls()); - EXPECT_EQ(!kDefaultAllowedScripting, - get_permissions_modifier()->IsAllowedOnAllUrls()); - } - - { - ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting); - - SyncChangeList list = - MakeSyncChangeList(good_crx, specifics, SyncChange::ACTION_UPDATE); - - extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); - EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); - EXPECT_TRUE(get_permissions_modifier()->HasSetAllowedOnAllUrls()); - EXPECT_EQ(kDefaultAllowedScripting, - get_permissions_modifier()->IsAllowedOnAllUrls()); } EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx)); @@ -2563,47 +2515,6 @@ registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1])); } -TEST_F(ExtensionServiceSyncTest, SyncExtensionHasAllhostsWithheld) { - InitializeEmptyExtensionService(); - StartSyncing(syncer::EXTENSIONS); - - // Create an extension that needs all-hosts. - const std::string kName("extension"); - scoped_refptr<const Extension> extension = - extensions::ExtensionBuilder(kName) - .SetLocation(Manifest::INTERNAL) - .AddPermission("*://*/*") - .Build(); - - // Install and enable it. - service()->AddExtension(extension.get()); - service()->GrantPermissionsAndEnableExtension(extension.get()); - const std::string id = extension->id(); - EXPECT_TRUE(registry()->enabled_extensions().GetByID(id)); - - // Simulate a sync node coming in where the extension had all-hosts withheld. - // This means that it should have all-hosts withheld on this machine, too. - sync_pb::EntitySpecifics specifics; - sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); - ext_specifics->set_id(id); - ext_specifics->set_name(kName); - ext_specifics->set_version("1.0"); - ext_specifics->set_all_urls_enabled(false); - ext_specifics->set_enabled(true); - - SyncChangeList list = - MakeSyncChangeList(id, specifics, SyncChange::ACTION_UPDATE); - - extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); - - const Extension* enabled_extension = - registry()->enabled_extensions().GetByID(id); - ASSERT_TRUE(enabled_extension); - ScriptingPermissionsModifier modifier(profile(), enabled_extension); - EXPECT_FALSE(modifier.IsAllowedOnAllUrls()); - EXPECT_TRUE(modifier.HasSetAllowedOnAllUrls()); -} - #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) // Tests sync behavior in the case of an item that starts out as an app and
diff --git a/chrome/browser/extensions/extension_sync_data.cc b/chrome/browser/extensions/extension_sync_data.cc index f6b4ed0..2b24159 100644 --- a/chrome/browser/extensions/extension_sync_data.cc +++ b/chrome/browser/extensions/extension_sync_data.cc
@@ -87,14 +87,12 @@ int disable_reasons, bool incognito_enabled, bool remote_install, - base::Optional<bool> all_urls_enabled, bool installed_by_custodian) : ExtensionSyncData(extension, enabled, disable_reasons, incognito_enabled, remote_install, - all_urls_enabled, installed_by_custodian, StringOrdinal(), StringOrdinal(), @@ -105,7 +103,6 @@ int disable_reasons, bool incognito_enabled, bool remote_install, - base::Optional<bool> all_urls_enabled, bool installed_by_custodian, const StringOrdinal& app_launch_ordinal, const StringOrdinal& page_ordinal, @@ -118,7 +115,6 @@ disable_reasons_(disable_reasons), incognito_enabled_(incognito_enabled), remote_install_(remote_install), - all_urls_enabled_(all_urls_enabled), installed_by_custodian_(installed_by_custodian), version_(extension.from_bookmark() ? base::Version("0") : extension.version()), @@ -196,8 +192,6 @@ specifics->set_disable_reasons(disable_reasons_); specifics->set_incognito_enabled(incognito_enabled_); specifics->set_remote_install(remote_install_); - if (all_urls_enabled_.has_value()) - specifics->set_all_urls_enabled(*all_urls_enabled_); specifics->set_installed_by_custodian(installed_by_custodian_); specifics->set_name(name_); } @@ -278,13 +272,6 @@ supports_disable_reasons_ = specifics.has_disable_reasons(); disable_reasons_ = specifics.disable_reasons(); incognito_enabled_ = specifics.incognito_enabled(); - if (specifics.has_all_urls_enabled()) { - all_urls_enabled_ = specifics.all_urls_enabled(); - } else { - // Set this explicitly (even though it's the default) on the offchance - // that someone is re-using an ExtensionSyncData object. - all_urls_enabled_ = base::nullopt; - } remote_install_ = specifics.remote_install(); installed_by_custodian_ = specifics.installed_by_custodian(); name_ = specifics.name();
diff --git a/chrome/browser/extensions/extension_sync_data.h b/chrome/browser/extensions/extension_sync_data.h index 9a17b64..9f79c87 100644 --- a/chrome/browser/extensions/extension_sync_data.h +++ b/chrome/browser/extensions/extension_sync_data.h
@@ -49,7 +49,6 @@ int disable_reasons, bool incognito_enabled, bool remote_install, - base::Optional<bool> all_urls_enabled, bool installed_by_custodian); // App constructor. ExtensionSyncData(const Extension& extension, @@ -57,7 +56,6 @@ int disable_reasons, bool incognito_enabled, bool remote_install, - base::Optional<bool> all_urls_enabled, bool installed_by_custodian, const syncer::StringOrdinal& app_launch_ordinal, const syncer::StringOrdinal& page_ordinal, @@ -90,7 +88,6 @@ int disable_reasons() const { return disable_reasons_; } bool incognito_enabled() const { return incognito_enabled_; } bool remote_install() const { return remote_install_; } - base::Optional<bool> all_urls_enabled() const { return all_urls_enabled_; } bool installed_by_custodian() const { return installed_by_custodian_; } // Version-dependent properties (i.e., should be used only when the @@ -156,7 +153,6 @@ int disable_reasons_; bool incognito_enabled_; bool remote_install_; - base::Optional<bool> all_urls_enabled_; bool installed_by_custodian_; base::Version version_; GURL update_url_;
diff --git a/chrome/browser/extensions/extension_sync_data_unittest.cc b/chrome/browser/extensions/extension_sync_data_unittest.cc index a823bddc..ba465d0 100644 --- a/chrome/browser/extensions/extension_sync_data_unittest.cc +++ b/chrome/browser/extensions/extension_sync_data_unittest.cc
@@ -59,9 +59,6 @@ EXPECT_EQ(input.incognito_enabled(), output.incognito_enabled()); EXPECT_EQ(input.remote_install(), output.remote_install()); EXPECT_EQ(input.installed_by_custodian(), output.installed_by_custodian()); - EXPECT_EQ(input.has_all_urls_enabled(), output.has_all_urls_enabled()); - if (input.has_all_urls_enabled()) - EXPECT_EQ(input.all_urls_enabled(), output.all_urls_enabled()); } // Serializes an ExtensionSyncData into a protobuf structure and back again, and @@ -78,7 +75,6 @@ EXPECT_EQ(input.incognito_enabled(), output->incognito_enabled()); EXPECT_EQ(input.remote_install(), output->remote_install()); EXPECT_EQ(input.installed_by_custodian(), output->installed_by_custodian()); - EXPECT_EQ(input.all_urls_enabled(), output->all_urls_enabled()); EXPECT_EQ(input.version(), output->version()); EXPECT_EQ(input.update_url(), output->update_url()); EXPECT_EQ(input.name(), output->name()); @@ -100,7 +96,6 @@ extension_specifics->set_incognito_enabled(true); extension_specifics->set_remote_install(false); extension_specifics->set_installed_by_custodian(false); - extension_specifics->set_all_urls_enabled(true); extension_specifics->set_version(kVersion); extension_specifics->set_name(kName); @@ -117,35 +112,21 @@ EXPECT_FALSE(extension_sync_data.enabled()); EXPECT_EQ(true, extension_sync_data.incognito_enabled()); EXPECT_FALSE(extension_sync_data.remote_install()); - EXPECT_EQ(base::Optional<bool>(true), extension_sync_data.all_urls_enabled()); EXPECT_EQ(base::Version(kVersion), extension_sync_data.version()); EXPECT_EQ(std::string(kName), extension_sync_data.name()); // Check the serialize-deserialize process for ExtensionSyncData to proto. SyncDataToProtobufEqual(extension_sync_data); - // The most important thing to test is the "all urls" bit, since it is a - // tri-state boolean (and thus has more logic). Also flip another bit for a - // sanity check. - extension_specifics->set_all_urls_enabled(false); + // Flip a bit and verify the result is correct. extension_specifics->set_incognito_enabled(false); ProtobufToSyncDataEqual(entity); extension_sync_data.PopulateFromExtensionSpecifics(*extension_specifics); - EXPECT_EQ(base::Optional<bool>(false), - extension_sync_data.all_urls_enabled()); EXPECT_FALSE(extension_sync_data.incognito_enabled()); SyncDataToProtobufEqual(extension_sync_data); - - extension_specifics->clear_all_urls_enabled(); ProtobufToSyncDataEqual(entity); - - extension_sync_data.PopulateFromExtensionSpecifics(*extension_specifics); - EXPECT_FALSE(extension_specifics->has_all_urls_enabled()); - EXPECT_FALSE(extension_sync_data.all_urls_enabled().has_value()); - - SyncDataToProtobufEqual(extension_sync_data); } class AppSyncDataTest : public testing::Test { @@ -162,7 +143,6 @@ extension_specifics->set_disable_reasons(kValidDisableReasons); extension_specifics->set_incognito_enabled(true); extension_specifics->set_remote_install(false); - extension_specifics->set_all_urls_enabled(true); extension_specifics->set_installed_by_custodian(false); extension_specifics->set_name(kName); }
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc index 9784710..57c43bb 100644 --- a/chrome/browser/extensions/extension_sync_service.cc +++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/extensions/extension_sync_service_factory.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/launch_util.h" -#include "chrome/browser/extensions/scripting_permissions_modifier.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/glue/sync_start_util.h" #include "chrome/common/buildflags.h" @@ -51,26 +50,6 @@ namespace { -// Returns the pref value for "all urls enabled" for the given extension id. -base::Optional<bool> GetAllowedOnAllUrlsValue( - const Extension& extension, - content::BrowserContext* context) { - extensions::ScriptingPermissionsModifier permissions_modifier(context, - &extension); - bool allowed_on_all_urls = permissions_modifier.IsAllowedOnAllUrls(); - // If the extension is not allowed on all urls (which is not the default), - // then we have to sync the preference. - if (!allowed_on_all_urls) - return false; - - // If the user has explicitly set a value, then we sync it. - if (permissions_modifier.HasSetAllowedOnAllUrls()) - return true; - - // Otherwise, unset. - return base::nullopt; -} - // Returns true if the sync type of |extension| matches |type|. bool IsCorrectSyncType(const Extension& extension, syncer::ModelType type) { return (type == syncer::EXTENSIONS && extension.is_extension()) || @@ -271,23 +250,21 @@ bool incognito_enabled = extensions::util::IsIncognitoEnabled(id, profile_); bool remote_install = extension_prefs->HasDisableReason( id, extensions::disable_reason::DISABLE_REMOTE_INSTALL); - base::Optional<bool> allowed_on_all_url = - GetAllowedOnAllUrlsValue(extension, profile_); bool installed_by_custodian = extensions::util::WasInstalledByCustodian(id, profile_); AppSorting* app_sorting = ExtensionSystem::Get(profile_)->app_sorting(); - ExtensionSyncData result = extension.is_app() - ? ExtensionSyncData( - extension, enabled, disable_reasons, incognito_enabled, - remote_install, allowed_on_all_url, - installed_by_custodian, - app_sorting->GetAppLaunchOrdinal(id), - app_sorting->GetPageOrdinal(id), - extensions::GetLaunchTypePrefValue(extension_prefs, id)) - : ExtensionSyncData( - extension, enabled, disable_reasons, incognito_enabled, - remote_install, allowed_on_all_url, installed_by_custodian); + ExtensionSyncData result = + extension.is_app() + ? ExtensionSyncData( + extension, enabled, disable_reasons, incognito_enabled, + remote_install, installed_by_custodian, + app_sorting->GetAppLaunchOrdinal(id), + app_sorting->GetPageOrdinal(id), + extensions::GetLaunchTypePrefValue(extension_prefs, id)) + : ExtensionSyncData(extension, enabled, disable_reasons, + incognito_enabled, remote_install, + installed_by_custodian); // If there's a pending update, send the new version to sync instead of the // installed one. @@ -481,13 +458,6 @@ id, profile_, extension_sync_data.incognito_enabled()); extension = nullptr; // No longer safe to use. - // Update the all urls flag. - if (extension_sync_data.all_urls_enabled().has_value()) { - bool allowed = *extension_sync_data.all_urls_enabled(); - extensions::ScriptingPermissionsModifier::SetAllowedOnAllUrlsForSync( - allowed, profile_, id); - } - // Set app-specific data. if (extension_sync_data.is_app()) { if (extension_sync_data.app_launch_ordinal().IsValid() &&
diff --git a/chrome/browser/extensions/extension_sync_service.h b/chrome/browser/extensions/extension_sync_service.h index efa3be4..12c12d8 100644 --- a/chrome/browser/extensions/extension_sync_service.h +++ b/chrome/browser/extensions/extension_sync_service.h
@@ -42,8 +42,7 @@ // Notifies Sync (if needed) of a newly-installed extension or a change to // an existing extension. Call this when you change an extension setting that - // is synced as part of ExtensionSyncData (e.g. incognito_enabled or - // all_urls_enabled). + // is synced as part of ExtensionSyncData (e.g. incognito_enabled). void SyncExtensionChangeIfNeeded(const extensions::Extension& extension); // Returns whether the extension with the given |id| will be re-enabled once
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 38f1910..00ce7a6 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1927,27 +1927,6 @@ const char kChromeDuplexDescription[] = "Enables Chrome Duplex, split toolbar Chrome Home, on Android."; -const char kChromeHomeEnableSurveyName[] = "Enable Chrome Home survey"; -const char kChromeHomeEnableSurveyDescription[] = - "If enabled, the survey process will allow surveys using sample " - "parameters."; - -const char kChromeHomeInactivitySheetExpansionName[] = - "Expansion of Chrome Home bottom sheet on startup"; -const char kChromeHomeInactivitySheetExpansionDescription[] = - "Expand bottom sheet on startup in Chrome Home after a period of" - " inactivity."; - -const char kChromeHomePersistentIphName[] = "Chrome Home Persistent Iph"; -const char kChromeHomePersistentIphDescription[] = - "Wait to dismiss the Chrome Home IPH until the user inteacts with the " - "toolbar or a timer expires."; - -const char kChromeHomePullToRefreshIphAtTopName[] = - "Chrome Home Pull-To-Refresh Iph At Top"; -const char kChromeHomePullToRefreshIphAtTopDescription[] = - "Show the Chrome Home pull-to-refresh help bubble at the top of the screen"; - const char kChromeHomeSwipeLogicName[] = "Chrome Home Swipe Logic"; const char kChromeHomeSwipeLogicDescription[] = "Various swipe logic options for Chrome Home for sheet expansion."; @@ -2386,6 +2365,10 @@ const char kVrBrowsingNativeAndroidUiDescription[] = "Enable Android UI elements in VR."; +const char kVrBrowsingTabsViewName[] = "VR browsing tabs view"; +const char kVrBrowsingTabsViewDescription[] = + "Enable tab overview (tab switcher) in VR."; + const char kThirdPartyDoodlesName[] = "Enable Doodles for third-party search engines"; const char kThirdPartyDoodlesDescription[] = @@ -3170,12 +3153,6 @@ const char kAshEnablePersistentWindowBoundsDescription[] = "Enable persistent window bounds in multi-displays scenario."; -const char kAshEnableModeSpecificPowerButtonName[] = - "Enable mode-specific power button behavior."; -const char kAshEnableModeSpecificPowerButtonDescription[] = - "Enable mode-specific power button behavior. While in tablet mode, tapping " - "the power button turns the display off."; - const char kAshEnableTrilinearFilteringName[] = "Enable trilinear filtering."; const char kAshEnableTrilinearFilteringDescription[] = "Enable trilinear filtering.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c6461aee..d328309 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1178,18 +1178,6 @@ extern const char kChromeDuplexName[]; extern const char kChromeDuplexDescription[]; -extern const char kChromeHomeEnableSurveyName[]; -extern const char kChromeHomeEnableSurveyDescription[]; - -extern const char kChromeHomeInactivitySheetExpansionName[]; -extern const char kChromeHomeInactivitySheetExpansionDescription[]; - -extern const char kChromeHomePersistentIphName[]; -extern const char kChromeHomePersistentIphDescription[]; - -extern const char kChromeHomePullToRefreshIphAtTopName[]; -extern const char kChromeHomePullToRefreshIphAtTopDescription[]; - extern const char kChromeHomeSwipeLogicName[]; extern const char kChromeHomeSwipeLogicDescription[]; extern const char kChromeHomeSwipeLogicRestrictArea[]; @@ -1448,6 +1436,9 @@ extern const char kVrBrowsingNativeAndroidUiName[]; extern const char kVrBrowsingNativeAndroidUiDescription[]; +extern const char kVrBrowsingTabsViewName[]; +extern const char kVrBrowsingTabsViewDescription[]; + extern const char kThirdPartyDoodlesName[]; extern const char kThirdPartyDoodlesDescription[]; @@ -1951,9 +1942,6 @@ extern const char kAshEnablePersistentWindowBoundsName[]; extern const char kAshEnablePersistentWindowBoundsDescription[]; -extern const char kAshEnableModeSpecificPowerButtonName[]; -extern const char kAshEnableModeSpecificPowerButtonDescription[]; - extern const char kAshEnableTrilinearFilteringName[]; extern const char kAshEnableTrilinearFilteringDescription[];
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index e47c404..4397c4a 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -803,9 +803,15 @@ } IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, Playback_Encryption_CBCS) { + // 'cbcs' decryption is only supported on CDM 10 or later as long as + // the appropriate buildflag is enabled. + std::string expected_result = + GetCdmInterfaceVersion() >= 10 && BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) + ? media::kEnded + : media::kError; TestMp4EncryptionPlayback(kExternalClearKeyKeySystem, "bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly, - media::kError); + expected_result); } #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index 1d281b0..f649626 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -606,6 +606,124 @@ } } +// Test certs cannot currently be installed on OSX with the network service +// enabled. +// TODO(mmenke): Once that is fixed, enable this test on OSX. +// See https://crbug.com/757088 +#if !defined(OS_MACOSX) + +// Visits a URL with an HSTS header, and makes sure it is respected. +IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, PRE_Hsts) { + net::test_server::EmbeddedTestServer ssl_server( + net::test_server::EmbeddedTestServer::TYPE_HTTPS); + ssl_server.SetSSLConfig( + net::test_server::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN); + ssl_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); + ASSERT_TRUE(ssl_server.Start()); + + // Make a request whose response has an STS header. + std::unique_ptr<network::ResourceRequest> request = + std::make_unique<network::ResourceRequest>(); + request->url = ssl_server.GetURL( + "/set-header?Strict-Transport-Security: max-age%3D600000"); + + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<network::SimpleURLLoader> simple_loader = + network::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory(), simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + EXPECT_EQ(net::OK, simple_loader->NetError()); + ASSERT_TRUE(simple_loader->ResponseInfo()->headers); + EXPECT_TRUE(simple_loader->ResponseInfo()->headers->HasHeaderValue( + "Strict-Transport-Security", "max-age=600000")); + + // Make a cache-only request to make sure the HSTS entry is respected. Using a + // cache-only request both prevents the result from being cached, and makes + // the check identical to the one in the next test, which is run after the + // test server has been shut down. + GURL exected_ssl_url = ssl_server.base_url(); + GURL::Replacements replacements; + replacements.SetSchemeStr("http"); + GURL start_url = exected_ssl_url.ReplaceComponents(replacements); + + request = std::make_unique<network::ResourceRequest>(); + request->url = start_url; + request->load_flags = net::LOAD_ONLY_FROM_CACHE; + + content::SimpleURLLoaderTestHelper simple_loader_helper2; + simple_loader = network::SimpleURLLoader::Create( + std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory(), simple_loader_helper2.GetCallback()); + simple_loader_helper2.WaitForCallback(); + EXPECT_FALSE(simple_loader_helper2.response_body()); + EXPECT_EQ(exected_ssl_url, simple_loader->GetFinalURL()); + + // Write the URL with HSTS information to a file, so it can be loaded in the + // next test. Have to use a file for this, since the server's port is random. + base::ScopedAllowBlockingForTesting allow_blocking; + base::FilePath save_url_file_path = browser()->profile()->GetPath().Append( + FILE_PATH_LITERAL("url_for_test.txt")); + std::string file_data = start_url.spec(); + ASSERT_EQ( + static_cast<int>(file_data.length()), + base::WriteFile(save_url_file_path, file_data.data(), file_data.size())); +} + +// Checks if the HSTS information from the last test is still available after a +// restart. +IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, Hsts) { + base::ScopedAllowBlockingForTesting allow_blocking; + base::FilePath save_url_file_path = browser()->profile()->GetPath().Append( + FILE_PATH_LITERAL("url_for_test.txt")); + std::string file_data; + ASSERT_TRUE(ReadFileToString(save_url_file_path, &file_data)); + GURL start_url = GURL(file_data); + + // Unfortunately, loading HSTS information is loaded asynchronously from + // disk, so there's no way to guarantee it has loaded by the time a + // request is made. As a result, may have to try multiple times to verify that + // cached HSTS information has been loaded, when it's stored on disk. + while (true) { + std::unique_ptr<network::ResourceRequest> request = + std::make_unique<network::ResourceRequest>(); + request->url = start_url; + request->load_flags = net::LOAD_ONLY_FROM_CACHE; + + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<network::SimpleURLLoader> simple_loader = + network::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory(), simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + EXPECT_FALSE(simple_loader_helper.response_body()); + + // HSTS information is currently stored on disk if-and-only-if there's an + // on-disk HTTP cache. + if (GetHttpCacheType() == StorageType::kDisk) { + GURL::Replacements replacements; + replacements.SetSchemeStr("https"); + GURL expected_https_url = start_url.ReplaceComponents(replacements); + // The file may not have been loaded yet, so if the cached HSTS + // information was not respected, try again. + if (expected_https_url != simple_loader->GetFinalURL()) + continue; + EXPECT_EQ(expected_https_url, simple_loader->GetFinalURL()); + break; + } else { + EXPECT_EQ(start_url, simple_loader->GetFinalURL()); + break; + } + } +} + +#endif // !defined(OS_MACOSX) + IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, ProxyConfig) { SetProxyPref(embedded_test_server()->host_port_pair()); TestProxyConfigured(); @@ -968,6 +1086,7 @@ } // |NetworkServiceTestHelper| doesn't work on browser_tests on OSX. +// See https://crbug.com/757088 #if defined(OS_MACOSX) // Instiates tests with a prefix indicating which NetworkContext is being // tested, and a suffix of "/0" if the network service is disabled and "/1" if
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 5de3140..707cb4e 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -209,6 +209,8 @@ network_context_params->restore_old_session_cookies = false; network_context_params->persist_session_cookies = false; } + + network_context_params->transport_security_persister_path = path; } // NOTE(mmenke): Keep these protocol handlers and
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 80411b4..842dc8b 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -1632,6 +1632,61 @@ #endif // defined(OS_MACOSX) +IN_PROC_BROWSER_TEST_P(PDFExtensionHitTestTest, MouseLeave) { + GURL url = embedded_test_server()->GetURL("/pdf/pdf_embed.html"); + + // Load page with embedded PDF and make sure it succeeds. + ASSERT_TRUE(LoadPdf(url)); + WebContents* guest_contents = nullptr; + WebContents* embedder_contents = GetActiveWebContents(); + content::BrowserPluginGuestManager* guest_manager = + embedder_contents->GetBrowserContext()->GetGuestManager(); + ASSERT_NO_FATAL_FAILURE(guest_manager->ForEachGuest( + embedder_contents, base::Bind(&GetGuestCallback, &guest_contents))); + ASSERT_NE(nullptr, guest_contents); +#if defined(USE_AURA) + // TODO(wjmaclean): In theory this should be used to make sure the hit testing + // for routing to the guest process works as intended. Not sure if not having + // this on Mac is an issue. + content::WaitForGuestSurfaceReady(guest_contents); +#endif + gfx::Point point_in_parent(250, 25); + gfx::Point point_in_pdf(250, 250); + + // Inject script to count MouseLeaves in the PDF. + ASSERT_TRUE(content::ExecuteScript( + guest_contents, + "var enter_count = 0;\n" + "var leave_count = 0;\n" + "document.addEventListener('mouseenter', function (){\n" + " enter_count++;" + "});\n" + "document.addEventListener('mouseleave', function (){\n" + " leave_count++;" + "});")); + + // Inject some MouseMoves to invoke a MouseLeave in the PDF. + content::SimulateRoutedMouseEvent( + embedder_contents, blink::WebInputEvent::kMouseMove, point_in_parent); + content::SimulateRoutedMouseEvent( + embedder_contents, blink::WebInputEvent::kMouseMove, point_in_pdf); + content::SimulateRoutedMouseEvent( + embedder_contents, blink::WebInputEvent::kMouseMove, point_in_parent); + + // Verify MouseEnter, MouseLeave received. + int leave_count = 0; + do { + ASSERT_TRUE(ExecuteScriptAndExtractInt( + guest_contents, "window.domAutomationController.send(leave_count);", + &leave_count)); + } while (!leave_count); + int enter_count = 0; + ASSERT_TRUE(ExecuteScriptAndExtractInt( + guest_contents, "window.domAutomationController.send(enter_count);", + &enter_count)); + EXPECT_EQ(1, enter_count); +} + IN_PROC_BROWSER_TEST_P(PDFExtensionHitTestTest, ContextMenuCoordinates) { GURL url = embedded_test_server()->GetURL("/pdf/pdf_embed.html");
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index bd9dd3e..38f4a7b3 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -1101,9 +1101,6 @@ io_thread->SetUpProxyService(builder.get()); - if (!IsOffTheRecord()) - builder->set_transport_security_persister_path(profile_params_->path); - // Take ownership over these parameters. cookie_settings_ = profile_params_->cookie_settings; host_content_settings_map_ = profile_params_->host_content_settings_map;
diff --git a/chrome/browser/resource_coordinator/leveldb_site_characteristics_database.cc b/chrome/browser/resource_coordinator/leveldb_site_characteristics_database.cc new file mode 100644 index 0000000..2991e1d --- /dev/null +++ b/chrome/browser/resource_coordinator/leveldb_site_characteristics_database.cc
@@ -0,0 +1,129 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/leveldb_site_characteristics_database.h" + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_restrictions.h" +#include "third_party/leveldatabase/env_chromium.h" +#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" + +namespace resource_coordinator { + +namespace { + +// Try to open a database (creates it if necessary). +// TODO(sebmarchand): Turn this into a callback that runs in TaskScheduler with +// MayBlock(). +std::unique_ptr<leveldb::DB> OpenDatabase(const base::FilePath& db_path) { + base::AssertBlockingAllowed(); + leveldb_env::Options options; + options.create_if_missing = true; + std::unique_ptr<leveldb::DB> db; + leveldb::Status status = + leveldb_env::OpenDB(options, db_path.AsUTF8Unsafe(), &db); + // TODO(sebmarchand): Do more validation here, try to repair the database if + // it's corrupt and report some metrics. + if (!status.ok()) { + LOG(ERROR) << "Unable to open the Site Characteristics database: " + << status.ToString(); + return nullptr; + } + return db; +} + +} // namespace + +// static: +std::unique_ptr<LevelDBSiteCharacteristicsDatabase> +LevelDBSiteCharacteristicsDatabase::OpenOrCreateDatabase( + const base::FilePath& db_path) { + std::unique_ptr<leveldb::DB> db = OpenDatabase(db_path); + if (!db) + return nullptr; + LevelDBSiteCharacteristicsDatabase* characteristics_db = + new LevelDBSiteCharacteristicsDatabase(std::move(db), db_path); + return base::WrapUnique(characteristics_db); +} + +LevelDBSiteCharacteristicsDatabase::~LevelDBSiteCharacteristicsDatabase() = + default; + +void LevelDBSiteCharacteristicsDatabase::ReadSiteCharacteristicsFromDB( + const std::string& site_origin, + LocalSiteCharacteristicsDatabase::ReadSiteCharacteristicsFromDBCallback + callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::AssertBlockingAllowed(); + std::string protobuf_value; + // TODO(sebmarchand): Move this to a separate thread as this is blocking. + leveldb::Status s = db_->Get(read_options_, site_origin, &protobuf_value); + base::Optional<SiteCharacteristicsProto> site_characteristic_proto; + if (s.ok()) { + site_characteristic_proto = SiteCharacteristicsProto(); + if (!site_characteristic_proto->ParseFromString(protobuf_value)) { + site_characteristic_proto = base::nullopt; + LOG(ERROR) << "Error while trying to parse a SiteCharacteristicsProto " + << "protobuf."; + } + } + std::move(callback).Run(std::move(site_characteristic_proto)); +} + +void LevelDBSiteCharacteristicsDatabase::WriteSiteCharacteristicsIntoDB( + const std::string& site_origin, + const SiteCharacteristicsProto& site_characteristic_proto) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::AssertBlockingAllowed(); + // TODO(sebmarchand): Move this to a separate thread as this is blocking. + leveldb::Status s = db_->Put(write_options_, site_origin, + site_characteristic_proto.SerializeAsString()); + if (!s.ok()) { + LOG(ERROR) << "Error while inserting an element in the site characteristic " + << "database: " << s.ToString(); + } +} + +void LevelDBSiteCharacteristicsDatabase::RemoveSiteCharacteristicsFromDB( + const std::vector<std::string>& site_origins) { + base::AssertBlockingAllowed(); + // TODO(sebmarchand): Move this to a separate thread as this is blocking. + leveldb::WriteBatch batch; + for (const auto iter : site_origins) + batch.Delete(iter); + leveldb::Status status = db_->Write(write_options_, &batch); + if (!status.ok()) { + LOG(WARNING) << "Failed to remove some entries from the site " + << "characteristics database: " << status.ToString(); + } +} + +void LevelDBSiteCharacteristicsDatabase::ClearDatabase() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::AssertBlockingAllowed(); + // TODO(sebmarchand): Move this to a separate thread as this is blocking. + leveldb_env::Options options; + db_.reset(); + leveldb::Status status = leveldb::DestroyDB(db_path_.AsUTF8Unsafe(), options); + if (status.ok()) { + db_ = OpenDatabase(db_path_); + } else { + LOG(WARNING) << "Failed to destroy the site characteristics database: " + << status.ToString(); + } +} + +LevelDBSiteCharacteristicsDatabase::LevelDBSiteCharacteristicsDatabase( + std::unique_ptr<leveldb::DB> db, + const base::FilePath& db_path) + : db_(std::move(db)), db_path_(db_path) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Setting |sync| to false might cause some data loss if the system crashes + // but it'll make the write operations faster (no data will be loss if only + // the process crashes). + write_options_.sync = false; +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/leveldb_site_characteristics_database.h b/chrome/browser/resource_coordinator/leveldb_site_characteristics_database.h new file mode 100644 index 0000000..280cbfe --- /dev/null +++ b/chrome/browser/resource_coordinator/leveldb_site_characteristics_database.h
@@ -0,0 +1,67 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LEVELDB_SITE_CHARACTERISTICS_DATABASE_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_LEVELDB_SITE_CHARACTERISTICS_DATABASE_H_ + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/sequence_checker.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_database.h" +#include "third_party/leveldatabase/src/include/leveldb/db.h" + +namespace resource_coordinator { + +// Manages a LevelDB database used by a site characteristic data store. +// TODO(sebmarchand): +// - Constraint the size of the database: Use a background task to trim the +// database if it becomes too big and ensure that this fail nicely when the +// disk is full. +// - Batch the write operations to reduce the number of I/O events. +// - Move the I/O operations to a different thread. +// +// All the DB operations need to be done on the I/O thread. +class LevelDBSiteCharacteristicsDatabase + : public LocalSiteCharacteristicsDatabase { + public: + // Initialize the database, create it if it doesn't exist or just open it if + // it does. The on-disk database will be stored in |db_path|. + static std::unique_ptr<LevelDBSiteCharacteristicsDatabase> + OpenOrCreateDatabase(const base::FilePath& db_path); + + ~LevelDBSiteCharacteristicsDatabase() override; + + // LocalSiteCharacteristicDatabase: + void ReadSiteCharacteristicsFromDB( + const std::string& site_origin, + LocalSiteCharacteristicsDatabase::ReadSiteCharacteristicsFromDBCallback + callback) override; + void WriteSiteCharacteristicsIntoDB( + const std::string& site_origin, + const SiteCharacteristicsProto& site_characteristic_proto) override; + void RemoveSiteCharacteristicsFromDB( + const std::vector<std::string>& site_origin) override; + void ClearDatabase() override; + + private: + LevelDBSiteCharacteristicsDatabase(std::unique_ptr<leveldb::DB> db, + const base::FilePath& db_path); + + // The connection to the LevelDB database. + std::unique_ptr<leveldb::DB> db_; + // The options to be used for all database read operations. + leveldb::ReadOptions read_options_; + // The options to be used for all database write operations. + leveldb::WriteOptions write_options_; + + // The on disk location of the database. + const base::FilePath db_path_; + + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(LevelDBSiteCharacteristicsDatabase); +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_LEVELDB_SITE_CHARACTERISTICS_DATABASE_H_
diff --git a/chrome/browser/resource_coordinator/leveldb_site_characteristics_database_unittest.cc b/chrome/browser/resource_coordinator/leveldb_site_characteristics_database_unittest.cc new file mode 100644 index 0000000..2362938 --- /dev/null +++ b/chrome/browser/resource_coordinator/leveldb_site_characteristics_database_unittest.cc
@@ -0,0 +1,137 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/leveldb_site_characteristics_database.h" + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/resource_coordinator/site_characteristics.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace resource_coordinator { + +namespace { + +const char kOrigin1[] = "foo.com"; + +// Initialize a SiteCharacteristicsProto object with a test value (the same +// value is used to initialize all fields). +void InitSiteCharacteristicProto(SiteCharacteristicsProto* proto, + ::google::protobuf::int64 test_value) { + proto->set_last_loaded(test_value); + + SiteCharacteristicsFeatureProto feature_proto; + feature_proto.set_observation_duration(test_value); + feature_proto.set_use_timestamp(test_value); + + proto->mutable_updates_favicon_in_background()->CopyFrom(feature_proto); + proto->mutable_updates_title_in_background()->CopyFrom(feature_proto); + proto->mutable_uses_notifications_in_background()->CopyFrom(feature_proto); + proto->mutable_uses_audio_in_background()->CopyFrom(feature_proto); +} + +} // namespace + +class LevelDBSiteCharacteristicsDatabaseTest : public ::testing::Test { + public: + LevelDBSiteCharacteristicsDatabaseTest() {} + + void SetUp() override { + EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); + db_ = LevelDBSiteCharacteristicsDatabase::OpenOrCreateDatabase( + temp_dir_.GetPath()); + EXPECT_TRUE(db_); + } + + void TearDown() override { + db_.reset(); + EXPECT_TRUE(temp_dir_.Delete()); + } + + protected: + // Try to read an entry from the database, returns true if the entry is + // present and false otherwise. |receiving_proto| will receive the protobuf + // corresponding to this entry on success. + bool ReadFromDB(const std::string& origin, + SiteCharacteristicsProto* receiving_proto) { + EXPECT_TRUE(receiving_proto); + bool success = false; + bool init_called = false; + auto init_callback = base::BindOnce( + [](SiteCharacteristicsProto* proto, bool* res, bool* init_called, + base::Optional<SiteCharacteristicsProto> proto_opt) { + *res = proto_opt.has_value(); + *init_called = true; + if (proto_opt) + proto->CopyFrom(proto_opt.value()); + }, + base::Unretained(receiving_proto), base::Unretained(&success), + base::Unretained(&init_called)); + db_->ReadSiteCharacteristicsFromDB(origin, std::move(init_callback)); + EXPECT_TRUE(init_called); + return success; + } + + base::ScopedTempDir temp_dir_; + std::unique_ptr<LevelDBSiteCharacteristicsDatabase> db_; +}; + +TEST_F(LevelDBSiteCharacteristicsDatabaseTest, InitAndStoreSiteCharacteristic) { + // Initializing an entry that doesn't exist in the database should fail. + SiteCharacteristicsProto early_read_proto; + EXPECT_FALSE(ReadFromDB(kOrigin1, &early_read_proto)); + + // Add an entry to the database and make sure that we can read it back. + ::google::protobuf::int64 test_value = 42; + SiteCharacteristicsProto stored_proto; + InitSiteCharacteristicProto(&stored_proto, test_value); + db_->WriteSiteCharacteristicsIntoDB(kOrigin1, stored_proto); + SiteCharacteristicsProto read_proto; + EXPECT_TRUE(ReadFromDB(kOrigin1, &read_proto)); + EXPECT_TRUE(read_proto.IsInitialized()); + EXPECT_EQ(stored_proto.SerializeAsString(), read_proto.SerializeAsString()); +} + +TEST_F(LevelDBSiteCharacteristicsDatabaseTest, RemoveEntries) { + // Add multiple origins to the database. + const size_t kEntryCount = 10; + SiteCharacteristicsProto protos[kEntryCount]; + std::vector<std::string> site_origins; + for (size_t i = 0; i < kEntryCount; ++i) { + std::string site_origin = base::StringPrintf("%zu.com", i); + InitSiteCharacteristicProto(&protos[i], + static_cast<::google::protobuf::int64>(i)); + db_->WriteSiteCharacteristicsIntoDB(site_origin, protos[i]); + site_origins.emplace_back(site_origin); + } + + for (size_t i = 0; i < kEntryCount; ++i) + EXPECT_TRUE(protos[i].IsInitialized()); + + // Remove half the origins from the database. + std::vector<std::string> site_origins_to_remove( + site_origins.begin(), site_origins.begin() + kEntryCount / 2); + db_->RemoveSiteCharacteristicsFromDB(site_origins_to_remove); + + // Verify that the origins were removed correctly. + SiteCharacteristicsProto proto_temp; + for (const auto& iter : site_origins_to_remove) + EXPECT_FALSE(ReadFromDB(iter, &proto_temp)); + + for (auto iter = site_origins.begin() + kEntryCount / 2; + iter != site_origins.end(); ++iter) { + EXPECT_TRUE(ReadFromDB(*iter, &proto_temp)); + } + + // Clear the database. + db_->ClearDatabase(); + + // Verify that no origin remains. + for (auto iter : site_origins) + EXPECT_FALSE(ReadFromDB(iter, &proto_temp)); +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc index 3131fe3..1f30f54a 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc
@@ -7,6 +7,8 @@ #include <algorithm> #include <vector> +#include "base/bind.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_database.h" #include "chrome/browser/resource_coordinator/time.h" namespace resource_coordinator { @@ -123,12 +125,36 @@ LocalSiteCharacteristicsDataImpl::LocalSiteCharacteristicsDataImpl( const std::string& origin_str, - OnDestroyDelegate* delegate) + OnDestroyDelegate* delegate, + LocalSiteCharacteristicsDatabase* database) : origin_str_(origin_str), active_webcontents_count_(0U), - delegate_(delegate) { + database_(database), + delegate_(delegate), + weak_factory_(this) { DCHECK_NE(nullptr, delegate_); - InitWithDefaultValues(); + DCHECK_NE(nullptr, database_); + DCHECK(!site_characteristics_.IsInitialized()); + database_->ReadSiteCharacteristicsFromDB( + origin_str_, + base::BindOnce(&LocalSiteCharacteristicsDataImpl::OnInitCallback, + weak_factory_.GetWeakPtr())); +} + +LocalSiteCharacteristicsDataImpl::~LocalSiteCharacteristicsDataImpl() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // It's currently required that the site gets unloaded before destroying this + // object. + // TODO(sebmarchand): Check if this is a valid assumption. + DCHECK(!IsLoaded()); + + DCHECK_NE(nullptr, delegate_); + delegate_->OnLocalSiteCharacteristicsDataImplDestroyed(this); + + if (site_characteristics_.IsInitialized()) { + database_->WriteSiteCharacteristicsIntoDB(origin_str_, + site_characteristics_); + } } base::TimeDelta LocalSiteCharacteristicsDataImpl::FeatureObservationDuration( @@ -153,22 +179,12 @@ return observation_time_for_feature; } -LocalSiteCharacteristicsDataImpl::~LocalSiteCharacteristicsDataImpl() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // It's currently required that the site gets unloaded before destroying this - // object. - // TODO(sebmarchand): Check if this is a valid assumption. - DCHECK(!IsLoaded()); - - DCHECK_NE(nullptr, delegate_); - delegate_->OnLocalSiteCharacteristicsDataImplDestroyed(this); -} - // static: void LocalSiteCharacteristicsDataImpl::IncrementFeatureObservationDuration( SiteCharacteristicsFeatureProto* feature_proto, base::TimeDelta extra_observation_duration) { - if (InternalRepresentationToTimeDelta(feature_proto->use_timestamp()) + if (!feature_proto->has_use_timestamp() || + InternalRepresentationToTimeDelta(feature_proto->use_timestamp()) .is_zero()) { feature_proto->set_observation_duration(TimeDeltaToInternalRepresentation( InternalRepresentationToTimeDelta( @@ -186,20 +202,26 @@ proto->set_use_timestamp(kZeroIntervalInternalRepresentation); } -void LocalSiteCharacteristicsDataImpl::InitWithDefaultValues() { +void LocalSiteCharacteristicsDataImpl::InitWithDefaultValues( + bool only_init_uninitialized_fields) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Initialize the feature elements with the default value, this is required // because some fields might otherwise never be initialized. - for (auto* iter : GetAllFeaturesFromProto(&site_characteristics_)) - InitSiteCharacteristicsFeatureProtoWithDefaultValues(iter); + for (auto* iter : GetAllFeaturesFromProto(&site_characteristics_)) { + if (!only_init_uninitialized_fields || !iter->IsInitialized()) + InitSiteCharacteristicsFeatureProtoWithDefaultValues(iter); + } - site_characteristics_.set_last_loaded(kZeroIntervalInternalRepresentation); + if (!only_init_uninitialized_fields || + !site_characteristics_.has_last_loaded()) { + site_characteristics_.set_last_loaded(kZeroIntervalInternalRepresentation); + } } void LocalSiteCharacteristicsDataImpl::ClearObservations() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Reset all the observations. - InitWithDefaultValues(); + InitWithDefaultValues(false); // Set the last loaded time to the current time if there's some loaded // instances of this site. @@ -214,6 +236,9 @@ const base::TimeDelta min_obs_time) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!feature_proto.IsInitialized()) + return SiteFeatureUsage::kSiteFeatureUsageUnknown; + // Checks if this feature has already been observed. // TODO(sebmarchand): Check the timestamp and reset features that haven't been // observed in a long time, https://crbug.com/826446. @@ -238,5 +263,58 @@ feature_proto->set_observation_duration(kZeroIntervalInternalRepresentation); } +void LocalSiteCharacteristicsDataImpl::OnInitCallback( + base::Optional<SiteCharacteristicsProto> db_site_characteristics) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // Check if the initialization has succeeded. + if (db_site_characteristics) { + // If so, iterates over all the features and initialize them. + auto this_features = GetAllFeaturesFromProto(&site_characteristics_); + auto db_features = + GetAllFeaturesFromProto(&db_site_characteristics.value()); + auto this_features_iter = this_features.begin(); + auto db_features_iter = db_features.begin(); + for (; this_features_iter != this_features.end() && + db_features_iter != db_features.end(); + ++this_features_iter, ++db_features_iter) { + // If the |use_timestamp| field is set for the in-memory entry for this + // feature then there's nothing to do, otherwise update it with the values + // from the database. + if (!(*this_features_iter)->has_use_timestamp()) { + if ((*db_features_iter)->has_use_timestamp()) { + // Keep the use timestamp from the database, if any. + (*this_features_iter) + ->set_use_timestamp((*db_features_iter)->use_timestamp()); + (*this_features_iter) + ->set_observation_duration(kZeroIntervalInternalRepresentation); + } else { + // Else, add the observation duration from the database to the + // in-memory observation duration. + if (!(*this_features_iter)->has_observation_duration()) { + (*this_features_iter) + ->set_observation_duration(kZeroIntervalInternalRepresentation); + } + IncrementFeatureObservationDuration( + (*this_features_iter), + InternalRepresentationToTimeDelta( + (*db_features_iter)->observation_duration())); + } + } + } + // Only update the last loaded field if we haven't updated it since the + // creation of this object. + if (!site_characteristics_.has_last_loaded()) { + site_characteristics_.set_last_loaded( + db_site_characteristics->last_loaded()); + } + } else { + // Init all the fields that haven't been initialized with a default value. + InitWithDefaultValues(true /* only_init_uninitialized_fields */); + } + + DCHECK(site_characteristics_.IsInitialized()); +} + } // namespace internal } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h index 53396c7..99a5429 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h
@@ -9,14 +9,17 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/time/time.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_database.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h" #include "chrome/browser/resource_coordinator/site_characteristics.pb.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" namespace resource_coordinator { +class LocalSiteCharacteristicsDatabase; class LocalSiteCharacteristicsDataStore; class LocalSiteCharacteristicsDataReaderTest; class LocalSiteCharacteristicsDataWriterTest; @@ -88,7 +91,10 @@ friend class resource_coordinator::LocalSiteCharacteristicsDataWriterTest; LocalSiteCharacteristicsDataImpl(const std::string& origin_str, - OnDestroyDelegate* delegate); + OnDestroyDelegate* delegate, + LocalSiteCharacteristicsDatabase* database); + + virtual ~LocalSiteCharacteristicsDataImpl(); // Helper functions to convert from/to the internal representation that is // used to store TimeDelta values in the |SiteCharacteristicsProto| protobuf. @@ -100,8 +106,6 @@ return delta.InSeconds(); } - virtual ~LocalSiteCharacteristicsDataImpl(); - // Returns for how long a given feature has been observed, this is the sum of // the recorded observation duration and the current observation duration // since this site has been loaded (if applicable). If a feature has been @@ -123,10 +127,13 @@ static void InitSiteCharacteristicsFeatureProtoWithDefaultValues( SiteCharacteristicsFeatureProto* proto); - // Initialize this object with default values. + // Initialize this object with default values. If + // |only_init_uninitialized_fields| is set to true then only the fields that + // haven't yet been initialized will be initialized, otherwise everything will + // be overriden with default values. // NOTE: Do not call this directly while the site is loaded as this will not // properly update the last_loaded time, instead call |ClearObservations|. - void InitWithDefaultValues(); + void InitWithDefaultValues(bool only_init_uninitialized_fields); // Clear all the past observations about this site. void ClearObservations(); @@ -144,6 +151,11 @@ bool IsLoaded() const { return active_webcontents_count_ > 0U; } + // Callback that needs to be called by the database once it has finished + // trying to read the protobuf. + void OnInitCallback( + base::Optional<SiteCharacteristicsProto> site_characteristic_proto); + // This site's characteristics, contains the features and other values are // measured. SiteCharacteristicsProto site_characteristics_; @@ -155,13 +167,24 @@ // same origin might share the same instance of this object, this counter // will allow to properly update the observation time (starts when the first // tab gets loaded, stops when the last one gets unloaded). + // + // TODO(sebmarchand): Also track the number of tabs that are in background for + // this origin and use this to update the observation windows. The number of + // active WebContents doesn't tell anything about the background/foreground + // state of a tab. size_t active_webcontents_count_; + // The database used to store the site characteristics. + LocalSiteCharacteristicsDatabase* database_; + // The delegate that should get notified when this object is about to get // destroyed. OnDestroyDelegate* const delegate_; SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<LocalSiteCharacteristicsDataImpl> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsDataImpl); };
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc index 35a01e66..ff64f521c 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc
@@ -31,8 +31,9 @@ explicit TestLocalSiteCharacteristicsDataImpl( const std::string& origin_str, - LocalSiteCharacteristicsDataImpl::OnDestroyDelegate* delegate) - : LocalSiteCharacteristicsDataImpl(origin_str, delegate) {} + LocalSiteCharacteristicsDataImpl::OnDestroyDelegate* delegate, + LocalSiteCharacteristicsDatabase* database) + : LocalSiteCharacteristicsDataImpl(origin_str, delegate, database) {} base::TimeDelta FeatureObservationTimestamp( const SiteCharacteristicsFeatureProto& feature_proto) { @@ -43,6 +44,47 @@ ~TestLocalSiteCharacteristicsDataImpl() override {} }; +class MockLocalSiteCharacteristicsDatabase + : public testing::NoopLocalSiteCharacteristicsDatabase { + public: + MockLocalSiteCharacteristicsDatabase() = default; + ~MockLocalSiteCharacteristicsDatabase() = default; + + // Note: As move-only parameters (e.g. OnceCallback) aren't supported by mock + // methods, add On... methods to pass a non-const reference to OnceCallback. + void ReadSiteCharacteristicsFromDB( + const std::string& origin_str, + LocalSiteCharacteristicsDatabase::ReadSiteCharacteristicsFromDBCallback + callback) override { + OnReadSiteCharacteristicsFromDB(origin_str, callback); + } + MOCK_METHOD2(OnReadSiteCharacteristicsFromDB, + void(const std::string&, + LocalSiteCharacteristicsDatabase:: + ReadSiteCharacteristicsFromDBCallback&)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockLocalSiteCharacteristicsDatabase); +}; + +// Returns a SiteCharacteristicsFeatureProto that indicates that a feature +// hasn't been used. +SiteCharacteristicsFeatureProto GetUnusedFeatureProto() { + SiteCharacteristicsFeatureProto unused_feature_proto; + unused_feature_proto.set_observation_duration(1U); + unused_feature_proto.set_use_timestamp(0U); + return unused_feature_proto; +} + +// Returns a SiteCharacteristicsFeatureProto that indicates that a feature +// has been used. +SiteCharacteristicsFeatureProto GetUsedFeatureProto() { + SiteCharacteristicsFeatureProto used_feature_proto; + used_feature_proto.set_observation_duration(0U); + used_feature_proto.set_use_timestamp(1U); + return used_feature_proto; +} + } // namespace class LocalSiteCharacteristicsDataImplTest : public ::testing::Test { @@ -65,12 +107,17 @@ ::testing::NiceMock< testing::MockLocalSiteCharacteristicsDataImplOnDestroyDelegate> destroy_delegate_; + + testing::NoopLocalSiteCharacteristicsDatabase database_; }; TEST_F(LocalSiteCharacteristicsDataImplTest, BasicTestEndToEnd) { auto local_site_data = base::MakeRefCounted<TestLocalSiteCharacteristicsDataImpl>( - kDummyOrigin, &destroy_delegate_); + kDummyOrigin, &destroy_delegate_, &database_); + + EXPECT_TRUE( + local_site_data->site_characteristics_for_testing().IsInitialized()); local_site_data->NotifySiteLoaded(); @@ -126,7 +173,7 @@ TEST_F(LocalSiteCharacteristicsDataImplTest, LastLoadedTime) { auto local_site_data = base::MakeRefCounted<TestLocalSiteCharacteristicsDataImpl>( - kDummyOrigin, &destroy_delegate_); + kDummyOrigin, &destroy_delegate_, &database_); // Create a second instance of this object, simulates having several tab // owning it. auto local_site_data2(local_site_data); @@ -157,7 +204,7 @@ TEST_F(LocalSiteCharacteristicsDataImplTest, GetFeatureUsageForUnloadedSite) { auto local_site_data = base::MakeRefCounted<TestLocalSiteCharacteristicsDataImpl>( - kDummyOrigin, &destroy_delegate_); + kDummyOrigin, &destroy_delegate_, &database_); local_site_data->NotifySiteLoaded(); local_site_data->NotifyUsesAudioInBackground(); @@ -210,7 +257,7 @@ // for all the features being tracked. auto local_site_data = base::MakeRefCounted<TestLocalSiteCharacteristicsDataImpl>( - kDummyOrigin, &destroy_delegate_); + kDummyOrigin, &destroy_delegate_, &database_); const base::TimeDelta kInterval = base::TimeDelta::FromSeconds(1); const auto kIntervalInternalRepresentation = @@ -266,6 +313,7 @@ expected_proto.mutable_uses_audio_in_background()->CopyFrom( used_feature_proto); + EXPECT_TRUE(expected_proto.IsInitialized()); EXPECT_TRUE( local_site_data->site_characteristics_for_testing().IsInitialized()); EXPECT_EQ( @@ -282,12 +330,110 @@ { auto local_site_data = base::MakeRefCounted<TestLocalSiteCharacteristicsDataImpl>( - kDummyOrigin, &strict_delegate); + kDummyOrigin, &strict_delegate, &database_); EXPECT_CALL(strict_delegate, OnLocalSiteCharacteristicsDataImplDestroyed( local_site_data.get())); } ::testing::Mock::VerifyAndClear(&strict_delegate); } +TEST_F(LocalSiteCharacteristicsDataImplTest, + OnInitCallbackMergePreviousObservations) { + // Use a mock database to intercept the initialization callback and save it + // locally so it can be run later. This simulates an asynchronous + // initialization of this object and is used to test that the observations + // made between the time this object has been created and the callback is + // called get properly merged. + ::testing::StrictMock<MockLocalSiteCharacteristicsDatabase> mock_db; + LocalSiteCharacteristicsDatabase::ReadSiteCharacteristicsFromDBCallback + read_cb; + auto read_from_db_mock_impl = + [&](const std::string& site_origin, + LocalSiteCharacteristicsDatabase:: + ReadSiteCharacteristicsFromDBCallback& callback) { + read_cb = std::move(callback); + }; + + EXPECT_CALL(mock_db, + OnReadSiteCharacteristicsFromDB(::testing::_, ::testing::_)) + .WillOnce(::testing::Invoke(read_from_db_mock_impl)); + auto local_site_data = + base::MakeRefCounted<TestLocalSiteCharacteristicsDataImpl>( + kDummyOrigin, &destroy_delegate_, &mock_db); + ::testing::Mock::VerifyAndClear(&mock_db); + + // Simulates audio in background usage before the callback gets called. + local_site_data->NotifySiteLoaded(); + local_site_data->NotifyUsesAudioInBackground(); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + local_site_data->UsesAudioInBackground()); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + local_site_data->UsesNotificationsInBackground()); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + local_site_data->UpdatesFaviconInBackground()); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + local_site_data->UpdatesTitleInBackground()); + + // Unload the site and save the last loaded time to make sure the + // initialization doesn't overwrite it. + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + local_site_data->NotifySiteUnloaded(); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + auto last_loaded = local_site_data->last_loaded_time_for_testing(); + + // This protobuf should have a valid |last_loaded| field and valid observation + // durations for each features, but the |use_timestamp| field shouldn't have + // been initialized for the features that haven't been used. + EXPECT_FALSE( + local_site_data->site_characteristics_for_testing().IsInitialized()); + EXPECT_TRUE( + local_site_data->site_characteristics_for_testing().has_last_loaded()); + EXPECT_TRUE(local_site_data->site_characteristics_for_testing() + .uses_audio_in_background() + .IsInitialized()); + EXPECT_FALSE(local_site_data->site_characteristics_for_testing() + .uses_notifications_in_background() + .IsInitialized()); + EXPECT_FALSE(local_site_data->site_characteristics_for_testing() + .uses_notifications_in_background() + .has_use_timestamp()); + EXPECT_TRUE(local_site_data->site_characteristics_for_testing() + .uses_notifications_in_background() + .has_observation_duration()); + + // Initialize a fake protobuf that indicates that this site updates its title + // while in background and set a fake last loaded time (this should be + // overriden once the callback runs). + base::Optional<SiteCharacteristicsProto> test_proto = + SiteCharacteristicsProto(); + SiteCharacteristicsFeatureProto unused_feature_proto = + GetUnusedFeatureProto(); + test_proto->mutable_updates_title_in_background()->CopyFrom( + GetUsedFeatureProto()); + test_proto->mutable_updates_favicon_in_background()->CopyFrom( + unused_feature_proto); + test_proto->mutable_uses_audio_in_background()->CopyFrom( + unused_feature_proto); + test_proto->mutable_uses_notifications_in_background()->CopyFrom( + unused_feature_proto); + test_proto->set_last_loaded(42); + + // Run the callback to indicate that the initialization has completed. + std::move(read_cb).Run(test_proto); + + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + local_site_data->UsesAudioInBackground()); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + local_site_data->UpdatesTitleInBackground()); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + local_site_data->UpdatesFaviconInBackground()); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + local_site_data->UsesNotificationsInBackground()); + EXPECT_EQ(last_loaded, local_site_data->last_loaded_time_for_testing()); + + EXPECT_TRUE( + local_site_data->site_characteristics_for_testing().IsInitialized()); +} + } // namespace internal } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc index 405ca28..3585c4d 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc
@@ -21,10 +21,10 @@ // LocalSiteCharacteristicsDataImpl is protected and not visible to // base::MakeRefCounted. LocalSiteCharacteristicsDataReaderTest() - : scoped_set_tick_clock_for_testing_(&test_clock_), - test_impl_(base::WrapRefCounted( - new internal::LocalSiteCharacteristicsDataImpl("foo.com", - &delegate_))) { + : scoped_set_tick_clock_for_testing_(&test_clock_) { + test_impl_ = + base::WrapRefCounted(new internal::LocalSiteCharacteristicsDataImpl( + "foo.com", &delegate_, &database_)); test_impl_->NotifySiteLoaded(); LocalSiteCharacteristicsDataReader* reader = new LocalSiteCharacteristicsDataReader(test_impl_.get()); @@ -52,6 +52,8 @@ // to create this object. std::unique_ptr<LocalSiteCharacteristicsDataReader> reader_; + testing::NoopLocalSiteCharacteristicsDatabase database_; + DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsDataReaderTest); };
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc index 178d10a..696b071b 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc
@@ -8,14 +8,24 @@ #include "base/stl_util.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/resource_coordinator/leveldb_site_characteristics_database.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h" #include "components/history/core/browser/history_service.h" namespace resource_coordinator { +namespace { +constexpr char kSiteCharacteristicsDirectoryName[] = + "Site Characteristics Database"; +} + LocalSiteCharacteristicsDataStore::LocalSiteCharacteristicsDataStore( Profile* profile) : history_observer_(this) { + database_ = LevelDBSiteCharacteristicsDatabase::OpenOrCreateDatabase( + profile->GetPath().AppendASCII(kSiteCharacteristicsDirectoryName)); + history::HistoryService* history = HistoryServiceFactory::GetForProfileWithoutCreating(profile); if (history) @@ -36,7 +46,7 @@ return base::WrapUnique(data_reader); } -std::unique_ptr<LocalSiteCharacteristicsDataWriter> +std::unique_ptr<SiteCharacteristicsDataWriter> LocalSiteCharacteristicsDataStore::GetWriterForOrigin( const std::string& origin_str) { internal::LocalSiteCharacteristicsDataImpl* impl = @@ -57,7 +67,8 @@ // If not create a new one and add it to the map. internal::LocalSiteCharacteristicsDataImpl* site_characteristic_data = - new internal::LocalSiteCharacteristicsDataImpl(origin_str, this); + new internal::LocalSiteCharacteristicsDataImpl(origin_str, this, + database_.get()); // internal::LocalSiteCharacteristicsDataImpl is a ref-counted object, it's // safe to store a raw pointer to it here as this class will get notified when // it's about to be destroyed and it'll be removed from the map. @@ -90,21 +101,25 @@ void LocalSiteCharacteristicsDataStore::OnURLsDeleted( history::HistoryService* history_service, const history::DeletionInfo& deletion_info) { - // TODO(sebmarchand): Removes these entry from the on-disk database once it's - // implemented. + // TODO(sebmarchand): Invalidates all the pending read/write operations to the + // database once it's asynchronous. if (deletion_info.IsAllHistory()) { for (auto iter = origin_data_map_.begin(); iter != origin_data_map_.end();) { iter = ResetLocalSiteCharacteristicsEntry(iter); } + database_->ClearDatabase(); } else { - for (const auto& deleted_row : deletion_info.deleted_rows()) { + std::vector<std::string> entries_to_remove; + for (auto deleted_row : deletion_info.deleted_rows()) { auto map_iter = origin_data_map_.find(deleted_row.url().GetOrigin().GetContent()); if (map_iter != origin_data_map_.end()) { ResetLocalSiteCharacteristicsEntry(map_iter); + entries_to_remove.emplace_back(map_iter->first); } } + database_->RemoveSiteCharacteristicsFromDB(entries_to_remove); } }
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h index 39436c05..689b370 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h
@@ -12,16 +12,21 @@ #include "base/macros.h" #include "base/scoped_observer.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h" -#include "chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h" #include "chrome/browser/resource_coordinator/site_characteristics_data_store.h" +#include "chrome/browser/resource_coordinator/site_characteristics_data_writer.h" #include "components/history/core/browser/history_service_observer.h" class Profile; namespace resource_coordinator { +class LocalSiteCharacteristicsDatabase; + // Implementation of a SiteCharacteristicsDataStore that use the local site // characteristics database as a backend. +// +// TODO(sebmarchand): Expose a method to receive a dummy writer that doesn't +// record anything, for use in incognito sessions. class LocalSiteCharacteristicsDataStore : public SiteCharacteristicsDataStore, public internal::LocalSiteCharacteristicsDataImpl::OnDestroyDelegate, @@ -37,13 +42,21 @@ std::unique_ptr<SiteCharacteristicsDataReader> GetReaderForOrigin( const std::string& origin_str) override; - std::unique_ptr<LocalSiteCharacteristicsDataWriter> GetWriterForOrigin( - const std::string& origin_str); + std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( + const std::string& origin_str) override; const LocalSiteCharacteristicsMap& origin_data_map_for_testing() const { return origin_data_map_; } + // NOTE: This should be called before creating any + // LocalSiteCharacteristicsDataImpl object (this doesn't update the database + // used by these objects). + void SetDatabaseForTesting( + std::unique_ptr<LocalSiteCharacteristicsDatabase> database) { + database_ = std::move(database); + } + private: FRIEND_TEST_ALL_PREFIXES(LocalSiteCharacteristicsDataStoreTest, EndToEnd); FRIEND_TEST_ALL_PREFIXES(LocalSiteCharacteristicsDataStoreTest, @@ -76,6 +89,8 @@ ScopedObserver<history::HistoryService, LocalSiteCharacteristicsDataStore> history_observer_; + std::unique_ptr<LocalSiteCharacteristicsDatabase> database_; + DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsDataStore); };
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc index bebbd1d0..6754b13 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc
@@ -7,18 +7,36 @@ #include "base/macros.h" #include "base/test/simple_test_tick_clock.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h" #include "chrome/browser/resource_coordinator/time.h" #include "chrome/test/base/testing_profile.h" #include "components/history/core/browser/history_types.h" #include "components/history/core/browser/url_row.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace resource_coordinator { namespace { + const char kTestOrigin[] = "http://www.foo.com"; const char kTestOrigin2[] = "http://www.bar.com"; + +class MockLocalSiteCharacteristicsDatabase + : public testing::NoopLocalSiteCharacteristicsDatabase { + public: + MockLocalSiteCharacteristicsDatabase() = default; + ~MockLocalSiteCharacteristicsDatabase() = default; + + MOCK_METHOD1(RemoveSiteCharacteristicsFromDB, + void(const std::vector<std::string>& site_origin)); + MOCK_METHOD0(ClearDatabase, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockLocalSiteCharacteristicsDatabase); +}; + } // namespace class LocalSiteCharacteristicsDataStoreTest : public ::testing::Test { @@ -72,11 +90,17 @@ } TEST_F(LocalSiteCharacteristicsDataStoreTest, HistoryServiceObserver) { + // Mock the database to ensure that the delete events get propagated properly. + ::testing::StrictMock<MockLocalSiteCharacteristicsDatabase>* mock_db = + new ::testing::StrictMock<MockLocalSiteCharacteristicsDatabase>(); + data_store_.SetDatabaseForTesting(base::WrapUnique(mock_db)); + // Load a first origin, and then make use of a feature on it. const std::string kOrigin1Url = GURL(kTestOrigin).GetOrigin().GetContent(); auto reader = data_store_.GetReaderForOrigin(kOrigin1Url); EXPECT_TRUE(reader); + auto writer = data_store_.GetWriterForOrigin(kOrigin1Url); EXPECT_TRUE(writer); @@ -104,8 +128,8 @@ internal::LocalSiteCharacteristicsDataImpl* data2 = data_store_.origin_data_map_for_testing().find(kOrigin2Url)->second; EXPECT_NE(nullptr, data2); - writer2->NotifySiteLoaded(); - writer2->NotifyUpdatesFaviconInBackground(); + data2->NotifySiteLoaded(); + data2->NotifyUpdatesFaviconInBackground(); // This site hasn'be been unloaded yet, so the last loaded time shouldn't have // changed. @@ -114,8 +138,11 @@ history::URLRows urls_to_delete = { history::URLRow(GURL(kTestOrigin)), history::URLRow(GURL("http://www.url-not-in-map.com"))}; + EXPECT_CALL(*mock_db, RemoveSiteCharacteristicsFromDB(::testing::ContainerEq( + std::vector<std::string>({kOrigin1Url})))); data_store_.OnURLsDeleted(nullptr, history::DeletionInfo::ForUrls( urls_to_delete, std::set<GURL>())); + ::testing::Mock::VerifyAndClear(mock_db); // The information for this site have been reset, so the last loaded time // should now be equal to the current time and the title update feature @@ -132,7 +159,9 @@ test_clock_.Advance(kDelay); // Delete all the information stored in the data store. + EXPECT_CALL(*mock_db, ClearDatabase()); data_store_.OnURLsDeleted(nullptr, history::DeletionInfo::ForAllHistory()); + ::testing::Mock::VerifyAndClear(mock_db); EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, reader2->UpdatesFaviconInBackground());
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.cc index 8e79238..502f5ec 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.cc
@@ -12,5 +12,24 @@ MockLocalSiteCharacteristicsDataImplOnDestroyDelegate:: ~MockLocalSiteCharacteristicsDataImplOnDestroyDelegate() = default; +NoopLocalSiteCharacteristicsDatabase::NoopLocalSiteCharacteristicsDatabase() = + default; +NoopLocalSiteCharacteristicsDatabase::~NoopLocalSiteCharacteristicsDatabase() {} + +void NoopLocalSiteCharacteristicsDatabase::ReadSiteCharacteristicsFromDB( + const std::string& site_origin, + ReadSiteCharacteristicsFromDBCallback callback) { + std::move(callback).Run(base::nullopt); +} + +void NoopLocalSiteCharacteristicsDatabase::WriteSiteCharacteristicsIntoDB( + const std::string& site_origin, + const SiteCharacteristicsProto& site_characteristic_proto) {} + +void NoopLocalSiteCharacteristicsDatabase::RemoveSiteCharacteristicsFromDB( + const std::vector<std::string>& site_origins) {} + +void NoopLocalSiteCharacteristicsDatabase::ClearDatabase() {} + } // namespace testing } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h index f14e5a8..327dd107 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_database.h" #include "testing/gmock/include/gmock/gmock.h" namespace resource_coordinator { @@ -26,6 +27,29 @@ MockLocalSiteCharacteristicsDataImplOnDestroyDelegate); }; +// An implementation of a LocalSiteCharacteristicsDatabase that doesn't record +// anything. +class NoopLocalSiteCharacteristicsDatabase + : public LocalSiteCharacteristicsDatabase { + public: + NoopLocalSiteCharacteristicsDatabase(); + ~NoopLocalSiteCharacteristicsDatabase() override; + + // LocalSiteCharacteristicsDatabase: + void ReadSiteCharacteristicsFromDB( + const std::string& site_origin, + ReadSiteCharacteristicsFromDBCallback callback) override; + void WriteSiteCharacteristicsIntoDB( + const std::string& site_origin, + const SiteCharacteristicsProto& site_characteristic_proto) override; + void RemoveSiteCharacteristicsFromDB( + const std::vector<std::string>& site_origins) override; + void ClearDatabase() override; + + private: + DISALLOW_COPY_AND_ASSIGN(NoopLocalSiteCharacteristicsDatabase); +}; + } // namespace testing } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h index b149aa9..68160628 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "chrome/browser/resource_coordinator/site_characteristics_data_writer.h" namespace resource_coordinator { @@ -14,21 +15,20 @@ class LocalSiteCharacteristicsDataImpl; } // namespace internal -// Used to record local characteristics usage observations in the local -// database. -class LocalSiteCharacteristicsDataWriter { +// Specialization of a SiteCharacteristicsDataWriter that delegates to a +// LocalSiteCharacteristicsDataImpl. +class LocalSiteCharacteristicsDataWriter + : public SiteCharacteristicsDataWriter { public: - ~LocalSiteCharacteristicsDataWriter(); + ~LocalSiteCharacteristicsDataWriter() override; - // Records tab load/unload events. - void NotifySiteLoaded(); - void NotifySiteUnloaded(); - - // Records feature usage. - void NotifyUpdatesFaviconInBackground(); - void NotifyUpdatesTitleInBackground(); - void NotifyUsesAudioInBackground(); - void NotifyUsesNotificationsInBackground(); + // SiteCharacteristicsDataWriter: + void NotifySiteLoaded() override; + void NotifySiteUnloaded() override; + void NotifyUpdatesFaviconInBackground() override; + void NotifyUpdatesTitleInBackground() override; + void NotifyUsesAudioInBackground() override; + void NotifyUsesNotificationsInBackground() override; private: friend class LocalSiteCharacteristicsDataWriterTest;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc index 659030b..9629625 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc
@@ -22,7 +22,8 @@ LocalSiteCharacteristicsDataWriterTest() : test_impl_(base::WrapRefCounted( new internal::LocalSiteCharacteristicsDataImpl("foo.com", - &delegate_))) { + &delegate_, + &database_))) { LocalSiteCharacteristicsDataWriter* writer = new LocalSiteCharacteristicsDataWriter(test_impl_.get()); writer_ = base::WrapUnique(writer); @@ -30,6 +31,8 @@ ~LocalSiteCharacteristicsDataWriterTest() override = default; + bool TabIsLoaded() { return test_impl_->IsLoaded(); } + // The mock delegate used by the LocalSiteCharacteristicsDataImpl objects // created by this class, NiceMock is used to avoid having to set // expectations in test cases that don't care about this. @@ -37,6 +40,8 @@ testing::MockLocalSiteCharacteristicsDataImplOnDestroyDelegate> delegate_; + testing::NoopLocalSiteCharacteristicsDatabase database_; + // The LocalSiteCharacteristicsDataImpl object used in these tests. scoped_refptr<internal::LocalSiteCharacteristicsDataImpl> test_impl_; @@ -44,8 +49,6 @@ // to create this object. std::unique_ptr<LocalSiteCharacteristicsDataWriter> writer_; - bool TabIsLoaded() { return test_impl_->IsLoaded(); } - DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsDataWriterTest); };
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_database.h b/chrome/browser/resource_coordinator/local_site_characteristics_database.h new file mode 100644 index 0000000..d41d62c --- /dev/null +++ b/chrome/browser/resource_coordinator/local_site_characteristics_database.h
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_DATABASE_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_DATABASE_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/optional.h" +#include "chrome/browser/resource_coordinator/site_characteristics.pb.h" + +class SiteCharacteristicsProto; + +namespace resource_coordinator { + +// Interface for a local site characteristic database. +class LocalSiteCharacteristicsDatabase { + public: + // Callback to call once the initialization from the database has completed, + // |site_characteristic_proto| should be equal to base::nullopt if the + // initialization has failed. + using ReadSiteCharacteristicsFromDBCallback = base::OnceCallback<void( + base::Optional<SiteCharacteristicsProto> site_characteristic_proto)>; + + LocalSiteCharacteristicsDatabase() = default; + virtual ~LocalSiteCharacteristicsDatabase() {} + + // Checks the if there's an entry with the key |site_origin| and if so use it + // to initialize |site_characteristic_proto|. Calls |callback| to indicate + // whether or not the initialization has been successful. + virtual void ReadSiteCharacteristicsFromDB( + const std::string& site_origin, + ReadSiteCharacteristicsFromDBCallback callback) = 0; + + // Store an entry in the database, create it if it doesn't exist and update it + // if it does. + virtual void WriteSiteCharacteristicsIntoDB( + const std::string& site_origin, + const SiteCharacteristicsProto& site_characteristic_proto) = 0; + + // Removes some entries from the database. + virtual void RemoveSiteCharacteristicsFromDB( + const std::vector<std::string>& site_origins) = 0; + + // Clear the database, removes every entries that it contains. + virtual void ClearDatabase() = 0; +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_DATABASE_H_
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc new file mode 100644 index 0000000..a90caec --- /dev/null +++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc
@@ -0,0 +1,38 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h" + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h" + +namespace resource_coordinator { + +LocalSiteCharacteristicsNonRecordingDataStore:: + LocalSiteCharacteristicsNonRecordingDataStore( + SiteCharacteristicsDataStore* data_store_for_readers) + : data_store_for_readers_(data_store_for_readers) { + DCHECK(data_store_for_readers_); +} + +LocalSiteCharacteristicsNonRecordingDataStore:: + ~LocalSiteCharacteristicsNonRecordingDataStore() = default; + +std::unique_ptr<SiteCharacteristicsDataReader> +LocalSiteCharacteristicsNonRecordingDataStore::GetReaderForOrigin( + const std::string& origin_str) { + return data_store_for_readers_->GetReaderForOrigin(origin_str); +} + +std::unique_ptr<SiteCharacteristicsDataWriter> +LocalSiteCharacteristicsNonRecordingDataStore::GetWriterForOrigin( + const std::string& origin_str) { + // Return a fake data writer. + SiteCharacteristicsDataWriter* writer = + new LocalSiteCharacteristicsNoopDataWriter(); + return base::WrapUnique(writer); +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h new file mode 100644 index 0000000..83a0aae --- /dev/null +++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h
@@ -0,0 +1,42 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_NON_RECORDING_DATA_STORE_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_NON_RECORDING_DATA_STORE_H_ + +#include "base/macros.h" +#include "chrome/browser/resource_coordinator/site_characteristics_data_store.h" + +namespace resource_coordinator { + +// Specialization of a SiteCharacteristicsDataStore whose +// SiteCharacteristicsDataWriters don't persist observations and whose +// SiteCharacteristicsDataReader are obtained from another +// SiteCharacteristicsDataStore. +class LocalSiteCharacteristicsNonRecordingDataStore + : public SiteCharacteristicsDataStore { + public: + // |data_store_for_readers| should outlive this object. + explicit LocalSiteCharacteristicsNonRecordingDataStore( + SiteCharacteristicsDataStore* data_store_for_readers); + ~LocalSiteCharacteristicsNonRecordingDataStore() override; + + // SiteCharacteristicDataStore: + std::unique_ptr<SiteCharacteristicsDataReader> GetReaderForOrigin( + const std::string& origin_str) override; + std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( + const std::string& origin_str) override; + + private: + // The data store to use to create the readers served by this data store. E.g. + // during an incognito session it should point to the data store used by the + // parent session. + SiteCharacteristicsDataStore* data_store_for_readers_; + + DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsNonRecordingDataStore); +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_NON_RECORDING_DATA_STORE_H_
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc new file mode 100644 index 0000000..578fe91 --- /dev/null +++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc
@@ -0,0 +1,54 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h" + +#include "chrome/browser/resource_coordinator/local_site_characteristics_data_store.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace resource_coordinator { + +using LocalSiteCharacteristicsNonRecordingDataStoreTest = ::testing::Test; + +TEST_F(LocalSiteCharacteristicsNonRecordingDataStoreTest, EndToEnd) { + content::TestBrowserThreadBundle test_browser_thread_bundle; + TestingProfile profile; + const char kTestOrigin[] = "http://www.foo.com"; + LocalSiteCharacteristicsDataStore recording_data_store(&profile); + LocalSiteCharacteristicsNonRecordingDataStore non_recording_data_store( + &recording_data_store); + + // Ensures that the observation made via a writer created by the non + // recording data store aren't recorded. + + auto reader = non_recording_data_store.GetReaderForOrigin(kTestOrigin); + EXPECT_TRUE(reader); + auto fake_writer = non_recording_data_store.GetWriterForOrigin(kTestOrigin); + EXPECT_TRUE(fake_writer); + auto real_writer = recording_data_store.GetWriterForOrigin(kTestOrigin); + EXPECT_TRUE(real_writer); + + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader->UpdatesTitleInBackground()); + fake_writer->NotifySiteLoaded(); + fake_writer->NotifyUpdatesTitleInBackground(); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + reader->UpdatesTitleInBackground()); + + real_writer->NotifySiteLoaded(); + real_writer->NotifyUpdatesTitleInBackground(); + EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + reader->UpdatesTitleInBackground()); + + // These unload events shouldn't be registered, make sure that they aren't by + // unloading the site more time than it has been loaded. + fake_writer->NotifySiteUnloaded(); + fake_writer->NotifySiteUnloaded(); + + real_writer->NotifySiteUnloaded(); +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc new file mode 100644 index 0000000..38bf8760 --- /dev/null +++ b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc
@@ -0,0 +1,28 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h" + +namespace resource_coordinator { + +LocalSiteCharacteristicsNoopDataWriter:: + LocalSiteCharacteristicsNoopDataWriter() = default; +LocalSiteCharacteristicsNoopDataWriter:: + ~LocalSiteCharacteristicsNoopDataWriter() = default; + +void LocalSiteCharacteristicsNoopDataWriter::NotifySiteLoaded() {} + +void LocalSiteCharacteristicsNoopDataWriter::NotifySiteUnloaded() {} + +void LocalSiteCharacteristicsNoopDataWriter:: + NotifyUpdatesFaviconInBackground() {} + +void LocalSiteCharacteristicsNoopDataWriter::NotifyUpdatesTitleInBackground() {} + +void LocalSiteCharacteristicsNoopDataWriter::NotifyUsesAudioInBackground() {} + +void LocalSiteCharacteristicsNoopDataWriter:: + NotifyUsesNotificationsInBackground() {} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h new file mode 100644 index 0000000..c106d16 --- /dev/null +++ b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h
@@ -0,0 +1,35 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_NOOP_DATA_WRITER_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_NOOP_DATA_WRITER_H_ + +#include "base/macros.h" +#include "chrome/browser/resource_coordinator/site_characteristics_data_writer.h" + +namespace resource_coordinator { + +// Specialization of a SiteCharacteristicsDataWriter that doesn't record +// anyting. +class LocalSiteCharacteristicsNoopDataWriter + : public SiteCharacteristicsDataWriter { + public: + LocalSiteCharacteristicsNoopDataWriter(); + ~LocalSiteCharacteristicsNoopDataWriter() override; + + // SiteCharacteristicsDataWriter: + void NotifySiteLoaded() override; + void NotifySiteUnloaded() override; + void NotifyUpdatesFaviconInBackground() override; + void NotifyUpdatesTitleInBackground() override; + void NotifyUsesAudioInBackground() override; + void NotifyUsesNotificationsInBackground() override; + + private: + DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsNoopDataWriter); +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_NOOP_DATA_WRITER_H_
diff --git a/chrome/browser/resource_coordinator/site_characteristics_data_store.h b/chrome/browser/resource_coordinator/site_characteristics_data_store.h index ebca4e4..970dc11 100644 --- a/chrome/browser/resource_coordinator/site_characteristics_data_store.h +++ b/chrome/browser/resource_coordinator/site_characteristics_data_store.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "chrome/browser/resource_coordinator/site_characteristics_data_reader.h" +#include "chrome/browser/resource_coordinator/site_characteristics_data_writer.h" namespace resource_coordinator { @@ -23,6 +24,10 @@ virtual std::unique_ptr<SiteCharacteristicsDataReader> GetReaderForOrigin( const std::string& origin) = 0; + // Returns a SiteCharacteristicsDataWriter for the given origin. + virtual std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( + const std::string& origin_str) = 0; + private: DISALLOW_COPY_AND_ASSIGN(SiteCharacteristicsDataStore); };
diff --git a/chrome/browser/resource_coordinator/site_characteristics_data_writer.h b/chrome/browser/resource_coordinator/site_characteristics_data_writer.h new file mode 100644 index 0000000..00f07823 --- /dev/null +++ b/chrome/browser/resource_coordinator/site_characteristics_data_writer.h
@@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_DATA_WRITER_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_DATA_WRITER_H_ + +namespace resource_coordinator { + +// Pure virtual interface to record the observations made for an origin. +class SiteCharacteristicsDataWriter { + public: + SiteCharacteristicsDataWriter() = default; + virtual ~SiteCharacteristicsDataWriter() {} + + // Records tab load/unload events. + virtual void NotifySiteLoaded() = 0; + virtual void NotifySiteUnloaded() = 0; + + // Records feature usage. + virtual void NotifyUpdatesFaviconInBackground() = 0; + virtual void NotifyUpdatesTitleInBackground() = 0; + virtual void NotifyUsesAudioInBackground() = 0; + virtual void NotifyUsesNotificationsInBackground() = 0; +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_DATA_WRITER_H_
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.css b/chrome/browser/resources/chromeos/login/arc_terms_of_service.css index ad8d4af..c825d9e 100644 --- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.css +++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.css
@@ -20,6 +20,7 @@ padding: 0; } +.arc-tos-disable-skip #arc-tos-skip-button, .arc-tos-loaded .arc-tos-loading, .arc-tos-loaded .arc-tos-error, .arc-tos-loaded #arc-tos-retry-button,
diff --git a/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js b/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js index c77a14c..f198d1c 100644 --- a/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js +++ b/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js
@@ -10,7 +10,7 @@ return { EXTERNAL_API: [ 'setMetricsMode', 'setBackupAndRestoreMode', 'setLocationServicesMode', - 'loadPlayStoreToS', 'setArcManaged' + 'loadPlayStoreToS', 'setArcManaged', 'hideSkipButton' ], /** @override */ @@ -168,6 +168,13 @@ }, /** + * Hides the "Skip" button in the ToS screen. + */ + hideSkipButton: function() { + this.addClass_('arc-tos-disable-skip'); + }, + + /** * Loads Play Store ToS in case country code has been changed or previous * attempt failed. * @param {string} countryCode Country code based on current timezone. @@ -306,7 +313,7 @@ }, /** - * Handles Retry button click. + * Handles Skip button click. */ onSkip: function() { this.enableButtons_(false);
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js index a5d8368..088ad8ca 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js +++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js
@@ -699,6 +699,8 @@ this.recordSelectToSpeakStateChangeEvent_( StateChangeEvent.CANCEL_SELECTION); } + this.onStateChangeRequestedCallbackForTest_ && + this.onStateChangeRequestedCallbackForTest_(); }, /** @@ -1310,9 +1312,9 @@ }, /** - * Fires a mock state change request. + * Function to be called when a state change request is received from the + * accessibilityPrivate API. + * @type {?function()} */ - fireMockStateChangeRequest: function() { - this.onStateChangeRequested_(); - }, + onStateChangeRequestedCallbackForTest_: null, };
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js index 49c264b..909da1f 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js +++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js
@@ -87,8 +87,8 @@ * |this.newCallback| if passed to asynchonous calls. Otherwise, the test * will be finished prematurely. * @param {string} url Url to load and wait for. - * @param {function(chrome.automation.AutomationNode)} callback - * Called once the document is ready. + * @param {function(chrome.automation.AutomationNode)} callback Called with + * the desktop node once the document is ready. */ runWithLoadedTree: function(url, callback) { callback = this.newCallback(callback); @@ -99,7 +99,7 @@ r.removeEventListener('focus', listener, true); r.removeEventListener('loadComplete', listener, true); - callback && callback(evt.target); + callback && callback(r); callback = null; }; r.addEventListener('focus', listener, true);
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_mouse_selection_test.extjs b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_mouse_selection_test.extjs index 1fe758a..b54be63 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_mouse_selection_test.extjs +++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_mouse_selection_test.extjs
@@ -33,6 +33,19 @@ selectToSpeak.fireMockKeyUpEvent( {keyCode: SelectToSpeak.SEARCH_KEY_CODE}); }, + + tapTrayButton(desktop, callback) { + let button = desktop.find({roleType: 'button', attributes: + {className: SELECT_TO_SPEAK_TRAY_CLASS_NAME} + }); + callback = this.newCallback(callback); + selectToSpeak.onStateChangeRequestedCallbackForTest_ = + this.newCallback(() => { + selectToSpeak.onStateChangeRequestedCallbackForTest_ = null; + callback(); + }); + button.doDefault(); + }, } TEST_F('SelectToSpeakMouseSelectionTest', 'SpeaksNodeWhenClicked', @@ -124,7 +137,7 @@ }); TEST_F('SelectToSpeakMouseSelectionTest', - 'SpeaksNodeWhenInSelectionModeAndClicked', function() { + 'SpeaksNodeAfterTrayTapAndMouseClick', function() { this.runWithLoadedTree('data:text/html;charset=utf-8,' + '<p>This is some text</p>', function(desktop) { @@ -144,9 +157,10 @@ screenY: textNode.location.top + 1}; // A state change request should shift us into 'selecting' state from // 'inactive'. - selectToSpeak.fireMockStateChangeRequest(); - selectToSpeak.fireMockMouseDownEvent(event); - selectToSpeak.fireMockMouseUpEvent(event); + this.tapTrayButton(desktop, () => { + selectToSpeak.fireMockMouseDownEvent(event); + selectToSpeak.fireMockMouseUpEvent(event); + }); } ); }); @@ -161,20 +175,20 @@ screenY: textNode.location.top + 1}; // A state change request should shift us into 'selecting' state from // 'inactive'. - selectToSpeak.fireMockStateChangeRequest(); - selectToSpeak.fireMockMouseDownEvent(event); - assertEquals(chrome.accessibilityPrivate.SelectToSpeakState.SELECTING, - selectToSpeak.state_); + this.tapTrayButton(desktop, () => { + selectToSpeak.fireMockMouseDownEvent(event); + assertEquals(SelectToSpeakState.SELECTING, selectToSpeak.state_); - // Another state change puts us back in 'inactive'. - selectToSpeak.fireMockStateChangeRequest(); - assertEquals(chrome.accessibilityPrivate.SelectToSpeakState.INACTIVE, - selectToSpeak.state_); + // Another state change puts us back in 'inactive'. + this.tapTrayButton(desktop, () => { + assertEquals(SelectToSpeakState.INACTIVE, selectToSpeak.state_); + }); + }); } ); }); -TEST_F('SelectToSpeakMouseSelectionTest', 'CancelsSpeechWithStateChange', +TEST_F('SelectToSpeakMouseSelectionTest', 'CancelsSpeechWithTrayTap', function() { this.runWithLoadedTree('data:text/html;charset=utf-8,' + '<p>This is some text</p>', @@ -187,15 +201,14 @@ assertTrue(this.mockTts.currentlySpeaking()); assertEquals(this.mockTts.pendingUtterances().length, 1); this.assertEqualsCollapseWhitespace( - this.mockTts.pendingUtterances()[0], 'This is some text'); + this.mockTts.pendingUtterances()[0], 'This is some text'); // Cancel speech and make sure state resets to INACTIVE. - selectToSpeak.fireMockStateChangeRequest(); - assertFalse(this.mockTts.currentlySpeaking()); - assertEquals(this.mockTts.pendingUtterances().length, 0); - assertEquals( - chrome.accessibilityPrivate.SelectToSpeakState.INACTIVE, - selectToSpeak.state_); + this.tapTrayButton(desktop, () => { + assertFalse(this.mockTts.currentlySpeaking()); + assertEquals(this.mockTts.pendingUtterances().length, 0); + assertEquals(SelectToSpeakState.INACTIVE, selectToSpeak.state_); + }); } )]); let textNode = this.findTextNode(desktop, 'This is some text'); @@ -204,4 +217,38 @@ this.selectRangeForSpeech(event, event); } ); -}); \ No newline at end of file +}); + +TEST_F('SelectToSpeakMouseSelectionTest', 'DoesNotSpeakOnlyTheTrayButton', + function() { + // The tray button itself should not be spoken when clicked in selection mode + // per UI review (but if more elements are being verbalized than just the STS + // tray button, it may be spoken). This is similar to how the stylus may + // act as a laser pointer unless it taps on the stylus options button, which + // always opens on a tap regardless of the stylus behavior selected. + chrome.automation.getDesktop(this.newCallback((desktop) => { + this.tapTrayButton(desktop, () => { + assertEquals(selectToSpeak.state_, SelectToSpeakState.SELECTING); + let button = desktop.find({roleType: 'button', attributes: + {className: SELECT_TO_SPEAK_TRAY_CLASS_NAME} + }); + + // Use the same automation callbacks as Select-to-Speak to make + // sure we actually don't start speech after the hittest and focus + // callbacks are used to check which nodes should be spoken. + desktop.addEventListener( + EventType.MOUSE_RELEASED, this.newCallback((evt) => { + chrome.automation.getFocus(this.newCallback((node) => { + assertEquals(selectToSpeak.state_, SelectToSpeakState.INACTIVE); + assertFalse(this.mockTts.currentlySpeaking()); + assertEquals(this.mockTts.pendingUtterances().length, 0); + })); + }), true); + + let event = {screenX: button.location.left + 1, + screenY: button.location.top + 1}; + selectToSpeak.fireMockMouseDownEvent(event); + selectToSpeak.fireMockMouseUpEvent(event); + }); + })); +});
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index 7f5e06f..cdba9162 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -94,13 +94,6 @@ -webkit-margin-start: calc(var(--cr-button-edge-spacing) * -1); } - paper-toggle-button { - @apply --settings-actionable; - height: var(--settings-row-min-height); - user-select: none; /* Prevents text selection while dragging. */ - width: 36px; - } - span ~ a { -webkit-margin-start: 4px; }
diff --git a/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc b/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc index b6e8704..044bd04 100644 --- a/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc +++ b/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc
@@ -36,11 +36,12 @@ // |*destroyed_tracker| is set to true in the destructor. TestSSLBlockingPage(content::WebContents* web_contents, GURL request_url, + net::SSLInfo ssl_info, bool* destroyed_tracker) : SSLBlockingPage( web_contents, net::ERR_CERT_CONTAINS_ERRORS, - net::SSLInfo(), + ssl_info, request_url, 0, base::Time::NowFromSystemTime(), @@ -72,9 +73,13 @@ // corresponding blocking page is destroyed. void CreateAssociatedBlockingPage(content::NavigationHandle* handle, bool* destroyed_tracker) { + net::SSLInfo ssl_info; + ssl_info.cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); + SSLErrorTabHelper::AssociateBlockingPage( web_contents(), handle->GetNavigationId(), - std::make_unique<TestSSLBlockingPage>(web_contents(), GURL(), + std::make_unique<TestSSLBlockingPage>(web_contents(), GURL(), ssl_info, destroyed_tracker)); } };
diff --git a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc index 0fc5ec4..4ce9167 100644 --- a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
@@ -367,7 +367,6 @@ original_data.disable_reasons(), original_data.incognito_enabled(), original_data.remote_install(), - original_data.all_urls_enabled(), original_data.installed_by_custodian(), original_data.app_launch_ordinal(), original_data.page_ordinal(),
diff --git a/chrome/browser/ui/android/ssl_client_certificate_request.cc b/chrome/browser/ui/android/ssl_client_certificate_request.cc index ec5be1f..f53076a 100644 --- a/chrome/browser/ui/android/ssl_client_certificate_request.cc +++ b/chrome/browser/ui/android/ssl_client_certificate_request.cc
@@ -160,7 +160,7 @@ } static void NotifyClientCertificatesChanged() { - net::CertDatabase::GetInstance()->OnAndroidKeyStoreChanged(); + net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); } static void
diff --git a/chrome/browser/ui/app_list/DEPS b/chrome/browser/ui/app_list/DEPS index 53de606b..226b2da1 100644 --- a/chrome/browser/ui/app_list/DEPS +++ b/chrome/browser/ui/app_list/DEPS
@@ -6,3 +6,10 @@ "+ash/public", ] + +specific_include_rules = { + # TODO(733662): Remove when app_list is migrated. + "crostini_app_model_builder\.cc": [ + "+ash/resources/grit/ash_resources.h", + ], +}
diff --git a/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc b/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc index cd9517b..446fb5d 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc +++ b/chrome/browser/ui/app_list/crostini/crostini_app_model_builder.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/app_list/crostini/crostini_app_model_builder.h" +#include "ash/resources/grit/ash_resources.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_pref_names.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" @@ -11,9 +12,11 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_item.h" +#include "chrome/grit/chrome_unscaled_resources.h" #include "components/crx_file/id_util.h" #include "components/prefs/pref_change_registrar.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" CrostiniAppModelBuilder::CrostiniAppModelBuilder( AppListControllerDelegate* controller)
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index c46297a..077d7cd 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -145,7 +145,7 @@ void ChromeAutofillClient::ShowAutofillSettings() { #if defined(OS_ANDROID) - chrome::android::PreferencesLauncher::ShowAutofillSettings(); + chrome::android::PreferencesLauncher::ShowAutofillSettings(web_contents()); #else Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); if (browser)
diff --git a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm index bce3d2d..16d6856 100644 --- a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm +++ b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
@@ -102,6 +102,7 @@ } bool IsJavaScriptEnabledForProfile(Profile* profile) { + DCHECK(profile); if (!base::FeatureList::IsEnabled( features::kAppleScriptExecuteJavaScriptMenuItem)) return YES;
diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm index 33216fe..f0a489a0 100644 --- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
@@ -105,6 +105,7 @@ webContents_ = webContents; SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(webContents); + profile_ = Profile::FromBrowserContext(webContents->GetBrowserContext()); base::scoped_nsobject<NSNumber> numID( [[NSNumber alloc] initWithInt:session_tab_helper->session_id().id()]); [self setUniqueID:numID]; @@ -127,6 +128,14 @@ } - (void)setURL:(NSString*)aURL { + // If a scripter sets a URL before |webContents_| or |profile_| is set, save + // it at a temporary location. Once they're set, -setURL: will be call again + // with the temporary URL. + if (!profile_ || !webContents_) { + [self setTempURL:aURL]; + return; + } + GURL url(base::SysNSStringToUTF8(aURL)); if (!chrome::mac::IsJavaScriptEnabledForProfile(profile_) && url.SchemeIs(url::kJavaScriptScheme)) { @@ -134,13 +143,6 @@ return; } - // If a scripter sets a URL before the node is added save it at a temporary - // location. - if (!webContents_) { - [self setTempURL:aURL]; - return; - } - // check for valid url. if (!url.is_empty() && !url.is_valid()) { AppleScript::SetError(AppleScript::errInvalidURL);
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm index 5236891..4ff77a0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
@@ -1999,7 +1999,7 @@ } hasInsertionPos_ = NO; BookmarkButton* draggedButton = [BookmarkButton draggedButton]; - if (!draggedButton) { + if (!draggedButton || [draggedButton bookmarkNode] == nullptr) { [self applyLayout:layout_ animated:YES]; return; }
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 98f9472..0443afe 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -169,7 +169,7 @@ {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_MESSAGE}, {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_MESSAGE}, {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_MESSAGE}, - {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_MESSAGE}, + // {CONTENT_SETTINGS_TYPE_POPUPS, No message. intentionally left out}, {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT}, {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_MESSAGE}, @@ -801,7 +801,7 @@ {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_UNBLOCK}, {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_UNBLOCK}, {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_UNBLOCK}, - {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_UNBLOCK}, + {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_REDIRECTS_UNBLOCK}, {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_UNBLOCK}, {CONTENT_SETTINGS_TYPE_SOUND, IDS_BLOCKED_SOUND_UNBLOCK}, {CONTENT_SETTINGS_TYPE_CLIPBOARD_READ, IDS_BLOCKED_CLIPBOARD_UNBLOCK}, @@ -829,7 +829,7 @@ {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_NO_ACTION}, {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_NO_ACTION}, {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_NO_ACTION}, - {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_NO_ACTION}, + {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_REDIRECTS_NO_ACTION}, {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_NO_ACTION}, {CONTENT_SETTINGS_TYPE_SOUND, IDS_BLOCKED_SOUND_NO_ACTION}, {CONTENT_SETTINGS_TYPE_CLIPBOARD_READ, IDS_BLOCKED_CLIPBOARD_NO_ACTION},
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index 77c5011..0934fee 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -112,13 +112,7 @@ {CONTENT_SETTINGS_TYPE_COOKIES, 0}, {CONTENT_SETTINGS_TYPE_IMAGES, IDS_PAGE_INFO_TYPE_IMAGES}, {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_PAGE_INFO_TYPE_JAVASCRIPT}, -#if defined(OS_ANDROID) {CONTENT_SETTINGS_TYPE_POPUPS, IDS_PAGE_INFO_TYPE_POPUPS_REDIRECTS}, -#else - // TODO(csharrison,ericrobinson): Use IDS_PAGE_INFO_TYPE_POPUPS_REDIRECTS on - // desktop as well. - {CONTENT_SETTINGS_TYPE_POPUPS, IDS_PAGE_INFO_TYPE_POPUPS}, -#endif #if BUILDFLAG(ENABLE_PLUGINS) {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_PAGE_INFO_TYPE_FLASH}, #endif
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index f9629a6..d4a0932 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -329,7 +329,19 @@ frame_header_->SchedulePaintForTitle(); } -void BrowserNonClientFrameViewAsh::SizeConstraintsChanged() { +void BrowserNonClientFrameViewAsh::SizeConstraintsChanged() {} + +void BrowserNonClientFrameViewAsh::ActivationChanged(bool active) { + BrowserNonClientFrameView::ActivationChanged(active); + + const bool should_paint_as_active = ShouldPaintAsActive(); + frame_header_->SetPaintAsActive(should_paint_as_active); + + if (hosted_app_button_container_) + hosted_app_button_container_->SetPaintAsActive(should_paint_as_active); + + if (frame_header_origin_text_) + frame_header_origin_text_->SetPaintAsActive(should_paint_as_active); } /////////////////////////////////////////////////////////////////////////////// @@ -339,20 +351,11 @@ if (!ShouldPaint()) return; - const bool should_paint_as_active = ShouldPaintAsActive(); - frame_header_->SetPaintAsActive(should_paint_as_active); - const ash::FrameHeader::Mode header_mode = - should_paint_as_active ? ash::FrameHeader::MODE_ACTIVE - : ash::FrameHeader::MODE_INACTIVE; + ShouldPaintAsActive() ? ash::FrameHeader::MODE_ACTIVE + : ash::FrameHeader::MODE_INACTIVE; frame_header_->PaintHeader(canvas, header_mode); - if (hosted_app_button_container_) - hosted_app_button_container_->SetPaintAsActive(should_paint_as_active); - - if (frame_header_origin_text_) - frame_header_origin_text_->SetPaintAsActive(should_paint_as_active); - if (browser_view()->IsToolbarVisible() && !browser_view()->toolbar()->GetPreferredSize().IsEmpty() && browser_view()->IsTabStripVisible()) {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h index 80dfc1f9..d3073ad 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
@@ -70,6 +70,7 @@ void UpdateWindowIcon() override; void UpdateWindowTitle() override; void SizeConstraintsChanged() override; + void ActivationChanged(bool active) override; // views::View: void OnPaint(gfx::Canvas* canvas) override; @@ -133,6 +134,8 @@ FRIEND_TEST_ALL_PREFIXES(BrowserNonClientFrameViewAshTest, ToggleTabletModeOnMinimizedWindow); FRIEND_TEST_ALL_PREFIXES(BrowserNonClientFrameViewAshTest, + ActiveStateOfButtonMatchesWidget); + FRIEND_TEST_ALL_PREFIXES(BrowserNonClientFrameViewAshTest, RestoreMinimizedBrowserUpdatesCaption); FRIEND_TEST_ALL_PREFIXES(ImmersiveModeControllerAshHostedAppBrowserTest, FrameLayoutToggleTabletMode);
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index 12ba5cb..df850862 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -453,6 +453,19 @@ *test.size_button()->icon_definition_for_test()->name); } +// Regression test for https://crbug.com/839955 +IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewAshTest, + ActiveStateOfButtonMatchesWidget) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + + ash::FrameCaptionButtonContainerView::TestApi test( + GetFrameViewAsh(browser_view)->caption_button_container_); + EXPECT_TRUE(test.size_button()->paint_as_active()); + + browser_view->GetWidget()->Deactivate(); + EXPECT_FALSE(test.size_button()->paint_as_active()); +} + // This is a regression test that session restore minimized browser should // update caption buttons (https://crbug.com/827444). IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewAshTest,
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 18c97e9f..cf8e89f0 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -966,6 +966,29 @@ toolbar_button_provider_ = provider; } +const views::View::Views BrowserView::DesiredPaintOrderForViews( + const views::View::Views views) { + // Ink drops in the toolbar can spread beyond the toolbar bounds, so if the + // bookmark bar is attached, we want it to be below the toolbar so the toolbar + // ink drops draw atop it. This doesn't cause a problem for interactions with + // the bookmark bar, since it does not host any ink drops that spread beyond + // its bounds. If it did, we would need to change how ink drops are drawn. + auto it = std::find(views.cbegin(), views.cend(), bookmark_bar_view_.get()); + if (it == views.cend()) + return views; + + views::View::Views result = {*it}; + for (auto* view : views) { + if (view != *it) + result.push_back(view); + } + return result; +} + +views::View::Views BrowserView::GetChildrenInZOrder() { + return DesiredPaintOrderForViews(views::View::GetChildrenInZOrder()); +} + LocationBar* BrowserView::GetLocationBar() const { return GetLocationBarView(); } @@ -2287,7 +2310,10 @@ new_parent = top_container_; } if (new_parent != bookmark_bar_view_->parent()) { - SetBookmarkBarParent(new_parent); + if (new_parent == nullptr) + bookmark_bar_view_->parent()->RemoveChildView(bookmark_bar_view_.get()); + else + new_parent->AddChildView(bookmark_bar_view_.get()); needs_layout = true; } @@ -2299,38 +2325,6 @@ return needs_layout; } -void BrowserView::SetBookmarkBarParent(views::View* new_parent) { - // Because children are drawn in order, the child order also affects z-order: - // earlier children will appear "below" later ones. This is important for ink - // drops, which are drawn with the z-order of the view that parents them. Ink - // drops in the toolbar can spread beyond the toolbar bounds, so if the - // bookmark bar is attached, we want it to be below the toolbar so the toolbar - // ink drops draw atop it. This doesn't cause a problem for interactions with - // the bookmark bar, since it does not host any ink drops that spread beyond - // its bounds. If it did, we would need to change how ink drops are drawn. - // TODO(bruthig): Consider a more general mechanism for manipulating the - // z-order of the ink drops. - - if (new_parent == this) { - // BookmarkBarView is detached. - const int top_container_index = GetIndexOf(top_container_); - DCHECK_GE(top_container_index, 0); - // |top_container_| contains the toolbar, so putting the bookmark bar ahead - // of it will ensure it's drawn before the toolbar. - AddChildViewAt(bookmark_bar_view_.get(), top_container_index); - } else if (new_parent == top_container_) { - // BookmarkBarView is attached. - - // The toolbar is a child of |top_container_|, so making the bookmark bar - // the first child ensures it's drawn before the toolbar. - new_parent->AddChildViewAt(bookmark_bar_view_.get(), 0); - } else { - DCHECK(!new_parent); - // Bookmark bar is being detached from all views because it is hidden. - bookmark_bar_view_->parent()->RemoveChildView(bookmark_bar_view_.get()); - } -} - bool BrowserView::MaybeShowInfoBar(WebContents* contents) { // TODO(beng): Remove this function once the interface between // InfoBarContainer, DownloadShelfView and WebContents and this
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 323642d..fe5d9f6 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -266,6 +266,13 @@ return toolbar_button_provider_; } + // Returns |views| reordered in the order in which they should be painted, + // suitable for returning in |GetChildrenInZOrder|. This is a public method + // so that |TopContainerView| can call into it, as it has no knowledge of + // what its subviews are. + const views::View::Views DesiredPaintOrderForViews( + const views::View::Views views); + // Overridden from BrowserWindow: void Show() override; void ShowInactive() override; @@ -451,6 +458,7 @@ // Overridden from views::View: const char* GetClassName() const override; + View::Views GetChildrenInZOrder() override; void Layout() override; void OnGestureEvent(ui::GestureEvent* event) override; void ViewHierarchyChanged( @@ -538,11 +546,6 @@ // |contents| can be null. bool MaybeShowBookmarkBar(content::WebContents* contents); - // Moves the bookmark bar view to the specified parent, which may be null, - // |this|, or |top_container_|. Ensures that |top_container_| stays in front - // of |bookmark_bar_view_|. - void SetBookmarkBarParent(views::View* new_parent); - // Prepare to show an Info Bar for the specified WebContents. Returns // true if there is an Info Bar to show and one is supported for this Browser // type, and there should be a subsequent re-layout to show it.
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc index 7658f06..a3cc69a1 100644 --- a/chrome/browser/ui/views/frame/browser_view_unittest.cc +++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -96,15 +96,6 @@ EXPECT_EQ(top_container, browser_view()->GetBookmarkBarView()->parent()); EXPECT_EQ(browser_view(), browser_view()->infobar_container()->parent()); - // Find bar host is at the front of the view hierarchy, followed by the - // infobar container and then top container. - EXPECT_EQ(browser_view()->child_count() - 1, - browser_view()->GetIndexOf(browser_view()->find_bar_host_view())); - EXPECT_EQ(browser_view()->child_count() - 2, - browser_view()->GetIndexOf(browser_view()->infobar_container())); - EXPECT_EQ(browser_view()->child_count() - 3, - browser_view()->GetIndexOf(top_container)); - // Verify basic layout. EXPECT_EQ(0, top_container->x()); EXPECT_EQ(0, top_container->y()); @@ -145,15 +136,6 @@ EXPECT_TRUE(bookmark_bar->IsDetached()); EXPECT_EQ(browser_view(), bookmark_bar->parent()); - // Find bar host is still at the front of the view hierarchy, followed by the - // infobar container and then top container. - EXPECT_EQ(browser_view()->child_count() - 1, - browser_view()->GetIndexOf(browser_view()->find_bar_host_view())); - EXPECT_EQ(browser_view()->child_count() - 2, - browser_view()->GetIndexOf(browser_view()->infobar_container())); - EXPECT_EQ(browser_view()->child_count() - 3, - browser_view()->GetIndexOf(top_container)); - // Bookmark bar layout on NTP. EXPECT_EQ(0, bookmark_bar->x()); EXPECT_EQ(tabstrip->bounds().bottom() + toolbar->height(), bookmark_bar->y()); @@ -175,6 +157,31 @@ BookmarkBarView::DisableAnimationsForTesting(false); } +TEST_F(BrowserViewTest, BookmarkBarPaintsFirst) { + // The bookmark bar should be first in the z-order of its parent so that + // any ink drops from the toolbar can overlap it. + + BookmarkBarView::DisableAnimationsForTesting(true); + + Browser* browser = browser_view()->browser(); + + // Attached bookmark bar. + AddTab(browser, GURL("about:blank")); + chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR); + EXPECT_EQ(browser_view()->top_container()->GetChildrenInZOrder()[0], + browser_view()->GetBookmarkBarView()); + + // If "Always Show Bookmark Bar" is off, the NTP displays the detached + // bookmark bar. + chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR); + NavigateAndCommitActiveTabWithTitle(browser, GURL(chrome::kChromeUINewTabURL), + base::string16()); + EXPECT_EQ(browser_view()->GetChildrenInZOrder()[0], + browser_view()->GetBookmarkBarView()); + + BookmarkBarView::DisableAnimationsForTesting(false); +} + // Test that repeated accelerators are processed or ignored depending on the // commands that they refer to. The behavior for different commands is dictated // by IsCommandRepeatable() in chrome/browser/ui/views/accelerator_table.h.
diff --git a/chrome/browser/ui/views/frame/top_container_view.cc b/chrome/browser/ui/views/frame/top_container_view.cc index 188132c..d3d1627 100644 --- a/chrome/browser/ui/views/frame/top_container_view.cc +++ b/chrome/browser/ui/views/frame/top_container_view.cc
@@ -45,3 +45,8 @@ void TopContainerView::ChildPreferredSizeChanged(views::View* child) { PreferredSizeChanged(); } + +views::View::Views TopContainerView::GetChildrenInZOrder() { + return browser_view_->DesiredPaintOrderForViews( + views::View::GetChildrenInZOrder()); +}
diff --git a/chrome/browser/ui/views/frame/top_container_view.h b/chrome/browser/ui/views/frame/top_container_view.h index 5ffacf8..f21a3b00 100644 --- a/chrome/browser/ui/views/frame/top_container_view.h +++ b/chrome/browser/ui/views/frame/top_container_view.h
@@ -23,6 +23,7 @@ const char* GetClassName() const override; void PaintChildren(const views::PaintInfo& paint_info) override; void ChildPreferredSizeChanged(views::View* child) override; + views::View::Views GetChildrenInZOrder() override; private: // The parent of this view. Not owned.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc index 1108151..a38bc20 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
@@ -151,12 +151,10 @@ //////////////////////////////////////////////////////////////////////////////// // OmniboxMatchCellView: -OmniboxMatchCellView::OmniboxMatchCellView(OmniboxResultView* result_view, - int text_height) +OmniboxMatchCellView::OmniboxMatchCellView(OmniboxResultView* result_view) : is_old_style_answer_(false), is_rich_suggestion_(false), - is_search_type_(false), - text_height_(text_height) { + is_search_type_(false) { AddChildView(icon_view_ = new OmniboxImageView()); AddChildView(image_view_ = new OmniboxImageView()); AddChildView(content_view_ = new OmniboxTextView(result_view)); @@ -171,8 +169,9 @@ OmniboxMatchCellView::~OmniboxMatchCellView() = default; gfx::Size OmniboxMatchCellView::CalculatePreferredSize() const { - int height = text_height_ + - GetVerticalInsets(text_height_, is_old_style_answer_).height(); + const int text_height = content_view_->GetLineHeight(); + int height = text_height + + GetVerticalInsets(text_height, is_old_style_answer_).height(); if (is_rich_suggestion_ || is_old_style_answer_) { height += GetDescriptionHeight(); } @@ -242,14 +241,15 @@ } void OmniboxMatchCellView::LayoutOldStyleAnswer() { + const int text_height = content_view_->GetLineHeight(); int x = GetIconAlignmentOffset() + HorizontalPadding(); - int y = GetVerticalInsets(text_height_, /*is_old_style_answer=*/true).top(); + int y = GetVerticalInsets(text_height, /*is_old_style_answer=*/true).top(); icon_view_->SetSize(icon_view_->CalculatePreferredSize()); icon_view_->SetPosition( - gfx::Point(x, y + (text_height_ - icon_view_->height()) / 2)); + gfx::Point(x, y + (text_height - icon_view_->height()) / 2)); x += icon_view_->width() + HorizontalPadding(); - content_view_->SetBounds(x, y, width() - x, text_height_); - y += text_height_; + content_view_->SetBounds(x, y, width() - x, text_height); + y += text_height; if (image_view_->visible()) { // The description may be multi-line. Using the view height results in // an image that's too large, so we use the line height here instead. @@ -267,14 +267,15 @@ } void OmniboxMatchCellView::LayoutRichSuggestion() { + const int text_height = content_view_->GetLineHeight(); int x = GetIconAlignmentOffset() + HorizontalPadding(); - int y = GetVerticalInsets(text_height_, /*is_old_style_answer=*/false).top(); + int y = GetVerticalInsets(text_height, /*is_old_style_answer=*/false).top(); image_view_->SetImageSize(gfx::Size(kRichImageSize, kRichImageSize)); - image_view_->SetBounds(x, y + (text_height_ * 2 - kRichImageSize) / 2, + image_view_->SetBounds(x, y + (text_height * 2 - kRichImageSize) / 2, kRichImageSize, kRichImageSize); x += kRichImageSize + HorizontalPadding(); - content_view_->SetBounds(x, y, width() - x, text_height_); - y += text_height_; + content_view_->SetBounds(x, y, width() - x, text_height); + y += text_height; int description_width = width() - x; description_view_->SetBounds( x, y, description_width, @@ -283,11 +284,12 @@ } void OmniboxMatchCellView::LayoutSplit() { + const int text_height = content_view_->GetLineHeight(); int x = GetIconAlignmentOffset() + HorizontalPadding(); icon_view_->SetSize(icon_view_->CalculatePreferredSize()); - int y = GetVerticalInsets(text_height_, /*is_old_style_answer=*/false).top(); + int y = GetVerticalInsets(text_height, /*is_old_style_answer=*/false).top(); icon_view_->SetPosition( - gfx::Point(x, y + (text_height_ - icon_view_->height()) / 2)); + gfx::Point(x, y + (text_height - icon_view_->height()) / 2)); x += icon_view_->width() + HorizontalPadding(); int content_width = content_view_->CalculatePreferredSize().width(); int description_width = description_view_->CalculatePreferredSize().width(); @@ -296,13 +298,13 @@ content_width, separator_size.width(), description_width, width() - x, /*description_on_separate_line=*/false, !is_search_type_, &content_width, &description_width); - content_view_->SetBounds(x, y, content_width, text_height_); + content_view_->SetBounds(x, y, content_width, text_height); if (description_width != 0) { x += content_view_->width(); separator_view_->SetSize(separator_size); - separator_view_->SetBounds(x, y, separator_view_->width(), text_height_); + separator_view_->SetBounds(x, y, separator_view_->width(), text_height); x += separator_view_->width(); - description_view_->SetBounds(x, y, description_width, text_height_); + description_view_->SetBounds(x, y, description_width, text_height); } else { description_view_->SetSize(gfx::Size()); separator_view_->SetSize(gfx::Size());
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.h b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.h index f8cbeef..b3aff004 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.h
@@ -17,8 +17,7 @@ class OmniboxMatchCellView : public views::View { public: - explicit OmniboxMatchCellView(OmniboxResultView* result_view, - int text_height); + explicit OmniboxMatchCellView(OmniboxResultView* result_view); ~OmniboxMatchCellView() override; views::ImageView* icon() { return icon_view_; } @@ -49,7 +48,6 @@ bool is_old_style_answer_; bool is_rich_suggestion_; bool is_search_type_; - int text_height_; // Weak pointers for easy reference. views::ImageView* icon_view_; // An icon representing the type or content.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc index 21d388a..4596c52 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -210,14 +210,12 @@ // OmniboxPopupContentsView, public: OmniboxPopupContentsView::OmniboxPopupContentsView( - const gfx::FontList& font_list, OmniboxView* omnibox_view, OmniboxEditModel* edit_model, LocationBarView* location_bar_view) : model_(new OmniboxPopupModel(this, edit_model)), omnibox_view_(omnibox_view), location_bar_view_(location_bar_view), - font_list_(font_list), start_margin_(0), end_margin_(0) { // The contents is owned by the LocationBarView. @@ -227,7 +225,7 @@ InitializeWideShadows(); for (size_t i = 0; i < AutocompleteResult::GetMaxMatches(); ++i) { - OmniboxResultView* result_view = new OmniboxResultView(this, i, font_list_); + OmniboxResultView* result_view = new OmniboxResultView(this, i); result_view->SetVisible(false); AddChildViewAt(result_view, static_cast<int>(i)); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h index 806132e3..85511e7 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
@@ -26,8 +26,7 @@ // A view representing the contents of the autocomplete popup. class OmniboxPopupContentsView : public views::View, public OmniboxPopupView { public: - OmniboxPopupContentsView(const gfx::FontList& font_list, - OmniboxView* omnibox_view, + OmniboxPopupContentsView(OmniboxView* omnibox_view, OmniboxEditModel* edit_model, LocationBarView* location_bar_view); ~OmniboxPopupContentsView() override; @@ -123,9 +122,6 @@ LocationBarView* location_bar_view_; - // The font list used for result rows, based on the omnibox font list. - gfx::FontList font_list_; - int start_margin_; int end_margin_;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 03fd742..2ce1ed0 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -44,7 +44,6 @@ #include "ui/gfx/paint_vector_icon.h" namespace { - // The vertical padding to provide each RenderText in addition to the height of // the font. Where possible, RenderText uses this additional space to vertically // center the cap height of the font instead of centering the entire font. @@ -85,20 +84,15 @@ // OmniboxResultView, public: OmniboxResultView::OmniboxResultView(OmniboxPopupContentsView* model, - int model_index, - const gfx::FontList& font_list) + int model_index) : model_(model), model_index_(model_index), is_hovered_(false), - font_height_(std::max( - font_list.GetHeight(), - font_list.DeriveWithWeight(gfx::Font::Weight::BOLD).GetHeight())), animation_(new gfx::SlideAnimation(this)) { CHECK_GE(model_index, 0); - AddChildView(suggestion_view_ = - new OmniboxMatchCellView(this, GetTextHeight())); - AddChildView(keyword_view_ = new OmniboxMatchCellView(this, GetTextHeight())); + AddChildView(suggestion_view_ = new OmniboxMatchCellView(this)); + AddChildView(keyword_view_ = new OmniboxMatchCellView(this)); keyword_view_->icon()->EnableCanvasFlippingForRTLUI(true); keyword_view_->icon()->SetImage(gfx::CreateVectorIcon( @@ -122,8 +116,11 @@ // Set up 'switch to tab' button. if (match.has_tab_match && !match_.associated_keyword.get()) { - suggestion_tab_switch_button_ = - std::make_unique<OmniboxTabSwitchButton>(model_, this, GetTextHeight()); + // TODO(dschuyler): the kVerticalPadding is added here, and again within + // OmniboxTabSwitchButton. Should that just be done once? + suggestion_tab_switch_button_ = std::make_unique<OmniboxTabSwitchButton>( + model_, this, + suggestion_view_->content()->GetLineHeight() + kVerticalPadding); suggestion_tab_switch_button_->set_owned_by_client(); AddChildView(suggestion_tab_switch_button_.get()); } else { @@ -323,10 +320,6 @@ //////////////////////////////////////////////////////////////////////////////// // OmniboxResultView, private: -int OmniboxResultView::GetTextHeight() const { - return font_height_ + kVerticalPadding; -} - gfx::Image OmniboxResultView::GetIcon() const { return model_->GetMatchIcon(match_, GetColor(OmniboxPart::RESULTS_ICON)); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.h b/chrome/browser/ui/views/omnibox/omnibox_result_view.h index f808bbe..432cfa2b 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
@@ -38,9 +38,7 @@ private gfx::AnimationDelegate, public views::ButtonListener { public: - OmniboxResultView(OmniboxPopupContentsView* model, - int model_index, - const gfx::FontList& font_list); + OmniboxResultView(OmniboxPopupContentsView* model, int model_index); ~OmniboxResultView() override; // Helper to get the color for |part| using the current state and tint. @@ -112,9 +110,6 @@ // Whether this view is in the hovered state. bool is_hovered_; - // Cache the font height as a minor optimization. - int font_height_; - // The data this class is built to display (the "Omnibox Result"). AutocompleteMatch match_;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc index 5b8d4a4..96dc8b0 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc
@@ -29,7 +29,10 @@ class TestOmniboxPopupContentsView : public OmniboxPopupContentsView { public: explicit TestOmniboxPopupContentsView(OmniboxEditModel* edit_model) - : OmniboxPopupContentsView(gfx::FontList(), nullptr, edit_model, nullptr), + : OmniboxPopupContentsView( + /*omnibox_view=*/nullptr, + edit_model, + /*location_bar_view=*/nullptr), selected_index_(0) {} void SetSelectedLine(size_t index) override { selected_index_ = index; } @@ -55,8 +58,8 @@ nullptr, nullptr, std::make_unique<TestOmniboxClient>()); popup_view_ = std::make_unique<TestOmniboxPopupContentsView>(edit_model_.get()); - result_view_ = new OmniboxResultView(popup_view_.get(), - kTestResultViewIndex, gfx::FontList()); + result_view_ = + new OmniboxResultView(popup_view_.get(), kTestResultViewIndex); // Create a widget and assign bounds to support calls to HitTestPoint. widget_.reset(new views::Widget);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc index d243db0..46f6582 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
@@ -233,21 +233,20 @@ void OmniboxTextView::SetText(const SuggestionAnswer::ImageLine& line) { wrap_text_lines_ = line.num_text_lines() > 1; - // This assumes that the first text type in the line can be used to specify - // the font for all the text fields in the line. For now this works but - // eventually it may be necessary to get RenderText to support multiple font - // sizes or use multiple RenderTexts. render_text_.reset(); - render_text_ = CreateText(line, GetFontForType(line.text_fields()[0].type())); + render_text_ = CreateText(line); UpdateLineHeight(); } std::unique_ptr<gfx::RenderText> OmniboxTextView::CreateText( - const SuggestionAnswer::ImageLine& line, - const gfx::FontList& font_list) const { + const SuggestionAnswer::ImageLine& line) const { std::unique_ptr<gfx::RenderText> destination = CreateRenderText(base::string16()); - destination->SetFontList(font_list); + // This assumes that the first text type in the line can be used to specify + // the font for all the text fields in the line. For now this works but + // eventually it may be necessary to get RenderText to support multiple font + // sizes or use multiple RenderTexts. + destination->SetFontList(GetFontForType(line.text_fields()[0].type())); for (const SuggestionAnswer::TextField& text_field : line.text_fields()) AppendText(destination.get(), text_field.text(), text_field.type());
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.h b/chrome/browser/ui/views/omnibox/omnibox_text_view.h index ee16eb19..15d3e32 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.h
@@ -63,8 +63,7 @@ // Creates a RenderText with text and styling from the image line. std::unique_ptr<gfx::RenderText> CreateText( - const SuggestionAnswer::ImageLine& line, - const gfx::FontList& font_list) const; + const SuggestionAnswer::ImageLine& line) const; // Adds |text| to |destination|. |text_type| is an index into the // kTextStyles constant defined in the .cc file and is used to style the text,
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index f50c24d..7461c8a 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -159,8 +159,8 @@ if (location_bar_view_) { // Initialize the popup view using the same font. - popup_view_.reset(new OmniboxPopupContentsView(GetFontList(), this, model(), - location_bar_view_)); + popup_view_.reset( + new OmniboxPopupContentsView(this, model(), location_bar_view_)); } // Override the default FocusableBorder from Textfield, since the
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index a01419a0..e106328f 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -1090,47 +1090,46 @@ PaintTabBackgroundStroke(canvas, fill_path, stroke_path, active, stroke_color); } - return; - } + } else { + BackgroundCache& cache = + active ? background_active_cache_ : background_inactive_cache_; + if (!cache.CacheKeyMatches(canvas->image_scale(), size(), active_color, + inactive_color, stroke_color)) { + gfx::Path fill_path = + GetInteriorPath(canvas->image_scale(), size(), endcap_width); + gfx::Path stroke_path = GetBorderPath(canvas->image_scale(), false, false, + endcap_width, size()); + cc::PaintRecorder recorder; - BackgroundCache& cache = - active ? background_active_cache_ : background_inactive_cache_; - if (!cache.CacheKeyMatches(canvas->image_scale(), size(), active_color, - inactive_color, stroke_color)) { - gfx::Path fill_path = - GetInteriorPath(canvas->image_scale(), size(), endcap_width); - gfx::Path stroke_path = GetBorderPath(canvas->image_scale(), false, false, - endcap_width, size()); - cc::PaintRecorder recorder; + { + gfx::Canvas cache_canvas( + recorder.beginRecording(size().width(), size().height()), + canvas->image_scale()); + PaintTabBackgroundFill(&cache_canvas, fill_path, active, + paint_hover_effect, active_color, inactive_color, + fill_id, y_offset); + cache.fill_record = recorder.finishRecordingAsPicture(); + } + if (TabStrip::ShouldDrawStrokes()) { + gfx::Canvas cache_canvas( + recorder.beginRecording(size().width(), size().height()), + canvas->image_scale()); + PaintTabBackgroundStroke(&cache_canvas, fill_path, stroke_path, active, + stroke_color); + cache.stroke_record = recorder.finishRecordingAsPicture(); + } - { - gfx::Canvas cache_canvas( - recorder.beginRecording(size().width(), size().height()), - canvas->image_scale()); - PaintTabBackgroundFill(&cache_canvas, fill_path, active, - paint_hover_effect, active_color, inactive_color, - fill_id, y_offset); - cache.fill_record = recorder.finishRecordingAsPicture(); + cache.SetCacheKey(canvas->image_scale(), size(), active_color, + inactive_color, stroke_color); } + + canvas->sk_canvas()->drawPicture(cache.fill_record); if (TabStrip::ShouldDrawStrokes()) { - gfx::Canvas cache_canvas( - recorder.beginRecording(size().width(), size().height()), - canvas->image_scale()); - PaintTabBackgroundStroke(&cache_canvas, fill_path, stroke_path, active, - stroke_color); - cache.stroke_record = recorder.finishRecordingAsPicture(); + gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr); + if (clip) + canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true); + canvas->sk_canvas()->drawPicture(cache.stroke_record); } - - cache.SetCacheKey(canvas->image_scale(), size(), active_color, - inactive_color, stroke_color); - } - - canvas->sk_canvas()->drawPicture(cache.fill_record); - if (TabStrip::ShouldDrawStrokes()) { - gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr); - if (clip) - canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true); - canvas->sk_canvas()->drawPicture(cache.stroke_record); } if (!active) @@ -1195,25 +1194,33 @@ } void Tab::PaintSeparator(gfx::Canvas* canvas, SkColor inactive_color) { - if (MD::GetMode() != MD::MATERIAL_REFRESH || IsMouseHovered()) + if (MD::GetMode() != MD::MATERIAL_REFRESH) return; - // If the tab to the left is either active or the mouse is hovered over it, - // the separator on this tab should not be painted. + // If the tab to the left is active, the separator on this tab should not be + // painted. Tab* previous_tab = controller_->GetAdjacentTab(this, TabController::BACKWARD); - if (previous_tab && - (previous_tab->IsActive() || previous_tab->IsMouseHovered())) + if (previous_tab && previous_tab->IsActive()) return; const int tab_height = GetContentsBounds().height(); gfx::RectF separator_bounds; separator_bounds.set_size(gfx::SizeF(1, 16)); separator_bounds.set_origin(gfx::PointF( - (tab_height - separator_bounds.height()) / 2, GetTabEndcapWidth() / 2)); + GetTabEndcapWidth() / 2, (tab_height - separator_bounds.height()) / 2)); + // The following will paint the separator using an opacity that should + // cross-fade with the maximum hover animation value of this tab or the + // tab to the left. This will have the effect of fading out the separator + // while this tab's or the tab to the left's hover animation is progressing. + const double max_hover_value = std::max( + hover_controller_.GetAnimationValue(), + previous_tab ? previous_tab->hover_controller()->GetAnimationValue() : 0); cc::PaintFlags flags; flags.setAntiAlias(true); - flags.setColor(color_utils::BlendTowardOppositeLuma(inactive_color, 0x5a)); + flags.setColor( + SkColorSetA(color_utils::BlendTowardOppositeLuma(inactive_color, 0x5a), + gfx::Tween::IntValueBetween(max_hover_value, 255, 0))); canvas->DrawRect(separator_bounds, flags); } @@ -1295,7 +1302,7 @@ int title_width = (!showing_icon_ + !showing_alert_indicator_) * favicon_width; if ((!hide_inactive_close_button || - (show_close_button_on_hover && IsMouseHovered())) && + (show_close_button_on_hover && hover_controller_.ShouldDraw())) && (title_width + close_button_width + extra_padding <= available_width)) { showing_close_button_ = true;
diff --git a/chrome/browser/ui/views/tabs/tab_close_button.cc b/chrome/browser/ui/views/tabs/tab_close_button.cc index c87643b3..2dfe8d1 100644 --- a/chrome/browser/ui/views/tabs/tab_close_button.cc +++ b/chrome/browser/ui/views/tabs/tab_close_button.cc
@@ -18,6 +18,8 @@ #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/material_design/material_design_controller.h" +#include "ui/gfx/animation/tween.h" +#include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" @@ -104,6 +106,12 @@ return "TabCloseButton"; } +void TabCloseButton::PaintButtonContents(gfx::Canvas* canvas) { + canvas->SaveLayerAlpha(GetOpacity()); + views::ImageButton::PaintButtonContents(canvas); + canvas->Restore(); +} + views::View* TabCloseButton::TargetForRect(views::View* root, const gfx::Rect& rect) { CHECK_EQ(root, this); @@ -137,6 +145,14 @@ return true; } +SkAlpha TabCloseButton::GetOpacity() { + if (MD::GetMode() != MD::MATERIAL_REFRESH && !IsMouseHovered()) + return SK_AlphaOPAQUE; + const double animation_value = + static_cast<Tab*>(parent())->hover_controller()->GetAnimationValue(); + return gfx::Tween::IntValueBetween(animation_value, 0, 255); +} + void TabCloseButton::GenerateImages(bool is_touch, SkColor normal_icon_color, SkColor hover_pressed_icon_color,
diff --git a/chrome/browser/ui/views/tabs/tab_close_button.h b/chrome/browser/ui/views/tabs/tab_close_button.h index 12cd81cb..932d189 100644 --- a/chrome/browser/ui/views/tabs/tab_close_button.h +++ b/chrome/browser/ui/views/tabs/tab_close_button.h
@@ -48,11 +48,18 @@ void OnGestureEvent(ui::GestureEvent* event) override; const char* GetClassName() const override; + protected: + void PaintButtonContents(gfx::Canvas* canvas) override; + private: // views::MaskedTargeterDelegate: views::View* TargetForRect(views::View* root, const gfx::Rect& rect) override; bool GetHitTestMask(gfx::Path* mask) const override; + // In material refresh mode, calculates opacity based on the current state of + // the hover animation on the parent tab. + SkAlpha GetOpacity(); + void GenerateImages(bool is_touch, SkColor normal_icon_color, SkColor hover_pressed_icon_color,
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc index 783491f..31a2a0e 100644 --- a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h" +#include "base/command_line.h" #include "base/i18n/timezone.h" #include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/chromeos/arc/arc_util.h" @@ -223,6 +224,12 @@ // ToS then prefs::kArcEnabled is automatically reset in ArcSessionManager. arc::SetArcPlayStoreEnabledForProfile(profile, true); + // Hide the Skip button if the ToS screen can not be skipped during OOBE. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableArcOobeOptinNoSkip)) { + CallJS("hideSkipButton"); + } + action_taken_ = false; ShowScreen(kScreenId);
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 5c9f0f0..412e677e 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -109,6 +109,7 @@ keyboard_delegate_ = std::make_unique<TestKeyboardDelegate>(); UiInitialState ui_initial_state; + ui_initial_state.create_tabs_view = true; ui_ = std::make_unique<Ui>(this, nullptr, keyboard_delegate_.get(), text_input_delegate_.get(), nullptr, ui_initial_state);
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h index 0c6cdfc..7aef648 100644 --- a/chrome/browser/vr/ui.h +++ b/chrome/browser/vr/ui.h
@@ -51,7 +51,6 @@ bool supports_selection = true; bool needs_keyboard_update = false; bool is_standalone_vr_device = false; - // TODO(crbug.com/838937): Enable tabs. bool create_tabs_view = false; };
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index fde31eb0..9c2c9cbd 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -59,10 +59,12 @@ if (is_chromeos) { sources += [ "$root_gen_dir/ash/components/resources/ash_components_resources_${percent}_percent.pak", + "$root_gen_dir/ash/resources/ash_resources_${percent}_percent.pak", "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_${percent}_percent.pak", ] deps += [ "//ash/components/resources", + "//ash/resources", "//ui/chromeos/resources", ] }
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index da90176..231520b 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -567,13 +567,11 @@ // Otherwise, it'll be treated as a sub-key-system of normal // kExternalClearKeyKeySystem. See MultipleCdmTypes test in // ECKEncryptedMediaTest. - // TODO(crbug.com/835009): Update when ECK supports more encryption - // schemes. cdms->push_back(content::CdmInfo( media::kClearKeyCdmDisplayName, media::kClearKeyCdmDifferentGuid, base::Version("0.1.0.0"), clear_key_cdm_path, media::kClearKeyCdmFileSystemId, {}, supports_persistent_license, - {media::EncryptionMode::kCenc}, + {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}, kExternalClearKeyDifferentGuidTestKeySystem, false)); // Supported codecs are hard-coded in ExternalClearKeyProperties. @@ -581,7 +579,8 @@ media::kClearKeyCdmDisplayName, media::kClearKeyCdmGuid, base::Version("0.1.0.0"), clear_key_cdm_path, media::kClearKeyCdmFileSystemId, {}, supports_persistent_license, - {media::EncryptionMode::kCenc}, kExternalClearKeyKeySystem, true)); + {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs}, + kExternalClearKeyKeySystem, true)); } #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 2e60b5e..b4e894ad 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2908,6 +2908,7 @@ "../browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc", "../browser/resource_coordinator/background_tab_navigation_throttle_unittest.cc", "../browser/resource_coordinator/discard_metrics_lifecycle_unit_observer_unittest.cc", + "../browser/resource_coordinator/leveldb_site_characteristics_database_unittest.cc", "../browser/resource_coordinator/lifecycle_unit_base_unittest.cc", "../browser/resource_coordinator/lifecycle_unit_unittest.cc", "../browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc", @@ -2916,6 +2917,7 @@ "../browser/resource_coordinator/local_site_characteristics_data_unittest_utils.cc", "../browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h", "../browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc", + "../browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc", "../browser/resource_coordinator/tab_activity_watcher_unittest.cc", "../browser/resource_coordinator/tab_lifecycle_unit_source_unittest.cc", "../browser/resource_coordinator/tab_lifecycle_unit_unittest.cc", @@ -3250,6 +3252,7 @@ deps += [ "//ash:test_support_with_content", "//ash/public/cpp/resources:ash_public_unscaled_resources", + "//ash/resources", "//ash/strings", ] } @@ -4882,6 +4885,7 @@ "//ash:interactive_ui_test_support", "//ash/app_list/presenter:test_support", "//ash/public/interfaces:test_interfaces", + "//ash/resources", "//chrome/browser/media/router:test_support", "//chromeos", "//mojo/edk",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 7bb94ac..23a5547 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -26,7 +26,6 @@ "javatests/src/org/chromium/chrome/test/util/BookmarkTestUtil.java", "javatests/src/org/chromium/chrome/test/util/browser/compositor/layouts/DisableChromeAnimations.java", "javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java", - "javatests/src/org/chromium/chrome/test/util/browser/ChromeHome.java", "javatests/src/org/chromium/chrome/test/util/browser/ChromeModernDesign.java", "javatests/src/org/chromium/chrome/test/util/browser/Features.java", "javatests/src/org/chromium/chrome/test/util/browser/LocationSettingsTestUtil.java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/ChromeHome.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/ChromeHome.java deleted file mode 100644 index 98c3d8a5..0000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/ChromeHome.java +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.test.util.browser; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; - -import android.os.StrictMode; - -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import org.chromium.base.test.util.AnnotationRule; -import org.chromium.base.test.util.Restriction; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; -import org.chromium.chrome.browser.util.FeatureUtilities; -import org.chromium.ui.test.util.UiRestriction; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Utility annotation and rule to enable or disable ChromeHome. Handles setting and resetting the - * feature flag and the preference. - * - * @see ChromeHome.Processor - * @see FeatureUtilities#isChromeHomeEnabled() - */ -public interface ChromeHome { - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD, ElementType.TYPE}) - @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - @Features.EnableFeatures(ChromeFeatureList.CHROME_HOME) - @interface Enable {} - - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD, ElementType.TYPE}) - @Features.DisableFeatures(ChromeFeatureList.CHROME_HOME) - @interface Disable {} - - /** - * Rule to handle setting and resetting the cached feature state for ChromeHome. Can be used by - * explicitly calling methods ({@link #setPrefs(boolean)} and {@link #clearTestState()}) or by - * using the {@link ChromeHome.Enable} and {@link ChromeHome.Disable} annotations on tests. - */ - class Processor extends AnnotationRule { - private Boolean mOldState; - - public Processor() { - super(ChromeHome.Enable.class, ChromeHome.Disable.class); - } - - @Override - public Statement apply(Statement base, Description description) { - Statement wrappedStatement = super.apply(base, description); - return getAnnotations().isEmpty() ? base : wrappedStatement; - } - - @Override - protected void before() throws Throwable { - boolean featureEnabled = getClosestAnnotation() instanceof ChromeHome.Enable; - setPrefs(featureEnabled); - } - - @Override - protected void after() { - clearTestState(); - } - - public void setPrefs(boolean enabled) { - // Chrome relies on a shared preference to determine if the ChromeHome feature is - // enabled during start up, so we need to manually set the preference to enable - // ChromeHome before starting Chrome. - ChromePreferenceManager prefsManager = ChromePreferenceManager.getInstance(); - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - mOldState = prefsManager.isChromeHomeEnabled(); - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } - - FeatureUtilities.resetChromeHomeEnabledForTests(); - - // The native library should not be enabled yet, so we set the preference here and - // cache it by checking for the feature. Ideally we instead would call - // FeatureUtilities.cacheChromeHomeEnabled() - prefsManager.setChromeHomeEnabled(enabled); - assertEquals(enabled, FeatureUtilities.isChromeHomeEnabled()); - } - - public void clearTestState() { - assertNotNull(mOldState); - ChromePreferenceManager.getInstance().setChromeHomeEnabled(mOldState); - } - } -}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/Features.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/Features.java index a67843a..d4a81a3c 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/Features.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/Features.java
@@ -34,7 +34,7 @@ * @Rule * public Features.Processor processor = new Features.JUnitProcessor(); * - * @Features.EnableFeatures(ChromeFeatureList.CHROME_HOME) + * @Features.EnableFeatures(ChromeFeatureList.CHROME_MODERN_DESIGN) * public void testFoo() { ... } * } * </pre>
diff --git a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc index 9860507..73a9c9f8 100644 --- a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc
@@ -207,6 +207,15 @@ } Status ChromeDesktopImpl::QuitImpl() { + Status status = devtools_websocket_client_->ConnectIfNecessary(); + if (status.IsOk()) { + status = devtools_websocket_client_->SendCommandAndIgnoreResponse( + "Browser.close", base::DictionaryValue()); + if (status.IsOk() && process_.WaitForExitWithTimeout( + base::TimeDelta::FromSeconds(10), nullptr)) + return status; + } + // If the Chrome session uses a custom user data directory, try sending a // SIGTERM signal before SIGKILL, so that Chrome has a chance to write // everything back out to the user data directory and exit cleanly. If we're
diff --git a/chromecast/base/init_command_line_shlib.h b/chromecast/base/init_command_line_shlib.h index 0ef1354c..dcf295d 100644 --- a/chromecast/base/init_command_line_shlib.h +++ b/chromecast/base/init_command_line_shlib.h
@@ -23,8 +23,8 @@ // THREAD SAFTEY: Accessing the CommandLine instance for this process is // technically not threadsafe when using the component build. However, the // instance is initialized on the main thread before any other threads are -// started (see content/app/content_main_runner.cc), so accessing this instance -// on those threads for read-operations is safe in practice. +// started (see content/app/content_main_runner_impl.cc), so accessing this +// instance on those threads for read-operations is safe in practice. void InitCommandLineShlib(const std::vector<std::string>& argv); } // namespace chromecast
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index b4f5914..a8cf538 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -303,6 +303,9 @@ // Enables starting the ARC instance upon session start. const char kEnableArc[] = "enable-arc"; +// Enables "hide Skip button" for ARC setup in the OOBE flow. +const char kEnableArcOobeOptinNoSkip[] = "enable-arc-oobe-optin-no-skip"; + // Enables using a random url for captive portal detection. const char kEnableCaptivePortalRandomUrl[] = "enable-captive-portal-random-url";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index c09dff7..a750afa 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -89,6 +89,7 @@ CHROMEOS_EXPORT extern const char kDisableWakeOnWifi[]; CHROMEOS_EXPORT extern const char kDisableZipArchiverUnpacker[]; CHROMEOS_EXPORT extern const char kEnableArc[]; +CHROMEOS_EXPORT extern const char kEnableArcOobeOptinNoSkip[]; CHROMEOS_EXPORT extern const char kEnableCaptivePortalRandomUrl[]; CHROMEOS_EXPORT extern const char kEnableCastReceiver[]; CHROMEOS_EXPORT extern const char kEnableChromeVoxArcSupport[];
diff --git a/chromeos/dbus/smb_provider_client.cc b/chromeos/dbus/smb_provider_client.cc index 6ae80c8..0f9a487 100644 --- a/chromeos/dbus/smb_provider_client.cc +++ b/chromeos/dbus/smb_provider_client.cc
@@ -236,7 +236,7 @@ options.set_mount_id(mount_id); options.set_source_path(source_path.value()); options.set_target_path(target_path.value()); - CallDefaultMethod(smbprovider::kCopyEntryMethod, options, &callback); + CallCopyEntryMethod(options, std::move(callback)); } void GetDeleteList(int32_t mount_id, @@ -328,6 +328,21 @@ std::move(*callback))); } + // Calls the CopyEntry D-Bus method with no timeout, passing the |protobuf| as + // an argument. Uses the default callback handler to process |callback|. + void CallCopyEntryMethod(const google::protobuf::MessageLite& protobuf, + StatusCallback callback) { + dbus::MethodCall method_call(smbprovider::kSmbProviderInterface, + smbprovider::kCopyEntryMethod); + dbus::MessageWriter writer(&method_call); + writer.AppendProtoAsArrayOfBytes(protobuf); + proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE, + base::BindOnce(&SmbProviderClientImpl::HandleDefaultCallback, + GetWeakPtr(), method_call.GetMember(), + std::move(callback))); + } + // Handles D-Bus callback for mount. void HandleMountCallback(MountCallback callback, dbus::Response* response) { if (!response) {
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc index 69c96bb..3abad2d 100644 --- a/chromeos/system/statistics_provider.cc +++ b/chromeos/system/statistics_provider.cc
@@ -106,8 +106,8 @@ // devices. It's known *not* to be present on caroline. // TODO(tnagel): Remove "Product_S/N" after all devices that have it are AUE. const char* const kMachineInfoSerialNumberKeys[] = { - "Product_S/N", // Samsung legacy - kSerialNumberKey, // VPD v2+ devices + "Product_S/N", // Samsung legacy + "serial_number", // VPD v2+ devices (Samsung: caroline and later) }; // Gets ListValue from given |dictionary| by given |key| and (unless |result| is @@ -198,7 +198,7 @@ const char kOffersGroupCodeKey[] = "gbind_attribute"; const char kRlzBrandCodeKey[] = "rlz_brand_code"; const char kRegionKey[] = "region"; -const char kSerialNumberKey[] = "serial_number"; +const char kSerialNumberKeyForTest[] = "serial_number"; const char kInitialLocaleKey[] = "initial_locale"; const char kInitialTimezoneKey[] = "initial_timezone"; const char kKeyboardLayoutKey[] = "keyboard_layout";
diff --git a/chromeos/system/statistics_provider.h b/chromeos/system/statistics_provider.h index d466392..3a21c12 100644 --- a/chromeos/system/statistics_provider.h +++ b/chromeos/system/statistics_provider.h
@@ -84,9 +84,10 @@ CHROMEOS_EXPORT extern const char kInitialTimezoneKey[]; CHROMEOS_EXPORT extern const char kKeyboardLayoutKey[]; -// Serial number key (only VPD v2+ devices). Use GetEnterpriseMachineID() to -// cover legacy devices. -CHROMEOS_EXPORT extern const char kSerialNumberKey[]; +// Serial number key (VPD v2+ devices, Samsung: caroline and later) for use in +// tests. Outside of tests GetEnterpriseMachineID() is the backward-compatible +// way to obtain the serial number. +CHROMEOS_EXPORT extern const char kSerialNumberKeyForTest[]; // This interface provides access to Chrome OS statistics. class CHROMEOS_EXPORT StatisticsProvider { @@ -116,12 +117,11 @@ virtual bool GetMachineFlag(const std::string& name, bool* result) = 0; // Returns the machine serial number after examining a set of well-known - // keys. In case no serial is found (possibly due to the device having already - // been enrolled or claimed by a local user), an empty string is returned. - // Caveat: For lumpy, the last letter is ommitted from the serial number for - // historical reasons. - // TODO(tnagel): Drop "Enterprise" from the method name and remove lumpy - // special casing after lumpy EOL. + // keys. In case no serial is found an empty string is returned. + // Caveat: On older Samsung devices, the last letter is omitted from the + // serial number for historical reasons. This is fine. + // TODO(tnagel): Drop "Enterprise" from the method name and remove Samsung + // special casing after kevin EOL. std::string GetEnterpriseMachineID(); // Cancels any pending file operations.
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index 242857d..40c8b8e 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -55,6 +55,8 @@ const base::Feature kAutofillRationalizeFieldTypePredictions{ "AutofillRationalizeFieldTypePredictions", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kAutofillSuggestInvalidProfileData{ + "AutofillSuggestInvalidProfileData", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kAutofillSuppressDisusedAddresses{ "AutofillSuppressDisusedAddresses", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kAutofillSuppressDisusedCreditCards{ @@ -68,6 +70,8 @@ const base::Feature kAutofillUpstreamUpdatePromptExplanation{ "AutofillUpstreamUpdatePromptExplanation", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kAutofillVoteUsingInvalidProfileData{ + "AutofillVoteUsingInvalidProfileData", base::FEATURE_ENABLED_BY_DEFAULT}; const char kCreditCardSigninPromoImpressionLimitParamKey[] = "impression_limit"; const char kAutofillCreditCardPopupBackgroundColorKey[] = "background_color";
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h index 887fbb8..e33d3afd1 100644 --- a/components/autofill/core/browser/autofill_experiments.h +++ b/components/autofill/core/browser/autofill_experiments.h
@@ -39,12 +39,14 @@ extern const base::Feature kAutofillExpandedPopupViews; extern const base::Feature kAutofillPreferServerNamePredictions; extern const base::Feature kAutofillRationalizeFieldTypePredictions; +extern const base::Feature kAutofillSuggestInvalidProfileData; extern const base::Feature kAutofillSuppressDisusedAddresses; extern const base::Feature kAutofillSuppressDisusedCreditCards; extern const base::Feature kAutofillUpstreamAllowAllEmailDomains; extern const base::Feature kAutofillUpstreamSendDetectedValues; extern const base::Feature kAutofillUpstreamSendPanFirstSix; extern const base::Feature kAutofillUpstreamUpdatePromptExplanation; +extern const base::Feature kAutofillVoteUsingInvalidProfileData; extern const char kCreditCardSigninPromoImpressionLimitParamKey[]; extern const char kAutofillCreditCardLastUsedDateShowExpirationDateKey[]; extern const char kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey[];
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 6f9df9f..bef60c5 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -604,7 +604,10 @@ friend class AutofillManagerTest; friend class FormStructureBrowserTest; + friend class GetMatchingTypesTest; friend class SaveCardBubbleViewsBrowserTestBase; + FRIEND_TEST_ALL_PREFIXES(ProfileMatchingTypesTest, + DeterminePossibleFieldTypesForUpload); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, DeterminePossibleFieldTypesForUpload); FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc index 8954769..13ad202 100644 --- a/components/autofill/core/browser/autofill_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -20,6 +20,7 @@ #include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/test/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" @@ -4445,28 +4446,163 @@ EXPECT_EQ(1, personal_data_.num_times_save_imported_profile_called()); } +struct ProfileMatchingTypesTestCase { + const char* input_value; // The value to input in the field. + ServerFieldType field_type; // The expected field type to be determined. +}; + +class ProfileMatchingTypesTest + : public AutofillManagerTest, + public ::testing::WithParamInterface< + std::tuple<ProfileMatchingTypesTestCase, + int, // AutofillProfile::ValidityState + bool>> {}; // Enable AutofillVoteUsingInvalidProfileValues + +const ProfileMatchingTypesTestCase kProfileMatchingTypesTestCases[] = { + // Profile fields matches. + {"Elvis", NAME_FIRST}, + {"Aaron", NAME_MIDDLE}, + {"A", NAME_MIDDLE_INITIAL}, + {"Presley", NAME_LAST}, + {"Elvis Aaron Presley", NAME_FULL}, + {"theking@gmail.com", EMAIL_ADDRESS}, + {"RCA", COMPANY_NAME}, + {"3734 Elvis Presley Blvd.", ADDRESS_HOME_LINE1}, + {"Apt. 10", ADDRESS_HOME_LINE2}, + {"Memphis", ADDRESS_HOME_CITY}, + {"Tennessee", ADDRESS_HOME_STATE}, + {"38116", ADDRESS_HOME_ZIP}, + {"USA", ADDRESS_HOME_COUNTRY}, + {"United States", ADDRESS_HOME_COUNTRY}, + {"12345678901", PHONE_HOME_WHOLE_NUMBER}, + {"+1 (234) 567-8901", PHONE_HOME_WHOLE_NUMBER}, + {"(234)567-8901", PHONE_HOME_CITY_AND_NUMBER}, + {"2345678901", PHONE_HOME_CITY_AND_NUMBER}, + {"1", PHONE_HOME_COUNTRY_CODE}, + {"234", PHONE_HOME_CITY_CODE}, + {"5678901", PHONE_HOME_NUMBER}, + {"567", PHONE_HOME_NUMBER}, + {"8901", PHONE_HOME_NUMBER}, + + // Test a European profile. + {"Paris", ADDRESS_HOME_CITY}, + {"Île de France", ADDRESS_HOME_STATE}, // Exact match + {"Ile de France", ADDRESS_HOME_STATE}, // Missing accent. + {"-Ile-de-France-", ADDRESS_HOME_STATE}, // Extra punctuation. + {"île dÉ FrÃÑÇË", ADDRESS_HOME_STATE}, // Other accents & case mismatch. + {"75008", ADDRESS_HOME_ZIP}, + {"FR", ADDRESS_HOME_COUNTRY}, + {"France", ADDRESS_HOME_COUNTRY}, + {"33249197070", PHONE_HOME_WHOLE_NUMBER}, + {"+33 2 49 19 70 70", PHONE_HOME_WHOLE_NUMBER}, + {"2 49 19 70 70", PHONE_HOME_CITY_AND_NUMBER}, + {"249197070", PHONE_HOME_CITY_AND_NUMBER}, + {"33", PHONE_HOME_COUNTRY_CODE}, + {"2", PHONE_HOME_CITY_CODE}, + + // Credit card fields matches. + {"John Doe", CREDIT_CARD_NAME_FULL}, + {"John", CREDIT_CARD_NAME_FIRST}, + {"Doe", CREDIT_CARD_NAME_LAST}, + {"4234-5678-9012-3456", CREDIT_CARD_NUMBER}, + {"04", CREDIT_CARD_EXP_MONTH}, + {"April", CREDIT_CARD_EXP_MONTH}, + {"2999", CREDIT_CARD_EXP_4_DIGIT_YEAR}, + {"99", CREDIT_CARD_EXP_2_DIGIT_YEAR}, + {"04/2999", CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, + + // Make sure whitespace and invalid characters are handled properly. + {"", EMPTY_TYPE}, + {" ", EMPTY_TYPE}, + {"***", UNKNOWN_TYPE}, + {" Elvis", NAME_FIRST}, + {"Elvis ", NAME_FIRST}, + + // Make sure fields that differ by case match. + {"elvis ", NAME_FIRST}, + {"UnItEd StAtEs", ADDRESS_HOME_COUNTRY}, + + // Make sure fields that differ by punctuation match. + {"3734 Elvis Presley Blvd", ADDRESS_HOME_LINE1}, + {"3734, Elvis Presley Blvd.", ADDRESS_HOME_LINE1}, + + // Make sure that a state's full name and abbreviation match. + {"TN", ADDRESS_HOME_STATE}, // Saved as "Tennessee" in profile. + {"Texas", ADDRESS_HOME_STATE}, // Saved as "TX" in profile. + + // Special phone number case. A profile with no country code should only + // match PHONE_HOME_CITY_AND_NUMBER. + {"5142821292", PHONE_HOME_CITY_AND_NUMBER}, + + // Make sure unsupported variants do not match. + {"Elvis Aaron", UNKNOWN_TYPE}, + {"Mr. Presley", UNKNOWN_TYPE}, + {"3734 Elvis Presley", UNKNOWN_TYPE}, + {"38116-1023", UNKNOWN_TYPE}, + {"5", UNKNOWN_TYPE}, + {"56", UNKNOWN_TYPE}, + {"901", UNKNOWN_TYPE}, +}; + // Tests that DeterminePossibleFieldTypesForUpload makes accurate matches. -TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesForUpload) { +TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) { + // Unpack the test paramters + const auto& test_case = std::get<0>(GetParam()); + const auto& validity_state = + static_cast<AutofillProfile::ValidityState>(std::get<1>(GetParam())); + const auto& vote_using_invalid_profile_data = std::get<2>(GetParam()); + + SCOPED_TRACE(base::StringPrintf( + "Test: input_value='%s', field_type=%s, validity_state=%d, " + "ignore_invalid_profile_data=%d", + test_case.input_value, + AutofillType(test_case.field_type).ToString().c_str(), validity_state, + vote_using_invalid_profile_data)); + + ASSERT_LE(AutofillProfile::UNVALIDATED, validity_state); + ASSERT_LE(validity_state, AutofillProfile::UNSUPPORTED); + + // Enable/Disable ignoring invalid profile data for the scope of this test. + base::test::ScopedFeatureList sfl; + if (vote_using_invalid_profile_data) { + sfl.InitAndEnableFeature(kAutofillVoteUsingInvalidProfileData); + } else { + sfl.InitAndDisableFeature(kAutofillVoteUsingInvalidProfileData); + } + // Set up the test profiles. std::vector<AutofillProfile> profiles; - AutofillProfile profile; - test::SetProfileInfo(&profile, "Elvis", "Aaron", "Presley", + profiles.resize(3); + test::SetProfileInfo(&profiles[0], "Elvis", "Aaron", "Presley", "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.", "Apt. 10", "Memphis", "Tennessee", "38116", "US", "+1 (234) 567-8901"); - profile.set_guid("00000000-0000-0000-0000-000000000001"); - profiles.push_back(profile); - test::SetProfileInfo(&profile, "Charles", "", "Holley", "buddy@gmail.com", + profiles[0].set_guid("00000000-0000-0000-0000-000000000001"); + + test::SetProfileInfo(&profiles[1], "Charles", "", "Holley", "buddy@gmail.com", "Decca", "123 Apple St.", "unit 6", "Lubbock", "TX", "79401", "US", "5142821292"); - profile.set_guid("00000000-0000-0000-0000-000000000002"); - profiles.push_back(profile); - test::SetProfileInfo(&profile, "Charles", "", "Baudelaire", + profiles[1].set_guid("00000000-0000-0000-0000-000000000002"); + + test::SetProfileInfo(&profiles[2], "Charles", "", "Baudelaire", "lesfleursdumal@gmail.com", "", "108 Rue Saint-Lazare", "Apt. 10", "Paris", "Île de France", "75008", "FR", "+33 2 49 19 70 70"); - profile.set_guid("00000000-0000-0000-0000-000000000001"); - profiles.push_back(profile); + profiles[2].set_guid("00000000-0000-0000-0000-000000000001"); + + // Set the validity state for the matching field type. + if (test_case.field_type != EMPTY_TYPE && + test_case.field_type != UNKNOWN_TYPE) { + auto field_type = test_case.field_type; + auto field_type_group = AutofillType(field_type).group(); + if (field_type_group != CREDIT_CARD) { + if (field_type_group == PHONE_HOME || field_type_group == PHONE_BILLING) + field_type = PHONE_HOME_WHOLE_NUMBER; + for (auto& profile : profiles) { + profile.SetValidityState(test_case.field_type, validity_state); + } + } + } // Set up the test credit cards. std::vector<CreditCard> credit_cards; @@ -4476,122 +4612,56 @@ credit_card.set_guid("00000000-0000-0000-0000-000000000003"); credit_cards.push_back(credit_card); - typedef struct { - std::string input_value; // The value to input in the field. - ServerFieldType field_type; // The expected field type to be determined. - } TestCase; + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.origin = GURL("http://myform.com/form.html"); + form.action = GURL("http://myform.com/submit.html"); - TestCase test_cases[] = { - // Profile fields matches. - {"Elvis", NAME_FIRST}, - {"Aaron", NAME_MIDDLE}, - {"A", NAME_MIDDLE_INITIAL}, - {"Presley", NAME_LAST}, - {"Elvis Aaron Presley", NAME_FULL}, - {"theking@gmail.com", EMAIL_ADDRESS}, - {"RCA", COMPANY_NAME}, - {"3734 Elvis Presley Blvd.", ADDRESS_HOME_LINE1}, - {"Apt. 10", ADDRESS_HOME_LINE2}, - {"Memphis", ADDRESS_HOME_CITY}, - {"Tennessee", ADDRESS_HOME_STATE}, - {"38116", ADDRESS_HOME_ZIP}, - {"USA", ADDRESS_HOME_COUNTRY}, - {"United States", ADDRESS_HOME_COUNTRY}, - {"12345678901", PHONE_HOME_WHOLE_NUMBER}, - {"+1 (234) 567-8901", PHONE_HOME_WHOLE_NUMBER}, - {"(234)567-8901", PHONE_HOME_CITY_AND_NUMBER}, - {"2345678901", PHONE_HOME_CITY_AND_NUMBER}, - {"1", PHONE_HOME_COUNTRY_CODE}, - {"234", PHONE_HOME_CITY_CODE}, - {"5678901", PHONE_HOME_NUMBER}, - {"567", PHONE_HOME_NUMBER}, - {"8901", PHONE_HOME_NUMBER}, + FormFieldData field; + test::CreateTestFormField("", "1", "", "text", &field); + field.value = UTF8ToUTF16(test_case.input_value); + form.fields.push_back(field); - // Test a European profile. - {"Paris", ADDRESS_HOME_CITY}, - {"Île de France", ADDRESS_HOME_STATE}, // Exact match - {"Ile de France", ADDRESS_HOME_STATE}, // Missing accent. - {"-Ile-de-France-", ADDRESS_HOME_STATE}, // Extra punctuation. - {"île dÉ FrÃÑÇË", ADDRESS_HOME_STATE}, // Other accents & case mismatch. - {"75008", ADDRESS_HOME_ZIP}, - {"FR", ADDRESS_HOME_COUNTRY}, - {"France", ADDRESS_HOME_COUNTRY}, - {"33249197070", PHONE_HOME_WHOLE_NUMBER}, - {"+33 2 49 19 70 70", PHONE_HOME_WHOLE_NUMBER}, - {"2 49 19 70 70", PHONE_HOME_CITY_AND_NUMBER}, - {"249197070", PHONE_HOME_CITY_AND_NUMBER}, - {"33", PHONE_HOME_COUNTRY_CODE}, - {"2", PHONE_HOME_CITY_CODE}, + FormStructure form_structure(form); - // Credit card fields matches. - {"John Doe", CREDIT_CARD_NAME_FULL}, - {"John", CREDIT_CARD_NAME_FIRST}, - {"Doe", CREDIT_CARD_NAME_LAST}, - {"4234-5678-9012-3456", CREDIT_CARD_NUMBER}, - {"04", CREDIT_CARD_EXP_MONTH}, - {"April", CREDIT_CARD_EXP_MONTH}, - {"2999", CREDIT_CARD_EXP_4_DIGIT_YEAR}, - {"99", CREDIT_CARD_EXP_2_DIGIT_YEAR}, - {"04/2999", CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, + base::HistogramTester histogram_tester; + AutofillManager::DeterminePossibleFieldTypesForUpload( + profiles, credit_cards, "en-us", &form_structure); - // Make sure whitespace and invalid characters are handled properly. - {"", EMPTY_TYPE}, - {" ", EMPTY_TYPE}, - {"***", UNKNOWN_TYPE}, - {" Elvis", NAME_FIRST}, - {"Elvis ", NAME_FIRST}, + ASSERT_EQ(1U, form_structure.field_count()); + ServerFieldTypeSet possible_types = form_structure.field(0)->possible_types(); + EXPECT_EQ(1U, possible_types.size()); - // Make sure fields that differ by case match. - {"elvis ", NAME_FIRST}, - {"UnItEd StAtEs", ADDRESS_HOME_COUNTRY}, - - // Make sure fields that differ by punctuation match. - {"3734 Elvis Presley Blvd", ADDRESS_HOME_LINE1}, - {"3734, Elvis Presley Blvd.", ADDRESS_HOME_LINE1}, - - // Make sure that a state's full name and abbreviation match. - {"TN", ADDRESS_HOME_STATE}, // Saved as "Tennessee" in profile. - {"Texas", ADDRESS_HOME_STATE}, // Saved as "TX" in profile. - - // Special phone number case. A profile with no country code should only - // match PHONE_HOME_CITY_AND_NUMBER. - {"5142821292", PHONE_HOME_CITY_AND_NUMBER}, - - // Make sure unsupported variants do not match. - {"Elvis Aaron", UNKNOWN_TYPE}, - {"Mr. Presley", UNKNOWN_TYPE}, - {"3734 Elvis Presley", UNKNOWN_TYPE}, - {"38116-1023", UNKNOWN_TYPE}, - {"5", UNKNOWN_TYPE}, - {"56", UNKNOWN_TYPE}, - {"901", UNKNOWN_TYPE}}; - - for (TestCase test_case : test_cases) { - FormData form; - form.name = ASCIIToUTF16("MyForm"); - form.origin = GURL("http://myform.com/form.html"); - form.action = GURL("http://myform.com/submit.html"); - - FormFieldData field; - test::CreateTestFormField("", "1", "", "text", &field); - field.value = UTF8ToUTF16(test_case.input_value); - form.fields.push_back(field); - - FormStructure form_structure(form); - - AutofillManager::DeterminePossibleFieldTypesForUpload( - profiles, credit_cards, "en-us", &form_structure); - - ASSERT_EQ(1U, form_structure.field_count()); - ServerFieldTypeSet possible_types = - form_structure.field(0)->possible_types(); - EXPECT_EQ(1U, possible_types.size()); - - EXPECT_NE(possible_types.end(), possible_types.find(test_case.field_type)) - << "Failed to determine type for: \"" << test_case.input_value << "\""; + if (test_case.field_type != EMPTY_TYPE && + AutofillProfile::IsValidationSupportedForType(test_case.field_type) && + validity_state == AutofillProfile::INVALID) { + // There are two addresses in the US, every other type/value pair is unique. + int expected_count = + (test_case.field_type == ADDRESS_HOME_COUNTRY && + base::StartsWith(test_case.input_value, "U", + base::CompareCase::INSENSITIVE_ASCII)) + ? 2 + : 1; + histogram_tester.ExpectBucketCount( + "Autofill.InvalidProfileData.UsedForMetrics", + vote_using_invalid_profile_data, expected_count); + EXPECT_EQ(*possible_types.begin(), vote_using_invalid_profile_data + ? test_case.field_type + : UNKNOWN_TYPE); + } else { + EXPECT_EQ(*possible_types.begin(), test_case.field_type); } } +INSTANTIATE_TEST_CASE_P( + AutofillManagerTest, + ProfileMatchingTypesTest, + testing::Combine( + testing::ValuesIn(kProfileMatchingTypesTestCases), + testing::Range(static_cast<int>(AutofillProfile::UNVALIDATED), + static_cast<int>(AutofillProfile::UNSUPPORTED) + 1), + testing::Bool())); + // Tests that DeterminePossibleFieldTypesForUpload is called when a form is // submitted. TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesForUpload_IsTriggered) {
diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc index cff037a..44b5d69a 100644 --- a/components/autofill/core/browser/autofill_profile.cc +++ b/components/autofill/core/browser/autofill_profile.cc
@@ -25,6 +25,7 @@ #include "components/autofill/core/browser/address.h" #include "components/autofill/core/browser/address_i18n.h" #include "components/autofill/core/browser/autofill_country.h" +#include "components/autofill/core/browser/autofill_experiments.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/autofill_profile_comparator.h" @@ -192,10 +193,10 @@ } // Constants for the validity bitfield. -static const size_t kValidityBitsPerType = 2; +const size_t kValidityBitsPerType = 2; // The order is important to ensure a consistent bitfield value. New values // should be added at the end NOT at the start or middle. -static const ServerFieldType kSupportedTypesForValidation[] = { +const ServerFieldType kSupportedTypesForValidation[] = { ADDRESS_HOME_COUNTRY, ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP, @@ -204,13 +205,22 @@ EMAIL_ADDRESS, PHONE_HOME_WHOLE_NUMBER}; -static const size_t kNumSupportedTypesForValidation = +const size_t kNumSupportedTypesForValidation = sizeof(kSupportedTypesForValidation) / sizeof(kSupportedTypesForValidation[0]); static_assert(kNumSupportedTypesForValidation * kValidityBitsPerType <= 64, "Not enough bits to encode profile validity information!"); +// Some types are specializations of other types. Normalize these back to the +// main stored type for used to mark field validity . +ServerFieldType NormalizeTypeForValidityCheck(ServerFieldType type) { + auto field_type_group = AutofillType(type).group(); + if (field_type_group == PHONE_HOME || field_type_group == PHONE_BILLING) + return PHONE_HOME_WHOLE_NUMBER; + return type; +} + } // namespace AutofillProfile::AutofillProfile(const std::string& guid, @@ -278,9 +288,22 @@ const base::string16& text, const std::string& app_locale, ServerFieldTypeSet* matching_types) const { + ServerFieldTypeSet matching_types_in_this_profile; FormGroupList info = FormGroups(); for (const auto* form_group : info) { - form_group->GetMatchingTypes(text, app_locale, matching_types); + form_group->GetMatchingTypes(text, app_locale, + &matching_types_in_this_profile); + } + for (auto type : matching_types_in_this_profile) { + if (GetValidityState(type) == INVALID) { + bool vote_using_invalid_data = + base::FeatureList::IsEnabled(kAutofillVoteUsingInvalidProfileData); + UMA_HISTOGRAM_BOOLEAN("Autofill.InvalidProfileData.UsedForMetrics", + vote_using_invalid_data); + if (!vote_using_invalid_data) + continue; + } + matching_types->insert(type); } } @@ -707,6 +730,7 @@ AutofillProfile::ValidityState AutofillProfile::GetValidityState( ServerFieldType type) const { + type = NormalizeTypeForValidityCheck(type); // Return UNSUPPORTED for types that autofill does not validate. if (!IsValidationSupportedForType(type)) return UNSUPPORTED; @@ -724,7 +748,8 @@ validity_states_[type] = validity; } -bool AutofillProfile::IsValidationSupportedForType(ServerFieldType type) const { +// static +bool AutofillProfile::IsValidationSupportedForType(ServerFieldType type) { for (auto supported_type : kSupportedTypesForValidation) { if (type == supported_type) return true;
diff --git a/components/autofill/core/browser/autofill_profile.h b/components/autofill/core/browser/autofill_profile.h index f5a06442..c097d14 100644 --- a/components/autofill/core/browser/autofill_profile.h +++ b/components/autofill/core/browser/autofill_profile.h
@@ -203,7 +203,7 @@ void SetValidityState(ServerFieldType type, ValidityState validity); // Returns whether autofill does the validation of the specified |type|. - bool IsValidationSupportedForType(ServerFieldType type) const; + static bool IsValidationSupportedForType(ServerFieldType type); // Returns the bitfield value representing the validity state of this profile. int GetValidityBitfieldValue() const;
diff --git a/components/autofill/core/browser/autofill_profile_unittest.cc b/components/autofill/core/browser/autofill_profile_unittest.cc index 22934f9..2689031 100644 --- a/components/autofill/core/browser/autofill_profile_unittest.cc +++ b/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -1127,7 +1127,7 @@ profile.GetValidityState(ADDRESS_HOME_LINE1)); EXPECT_EQ(AutofillProfile::UNSUPPORTED, profile.GetValidityState(ADDRESS_HOME_LINE2)); - EXPECT_EQ(AutofillProfile::UNSUPPORTED, + EXPECT_EQ(AutofillProfile::UNVALIDATED, profile.GetValidityState(PHONE_HOME_CITY_AND_NUMBER)); }
diff --git a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc index becc128..66d8074 100644 --- a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc +++ b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -85,7 +85,7 @@ bool AutofillSaveCardInfoBarDelegateMobile::IsGooglePayBrandingEnabled() const { return upload_ && base::FeatureList::IsEnabled( - features::kAutofillUpstreamUseGooglePayOnAndroidBranding); + features::kAutofillUpstreamUseGooglePayBrandingOnMobile); } base::string16 AutofillSaveCardInfoBarDelegateMobile::GetTitleText() const {
diff --git a/components/autofill/core/browser/credit_card_unittest.cc b/components/autofill/core/browser/credit_card_unittest.cc index 803170b..413948a 100644 --- a/components/autofill/core/browser/credit_card_unittest.cc +++ b/components/autofill/core/browser/credit_card_unittest.cc
@@ -731,13 +731,13 @@ EXPECT_EQ(base::string16(), card.GetRawInfo(CREDIT_CARD_VERIFICATION_CODE)); } -struct MatchingTypesCase { - MatchingTypesCase(const char* value, - const char* card_exp_month, - const char* card_exp_year, - CreditCard::RecordType record_type, - ServerFieldTypeSet expected_matched_types, - const char* locale = "US") +struct CreditCardMatchingTypesCase { + CreditCardMatchingTypesCase(const char* value, + const char* card_exp_month, + const char* card_exp_year, + CreditCard::RecordType record_type, + ServerFieldTypeSet expected_matched_types, + const char* locale = "US") : value(value), card_exp_month(card_exp_month), card_exp_year(card_exp_year), @@ -746,7 +746,7 @@ locale(locale) {} // The value entered by the user. - const std::string value; + const char* value; // Some values for an already saved card. Card number will be fixed to // 4012888888881881. const char* card_exp_month; @@ -755,13 +755,13 @@ // The types that are expected to match. const ServerFieldTypeSet expected_matched_types; - const std::string locale; + const char* locale = "US"; }; -class GetMatchingTypesTest : public testing::TestWithParam<MatchingTypesCase> { -}; +class CreditCardMatchingTypesTest + : public testing::TestWithParam<CreditCardMatchingTypesCase> {}; -TEST_P(GetMatchingTypesTest, Cases) { +TEST_P(CreditCardMatchingTypesTest, Cases) { auto test_case = GetParam(); CreditCard card(base::GenerateGUID(), "https://www.example.com/"); card.set_record_type(test_case.record_type); @@ -777,129 +777,60 @@ EXPECT_EQ(test_case.expected_matched_types, matching_types); } -INSTANTIATE_TEST_CASE_P( - CreditCardTest, - GetMatchingTypesTest, - testing::Values( - // If comparing against a masked card, last four digits are checked. - MatchingTypesCase{"1881", - "01", - "2020", - MASKED_SERVER_CARD, - {CREDIT_CARD_NUMBER}}, - MatchingTypesCase{"4012888888881881", - "01", - "2020", - MASKED_SERVER_CARD, - {CREDIT_CARD_NUMBER}}, - MatchingTypesCase{"4111111111111111", "01", "2020", - CreditCard::MASKED_SERVER_CARD, ServerFieldTypeSet()}, - // Same value will not match a local card or full server card since we - // have the full number for those. However the full number will. - MatchingTypesCase{"1881", "01", "2020", LOCAL_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"1881", "01", "2020", FULL_SERVER_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"4012888888881881", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_NUMBER}}, - MatchingTypesCase{"4012888888881881", - "01", - "2020", - FULL_SERVER_CARD, - {CREDIT_CARD_NUMBER}}, +const CreditCardMatchingTypesCase kCreditCardMatchingTypesTestCases[] = { + // If comparing against a masked card, last four digits are checked. + {"1881", "01", "2020", MASKED_SERVER_CARD, {CREDIT_CARD_NUMBER}}, + {"4012888888881881", + "01", + "2020", + MASKED_SERVER_CARD, + {CREDIT_CARD_NUMBER}}, + {"4111111111111111", "01", "2020", CreditCard::MASKED_SERVER_CARD, + ServerFieldTypeSet()}, + // Same value will not match a local card or full server card since we + // have the full number for those. However the full number will. + {"1881", "01", "2020", LOCAL_CARD, ServerFieldTypeSet()}, + {"1881", "01", "2020", FULL_SERVER_CARD, ServerFieldTypeSet()}, + {"4012888888881881", "01", "2020", LOCAL_CARD, {CREDIT_CARD_NUMBER}}, + {"4012888888881881", "01", "2020", FULL_SERVER_CARD, {CREDIT_CARD_NUMBER}}, - // Wrong last four digits. - MatchingTypesCase{"1111", "01", "2020", MASKED_SERVER_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"1111", "01", "2020", LOCAL_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"1111", "01", "2020", FULL_SERVER_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"4111111111111111", "01", "2020", MASKED_SERVER_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"4111111111111111", "01", "2020", LOCAL_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"4111111111111111", "01", "2020", FULL_SERVER_CARD, - ServerFieldTypeSet()}, + // Wrong last four digits. + {"1111", "01", "2020", MASKED_SERVER_CARD, ServerFieldTypeSet()}, + {"1111", "01", "2020", LOCAL_CARD, ServerFieldTypeSet()}, + {"1111", "01", "2020", FULL_SERVER_CARD, ServerFieldTypeSet()}, + {"4111111111111111", "01", "2020", MASKED_SERVER_CARD, + ServerFieldTypeSet()}, + {"4111111111111111", "01", "2020", LOCAL_CARD, ServerFieldTypeSet()}, + {"4111111111111111", "01", "2020", FULL_SERVER_CARD, ServerFieldTypeSet()}, - // Matching the expiration month. - MatchingTypesCase{"01", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}}, - MatchingTypesCase{"1", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}}, - MatchingTypesCase{"jan", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}, - "US"}, - // Locale-specific interpretations. - MatchingTypesCase{"janv", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}, - "FR"}, - MatchingTypesCase{"janv.", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}, - "FR"}, - MatchingTypesCase{"janvier", - "01", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}, - "FR"}, - MatchingTypesCase{"février", - "02", - "2020", - LOCAL_CARD, - {CREDIT_CARD_EXP_MONTH}, - "FR"}, - MatchingTypesCase{"mars", "01", "2020", LOCAL_CARD, - ServerFieldTypeSet(), "FR"}, + // Matching the expiration month. + {"01", "01", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}}, + {"1", "01", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}}, + {"jan", "01", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}, "US"}, + // Locale-specific interpretations. + {"janv", "01", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}, "FR"}, + {"janv.", "01", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}, "FR"}, + {"janvier", "01", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}, "FR"}, + {"février", "02", "2020", LOCAL_CARD, {CREDIT_CARD_EXP_MONTH}, "FR"}, + {"mars", "01", "2020", LOCAL_CARD, ServerFieldTypeSet(), "FR"}, - // Matching the expiration year. - MatchingTypesCase{"2019", - "01", - "2019", - LOCAL_CARD, - {CREDIT_CARD_EXP_4_DIGIT_YEAR}}, - MatchingTypesCase{"19", - "01", - "2019", - LOCAL_CARD, - {CREDIT_CARD_EXP_2_DIGIT_YEAR}}, - MatchingTypesCase{"01/2019", - "01", - "2019", - LOCAL_CARD, - {CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}}, - MatchingTypesCase{"01-2019", - "01", - "2019", - LOCAL_CARD, - {CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}}, - MatchingTypesCase{"01/2020", "01", "2019", LOCAL_CARD, - ServerFieldTypeSet()}, - MatchingTypesCase{"20", "01", "2019", LOCAL_CARD, ServerFieldTypeSet()}, - MatchingTypesCase{"2021", "01", "2019", LOCAL_CARD, - ServerFieldTypeSet()})); + // Matching the expiration year. + {"2019", "01", "2019", LOCAL_CARD, {CREDIT_CARD_EXP_4_DIGIT_YEAR}}, + {"19", "01", "2019", LOCAL_CARD, {CREDIT_CARD_EXP_2_DIGIT_YEAR}}, + {"01/2019", "01", "2019", LOCAL_CARD, {CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}}, + {"01-2019", "01", "2019", LOCAL_CARD, {CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}}, + {"01/2020", "01", "2019", LOCAL_CARD, ServerFieldTypeSet()}, + {"20", "01", "2019", LOCAL_CARD, ServerFieldTypeSet()}, + {"2021", "01", "2019", LOCAL_CARD, ServerFieldTypeSet()}, +}; + +INSTANTIATE_TEST_CASE_P(CreditCardTest, + CreditCardMatchingTypesTest, + testing::ValuesIn(kCreditCardMatchingTypesTestCases)); struct GetCardNetworkTestCase { - std::string card_number; - std::string issuer_network; + const char* card_number; + const char* issuer_network; bool is_valid; }; @@ -975,7 +906,7 @@ GetCardNetworkTestCase{"6362970000457013", kEloCard, true}, // Empty string - GetCardNetworkTestCase{std::string(), kGenericCard, false}, + GetCardNetworkTestCase{"", kGenericCard, false}, // Non-numeric GetCardNetworkTestCase{"garbage", kGenericCard, false},
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 43fdcc0..6fed3ff6 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -16,6 +16,7 @@ #include "base/feature_list.h" #include "base/i18n/case_conversion.h" #include "base/i18n/timezone.h" +#include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -975,6 +976,32 @@ num_profiles_supressed); } +// static +void PersonalDataManager::MaybeRemoveInvalidSuggestions( + const AutofillType& type, + std::vector<AutofillProfile*>* profiles) { + const bool suggest_invalid = + base::FeatureList::IsEnabled(kAutofillSuggestInvalidProfileData); + + for (size_t i = 0; i < profiles->size(); ++i) { + bool is_invalid = (*profiles)[i]->GetValidityState( + type.GetStorableType()) == AutofillProfile::INVALID; + if (is_invalid) { + UMA_HISTOGRAM_BOOLEAN("Autofill.InvalidProfileData.UsedForSuggestion", + suggest_invalid); + if (!suggest_invalid) + (*profiles)[i] = nullptr; + } + } + + if (!suggest_invalid) { + profiles->erase( + std::stable_partition(profiles->begin(), profiles->end(), + [](AutofillProfile* p) { return p != nullptr; }), + profiles->end()); + } +} + std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions( const AutofillType& type, const base::string16& field_contents, @@ -990,13 +1017,15 @@ // Get the profiles to suggest, which are already sorted. std::vector<AutofillProfile*> profiles = GetProfilesToSuggest(); - // If enabled, suppress disused address profiles when triggered from an empty - // field. - if (field_contents_canon.empty() && - base::FeatureList::IsEnabled(kAutofillSuppressDisusedAddresses)) { - const base::Time min_last_used = - AutofillClock::Now() - kDisusedProfileTimeDelta; - RemoveProfilesNotUsedSinceTimestamp(min_last_used, &profiles); + // When suggesting with no prefix to match, consider suppressing disused + // address suggestions as well as those based on invalid profile data. + if (field_contents_canon.empty()) { + if (base::FeatureList::IsEnabled(kAutofillSuppressDisusedAddresses)) { + const base::Time min_last_used = + AutofillClock::Now() - kDisusedProfileTimeDelta; + RemoveProfilesNotUsedSinceTimestamp(min_last_used, &profiles); + } + MaybeRemoveInvalidSuggestions(type, &profiles); } std::vector<Suggestion> suggestions;
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index 6eb722b0..5fc2d9f 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -215,6 +215,12 @@ base::Time min_last_used, std::vector<AutofillProfile*>* profiles); + // Remove profiles that whose |type| field is flagged as invalid, if Chrome + // is configured to not make suggestions based on invalid data. + static void MaybeRemoveInvalidSuggestions( + const AutofillType& type, + std::vector<AutofillProfile*>* profiles); + // Loads profiles that can suggest data for |type|. |field_contents| is the // part the user has already typed. |field_is_autofilled| is true if the field // has already been autofilled. |other_field_types| represents the rest of
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 584fa7d..a34e66d3 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -1925,6 +1925,54 @@ } } +// Tests that suggestions based on invalid data are handled correctly. +TEST_F(PersonalDataManagerTest, GetProfileSuggestions_InvalidData) { + // Set up 2 different profiles. + AutofillProfile profile1(base::GenerateGUID(), "https://www.example.com"); + test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison", + "johnwayne@me.xyz", "Fox", + "123 Zoo St.\nSecond Line\nThird line", "unit 5", + "Hollywood", "CA", "91601", "US", "9876543210"); + profile1.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID); + profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20)); + personal_data_->AddProfile(profile1); + + AutofillProfile profile2(base::GenerateGUID(), "https://www.example.com"); + test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison", + "johnwayne@me.xyz", "Fox", + "456 Zoo St.\nSecond Line\nThird line", "unit 5", + "Hollywood", "CA", "91601", "US", "1234567890"); + personal_data_->AddProfile(profile2); + + ResetPersonalDataManager(USER_MODE_NORMAL); + { + base::HistogramTester histogram_tester; + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndDisableFeature(kAutofillSuggestInvalidProfileData); + std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions( + AutofillType(PHONE_HOME_WHOLE_NUMBER), base::string16(), false, + std::vector<ServerFieldType>()); + ASSERT_EQ(1U, suggestions.size()); + EXPECT_EQ(base::ASCIIToUTF16("1234567890"), suggestions[0].value); + histogram_tester.ExpectUniqueSample( + "Autofill.InvalidProfileData.UsedForSuggestion", false, 1); + } + + { + base::HistogramTester histogram_tester; + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndEnableFeature(kAutofillSuggestInvalidProfileData); + std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions( + AutofillType(PHONE_HOME_WHOLE_NUMBER), base::string16(), false, + std::vector<ServerFieldType>()); + ASSERT_EQ(2U, suggestions.size()); + EXPECT_EQ(base::ASCIIToUTF16("1234567890"), suggestions[0].value); + EXPECT_EQ(base::ASCIIToUTF16("9876543210"), suggestions[1].value); + histogram_tester.ExpectUniqueSample( + "Autofill.InvalidProfileData.UsedForSuggestion", true, 1); + } +} + TEST_F(PersonalDataManagerTest, IsKnownCard_MatchesMaskedServerCard) { // Add a masked server card. std::vector<CreditCard> server_cards;
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index df69471..476678b1 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -56,8 +56,8 @@ "AutofillSkipComparingInferredLabels", base::FEATURE_DISABLED_BY_DEFAULT}; // Controls whether the credit card upload bubble shows the Google Pay logo and -// a shorter "Save card?" header message on Android. -const base::Feature kAutofillUpstreamUseGooglePayOnAndroidBranding{ +// a shorter "Save card?" header message on mobile. +const base::Feature kAutofillUpstreamUseGooglePayBrandingOnMobile{ "AutofillUpstreamUseGooglePayOnAndroidBranding", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 3d32bcf..e354955 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -20,7 +20,7 @@ extern const base::Feature kAutofillRestrictUnownedFieldsToFormlessCheckout; extern const base::Feature kAutofillShowTypePredictions; extern const base::Feature kAutofillSkipComparingInferredLabels; -extern const base::Feature kAutofillUpstreamUseGooglePayOnAndroidBranding; +extern const base::Feature kAutofillUpstreamUseGooglePayBrandingOnMobile; } // namespace features } // namespace autofill
diff --git a/components/certificate_transparency/ct_policy_manager_unittest.cc b/components/certificate_transparency/ct_policy_manager_unittest.cc index 9d3b3b1..0cd328e 100644 --- a/components/certificate_transparency/ct_policy_manager_unittest.cc +++ b/components/certificate_transparency/ct_policy_manager_unittest.cc
@@ -130,9 +130,10 @@ // Wildcards are ignored (both * and https://*). EXPECT_EQ(CTRequirementLevel::DEFAULT, delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); - // File URL hosts are ignored. - EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("withahost", cert_.get(), hashes_)); + // TODO(rsleevi): https://crbug.com/841407 - Ensure that file URLs have their + // hosts ignored for policy. + // EXPECT_EQ(CTRequirementLevel::DEFAULT, + // delegate->IsCTRequiredForHost("withahost", cert_.get(), hashes_)); // While the partially parsed hosts should take effect. EXPECT_EQ(
diff --git a/components/components_locale_settings.grd b/components/components_locale_settings.grd index 1db75317..a9ffdfb3 100644 --- a/components/components_locale_settings.grd +++ b/components/components_locale_settings.grd
@@ -250,7 +250,7 @@ <messages fallback_to_english="true"> <!-- The default value for HTTP Accept-Language header. --> - <message name="IDS_ACCEPT_LANGUAGES" use_name_for_id="true" formatter_data="android_java"> + <message name="IDS_ACCEPT_LANGUAGES" use_name_for_id="true"> en-US,en </message>
diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc index 3130623..42e80de 100644 --- a/components/omnibox/browser/autocomplete_input.cc +++ b/components/omnibox/browser/autocomplete_input.cc
@@ -175,21 +175,6 @@ } // static -void AutocompleteInput::ParseFilePath(const base::string16& text, - size_t offset, - url::Parsed* parts) { - parts->path.begin = offset; - size_t hash_offset = text.find('#', offset); - if (hash_offset != text.npos) { - parts->path.len = hash_offset - offset; - parts->ref.begin = hash_offset + 1; - parts->ref.len = text.size() - parts->ref.begin; - } else { - parts->path.len = text.size() - offset; - } -} - -// static metrics::OmniboxInputType AutocompleteInput::Parse( const base::string16& text, const std::string& desired_tld, @@ -228,8 +213,6 @@ // A user might or might not type a scheme when entering a file URL. In // either case, |parsed_scheme_utf8| will tell us that this is a file URL, // but |parts->scheme| might be empty, e.g. if the user typed "C:\foo". - ParseFilePath(text, parts->scheme.is_nonempty() ? parts->scheme.end() : 0, - parts); return metrics::OmniboxInputType::URL; }
diff --git a/components/omnibox/browser/autocomplete_input.h b/components/omnibox/browser/autocomplete_input.h index c456b61..f1220c3 100644 --- a/components/omnibox/browser/autocomplete_input.h +++ b/components/omnibox/browser/autocomplete_input.h
@@ -61,11 +61,6 @@ // Converts |type| to a string representation. Used in logging. static std::string TypeToString(metrics::OmniboxInputType type); - // Parses the |path| and |ref| fields of |parts| from a file path input. - static void ParseFilePath(const base::string16& text, - size_t offset, - url::Parsed* parts); - // Parses |text| (including an optional |desired_tld|) and returns the type of // input this will be interpreted as. |scheme_classifier| is used to check // the scheme in |text| is known and registered in the current environment.
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index ebdd632b..bf9098b0 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -85,7 +85,13 @@ // Feature used to display the title of the current URL match. const base::Feature kDisplayTitleForCurrentUrl{ - "OmniboxDisplayTitleForCurrentUrl", base::FEATURE_DISABLED_BY_DEFAULT}; + "OmniboxDisplayTitleForCurrentUrl", +#if defined(OS_ANDROID) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; // Feature used for the max autocomplete matches UI experiment. const base::Feature kUIExperimentMaxAutocompleteMatches{
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.cc b/components/policy/core/common/cloud/cloud_policy_constants.cc index bddd608..3c3e697 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.cc +++ b/components/policy/core/common/cloud/cloud_policy_constants.cc
@@ -57,6 +57,8 @@ const char kValueRequestAppInstallReport[] = "app_install_report"; const char kValueRequestTokenEnrollment[] = "register_browser"; const char kValueRequestChromeDesktopReport[] = "chrome_desktop_report"; +const char kValueRequestInitialEnrollmentStateRetrieval[] = + "device_initial_enrollment_state"; const char kChromeDevicePolicyType[] = "google/chromeos/device"; #if defined(OS_CHROMEOS)
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h index f2a82709..2d1cc55 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.h +++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -49,6 +49,7 @@ POLICY_EXPORT extern const char kValueRequestAppInstallReport[]; POLICY_EXPORT extern const char kValueRequestTokenEnrollment[]; POLICY_EXPORT extern const char kValueRequestChromeDesktopReport[]; +POLICY_EXPORT extern const char kValueRequestInitialEnrollmentStateRetrieval[]; // Policy type strings for the policy_type field in PolicyFetchRequest. POLICY_EXPORT extern const char kChromeDevicePolicyType[];
diff --git a/components/policy/core/common/cloud/device_management_service.cc b/components/policy/core/common/cloud/device_management_service.cc index b81384b1..93eb38a 100644 --- a/components/policy/core/common/cloud/device_management_service.cc +++ b/components/policy/core/common/cloud/device_management_service.cc
@@ -166,6 +166,8 @@ return dm_protocol::kValueRequestTokenEnrollment; case DeviceManagementRequestJob::TYPE_CHROME_DESKTOP_REPORT: return dm_protocol::kValueRequestChromeDesktopReport; + case DeviceManagementRequestJob::TYPE_INITIAL_ENROLLMENT_STATE_RETRIEVAL: + return dm_protocol::kValueRequestInitialEnrollmentStateRetrieval; } NOTREACHED() << "Invalid job type " << type; return "";
diff --git a/components/policy/core/common/cloud/device_management_service.h b/components/policy/core/common/cloud/device_management_service.h index ec6f24b7..28816b39 100644 --- a/components/policy/core/common/cloud/device_management_service.h +++ b/components/policy/core/common/cloud/device_management_service.h
@@ -66,6 +66,7 @@ TYPE_UPLOAD_APP_INSTALL_REPORT = 17, TYPE_TOKEN_ENROLLMENT = 18, TYPE_CHROME_DESKTOP_REPORT = 19, + TYPE_INITIAL_ENROLLMENT_STATE_RETRIEVAL = 20, }; typedef base::Callback<
diff --git a/components/sync/protocol/extension_specifics.proto b/components/sync/protocol/extension_specifics.proto index 394b0b04..e560995 100644 --- a/components/sync/protocol/extension_specifics.proto +++ b/components/sync/protocol/extension_specifics.proto
@@ -42,11 +42,8 @@ // Whether this extension was installed by the custodian of a supervised user. optional bool installed_by_custodian = 8; - // Whether this extension has explicit user consent access to all urls. - // This is a tri-state boolean, so, unlike most fields here, it really *is* - // optional and may be absent. We need this for the time being because we need - // to know if a user has not set an explicit preference. - optional bool all_urls_enabled = 9; + // DEPRECATED. See https://crbug.com/839681. + optional bool all_urls_enabled = 9 [deprecated = true]; // Bitmask of the set of reasons why the extension is disabled (see // extensions::disable_reason::DisableReason). Only relevant when enabled ==
diff --git a/components/url_formatter/url_fixer.cc b/components/url_formatter/url_fixer.cc index 36511cf5..26be3c86 100644 --- a/components/url_formatter/url_fixer.cc +++ b/components/url_formatter/url_fixer.cc
@@ -404,20 +404,20 @@ if (trimmed.empty()) return std::string(); // Nothing to segment. + std::string scheme; #if defined(OS_WIN) int trimmed_length = static_cast<int>(trimmed.length()); if (url::DoesBeginWindowsDriveSpec(trimmed.data(), 0, trimmed_length) || url::DoesBeginUNCPath(trimmed.data(), 0, trimmed_length, true)) - return url::kFileScheme; + scheme = url::kFileScheme; #elif defined(OS_POSIX) || defined(OS_FUCHSIA) if (base::FilePath::IsSeparator(trimmed.data()[0]) || trimmed.data()[0] == '~') - return url::kFileScheme; + scheme = url::kFileScheme; #endif // Otherwise, we need to look at things carefully. - std::string scheme; - if (!GetValidScheme(*text, &parts->scheme, &scheme)) { + if (scheme.empty() && !GetValidScheme(*text, &parts->scheme, &scheme)) { // Try again if there is a ';' in the text. If changing it to a ':' results // in a standard scheme, "about", "chrome" or "file" scheme being found, // continue processing with the modified text. @@ -444,24 +444,26 @@ // Proceed with about and chrome schemes, but not file or nonstandard schemes. if ((scheme != url::kAboutScheme) && (scheme != kChromeUIScheme) && - ((scheme == url::kFileScheme) || - !url::IsStandard( - scheme.c_str(), - url::Component(0, static_cast<int>(scheme.length()))))) { + !url::IsStandard(scheme.c_str(), + url::Component(0, static_cast<int>(scheme.length())))) { + return scheme; + } + + int text_length = static_cast<int>(text->length()); + if (scheme == url::kFileScheme) { + url::ParseFileURL(text->data(), text_length, parts); return scheme; } if (scheme == url::kFileSystemScheme) { // Have the GURL parser do the heavy lifting for us. - url::ParseFileSystemURL(text->data(), static_cast<int>(text->length()), - parts); + url::ParseFileSystemURL(text->data(), text_length, parts); return scheme; } if (parts->scheme.is_valid()) { // Have the GURL parser do the heavy lifting for us. - url::ParseStandardURL(text->data(), static_cast<int>(text->length()), - parts); + url::ParseStandardURL(text->data(), text_length, parts); return scheme; }
diff --git a/components/url_formatter/url_fixer_unittest.cc b/components/url_formatter/url_fixer_unittest.cc index e946f23..5415d19 100644 --- a/components/url_formatter/url_fixer_unittest.cc +++ b/components/url_formatter/url_fixer_unittest.cc
@@ -192,6 +192,52 @@ url::Component(), // query url::Component(), // ref }, + { + "file://host/path/file#ref", "file", url::Component(0, 4), // scheme + url::Component(), // username + url::Component(), // password + url::Component(7, 4), // host + url::Component(), // port + url::Component(11, 10), // path + url::Component(), // query + url::Component(22, 3), // ref + }, + { + "file:///notahost/path/file#ref", "file", + url::Component(0, 4), // scheme + url::Component(), // username + url::Component(), // password + url::Component(), // host + url::Component(), // port + url::Component(7, 19), // path + url::Component(), // query + url::Component(27, 3), // ref + }, +#if defined(OS_WIN) + { + "c:/notahost/path/file#ref", "file", + url::Component(), // scheme + url::Component(), // username + url::Component(), // password + url::Component(), // host + url::Component(), // port + url::Component(0, 21), // path + url::Component(), // query + url::Component(22, 3), // ref + }, +#elif defined(OS_POSIX) + { + "~/notahost/path/file#ref", "file", + url::Component(), // scheme + url::Component(), // username + url::Component(), // password + url::Component(), // host + url::Component(), // port + url::Component(0, 20), // path + url::Component(), // query + url::Component(21, 3), // ref + }, +#endif }; typedef testing::Test URLFixerTest;
diff --git a/components/viz/common/frame_sinks/copy_output_request.cc b/components/viz/common/frame_sinks/copy_output_request.cc index 43fa33b..56164fa 100644 --- a/components/viz/common/frame_sinks/copy_output_request.cc +++ b/components/viz/common/frame_sinks/copy_output_request.cc
@@ -64,14 +64,6 @@ result_task_runner_->RunsTasksInCurrentSequence(); } -void CopyOutputRequest::SetMailbox(const gpu::Mailbox& mailbox, - const gpu::SyncToken& sync_token) { - DCHECK_EQ(result_format_, ResultFormat::RGBA_TEXTURE); - DCHECK(!mailbox.IsZero()); - mailbox_ = mailbox; - sync_token_ = sync_token; -} - // static std::unique_ptr<CopyOutputRequest> CopyOutputRequest::CreateStubForTesting() { return std::make_unique<CopyOutputRequest>(
diff --git a/components/viz/common/frame_sinks/copy_output_request.h b/components/viz/common/frame_sinks/copy_output_request.h index 4c57ab26..d38cfde 100644 --- a/components/viz/common/frame_sinks/copy_output_request.h +++ b/components/viz/common/frame_sinks/copy_output_request.h
@@ -107,17 +107,6 @@ bool has_result_selection() const { return result_selection_.has_value(); } const gfx::Rect& result_selection() const { return *result_selection_; } - // Legacy support for providing textures up-front, to copy results into. - // TODO(miu): Remove these methods after tab capture is moved to VIZ. - // http://crbug.com/754872 - // The texture bound to the mailbox is expected to have a GL_TEXTURE_2D - // target. - void SetMailbox(const gpu::Mailbox& mailbox, - const gpu::SyncToken& sync_token); - bool has_mailbox() const { return mailbox_.has_value(); } - const gpu::Mailbox& mailbox() const { return *mailbox_; } - const gpu::SyncToken& sync_token() const { return *sync_token_; } - // Sends the result from executing this request. Called by the internal // implementation, usually a DirectRenderer. void SendResult(std::unique_ptr<CopyOutputResult> result); @@ -144,8 +133,6 @@ base::Optional<base::UnguessableToken> source_; base::Optional<gfx::Rect> area_; base::Optional<gfx::Rect> result_selection_; - base::Optional<gpu::Mailbox> mailbox_; - base::Optional<gpu::SyncToken> sync_token_; DISALLOW_COPY_AND_ASSIGN(CopyOutputRequest); };
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 42b6787..202e608 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -39,6 +39,13 @@ namespace viz { +struct Display::PendingPresentedCallbacks { + PendingPresentedCallbacks(uint64_t swap_id, PresentedCallbacks callbacks) + : swap_id(swap_id), callbacks(std::move(callbacks)) {} + uint64_t swap_id = 0; + PresentedCallbacks callbacks; +}; + Display::Display( SharedBitmapManager* bitmap_manager, const RendererSettings& settings, @@ -61,14 +68,11 @@ } Display::~Display() { - for (auto& callbacks : previous_presented_callbacks_) { - for (auto& callback : callbacks) + for (auto& pending_callbacks : pending_presented_callbacks_) { + for (auto& callback : pending_callbacks.callbacks) std::move(callback).Run(base::TimeTicks(), base::TimeDelta(), 0); } - for (auto& callback : active_presented_callbacks_) - std::move(callback).Run(base::TimeTicks(), base::TimeDelta(), 0); - for (auto& callback : presented_callbacks_) std::move(callback).Run(base::TimeTicks(), base::TimeDelta(), 0); @@ -444,16 +448,12 @@ } void Display::DidReceiveSwapBuffersAck(uint64_t swap_id) { - // TODO(penghuang): Remove it when we can get accurate presentation time from - // GPU for every SwapBuffers. https://crbug.com/776877 - if (!active_presented_callbacks_.empty() || - !previous_presented_callbacks_.empty()) { - DLOG(WARNING) << "VSync for last SwapBuffers is not received!"; - previous_presented_callbacks_.push_back( - std::move(active_presented_callbacks_)); + DCHECK(pending_presented_callbacks_.empty() || + pending_presented_callbacks_.back().swap_id < swap_id); + if (!presented_callbacks_.empty()) { + pending_presented_callbacks_.emplace_back(swap_id, + std::move(presented_callbacks_)); } - active_presented_callbacks_ = std::move(presented_callbacks_); - if (scheduler_) scheduler_->DidReceiveSwapBuffersAck(); if (renderer_) @@ -475,23 +475,17 @@ void Display::DidReceivePresentationFeedback( uint64_t swap_id, const gfx::PresentationFeedback& feedback) { - // TODO(penghuang): Remove it when we can get accurate presentation time from - // GPU for every SwapBuffers. https://crbug.com/776877 - base::TimeTicks previous_timebase = - feedback.timestamp - - feedback.interval * previous_presented_callbacks_.size(); - for (auto& callbacks : previous_presented_callbacks_) { - for (auto& callback : callbacks) - std::move(callback).Run(previous_timebase, feedback.interval, 0); - previous_timebase += feedback.interval; + if (pending_presented_callbacks_.empty()) + return; + DCHECK_LE(swap_id, pending_presented_callbacks_.front().swap_id); + auto& pending_callbacks = pending_presented_callbacks_.front(); + if (swap_id == pending_callbacks.swap_id) { + for (auto& callback : pending_callbacks.callbacks) { + std::move(callback).Run(feedback.timestamp, feedback.interval, + feedback.flags); + } + pending_presented_callbacks_.pop_front(); } - previous_presented_callbacks_.clear(); - - for (auto& callback : active_presented_callbacks_) { - std::move(callback).Run(feedback.timestamp, feedback.interval, - feedback.flags); - } - active_presented_callbacks_.clear(); } void Display::DidFinishLatencyInfo(
diff --git a/components/viz/service/display/display.h b/components/viz/service/display/display.h index 4b7d805..4b4f705 100644 --- a/components/viz/service/display/display.h +++ b/components/viz/service/display/display.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "base/containers/circular_deque.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/single_thread_task_runner.h" @@ -170,10 +171,8 @@ using PresentedCallbacks = std::vector<Surface::PresentedCallback>; PresentedCallbacks presented_callbacks_; - PresentedCallbacks active_presented_callbacks_; - // TODO(penghuang): Remove it when we can get accurate presentation time from - // GPU for every SwapBuffers. https://crbug.com/776877 - std::vector<PresentedCallbacks> previous_presented_callbacks_; + struct PendingPresentedCallbacks; + base::circular_deque<PendingPresentedCallbacks> pending_presented_callbacks_; private: DISALLOW_COPY_AND_ASSIGN(Display);
diff --git a/components/viz/service/display/gl_renderer_copier.cc b/components/viz/service/display/gl_renderer_copier.cc index ee56fad4..fb4b00ef 100644 --- a/components/viz/service/display/gl_renderer_copier.cc +++ b/components/viz/service/display/gl_renderer_copier.cc
@@ -215,10 +215,10 @@ // return it as the result texture. The request must not include scaling nor // a texture mailbox to use for delivering results. The texture format must // also be GL_RGBA, as described by CopyOutputResult::Format::RGBA_TEXTURE. - const int purpose = (!request.is_scaled() && flipped_source && - !request.has_mailbox() && internal_format == GL_RGBA) - ? CacheEntry::kResultTexture - : CacheEntry::kFramebufferCopyTexture; + const int purpose = + (!request.is_scaled() && flipped_source && internal_format == GL_RGBA) + ? CacheEntry::kResultTexture + : CacheEntry::kFramebufferCopyTexture; TakeCachedObjectsOrCreate(SourceOf(request), purpose, 1, &source_texture); gl->BindTexture(GL_TEXTURE_2D, source_texture); gl->CopyTexImage2D(GL_TEXTURE_2D, 0, internal_format, sampling_rect.x(), @@ -230,21 +230,9 @@ sampling_rect.set_origin(gfx::Point()); } - // Determine the result texture: If the copy request provided a valid one, use - // it instead of one owned by GLRendererCopier. GLuint result_texture = 0; - if (request.has_mailbox()) { - if (!request.mailbox().IsZero()) { - if (request.sync_token().HasData()) - gl->WaitSyncTokenCHROMIUM(request.sync_token().GetConstData()); - result_texture = - gl->CreateAndConsumeTextureCHROMIUM(request.mailbox().name); - } - } - if (result_texture == 0) { - TakeCachedObjectsOrCreate(SourceOf(request), CacheEntry::kResultTexture, 1, - &result_texture); - } + TakeCachedObjectsOrCreate(SourceOf(request), CacheEntry::kResultTexture, 1, + &result_texture); gl->BindTexture(GL_TEXTURE_2D, result_texture); gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, result_rect.width(), result_rect.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -492,34 +480,18 @@ // within its own GL context will be using the texture at a point in time // after the texture has been rendered (via GLRendererCopier's GL context). gpu::Mailbox mailbox; - if (request->has_mailbox()) { - mailbox = request->mailbox(); - } else { - gl->GenMailboxCHROMIUM(mailbox.name); - gl->ProduceTextureDirectCHROMIUM(result_texture, mailbox.name); - } + gl->GenMailboxCHROMIUM(mailbox.name); + gl->ProduceTextureDirectCHROMIUM(result_texture, mailbox.name); gpu::SyncToken sync_token; gl->GenSyncTokenCHROMIUM(sync_token.GetData()); - // Create a |release_callback| appropriate to the situation: If the - // |result_texture| was provided in the mailbox of the copy request, - // create a no-op release callback because the requestor owns the texture. - // Otherwise, create a callback that deletes what was created in this GL - // context. - std::unique_ptr<SingleReleaseCallback> release_callback; - if (request->has_mailbox()) { - gl->DeleteTextures(1, &result_texture); - // TODO(crbug/754872): This non-null release callback wart is going away - // soon, as copy requestors won't need pool/manage textures anymore. - release_callback = SingleReleaseCallback::Create(base::DoNothing()); - } else { - // Note: There's no need to try to pool/re-use the result texture from here, - // since only clients that are trying to re-invent video capture would see - // any significant performance benefit. Instead, such clients should use the - // video capture services provided by VIZ. - release_callback = - texture_deleter_->GetReleaseCallback(context_provider_, result_texture); - } + // Create a callback that deletes what was created in this GL context. + // Note: There's no need to try to pool/re-use the result texture from here, + // since only clients that are trying to re-invent video capture would see any + // significant performance benefit. Instead, such clients should use the video + // capture services provided by VIZ. + auto release_callback = + texture_deleter_->GetReleaseCallback(context_provider_, result_texture); request->SendResult(std::make_unique<CopyOutputTextureResult>( result_rect, mailbox, sync_token, color_space,
diff --git a/components/viz/test/test_context_provider.cc b/components/viz/test/test_context_provider.cc index 42c74f06..f6b0624 100644 --- a/components/viz/test/test_context_provider.cc +++ b/components/viz/test/test_context_provider.cc
@@ -9,6 +9,7 @@ #include <set> #include <string> +#include <utility> #include <vector> #include "base/bind.h" @@ -204,8 +205,7 @@ context_gl_->set_test_context(context3d_.get()); context3d_->set_test_support(support_.get()); raster_context_ = std::make_unique<gpu::raster::RasterImplementationGLES>( - context_gl_.get(), support_.get(), nullptr, - context3d_->test_capabilities()); + context_gl_.get(), nullptr, context3d_->test_capabilities()); // Just pass nullptr to the ContextCacheController for its task runner. // Idle handling is tested directly in ContextCacheController's // unittests, and isn't needed here.
diff --git a/content/app/BUILD.gn b/content/app/BUILD.gn index 8d8f282..70d55be 100644 --- a/content/app/BUILD.gn +++ b/content/app/BUILD.gn
@@ -71,7 +71,7 @@ content_app_deps += [ "//content/ppapi_plugin:ppapi_plugin_sources" ] } - # Compile content_main_runner.cc in a separate target to exempt from GN + # Compile content_main_runner_impl.cc in a separate target to exempt from GN # header checking without exempting any other source file. This file includes # headers of all process types and varies significantly per platform in # between browser and child. Otherwise it would require many "nogncheck" @@ -84,7 +84,7 @@ check_includes = false sources = [ - "content_main_runner.cc", + "content_main_runner_impl.cc", ] configs += extra_configs
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner_impl.cc similarity index 96% rename from content/app/content_main_runner.cc rename to content/app/content_main_runner_impl.cc index 2296874..4863bbf 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner_impl.cc
@@ -191,8 +191,8 @@ // browser process. field_trial_list->reset(new base::FieldTrialList(nullptr)); - // Ensure any field trials in browser are reflected into the child - // process. +// Ensure any field trials in browser are reflected into the child +// process. #if defined(OS_WIN) base::FieldTrialList::CreateTrialsFromCommandLine( command_line, switches::kFieldTrialHandle, -1); @@ -587,12 +587,12 @@ #else base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(switches::kSingleProcess)) { - LOG(FATAL) << - "--single-process is not supported in chrome multiple dll browser."; + LOG(FATAL) + << "--single-process is not supported in chrome multiple dll browser."; } if (command_line.HasSwitch(switches::kInProcessGPU)) { - LOG(FATAL) << - "--in-process-gpu is not supported in chrome multiple dll browser."; + LOG(FATAL) + << "--in-process-gpu is not supported in chrome multiple dll browser."; } #endif // !CHROME_MULTIPLE_DLL_BROWSER && !CHROME_MULTIPLE_DLL_CHILD } @@ -600,22 +600,21 @@ // Run the FooMain() for a given process type. // If |process_type| is empty, runs BrowserMain(). // Returns the exit code for this process. -int RunNamedProcessTypeMain( - const std::string& process_type, - const MainFunctionParams& main_function_params, - ContentMainDelegate* delegate) { +int RunNamedProcessTypeMain(const std::string& process_type, + const MainFunctionParams& main_function_params, + ContentMainDelegate* delegate) { static const MainFunction kMainFunctions[] = { #if !defined(CHROME_MULTIPLE_DLL_CHILD) - { "", BrowserMain }, + {"", BrowserMain}, #endif #if !defined(CHROME_MULTIPLE_DLL_BROWSER) #if BUILDFLAG(ENABLE_PLUGINS) - { switches::kPpapiPluginProcess, PpapiPluginMain }, - { switches::kPpapiBrokerProcess, PpapiBrokerMain }, + {switches::kPpapiPluginProcess, PpapiPluginMain}, + {switches::kPpapiBrokerProcess, PpapiBrokerMain}, #endif // ENABLE_PLUGINS - { switches::kUtilityProcess, UtilityMain }, - { switches::kRendererProcess, RendererMain }, - { switches::kGpuProcess, GpuMain }, + {switches::kUtilityProcess, UtilityMain}, + {switches::kRendererProcess, RendererMain}, + {switches::kGpuProcess, GpuMain}, #endif // !CHROME_MULTIPLE_DLL_BROWSER }; @@ -624,8 +623,8 @@ for (size_t i = 0; i < arraysize(kMainFunctions); ++i) { if (process_type == kMainFunctions[i].name) { if (delegate) { - int exit_code = delegate->RunProcess(process_type, - main_function_params); + int exit_code = + delegate->RunProcess(process_type, main_function_params); #if defined(OS_ANDROID) // In Android's browser process, the negative exit code doesn't mean the // default behavior should be used as the UI message loop is managed by @@ -719,10 +718,10 @@ is_initialized_ = true; delegate_ = params.delegate; - // The exit manager is in charge of calling the dtors of singleton objects. - // On Android, AtExitManager is set up when library is loaded. - // A consequence of this is that you can't use the ctor/dtor-based - // TRACE_EVENT methods on Linux or iOS builds till after we set this up. +// The exit manager is in charge of calling the dtors of singleton objects. +// On Android, AtExitManager is set up when library is loaded. +// A consequence of this is that you can't use the ctor/dtor-based +// TRACE_EVENT methods on Linux or iOS builds till after we set this up. #if !defined(OS_ANDROID) if (!ui_task_) { // When running browser tests, don't create a second AtExitManager as that @@ -752,8 +751,8 @@ #if defined(OS_WIN) if (command_line.HasSwitch(switches::kDeviceScaleFactor)) { - std::string scale_factor_string = command_line.GetSwitchValueASCII( - switches::kDeviceScaleFactor); + std::string scale_factor_string = + command_line.GetSwitchValueASCII(switches::kDeviceScaleFactor); double scale_factor = 0; if (base::StringToDouble(scale_factor_string, &scale_factor)) display::win::SetDefaultDeviceScaleFactor(scale_factor);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 7299492..ccb4f8e 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -325,8 +325,6 @@ "android/launcher_thread.h", "android/scoped_surface_request_manager.cc", "android/scoped_surface_request_manager.h", - "android/string_message_codec.cc", - "android/string_message_codec.h", "android/text_suggestion_host_android.cc", "android/text_suggestion_host_android.h", "android/text_suggestion_host_mojo_impl_android.cc", @@ -501,7 +499,7 @@ "browser_main.h", "browser_main_loop.cc", "browser_main_loop.h", - "browser_main_runner.cc", + "browser_main_runner_impl.cc", "browser_plugin/browser_plugin_embedder.cc", "browser_plugin/browser_plugin_embedder.h", "browser_plugin/browser_plugin_guest.cc",
diff --git a/content/browser/android/app_web_message_port.cc b/content/browser/android/app_web_message_port.cc index 97e66fd5..ec7b9ba 100644 --- a/content/browser/android/app_web_message_port.cc +++ b/content/browser/android/app_web_message_port.cc
@@ -9,8 +9,8 @@ #include "base/android/jni_string.h" #include "base/bind.h" #include "base/threading/thread_task_runner_handle.h" -#include "content/browser/android/string_message_codec.h" #include "jni/AppWebMessagePort_jni.h" +#include "third_party/blink/public/common/message_port/string_message_codec.h" using blink::MessagePortChannel; @@ -44,7 +44,7 @@ &encoded_message); base::string16 message; - if (!DecodeStringMessage(encoded_message, &message)) + if (!blink::DecodeStringMessage(encoded_message, &message)) return nullptr; base::android::ScopedJavaLocalRef<jstring> jmessage = @@ -57,8 +57,8 @@ JNIEnv* env, const base::android::JavaParamRef<jclass>& jcaller, const base::android::JavaParamRef<jstring>& jmessage) { - std::vector<uint8_t> encoded_message = - EncodeStringMessage(base::android::ConvertJavaStringToUTF16(jmessage)); + std::vector<uint8_t> encoded_message = blink::EncodeStringMessage( + base::android::ConvertJavaStringToUTF16(jmessage)); return base::android::ToJavaByteArray(env, encoded_message); }
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner_impl.cc similarity index 96% rename from content/browser/browser_main_runner.cc rename to content/browser/browser_main_runner_impl.cc index 9c94248..8e5ef3c 100644 --- a/content/browser/browser_main_runner.cc +++ b/content/browser/browser_main_runner_impl.cc
@@ -127,9 +127,9 @@ main_loop_->MainMessageLoopStart(); main_loop_->PostMainMessageLoopStart(); -// WARNING: If we get a WM_ENDSESSION, objects created on the stack here -// are NOT deleted. If you need something to run during WM_ENDSESSION add it -// to browser_shutdown::Shutdown or BrowserProcess::EndSession. + // WARNING: If we get a WM_ENDSESSION, objects created on the stack here + // are NOT deleted. If you need something to run during WM_ENDSESSION add + // it to browser_shutdown::Shutdown or BrowserProcess::EndSession. ui::InitializeInputMethod(); UMA_HISTOGRAM_TIMES("Startup.BrowserMainRunnerImplInitializeStep1Time", @@ -215,16 +215,16 @@ main_loop_->ShutdownThreadsAndCleanUp(); ui::ShutdownInputMethod(); - #if defined(OS_WIN) +#if defined(OS_WIN) ole_initializer_.reset(NULL); - #endif - #if defined(OS_ANDROID) +#endif +#if defined(OS_ANDROID) // Forcefully terminates the RunLoop inside MessagePumpForUI, ensuring // proper shutdown for content_browsertests. Shutdown() is not used by // the actual browser. if (base::RunLoop::IsRunningOnCurrentThread()) base::RunLoop::QuitCurrentDeprecated(); - #endif +#endif main_loop_.reset(nullptr); notification_service_.reset(nullptr);
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index dfc17cc..8677c1cc 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -96,6 +96,10 @@ return rwhv; } +RenderWidgetHostViewBase* RenderWidgetHostViewGuest::GetParentView() { + return GetOwnerRenderWidgetHostView(); +} + RenderWidgetHostViewGuest::RenderWidgetHostViewGuest( RenderWidgetHost* widget_host, BrowserPluginGuest* guest,
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h index 39125bf..529bf0bf 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.h +++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -62,6 +62,9 @@ // Called when this RenderWidgetHostViewGuest is attached. void OnAttached(); + // RenderWidgetHostViewChildFrame implementation. + RenderWidgetHostViewBase* GetParentView() override; + // RenderWidgetHostView implementation. bool OnMessageReceived(const IPC::Message& msg) override; void InitAsChild(gfx::NativeView parent_view) override;
diff --git a/content/browser/media/audio_input_stream_broker_unittest.cc b/content/browser/media/audio_input_stream_broker_unittest.cc index 1d078d3..956f5f04 100644 --- a/content/browser/media/audio_input_stream_broker_unittest.cc +++ b/content/browser/media/audio_input_stream_broker_unittest.cc
@@ -12,6 +12,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "media/mojo/interfaces/audio_input_stream.mojom.h" #include "mojo/public/cpp/system/platform_handle.h" +#include "services/audio/public/cpp/fake_stream_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -69,19 +70,11 @@ media::mojom::AudioInputStreamClientRequest client_request_; }; -class MockStreamFactory : public audio::mojom::StreamFactory { +class MockStreamFactory : public audio::FakeStreamFactory { public: - MockStreamFactory() : binding_(this) {} + MockStreamFactory() {} ~MockStreamFactory() final {} - audio::mojom::StreamFactoryPtr MakePtr() { - audio::mojom::StreamFactoryPtr ret; - binding_.Bind(mojo::MakeRequest(&ret)); - return ret; - } - - void CloseBinding() { binding_.Close(); } - // State of an expected stream creation. |device_id| and |params| are set // ahead of time and verified during request. The other fields are filled in // when the request is received. @@ -134,23 +127,6 @@ stream_request_data_->created_callback = std::move(created_callback); } - void CreateOutputStream( - media::mojom::AudioOutputStreamRequest stream_request, - media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info, - media::mojom::AudioLogPtr log, - const std::string& output_device_id, - const media::AudioParameters& params, - const base::UnguessableToken& group_id, - CreateOutputStreamCallback created_callback) final { - ADD_FAILURE() << "Unexpected output stream creation in input test."; - } - - void BindMuter(audio::mojom::LocalMuterAssociatedRequest request, - const base::UnguessableToken& group_id) final { - ADD_FAILURE() << "Unexpected muting in input stream test"; - } - - mojo::Binding<audio::mojom::StreamFactory> binding_; StreamRequestData* stream_request_data_; };
diff --git a/content/browser/media/audio_output_stream_broker_unittest.cc b/content/browser/media/audio_output_stream_broker_unittest.cc index 98fb2d4..2a634904 100644 --- a/content/browser/media/audio_output_stream_broker_unittest.cc +++ b/content/browser/media/audio_output_stream_broker_unittest.cc
@@ -20,7 +20,7 @@ #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/platform_handle.h" -#include "services/audio/public/mojom/stream_factory.mojom.h" +#include "services/audio/public/cpp/fake_stream_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -76,19 +76,11 @@ mojo::Binding<media::mojom::AudioOutputStreamProviderClient> binding_; }; -class MockStreamFactory : public audio::mojom::StreamFactory { +class MockStreamFactory : public audio::FakeStreamFactory { public: - MockStreamFactory() : binding_(this) {} + MockStreamFactory() {} ~MockStreamFactory() final {} - audio::mojom::StreamFactoryPtr MakePtr() { - audio::mojom::StreamFactoryPtr ret; - binding_.Bind(mojo::MakeRequest(&ret)); - return ret; - } - - void CloseBinding() { binding_.Close(); } - // State of an expected stream creation. |output_device_id|, |params|, // and |groups_id| are set ahead of time and verified during request. // The other fields are filled in when the request is received. @@ -115,19 +107,6 @@ } private: - void CreateInputStream(media::mojom::AudioInputStreamRequest stream_request, - media::mojom::AudioInputStreamClientPtr client, - media::mojom::AudioInputStreamObserverPtr observer, - media::mojom::AudioLogPtr log, - const std::string& device_id, - const media::AudioParameters& params, - uint32_t shared_memory_count, - bool enable_agc, - mojo::ScopedSharedBufferHandle key_press_count_buffer, - CreateInputStreamCallback created_callback) final { - ADD_FAILURE() << "Unexpected input stream creation in output test."; - } - void CreateOutputStream( media::mojom::AudioOutputStreamRequest stream_request, media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info, @@ -148,12 +127,6 @@ stream_request_data_->created_callback = std::move(created_callback); } - void BindMuter(audio::mojom::LocalMuterAssociatedRequest request, - const base::UnguessableToken& group_id) final { - ADD_FAILURE() << "Unexpected muting in output stream test"; - } - - mojo::Binding<audio::mojom::StreamFactory> binding_; StreamRequestData* stream_request_data_; };
diff --git a/content/browser/message_port_provider.cc b/content/browser/message_port_provider.cc index 86ebc20d..e5d8f66 100644 --- a/content/browser/message_port_provider.cc +++ b/content/browser/message_port_provider.cc
@@ -9,6 +9,7 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/public/browser/browser_thread.h" +#include "third_party/blink/public/common/message_port/string_message_codec.h" #if defined(OS_ANDROID) #include "base/android/jni_string.h" @@ -28,11 +29,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); FrameMsg_PostMessage_Params params; - params.is_data_raw_string = true; params.message = new base::RefCountedData<blink::TransferableMessage>(); + params.message->data.owned_encoded_message = blink::EncodeStringMessage(data); params.message->data.encoded_message = - base::make_span(reinterpret_cast<const uint8_t*>(data.data()), - data.size() * sizeof(base::char16)); + params.message->data.owned_encoded_message; params.message->data.ports = std::move(channels); params.source_routing_id = MSG_ROUTING_NONE; params.source_origin = source_origin;
diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc index 0ec4dc82..0a57242 100644 --- a/content/browser/renderer_host/media/media_devices_manager.cc +++ b/content/browser/renderer_host/media/media_devices_manager.cc
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/location.h" +#include "base/sequence_checker.h" #include "base/strings/stringprintf.h" #include "base/task_runner_util.h" #include "base/threading/thread_checker.h" @@ -20,11 +21,18 @@ #include "content/browser/media/media_devices_permission_checker.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_manager.h" +#include "content/browser/service_manager/service_manager_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_features.h" #include "media/audio/audio_device_description.h" #include "media/audio/audio_system.h" #include "media/base/media_switches.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/audio/public/mojom/constants.mojom.h" +#include "services/audio/public/mojom/device_notifications.mojom.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/identity.h" +#include "services/service_manager/public/mojom/connector.mojom-shared.h" #if defined(OS_MACOSX) #include "base/bind_helpers.h" @@ -267,6 +275,64 @@ MediaDevicesManager::SubscriptionRequest::operator=(SubscriptionRequest&&) = default; +class MediaDevicesManager::AudioServiceDeviceListener + : public audio::mojom::DeviceListener { + public: + explicit AudioServiceDeviceListener(service_manager::Connector* connector) + : binding_(this), weak_factory_(this) { + TryConnectToService(connector); + } + ~AudioServiceDeviceListener() override = default; + + void DevicesChanged() override { + auto* system_monitor = base::SystemMonitor::Get(); + if (system_monitor) + system_monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO); + } + + private: + void TryConnectToService(service_manager::Connector* connector) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Check if the service manager is managing the audio service. + connector->QueryService( + service_manager::Identity(audio::mojom::kServiceName), + base::BindOnce(&AudioServiceDeviceListener::DoConnectToService, + weak_factory_.GetWeakPtr(), connector)); + } + + void DoConnectToService(service_manager::Connector* connector, + service_manager::mojom::ConnectResult connect_result, + const std::string& ignore) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!mojo_audio_device_notifier_); + DCHECK(!binding_); + // Do not connect if the service manager is not managing the audio service. + if (connect_result != service_manager::mojom::ConnectResult::SUCCEEDED) { + LOG(WARNING) << "Audio service not available: " << connect_result; + return; + } + + connector->BindInterface(audio::mojom::kServiceName, + mojo::MakeRequest(&mojo_audio_device_notifier_)); + mojo_audio_device_notifier_.set_connection_error_handler(base::BindOnce( + &MediaDevicesManager::AudioServiceDeviceListener::TryConnectToService, + weak_factory_.GetWeakPtr(), connector)); + audio::mojom::DeviceListenerPtr audio_device_listener_ptr; + binding_.Bind(mojo::MakeRequest(&audio_device_listener_ptr)); + mojo_audio_device_notifier_->RegisterListener( + std::move(audio_device_listener_ptr)); + } + + mojo::Binding<audio::mojom::DeviceListener> binding_; + audio::mojom::DeviceNotifierPtr mojo_audio_device_notifier_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<AudioServiceDeviceListener> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(AudioServiceDeviceListener); +}; + MediaDevicesManager::MediaDevicesManager( media::AudioSystem* audio_system, const scoped_refptr<VideoCaptureManager>& video_capture_manager, @@ -336,6 +402,7 @@ const BoolDeviceTypes& subscribe_types, blink::mojom::MediaDevicesListenerPtr listener) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + StartMonitoring(); uint32_t subscription_id = ++last_subscription_id_; blink::mojom::MediaDevicesListenerPtr media_devices_listener = std::move(listener); @@ -385,6 +452,22 @@ return; #endif +#if defined(OS_WIN) + if (base::FeatureList::IsEnabled(features::kAudioServiceOutOfProcess)) { + DCHECK(!audio_service_device_listener_); + if (!connector_) { + auto* connector = ServiceManagerContext::GetConnectorForIOThread(); + // |connector| can be null on unit tests. + if (!connector) + return; + + connector_ = connector->Clone(); + } + + audio_service_device_listener_ = + std::make_unique<AudioServiceDeviceListener>(connector_.get()); + } +#endif monitoring_started_ = true; base::SystemMonitor::Get()->AddDevicesChangedObserver(this); @@ -419,6 +502,7 @@ if (!monitoring_started_) return; base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); + audio_service_device_listener_.reset(); monitoring_started_ = false; for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) SetCachePolicy(static_cast<MediaDeviceType>(i), CachePolicy::NO_CACHE);
diff --git a/content/browser/renderer_host/media/media_devices_manager.h b/content/browser/renderer_host/media/media_devices_manager.h index 59fae7ff..a6696e0 100644 --- a/content/browser/renderer_host/media/media_devices_manager.h +++ b/content/browser/renderer_host/media/media_devices_manager.h
@@ -30,6 +30,10 @@ class AudioSystem; } +namespace service_manager { +class Connector; +} + namespace content { class MediaDevicesPermissionChecker; @@ -264,6 +268,11 @@ // Callback used to obtain the current device ID salt and security origin. MediaDeviceSaltAndOriginCallback salt_and_origin_callback_; + std::unique_ptr<service_manager::Connector> connector_; + + class AudioServiceDeviceListener; + std::unique_ptr<AudioServiceDeviceListener> audio_service_device_listener_; + base::WeakPtrFactory<MediaDevicesManager> weak_factory_; DISALLOW_COPY_AND_ASSIGN(MediaDevicesManager);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 54864936..44fe389 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1939,9 +1939,9 @@ scoped_refptr<ChromeBlobStorageContext> blob_storage_context = ChromeBlobStorageContext::GetFor(browser_context); - AddUIThreadInterface( - registry.get(), - base::Bind(&ClipboardHostImpl::Create, std::move(blob_storage_context))); + AddUIThreadInterface(registry.get(), + base::BindRepeating(&ClipboardHostImpl::Create, + std::move(blob_storage_context))); media::VideoDecodePerfHistory* video_perf_history = GetBrowserContext()->GetVideoDecodePerfHistory(); @@ -2014,8 +2014,6 @@ AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create)); associated_interfaces_.reset(new AssociatedInterfaceRegistryImpl()); - GetContentClient()->browser()->ExposeInterfacesToRenderer( - registry.get(), associated_interfaces_.get(), this); blink::AssociatedInterfaceRegistry* associated_registry = associated_interfaces_.get(); associated_registry->AddInterface(base::Bind( @@ -2038,6 +2036,14 @@ registry->AddInterface(base::BindRepeating(&KeySystemSupportImpl::Create)); #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) + // ---- Please do not register interfaces below this line ------ + // + // This call should be done after registering all interfaces above, so that + // embedder can override any interfaces. The fact that registry calls + // the last registration for the name allows us to easily override interfaces. + GetContentClient()->browser()->ExposeInterfacesToRenderer( + registry.get(), associated_interfaces_.get(), this); + ServiceManagerConnection* service_manager_connection = BrowserContext::GetServiceManagerConnectionFor(browser_context_); if (connection_filter_id_ !=
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h index c94df659..bed6be9 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.h +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -221,7 +221,7 @@ // Returns the view into which this view is directly embedded. This can // return nullptr when this view's associated child frame is not connected // to the frame tree. - RenderWidgetHostViewBase* GetParentView(); + virtual RenderWidgetHostViewBase* GetParentView(); void RegisterFrameSinkId(); void UnregisterFrameSinkId();
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 1b5b3ad3..c5720b29 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -431,11 +431,6 @@ IPC_STRUCT_END() IPC_STRUCT_BEGIN(FrameMsg_PostMessage_Params) - // Whether the data format is supplied as serialized script value, or as - // a simple string. If it is a raw string, must be converted from string to a - // WebSerializedScriptValue in the renderer process. - IPC_STRUCT_MEMBER(bool, is_data_raw_string) - // When sent to the browser, this is the routing ID of the source frame in // the source process. The browser replaces it with the routing ID of the // equivalent frame proxy in the destination process.
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java index 4dd4761b..9cacde5 100644 --- a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java
@@ -79,6 +79,11 @@ return (int) Math.ceil(getLastFrameViewportHeightPix()); } + @Override + public int getMaxVerticalScrollPixInt() { + return (int) Math.floor(getMaxVerticalScrollPix()); + } + void updateContentSizeCss(float contentWidthCss, float contentHeightCss) { mContentWidthCss = contentWidthCss; mContentHeightCss = contentHeightCss; @@ -224,9 +229,4 @@ private int getMaxHorizontalScrollPixInt() { return (int) Math.floor(getMaxHorizontalScrollPix()); } - - // Maximum possible vertical scroll in physical pixels (approx, integer). - private int getMaxVerticalScrollPixInt() { - return (int) Math.floor(getMaxVerticalScrollPix()); - } }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java b/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java index 87ee3fc..1244d05 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java
@@ -46,4 +46,9 @@ * @return Render-reported height of the viewport in physical pixels (approx, integer). */ int getLastFrameViewportHeightPixInt(); + + /** + * @return Maximum possible vertical scroll in physical pixels (approx, integer). + */ + int getMaxVerticalScrollPixInt(); }
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index e3c4a13..9642ff3 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -74,7 +74,12 @@ }, "requires": { "*": [ "app" ], - "audio": [ "info", "debug_recording", "stream_factory"], + "audio": [ + "info", + "debug_recording", + "device_notifier", + "stream_factory" + ], "cdm": [ "media:cdm" ], "content_gpu": [ "browser" ], "content_plugin": [ "browser" ],
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h index dffff04f..b5cad2b 100644 --- a/content/public/browser/browser_context.h +++ b/content/public/browser/browser_context.h
@@ -134,7 +134,9 @@ using BlobContextGetter = base::RepeatingCallback<base::WeakPtr<storage::BlobStorageContext>()>; - // |callback| returns a nullptr scoped_ptr on failure. + // This method should be called on UI thread and calls back on UI thread + // as well. Note that retrieving a blob ptr out of BlobHandle can only be + // done on IO. |callback| returns a nullptr on failure. static void CreateMemoryBackedBlob(BrowserContext* browser_context, const char* data, size_t length,
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc index c8e1db9..5ff6ab1 100644 --- a/content/public/renderer/content_renderer_client.cc +++ b/content/public/renderer/content_renderer_client.cc
@@ -70,10 +70,6 @@ return nullptr; } -blink::WebClipboard* ContentRendererClient::OverrideWebClipboard() { - return nullptr; -} - blink::WebThemeEngine* ContentRendererClient::OverrideThemeEngine() { return nullptr; }
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index e62a17b..59aba6d 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h
@@ -41,7 +41,6 @@ namespace blink { class WebAudioDevice; class WebAudioLatencyHint; -class WebClipboard; class WebFrame; class WebLocalFrame; class WebMIDIAccessor; @@ -172,10 +171,6 @@ virtual std::unique_ptr<blink::WebAudioDevice> OverrideCreateAudioDevice( const blink::WebAudioLatencyHint& latency_hint); - // Allows the embedder to override the blink::WebClipboard used. If it - // returns NULL the content layer will handle clipboard interactions. - virtual blink::WebClipboard* OverrideWebClipboard(); - // Allows the embedder to override the WebThemeEngine used. If it returns NULL // the content layer will provide an engine. virtual blink::WebThemeEngine* OverrideThemeEngine();
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 86db62d..53e2aa1 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -751,6 +751,25 @@ mouse_event); } +void SimulateRoutedMouseEvent(WebContents* web_contents, + blink::WebInputEvent::Type type, + const gfx::Point& point) { + content::WebContentsImpl* web_contents_impl = + static_cast<content::WebContentsImpl*>(web_contents); + content::RenderWidgetHostViewBase* rwhvb = + static_cast<content::RenderWidgetHostViewBase*>( + web_contents->GetRenderWidgetHostView()); + blink::WebMouseEvent mouse_event(type, 0, ui::EventTimeForNow()); + mouse_event.SetPositionInWidget(point.x(), point.y()); + // Mac needs positionInScreen for events to plugins. + gfx::Rect offset = web_contents->GetContainerBounds(); + mouse_event.SetPositionInScreen(point.x() + offset.x(), + point.y() + offset.y()); + + web_contents_impl->GetInputEventRouter()->RouteMouseEvent(rwhvb, &mouse_event, + ui::LatencyInfo()); +} + void SimulateMouseWheelEvent(WebContents* web_contents, const gfx::Point& point, const gfx::Vector2d& delta,
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index e2954ad2..1cca5c1 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -160,6 +160,12 @@ blink::WebInputEvent::Type type, const gfx::Point& point); +// Same as SimulateMouseEvent() except it forces the mouse event to go through +// RenderWidgetHostInputEventRouter. +void SimulateRoutedMouseEvent(WebContents* web_contents, + blink::WebInputEvent::Type type, + const gfx::Point& point); + // Simulate a mouse wheel event. void SimulateMouseWheelEvent(WebContents* web_contents, const gfx::Point& point,
diff --git a/content/renderer/loader/sync_load_context.cc b/content/renderer/loader/sync_load_context.cc index 387ebc9b..3c0fcb21 100644 --- a/content/renderer/loader/sync_load_context.cc +++ b/content/renderer/loader/sync_load_context.cc
@@ -57,8 +57,7 @@ : response_(response), completed_event_(completed_event), download_to_blob_registry_(std::move(download_to_blob_registry)), - task_runner_(std::move(task_runner)), - fetch_request_mode_(request->fetch_request_mode) { + task_runner_(std::move(task_runner)) { url_loader_factory_ = network::SharedURLLoaderFactory::Create(std::move(url_loader_factory)); if (abort_event) { @@ -88,25 +87,19 @@ const net::RedirectInfo& redirect_info, const network::ResourceResponseInfo& info) { DCHECK(!Completed()); - // Synchronous loads in blink aren't associated with a ResourceClient, and - // CORS checks are performed by ResourceClient subclasses, so there's - // currently no way to perform CORS checks for redirects. - // Err on the side of extreme caution and block any cross origin redirect - // that might have CORS implications. - if (fetch_request_mode_ != network::mojom::FetchRequestMode::kNoCORS && - redirect_info.new_url.GetOrigin() != response_->url.GetOrigin()) { + if (redirect_info.new_url.GetOrigin() != response_->url.GetOrigin()) { LOG(ERROR) << "Cross origin redirect denied"; response_->error_code = net::ERR_ABORTED; - } else { - response_->info = info; - response_->redirect_info = redirect_info; + + CompleteRequest(false /* remove_pending_request */); + + // Returning false here will cause the request to be cancelled and this + // object deleted. + return false; } - // Returning false here will cause the request to be cancelled and this - // object deleted. WebURLLoaderImpl may create a new SyncLoadContext to - // manually follow the redirect. - CompleteRequest(false /* remove_pending_request */); - return false; + response_->url = redirect_info.new_url; + return true; } void SyncLoadContext::OnReceivedResponse(
diff --git a/content/renderer/loader/sync_load_context.h b/content/renderer/loader/sync_load_context.h index 96c8b901..26c0772 100644 --- a/content/renderer/loader/sync_load_context.h +++ b/content/renderer/loader/sync_load_context.h
@@ -114,8 +114,6 @@ base::WaitableEventWatcher abort_watcher_; base::OneShotTimer timeout_timer_; - const network::mojom::FetchRequestMode fetch_request_mode_; - DISALLOW_COPY_AND_ASSIGN(SyncLoadContext); };
diff --git a/content/renderer/loader/sync_load_response.h b/content/renderer/loader/sync_load_response.h index 9c845bc2..bd46a9b 100644 --- a/content/renderer/loader/sync_load_response.h +++ b/content/renderer/loader/sync_load_response.h
@@ -26,8 +26,6 @@ SyncLoadResponse& operator=(SyncLoadResponse&& other); - base::Optional<net::RedirectInfo> redirect_info; - network::ResourceResponseInfo info; // The response error code.
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index c61303a..622625df 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -1290,8 +1290,7 @@ } void WebURLLoaderImpl::LoadSynchronously( - WebURLLoaderClient* client, - const WebURLRequest& passed_request, + const WebURLRequest& request, WebURLResponse& response, base::Optional<WebURLError>& error, WebData& data, @@ -1301,40 +1300,7 @@ blink::WebBlobInfo& downloaded_blob) { TRACE_EVENT0("loading", "WebURLLoaderImpl::loadSynchronously"); SyncLoadResponse sync_load_response; - int redirect_limit = net::URLRequest::kMaxRedirects; - WebURLRequest request(passed_request); - - // SyncLoadResponse won't automatically follow redirects, so manually - // check and follow valid redirects here. - while (true) { - context_->Start(request, &sync_load_response); - - if (!sync_load_response.redirect_info) - break; - - if (!redirect_limit--) { - error = WebURLError(net::ERR_TOO_MANY_REDIRECTS, sync_load_response.url); - return; - } - - const net::RedirectInfo& redirect_info = *sync_load_response.redirect_info; - WebURLResponse redirect_response; - PopulateURLResponse(sync_load_response.url, sync_load_response.info, - &redirect_response, request.ReportRawHeaders()); - bool report_raw_headers = false; - if (!client->WillFollowRedirect( - redirect_info.new_url, redirect_info.new_site_for_cookies, - WebString::FromUTF8(redirect_info.new_referrer), - Referrer::NetReferrerPolicyToBlinkReferrerPolicy( - redirect_info.new_referrer_policy), - WebString::FromUTF8(redirect_info.new_method), redirect_response, - report_raw_headers)) { - return; - } - - request.SetURL(redirect_info.new_url); - sync_load_response = SyncLoadResponse(); - } + context_->Start(request, &sync_load_response); const GURL& final_url = sync_load_response.url;
diff --git a/content/renderer/loader/web_url_loader_impl.h b/content/renderer/loader/web_url_loader_impl.h index 552d5b4..36ac4350 100644 --- a/content/renderer/loader/web_url_loader_impl.h +++ b/content/renderer/loader/web_url_loader_impl.h
@@ -69,8 +69,7 @@ blink::WebURLResponse* response, bool report_security_info); // WebURLLoader methods: - void LoadSynchronously(blink::WebURLLoaderClient* client, - const blink::WebURLRequest& request, + void LoadSynchronously(const blink::WebURLRequest& request, blink::WebURLResponse& response, base::Optional<blink::WebURLError>& error, blink::WebData& data,
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc index 0dfe9aa..c842cb5 100644 --- a/content/renderer/loader/web_url_loader_impl_unittest.cc +++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -798,8 +798,8 @@ base::Optional<int64_t> downloaded_file_length; blink::WebBlobInfo downloaded_blob; client()->loader()->LoadSynchronously( - nullptr, request, response, error, data, encoded_data_length, - encoded_body_length, downloaded_file_length, downloaded_blob); + request, response, error, data, encoded_data_length, encoded_body_length, + downloaded_file_length, downloaded_blob); EXPECT_EQ(kEncodedBodyLength, encoded_body_length); EXPECT_EQ(kEncodedDataLength, encoded_data_length);
diff --git a/content/renderer/media_capture_from_element/canvas_capture_handler.cc b/content/renderer/media_capture_from_element/canvas_capture_handler.cc index 9c71a01..c2d9031 100644 --- a/content/renderer/media_capture_from_element/canvas_capture_handler.cc +++ b/content/renderer/media_capture_from_element/canvas_capture_handler.cc
@@ -62,12 +62,15 @@ const VideoCaptureDeliverFrameCB& frame_callback, const RunningCallback& running_callback) override { DCHECK(main_render_thread_checker_.CalledOnValidThread()); - canvas_handler_->StartVideoCapture(params, frame_callback, - running_callback); + if (canvas_handler_.get()) { + canvas_handler_->StartVideoCapture(params, frame_callback, + running_callback); + } } void RequestRefreshFrame() override { DCHECK(main_render_thread_checker_.CalledOnValidThread()); - canvas_handler_->RequestRefreshFrame(); + if (canvas_handler_.get()) + canvas_handler_->RequestRefreshFrame(); } void StopCapture() override { DCHECK(main_render_thread_checker_.CalledOnValidThread()); @@ -80,8 +83,10 @@ const float frame_rate_; // Bound to Main Render thread. base::ThreadChecker main_render_thread_checker_; - // CanvasCaptureHandler is owned by CanvasDrawListener in blink and might be - // destroyed before StopCapture() call. + // CanvasCaptureHandler is owned by CanvasDrawListener in blink. It is + // guaranteed to be destroyed on Main Render thread and it would happen + // independently of this class. Therefore, WeakPtr should always be checked + // before use. base::WeakPtr<CanvasCaptureHandler> canvas_handler_; };
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 3f687911..48d934d 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2297,33 +2297,9 @@ WebString::FromUTF16(params.target_origin)); } - WebDOMMessageEvent msg_event; - if (params.is_data_raw_string) { - v8::Isolate* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Local<v8::Context> context = frame_->MainWorldScriptContext(); - v8::Context::Scope context_scope(context); - V8ValueConverterImpl converter; - converter.SetDateAllowed(true); - converter.SetRegExpAllowed(true); - base::string16 data; - data.resize(params.message->data.encoded_message.size() / - sizeof(base::char16)); - std::memcpy(&data[0], params.message->data.encoded_message.data(), - data.length() * sizeof(base::char16)); - base::Value value(data); - v8::Local<v8::Value> result_value = converter.ToV8Value(&value, context); - WebSerializedScriptValue serialized_script_value = - WebSerializedScriptValue::Serialize(isolate, result_value); - msg_event = WebDOMMessageEvent(serialized_script_value, - WebString::FromUTF16(params.source_origin), - source_frame, frame_->GetDocument(), - std::move(params.message->data.ports)); - } else { - msg_event = WebDOMMessageEvent(std::move(params.message->data), - WebString::FromUTF16(params.source_origin), - source_frame, frame_->GetDocument()); - } + WebDOMMessageEvent msg_event(std::move(params.message->data), + WebString::FromUTF16(params.source_origin), + source_frame, frame_->GetDocument()); frame_->DispatchMessageEventWithOriginCheck( target_origin, msg_event, params.message->data.has_user_gesture); @@ -4568,10 +4544,6 @@ } void RenderFrameImpl::ShowDeferredContextMenu(const ContextMenuParams& params) { - // TODO (amaralp): Remove this once selection menu race conditions are fixed. - if (selection_text_.empty() && !params.selection_text.empty()) - return; - Send(new FrameHostMsg_ContextMenu(routing_id_, params)); }
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 5dbe0ff..6ed73a7 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -734,7 +734,6 @@ DCHECK(!web_frame_ || web_frame_ == target_frame); FrameMsg_PostMessage_Params params; - params.is_data_raw_string = false; params.message = new base::RefCountedData<blink::TransferableMessage>(event.AsMessage()); params.message->data.has_user_gesture = has_user_gesture;
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index bc8a289..d7262fe 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -96,7 +96,6 @@ #include "third_party/blink/public/platform/web_gesture_device.h" #include "third_party/blink/public/platform/web_gesture_event.h" #include "third_party/blink/public/platform/web_input_event.h" -#include <android/keycodes.h> #endif #if defined(OS_WIN) @@ -1552,55 +1551,6 @@ ExecuteJavaScriptAndReturnIntValue(check_did_select, &did_select)); EXPECT_EQ(1, did_select); } - -TEST_F(RenderViewImplTest, AndroidContextMenuSelectionCleared) { - // Load an HTML page consisting of an input field. - LoadHTML("<html>" - "<head>" - "</head>" - "<body>" - "<input id=\"test1\" value=\"abcdefghijklmnopqrstuvwxyz\"></input>" - "</body>" - "</html>"); - - WebGestureEvent gesture_event(WebInputEvent::kGestureTap, - WebInputEvent::kNoModifiers, - ui::EventTimeForNow()); - gesture_event.SetPositionInWidget(gfx::PointF(20, 20)); - - SendWebGestureEvent(gesture_event); - - frame()->GetWebFrame()->ExecuteCommand("SelectAll"); - - blink::WebKeyboardEvent event(blink::WebKeyboardEvent::kRawKeyDown, - blink::WebInputEvent::kNoModifiers, - ui::EventTimeForNow()); - event.windows_key_code = ui::VKEY_BACK; - event.native_key_code = AKEYCODE_DEL; - SendWebKeyboardEvent(event); - - scoped_refptr<content::MessageLoopRunner> message_loop_runner = - new content::MessageLoopRunner; - blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostTask( - FROM_HERE, message_loop_runner->QuitClosure()); - - EXPECT_FALSE(render_thread_->sink().GetUniqueMessageMatching( - FrameHostMsg_ContextMenu::ID)); - - message_loop_runner->Run(); - - EXPECT_FALSE(render_thread_->sink().GetUniqueMessageMatching( - FrameHostMsg_ContextMenu::ID)); - - // Check whether text selection is cleared. - blink::WebInputMethodController* controller = - frame()->GetWebFrame()->GetInputMethodController(); - blink::WebTextInputInfo info = controller->TextInputInfo(); - EXPECT_EQ(0, info.selection_start); - EXPECT_EQ(0, info.selection_end); -} - - #endif TEST_F(RenderViewImplTest, TestBackForward) {
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 1007db7..e6ada07 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -400,11 +400,7 @@ } blink::WebClipboard* RendererBlinkPlatformImpl::Clipboard() { - blink::WebClipboard* clipboard = - GetContentClient()->renderer()->OverrideWebClipboard(); - if (clipboard) - return clipboard; - + // TODO(dgozman): remove the ability to override this from embedder. return BlinkPlatformImpl::Clipboard(); }
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 363653d..924625a 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -490,6 +490,7 @@ prefs_ = WebPreferences(); should_override_prefs_ = false; LayoutTestContentBrowserClient::Get()->SetPopupBlockingEnabled(false); + LayoutTestContentBrowserClient::Get()->ResetMockClipboardHost(); navigation_history_dump_ = ""; pixel_dump_.reset(); actual_pixel_hash_ = "";
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc index 9b1341b..f601736 100644 --- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc +++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -26,6 +26,7 @@ #include "content/shell/common/layout_test/layout_test_switches.h" #include "content/shell/common/shell_messages.h" #include "content/shell/renderer/layout_test/blink_test_helpers.h" +#include "content/test/mock_clipboard_host.h" #include "device/bluetooth/test/fake_bluetooth.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -97,6 +98,11 @@ block_popups_ = block_popups; } +void LayoutTestContentBrowserClient::ResetMockClipboardHost() { + if (mock_clipboard_host_) + mock_clipboard_host_->Reset(); +} + std::unique_ptr<FakeBluetoothChooser> LayoutTestContentBrowserClient::GetNextFakeBluetoothChooser() { return std::move(next_fake_bluetooth_chooser_); @@ -134,9 +140,9 @@ registry->AddInterface(base::BindRepeating(&bluetooth::FakeBluetooth::Create), ui_task_runner); // This class outlives |render_process_host|, which owns |registry|. Since - // CreateFakeBluetoothChooser will not be called after |registry| is deleted + // any binders will not be called after |registry| is deleted // and |registry| is outlived by this class, it is safe to use - // base::Unretained. + // base::Unretained in all binders. registry->AddInterface( base::BindRepeating( &LayoutTestContentBrowserClient::CreateFakeBluetoothChooser, @@ -147,6 +153,19 @@ base::Unretained( render_process_host->GetStoragePartition()->GetWebPackageContext()))); registry->AddInterface(base::BindRepeating(&MojoLayoutTestHelper::Create)); + registry->AddInterface( + base::BindRepeating(&LayoutTestContentBrowserClient::BindClipboardHost, + base::Unretained(this)), + ui_task_runner); +} + +void LayoutTestContentBrowserClient::BindClipboardHost( + blink::mojom::ClipboardHostRequest request) { + if (!mock_clipboard_host_) { + mock_clipboard_host_ = + std::make_unique<MockClipboardHost>(browser_context()); + } + mock_clipboard_host_->Bind(std::move(request)); } void LayoutTestContentBrowserClient::OverrideWebkitPrefs(
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.h b/content/shell/browser/layout_test/layout_test_content_browser_client.h index 22245bf..d0ba191 100644 --- a/content/shell/browser/layout_test/layout_test_content_browser_client.h +++ b/content/shell/browser/layout_test/layout_test_content_browser_client.h
@@ -7,12 +7,14 @@ #include "content/shell/browser/shell_content_browser_client.h" #include "content/shell/common/layout_test/fake_bluetooth_chooser.mojom.h" +#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h" namespace content { class FakeBluetoothChooser; class LayoutTestBrowserContext; class LayoutTestNotificationManager; +class MockClipboardHost; class LayoutTestContentBrowserClient : public ShellContentBrowserClient { public: @@ -24,6 +26,7 @@ LayoutTestBrowserContext* GetLayoutTestBrowserContext(); void SetPopupBlockingEnabled(bool block_popups_); + void ResetMockClipboardHost(); // Retrieves the last created FakeBluetoothChooser instance. std::unique_ptr<FakeBluetoothChooser> GetNextFakeBluetoothChooser(); @@ -83,6 +86,7 @@ private: // Creates and stores a FakeBluetoothChooser instance. void CreateFakeBluetoothChooser(mojom::FakeBluetoothChooserRequest request); + void BindClipboardHost(blink::mojom::ClipboardHostRequest request); std::unique_ptr<LayoutTestNotificationManager> layout_test_notification_manager_; @@ -91,6 +95,7 @@ // Stores the next instance of FakeBluetoothChooser that is to be returned // when GetNextFakeBluetoothChooser is called. std::unique_ptr<FakeBluetoothChooser> next_fake_bluetooth_chooser_; + std::unique_ptr<MockClipboardHost> mock_clipboard_host_; }; } // content
diff --git a/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc b/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc index ac36346..a406244 100644 --- a/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc +++ b/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc
@@ -31,7 +31,6 @@ #include "content/shell/test_runner/web_test_interfaces.h" #include "content/shell/test_runner/web_test_runner.h" #include "content/shell/test_runner/web_view_test_proxy.h" -#include "content/test/mock_webclipboard_impl.h" #include "media/base/audio_latency.h" #include "media/base/mime_util.h" #include "media/media_buildflags.h" @@ -49,7 +48,6 @@ #include "v8/include/v8.h" using blink::WebAudioDevice; -using blink::WebClipboard; using blink::WebFrame; using blink::WebLocalFrame; using blink::WebMIDIAccessor; @@ -205,12 +203,6 @@ return interfaces->CreateAudioDevice(hw_sample_rate, buffer_size); } -WebClipboard* LayoutTestContentRendererClient::OverrideWebClipboard() { - if (!clipboard_) - clipboard_.reset(new MockWebClipboardImpl); - return clipboard_.get(); -} - WebThemeEngine* LayoutTestContentRendererClient::OverrideThemeEngine() { return LayoutTestRenderThreadObserver::GetInstance() ->test_interfaces()
diff --git a/content/shell/renderer/layout_test/layout_test_content_renderer_client.h b/content/shell/renderer/layout_test/layout_test_content_renderer_client.h index 4f66252..c3dbbb2b 100644 --- a/content/shell/renderer/layout_test/layout_test_content_renderer_client.h +++ b/content/shell/renderer/layout_test/layout_test_content_renderer_client.h
@@ -12,7 +12,6 @@ namespace content { class LayoutTestRenderThreadObserver; -class MockWebClipboardImpl; class LayoutTestContentRendererClient : public ShellContentRendererClient { public: @@ -27,7 +26,6 @@ blink::WebMIDIAccessorClient* client) override; std::unique_ptr<blink::WebAudioDevice> OverrideCreateAudioDevice( const blink::WebAudioLatencyHint& latency_hint) override; - blink::WebClipboard* OverrideWebClipboard() override; blink::WebThemeEngine* OverrideThemeEngine() override; std::unique_ptr<MediaStreamRendererFactory> CreateMediaStreamRendererFactory() override; @@ -40,7 +38,6 @@ private: std::unique_ptr<LayoutTestRenderThreadObserver> shell_observer_; - std::unique_ptr<MockWebClipboardImpl> clipboard_; }; } // namespace content
diff --git a/content/shell/test_runner/DEPS b/content/shell/test_runner/DEPS index 93c11b5..87557c17 100644 --- a/content/shell/test_runner/DEPS +++ b/content/shell/test_runner/DEPS
@@ -9,6 +9,7 @@ "+net/base", "+services/device/public/cpp/generic_sensor", "+services/device/public/mojom", + "+services/service_manager/public/cpp", "+skia", "+third_party/khronos/GLES2/gl2.h", "+third_party/skia",
diff --git a/content/shell/test_runner/pixel_dump.cc b/content/shell/test_runner/pixel_dump.cc index 9fe74f9..691b465 100644 --- a/content/shell/test_runner/pixel_dump.cc +++ b/content/shell/test_runner/pixel_dump.cc
@@ -17,23 +17,51 @@ #include "cc/paint/paint_flags.h" #include "cc/paint/skia_paint_canvas.h" #include "content/shell/test_runner/layout_test_runtime_flags.h" +#include "mojo/public/cpp/system/data_pipe_drainer.h" +#include "services/service_manager/public/cpp/connector.h" // FIXME: Including platform_canvas.h here is a layering violation. #include "skia/ext/platform_canvas.h" +#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_image.h" -#include "third_party/blink/public/platform/web_mock_clipboard.h" #include "third_party/blink/public/platform/web_point.h" #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_page_popup.h" #include "third_party/blink/public/web/web_print_params.h" +#include "ui/gfx/codec/png_codec.h" #include "ui/gfx/geometry/point.h" namespace test_runner { namespace { +class BitmapDataPipeDrainer : public mojo::DataPipeDrainer::Client { + public: + BitmapDataPipeDrainer(mojo::ScopedDataPipeConsumerHandle handle, + base::OnceCallback<void(const SkBitmap&)> callback) + : callback_(std::move(callback)), drainer_(this, std::move(handle)) {} + + void OnDataAvailable(const void* data, size_t num_bytes) override { + const unsigned char* ptr = static_cast<const unsigned char*>(data); + data_.insert(data_.end(), ptr, ptr + num_bytes); + } + + void OnDataComplete() override { + SkBitmap bitmap; + if (!gfx::PNGCodec::Decode(data_.data(), data_.size(), &bitmap)) + bitmap.reset(); + std::move(callback_).Run(bitmap); + delete this; + } + + private: + base::OnceCallback<void(const SkBitmap&)> callback_; + mojo::DataPipeDrainer drainer_; + std::vector<unsigned char> data_; +}; + class CaptureCallback : public base::RefCountedThreadSafe<CaptureCallback> { public: explicit CaptureCallback(base::OnceCallback<void(const SkBitmap&)> callback); @@ -182,24 +210,30 @@ int x, int y, base::OnceCallback<void(const SkBitmap&)> callback) { - DCHECK(!callback.is_null()); - uint64_t sequence_number = - blink::Platform::Current()->Clipboard()->SequenceNumber( - blink::mojom::ClipboardBuffer::kStandard); + blink::mojom::ClipboardHostPtr clipboard; + blink::Platform::Current()->GetConnector()->BindInterface( + blink::Platform::Current()->GetBrowserServiceName(), &clipboard); + + uint64_t sequence_number_before; + clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE, + &sequence_number_before); web_frame->CopyImageAt(blink::WebPoint(x, y)); - if (sequence_number == - blink::Platform::Current()->Clipboard()->SequenceNumber( - blink::mojom::ClipboardBuffer::kStandard)) { - SkBitmap emptyBitmap; - std::move(callback).Run(emptyBitmap); + uint64_t sequence_number_after; + clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE, + &sequence_number_after); + if (sequence_number_before == sequence_number_after) { + std::move(callback).Run(SkBitmap()); return; } - blink::WebImage image = - static_cast<blink::WebMockClipboard*>( - blink::Platform::Current()->Clipboard()) - ->ReadRawImage(blink::mojom::ClipboardBuffer::kStandard); - std::move(callback).Run(image.GetSkBitmap()); + blink::mojom::SerializedBlobPtr serialized_blob; + clipboard->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE, &serialized_blob); + blink::mojom::BlobPtr blob(std::move(serialized_blob->blob)); + mojo::DataPipe pipe; + blob->ReadAll(std::move(pipe.producer_handle), nullptr); + // Self-destructs after draining the pipe. + new BitmapDataPipeDrainer(std::move(pipe.consumer_handle), + std::move(callback)); } } // namespace test_runner
diff --git a/content/shell/test_runner/test_runner_for_specific_view.cc b/content/shell/test_runner/test_runner_for_specific_view.cc index cef9fa3..e2a3608 100644 --- a/content/shell/test_runner/test_runner_for_specific_view.cc +++ b/content/shell/test_runner/test_runner_for_specific_view.cc
@@ -283,13 +283,6 @@ v8::Local<v8::Function> callback) { v8::UniquePersistent<v8::Function> persistent_callback( blink::MainThreadIsolate(), callback); - - // TODO(lukasza): Support image capture in OOPIFs for - // https://crbug.com/477150. - CHECK(web_view()->MainFrame()->IsWebLocalFrame()) - << "Layout tests harness doesn't support calling " - << "testRunner.copyImageAtAndCapturePixelsAsyncThen from an OOPIF."; - CopyImageAtAndCapturePixels( web_view()->MainFrame()->ToWebLocalFrame(), x, y, base::BindOnce(&TestRunnerForSpecificView::CapturePixelsCallback,
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 6f7a854..597cbe3 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -213,6 +213,8 @@ "leveldb_wrapper_test_util.h", "mock_background_sync_controller.cc", "mock_background_sync_controller.h", + "mock_clipboard_host.cc", + "mock_clipboard_host.h", "mock_keyboard.cc", "mock_keyboard.h", "mock_keyboard_driver_win.cc", @@ -228,8 +230,6 @@ "mock_ssl_host_state_delegate.h", "mock_webblob_registry_impl.cc", "mock_webblob_registry_impl.h", - "mock_webclipboard_impl.cc", - "mock_webclipboard_impl.h", "mock_widget_impl.cc", "mock_widget_impl.h", "mock_widget_input_handler.cc", @@ -1955,7 +1955,6 @@ "../browser/android/java/java_type_unittest.cc", "../browser/android/overscroll_controller_android_unittest.cc", "../browser/android/scoped_surface_request_manager_unittest.cc", - "../browser/android/string_message_codec_unittest.cc", "../browser/android/url_request_content_job_unittest.cc", "../browser/media/capture/screen_capture_device_android_unittest.cc", "../renderer/java/gin_java_bridge_value_converter_unittest.cc",
diff --git a/content/test/data/gpu/pixel_webgl_sad_canvas.html b/content/test/data/gpu/pixel_webgl_sad_canvas.html index 5c714d4..5abcdfcd 100644 --- a/content/test/data/gpu/pixel_webgl_sad_canvas.html +++ b/content/test/data/gpu/pixel_webgl_sad_canvas.html
@@ -39,6 +39,8 @@ gl.clearColor(1.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); + + // Sending READY will make the GPU crash. sendResult("READY"); }
diff --git a/content/test/data/gpu/pixel_worker_requestAnimationFrame.html b/content/test/data/gpu/pixel_worker_requestAnimationFrame.html new file mode 100644 index 0000000..429174c --- /dev/null +++ b/content/test/data/gpu/pixel_worker_requestAnimationFrame.html
@@ -0,0 +1,69 @@ +<!DOCTYPE HTML> + +<html> +<head> +<title>Worker requestAnimationFrame after GPU crash</title> +<style type="text/css"> +.nomargin { + margin: 0px auto; +} +</style> +<script id="worker" type="text/worker"> +// This test kills the GPU process, which takes some time to recover, +// so give it a few seconds before proceeding. +var numFramesBeforeEnd = 200; + +function frame() { + if (--numFramesBeforeEnd == 0) { + postMessage("DONE"); + } else { + requestAnimationFrame(frame); + } +} +frame(); +postMessage("READY"); +</script> +<script> +var numFramesBeforeFail = 500; + +function sendResult(status, detail) { + console.log(detail); + if (window.domAutomationController) { + window.domAutomationController.send(status); + } else { + console.log(status); + } +} + +function main() { + var blob = new Blob([document.getElementById('worker').textContent]); + var worker = new Worker(URL.createObjectURL(blob)); + var done = false; + + worker.addEventListener("message", (ev) => { + if (ev.data == "READY") { + // Sending READY will make the GPU crash. + sendResult("READY"); + frame(); + } else { + sendResult("SUCCESS", "Test complete"); + done = true; + } + }); + + function frame() { + if (done) return; + if (--numFramesBeforeFail == 0) { + sendResult("FAILURE", "Worker.requestAnimationFrame didn't recover"); + } else { + requestAnimationFrame(frame); + } + } +} +</script> +</head> +<body onload="main()"> +<canvas id="c" width="300" height="300" class="nomargin" style="position:absolute; top:0px; left:0px;"></canvas> +</div> +</body> +</html>
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index f4e82ad..a88499d3 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -101,3 +101,6 @@ self.Flaky('Pixel_WebGLSadCanvas', ['mac'], bug=575305) self.Flaky('Pixel_WebGLSadCanvas', ['win', 'intel'], bug=575305) self.Fail('Pixel_WebGLSadCanvas', ['android', 'nvidia'], bug=575305) + + # TODO(fserb): temporary suppression for new test. + self.Fail('Pixel_WorkerRAF_OOPD', bug=833902)
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index e83c6fa..8de3698 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -395,6 +395,9 @@ unaccelerated_args = [ '--disable-accelerated-2d-canvas', '--disable-gpu-compositing'] + browser_args_oopd = [ + '--enable-viz-display-compositor', + '--enable-experimental-web-platform-features'] return [ PixelTestPage( @@ -412,6 +415,14 @@ browser_args=browser_args), PixelTestPage( + 'pixel_worker_requestAnimationFrame.html', + base_name + '_WorkerRAF_OOPD', + test_rect=[0, 0, 1, 1], + revision=1, + optional_action='CrashGpuProcess', + browser_args=browser_args_oopd), + + PixelTestPage( 'pixel_offscreenCanvas_transferToImageBitmap_main.html', base_name + '_OffscreenCanvasTransferToImageBitmap', test_rect=[0, 0, 300, 300], @@ -599,8 +610,7 @@ # arguments. def MacSpecificPages(base_name): iosurface_2d_canvas_args = [ - '--enable-accelerated-2d-canvas', - '--disable-display-list-2d-canvas'] + '--enable-accelerated-2d-canvas'] non_chromium_image_args = ['--disable-webgl-image-chromium']
diff --git a/content/test/mock_clipboard_host.cc b/content/test/mock_clipboard_host.cc new file mode 100644 index 0000000..23a088e --- /dev/null +++ b/content/test/mock_clipboard_host.cc
@@ -0,0 +1,225 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/mock_clipboard_host.h" + +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/blob_handle.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "ui/gfx/codec/png_codec.h" + +namespace content { + +namespace { + +void ReleaseSharedMemoryPixels(void* addr, void* context) { + MojoResult result = MojoUnmapBuffer(context); + DCHECK_EQ(MOJO_RESULT_OK, result); +} + +blink::mojom::SerializedBlobPtr ConstructSerializedBlobOnIO( + size_t data_size, + std::unique_ptr<BlobHandle> blob_handle) { + blink::mojom::SerializedBlobPtr blob; + if (blob_handle) { + blob = blink::mojom::SerializedBlob::New( + blob_handle->GetUUID(), "image/png", static_cast<int64_t>(data_size), + blob_handle->PassBlob().PassInterface()); + } + return blob; +} + +void ReplyToReadImage(blink::mojom::ClipboardHost::ReadImageCallback callback, + size_t data_size, + std::vector<unsigned char> owner_buffer, + std::unique_ptr<BlobHandle> blob_handle) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Unfortunately, we cannot call blob_handle->PassBlob() on UI, + // since that binds a blob ptr which only works on IO. If we do, + // future access to that blob will be handled by Mojo on the wrong + // thread. + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&ConstructSerializedBlobOnIO, data_size, + std::move(blob_handle)), + std::move(callback)); +} + +} // namespace + +MockClipboardHost::MockClipboardHost(BrowserContext* browser_context) + : browser_context_(browser_context) {} + +MockClipboardHost::~MockClipboardHost() {} + +void MockClipboardHost::Bind(blink::mojom::ClipboardHostRequest request) { + bindings_.AddBinding(this, std::move(request)); +} + +void MockClipboardHost::Reset() { + plain_text_ = base::string16(); + html_text_ = base::string16(); + url_ = GURL(); + image_.reset(); + custom_data_.clear(); + write_smart_paste_ = false; + needs_reset_ = false; +} + +void MockClipboardHost::GetSequenceNumber(ui::ClipboardType clipboard_type, + GetSequenceNumberCallback callback) { + std::move(callback).Run(sequence_number_); +} + +void MockClipboardHost::ReadAvailableTypes( + ui::ClipboardType clipboard_type, + ReadAvailableTypesCallback callback) { + std::vector<base::string16> types; + if (!plain_text_.empty()) + types.push_back(base::UTF8ToUTF16("text/plain")); + if (!html_text_.empty()) + types.push_back(base::UTF8ToUTF16("text/html")); + if (!image_.isNull()) + types.push_back(base::UTF8ToUTF16("image/png")); + for (auto& it : custom_data_) { + CHECK(std::find(types.begin(), types.end(), it.first) == types.end()); + types.push_back(it.first); + } + std::move(callback).Run(types, false); +} + +void MockClipboardHost::IsFormatAvailable(blink::mojom::ClipboardFormat format, + ui::ClipboardType clipboard_type, + IsFormatAvailableCallback callback) { + bool result = false; + switch (format) { + case blink::mojom::ClipboardFormat::kPlaintext: + result = !plain_text_.empty(); + break; + case blink::mojom::ClipboardFormat::kHtml: + result = !html_text_.empty(); + break; + case blink::mojom::ClipboardFormat::kSmartPaste: + result = write_smart_paste_; + break; + case blink::mojom::ClipboardFormat::kBookmark: + result = false; + break; + } + std::move(callback).Run(result); +} + +void MockClipboardHost::ReadText(ui::ClipboardType clipboard_type, + ReadTextCallback callback) { + std::move(callback).Run(plain_text_); +} + +void MockClipboardHost::ReadHtml(ui::ClipboardType clipboard_type, + ReadHtmlCallback callback) { + std::move(callback).Run(html_text_, url_, 0, html_text_.length()); +} + +void MockClipboardHost::ReadRtf(ui::ClipboardType clipboard_type, + ReadRtfCallback callback) { + std::move(callback).Run(std::string()); +} + +void MockClipboardHost::ReadImage(ui::ClipboardType clipboard_type, + ReadImageCallback callback) { + if (image_.isNull() || !browser_context_) { + std::move(callback).Run(nullptr); + return; + } + std::vector<unsigned char> png_data; + if (!gfx::PNGCodec::FastEncodeBGRASkBitmap(image_, false, &png_data)) { + std::move(callback).Run(nullptr); + return; + } + if (png_data.size() >= std::numeric_limits<uint32_t>::max()) { + std::move(callback).Run(nullptr); + return; + } + + char* char_data = reinterpret_cast<char*>(png_data.data()); + size_t size = png_data.size(); + // We pass png_data to retain encoded data until CreateMemoryBackedBlob + // takes a copy of it. + BrowserContext::CreateMemoryBackedBlob( + browser_context_, char_data, size, "", + base::BindOnce(&ReplyToReadImage, std::move(callback), size, + std::move(png_data))); +} + +void MockClipboardHost::ReadCustomData(ui::ClipboardType clipboard_type, + const base::string16& type, + ReadCustomDataCallback callback) { + auto it = custom_data_.find(type); + std::move(callback).Run(it != custom_data_.end() ? it->second + : base::string16()); +} + +void MockClipboardHost::WriteText(ui::ClipboardType, + const base::string16& text) { + if (needs_reset_) + Reset(); + plain_text_ = text; +} + +void MockClipboardHost::WriteHtml(ui::ClipboardType, + const base::string16& markup, + const GURL& url) { + if (needs_reset_) + Reset(); + html_text_ = markup; + url_ = url; +} + +void MockClipboardHost::WriteSmartPasteMarker(ui::ClipboardType) { + if (needs_reset_) + Reset(); + write_smart_paste_ = true; +} + +void MockClipboardHost::WriteCustomData( + ui::ClipboardType, + const base::flat_map<base::string16, base::string16>& data) { + if (needs_reset_) + Reset(); + for (auto& it : data) + custom_data_[it.first] = it.second; +} + +void MockClipboardHost::WriteBookmark(ui::ClipboardType, + const std::string& url, + const base::string16& title) {} + +void MockClipboardHost::WriteImage( + ui::ClipboardType, + const gfx::Size& size, + mojo::ScopedSharedBufferHandle shared_buffer_handle) { + if (needs_reset_) + Reset(); + if (!image_.setInfo(SkImageInfo::MakeN32Premul(size.width(), size.height()))) + return; + auto mapped = shared_buffer_handle->Map(image_.computeByteSize()); + if (!mapped) + return; + if (!image_.installPixels(image_.info(), mapped.get(), image_.rowBytes(), + &ReleaseSharedMemoryPixels, mapped.get())) { + return; + } + mapped.release(); +} + +void MockClipboardHost::CommitWrite(ui::ClipboardType) { + ++sequence_number_; + needs_reset_ = true; +} + +#if defined(OS_MACOSX) +void MockClipboardHost::WriteStringToFindPboard(const base::string16& text) {} +#endif + +} // namespace content
diff --git a/content/test/mock_clipboard_host.h b/content/test/mock_clipboard_host.h new file mode 100644 index 0000000..9d300df --- /dev/null +++ b/content/test/mock_clipboard_host.h
@@ -0,0 +1,85 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_MOCK_CLIPBOARD_HOST_H_ +#define CONTENT_TEST_MOCK_CLIPBOARD_HOST_H_ + +#include "base/macros.h" +#include "base/strings/string16.h" +#include "build/build_config.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace content { + +class BrowserContext; + +class MockClipboardHost : public blink::mojom::ClipboardHost { + public: + // |browser_context| could be null, in which case reading images + // is not supported. + explicit MockClipboardHost(BrowserContext* browser_context); + ~MockClipboardHost() override; + + void Bind(blink::mojom::ClipboardHostRequest request); + void Reset(); + + private: + // blink::mojom::ClipboardHost + void GetSequenceNumber(ui::ClipboardType clipboard_type, + GetSequenceNumberCallback callback) override; + void IsFormatAvailable(blink::mojom::ClipboardFormat format, + ui::ClipboardType clipboard_type, + IsFormatAvailableCallback callback) override; + void ReadAvailableTypes(ui::ClipboardType clipboard_type, + ReadAvailableTypesCallback callback) override; + void ReadText(ui::ClipboardType clipboard_type, + ReadTextCallback callback) override; + void ReadHtml(ui::ClipboardType clipboard_type, + ReadHtmlCallback callback) override; + void ReadRtf(ui::ClipboardType clipboard_type, + ReadRtfCallback callback) override; + void ReadImage(ui::ClipboardType clipboard_type, + ReadImageCallback callback) override; + void ReadCustomData(ui::ClipboardType clipboard_type, + const base::string16& type, + ReadCustomDataCallback callback) override; + void WriteText(ui::ClipboardType clipboard_type, + const base::string16& text) override; + void WriteHtml(ui::ClipboardType clipboard_type, + const base::string16& markup, + const GURL& url) override; + void WriteSmartPasteMarker(ui::ClipboardType clipboard_type) override; + void WriteCustomData( + ui::ClipboardType clipboard_type, + const base::flat_map<base::string16, base::string16>& data) override; + void WriteBookmark(ui::ClipboardType clipboard_type, + const std::string& url, + const base::string16& title) override; + void WriteImage(ui::ClipboardType clipboard_type, + const gfx::Size& size_in_pixels, + mojo::ScopedSharedBufferHandle shared_buffer_handle) override; + void CommitWrite(ui::ClipboardType clipboard_type) override; +#if defined(OS_MACOSX) + void WriteStringToFindPboard(const base::string16& text) override; +#endif + + BrowserContext* browser_context_; + mojo::BindingSet<blink::mojom::ClipboardHost> bindings_; + uint64_t sequence_number_ = 0; + base::string16 plain_text_; + base::string16 html_text_; + GURL url_; + SkBitmap image_; + std::map<base::string16, base::string16> custom_data_; + bool write_smart_paste_ = false; + bool needs_reset_ = false; + + DISALLOW_COPY_AND_ASSIGN(MockClipboardHost); +}; + +} // namespace content + +#endif // CONTENT_TEST_MOCK_CLIPBOARD_HOST_H_
diff --git a/content/test/mock_webclipboard_impl.cc b/content/test/mock_webclipboard_impl.cc deleted file mode 100644 index d38b97d..0000000 --- a/content/test/mock_webclipboard_impl.cc +++ /dev/null
@@ -1,198 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/test/mock_webclipboard_impl.h" - -#include <stddef.h> - -#include <algorithm> - -#include "base/guid.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "content/renderer/clipboard_utils.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_drag_data.h" -#include "third_party/blink/public/platform/web_image.h" -#include "third_party/blink/public/platform/web_thread_safe_data.h" -#include "third_party/blink/public/platform/web_url.h" -#include "ui/base/clipboard/clipboard.h" -#include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/geometry/size.h" - -using blink::WebDragData; -using blink::WebString; -using blink::WebURL; -using blink::WebVector; - -namespace content { - -MockWebClipboardImpl::MockWebClipboardImpl() - : m_sequenceNumber(0), - m_writeSmartPaste(false) {} - -MockWebClipboardImpl::~MockWebClipboardImpl() {} - -uint64_t MockWebClipboardImpl::SequenceNumber(blink::mojom::ClipboardBuffer) { - return m_sequenceNumber; -} - -bool MockWebClipboardImpl::IsFormatAvailable( - blink::mojom::ClipboardFormat format, - blink::mojom::ClipboardBuffer buffer) { - switch (format) { - case blink::mojom::ClipboardFormat::kPlaintext: - return !m_plainText.is_null(); - - case blink::mojom::ClipboardFormat::kHtml: - return !m_htmlText.is_null(); - - case blink::mojom::ClipboardFormat::kSmartPaste: - return m_writeSmartPaste; - - case blink::mojom::ClipboardFormat::kBookmark: - return false; - } - return false; -} - -WebVector<WebString> MockWebClipboardImpl::ReadAvailableTypes( - blink::mojom::ClipboardBuffer buffer, - bool* containsFilenames) { - *containsFilenames = false; - std::vector<WebString> results; - if (!m_plainText.string().empty()) { - results.push_back(WebString("text/plain")); - } - if (!m_htmlText.string().empty()) { - results.push_back(WebString("text/html")); - } - if (!m_image.IsNull()) { - results.push_back(WebString("image/png")); - } - for (std::map<base::string16, base::string16>::const_iterator it = - m_customData.begin(); - it != m_customData.end(); ++it) { - CHECK(std::find(results.begin(), results.end(), - WebString::FromUTF16(it->first)) == results.end()); - results.push_back(WebString::FromUTF16(it->first)); - } - return results; -} - -blink::WebString MockWebClipboardImpl::ReadPlainText( - blink::mojom::ClipboardBuffer buffer) { - return WebString::FromUTF16(m_plainText); -} - -// TODO(wtc): set output argument *url. -blink::WebString MockWebClipboardImpl::ReadHTML( - blink::mojom::ClipboardBuffer buffer, - blink::WebURL* url, - unsigned* fragmentStart, - unsigned* fragmentEnd) { - *fragmentStart = 0; - *fragmentEnd = static_cast<unsigned>(m_htmlText.string().length()); - return WebString::FromUTF16(m_htmlText); -} - -blink::WebBlobInfo MockWebClipboardImpl::ReadImage( - blink::mojom::ClipboardBuffer buffer) { - std::vector<unsigned char> output; - const SkBitmap& bitmap = m_image.GetSkBitmap(); - if (!gfx::PNGCodec::FastEncodeBGRASkBitmap( - bitmap, false /* discard_transparency */, &output)) { - return blink::WebBlobInfo(); - } - return CreateBlobFromData(output, - WebString::FromASCII(ui::Clipboard::kMimeTypePNG)); -} - -blink::WebImage MockWebClipboardImpl::ReadRawImage( - blink::mojom::ClipboardBuffer buffer) { - return m_image; -} - -blink::WebString MockWebClipboardImpl::ReadCustomData( - blink::mojom::ClipboardBuffer buffer, - const blink::WebString& type) { - std::map<base::string16, base::string16>::const_iterator it = - m_customData.find(type.Utf16()); - if (it != m_customData.end()) - return WebString::FromUTF16(it->second); - return blink::WebString(); -} - -void MockWebClipboardImpl::WriteHTML(const blink::WebString& htmlText, - const blink::WebURL& url, - const blink::WebString& plainText, - bool writeSmartPaste) { - clear(); - - m_htmlText = WebString::ToNullableString16(htmlText); - m_plainText = WebString::ToNullableString16(plainText); - m_writeSmartPaste = writeSmartPaste; - ++m_sequenceNumber; -} - -void MockWebClipboardImpl::WritePlainText(const blink::WebString& plain_text) { - clear(); - - m_plainText = WebString::ToNullableString16(plain_text); - ++m_sequenceNumber; -} - -void MockWebClipboardImpl::WriteImage(const blink::WebImage& image, - const blink::WebURL& url, - const blink::WebString& title) { - if (!image.IsNull()) { - clear(); - - m_plainText = m_htmlText; - m_htmlText = base::NullableString16( - base::UTF8ToUTF16(URLToImageMarkup(url, title)), false /* is_null */); - m_image = image; - ++m_sequenceNumber; - } -} - -void MockWebClipboardImpl::WriteDataObject(const WebDragData& data) { - clear(); - - const WebVector<WebDragData::Item>& itemList = data.Items(); - for (size_t i = 0; i < itemList.size(); ++i) { - const WebDragData::Item& item = itemList[i]; - switch (item.storage_type) { - case WebDragData::Item::kStorageTypeString: { - ++m_sequenceNumber; - base::string16 type(item.string_type.Utf16()); - if (base::EqualsASCII(type, ui::Clipboard::kMimeTypeText)) { - m_plainText = WebString::ToNullableString16(item.string_data); - continue; - } - if (base::EqualsASCII(type, ui::Clipboard::kMimeTypeHTML)) { - m_htmlText = WebString::ToNullableString16(item.string_data); - continue; - } - m_customData.insert(std::make_pair(type, item.string_data.Utf16())); - continue; - } - default: - // Currently other types are unused by the clipboard implementation. - NOTREACHED(); - } - } -} - -void MockWebClipboardImpl::clear() { - m_plainText = base::NullableString16(); - m_htmlText = base::NullableString16(); - m_image.Reset(); - m_customData.clear(); - m_writeSmartPaste = false; -} - -} // namespace content
diff --git a/content/test/mock_webclipboard_impl.h b/content/test/mock_webclipboard_impl.h deleted file mode 100644 index 7974248..0000000 --- a/content/test/mock_webclipboard_impl.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This file mocks out just enough of the WebClipboard API for running the -// webkit tests. This is so we can run webkit tests without them sharing a -// clipboard, which allows for running them in parallel and having the tests -// not interact with actual user actions. - -#ifndef CONTENT_TEST_MOCK_WEBCLIPBOARD_IMPL_H_ -#define CONTENT_TEST_MOCK_WEBCLIPBOARD_IMPL_H_ - -#include <stdint.h> - -#include <map> - -#include "base/strings/nullable_string16.h" -#include "base/strings/string16.h" -#include "third_party/blink/public/platform/web_drag_data.h" -#include "third_party/blink/public/platform/web_image.h" -#include "third_party/blink/public/platform/web_mock_clipboard.h" - -namespace content { - -class MockWebClipboardImpl : public blink::WebMockClipboard { - public: - MockWebClipboardImpl(); - virtual ~MockWebClipboardImpl(); - - uint64_t SequenceNumber(blink::mojom::ClipboardBuffer) override; - bool IsFormatAvailable(blink::mojom::ClipboardFormat format, - blink::mojom::ClipboardBuffer buffer) override; - blink::WebVector<blink::WebString> ReadAvailableTypes( - blink::mojom::ClipboardBuffer buffer, - bool* containsFilenames) override; - - blink::WebString ReadPlainText(blink::mojom::ClipboardBuffer buffer) override; - blink::WebString ReadHTML(blink::mojom::ClipboardBuffer buffer, - blink::WebURL* url, - unsigned* fragmentStart, - unsigned* fragmentEnd) override; - blink::WebBlobInfo ReadImage(blink::mojom::ClipboardBuffer buffer) override; - blink::WebImage ReadRawImage(blink::mojom::ClipboardBuffer buffer) override; - blink::WebString ReadCustomData(blink::mojom::ClipboardBuffer buffer, - const blink::WebString& type) override; - - void WritePlainText(const blink::WebString& plain_text) override; - void WriteHTML(const blink::WebString& htmlText, - const blink::WebURL& url, - const blink::WebString& plainText, - bool writeSmartPaste) override; - void WriteImage(const blink::WebImage& image, - const blink::WebURL& url, - const blink::WebString& title) override; - void WriteDataObject(const blink::WebDragData& data) override; - - private: - void clear(); - - uint64_t m_sequenceNumber; - base::NullableString16 m_plainText; - base::NullableString16 m_htmlText; - blink::WebImage m_image; - std::map<base::string16, base::string16> m_customData; - bool m_writeSmartPaste; -}; - -} // namespace content - -#endif // CONTENT_TEST_MOCK_WEBCLIPBOARD_IMPL_H_
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc index a681ff9..6ed97e9 100644 --- a/content/test/test_blink_web_unit_test_support.cc +++ b/content/test/test_blink_web_unit_test_support.cc
@@ -18,14 +18,16 @@ #include "cc/blink/web_layer_impl.h" #include "cc/trees/layer_tree_settings.h" #include "content/app/mojo/mojo_init.h" +#include "content/public/common/service_names.mojom.h" #include "content/renderer/loader/web_data_consumer_handle_impl.h" #include "content/renderer/loader/web_url_loader_impl.h" -#include "content/test/mock_webclipboard_impl.h" +#include "content/test/mock_clipboard_host.h" #include "content/test/web_gesture_curve_mock.h" #include "media/base/media.h" #include "media/media_buildflags.h" #include "net/cookies/cookie_monster.h" #include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/connector.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h" #include "third_party/blink/public/platform/web_connection_type.h" @@ -135,7 +137,9 @@ #endif url_loader_factory_ = blink::WebURLLoaderMockFactory::Create(); - mock_clipboard_.reset(new MockWebClipboardImpl()); + // Mock out clipboard calls so that tests don't mess + // with each other's copies/pastes when running in parallel. + mock_clipboard_host_ = std::make_unique<MockClipboardHost>(nullptr); #if defined(V8_USE_EXTERNAL_STARTUP_DATA) gin::V8Initializer::LoadV8Snapshot(kSnapshotType); @@ -164,6 +168,15 @@ // Initialize mojo firstly to enable Blink initialization to use it. InitializeMojo(); + connector_ = std::make_unique<service_manager::Connector>( + service_manager::mojom::ConnectorPtrInfo()); + service_manager::Connector::TestApi test_api(connector_.get()); + test_api.OverrideBinderForTesting( + service_manager::Identity(mojom::kBrowserServiceName), + blink::mojom::ClipboardHost::Name_, + base::BindRepeating(&TestBlinkWebUnitTestSupport::BindClipboardHost, + weak_factory_.GetWeakPtr())); + service_manager::BinderRegistry empty_registry; blink::Initialize(this, &empty_registry); blink::SetLayoutTestMode(true); @@ -192,7 +205,7 @@ TestBlinkWebUnitTestSupport::~TestBlinkWebUnitTestSupport() { url_loader_factory_.reset(); - mock_clipboard_.reset(); + mock_clipboard_host_.reset(); if (main_thread_scheduler_) main_thread_scheduler_->Shutdown(); } @@ -201,12 +214,6 @@ return &blob_registry_; } -blink::WebClipboard* TestBlinkWebUnitTestSupport::Clipboard() { - // Mock out clipboard calls so that tests don't mess - // with each other's copies/pastes when running in parallel. - return mock_clipboard_.get(); -} - blink::WebIDBFactory* TestBlinkWebUnitTestSupport::IdbFactory() { NOTREACHED() << "IndexedDB cannot be tested with in-process harnesses."; @@ -361,4 +368,14 @@ #endif } +service_manager::Connector* TestBlinkWebUnitTestSupport::GetConnector() { + return connector_.get(); +} + +void TestBlinkWebUnitTestSupport::BindClipboardHost( + mojo::ScopedMessagePipeHandle handle) { + mock_clipboard_host_->Bind( + blink::mojom::ClipboardHostRequest(std::move(handle))); +} + } // namespace content
diff --git a/content/test/test_blink_web_unit_test_support.h b/content/test/test_blink_web_unit_test_support.h index 869f24d..1381f83 100644 --- a/content/test/test_blink_web_unit_test_support.h +++ b/content/test/test_blink_web_unit_test_support.h
@@ -15,7 +15,6 @@ #include "cc/blink/web_compositor_support_impl.h" #include "content/child/blink_platform_impl.h" #include "content/test/mock_webblob_registry_impl.h" -#include "content/test/mock_webclipboard_impl.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" namespace blink { @@ -26,6 +25,8 @@ namespace content { +class MockClipboardHost; + // An implementation of BlinkPlatformImpl for tests. class TestBlinkWebUnitTestSupport : public BlinkPlatformImpl { public: @@ -33,7 +34,6 @@ ~TestBlinkWebUnitTestSupport() override; blink::WebBlobRegistry* GetBlobRegistry() override; - blink::WebClipboard* Clipboard() override; blink::WebIDBFactory* IdbFactory() override; std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory() @@ -69,9 +69,14 @@ std::unique_ptr<blink::WebRTCCertificateGenerator> CreateRTCCertificateGenerator() override; + service_manager::Connector* GetConnector() override; + private: + void BindClipboardHost(mojo::ScopedMessagePipeHandle handle); + + std::unique_ptr<service_manager::Connector> connector_; MockWebBlobRegistryImpl blob_registry_; - std::unique_ptr<MockWebClipboardImpl> mock_clipboard_; + std::unique_ptr<MockClipboardHost> mock_clipboard_host_; base::ScopedTempDir file_system_root_; std::unique_ptr<blink::WebURLLoaderMockFactory> url_loader_factory_; cc_blink::WebCompositorSupportImpl compositor_support_;
diff --git a/device/BUILD.gn b/device/BUILD.gn index 0e699bb..165c841 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -283,7 +283,7 @@ ] } - if (enable_vr && is_android) { + if (enable_vr) { sources += [ "vr/orientation/orientation_device_provider_unittest.cc", "vr/orientation/orientation_device_unittest.cc", @@ -291,10 +291,15 @@ "vr/vr_display_impl_unittest.cc", ] + if (is_android) { + deps += [ "//device/vr:java" ] + } + + defines = [ "DEVICE_VR_IMPLEMENTATION" ] + deps += [ "//device/vr", "//device/vr:fakes", - "//device/vr:java", "//device/vr/public/mojom", "//services/device/public/cpp/generic_sensor", "//ui/display",
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 7b14c18..8d5ab6b 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -395,11 +395,6 @@ GLES2_GET_FUN(UnlockDiscardableTextureCHROMIUM) #define glLockDiscardableTextureCHROMIUM \ GLES2_GET_FUN(LockDiscardableTextureCHROMIUM) -#define glBeginRasterCHROMIUM GLES2_GET_FUN(BeginRasterCHROMIUM) -#define glMapRasterCHROMIUM GLES2_GET_FUN(MapRasterCHROMIUM) -#define glMapFontBufferCHROMIUM GLES2_GET_FUN(MapFontBufferCHROMIUM) -#define glUnmapRasterCHROMIUM GLES2_GET_FUN(UnmapRasterCHROMIUM) -#define glEndRasterCHROMIUM GLES2_GET_FUN(EndRasterCHROMIUM) #define glTexStorage2DImageCHROMIUM GLES2_GET_FUN(TexStorage2DImageCHROMIUM) #define glSetColorSpaceMetadataCHROMIUM \ GLES2_GET_FUN(SetColorSpaceMetadataCHROMIUM)
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index ee0b5058..4292ae2 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1770,29 +1770,6 @@ bool GL_APIENTRY GLES2LockDiscardableTextureCHROMIUM(GLuint texture_id) { return gles2::GetGLContext()->LockDiscardableTextureCHROMIUM(texture_id); } -void GL_APIENTRY -GLES2BeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) { - gles2::GetGLContext()->BeginRasterCHROMIUM( - texture_id, sk_color, msaa_sample_count, can_use_lcd_text, color_type, - color_space_transfer_cache_id); -} -void* GL_APIENTRY GLES2MapRasterCHROMIUM(GLsizeiptr size) { - return gles2::GetGLContext()->MapRasterCHROMIUM(size); -} -void* GL_APIENTRY GLES2MapFontBufferCHROMIUM(GLsizeiptr size) { - return gles2::GetGLContext()->MapFontBufferCHROMIUM(size); -} -void GL_APIENTRY GLES2UnmapRasterCHROMIUM(GLsizeiptr written_size) { - gles2::GetGLContext()->UnmapRasterCHROMIUM(written_size); -} -void GL_APIENTRY GLES2EndRasterCHROMIUM() { - gles2::GetGLContext()->EndRasterCHROMIUM(); -} void GL_APIENTRY GLES2TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage, @@ -3151,26 +3128,6 @@ glLockDiscardableTextureCHROMIUM), }, { - "glBeginRasterCHROMIUM", - reinterpret_cast<GLES2FunctionPointer>(glBeginRasterCHROMIUM), - }, - { - "glMapRasterCHROMIUM", - reinterpret_cast<GLES2FunctionPointer>(glMapRasterCHROMIUM), - }, - { - "glMapFontBufferCHROMIUM", - reinterpret_cast<GLES2FunctionPointer>(glMapFontBufferCHROMIUM), - }, - { - "glUnmapRasterCHROMIUM", - reinterpret_cast<GLES2FunctionPointer>(glUnmapRasterCHROMIUM), - }, - { - "glEndRasterCHROMIUM", - reinterpret_cast<GLES2FunctionPointer>(glEndRasterCHROMIUM), - }, - { "glTexStorage2DImageCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glTexStorage2DImageCHROMIUM), },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 40f741b..b2b1d52 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3269,72 +3269,6 @@ } } -void BeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) { - gles2::cmds::BeginRasterCHROMIUM* c = - GetCmdSpace<gles2::cmds::BeginRasterCHROMIUM>(); - if (c) { - c->Init(texture_id, sk_color, msaa_sample_count, can_use_lcd_text, - color_type, color_space_transfer_cache_id); - } -} - -void RasterCHROMIUM(GLuint raster_shm_id, - GLuint raster_shm_offset, - GLsizeiptr raster_shm_size, - GLuint font_shm_id, - GLuint font_shm_offset, - GLsizeiptr font_shm_size) { - gles2::cmds::RasterCHROMIUM* c = GetCmdSpace<gles2::cmds::RasterCHROMIUM>(); - if (c) { - c->Init(raster_shm_id, raster_shm_offset, raster_shm_size, font_shm_id, - font_shm_offset, font_shm_size); - } -} - -void EndRasterCHROMIUM() { - gles2::cmds::EndRasterCHROMIUM* c = - GetCmdSpace<gles2::cmds::EndRasterCHROMIUM>(); - if (c) { - c->Init(); - } -} - -void CreateTransferCacheEntryINTERNAL(GLuint entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size) { - gles2::cmds::CreateTransferCacheEntryINTERNAL* c = - GetCmdSpace<gles2::cmds::CreateTransferCacheEntryINTERNAL>(); - if (c) { - c->Init(entry_type, entry_id, handle_shm_id, handle_shm_offset, data_shm_id, - data_shm_offset, data_size); - } -} - -void DeleteTransferCacheEntryINTERNAL(GLuint entry_type, GLuint entry_id) { - gles2::cmds::DeleteTransferCacheEntryINTERNAL* c = - GetCmdSpace<gles2::cmds::DeleteTransferCacheEntryINTERNAL>(); - if (c) { - c->Init(entry_type, entry_id); - } -} - -void UnlockTransferCacheEntryINTERNAL(GLuint entry_type, GLuint entry_id) { - gles2::cmds::UnlockTransferCacheEntryINTERNAL* c = - GetCmdSpace<gles2::cmds::UnlockTransferCacheEntryINTERNAL>(); - if (c) { - c->Init(entry_type, entry_id); - } -} - void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLsizei width,
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index ed59f135e..4616347 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -5949,6 +5949,36 @@ return manager->TextureIsDeletedForTracing(texture_id); } +void* GLES2Implementation::MapTransferCacheEntry(size_t serialized_size) { + NOTREACHED(); + return nullptr; +} + +void GLES2Implementation::UnmapAndCreateTransferCacheEntry(uint32_t type, + uint32_t id) { + NOTREACHED(); +} + +bool GLES2Implementation::ThreadsafeLockTransferCacheEntry(uint32_t type, + uint32_t id) { + NOTREACHED(); + return false; +} + +void GLES2Implementation::UnlockTransferCacheEntries( + const std::vector<std::pair<uint32_t, uint32_t>>& entries) { + NOTREACHED(); +} + +void GLES2Implementation::DeleteTransferCacheEntry(uint32_t type, uint32_t id) { + NOTREACHED(); +} + +unsigned int GLES2Implementation::GetTransferBufferFreeSize() const { + NOTREACHED(); + return 0; +} + void GLES2Implementation::GenSyncTokenCHROMIUM(GLbyte* sync_token) { if (!sync_token) { SetGLError(GL_INVALID_VALUE, "glGenSyncTokenCHROMIUM", "empty sync_token"); @@ -6482,7 +6512,7 @@ coords_shm_offset = buffer.offset(); } - DCHECK(num_commands > 0); + DCHECK_GT(num_commands, 0); unsigned char* commands_addr = static_cast<unsigned char*>(buffer.address()) + coords_size; memcpy(commands_addr, commands, num_commands); @@ -6556,7 +6586,7 @@ } // The multiplication below will not overflow. - DCHECK(transforms_component_count <= 12); + DCHECK_LE(transforms_component_count, 12U); uint32_t one_transform_size = sizeof(GLfloat) * transforms_component_count; uint32_t transforms_size; @@ -6590,7 +6620,7 @@ *out_transforms_offset = 0; } - DCHECK(paths_size > 0); + DCHECK_GT(paths_size, 0U); unsigned char* paths_addr = static_cast<unsigned char*>(buffer->address()) + transforms_size; memcpy(paths_addr, paths, paths_size); @@ -6859,7 +6889,7 @@ return; } - DCHECK(coeffs_size > 0); + DCHECK_GT(coeffs_size, 0U); unsigned char* addr = static_cast<unsigned char*>(buffer.address()); memcpy(addr, coeffs, coeffs_size); @@ -6953,83 +6983,6 @@ CheckGLError(); } -void* GLES2Implementation::MapRasterCHROMIUM(GLsizeiptr size) { - if (size < 0) { - SetGLError(GL_INVALID_VALUE, "glMapRasterCHROMIUM", "negative size"); - return nullptr; - } - if (raster_mapped_buffer_) { - SetGLError(GL_INVALID_OPERATION, "glMapRasterCHROMIUM", "already mapped"); - return nullptr; - } - raster_mapped_buffer_.emplace(size, helper_, transfer_buffer_); - if (!raster_mapped_buffer_->valid()) { - SetGLError(GL_INVALID_OPERATION, "glMapRasterCHROMIUM", "size too big"); - raster_mapped_buffer_ = base::nullopt; - return nullptr; - } - return raster_mapped_buffer_->address(); -} - -void* GLES2Implementation::MapFontBufferCHROMIUM(GLsizeiptr size) { - if (size < 0) { - SetGLError(GL_INVALID_VALUE, "glMapFontBufferCHROMIUM", "negative size"); - return nullptr; - } - if (font_mapped_buffer_) { - SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM", - "already mapped"); - return nullptr; - } - if (!raster_mapped_buffer_) { - SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM", - "mapped font buffer with no raster buffer"); - return nullptr; - } - - font_mapped_buffer_.emplace(size, helper_, mapped_memory_.get()); - if (!font_mapped_buffer_->valid()) { - SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM", "size too big"); - font_mapped_buffer_ = base::nullopt; - return nullptr; - } - return font_mapped_buffer_->address(); -} - -void GLES2Implementation::UnmapRasterCHROMIUM(GLsizeiptr written_size) { - if (written_size < 0) { - SetGLError(GL_INVALID_VALUE, "glUnmapRasterCHROMIUM", - "negative written_size"); - return; - } - if (!raster_mapped_buffer_) { - SetGLError(GL_INVALID_OPERATION, "glUnmapRasterCHROMIUM", "not mapped"); - return; - } - DCHECK(raster_mapped_buffer_->valid()); - if (written_size == 0) { - raster_mapped_buffer_->Discard(); - raster_mapped_buffer_ = base::nullopt; - return; - } - raster_mapped_buffer_->Shrink(written_size); - - GLuint font_shm_id = 0u; - GLuint font_shm_offset = 0u; - GLsizeiptr font_shm_size = 0u; - if (font_mapped_buffer_) { - font_shm_id = font_mapped_buffer_->shm_id(); - font_shm_offset = font_mapped_buffer_->offset(); - font_shm_size = font_mapped_buffer_->size(); - } - helper_->RasterCHROMIUM(raster_mapped_buffer_->shm_id(), - raster_mapped_buffer_->offset(), written_size, - font_shm_id, font_shm_offset, font_shm_size); - raster_mapped_buffer_ = base::nullopt; - font_mapped_buffer_ = base::nullopt; - CheckGLError(); -} - void GLES2Implementation::IssueBeginQuery(GLenum target, GLuint id, uint32_t sync_data_shm_id, @@ -7076,29 +7029,6 @@ return helper_; } -void GLES2Implementation::IssueCreateTransferCacheEntry( - GLuint entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size) { - helper_->CreateTransferCacheEntryINTERNAL(entry_type, entry_id, handle_shm_id, - handle_shm_offset, data_shm_id, - data_shm_offset, data_size); -} - -void GLES2Implementation::IssueDeleteTransferCacheEntry(GLuint entry_type, - GLuint entry_id) { - helper_->DeleteTransferCacheEntryINTERNAL(entry_type, entry_id); -} - -void GLES2Implementation::IssueUnlockTransferCacheEntry(GLuint entry_type, - GLuint entry_id) { - helper_->UnlockTransferCacheEntryINTERNAL(entry_type, entry_id); -} - CommandBuffer* GLES2Implementation::command_buffer() const { return helper_->command_buffer(); }
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index b3e8f1c..1cdbffa 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -128,7 +128,13 @@ uint32_t texture_id) override; bool ThreadsafeDiscardableTextureIsDeletedForTracing( uint32_t texture_id) override; - + void* MapTransferCacheEntry(size_t serialized_size) override; + void UnmapAndCreateTransferCacheEntry(uint32_t type, uint32_t id) override; + bool ThreadsafeLockTransferCacheEntry(uint32_t type, uint32_t id) override; + void UnlockTransferCacheEntries( + const std::vector<std::pair<uint32_t, uint32_t>>& entries) override; + void DeleteTransferCacheEntry(uint32_t type, uint32_t id) override; + unsigned int GetTransferBufferFreeSize() const override; void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8_t>* result); GLint GetAttribLocationHelper(GLuint program, const char* name); @@ -196,19 +202,7 @@ const char* function_name, const char* msg) override; - // ClientTransferCache::Client implementation. - void IssueCreateTransferCacheEntry(GLuint entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size) override; - void IssueDeleteTransferCacheEntry(GLuint entry_type, - GLuint entry_id) override; - void IssueUnlockTransferCacheEntry(GLuint entry_type, - GLuint entry_id) override; - CommandBuffer* command_buffer() const override; + CommandBuffer* command_buffer() const; private: friend class GLES2ImplementationTest;
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 3ad0d1f..258b9c2 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1244,21 +1244,6 @@ bool LockDiscardableTextureCHROMIUM(GLuint texture_id) override; -void BeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) override; - -void* MapRasterCHROMIUM(GLsizeiptr size) override; - -void* MapFontBufferCHROMIUM(GLsizeiptr size) override; - -void UnmapRasterCHROMIUM(GLsizeiptr written_size) override; - -void EndRasterCHROMIUM() override; - void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage,
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 64bc0f4..4a2358ee 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3576,33 +3576,6 @@ CheckGLError(); } -void GLES2Implementation::BeginRasterCHROMIUM( - GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) { - GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG( - "[" << GetLogPrefix() << "] glBeginRasterCHROMIUM(" << texture_id << ", " - << sk_color << ", " << msaa_sample_count << ", " - << GLES2Util::GetStringBool(can_use_lcd_text) << ", " << color_type - << ", " << color_space_transfer_cache_id << ")"); - helper_->BeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count, - can_use_lcd_text, color_type, - color_space_transfer_cache_id); - CheckGLError(); -} - -void GLES2Implementation::EndRasterCHROMIUM() { - GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEndRasterCHROMIUM(" - << ")"); - helper_->EndRasterCHROMIUM(); - CheckGLError(); -} - void GLES2Implementation::TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage,
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index f73cba23..a00aeb5 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3082,28 +3082,6 @@ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -TEST_F(GLES2ImplementationTest, BeginRasterCHROMIUM) { - struct Cmds { - cmds::BeginRasterCHROMIUM cmd; - }; - Cmds expected; - expected.cmd.Init(1, 2, 3, true, 5, 6); - - gl_->BeginRasterCHROMIUM(1, 2, 3, true, 5, 6); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); -} - -TEST_F(GLES2ImplementationTest, EndRasterCHROMIUM) { - struct Cmds { - cmds::EndRasterCHROMIUM cmd; - }; - Cmds expected; - expected.cmd.Init(); - - gl_->EndRasterCHROMIUM(); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); -} - TEST_F(GLES2ImplementationTest, TexStorage2DImageCHROMIUM) { struct Cmds { cmds::TexStorage2DImageCHROMIUM cmd;
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 96cdec5..8ae17d8 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -925,16 +925,6 @@ virtual void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) = 0; virtual void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) = 0; virtual bool LockDiscardableTextureCHROMIUM(GLuint texture_id) = 0; -virtual void BeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) = 0; -virtual void* MapRasterCHROMIUM(GLsizeiptr size) = 0; -virtual void* MapFontBufferCHROMIUM(GLsizeiptr size) = 0; -virtual void UnmapRasterCHROMIUM(GLsizeiptr written_size) = 0; -virtual void EndRasterCHROMIUM() = 0; virtual void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index e8887813..9b7ab78 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -898,16 +898,6 @@ void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) override; void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) override; bool LockDiscardableTextureCHROMIUM(GLuint texture_id) override; -void BeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) override; -void* MapRasterCHROMIUM(GLsizeiptr size) override; -void* MapFontBufferCHROMIUM(GLsizeiptr size) override; -void UnmapRasterCHROMIUM(GLsizeiptr written_size) override; -void EndRasterCHROMIUM() override; void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 9cb545a..5da71d4 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1206,21 +1206,6 @@ GLuint /* texture_id */) { return 0; } -void GLES2InterfaceStub::BeginRasterCHROMIUM( - GLuint /* texture_id */, - GLuint /* sk_color */, - GLuint /* msaa_sample_count */, - GLboolean /* can_use_lcd_text */, - GLint /* color_type */, - GLuint /* color_space_transfer_cache_id */) {} -void* GLES2InterfaceStub::MapRasterCHROMIUM(GLsizeiptr /* size */) { - return 0; -} -void* GLES2InterfaceStub::MapFontBufferCHROMIUM(GLsizeiptr /* size */) { - return 0; -} -void GLES2InterfaceStub::UnmapRasterCHROMIUM(GLsizeiptr /* written_size */) {} -void GLES2InterfaceStub::EndRasterCHROMIUM() {} void GLES2InterfaceStub::TexStorage2DImageCHROMIUM(GLenum /* target */, GLenum /* internalFormat */, GLenum /* bufferUsage */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 3ebafff6a..5820e10 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -898,16 +898,6 @@ void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) override; void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) override; bool LockDiscardableTextureCHROMIUM(GLuint texture_id) override; -void BeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) override; -void* MapRasterCHROMIUM(GLsizeiptr size) override; -void* MapFontBufferCHROMIUM(GLsizeiptr size) override; -void UnmapRasterCHROMIUM(GLsizeiptr written_size) override; -void EndRasterCHROMIUM() override; void TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 7934e5b..36510df 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2569,39 +2569,6 @@ return gl_->LockDiscardableTextureCHROMIUM(texture_id); } -void GLES2TraceImplementation::BeginRasterCHROMIUM( - GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BeginRasterCHROMIUM"); - gl_->BeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count, - can_use_lcd_text, color_type, - color_space_transfer_cache_id); -} - -void* GLES2TraceImplementation::MapRasterCHROMIUM(GLsizeiptr size) { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapRasterCHROMIUM"); - return gl_->MapRasterCHROMIUM(size); -} - -void* GLES2TraceImplementation::MapFontBufferCHROMIUM(GLsizeiptr size) { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapFontBufferCHROMIUM"); - return gl_->MapFontBufferCHROMIUM(size); -} - -void GLES2TraceImplementation::UnmapRasterCHROMIUM(GLsizeiptr written_size) { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UnmapRasterCHROMIUM"); - gl_->UnmapRasterCHROMIUM(written_size); -} - -void GLES2TraceImplementation::EndRasterCHROMIUM() { - TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::EndRasterCHROMIUM"); - gl_->EndRasterCHROMIUM(); -} - void GLES2TraceImplementation::TexStorage2DImageCHROMIUM(GLenum target, GLenum internalFormat, GLenum bufferUsage,
diff --git a/gpu/command_buffer/client/implementation_base.cc b/gpu/command_buffer/client/implementation_base.cc index 06678ce..508cf12 100644 --- a/gpu/command_buffer/client/implementation_base.cc +++ b/gpu/command_buffer/client/implementation_base.cc
@@ -4,6 +4,8 @@ #include "gpu/command_buffer/client/implementation_base.h" +#include <algorithm> + #include "base/strings/stringprintf.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" @@ -28,7 +30,6 @@ gpu_control_(gpu_control), capabilities_(gpu_control->GetCapabilities()), helper_(helper), - transfer_cache_(this), weak_ptr_factory_(this) {} ImplementationBase::~ImplementationBase() { @@ -101,33 +102,6 @@ gpu_control_->GetGpuFence(gpu_fence_id, std::move(callback)); } -void* ImplementationBase::MapTransferCacheEntry(size_t serialized_size) { - return transfer_cache_.MapEntry(mapped_memory_.get(), serialized_size); -} - -void ImplementationBase::UnmapAndCreateTransferCacheEntry(uint32_t type, - uint32_t id) { - transfer_cache_.UnmapAndCreateEntry(type, id); -} - -bool ImplementationBase::ThreadsafeLockTransferCacheEntry(uint32_t type, - uint32_t id) { - return transfer_cache_.LockEntry(type, id); -} - -void ImplementationBase::UnlockTransferCacheEntries( - const std::vector<std::pair<uint32_t, uint32_t>>& entries) { - transfer_cache_.UnlockEntries(entries); -} - -void ImplementationBase::DeleteTransferCacheEntry(uint32_t type, uint32_t id) { - transfer_cache_.DeleteEntry(type, id); -} - -unsigned int ImplementationBase::GetTransferBufferFreeSize() const { - return transfer_buffer_->GetFreeSize(); -} - bool ImplementationBase::OnMemoryDump( const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) {
diff --git a/gpu/command_buffer/client/implementation_base.h b/gpu/command_buffer/client/implementation_base.h index 81ca9c5..376ed98 100644 --- a/gpu/command_buffer/client/implementation_base.h +++ b/gpu/command_buffer/client/implementation_base.h
@@ -42,8 +42,7 @@ class GLES2_IMPL_EXPORT ImplementationBase : public base::trace_event::MemoryDumpProvider, public ContextSupport, - public GpuControlClient, - public ClientTransferCache::Client { + public GpuControlClient { public: // The maximum result size from simple GL get commands. static const size_t kMaxSizeOfSimpleResult = @@ -84,13 +83,6 @@ void GetGpuFence(uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) override; - void* MapTransferCacheEntry(size_t serialized_size) override; - void UnmapAndCreateTransferCacheEntry(uint32_t type, uint32_t id) override; - bool ThreadsafeLockTransferCacheEntry(uint32_t type, uint32_t id) override; - void UnlockTransferCacheEntries( - const std::vector<std::pair<uint32_t, uint32_t>>& entries) override; - void DeleteTransferCacheEntry(uint32_t type, uint32_t id) override; - unsigned int GetTransferBufferFreeSize() const override; void SetGrContext(GrContext* gr) override; bool HasGrContextSupport() const override; void WillCallGLFromSkia() override; @@ -159,8 +151,6 @@ CommandBufferHelper* helper_; - ClientTransferCache transfer_cache_; - base::WeakPtrFactory<ImplementationBase> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ImplementationBase);
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index aa59eec..c18bda98 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -227,7 +227,8 @@ current_trace_stack_(0), aggressively_free_resources_(false), font_manager_(this, helper->command_buffer()), - lost_(false) { + lost_(false), + transfer_cache_(this) { DCHECK(helper); DCHECK(transfer_buffer); DCHECK(gpu_control); @@ -392,6 +393,34 @@ return false; } +void* RasterImplementation::MapTransferCacheEntry(size_t serialized_size) { + return transfer_cache_.MapEntry(mapped_memory_.get(), serialized_size); +} + +void RasterImplementation::UnmapAndCreateTransferCacheEntry(uint32_t type, + uint32_t id) { + transfer_cache_.UnmapAndCreateEntry(type, id); +} + +bool RasterImplementation::ThreadsafeLockTransferCacheEntry(uint32_t type, + uint32_t id) { + return transfer_cache_.LockEntry(type, id); +} + +void RasterImplementation::UnlockTransferCacheEntries( + const std::vector<std::pair<uint32_t, uint32_t>>& entries) { + transfer_cache_.UnlockEntries(entries); +} + +void RasterImplementation::DeleteTransferCacheEntry(uint32_t type, + uint32_t id) { + transfer_cache_.DeleteEntry(type, id); +} + +unsigned int RasterImplementation::GetTransferBufferFreeSize() const { + return transfer_buffer_->GetFreeSize(); +} + const std::string& RasterImplementation::GetLogPrefix() const { const std::string& prefix(debug_marker_manager_.GetMarker()); return prefix.empty() ? this_in_hex_ : prefix;
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h index 88adb82..9ebd3c4 100644 --- a/gpu/command_buffer/client/raster_implementation.h +++ b/gpu/command_buffer/client/raster_implementation.h
@@ -45,6 +45,7 @@ // buffer management. class RASTER_EXPORT RasterImplementation : public RasterInterface, public ImplementationBase, + public ClientTransferCache::Client, public gles2::QueryTrackerClient, public ClientFontManager::Client { public: @@ -145,6 +146,13 @@ uint32_t texture_id) override; bool ThreadsafeDiscardableTextureIsDeletedForTracing( uint32_t texture_id) override; + void* MapTransferCacheEntry(size_t serialized_size) override; + void UnmapAndCreateTransferCacheEntry(uint32_t type, uint32_t id) override; + bool ThreadsafeLockTransferCacheEntry(uint32_t type, uint32_t id) override; + void UnlockTransferCacheEntries( + const std::vector<std::pair<uint32_t, uint32_t>>& entries) override; + void DeleteTransferCacheEntry(uint32_t type, uint32_t id) override; + unsigned int GetTransferBufferFreeSize() const override; bool GetQueryObjectValueHelper(const char* function_name, GLuint id, @@ -292,6 +300,8 @@ }; base::Optional<RasterProperties> raster_properties_; + ClientTransferCache transfer_cache_; + DISALLOW_COPY_AND_ASSIGN(RasterImplementation); };
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc index 4ea1276..8630cf5 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -20,7 +20,6 @@ #include "cc/paint/transfer_cache_serialize_helper.h" #include "components/viz/common/resources/resource_format_utils.h" #include "gpu/GLES2/gl2extchromium.h" -#include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" @@ -30,117 +29,6 @@ namespace gpu { namespace raster { -namespace { - -class TransferCacheSerializeHelperImpl - : public cc::TransferCacheSerializeHelper { - public: - TransferCacheSerializeHelperImpl(ContextSupport* support) - : support_(support) {} - ~TransferCacheSerializeHelperImpl() final = default; - - private: - bool LockEntryInternal(const EntryKey& key) final { - return support_->ThreadsafeLockTransferCacheEntry( - static_cast<uint32_t>(key.first), key.second); - } - - void CreateEntryInternal(const cc::ClientTransferCacheEntry& entry) final { - size_t size = entry.SerializedSize(); - void* data = support_->MapTransferCacheEntry(size); - // TODO(piman): handle error (failed to allocate/map shm) - DCHECK(data); - bool succeeded = entry.Serialize( - base::make_span(reinterpret_cast<uint8_t*>(data), size)); - DCHECK(succeeded); - support_->UnmapAndCreateTransferCacheEntry(entry.UnsafeType(), entry.Id()); - } - - void FlushEntriesInternal(std::set<EntryKey> entries) final { - std::vector<std::pair<uint32_t, uint32_t>> transformed; - transformed.reserve(entries.size()); - for (const auto& e : entries) - transformed.emplace_back(static_cast<uint32_t>(e.first), e.second); - support_->UnlockTransferCacheEntries(transformed); - } - - ContextSupport* support_; -}; - -struct PaintOpSerializer { - public: - PaintOpSerializer(size_t initial_size, - gles2::GLES2Interface* gl, - cc::DecodeStashingImageProvider* stashing_image_provider, - cc::TransferCacheSerializeHelper* transfer_cache_helper, - ClientFontManager* font_manager) - : gl_(gl), - buffer_(static_cast<char*>(gl_->MapRasterCHROMIUM(initial_size))), - stashing_image_provider_(stashing_image_provider), - transfer_cache_helper_(transfer_cache_helper), - font_manager_(font_manager), - free_bytes_(buffer_ ? initial_size : 0) {} - - ~PaintOpSerializer() { - // Need to call SendSerializedData; - DCHECK(!written_bytes_); - } - - size_t Serialize(const cc::PaintOp* op, - const cc::PaintOp::SerializeOptions& options) { - if (!valid()) - return 0; - size_t size = op->Serialize(buffer_ + written_bytes_, free_bytes_, options); - if (!size) { - SendSerializedData(); - buffer_ = static_cast<char*>(gl_->MapRasterCHROMIUM(kBlockAlloc)); - if (!buffer_) { - free_bytes_ = 0; - return 0; - } - free_bytes_ = kBlockAlloc; - size = op->Serialize(buffer_ + written_bytes_, free_bytes_, options); - } - DCHECK_LE(size, free_bytes_); - - written_bytes_ += size; - free_bytes_ -= size; - return size; - } - - void SendSerializedData() { - if (!valid()) - return; - - // Serialize fonts before sending raster commands. - font_manager_->Serialize(); - gl_->UnmapRasterCHROMIUM(written_bytes_); - - // Now that we've issued the RasterCHROMIUM referencing the stashed - // images, Reset the |stashing_image_provider_|, causing us to issue - // unlock commands for these images. - stashing_image_provider_->Reset(); - transfer_cache_helper_->FlushEntries(); - written_bytes_ = 0; - } - - bool valid() const { return !!buffer_; } - - private: - static constexpr unsigned int kBlockAlloc = 512 * 1024; - - gles2::GLES2Interface* gl_; - char* buffer_; - cc::DecodeStashingImageProvider* stashing_image_provider_; - cc::TransferCacheSerializeHelper* transfer_cache_helper_; - ClientFontManager* font_manager_; - - size_t written_bytes_ = 0; - size_t free_bytes_ = 0; -}; - -} // anonymous namespace - static GLenum GetImageTextureTarget(const gpu::Capabilities& caps, gfx::BufferUsage usage, viz::ResourceFormat format) { @@ -159,16 +47,6 @@ buffer_usage(buffer_usage), format(format) {} -RasterImplementationGLES::RasterProperties::RasterProperties( - SkColor background_color, - bool can_use_lcd_text, - sk_sp<SkColorSpace> color_space) - : background_color(background_color), - can_use_lcd_text(can_use_lcd_text), - color_space(std::move(color_space)) {} - -RasterImplementationGLES::RasterProperties::~RasterProperties() = default; - RasterImplementationGLES::Texture* RasterImplementationGLES::GetTexture( GLuint texture_id) { auto it = texture_info_.find(texture_id); @@ -188,15 +66,12 @@ RasterImplementationGLES::RasterImplementationGLES( gles2::GLES2Interface* gl, - ContextSupport* support, CommandBuffer* command_buffer, const gpu::Capabilities& caps) : gl_(gl), - support_(support), caps_(caps), use_texture_storage_(caps.texture_storage), - use_texture_storage_image_(caps.texture_storage_image), - font_manager_(this, command_buffer) {} + use_texture_storage_image_(caps.texture_storage_image) {} RasterImplementationGLES::~RasterImplementationGLES() {} @@ -439,27 +314,7 @@ GLboolean can_use_lcd_text, GLint color_type, const cc::RasterColorSpace& raster_color_space) { - DCHECK(!raster_properties_); - - TransferCacheSerializeHelperImpl transfer_cache_serialize_helper(support_); - if (!transfer_cache_serialize_helper.LockEntry( - cc::TransferCacheEntryType::kColorSpace, - raster_color_space.color_space_id)) { - transfer_cache_serialize_helper.CreateEntry( - cc::ClientColorSpaceTransferCacheEntry(raster_color_space)); - } - transfer_cache_serialize_helper.AssertLocked( - cc::TransferCacheEntryType::kColorSpace, - raster_color_space.color_space_id); - - Texture* texture = GetTexture(texture_id); - gl_->BeginRasterCHROMIUM(texture->id, sk_color, msaa_sample_count, - can_use_lcd_text, color_type, - raster_color_space.color_space_id); - transfer_cache_serialize_helper.FlushEntries(); - - raster_properties_.emplace(sk_color, can_use_lcd_text, - raster_color_space.color_space.ToSkColorSpace()); + NOTREACHED(); } void RasterImplementationGLES::RasterCHROMIUM( @@ -471,58 +326,11 @@ const gfx::Vector2dF& post_translate, GLfloat post_scale, bool requires_clear) { - if (std::abs(post_scale) < std::numeric_limits<float>::epsilon()) - return; - - gfx::Rect query_rect = - gfx::ScaleToEnclosingRect(playback_rect, 1.f / post_scale); - std::vector<size_t> offsets = list->rtree_.Search(query_rect); - if (offsets.empty()) - return; - - // TODO(enne): tune these numbers - // TODO(enne): convert these types here and in transfer buffer to be size_t. - static constexpr unsigned int kMinAlloc = 16 * 1024; - unsigned int free_size = - std::max(support_->GetTransferBufferFreeSize(), kMinAlloc); - - // This section duplicates RasterSource::PlaybackToCanvas setup preamble. - cc::PaintOpBufferSerializer::Preamble preamble; - preamble.content_size = content_size; - preamble.full_raster_rect = full_raster_rect; - preamble.playback_rect = playback_rect; - preamble.post_translation = post_translate; - preamble.post_scale = gfx::SizeF(post_scale, post_scale); - preamble.requires_clear = requires_clear; - preamble.background_color = raster_properties_->background_color; - - // Wrap the provided provider in a stashing provider so that we can delay - // unrefing images until we have serialized dependent commands. - cc::DecodeStashingImageProvider stashing_image_provider(provider); - - // TODO(enne): don't access private members of DisplayItemList. - TransferCacheSerializeHelperImpl transfer_cache_serialize_helper(support_); - PaintOpSerializer op_serializer(free_size, gl_, &stashing_image_provider, - &transfer_cache_serialize_helper, - &font_manager_); - - cc::PaintOpBufferSerializer::SerializeCallback serialize_cb = - base::BindRepeating(&PaintOpSerializer::Serialize, - base::Unretained(&op_serializer)); - cc::PaintOpBufferSerializer serializer( - serialize_cb, &stashing_image_provider, &transfer_cache_serialize_helper, - font_manager_.strike_server(), raster_properties_->color_space.get(), - raster_properties_->can_use_lcd_text); - serializer.Serialize(&list->paint_op_buffer_, &offsets, preamble); - // TODO(piman): raise error if !serializer.valid()? - op_serializer.SendSerializedData(); + NOTREACHED(); } void RasterImplementationGLES::EndRasterCHROMIUM() { - DCHECK(raster_properties_); - - gl_->EndRasterCHROMIUM(); - raster_properties_.reset(); + NOTREACHED(); } void RasterImplementationGLES::BeginGpuRaster() { @@ -544,9 +352,5 @@ gl_->ActiveTexture(GL_TEXTURE0); } -void* RasterImplementationGLES::MapFontBuffer(size_t size) { - return gl_->MapFontBufferCHROMIUM(size); -} - } // namespace raster } // namespace gpu
diff --git a/gpu/command_buffer/client/raster_implementation_gles.h b/gpu/command_buffer/client/raster_implementation_gles.h index 7dd2682..a665567f 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.h +++ b/gpu/command_buffer/client/raster_implementation_gles.h
@@ -20,19 +20,15 @@ namespace gpu { class CommandBuffer; -class ContextSupport; namespace raster { struct Capabilities; // An implementation of RasterInterface on top of GLES2Interface. -class RASTER_EXPORT RasterImplementationGLES - : public RasterInterface, - public ClientFontManager::Client { +class RASTER_EXPORT RasterImplementationGLES : public RasterInterface { public: RasterImplementationGLES(gles2::GLES2Interface* gl, - ContextSupport* support, CommandBuffer* command_buffer, const gpu::Capabilities& caps); ~RasterImplementationGLES() override; @@ -132,9 +128,6 @@ void BeginGpuRaster() override; void EndGpuRaster() override; - // ClientFontManager::Client implementation. - void* MapFontBuffer(size_t size) override; - private: struct Texture { Texture(GLuint id, @@ -153,7 +146,6 @@ Texture* EnsureTextureBound(Texture* texture); gles2::GLES2Interface* gl_; - ContextSupport* support_; gpu::Capabilities caps_; bool use_texture_storage_; bool use_texture_storage_image_; @@ -161,18 +153,6 @@ std::unordered_map<GLuint, Texture> texture_info_; Texture* bound_texture_ = nullptr; - ClientFontManager font_manager_; - struct RasterProperties { - RasterProperties(SkColor background_color, - bool can_use_lcd_text, - sk_sp<SkColorSpace> color_space); - ~RasterProperties(); - SkColor background_color = SK_ColorWHITE; - bool can_use_lcd_text = false; - sk_sp<SkColorSpace> color_space; - }; - base::Optional<RasterProperties> raster_properties_; - DISALLOW_COPY_AND_ASSIGN(RasterImplementationGLES); };
diff --git a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc index 533bb58..cb0d222 100644 --- a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc +++ b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc
@@ -241,15 +241,15 @@ void SetUp() override { gl_.reset(new RasterMockGLES2Interface()); - ri_.reset(new RasterImplementationGLES( - gl_.get(), &support_, &command_buffer_, gpu::Capabilities())); + ri_.reset(new RasterImplementationGLES(gl_.get(), &command_buffer_, + gpu::Capabilities())); } void TearDown() override {} void SetUpWithCapabilities(const gpu::Capabilities& capabilities) { - ri_.reset(new RasterImplementationGLES(gl_.get(), &support_, - &command_buffer_, capabilities)); + ri_.reset(new RasterImplementationGLES(gl_.get(), &command_buffer_, + capabilities)); } void ExpectBindTexture(GLenum target, GLuint texture_id) { @@ -636,52 +636,6 @@ } } -TEST_F(RasterImplementationGLESTest, RasterCHROMIUM) { - const GLuint texture_id = 23; - const GLuint sk_color = 0x226688AAu; - const GLuint msaa_sample_count = 4; - const GLboolean can_use_lcd_text = GL_TRUE; - const GLint color_type = kRGBA_8888_SkColorType; - const auto raster_color_space = - cc::RasterColorSpace(gfx::ColorSpace::CreateSRGB(), 2); - - AllocTextureId(false, gfx::BufferUsage::GPU_READ, viz::RGBA_8888, texture_id); - - EXPECT_CALL(*gl_, BeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count, - can_use_lcd_text, color_type, 2)) - .Times(1); - ri_->BeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count, - can_use_lcd_text, color_type, raster_color_space); - - scoped_refptr<cc::DisplayItemList> display_list = new cc::DisplayItemList; - display_list->StartPaint(); - display_list->push<cc::DrawColorOp>(SK_ColorRED, SkBlendMode::kSrc); - display_list->EndPaintOfUnpaired(gfx::Rect(100, 100)); - display_list->Finalize(); - - ImageProviderStub image_provider; - const gfx::Size content_size(100, 200); - const gfx::Rect full_raster_rect(2, 3, 8, 9); - const gfx::Rect playback_rect(3, 4, 5, 6); - const gfx::Vector2dF post_translate(7.0f, 8.0f); - const GLfloat post_scale = 9.0f; - bool requires_clear = false; - - constexpr const GLsizeiptr kBufferSize = 16 << 10; - char buffer[kBufferSize]; - - EXPECT_CALL(*gl_, MapRasterCHROMIUM(Le(kBufferSize))) - .WillOnce(Return(buffer)); - EXPECT_CALL(*gl_, UnmapRasterCHROMIUM(Gt(0))).Times(1); - - ri_->RasterCHROMIUM(display_list.get(), &image_provider, content_size, - full_raster_rect, playback_rect, post_translate, - post_scale, requires_clear); - - EXPECT_CALL(*gl_, EndRasterCHROMIUM()).Times(1); - ri_->EndRasterCHROMIUM(); -} - TEST_F(RasterImplementationGLESTest, BeginGpuRaster) { EXPECT_CALL(*gl_, TraceBeginCHROMIUM(StrEq("BeginGpuRaster"), StrEq("GpuRasterization")))
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index bef8ef8..3b2a6a5 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -16128,324 +16128,6 @@ offsetof(LockDiscardableTextureCHROMIUM, texture_id) == 4, "offset of LockDiscardableTextureCHROMIUM texture_id should be 4"); -struct BeginRasterCHROMIUM { - typedef BeginRasterCHROMIUM ValueType; - static const CommandId kCmdId = kBeginRasterCHROMIUM; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init(GLuint _texture_id, - GLuint _sk_color, - GLuint _msaa_sample_count, - GLboolean _can_use_lcd_text, - GLint _color_type, - GLuint _color_space_transfer_cache_id) { - SetHeader(); - texture_id = _texture_id; - sk_color = _sk_color; - msaa_sample_count = _msaa_sample_count; - can_use_lcd_text = _can_use_lcd_text; - color_type = _color_type; - color_space_transfer_cache_id = _color_space_transfer_cache_id; - } - - void* Set(void* cmd, - GLuint _texture_id, - GLuint _sk_color, - GLuint _msaa_sample_count, - GLboolean _can_use_lcd_text, - GLint _color_type, - GLuint _color_space_transfer_cache_id) { - static_cast<ValueType*>(cmd)->Init( - _texture_id, _sk_color, _msaa_sample_count, _can_use_lcd_text, - _color_type, _color_space_transfer_cache_id); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32_t texture_id; - uint32_t sk_color; - uint32_t msaa_sample_count; - uint32_t can_use_lcd_text; - int32_t color_type; - uint32_t color_space_transfer_cache_id; -}; - -static_assert(sizeof(BeginRasterCHROMIUM) == 28, - "size of BeginRasterCHROMIUM should be 28"); -static_assert(offsetof(BeginRasterCHROMIUM, header) == 0, - "offset of BeginRasterCHROMIUM header should be 0"); -static_assert(offsetof(BeginRasterCHROMIUM, texture_id) == 4, - "offset of BeginRasterCHROMIUM texture_id should be 4"); -static_assert(offsetof(BeginRasterCHROMIUM, sk_color) == 8, - "offset of BeginRasterCHROMIUM sk_color should be 8"); -static_assert(offsetof(BeginRasterCHROMIUM, msaa_sample_count) == 12, - "offset of BeginRasterCHROMIUM msaa_sample_count should be 12"); -static_assert(offsetof(BeginRasterCHROMIUM, can_use_lcd_text) == 16, - "offset of BeginRasterCHROMIUM can_use_lcd_text should be 16"); -static_assert(offsetof(BeginRasterCHROMIUM, color_type) == 20, - "offset of BeginRasterCHROMIUM color_type should be 20"); -static_assert( - offsetof(BeginRasterCHROMIUM, color_space_transfer_cache_id) == 24, - "offset of BeginRasterCHROMIUM color_space_transfer_cache_id should be 24"); - -struct RasterCHROMIUM { - typedef RasterCHROMIUM ValueType; - static const CommandId kCmdId = kRasterCHROMIUM; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init(GLuint _raster_shm_id, - GLuint _raster_shm_offset, - GLsizeiptr _raster_shm_size, - GLuint _font_shm_id, - GLuint _font_shm_offset, - GLsizeiptr _font_shm_size) { - SetHeader(); - raster_shm_id = _raster_shm_id; - raster_shm_offset = _raster_shm_offset; - raster_shm_size = _raster_shm_size; - font_shm_id = _font_shm_id; - font_shm_offset = _font_shm_offset; - font_shm_size = _font_shm_size; - } - - void* Set(void* cmd, - GLuint _raster_shm_id, - GLuint _raster_shm_offset, - GLsizeiptr _raster_shm_size, - GLuint _font_shm_id, - GLuint _font_shm_offset, - GLsizeiptr _font_shm_size) { - static_cast<ValueType*>(cmd)->Init(_raster_shm_id, _raster_shm_offset, - _raster_shm_size, _font_shm_id, - _font_shm_offset, _font_shm_size); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32_t raster_shm_id; - uint32_t raster_shm_offset; - int32_t raster_shm_size; - uint32_t font_shm_id; - uint32_t font_shm_offset; - int32_t font_shm_size; -}; - -static_assert(sizeof(RasterCHROMIUM) == 28, - "size of RasterCHROMIUM should be 28"); -static_assert(offsetof(RasterCHROMIUM, header) == 0, - "offset of RasterCHROMIUM header should be 0"); -static_assert(offsetof(RasterCHROMIUM, raster_shm_id) == 4, - "offset of RasterCHROMIUM raster_shm_id should be 4"); -static_assert(offsetof(RasterCHROMIUM, raster_shm_offset) == 8, - "offset of RasterCHROMIUM raster_shm_offset should be 8"); -static_assert(offsetof(RasterCHROMIUM, raster_shm_size) == 12, - "offset of RasterCHROMIUM raster_shm_size should be 12"); -static_assert(offsetof(RasterCHROMIUM, font_shm_id) == 16, - "offset of RasterCHROMIUM font_shm_id should be 16"); -static_assert(offsetof(RasterCHROMIUM, font_shm_offset) == 20, - "offset of RasterCHROMIUM font_shm_offset should be 20"); -static_assert(offsetof(RasterCHROMIUM, font_shm_size) == 24, - "offset of RasterCHROMIUM font_shm_size should be 24"); - -struct EndRasterCHROMIUM { - typedef EndRasterCHROMIUM ValueType; - static const CommandId kCmdId = kEndRasterCHROMIUM; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init() { SetHeader(); } - - void* Set(void* cmd) { - static_cast<ValueType*>(cmd)->Init(); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; -}; - -static_assert(sizeof(EndRasterCHROMIUM) == 4, - "size of EndRasterCHROMIUM should be 4"); -static_assert(offsetof(EndRasterCHROMIUM, header) == 0, - "offset of EndRasterCHROMIUM header should be 0"); - -struct CreateTransferCacheEntryINTERNAL { - typedef CreateTransferCacheEntryINTERNAL ValueType; - static const CommandId kCmdId = kCreateTransferCacheEntryINTERNAL; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init(GLuint _entry_type, - GLuint _entry_id, - GLuint _handle_shm_id, - GLuint _handle_shm_offset, - GLuint _data_shm_id, - GLuint _data_shm_offset, - GLuint _data_size) { - SetHeader(); - entry_type = _entry_type; - entry_id = _entry_id; - handle_shm_id = _handle_shm_id; - handle_shm_offset = _handle_shm_offset; - data_shm_id = _data_shm_id; - data_shm_offset = _data_shm_offset; - data_size = _data_size; - } - - void* Set(void* cmd, - GLuint _entry_type, - GLuint _entry_id, - GLuint _handle_shm_id, - GLuint _handle_shm_offset, - GLuint _data_shm_id, - GLuint _data_shm_offset, - GLuint _data_size) { - static_cast<ValueType*>(cmd)->Init(_entry_type, _entry_id, _handle_shm_id, - _handle_shm_offset, _data_shm_id, - _data_shm_offset, _data_size); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32_t entry_type; - uint32_t entry_id; - uint32_t handle_shm_id; - uint32_t handle_shm_offset; - uint32_t data_shm_id; - uint32_t data_shm_offset; - uint32_t data_size; -}; - -static_assert(sizeof(CreateTransferCacheEntryINTERNAL) == 32, - "size of CreateTransferCacheEntryINTERNAL should be 32"); -static_assert(offsetof(CreateTransferCacheEntryINTERNAL, header) == 0, - "offset of CreateTransferCacheEntryINTERNAL header should be 0"); -static_assert( - offsetof(CreateTransferCacheEntryINTERNAL, entry_type) == 4, - "offset of CreateTransferCacheEntryINTERNAL entry_type should be 4"); -static_assert( - offsetof(CreateTransferCacheEntryINTERNAL, entry_id) == 8, - "offset of CreateTransferCacheEntryINTERNAL entry_id should be 8"); -static_assert( - offsetof(CreateTransferCacheEntryINTERNAL, handle_shm_id) == 12, - "offset of CreateTransferCacheEntryINTERNAL handle_shm_id should be 12"); -static_assert(offsetof(CreateTransferCacheEntryINTERNAL, handle_shm_offset) == - 16, - "offset of CreateTransferCacheEntryINTERNAL handle_shm_offset " - "should be 16"); -static_assert( - offsetof(CreateTransferCacheEntryINTERNAL, data_shm_id) == 20, - "offset of CreateTransferCacheEntryINTERNAL data_shm_id should be 20"); -static_assert( - offsetof(CreateTransferCacheEntryINTERNAL, data_shm_offset) == 24, - "offset of CreateTransferCacheEntryINTERNAL data_shm_offset should be 24"); -static_assert( - offsetof(CreateTransferCacheEntryINTERNAL, data_size) == 28, - "offset of CreateTransferCacheEntryINTERNAL data_size should be 28"); - -struct DeleteTransferCacheEntryINTERNAL { - typedef DeleteTransferCacheEntryINTERNAL ValueType; - static const CommandId kCmdId = kDeleteTransferCacheEntryINTERNAL; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init(GLuint _entry_type, GLuint _entry_id) { - SetHeader(); - entry_type = _entry_type; - entry_id = _entry_id; - } - - void* Set(void* cmd, GLuint _entry_type, GLuint _entry_id) { - static_cast<ValueType*>(cmd)->Init(_entry_type, _entry_id); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32_t entry_type; - uint32_t entry_id; -}; - -static_assert(sizeof(DeleteTransferCacheEntryINTERNAL) == 12, - "size of DeleteTransferCacheEntryINTERNAL should be 12"); -static_assert(offsetof(DeleteTransferCacheEntryINTERNAL, header) == 0, - "offset of DeleteTransferCacheEntryINTERNAL header should be 0"); -static_assert( - offsetof(DeleteTransferCacheEntryINTERNAL, entry_type) == 4, - "offset of DeleteTransferCacheEntryINTERNAL entry_type should be 4"); -static_assert( - offsetof(DeleteTransferCacheEntryINTERNAL, entry_id) == 8, - "offset of DeleteTransferCacheEntryINTERNAL entry_id should be 8"); - -struct UnlockTransferCacheEntryINTERNAL { - typedef UnlockTransferCacheEntryINTERNAL ValueType; - static const CommandId kCmdId = kUnlockTransferCacheEntryINTERNAL; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); - - static uint32_t ComputeSize() { - return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT - } - - void SetHeader() { header.SetCmd<ValueType>(); } - - void Init(GLuint _entry_type, GLuint _entry_id) { - SetHeader(); - entry_type = _entry_type; - entry_id = _entry_id; - } - - void* Set(void* cmd, GLuint _entry_type, GLuint _entry_id) { - static_cast<ValueType*>(cmd)->Init(_entry_type, _entry_id); - return NextCmdAddress<ValueType>(cmd); - } - - gpu::CommandHeader header; - uint32_t entry_type; - uint32_t entry_id; -}; - -static_assert(sizeof(UnlockTransferCacheEntryINTERNAL) == 12, - "size of UnlockTransferCacheEntryINTERNAL should be 12"); -static_assert(offsetof(UnlockTransferCacheEntryINTERNAL, header) == 0, - "offset of UnlockTransferCacheEntryINTERNAL header should be 0"); -static_assert( - offsetof(UnlockTransferCacheEntryINTERNAL, entry_type) == 4, - "offset of UnlockTransferCacheEntryINTERNAL entry_type should be 4"); -static_assert( - offsetof(UnlockTransferCacheEntryINTERNAL, entry_id) == 8, - "offset of UnlockTransferCacheEntryINTERNAL entry_id should be 8"); - struct TexStorage2DImageCHROMIUM { typedef TexStorage2DImageCHROMIUM ValueType; static const CommandId kCmdId = kTexStorage2DImageCHROMIUM;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 9bc651a1..ece4f7b 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5341,100 +5341,6 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, BeginRasterCHROMIUM) { - cmds::BeginRasterCHROMIUM& cmd = *GetBufferAs<cmds::BeginRasterCHROMIUM>(); - void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), - static_cast<GLuint>(13), static_cast<GLboolean>(14), - static_cast<GLint>(15), static_cast<GLuint>(16)); - EXPECT_EQ(static_cast<uint32_t>(cmds::BeginRasterCHROMIUM::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.texture_id); - EXPECT_EQ(static_cast<GLuint>(12), cmd.sk_color); - EXPECT_EQ(static_cast<GLuint>(13), cmd.msaa_sample_count); - EXPECT_EQ(static_cast<GLboolean>(14), cmd.can_use_lcd_text); - EXPECT_EQ(static_cast<GLint>(15), cmd.color_type); - EXPECT_EQ(static_cast<GLuint>(16), cmd.color_space_transfer_cache_id); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - -TEST_F(GLES2FormatTest, RasterCHROMIUM) { - cmds::RasterCHROMIUM& cmd = *GetBufferAs<cmds::RasterCHROMIUM>(); - void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12), - static_cast<GLsizeiptr>(13), static_cast<GLuint>(14), - static_cast<GLuint>(15), static_cast<GLsizeiptr>(16)); - EXPECT_EQ(static_cast<uint32_t>(cmds::RasterCHROMIUM::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.raster_shm_id); - EXPECT_EQ(static_cast<GLuint>(12), cmd.raster_shm_offset); - EXPECT_EQ(static_cast<GLsizeiptr>(13), cmd.raster_shm_size); - EXPECT_EQ(static_cast<GLuint>(14), cmd.font_shm_id); - EXPECT_EQ(static_cast<GLuint>(15), cmd.font_shm_offset); - EXPECT_EQ(static_cast<GLsizeiptr>(16), cmd.font_shm_size); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - -TEST_F(GLES2FormatTest, EndRasterCHROMIUM) { - cmds::EndRasterCHROMIUM& cmd = *GetBufferAs<cmds::EndRasterCHROMIUM>(); - void* next_cmd = cmd.Set(&cmd); - EXPECT_EQ(static_cast<uint32_t>(cmds::EndRasterCHROMIUM::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - -TEST_F(GLES2FormatTest, CreateTransferCacheEntryINTERNAL) { - cmds::CreateTransferCacheEntryINTERNAL& cmd = - *GetBufferAs<cmds::CreateTransferCacheEntryINTERNAL>(); - void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), - static_cast<GLuint>(12), static_cast<GLuint>(13), - static_cast<GLuint>(14), static_cast<GLuint>(15), - static_cast<GLuint>(16), static_cast<GLuint>(17)); - EXPECT_EQ( - static_cast<uint32_t>(cmds::CreateTransferCacheEntryINTERNAL::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.entry_type); - EXPECT_EQ(static_cast<GLuint>(12), cmd.entry_id); - EXPECT_EQ(static_cast<GLuint>(13), cmd.handle_shm_id); - EXPECT_EQ(static_cast<GLuint>(14), cmd.handle_shm_offset); - EXPECT_EQ(static_cast<GLuint>(15), cmd.data_shm_id); - EXPECT_EQ(static_cast<GLuint>(16), cmd.data_shm_offset); - EXPECT_EQ(static_cast<GLuint>(17), cmd.data_size); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - -TEST_F(GLES2FormatTest, DeleteTransferCacheEntryINTERNAL) { - cmds::DeleteTransferCacheEntryINTERNAL& cmd = - *GetBufferAs<cmds::DeleteTransferCacheEntryINTERNAL>(); - void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12)); - EXPECT_EQ( - static_cast<uint32_t>(cmds::DeleteTransferCacheEntryINTERNAL::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.entry_type); - EXPECT_EQ(static_cast<GLuint>(12), cmd.entry_id); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - -TEST_F(GLES2FormatTest, UnlockTransferCacheEntryINTERNAL) { - cmds::UnlockTransferCacheEntryINTERNAL& cmd = - *GetBufferAs<cmds::UnlockTransferCacheEntryINTERNAL>(); - void* next_cmd = - cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12)); - EXPECT_EQ( - static_cast<uint32_t>(cmds::UnlockTransferCacheEntryINTERNAL::kCmdId), - cmd.header.command); - EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); - EXPECT_EQ(static_cast<GLuint>(11), cmd.entry_type); - EXPECT_EQ(static_cast<GLuint>(12), cmd.entry_id); - CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); -} - TEST_F(GLES2FormatTest, TexStorage2DImageCHROMIUM) { cmds::TexStorage2DImageCHROMIUM& cmd = *GetBufferAs<cmds::TexStorage2DImageCHROMIUM>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 047ff08..50e83cf 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -336,18 +336,12 @@ OP(InitializeDiscardableTextureCHROMIUM) /* 577 */ \ OP(UnlockDiscardableTextureCHROMIUM) /* 578 */ \ OP(LockDiscardableTextureCHROMIUM) /* 579 */ \ - OP(BeginRasterCHROMIUM) /* 580 */ \ - OP(RasterCHROMIUM) /* 581 */ \ - OP(EndRasterCHROMIUM) /* 582 */ \ - OP(CreateTransferCacheEntryINTERNAL) /* 583 */ \ - OP(DeleteTransferCacheEntryINTERNAL) /* 584 */ \ - OP(UnlockTransferCacheEntryINTERNAL) /* 585 */ \ - OP(TexStorage2DImageCHROMIUM) /* 586 */ \ - OP(SetColorSpaceMetadataCHROMIUM) /* 587 */ \ - OP(WindowRectanglesEXTImmediate) /* 588 */ \ - OP(CreateGpuFenceINTERNAL) /* 589 */ \ - OP(WaitGpuFenceCHROMIUM) /* 590 */ \ - OP(DestroyGpuFenceCHROMIUM) /* 591 */ + OP(TexStorage2DImageCHROMIUM) /* 580 */ \ + OP(SetColorSpaceMetadataCHROMIUM) /* 581 */ \ + OP(WindowRectanglesEXTImmediate) /* 582 */ \ + OP(CreateGpuFenceINTERNAL) /* 583 */ \ + OP(WaitGpuFenceCHROMIUM) /* 584 */ \ + OP(DestroyGpuFenceCHROMIUM) /* 585 */ enum CommandId { kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index f816ebb..cfebb94 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -376,17 +376,6 @@ GL_APICALL void GL_APIENTRY glUnlockDiscardableTextureCHROMIUM (GLuint texture_id); GL_APICALL bool GL_APIENTRY glLockDiscardableTextureCHROMIUM (GLuint texture_id); -// Extension CHROMIUM_raster_transport -GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint texture_id, GLuint sk_color, GLuint msaa_sample_count, GLboolean can_use_lcd_text, GLint color_type, GLuint color_space_transfer_cache_id); -GL_APICALL void GL_APIENTRY glRasterCHROMIUM (GLuint raster_shm_id, GLuint raster_shm_offset, GLsizeiptr raster_shm_size, GLuint font_shm_id, GLuint font_shm_offset, GLsizeiptr font_shm_size); -GL_APICALL void* GL_APIENTRY glMapRasterCHROMIUM (GLsizeiptr size); -GL_APICALL void* GL_APIENTRY glMapFontBufferCHROMIUM (GLsizeiptr size); -GL_APICALL void GL_APIENTRY glUnmapRasterCHROMIUM (GLsizeiptr written_size); -GL_APICALL void GL_APIENTRY glEndRasterCHROMIUM (void); -GL_APICALL void GL_APIENTRY glCreateTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, GLuint handle_shm_offset, GLuint data_shm_id, GLuint data_shm_offset, GLuint data_size); -GL_APICALL void GL_APIENTRY glDeleteTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id); -GL_APICALL void GL_APIENTRY glUnlockTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id); - // Extension CHROMIUM_texture_storage_image GL_APICALL void GL_APIENTRY glTexStorage2DImageCHROMIUM (GLenumTextureBindTarget target, GLenumTextureInternalFormatStorage internalFormat, GLenumClientBufferUsage bufferUsage, GLsizei width, GLsizei height);
diff --git a/gpu/command_buffer/service/decoder_context.h b/gpu/command_buffer/service/decoder_context.h index 0be8902..2c2ab08 100644 --- a/gpu/command_buffer/service/decoder_context.h +++ b/gpu/command_buffer/service/decoder_context.h
@@ -27,7 +27,6 @@ namespace gpu { class QueryManager; -class ServiceTransferCache; class TextureBase; struct ContextCreationAttribs; @@ -217,9 +216,6 @@ // // Methods required by InProcessCommandBuffer // - // Gets the ServiceTransferCache for this context. - virtual ServiceTransferCache* GetTransferCacheForTest() = 0; - // Set to true to LOG every command. virtual void SetLogCommands(bool log_commands) = 0; };
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index dca71dc..00a82d0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -21,6 +21,7 @@ #include "base/callback_helpers.h" #include "base/containers/queue.h" #include "base/containers/span.h" +#include "base/debug/alias.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/ranges.h" @@ -29,9 +30,6 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "cc/paint/color_space_transfer_cache_entry.h" -#include "cc/paint/paint_op_buffer.h" -#include "cc/paint/transfer_cache_entry.h" #include "gpu/command_buffer/common/debug_marker_manager.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" @@ -69,8 +67,6 @@ #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/sampler_manager.h" #include "gpu/command_buffer/service/service_discardable_manager.h" -#include "gpu/command_buffer/service/service_font_manager.h" -#include "gpu/command_buffer/service/service_transfer_cache.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/shader_translator.h" #include "gpu/command_buffer/service/texture_manager.h" @@ -78,14 +74,6 @@ #include "gpu/command_buffer/service/vertex_array_manager.h" #include "gpu/command_buffer/service/vertex_attrib_manager.h" #include "third_party/angle/src/image_util/loadimage.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h" -#include "third_party/skia/include/core/SkSurface.h" -#include "third_party/skia/include/core/SkSurfaceProps.h" -#include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/gpu/GrBackendSurface.h" -#include "third_party/skia/include/gpu/GrContext.h" -#include "third_party/skia/src/core/SkRemoteGlyphCache.h" #include "third_party/smhasher/src/City.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/color_space.h" @@ -574,9 +562,7 @@ // This class implements GLES2Decoder so we don't have to expose all the GLES2 // cmd stuff to outside this class. -class GLES2DecoderImpl : public GLES2Decoder, - public ErrorStateClient, - public ServiceFontManager::Client { +class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { public: GLES2DecoderImpl(DecoderClient* client, CommandBufferServiceBase* command_buffer_service, @@ -670,9 +656,6 @@ ImageManager* GetImageManagerForTest() override { return group_->image_manager(); } - ServiceTransferCache* GetTransferCacheForTest() override { - return transfer_cache_.get(); - } bool HasPendingQueries() const override; void ProcessPendingQueries(bool did_finish) override; @@ -757,7 +740,7 @@ } // ServiceFontManager::Client implementation. - scoped_refptr<gpu::Buffer> GetShmBuffer(uint32_t shm_id) override; + scoped_refptr<gpu::Buffer> GetShmBuffer(uint32_t shm_id); private: friend class ScopedFramebufferBinder; @@ -2039,30 +2022,6 @@ GLenum textarget, GLuint texture_unit); - void DoBeginRasterCHROMIUM(GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id); - void DoRasterCHROMIUM(GLuint raster_shm_id, - GLuint raster_shm_offset, - GLsizeiptr raster_shm_size, - GLuint font_shm_id, - GLuint font_shm_offset, - GLsizeiptr font_shm_size); - void DoEndRasterCHROMIUM(); - - void DoCreateTransferCacheEntryINTERNAL(GLuint entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size); - void DoUnlockTransferCacheEntryINTERNAL(GLuint entry_type, GLuint entry_id); - void DoDeleteTransferCacheEntryINTERNAL(GLuint entry_type, GLuint entry_id); - void DoUnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id, GLuint dest_id, GLint x, @@ -2497,14 +2456,6 @@ std::unique_ptr<VertexArrayManager> vertex_array_manager_; - // ServiceTransferCache uses Ids based on transfer buffer shm_id+offset, which - // are guaranteed to be unique within the scope of the TransferBufferManager - // which generates them. Because of this, |transfer_cache_| must have a - // narrower scope than |transfer_buffer_manager_|. - // In the future, we could add necessary scoping Id(s) to allow a single - // ServiceTransferCache to be shared among multiple contexts / channels. - std::unique_ptr<ServiceTransferCache> transfer_cache_; - // The format of the back buffer_ GLenum back_buffer_color_format_; bool back_buffer_has_depth_; @@ -2549,7 +2500,6 @@ bool supports_swap_buffers_with_bounds_; bool supports_commit_overlay_planes_; bool supports_async_swap_; - bool supports_oop_raster_; bool supports_dc_layers_ = false; // These flags are used to override the state of the shared feature_info_ @@ -2640,12 +2590,6 @@ std::unique_ptr<CALayerSharedState> ca_layer_shared_state_; std::unique_ptr<DCLayerSharedState> dc_layer_shared_state_; - // Raster helpers. - ServiceFontManager font_manager_; - sk_sp<GrContext> gr_context_; - sk_sp<SkSurface> sk_surface_; - std::unique_ptr<SkCanvas> raster_canvas_; - base::WeakPtrFactory<GLES2DecoderImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); @@ -3287,7 +3231,6 @@ supports_swap_buffers_with_bounds_(false), supports_commit_overlay_planes_(false), supports_async_swap_(false), - supports_oop_raster_(false), derivatives_explicitly_enabled_(false), frag_depth_explicitly_enabled_(false), draw_buffers_explicitly_enabled_(false), @@ -3310,7 +3253,6 @@ validation_fbo_(0), texture_manager_service_id_generation_(0), force_shader_name_hashing_for_test(false), - font_manager_(this), weak_ptr_factory_(this) { DCHECK(client); DCHECK(group); @@ -3884,49 +3826,6 @@ api()->glHintFn(GL_TEXTURE_FILTERING_HINT_CHROMIUM, GL_NICEST); } - if (attrib_helper.enable_oop_rasterization) { - if (!features().chromium_raster_transport) { - LOG(ERROR) << "ContextResult::kFatalFailure: " - "chromium_raster_transport not present"; - return gpu::ContextResult::kFatalFailure; - } - // Assume that we can create a GrContext. This will be set to false if - // there's a failure. - supports_oop_raster_ = true; - sk_sp<const GrGLInterface> interface( - gl::init::CreateGrGLInterface(gl_version_info())); - if (!interface) { - DLOG(ERROR) << "OOP raster support disabled: GrGLInterface creation " - "failed."; - supports_oop_raster_ = false; - } - - if (supports_oop_raster_) { - gr_context_ = GrContext::MakeGL(std::move(interface)); - if (gr_context_) { - // TODO(enne): this cache is for this decoder only and each decoder has - // its own cache. This is pretty unfortunate. This really needs to be - // rethought before shipping. Most likely a different command buffer - // context for raster-in-gpu, with a shared gl context / gr context - // that different decoders can use. - static const int kMaxGaneshResourceCacheCount = 8196; - static const size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024; - gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount, - kMaxGaneshResourceCacheBytes); - transfer_cache_ = std::make_unique<ServiceTransferCache>(); - } else { - bool was_lost = CheckResetStatus(); - if (was_lost) { - DLOG(ERROR) - << "ContextResult::kTransientFailure: Could not create GrContext"; - return gpu::ContextResult::kTransientFailure; - } - DLOG(ERROR) << "OOP raster support disabled: GrContext creation " - "failed."; - supports_oop_raster_ = false; - } - } - } return gpu::ContextResult::kSuccess; } @@ -4129,7 +4028,7 @@ caps.texture_npot = feature_info_->feature_flags().npot_ok; caps.texture_storage_image = feature_info_->feature_flags().chromium_texture_storage_image; - caps.supports_oop_raster = supports_oop_raster_; + caps.supports_oop_raster = false; caps.chromium_gpu_fence = feature_info_->feature_flags().chromium_gpu_fence; caps.unpremultiply_and_dither_copy = feature_info_->feature_flags().unpremultiply_and_dither_copy; @@ -5137,8 +5036,6 @@ if (group_ && group_->texture_manager()) group_->texture_manager()->MarkContextLost(); - if (gr_context_) - gr_context_->abandonContext(); state_.MarkContextLost(); } deschedule_until_finished_fences_.clear(); @@ -5175,7 +5072,6 @@ copy_texture_chromium_.reset(); srgb_converter_.reset(); clear_framebuffer_blit_.reset(); - transfer_cache_.reset(); if (framebuffer_manager_.get()) { framebuffer_manager_->Destroy(have_context); @@ -20173,290 +20069,11 @@ return error::kNoError; } -namespace { - -class TransferCacheDeserializeHelperImpl - : public cc::TransferCacheDeserializeHelper { - public: - explicit TransferCacheDeserializeHelperImpl( - ServiceTransferCache* transfer_cache) - : transfer_cache_(transfer_cache) { - DCHECK(transfer_cache_); - } - ~TransferCacheDeserializeHelperImpl() override = default; - - void CreateLocalEntry( - uint32_t id, - std::unique_ptr<cc::ServiceTransferCacheEntry> entry) override { - transfer_cache_->CreateLocalEntry(id, std::move(entry)); - } - - private: - cc::ServiceTransferCacheEntry* GetEntryInternal( - cc::TransferCacheEntryType entry_type, - uint32_t entry_id) override { - return transfer_cache_->GetEntry(entry_type, entry_id); - } - ServiceTransferCache* transfer_cache_; -}; - -} // namespace - -void GLES2DecoderImpl::DoBeginRasterCHROMIUM( - GLuint texture_id, - GLuint sk_color, - GLuint msaa_sample_count, - GLboolean can_use_lcd_text, - GLint color_type, - GLuint color_space_transfer_cache_id) { - if (!gr_context_) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "chromium_raster_transport not enabled via attribs"); - return; - } - if (sk_surface_) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "BeginRasterCHROMIUM without EndRasterCHROMIUM"); - return; - } - - DCHECK(!raster_canvas_); - gr_context_->resetContext(); - - // This function should look identical to - // ResourceProvider::ScopedSkSurfaceProvider. - GrGLTextureInfo texture_info; - auto* texture_ref = GetTexture(texture_id); - if (!texture_ref) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "unknown texture id"); - return; - } - auto* texture = texture_ref->texture(); - int width; - int height; - int depth; - if (!texture->GetLevelSize(texture->target(), 0, &width, &height, &depth)) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "missing texture size info"); - return; - } - GLenum type; - GLenum internal_format; - if (!texture->GetLevelType(texture->target(), 0, &type, &internal_format)) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "missing texture type info"); - return; - } - texture_info.fID = texture_ref->service_id(); - texture_info.fTarget = texture->target(); - - if (texture->target() != GL_TEXTURE_2D && - texture->target() != GL_TEXTURE_RECTANGLE_ARB) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "invalid texture target"); - return; - } - - // GetInternalFormat may return a base internal format but Skia requires a - // sized internal format. So this may be adjusted below. - texture_info.fFormat = GetInternalFormat(&gl_version_info(), internal_format); - switch (color_type) { - case kARGB_4444_SkColorType: - if (internal_format != GL_RGBA4 && internal_format != GL_RGBA) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "color type mismatch"); - return; - } - if (texture_info.fFormat == GL_RGBA) - texture_info.fFormat = GL_RGBA4; - break; - case kRGBA_8888_SkColorType: - if (internal_format != GL_RGBA8_OES && internal_format != GL_RGBA) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "color type mismatch"); - return; - } - if (texture_info.fFormat == GL_RGBA) - texture_info.fFormat = GL_RGBA8_OES; - break; - case kBGRA_8888_SkColorType: - if (internal_format != GL_BGRA_EXT && internal_format != GL_BGRA8_EXT) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "color type mismatch"); - return; - } - if (texture_info.fFormat == GL_BGRA_EXT) - texture_info.fFormat = GL_BGRA8_EXT; - if (texture_info.fFormat == GL_RGBA) - texture_info.fFormat = GL_RGBA8_OES; - break; - default: - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "unsupported color type"); - return; - } - - GrBackendTexture gr_texture(width, height, GrMipMapped::kNo, texture_info); - - uint32_t flags = 0; - - // Use unknown pixel geometry to disable LCD text. - SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry); - if (can_use_lcd_text) { - // LegacyFontHost will get LCD text and skia figures out what type to use. - surface_props = - SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); - } - - SkColorType sk_color_type = static_cast<SkColorType>(color_type); - // If we can't match requested MSAA samples, don't use MSAA. - int final_msaa_count = std::max(static_cast<int>(msaa_sample_count), 0); - if (final_msaa_count > - gr_context_->maxSurfaceSampleCountForColorType(sk_color_type)) - final_msaa_count = 0; - sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( - gr_context_.get(), gr_texture, kTopLeft_GrSurfaceOrigin, final_msaa_count, - sk_color_type, nullptr, &surface_props); - - if (!sk_surface_) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "failed to create surface"); - return; - } - - TransferCacheDeserializeHelperImpl transfer_cache_deserializer( - transfer_cache_.get()); - auto* color_space_entry = - transfer_cache_deserializer - .GetEntryAs<cc::ServiceColorSpaceTransferCacheEntry>( - color_space_transfer_cache_id); - if (!color_space_entry || !color_space_entry->color_space().IsValid()) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "failed to find valid color space"); - return; - } - raster_canvas_ = SkCreateColorSpaceXformCanvas( - sk_surface_->getCanvas(), - color_space_entry->color_space().ToSkColorSpace()); - - // All or nothing clearing, as no way to validate the client's input on what - // is the "used" part of the texture. - if (texture->IsLevelCleared(texture->target(), 0)) - return; - - // TODO(enne): this doesn't handle the case where the background color - // changes and so any extra pixels outside the raster area that get - // sampled may be incorrect. - raster_canvas_->drawColor(sk_color); - texture_manager()->SetLevelCleared(texture_ref, texture->target(), 0, true); -} scoped_refptr<gpu::Buffer> GLES2DecoderImpl::GetShmBuffer(uint32_t shm_id) { return GetSharedMemoryBuffer(shm_id); } -void GLES2DecoderImpl::DoRasterCHROMIUM(GLuint raster_shm_id, - GLuint raster_shm_offset, - GLsizeiptr raster_shm_size, - GLuint font_shm_id, - GLuint font_shm_offset, - GLsizeiptr font_shm_size) { - TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoRasterCHROMIUM"); - - if (!sk_surface_) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glRasterCHROMIUM", - "RasterCHROMIUM without BeginRasterCHROMIUM"); - return; - } - DCHECK(transfer_cache_); - - std::vector<SkDiscardableHandleId> locked_handles; - if (font_shm_size > 0) { - // Deserialize fonts before raster. - volatile char* font_buffer_memory = - GetSharedMemoryAs<char*>(font_shm_id, font_shm_offset, font_shm_size); - if (!font_buffer_memory) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM", - "Can not read font buffer."); - return; - } - - if (!font_manager_.Deserialize(font_buffer_memory, font_shm_size, - &locked_handles)) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM", - "Invalid font buffer."); - return; - } - } - - char* paint_buffer_memory = GetSharedMemoryAs<char*>( - raster_shm_id, raster_shm_offset, raster_shm_size); - if (!paint_buffer_memory) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM", - "Can not read paint buffer."); - return; - } - - alignas( - cc::PaintOpBuffer::PaintOpAlign) char data[sizeof(cc::LargestPaintOp)]; - - SkCanvas* canvas = raster_canvas_.get(); - SkMatrix original_ctm; - cc::PlaybackParams playback_params(nullptr, original_ctm); - cc::PaintOp::DeserializeOptions options; - TransferCacheDeserializeHelperImpl impl(transfer_cache_.get()); - options.transfer_cache = &impl; - options.strike_client = font_manager_.strike_client(); - - int op_idx = 0; - size_t paint_buffer_size = raster_shm_size; - while (paint_buffer_size > 4) { - size_t skip = 0; - cc::PaintOp* deserialized_op = cc::PaintOp::Deserialize( - paint_buffer_memory, paint_buffer_size, &data[0], - sizeof(cc::LargestPaintOp), &skip, options); - if (!deserialized_op) { - std::string msg = - base::StringPrintf("RasterCHROMIUM: bad op: %i", op_idx); - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glRasterCHROMIUM", msg.c_str()); - return; - } - - deserialized_op->Raster(canvas, playback_params); - deserialized_op->DestroyThis(); - - paint_buffer_size -= skip; - paint_buffer_memory += skip; - op_idx++; - } - - // Unlock all font handles. - // TODO(khushalsagar): We just unlocked a bunch of handles, do we need to give - // a call to skia to attempt to purge any unlocked handles? - if (!font_manager_.Unlock(locked_handles)) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM", - "Invalid font discardable handle."); - } -} - -void GLES2DecoderImpl::DoEndRasterCHROMIUM() { - if (!sk_surface_) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", - "EndRasterCHROMIUM without BeginRasterCHROMIUM"); - return; - } - - raster_canvas_ = nullptr; - sk_surface_->prepareForExternalIO(); - sk_surface_.reset(); - - // It is important to reset state after each RasterCHROMIUM since skia can - // change the GL state which can invalidate the tracking done in this - // decoder. - RestoreState(nullptr); -} - void GLES2DecoderImpl::DoWindowRectanglesEXT(GLenum mode, GLsizei n, const volatile GLint* box) { @@ -20478,109 +20095,6 @@ state_.UpdateWindowRectangles(); } -void GLES2DecoderImpl::DoCreateTransferCacheEntryINTERNAL( - GLuint raw_entry_type, - GLuint entry_id, - GLuint handle_shm_id, - GLuint handle_shm_offset, - GLuint data_shm_id, - GLuint data_shm_offset, - GLuint data_size) { - if (!supports_oop_raster_) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCreateTransferCacheEntryINTERNAL", - "Attempt to use OOP transfer cache on a context without OOP raster."); - return; - } - DCHECK(gr_context_); - DCHECK(transfer_cache_); - - // Validate the type we are about to create. - cc::TransferCacheEntryType entry_type; - if (!cc::ServiceTransferCacheEntry::SafeConvertToType(raw_entry_type, - &entry_type)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glCreateTransferCacheEntryINTERNAL", - "Attempt to use OOP transfer cache with an invalid cache entry type."); - return; - } - - uint8_t* data_memory = - GetSharedMemoryAs<uint8_t*>(data_shm_id, data_shm_offset, data_size); - if (!data_memory) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCreateTransferCacheEntryINTERNAL", - "Can not read transfer cache entry data."); - return; - } - - scoped_refptr<gpu::Buffer> handle_buffer = - GetSharedMemoryBuffer(handle_shm_id); - if (!DiscardableHandleBase::ValidateParameters(handle_buffer.get(), - handle_shm_offset)) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCreateTransferCacheEntryINTERNAL", - "Invalid shm for discardable handle."); - return; - } - ServiceDiscardableHandle handle(std::move(handle_buffer), handle_shm_offset, - handle_shm_id); - - if (!transfer_cache_->CreateLockedEntry( - entry_type, entry_id, handle, gr_context_.get(), - base::make_span(data_memory, data_size))) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCreateTransferCacheEntryINTERNAL", - "Failure to deserialize transfer cache entry."); - return; - } -} - -void GLES2DecoderImpl::DoUnlockTransferCacheEntryINTERNAL(GLuint raw_entry_type, - GLuint entry_id) { - if (!supports_oop_raster_) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glUnlockTransferCacheEntryINTERNAL", - "Attempt to use OOP transfer cache on a context without OOP raster."); - return; - } - DCHECK(transfer_cache_); - cc::TransferCacheEntryType entry_type; - if (!cc::ServiceTransferCacheEntry::SafeConvertToType(raw_entry_type, - &entry_type)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glUnlockTransferCacheEntryINTERNAL", - "Attempt to use OOP transfer cache with an invalid cache entry type."); - return; - } - - if (!transfer_cache_->UnlockEntry(entry_type, entry_id)) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glUnlockTransferCacheEntryINTERNAL", - "Attempt to unlock an invalid ID"); - } -} - -void GLES2DecoderImpl::DoDeleteTransferCacheEntryINTERNAL(GLuint raw_entry_type, - GLuint entry_id) { - if (!supports_oop_raster_) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glDeleteTransferCacheEntryINTERNAL", - "Attempt to use OOP transfer cache on a context without OOP raster."); - return; - } - DCHECK(transfer_cache_); - cc::TransferCacheEntryType entry_type; - if (!cc::ServiceTransferCacheEntry::SafeConvertToType(raw_entry_type, - &entry_type)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glDeleteTransferCacheEntryINTERNAL", - "Attempt to use OOP transfer cache with an invalid cache entry type."); - return; - } - - if (!transfer_cache_->DeleteEntry(entry_type, entry_id)) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteTransferCacheEntryINTERNAL", - "Attempt to delete an invalid ID"); - } -} - void GLES2DecoderImpl::DoUnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id, GLuint dest_id, GLint x,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 1ed0b20..0e00579 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5186,115 +5186,6 @@ return error::kNoError; } -error::Error GLES2DecoderImpl::HandleBeginRasterCHROMIUM( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::BeginRasterCHROMIUM& c = - *static_cast<const volatile gles2::cmds::BeginRasterCHROMIUM*>(cmd_data); - if (!features().chromium_raster_transport) { - return error::kUnknownCommand; - } - - GLuint texture_id = static_cast<GLuint>(c.texture_id); - GLuint sk_color = static_cast<GLuint>(c.sk_color); - GLuint msaa_sample_count = static_cast<GLuint>(c.msaa_sample_count); - GLboolean can_use_lcd_text = static_cast<GLboolean>(c.can_use_lcd_text); - GLint color_type = static_cast<GLint>(c.color_type); - GLuint color_space_transfer_cache_id = - static_cast<GLuint>(c.color_space_transfer_cache_id); - DoBeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count, - can_use_lcd_text, color_type, - color_space_transfer_cache_id); - return error::kNoError; -} - -error::Error GLES2DecoderImpl::HandleRasterCHROMIUM( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::RasterCHROMIUM& c = - *static_cast<const volatile gles2::cmds::RasterCHROMIUM*>(cmd_data); - if (!features().chromium_raster_transport) { - return error::kUnknownCommand; - } - - GLuint raster_shm_id = static_cast<GLuint>(c.raster_shm_id); - GLuint raster_shm_offset = static_cast<GLuint>(c.raster_shm_offset); - GLsizeiptr raster_shm_size = static_cast<GLsizeiptr>(c.raster_shm_size); - GLuint font_shm_id = static_cast<GLuint>(c.font_shm_id); - GLuint font_shm_offset = static_cast<GLuint>(c.font_shm_offset); - GLsizeiptr font_shm_size = static_cast<GLsizeiptr>(c.font_shm_size); - if (raster_shm_size < 0) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM", - "raster_shm_size < 0"); - return error::kNoError; - } - if (font_shm_size < 0) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM", - "font_shm_size < 0"); - return error::kNoError; - } - DoRasterCHROMIUM(raster_shm_id, raster_shm_offset, raster_shm_size, - font_shm_id, font_shm_offset, font_shm_size); - return error::kNoError; -} - -error::Error GLES2DecoderImpl::HandleEndRasterCHROMIUM( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - if (!features().chromium_raster_transport) { - return error::kUnknownCommand; - } - - DoEndRasterCHROMIUM(); - return error::kNoError; -} - -error::Error GLES2DecoderImpl::HandleCreateTransferCacheEntryINTERNAL( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::CreateTransferCacheEntryINTERNAL& c = - *static_cast< - const volatile gles2::cmds::CreateTransferCacheEntryINTERNAL*>( - cmd_data); - GLuint entry_type = static_cast<GLuint>(c.entry_type); - GLuint entry_id = static_cast<GLuint>(c.entry_id); - GLuint handle_shm_id = static_cast<GLuint>(c.handle_shm_id); - GLuint handle_shm_offset = static_cast<GLuint>(c.handle_shm_offset); - GLuint data_shm_id = static_cast<GLuint>(c.data_shm_id); - GLuint data_shm_offset = static_cast<GLuint>(c.data_shm_offset); - GLuint data_size = static_cast<GLuint>(c.data_size); - DoCreateTransferCacheEntryINTERNAL(entry_type, entry_id, handle_shm_id, - handle_shm_offset, data_shm_id, - data_shm_offset, data_size); - return error::kNoError; -} - -error::Error GLES2DecoderImpl::HandleDeleteTransferCacheEntryINTERNAL( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::DeleteTransferCacheEntryINTERNAL& c = - *static_cast< - const volatile gles2::cmds::DeleteTransferCacheEntryINTERNAL*>( - cmd_data); - GLuint entry_type = static_cast<GLuint>(c.entry_type); - GLuint entry_id = static_cast<GLuint>(c.entry_id); - DoDeleteTransferCacheEntryINTERNAL(entry_type, entry_id); - return error::kNoError; -} - -error::Error GLES2DecoderImpl::HandleUnlockTransferCacheEntryINTERNAL( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::UnlockTransferCacheEntryINTERNAL& c = - *static_cast< - const volatile gles2::cmds::UnlockTransferCacheEntryINTERNAL*>( - cmd_data); - GLuint entry_type = static_cast<GLuint>(c.entry_type); - GLuint entry_id = static_cast<GLuint>(c.entry_id); - DoUnlockTransferCacheEntryINTERNAL(entry_type, entry_id); - return error::kNoError; -} - error::Error GLES2DecoderImpl::HandleTexStorage2DImageCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 21366933..53fc3af 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -100,7 +100,6 @@ GetTransformFeedbackManager, gpu::gles2::TransformFeedbackManager*()); MOCK_METHOD0(GetVertexArrayManager, gpu::gles2::VertexArrayManager*()); MOCK_METHOD0(GetImageManagerForTest, gpu::gles2::ImageManager*()); - MOCK_METHOD0(GetTransferCacheForTest, gpu::ServiceTransferCache*()); MOCK_METHOD1( SetResizeCallback, void(const base::Callback<void(gfx::Size, float)>&)); MOCK_METHOD1(SetIgnoreCachedStateForTest, void(bool ignore));
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index 5a7f0fa..ed5d2dbe 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -4,6 +4,9 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h" +#include <string> +#include <utility> + #include "base/callback.h" #include "base/strings/string_split.h" #include "gpu/command_buffer/service/command_buffer_service.h" @@ -43,7 +46,7 @@ } *result = static_cast<ResultType>(client_id); return true; -}; +} void ResizeRenderbuffer(gl::GLApi* api, GLuint renderbuffer, @@ -1226,7 +1229,6 @@ } void GLES2DecoderPassthroughImpl::RestoreState(const ContextState* prev_state) { - } void GLES2DecoderPassthroughImpl::RestoreActiveTexture() const {} @@ -1268,7 +1270,6 @@ void GLES2DecoderPassthroughImpl::SetIgnoreCachedStateForTest(bool ignore) {} void GLES2DecoderPassthroughImpl::SetForceShaderNameHashingForTest(bool force) { - } size_t GLES2DecoderPassthroughImpl::GetSavedBackTextureCountForTest() { @@ -1307,10 +1308,6 @@ return group_->image_manager(); } -ServiceTransferCache* GLES2DecoderPassthroughImpl::GetTransferCacheForTest() { - return nullptr; -} - bool GLES2DecoderPassthroughImpl::HasPendingQueries() const { return !pending_queries_.empty(); } @@ -1633,8 +1630,8 @@ } // Buffer is mapped, patch the result with the original access flags - DCHECK(bufsize >= 1); - DCHECK(*length == 1); + DCHECK_GE(bufsize, 1); + DCHECK_EQ(*length, 1); params[0] = mapped_buffer_info_iter->second.original_access; return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index d5265a9..67ebd52c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -7,6 +7,12 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_PASSTHROUGH_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_PASSTHROUGH_H_ +#include <algorithm> +#include <memory> +#include <set> +#include <unordered_map> +#include <vector> + #include "base/containers/circular_deque.h" #include "base/memory/ref_counted.h" #include "gpu/command_buffer/common/debug_marker_manager.h" @@ -216,8 +222,6 @@ // Gets the ImageManager for this context. ImageManager* GetImageManagerForTest() override; - ServiceTransferCache* GetTransferCacheForTest() override; - // Returns false if there are no pending queries. bool HasPendingQueries() const override;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 2a43665..9291238 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4550,127 +4550,6 @@ return error::kNoError; } -error::Error GLES2DecoderPassthroughImpl::HandleBeginRasterCHROMIUM( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::BeginRasterCHROMIUM& c = - *static_cast<const volatile gles2::cmds::BeginRasterCHROMIUM*>(cmd_data); - if (!features().chromium_raster_transport) { - return error::kUnknownCommand; - } - - GLuint texture_id = static_cast<GLuint>(c.texture_id); - GLuint sk_color = static_cast<GLuint>(c.sk_color); - GLuint msaa_sample_count = static_cast<GLuint>(c.msaa_sample_count); - GLboolean can_use_lcd_text = static_cast<GLboolean>(c.can_use_lcd_text); - GLint color_type = static_cast<GLint>(c.color_type); - GLuint color_space_transfer_cache_id = - static_cast<GLuint>(c.color_space_transfer_cache_id); - error::Error error = DoBeginRasterCHROMIUM( - texture_id, sk_color, msaa_sample_count, can_use_lcd_text, color_type, - color_space_transfer_cache_id); - if (error != error::kNoError) { - return error; - } - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::HandleRasterCHROMIUM( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::RasterCHROMIUM& c = - *static_cast<const volatile gles2::cmds::RasterCHROMIUM*>(cmd_data); - if (!features().chromium_raster_transport) { - return error::kUnknownCommand; - } - - GLuint raster_shm_id = static_cast<GLuint>(c.raster_shm_id); - GLuint raster_shm_offset = static_cast<GLuint>(c.raster_shm_offset); - GLsizeiptr raster_shm_size = static_cast<GLsizeiptr>(c.raster_shm_size); - GLuint font_shm_id = static_cast<GLuint>(c.font_shm_id); - GLuint font_shm_offset = static_cast<GLuint>(c.font_shm_offset); - GLsizeiptr font_shm_size = static_cast<GLsizeiptr>(c.font_shm_size); - error::Error error = - DoRasterCHROMIUM(raster_shm_id, raster_shm_offset, raster_shm_size, - font_shm_id, font_shm_offset, font_shm_size); - if (error != error::kNoError) { - return error; - } - return error::kNoError; -} - -error::Error GLES2DecoderPassthroughImpl::HandleEndRasterCHROMIUM( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - if (!features().chromium_raster_transport) { - return error::kUnknownCommand; - } - - error::Error error = DoEndRasterCHROMIUM(); - if (error != error::kNoError) { - return error; - } - return error::kNoError; -} - -error::Error -GLES2DecoderPassthroughImpl::HandleCreateTransferCacheEntryINTERNAL( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::CreateTransferCacheEntryINTERNAL& c = - *static_cast< - const volatile gles2::cmds::CreateTransferCacheEntryINTERNAL*>( - cmd_data); - GLuint entry_type = static_cast<GLuint>(c.entry_type); - GLuint entry_id = static_cast<GLuint>(c.entry_id); - GLuint handle_shm_id = static_cast<GLuint>(c.handle_shm_id); - GLuint handle_shm_offset = static_cast<GLuint>(c.handle_shm_offset); - GLuint data_shm_id = static_cast<GLuint>(c.data_shm_id); - GLuint data_shm_offset = static_cast<GLuint>(c.data_shm_offset); - GLuint data_size = static_cast<GLuint>(c.data_size); - error::Error error = DoCreateTransferCacheEntryINTERNAL( - entry_type, entry_id, handle_shm_id, handle_shm_offset, data_shm_id, - data_shm_offset, data_size); - if (error != error::kNoError) { - return error; - } - return error::kNoError; -} - -error::Error -GLES2DecoderPassthroughImpl::HandleDeleteTransferCacheEntryINTERNAL( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::DeleteTransferCacheEntryINTERNAL& c = - *static_cast< - const volatile gles2::cmds::DeleteTransferCacheEntryINTERNAL*>( - cmd_data); - GLuint entry_type = static_cast<GLuint>(c.entry_type); - GLuint entry_id = static_cast<GLuint>(c.entry_id); - error::Error error = DoDeleteTransferCacheEntryINTERNAL(entry_type, entry_id); - if (error != error::kNoError) { - return error; - } - return error::kNoError; -} - -error::Error -GLES2DecoderPassthroughImpl::HandleUnlockTransferCacheEntryINTERNAL( - uint32_t immediate_data_size, - const volatile void* cmd_data) { - const volatile gles2::cmds::UnlockTransferCacheEntryINTERNAL& c = - *static_cast< - const volatile gles2::cmds::UnlockTransferCacheEntryINTERNAL*>( - cmd_data); - GLuint entry_type = static_cast<GLuint>(c.entry_type); - GLuint entry_id = static_cast<GLuint>(c.entry_id); - error::Error error = DoUnlockTransferCacheEntryINTERNAL(entry_type, entry_id); - if (error != error::kNoError) { - return error; - } - return error::kNoError; -} - error::Error GLES2DecoderPassthroughImpl::HandleTexStorage2DImageCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 25e2fd6..29b4b12 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -947,6 +947,9 @@ if (group_ && group_->texture_manager()) { group_->texture_manager()->MarkContextLost(); } + if (gr_context_) { + gr_context_->abandonContext(); + } state_.MarkContextLost(); }
diff --git a/gpu/command_buffer/service/raster_decoder.h b/gpu/command_buffer/service/raster_decoder.h index cd1afdf..c2ce9cc5c 100644 --- a/gpu/command_buffer/service/raster_decoder.h +++ b/gpu/command_buffer/service/raster_decoder.h
@@ -13,6 +13,7 @@ namespace gpu { class DecoderClient; +class ServiceTransferCache; namespace gles2 { class CopyTextureCHROMIUMResourceManager; @@ -73,6 +74,8 @@ gles2::CopyTextureCHROMIUMResourceManager* copy_texture_resource_manager) = 0; + virtual ServiceTransferCache* GetTransferCacheForTest() = 0; + protected: RasterDecoder(CommandBufferServiceBase* command_buffer_service);
diff --git a/gpu/ipc/gl_in_process_context.cc b/gpu/ipc/gl_in_process_context.cc index 9837987..d3da675c 100644 --- a/gpu/ipc/gl_in_process_context.cc +++ b/gpu/ipc/gl_in_process_context.cc
@@ -64,7 +64,6 @@ void SetPresentationCallback( const InProcessCommandBuffer::PresentationCallback& callback) override; void SetLock(base::Lock* lock) override; - ServiceTransferCache* GetTransferCacheForTest() const override; private: std::unique_ptr<gles2::GLES2CmdHelper> gles2_helper_; @@ -120,10 +119,6 @@ NOTREACHED(); } -ServiceTransferCache* GLInProcessContextImpl::GetTransferCacheForTest() const { - return command_buffer_->GetTransferCacheForTest(); -} - ContextResult GLInProcessContextImpl::Initialize( scoped_refptr<InProcessCommandBuffer::Service> service, scoped_refptr<gl::GLSurface> surface,
diff --git a/gpu/ipc/gl_in_process_context.h b/gpu/ipc/gl_in_process_context.h index bf4cec82..160c3b2 100644 --- a/gpu/ipc/gl_in_process_context.h +++ b/gpu/ipc/gl_in_process_context.h
@@ -16,7 +16,6 @@ namespace gpu { struct GpuFeatureInfo; -class ServiceTransferCache; struct SharedMemoryLimits; namespace gles2 { @@ -67,9 +66,6 @@ virtual void SetPresentationCallback( const InProcessCommandBuffer::PresentationCallback& callback) = 0; - - // Test only functions. - virtual ServiceTransferCache* GetTransferCacheForTest() const = 0; }; } // namespace gpu
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 8a1e7f3..cca06289 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -238,6 +238,12 @@ g_default_service.Get().SetGpuFeatureInfo(gpu_feature_info); } +gpu::ServiceTransferCache* InProcessCommandBuffer::GetTransferCacheForTest() + const { + return static_cast<raster::RasterDecoder*>(decoder_.get()) + ->GetTransferCacheForTest(); +} + bool InProcessCommandBuffer::MakeCurrent() { CheckSequencedThread(); command_buffer_lock_.AssertAcquired();
diff --git a/gpu/ipc/in_process_command_buffer.h b/gpu/ipc/in_process_command_buffer.h index d3e7ea6..5f111d2 100644 --- a/gpu/ipc/in_process_command_buffer.h +++ b/gpu/ipc/in_process_command_buffer.h
@@ -209,9 +209,7 @@ static void InitializeDefaultServiceForTesting( const GpuFeatureInfo& gpu_feature_info); - gpu::ServiceTransferCache* GetTransferCacheForTest() const { - return decoder_->GetTransferCacheForTest(); - } + gpu::ServiceTransferCache* GetTransferCacheForTest() const; static const int kGpuMemoryBufferClientId;
diff --git a/gpu/ipc/raster_in_process_context.cc b/gpu/ipc/raster_in_process_context.cc index 8504141..d45bfdd 100644 --- a/gpu/ipc/raster_in_process_context.cc +++ b/gpu/ipc/raster_in_process_context.cc
@@ -20,7 +20,6 @@ #include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_switches.h" #include "gpu/ipc/common/surface_handle.h" -#include "gpu/skia_bindings/gles2_implementation_with_grcontext_support.h" namespace gpu { @@ -36,11 +35,6 @@ raster_implementation_->Flush(); raster_implementation_.reset(); } - if (gles2_implementation_) { - gles2_implementation_->Flush(); - gles2_implementation_.reset(); - } - transfer_buffer_.reset(); helper_.reset(); command_buffer_.reset(); @@ -58,6 +52,10 @@ if (!attribs.enable_raster_interface) { return ContextResult::kFatalFailure; } + DCHECK(!attribs.enable_gles2_interface); + if (attribs.enable_gles2_interface) { + return ContextResult::kFatalFailure; + } // TODO(backer): Remove this. Currently used to set // |chromium_raster_transport| features flag (https://crbug.com/786591) and @@ -82,52 +80,28 @@ // Check for consistency. DCHECK(!attribs.bind_generates_resource); constexpr bool bind_generates_resource = false; - constexpr bool support_client_side_arrays = false; - if (attribs.enable_gles2_interface) { - auto gles2_helper = - std::make_unique<gles2::GLES2CmdHelper>(command_buffer_.get()); - result = gles2_helper->Initialize(memory_limits.command_buffer_size); - if (result != ContextResult::kSuccess) { - LOG(ERROR) << "Failed to initialize GLES2CmdHelper"; - return result; - } - transfer_buffer_ = std::make_unique<TransferBuffer>(gles2_helper.get()); + // TODO(https://crbug.com/829469): Remove check once we fuzz RasterDecoder. + // enable_oop_rasterization is currently necessary to create RasterDecoder + // in InProcessCommandBuffer. + DCHECK(attribs.enable_oop_rasterization); - // Create the object exposing the OpenGL API. - gles2_implementation_ = std::make_unique< - skia_bindings::GLES2ImplementationWithGrContextSupport>( - gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(), - bind_generates_resource, attribs.lose_context_when_out_of_memory, - support_client_side_arrays, command_buffer_.get()); - result = gles2_implementation_->Initialize(memory_limits); - raster_implementation_ = std::make_unique<raster::RasterImplementationGLES>( - gles2_implementation_.get(), gles2_implementation_.get(), - gles2_implementation_->command_buffer(), GetCapabilities()); - helper_ = std::move(gles2_helper); - } else { - // TODO(https://crbug.com/829469): Remove check once we fuzz RasterDecoder. - // enable_oop_rasterization is currently necessary to create RasterDecoder - // in InProcessCommandBuffer. - DCHECK(attribs.enable_oop_rasterization); - - // Create the RasterCmdHelper, which writes the command buffer protocol. - auto raster_helper = - std::make_unique<raster::RasterCmdHelper>(command_buffer_.get()); - result = raster_helper->Initialize(memory_limits.command_buffer_size); - if (result != ContextResult::kSuccess) { - LOG(ERROR) << "Failed to initialize RasterCmdHelper"; - return result; - } - transfer_buffer_ = std::make_unique<TransferBuffer>(raster_helper.get()); - - auto raster_implementation = std::make_unique<raster::RasterImplementation>( - raster_helper.get(), transfer_buffer_.get(), bind_generates_resource, - attribs.lose_context_when_out_of_memory, command_buffer_.get()); - result = raster_implementation->Initialize(memory_limits); - raster_implementation_ = std::move(raster_implementation); - helper_ = std::move(raster_helper); + // Create the RasterCmdHelper, which writes the command buffer protocol. + auto raster_helper = + std::make_unique<raster::RasterCmdHelper>(command_buffer_.get()); + result = raster_helper->Initialize(memory_limits.command_buffer_size); + if (result != ContextResult::kSuccess) { + LOG(ERROR) << "Failed to initialize RasterCmdHelper"; + return result; } + transfer_buffer_ = std::make_unique<TransferBuffer>(raster_helper.get()); + + auto raster_implementation = std::make_unique<raster::RasterImplementation>( + raster_helper.get(), transfer_buffer_.get(), bind_generates_resource, + attribs.lose_context_when_out_of_memory, command_buffer_.get()); + result = raster_implementation->Initialize(memory_limits); + raster_implementation_ = std::move(raster_implementation); + helper_ = std::move(raster_helper); return result; } @@ -144,12 +118,7 @@ } ContextSupport* RasterInProcessContext::GetContextSupport() { - if (gles2_implementation_) { - return gles2_implementation_.get(); - } else { - return static_cast<raster::RasterImplementation*>( - raster_implementation_.get()); - } + return raster_implementation_.get(); } ServiceTransferCache* RasterInProcessContext::GetTransferCacheForTest() const {
diff --git a/gpu/ipc/raster_in_process_context.h b/gpu/ipc/raster_in_process_context.h index aa34d8b51..ee9be759 100644 --- a/gpu/ipc/raster_in_process_context.h +++ b/gpu/ipc/raster_in_process_context.h
@@ -20,12 +20,9 @@ struct GpuFeatureInfo; struct SharedMemoryLimits; -namespace gles2 { -class GLES2Implementation; -} - namespace raster { class RasterInterface; +class RasterImplementation; } // namespace raster // Runs client and server side command buffer code in process. Only supports @@ -62,12 +59,7 @@ private: std::unique_ptr<CommandBufferHelper> helper_; std::unique_ptr<TransferBuffer> transfer_buffer_; - std::unique_ptr<raster::RasterInterface> raster_implementation_; - - // TODO(backer): Nix this once RasterDecoder launches. - // Only created if attribs.enable_gles2_interface. - std::unique_ptr<gles2::GLES2Implementation> gles2_implementation_; - + std::unique_ptr<raster::RasterImplementation> raster_implementation_; std::unique_ptr<InProcessCommandBuffer> command_buffer_; DISALLOW_COPY_AND_ASSIGN(RasterInProcessContext);
diff --git a/gpu/skia_bindings/gles2_implementation_with_grcontext_support.cc b/gpu/skia_bindings/gles2_implementation_with_grcontext_support.cc index 37820e9b..1d1e0c6 100644 --- a/gpu/skia_bindings/gles2_implementation_with_grcontext_support.cc +++ b/gpu/skia_bindings/gles2_implementation_with_grcontext_support.cc
@@ -4,6 +4,8 @@ #include "gpu/skia_bindings/gles2_implementation_with_grcontext_support.h" +#include <utility> + #include "gpu/skia_bindings/grcontext_for_gles2_interface.h" #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/skia/include/gpu/GrContext.h" @@ -54,13 +56,6 @@ using_gl_from_skia_ = false; } -void GLES2ImplementationWithGrContextSupport::EndRasterCHROMIUM() { - BaseClass::EndRasterCHROMIUM(); - // Assume that invoking the GLES2-backed version of the raster interface - // invalidates everything. - ResetGrContextIfNeeded(kALL_GrGLBackendState); -} - // Calls that invalidate kRenderTarget_GrGLBackendState void GLES2ImplementationWithGrContextSupport::BindFramebuffer( GLenum target,
diff --git a/gpu/skia_bindings/gles2_implementation_with_grcontext_support.h b/gpu/skia_bindings/gles2_implementation_with_grcontext_support.h index baadbeef..01cacea 100644 --- a/gpu/skia_bindings/gles2_implementation_with_grcontext_support.h +++ b/gpu/skia_bindings/gles2_implementation_with_grcontext_support.h
@@ -38,9 +38,6 @@ // These must be kept in sync with the invalidation defines in // GrGLGpu::onResetContext() - // Calls that invalidate arbitrary state - void EndRasterCHROMIUM() override; - // Calls that invalidate kRenderTarget_GrGLBackendState void BindFramebuffer(GLenum target, GLuint framebuffer) override; void BindRenderbuffer(GLenum target, GLuint renderbuffer) override; @@ -193,4 +190,4 @@ } // namespace skia_bindings -#endif +#endif // GPU_SKIA_BINDINGS_GLES2_IMPLEMENTATION_WITH_GRCONTEXT_SUPPORT_H_
diff --git a/infra/config/global/luci-milo-dev.cfg b/infra/config/global/luci-milo-dev.cfg index 518f5677..e066ff7 100644 --- a/infra/config/global/luci-milo-dev.cfg +++ b/infra/config/global/luci-milo-dev.cfg
@@ -1258,11 +1258,6 @@ short_name: "32" } builders: { - name: "buildbot/chromium.perf/Win 7 Intel GPU Perf" - category: "perf|win|7" - short_name: "int" - } - builders: { name: "buildbot/chromium.perf/Win 7 Nvidia GPU Perf" category: "perf|win|7" short_name: "nvi"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index 65f17d7..f9f3be9 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -1318,11 +1318,6 @@ short_name: "32" } builders: { - name: "buildbot/chromium.perf/Win 7 Intel GPU Perf" - category: "perf|win|7" - short_name: "int" - } - builders: { name: "buildbot/chromium.perf/Win 7 Nvidia GPU Perf" category: "perf|win|7" short_name: "nvi"
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 5e823ca..dd283f4 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -116,7 +116,7 @@ "//ios/chrome/browser/browsing_data:features", "//ios/chrome/browser/download", "//ios/chrome/browser/drag_and_drop", - "//ios/chrome/browser/itunes_links", + "//ios/chrome/browser/itunes_urls", "//ios/chrome/browser/mailto:features", "//ios/chrome/browser/payments:constants", "//ios/chrome/browser/ssl:features",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 5a3c906..31ffbb6e 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -42,7 +42,7 @@ #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/drag_and_drop/drag_and_drop_flag.h" #include "ios/chrome/browser/ios_chrome_flag_descriptions.h" -#include "ios/chrome/browser/itunes_links/itunes_links_flag.h" +#include "ios/chrome/browser/itunes_urls/itunes_urls_flag.h" #include "ios/chrome/browser/mailto/features.h" #include "ios/chrome/browser/ssl/captive_portal_features.h" #include "ios/chrome/browser/ui/external_search/features.h" @@ -216,6 +216,13 @@ flag_descriptions::kWKHTTPSystemCookieStoreName, flag_descriptions::kWKHTTPSystemCookieStoreName, flags_ui::kOsIos, FEATURE_VALUE_TYPE(web::features::kWKHTTPSystemCookieStore)}, + {"enable-autofill-credit-card-upload-google-pay-branding", + flag_descriptions::kAutofillUpstreamUseGooglePayBrandingOnMobileName, + flag_descriptions:: + kAutofillUpstreamUseGooglePayBrandingOnMobileDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillUpstreamUseGooglePayBrandingOnMobile)}, {"show-autofill-type-predictions", flag_descriptions::kShowAutofillTypePredictionsName, flag_descriptions::kShowAutofillTypePredictionsDescription, @@ -257,10 +264,10 @@ {"new-tools_menu", flag_descriptions::kNewToolsMenuName, flag_descriptions::kNewToolsMenuDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kNewToolsMenu)}, - {"itunes-links-store-kit-handling", - flag_descriptions::kITunesLinksStoreKitHandlingName, - flag_descriptions::kITunesLinksStoreKitHandlingDescription, - flags_ui::kOsIos, FEATURE_VALUE_TYPE(kITunesLinksStoreKitHandling)}, + {"itunes-urls-store-kit-handling", + flag_descriptions::kITunesUrlsStoreKitHandlingName, + flag_descriptions::kITunesUrlsStoreKitHandlingDescription, + flags_ui::kOsIos, FEATURE_VALUE_TYPE(kITunesUrlsStoreKitHandling)}, {"unified-consent", flag_descriptions::kUnifiedConsentName, flag_descriptions::kUnifiedConsentDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(signin::kUnifiedConsent)},
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index d2d5c6d..9c17f1267 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -11,6 +11,12 @@ namespace flag_descriptions { +const char kAutofillUpstreamUseGooglePayBrandingOnMobileName[] = + "Enable Google Pay branding when offering credit card upload"; +const char kAutofillUpstreamUseGooglePayBrandingOnMobileDescription[] = + "If enabled, shows the Google Pay logo and a shorter header message when " + "credit card upload to Google Payments is offered."; + const char kAutofillIOSDelayBetweenFieldsName[] = "Autofill delay"; const char kAutofillIOSDelayBetweenFieldsDescription[] = "Delay between the different fields of a form being autofilled. In " @@ -108,10 +114,11 @@ "an individual promotion causes that promotion but no other promotions to " "occur."; -const char kITunesLinksStoreKitHandlingName[] = "Store kit for ITunes links"; -const char kITunesLinksStoreKitHandlingDescription[] = - "When enabled, opening itunes product links will be handled using the " - "store kit."; +const char kITunesUrlsStoreKitHandlingName[] = + "Store kit handling for ITunes links"; +const char kITunesUrlsStoreKitHandlingDescription[] = + "When enabled, opening itunes product URLs will be handled using the store " + "kit."; const char kMailtoHandlingWithGoogleUIName[] = "Mailto Handling with Google UI"; const char kMailtoHandlingWithGoogleUIDescription[] =
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index b1ae1cd..59c9a52 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -7,11 +7,16 @@ namespace flag_descriptions { -// Title and description for the flag to controll the autofill delay. +// Title and description for the flag to control GPay branding in credit card +// upstream infobar. +extern const char kAutofillUpstreamUseGooglePayBrandingOnMobileName[]; +extern const char kAutofillUpstreamUseGooglePayBrandingOnMobileDescription[]; + +// Title and description for the flag to control the autofill delay. extern const char kAutofillIOSDelayBetweenFieldsName[]; extern const char kAutofillIOSDelayBetweenFieldsDescription[]; -// Title and description for the flag to controll the dynamic autofill. +// Title and description for the flag to control the dynamic autofill. extern const char kAutofillDynamicFormsName[]; extern const char kAutofillDynamicFormsDescription[]; @@ -87,8 +92,8 @@ extern const char kInProductHelpDemoModeDescription[]; // Title and description for the flag to enable ITunes links store kit handling. -extern const char kITunesLinksStoreKitHandlingName[]; -extern const char kITunesLinksStoreKitHandlingDescription[]; +extern const char kITunesUrlsStoreKitHandlingName[]; +extern const char kITunesUrlsStoreKitHandlingDescription[]; // Title, description, and options for Google UI menu for handling mailto links. extern const char kMailtoHandlingWithGoogleUIName[];
diff --git a/ios/chrome/browser/itunes_links/OWNERS b/ios/chrome/browser/itunes_links/OWNERS deleted file mode 100644 index c85e66a..0000000 --- a/ios/chrome/browser/itunes_links/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -jif@chromium.org - -# TEAM: ios-directory-owners@chromium.org -# OS: iOS
diff --git a/ios/chrome/browser/itunes_links/itunes_links_flag.h b/ios/chrome/browser/itunes_links/itunes_links_flag.h deleted file mode 100644 index 5f548559..0000000 --- a/ios/chrome/browser/itunes_links/itunes_links_flag.h +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_ITUNES_LINKS_ITUNES_LINKS_FLAG_H_ -#define IOS_CHROME_BROWSER_ITUNES_LINKS_ITUNES_LINKS_FLAG_H_ - -#include "base/feature_list.h" - -extern const base::Feature kITunesLinksStoreKitHandling; - -#endif // IOS_CHROME_BROWSER_ITUNES_LINKS_ITUNES_LINKS_FLAG_H
diff --git a/ios/chrome/browser/itunes_links/itunes_links_flag.mm b/ios/chrome/browser/itunes_links/itunes_links_flag.mm deleted file mode 100644 index a2f6f7a..0000000 --- a/ios/chrome/browser/itunes_links/itunes_links_flag.mm +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/itunes_links/itunes_links_flag.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -const base::Feature kITunesLinksStoreKitHandling{ - "ITunesLinksStoreKitHandling", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/itunes_links/BUILD.gn b/ios/chrome/browser/itunes_urls/BUILD.gn similarity index 76% rename from ios/chrome/browser/itunes_links/BUILD.gn rename to ios/chrome/browser/itunes_urls/BUILD.gn index ad2ccf1..1a7608b 100644 --- a/ios/chrome/browser/itunes_links/BUILD.gn +++ b/ios/chrome/browser/itunes_urls/BUILD.gn
@@ -2,13 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("itunes_links") { +source_set("itunes_urls") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "itunes_links_flag.h", - "itunes_links_flag.mm", - "itunes_links_handler_tab_helper.h", - "itunes_links_handler_tab_helper.mm", + "itunes_urls_flag.h", + "itunes_urls_flag.mm", + "itunes_urls_handler_tab_helper.h", + "itunes_urls_handler_tab_helper.mm", ] deps = [ "//base", @@ -22,10 +22,10 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ - "itunes_links_handler_tab_helper_unittest.mm", + "itunes_urls_handler_tab_helper_unittest.mm", ] deps = [ - ":itunes_links", + ":itunes_urls", "//base", "//base/test:test_support", "//ios/chrome/browser/browser_state:test_support",
diff --git a/ios/chrome/browser/itunes_urls/OWNERS b/ios/chrome/browser/itunes_urls/OWNERS new file mode 100644 index 0000000..e7b3304 --- /dev/null +++ b/ios/chrome/browser/itunes_urls/OWNERS
@@ -0,0 +1,5 @@ +eugenebut@chromium.org +mrefaat@chromium.org + +# TEAM: ios-directory-owners@chromium.org +# OS: iOS
diff --git a/ios/chrome/browser/itunes_urls/itunes_urls_flag.h b/ios/chrome/browser/itunes_urls/itunes_urls_flag.h new file mode 100644 index 0000000..607a43c --- /dev/null +++ b/ios/chrome/browser/itunes_urls/itunes_urls_flag.h
@@ -0,0 +1,12 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_ITUNES_URLS_ITUNES_URLS_FLAG_H_ +#define IOS_CHROME_BROWSER_ITUNES_URLS_ITUNES_URLS_FLAG_H_ + +#include "base/feature_list.h" + +extern const base::Feature kITunesUrlsStoreKitHandling; + +#endif // IOS_CHROME_BROWSER_ITUNES_URLS_ITUNES_URLS_FLAG_H
diff --git a/ios/chrome/browser/itunes_urls/itunes_urls_flag.mm b/ios/chrome/browser/itunes_urls/itunes_urls_flag.mm new file mode 100644 index 0000000..aed47f7b --- /dev/null +++ b/ios/chrome/browser/itunes_urls/itunes_urls_flag.mm
@@ -0,0 +1,12 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/itunes_urls/itunes_urls_flag.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +const base::Feature kITunesUrlsStoreKitHandling{ + "ITunesUrlsStoreKitHandling", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.h b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h similarity index 79% rename from ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.h rename to ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h index d4ab5f9..b875176 100644 --- a/ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.h +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_ITUNES_LINKS_ITUNES_LINKS_HANDLER_TAB_HELPER_H_ -#define IOS_CHROME_BROWSER_ITUNES_LINKS_ITUNES_LINKS_HANDLER_TAB_HELPER_H_ +#ifndef IOS_CHROME_BROWSER_ITUNES_URLS_ITUNES_URLS_HANDLER_TAB_HELPER_H_ +#define IOS_CHROME_BROWSER_ITUNES_URLS_ITUNES_URLS_HANDLER_TAB_HELPER_H_ #include "base/macros.h" #import "ios/web/public/web_state/web_state_policy_decider.h" @@ -33,12 +33,12 @@ // StoreKitTabHelper to present the information of that product. The goal of // this class is to workaround a bug where appstore website serves the wrong // content for itunes.apple.com pages, see http://crbug.com/623016. -class ITunesLinksHandlerTabHelper +class ITunesUrlsHandlerTabHelper : public web::WebStatePolicyDecider, - public web::WebStateUserData<ITunesLinksHandlerTabHelper> { + public web::WebStateUserData<ITunesUrlsHandlerTabHelper> { public: - ~ITunesLinksHandlerTabHelper() override; - explicit ITunesLinksHandlerTabHelper(web::WebState* web_state); + ~ITunesUrlsHandlerTabHelper() override; + explicit ITunesUrlsHandlerTabHelper(web::WebState* web_state); // web::WebStatePolicyDecider implementation bool ShouldAllowRequest(NSURLRequest* request, ui::PageTransition transition, @@ -48,7 +48,7 @@ // Opens the StoreKit for the given iTunes app |url|. void HandleITunesUrl(const GURL& url); - DISALLOW_COPY_AND_ASSIGN(ITunesLinksHandlerTabHelper); + DISALLOW_COPY_AND_ASSIGN(ITunesUrlsHandlerTabHelper); }; -#endif // IOS_CHROME_BROWSER_ITUNES_LINKS_ITUNES_LINKS_HANDLER_TAB_HELPER_H_ +#endif // IOS_CHROME_BROWSER_ITUNES_URLS_ITUNES_URLS_HANDLER_TAB_HELPER_H_
diff --git a/ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.mm b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm similarity index 89% rename from ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.mm rename to ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm index d3bb5642..34f9216 100644 --- a/ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.mm +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.mm
@@ -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 "ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.h" +#import "ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h" #import <Foundation/Foundation.h> #import <StoreKit/StoreKit.h> @@ -28,11 +28,11 @@ #error "This file requires ARC support." #endif -DEFINE_WEB_STATE_USER_DATA_KEY(ITunesLinksHandlerTabHelper); +DEFINE_WEB_STATE_USER_DATA_KEY(ITunesUrlsHandlerTabHelper); namespace { -// The domain for iTunes appstore links. +// The domain for iTunes appstore URLs. const char kITunesUrlDomain[] = "itunes.apple.com"; const char kITunesProductIdPrefix[] = "id"; const char kITunesAppPathIdentifier[] = "app"; @@ -77,7 +77,7 @@ return params_dictionary; } -// Returns true, if ITunesLinksHandlerTabHelper can handle the given |url|. +// Returns true, if ITunesUrlsHandlerTabHelper can handle the given |url|. bool CanHandleUrl(const GURL& url) { if (!IsITunesProductUrl(url)) return false; @@ -103,13 +103,12 @@ } // namespace -ITunesLinksHandlerTabHelper::~ITunesLinksHandlerTabHelper() = default; +ITunesUrlsHandlerTabHelper::~ITunesUrlsHandlerTabHelper() = default; -ITunesLinksHandlerTabHelper::ITunesLinksHandlerTabHelper( - web::WebState* web_state) +ITunesUrlsHandlerTabHelper::ITunesUrlsHandlerTabHelper(web::WebState* web_state) : web::WebStatePolicyDecider(web_state) {} -bool ITunesLinksHandlerTabHelper::ShouldAllowRequest( +bool ITunesUrlsHandlerTabHelper::ShouldAllowRequest( NSURLRequest* request, ui::PageTransition transition, bool from_main_frame) { @@ -128,7 +127,7 @@ } // private -void ITunesLinksHandlerTabHelper::HandleITunesUrl(const GURL& url) { +void ITunesUrlsHandlerTabHelper::HandleITunesUrl(const GURL& url) { ITunesUrlsStoreKitHandlingResult handling_result = ITunesUrlsStoreKitHandlingResult::kSingleAppUrlHandled; StoreKitTabHelper* tab_helper = StoreKitTabHelper::FromWebState(web_state());
diff --git a/ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper_unittest.mm b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm similarity index 92% rename from ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper_unittest.mm rename to ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm index b05cd208..8df78fd77 100644 --- a/ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper_unittest.mm +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm
@@ -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 "ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.h" +#import "ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h" #import <Foundation/Foundation.h> @@ -25,15 +25,15 @@ "IOS.StoreKit.ITunesURLsHandlingResult"; } // namespace -class ITunesLinksHandlerTabHelperTest : public PlatformTest { +class ITunesUrlsHandlerTabHelperTest : public PlatformTest { protected: - ITunesLinksHandlerTabHelperTest() + ITunesUrlsHandlerTabHelperTest() : fake_launcher_([[FakeStoreKitLauncher alloc] init]), chrome_browser_state_(TestChromeBrowserState::Builder().Build()) { web_state_.SetBrowserState( chrome_browser_state_->GetOriginalChromeBrowserState()); StoreKitTabHelper::CreateForWebState(&web_state_); - ITunesLinksHandlerTabHelper::CreateForWebState(&web_state_); + ITunesUrlsHandlerTabHelper::CreateForWebState(&web_state_); StoreKitTabHelper::FromWebState(&web_state_)->SetLauncher(fake_launcher_); } @@ -57,7 +57,7 @@ }; // Verifies that iTunes URLs are not handled when in off the record mode. -TEST_F(ITunesLinksHandlerTabHelperTest, NoHandlingInOffTheRecordMode) { +TEST_F(ITunesUrlsHandlerTabHelperTest, NoHandlingInOffTheRecordMode) { NSString* url = @"http://itunes.apple.com/us/app/app_name/id123"; EXPECT_TRUE(VerifyStoreKitLaunched(url, /*main_frame=*/true)); web_state_.SetBrowserState( @@ -66,7 +66,7 @@ } // Verifies that iTunes URLs are not handled when the request is from iframe. -TEST_F(ITunesLinksHandlerTabHelperTest, NoHandlingInIframes) { +TEST_F(ITunesUrlsHandlerTabHelperTest, NoHandlingInIframes) { EXPECT_TRUE(VerifyStoreKitLaunched( @"http://itunes.apple.com/us/app/app_name/id123", /*main_frame=*/true)); EXPECT_FALSE(VerifyStoreKitLaunched( @@ -79,7 +79,7 @@ // Verifies that navigating to non iTunes product URLs, or not supported iTunes // product type URLs does not launch storekit. -TEST_F(ITunesLinksHandlerTabHelperTest, NonMatchingUrlsDoesntLaunchStoreKit) { +TEST_F(ITunesUrlsHandlerTabHelperTest, NonMatchingUrlsDoesntLaunchStoreKit) { EXPECT_FALSE(VerifyStoreKitLaunched(@"", /*main_frame=*/true)); EXPECT_FALSE(VerifyStoreKitLaunched(@"foobar", /*main_frame=*/true)); EXPECT_FALSE(VerifyStoreKitLaunched(@"foo://bar", /*main_frame=*/true)); @@ -108,7 +108,7 @@ // Verifies that navigating to URLs for a product hosted on iTunes AppStore // with supported media type launches storekit. -TEST_F(ITunesLinksHandlerTabHelperTest, MatchingUrlsLaunchesStoreKit) { +TEST_F(ITunesUrlsHandlerTabHelperTest, MatchingUrlsLaunchesStoreKit) { EXPECT_TRUE(VerifyStoreKitLaunched( @"http://itunes.apple.com/us/app/app_name/id123", /*main_frame=*/true)); NSString* product_id = @"id";
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index ff4cafb27..cca1c88 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -97,7 +97,7 @@ "//ios/chrome/browser/history", "//ios/chrome/browser/history:tab_helper", "//ios/chrome/browser/infobars", - "//ios/chrome/browser/itunes_links", + "//ios/chrome/browser/itunes_urls", "//ios/chrome/browser/language", "//ios/chrome/browser/metrics", "//ios/chrome/browser/metrics:metrics_internal",
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm index a0c9ff3..0cca4da 100644 --- a/ios/chrome/browser/tabs/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -24,8 +24,8 @@ #include "ios/chrome/browser/history/history_tab_helper.h" #include "ios/chrome/browser/history/top_sites_factory.h" #import "ios/chrome/browser/infobars/infobar_manager_impl.h" -#include "ios/chrome/browser/itunes_links/itunes_links_flag.h" -#import "ios/chrome/browser/itunes_links/itunes_links_handler_tab_helper.h" +#include "ios/chrome/browser/itunes_urls/itunes_urls_flag.h" +#import "ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h" #import "ios/chrome/browser/metrics/ukm_url_recorder.h" #import "ios/chrome/browser/passwords/password_tab_helper.h" #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" @@ -80,8 +80,8 @@ BlockedPopupTabHelper::CreateForWebState(web_state); FindTabHelper::CreateForWebState(web_state); StoreKitTabHelper::CreateForWebState(web_state); - if (base::FeatureList::IsEnabled(kITunesLinksStoreKitHandling)) { - ITunesLinksHandlerTabHelper::CreateForWebState(web_state); + if (base::FeatureList::IsEnabled(kITunesUrlsStoreKitHandling)) { + ITunesUrlsHandlerTabHelper::CreateForWebState(web_state); } HistoryTabHelper::CreateForWebState(web_state); LoadTimingTabHelper::CreateForWebState(web_state);
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn index 1a84806e..d9bdc71 100644 --- a/ios/chrome/browser/ui/bookmarks/BUILD.gn +++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -7,8 +7,6 @@ sources = [ "bookmark_edit_view_controller.h", "bookmark_edit_view_controller.mm", - "bookmark_elevated_toolbar.h", - "bookmark_elevated_toolbar.mm", "bookmark_empty_background.h", "bookmark_empty_background.mm", "bookmark_folder_editor_view_controller.h", @@ -46,6 +44,7 @@ "undo_manager_wrapper.mm", ] deps = [ + ":bookmarks_ui", "resources:bookmark_bar_innershadow", "resources:bookmark_bar_shadow", "resources:bookmark_black_delete", @@ -132,6 +131,15 @@ ] } +source_set("bookmarks_ui") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "bookmark_ui_constants.h", + "bookmark_ui_constants.mm", + ] + deps = [] +} + source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true @@ -164,6 +172,7 @@ "bookmarks_egtest.mm", ] deps = [ + ":bookmarks_ui", "//base", "//components/bookmarks/browser", "//components/prefs",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm index d90fd18..a7c91de 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -21,6 +21,7 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_mediator.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h" @@ -38,6 +39,7 @@ #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #import "ios/third_party/material_components_ios/src/components/ShadowElevations/src/MaterialShadowElevations.h" #import "ios/third_party/material_components_ios/src/components/ShadowLayer/src/MaterialShadowLayer.h" +#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/gfx/image/image.h" #include "url/gurl.h" @@ -224,14 +226,24 @@ self.doneItem = doneItem; // Setup the bottom toolbar. + self.navigationController.toolbar.barTintColor = [UIColor whiteColor]; NSString* titleString = l10n_util::GetNSString(IDS_IOS_BOOKMARK_DELETE); + titleString = [titleString uppercaseString]; UIBarButtonItem* deleteButton = [[UIBarButtonItem alloc] initWithTitle:titleString style:UIBarButtonItemStylePlain target:self action:@selector(deleteBookmark)]; - deleteButton.accessibilityIdentifier = @"Delete_action"; - deleteButton.tintColor = [UIColor blackColor]; + deleteButton.accessibilityIdentifier = kBookmarkEditDeleteButtonIdentifier; + [deleteButton + setTitleTextAttributes:[NSDictionary + dictionaryWithObjectsAndKeys: + [[MDCTypography fontLoader] + mediumFontOfSize:14], + NSFontAttributeName, [UIColor blackColor], + NSForegroundColorAttributeName, nil] + forState:UIControlStateNormal]; + UIBarButtonItem* spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil @@ -455,8 +467,8 @@ cell.selectionStyle = UITableViewCellSelectionStyleNone; break; case ItemTypeURL: { - BookmarkTextFieldCell* URLCell = - base::mac::ObjCCastStrict<BookmarkTextFieldCell>(cell); + LegacyBookmarkTextFieldCell* URLCell = + base::mac::ObjCCastStrict<LegacyBookmarkTextFieldCell>(cell); URLCell.textField.textValidator = self; URLCell.selectionStyle = UITableViewCellSelectionStyleNone; break;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.h b/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.h deleted file mode 100644 index 91a00195..0000000 --- a/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_ELEVATED_TOOLBAR_H_ -#define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_ELEVATED_TOOLBAR_H_ - -#import <UIKit/UIKit.h> - -@class MDCButton; - -// A class containing one button that has a Material shadow. -@interface BookmarksElevatedToolbar : UIView - -@property(nonatomic, assign) CGFloat shadowElevation; - -- (void)setButton:(MDCButton*)button; - -@end - -#endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_ELEVATED_TOOLBAR_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm b/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm deleted file mode 100644 index 1dc74d7..0000000 --- a/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.h" - -#import "ios/chrome/browser/ui/util/constraints_ui_util.h" -#import "ios/third_party/material_components_ios/src/components/Buttons/src/MDCButton.h" -#import "ios/third_party/material_components_ios/src/components/ShadowElevations/src/MaterialShadowElevations.h" -#import "ios/third_party/material_components_ios/src/components/ShadowLayer/src/MaterialShadowLayer.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -const CGFloat kButtonHeight = 48; -} - -@interface BookmarksElevatedToolbar () - -@property(nonatomic, readonly) MDCShadowLayer* shadowLayer; -@property(nonatomic, strong) MDCButton* currentButton; - -@end - -@implementation BookmarksElevatedToolbar - -@synthesize currentButton = _currentButton; -@synthesize shadowLayer = _shadowLayer; - -- (instancetype)init { - self = [super init]; - if (self) { - [self.layer addSublayer:[[MDCShadowLayer alloc] init]]; - self.shadowElevation = MDCShadowElevationSearchBarResting; - self.backgroundColor = [UIColor whiteColor]; - } - return self; -} - -- (void)setButton:(MDCButton*)button { - [self.currentButton removeFromSuperview]; - self.currentButton = button; - if (!button) - return; - - [self addSubview:button]; - button.translatesAutoresizingMaskIntoConstraints = NO; - - id<LayoutGuideProvider> safeAreaLayoutGuide = - SafeAreaLayoutGuideForView(self); - [NSLayoutConstraint activateConstraints:@[ - [button.leadingAnchor - constraintEqualToAnchor:safeAreaLayoutGuide.leadingAnchor], - [button.topAnchor constraintEqualToAnchor:safeAreaLayoutGuide.topAnchor], - [button.bottomAnchor - constraintEqualToAnchor:safeAreaLayoutGuide.bottomAnchor], - [button.heightAnchor constraintEqualToConstant:kButtonHeight], - ]]; -} - -#pragma mark - Properties - -- (MDCShadowLayer*)shadowLayer { - if (!_shadowLayer) { - _shadowLayer = [[MDCShadowLayer alloc] init]; - _shadowLayer.elevation = MDCShadowElevationNone; - [self.layer addSublayer:self.shadowLayer]; - } - return _shadowLayer; -} - -- (void)setShadowElevation:(CGFloat)shadowElevation { - self.shadowLayer.elevation = shadowElevation; -} - -- (CGFloat)shadowElevation { - return self.shadowLayer.elevation; -} - -#pragma mark - UIView - -- (void)layoutSubviews { - [super layoutSubviews]; - self.shadowLayer.frame = self.layer.bounds; -} - -@end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm index 12b688ab..0baccf99f 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
@@ -16,6 +16,7 @@ #include "components/bookmarks/browser/bookmark_node.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h" @@ -450,14 +451,24 @@ - (void)addToolbar { self.navigationController.toolbarHidden = NO; + self.navigationController.toolbar.barTintColor = [UIColor whiteColor]; NSString* titleString = l10n_util::GetNSString(IDS_IOS_BOOKMARK_GROUP_DELETE); + titleString = [titleString uppercaseString]; UIBarButtonItem* deleteButton = [[UIBarButtonItem alloc] initWithTitle:titleString style:UIBarButtonItemStylePlain target:self action:@selector(deleteFolder)]; - deleteButton.accessibilityIdentifier = @"Delete Folder"; - deleteButton.tintColor = [UIColor blackColor]; + deleteButton.accessibilityIdentifier = + kBookmarkFolderEditorDeleteButtonIdentifier; + [deleteButton + setTitleTextAttributes:[NSDictionary + dictionaryWithObjectsAndKeys: + [[MDCTypography fontLoader] + mediumFontOfSize:14], + NSFontAttributeName, [UIColor blackColor], + NSForegroundColorAttributeName, nil] + forState:UIControlStateNormal]; UIBarButtonItem* spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_consumer.h b/ios/chrome/browser/ui/bookmarks/bookmark_home_consumer.h index 8d8a4c3..f24f0ba5 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_consumer.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_consumer.h
@@ -7,6 +7,10 @@ #import "ios/chrome/browser/ui/table_view/chrome_table_view_consumer.h" +@class NSIndexPath; +@class ShowSigninCommand; +@class SigninPromoViewConfigurator; + typedef NS_ENUM(NSInteger, BookmarkHomeBackgroundStyle) { // The default background style. BookmarkHomeBackgroundStyleDefault, @@ -33,6 +37,16 @@ // Displays the table view background for the given |style|. - (void)updateTableViewBackgroundStyle:(BookmarkHomeBackgroundStyle)style; +// Displays the signin UI configured by |command|. +- (void)showSignin:(ShowSigninCommand*)command; + +// Reconfigures the cell at the given |indexPath| with the given |configurator|. +// If |forceReloadCell| is YES, reloads the section when complete. +- (void)configureSigninPromoWithConfigurator: + (SigninPromoViewConfigurator*)configurator + atIndexPath:(NSIndexPath*)indexPath + forceReloadCell:(BOOL)forceReloadCell; + @end #endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_HOME_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm index 64d0017..689ef23 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm
@@ -9,10 +9,14 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/sync/synced_sessions_bridge.h" +#import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_consumer.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_shared_state.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_node_item.h" +#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_promo_item.h" +#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -21,7 +25,10 @@ using bookmarks::BookmarkNode; -@interface BookmarkHomeMediator ()<BookmarkModelBridgeObserver, +@interface BookmarkHomeMediator ()<BookmarkHomePromoItemDelegate, + BookmarkModelBridgeObserver, + BookmarkPromoControllerDelegate, + SigninPresenter, SyncedSessionsObserver> { // Bridge to register for bookmark changes. std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge; @@ -31,13 +38,20 @@ _syncedSessionsObserver; } +// Shared state between Bookmark home classes. @property(nonatomic, strong) BookmarkHomeSharedState* sharedState; +// The browser state for this mediator. @property(nonatomic, assign) ios::ChromeBrowserState* browserState; +// The controller managing the display of the promo cell and the promo view +// controller. +@property(nonatomic, strong) BookmarkPromoController* bookmarkPromoController; + @end @implementation BookmarkHomeMediator +@synthesize bookmarkPromoController = _bookmarkPromoController; @synthesize browserState = _browserState; @synthesize consumer = _consumer; @synthesize sharedState = _sharedState; @@ -61,7 +75,12 @@ _syncedSessionsObserver = std::make_unique<synced_sessions::SyncedSessionsObserverBridge>( self, self.browserState); + _bookmarkPromoController = + [[BookmarkPromoController alloc] initWithBrowserState:self.browserState + delegate:self + presenter:self]; + [self computePromoTableViewData]; [self computeBookmarkTableViewData]; } @@ -185,6 +204,49 @@ } } +#pragma mark - Public + +- (void)computePromoTableViewData { + // We show promo cell only on the root view, that is when showing + // the permanent nodes. + BOOL promoVisible = ((self.sharedState.tableViewDisplayedRootNode == + self.sharedState.bookmarkModel->root_node()) && + self.bookmarkPromoController.shouldShowSigninPromo); + + if (promoVisible == self.sharedState.promoVisible) { + return; + } + self.sharedState.promoVisible = promoVisible; + + SigninPromoViewMediator* mediator = self.signinPromoViewMediator; + if (self.sharedState.promoVisible) { + DCHECK(![self.sharedState.tableViewModel + hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]); + [self.sharedState.tableViewModel + insertSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo + atIndex:0]; + BookmarkHomePromoItem* item = + [[BookmarkHomePromoItem alloc] initWithType:BookmarkHomeItemTypePromo]; + item.delegate = self; + [self.sharedState.tableViewModel + addItem:item + toSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo]; + [mediator signinPromoViewVisible]; + } else { + if (![mediator isInvalidClosedOrNeverVisible]) { + // When the sign-in view is closed, the promo state changes, but + // -[SigninPromoViewMediator signinPromoViewHidden] should not be called. + [mediator signinPromoViewHidden]; + } + + DCHECK([self.sharedState.tableViewModel + hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]); + [self.sharedState.tableViewModel + removeSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo]; + } + [self.sharedState.tableView reloadData]; +} + #pragma mark - BookmarkModelBridgeObserver Callbacks // BookmarkModelBridgeObserver Callbacks @@ -283,6 +345,41 @@ return nil; } +#pragma mark - BookmarkHomePromoItemDelegate + +- (SigninPromoViewMediator*)signinPromoViewMediator { + return self.bookmarkPromoController.signinPromoViewMediator; +} + +#pragma mark - BookmarkPromoControllerDelegate + +- (void)promoStateChanged:(BOOL)promoEnabled { + [self computePromoTableViewData]; +} + +- (void)configureSigninPromoWithConfigurator: + (SigninPromoViewConfigurator*)configurator + identityChanged:(BOOL)identityChanged { + if (![self.sharedState.tableViewModel + hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]) { + return; + } + + NSIndexPath* indexPath = [self.sharedState.tableViewModel + indexPathForItemType:BookmarkHomeItemTypePromo + sectionIdentifier:BookmarkHomeSectionIdentifierPromo]; + [self.consumer configureSigninPromoWithConfigurator:configurator + atIndexPath:indexPath + forceReloadCell:identityChanged]; +} + +#pragma mark - SigninPresenter + +- (void)showSignin:(ShowSigninCommand*)command { + // Proxy this call along to the consumer. + [self.consumer showSignin:command]; +} + #pragma mark - SyncedSessionsObserver - (void)reloadSessions {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm index 9893581e..f60515cd 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -4,15 +4,22 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h" +#include "base/mac/bind_objc_block.h" #include "base/mac/foundation_util.h" #include "base/metrics/user_metrics.h" #include "base/strings/sys_string_conversions.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/favicon/core/fallback_url_util.h" +#include "components/favicon/core/favicon_server_fetcher_params.h" +#include "components/favicon/core/large_icon_service.h" +#include "components/favicon_base/fallback_icon_style.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #import "ios/chrome/browser/metrics/new_tab_page_uma.h" +#import "ios/chrome/browser/ui/authentication/signin_promo_view_configurator.h" #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_context_bar.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h" @@ -24,18 +31,16 @@ #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h" -#import "ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_table_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_node_item.h" -#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_promo_item.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_cell.h" +#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_signin_promo_cell.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h" #import "ios/chrome/browser/ui/material_components/utils.h" #import "ios/chrome/browser/ui/rtl_geometry.h" -#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h" #import "ios/chrome/browser/ui/ui_util.h" @@ -46,11 +51,16 @@ #import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ios/web/public/referrer.h" +#include "skia/ext/skia_utils_ios.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" using bookmarks::BookmarkNode; +// Used to store a pair of NSIntegers when storing a NSIndexPath in C++ +// collections. +using IntegerPair = std::pair<NSInteger, NSInteger>; + namespace { typedef NS_ENUM(NSInteger, BookmarksContextBarState) { BookmarksContextBarNone, // No state. @@ -65,6 +75,27 @@ BookmarksContextBarMixedSelection, // Multiple URL / Folders selected. }; +// NetworkTrafficAnnotationTag for fetching favicon from a Google server. +const net::NetworkTrafficAnnotationTag kTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("bookmarks_get_large_icon", R"( + semantics { + sender: "Bookmarks" + description: + "Sends a request to a Google server to retrieve the favicon bitmap " + "for a bookmark." + trigger: + "A request can be sent if Chrome does not have a favicon for a " + "bookmark." + data: "Page URL and desired icon size." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: "This feature cannot be disabled by settings." + policy_exception_justification: "Not implemented." + } + )"); + // Returns a vector of all URLs in |nodes|. std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { std::vector<GURL> urls; @@ -84,11 +115,9 @@ BookmarkHomeConsumer, BookmarkHomeSharedStateObserver, BookmarkModelBridgeObserver, - BookmarkPromoControllerDelegate, BookmarkTableCellTitleEditDelegate, BookmarkTableViewDelegate, ContextBarDelegate, - SigninPresenter, UIGestureRecognizerDelegate, UITableViewDataSource, UITableViewDelegate> { @@ -97,8 +126,16 @@ // The root node, whose child nodes are shown in the bookmark table view. const bookmarks::BookmarkNode* _rootNode; + // YES if NSLayoutConstraits were added. BOOL _addedConstraints; + + // Map of favicon load tasks for each index path. Used to keep track of + // pending favicon load operations so that they can be cancelled upon cell + // reuse. Keys are (section, item) pairs of cell index paths. + std::map<IntegerPair, base::CancelableTaskTracker::TaskId> _faviconLoadTasks; + // Task tracker used for async favicon loads. + base::CancelableTaskTracker _faviconTaskTracker; } // Shared state between BookmarkHome classes. Used as a temporary refactoring @@ -143,10 +180,6 @@ // The view controller to present when editing the current folder. @property(nonatomic, strong) BookmarkFolderEditorViewController* folderEditor; -// The controller managing the display of the promo cell and the promo view -// controller. -@property(nonatomic, strong) BookmarkPromoController* bookmarkPromoController; - // The current state of the context bar UI. @property(nonatomic, assign) BookmarksContextBarState contextBarState; @@ -162,7 +195,6 @@ @implementation BookmarkHomeViewController @synthesize appBar = _appBar; -@synthesize bookmarkPromoController = _bookmarkPromoController; @synthesize bookmarks = _bookmarks; @synthesize browserState = _browserState; @synthesize editViewController = _editViewController; @@ -200,13 +232,6 @@ _bookmarks = ios::BookmarkModelFactory::GetForBrowserState(browserState); _bridge.reset(new bookmarks::BookmarkModelBridge(self, _bookmarks)); - - // It is important to initialize the promo controller with the browser state - // passed in, as it could be incognito. - _bookmarkPromoController = [[BookmarkPromoController alloc] - initWithBrowserState:browserState - delegate:self - presenter:self /* id<SigninPresenter> */]; } return self; } @@ -214,6 +239,7 @@ - (void)dealloc { [self.mediator disconnect]; [self removeKeyboardObservers]; + _faviconTaskTracker.TryCancelAll(); _sharedState.tableView.dataSource = nil; _sharedState.tableView.delegate = nil; } @@ -247,8 +273,7 @@ // Set the content position after views are laid out, to ensure the right // window of rows is shown. Once used, reset self.cachedContentPosition. if (self.cachedContentPosition) { - [self.bookmarksTableView - setContentPosition:self.cachedContentPosition.floatValue]; + [self setContentPosition:self.cachedContentPosition.floatValue]; self.cachedContentPosition = nil; } // The height of contextBar might change due to word wrapping of buttons @@ -260,6 +285,12 @@ return NO; } +- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + // Stop edit of current bookmark folder name, if any. + [self.sharedState.editingFolderCell stopEdit]; +} + - (NSArray*)keyCommands { __weak BookmarkHomeViewController* weakSelf = self; return @[ [UIKeyCommand cr_keyCommandWithInput:UIKeyInputEscape @@ -357,8 +388,7 @@ cacheBookmarkUIPositionWithPrefService:self.browserState->GetPrefs() folderId:_rootNode->id() scrollPosition:static_cast<double>( - self.bookmarksTableView - .contentPosition)]; + self.contentPosition)]; } #pragma mark - BookmarkHomeConsumer @@ -379,20 +409,90 @@ - (void)refreshContents { [self.mediator computeBookmarkTableViewData]; - [self.bookmarksTableView cancelAllFaviconLoads]; + [self cancelAllFaviconLoads]; [self bookmarkTableViewRefreshContextBar:self.bookmarksTableView]; [self.sharedState.editingFolderCell stopEdit]; [self.sharedState.tableView reloadData]; if (self.sharedState.currentlyInEditMode && !self.sharedState.editNodes.empty()) { - [self.bookmarksTableView restoreRowSelection]; + [self restoreRowSelection]; } } +// Asynchronously loads favicon for given index path. The loads are cancelled +// upon cell reuse automatically. When the favicon is not found in cache, try +// loading it from a Google server if |continueToGoogleServer| is YES, +// otherwise, use the fall back icon style. - (void)loadFaviconAtIndexPath:(NSIndexPath*)indexPath continueToGoogleServer:(BOOL)continueToGoogleServer { - [self.bookmarksTableView loadFaviconAtIndexPath:indexPath - continueToGoogleServer:continueToGoogleServer]; + const bookmarks::BookmarkNode* node = [self nodeAtIndexPath:indexPath]; + if (node->is_folder()) { + return; + } + + CGFloat scale = [UIScreen mainScreen].scale; + CGFloat desiredFaviconSizeInPixel = + scale * [BookmarkHomeSharedState desiredFaviconSizePt]; + CGFloat minFaviconSizeInPixel = + scale * [BookmarkHomeSharedState minFaviconSizePt]; + + // Start loading a favicon. + __weak BookmarkHomeViewController* weakSelf = self; + GURL blockURL(node->url()); + NSString* fallbackText = + base::SysUTF16ToNSString(favicon::GetFallbackIconText(blockURL)); + void (^faviconLoadedFromCacheBlock)(const favicon_base::LargeIconResult&) = ^( + const favicon_base::LargeIconResult& result) { + BookmarkHomeViewController* strongSelf = weakSelf; + if (!strongSelf) { + return; + } + // TODO(crbug.com/697329) When fetching icon from server to replace existing + // cache is allowed, fetch icon from server here when cached icon is smaller + // than the desired size. + if (!result.bitmap.is_valid() && continueToGoogleServer && + strongSelf.sharedState.faviconDownloadCount < + [BookmarkHomeSharedState maxDownloadFaviconCount]) { + void (^faviconLoadedFromServerBlock)( + favicon_base::GoogleFaviconServerRequestStatus status) = + ^(const favicon_base::GoogleFaviconServerRequestStatus status) { + if (status == + favicon_base::GoogleFaviconServerRequestStatus::SUCCESS) { + BookmarkHomeViewController* strongSelf = weakSelf; + // GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache + // is not cancellable. So need to check if node has been changed + // before proceeding to favicon update. + if (!strongSelf || + [strongSelf nodeAtIndexPath:indexPath] != node) { + return; + } + // Favicon should be ready in cache now. Fetch it again. + [strongSelf loadFaviconAtIndexPath:indexPath + continueToGoogleServer:NO]; + } + }; // faviconLoadedFromServerBlock + + strongSelf.sharedState.faviconDownloadCount++; + IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) + ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( + favicon::FaviconServerFetcherParams::CreateForMobile( + node->url(), minFaviconSizeInPixel, + desiredFaviconSizeInPixel), + /*may_page_url_be_private=*/true, kTrafficAnnotation, + base::BindBlockArc(faviconLoadedFromServerBlock)); + } + [strongSelf updateCellAtIndexPath:indexPath + withLargeIconResult:result + fallbackText:fallbackText]; + }; // faviconLoadedFromCacheBlock + + base::CancelableTaskTracker::TaskId taskId = + IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) + ->GetLargeIconOrFallbackStyle( + node->url(), minFaviconSizeInPixel, desiredFaviconSizeInPixel, + base::BindBlockArc(faviconLoadedFromCacheBlock), + &_faviconTaskTracker); + _faviconLoadTasks[IntegerPair(indexPath.section, indexPath.item)] = taskId; } - (void)updateTableViewBackgroundStyle:(BookmarkHomeBackgroundStyle)style { @@ -408,21 +508,32 @@ } } -#pragma mark - BookmarkPromoControllerDelegate - -- (void)promoStateChanged:(BOOL)promoEnabled { - [self.bookmarksTableView promoStateChangedAnimated:YES]; +- (void)showSignin:(ShowSigninCommand*)command { + [self.dispatcher showSignin:command baseViewController:self]; } - (void)configureSigninPromoWithConfigurator: (SigninPromoViewConfigurator*)configurator - identityChanged:(BOOL)identityChanged { - [self.bookmarksTableView - configureSigninPromoWithConfigurator:configurator - identityChanged:identityChanged]; + atIndexPath:(NSIndexPath*)indexPath + forceReloadCell:(BOOL)forceReloadCell { + BookmarkTableSigninPromoCell* signinPromoCell = + base::mac::ObjCCast<BookmarkTableSigninPromoCell>( + [self.sharedState.tableView cellForRowAtIndexPath:indexPath]); + if (!signinPromoCell) { + return; + } + // Should always reconfigure the cell size even if it has to be reloaded, + // to make sure it has the right size to compute the cell size. + [configurator configureSigninPromoView:signinPromoCell.signinPromoView]; + if (forceReloadCell) { + // The section should be reload to update the cell height. + NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:indexPath.section]; + [self.sharedState.tableView reloadSections:indexSet + withRowAnimation:UITableViewRowAnimationNone]; + } } -#pragma mark Action sheet callbacks +#pragma mark - Action sheet callbacks // Opens the folder move editor for the given node. - (void)moveNodes:(const std::set<const BookmarkNode*>&)nodes { @@ -494,16 +605,12 @@ #pragma mark - Navigation Bar Callbacks - (void)navigationBarCancel:(id)sender { - [self.bookmarksTableView navigateAway]; + [self navigateAway]; [self dismissWithURL:GURL()]; } #pragma mark - BookmarkTableViewDelegate -- (SigninPromoViewMediator*)signinPromoViewMediator { - return self.bookmarkPromoController.signinPromoViewMediator; -} - - (void)bookmarkTableView:(BookmarkTableView*)view selectedUrlForNavigation:(const GURL&)url { [self dismissWithURL:url]; @@ -522,10 +629,6 @@ [self deleteNodes:nodes]; } -- (BOOL)bookmarkTableViewShouldShowPromoCell:(BookmarkTableView*)tableView { - return self.bookmarkPromoController.shouldShowSigninPromo; -} - - (void)bookmarkTableView:(BookmarkTableView*)view selectedEditNodes: (const std::set<const bookmarks::BookmarkNode*>&)nodes { @@ -885,7 +988,7 @@ // Back button callback for the new ui. - (void)back { - [self.bookmarksTableView navigateAway]; + [self navigateAway]; [self.navigationController popViewControllerAnimated:YES]; } @@ -962,6 +1065,45 @@ [super updateViewConstraints]; } +- (void)addNewFolder { + [self.sharedState.editingFolderCell stopEdit]; + if (!self.sharedState.tableViewDisplayedRootNode) { + return; + } + self.sharedState.addingNewFolder = YES; + base::string16 folderTitle = base::SysNSStringToUTF16( + l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_GROUP_DEFAULT_NAME)); + self.sharedState.editingFolderNode = + self.sharedState.bookmarkModel->AddFolder( + self.sharedState.tableViewDisplayedRootNode, + self.sharedState.tableViewDisplayedRootNode->child_count(), + folderTitle); + + BookmarkHomeNodeItem* nodeItem = [[BookmarkHomeNodeItem alloc] + initWithType:BookmarkHomeItemTypeBookmark + bookmarkNode:self.sharedState.editingFolderNode]; + [self.sharedState.tableViewModel + addItem:nodeItem + toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks]; + + // Insert the new folder cell at the end of the table. + NSIndexPath* newRowIndexPath = + [self.sharedState.tableViewModel indexPathForItem:nodeItem]; + NSMutableArray* newRowIndexPaths = + [[NSMutableArray alloc] initWithObjects:newRowIndexPath, nil]; + [self.sharedState.tableView beginUpdates]; + [self.sharedState.tableView + insertRowsAtIndexPaths:newRowIndexPaths + withRowAnimation:UITableViewRowAnimationNone]; + [self.sharedState.tableView endUpdates]; + + // Scroll to the end of the table + [self.sharedState.tableView + scrollToRowAtIndexPath:newRowIndexPath + atScrollPosition:UITableViewScrollPositionBottom + animated:YES]; +} + - (BookmarkHomeViewController*)createControllerWithRootFolder: (const bookmarks::BookmarkNode*)folder { BookmarkHomeViewController* controller = @@ -980,6 +1122,71 @@ : BookmarksContextBarDefault]; } +// Row selection of the tableView will be cleared after reloadData. This +// function is used to restore the row selection. It also updates editNodes in +// case some selected nodes are removed. +- (void)restoreRowSelection { + // Create a new editNodes set to check if some selected nodes are removed. + std::set<const bookmarks::BookmarkNode*> newEditNodes; + + // Add selected nodes to editNodes only if they are not removed (still exist + // in the table). + NSArray<TableViewItem*>* items = [self.sharedState.tableViewModel + itemsInSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks]; + for (TableViewItem* item in items) { + BookmarkHomeNodeItem* nodeItem = + base::mac::ObjCCastStrict<BookmarkHomeNodeItem>(item); + const BookmarkNode* node = nodeItem.bookmarkNode; + if (self.sharedState.editNodes.find(node) != + self.sharedState.editNodes.end()) { + newEditNodes.insert(node); + // Reselect the row of this node. + NSIndexPath* itemPath = + [self.sharedState.tableViewModel indexPathForItem:nodeItem]; + [self.sharedState.tableView + selectRowAtIndexPath:itemPath + animated:NO + scrollPosition:UITableViewScrollPositionNone]; + } + } + + // if editNodes is changed, update it and tell BookmarkTableViewDelegate. + if (self.sharedState.editNodes.size() != newEditNodes.size()) { + self.sharedState.editNodes = newEditNodes; + [self bookmarkTableView:self.bookmarksTableView + selectedEditNodes:self.sharedState.editNodes]; + } +} + +- (BOOL)allowsNewFolder { + // When the current root node has been removed remotely (becomes NULL), + // creating new folder is forbidden. + return self.sharedState.tableViewDisplayedRootNode != NULL; +} + +- (CGFloat)contentPosition { + if (self.sharedState.tableViewDisplayedRootNode == + self.sharedState.bookmarkModel->root_node()) { + return 0; + } + // Divided the scroll position by cell height so that it will stay correct in + // case the cell height is changed in future. + return self.sharedState.tableView.contentOffset.y / + [BookmarkHomeSharedState cellHeightPt]; +} + +- (void)setContentPosition:(CGFloat)position { + // The scroll position was divided by the cell height when stored. + [self.sharedState.tableView + setContentOffset:CGPointMake( + 0, + position * [BookmarkHomeSharedState cellHeightPt])]; +} + +- (void)navigateAway { + [self.sharedState.editingFolderCell stopEdit]; +} + // Returns YES if the given node is a url or folder node. - (BOOL)isUrlOrFolder:(const BookmarkNode*)node { return node->type() == BookmarkNode::URL || @@ -1006,6 +1213,21 @@ !self.sharedState.tableViewDisplayedRootNode->empty(); } +- (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector { + // Create a vector of edit nodes in the same order as the nodes in folder. + std::vector<const bookmarks::BookmarkNode*> nodes; + int childCount = self.sharedState.tableViewDisplayedRootNode->child_count(); + for (int i = 0; i < childCount; ++i) { + const BookmarkNode* node = + self.sharedState.tableViewDisplayedRootNode->GetChild(i); + if (self.sharedState.editNodes.find(node) != + self.sharedState.editNodes.end()) { + nodes.push_back(node); + } + } + return nodes; +} + #pragma mark - ContextBarDelegate implementation // Called when the leading button is clicked. @@ -1019,7 +1241,7 @@ switch (self.contextBarState) { case BookmarksContextBarDefault: // New Folder clicked. - [self.bookmarksTableView addNewFolder]; + [self addNewFolder]; break; case BookmarksContextBarBeginSelection: // This must never happen, as the leading button is disabled at this @@ -1139,7 +1361,7 @@ IDS_IOS_BOOKMARK_CONTEXT_BAR_NEW_FOLDER) forButton:ContextBarLeadingButton]; [self.contextBar setButtonVisibility:YES forButton:ContextBarLeadingButton]; - [self.contextBar setButtonEnabled:[self.bookmarksTableView allowsNewFolder] + [self.contextBar setButtonEnabled:[self allowsNewFolder] forButton:ContextBarLeadingButton]; [self.contextBar setButtonStyle:ContextBarButtonStyleDefault forButton:ContextBarLeadingButton]; @@ -1201,7 +1423,7 @@ style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) { std::vector<const BookmarkNode*> nodes = - [weakSelf.bookmarksTableView getEditNodesInVector]; + [weakSelf getEditNodesInVector]; [weakSelf openAllNodes:nodes inIncognito:NO newTab:NO]; }]; @@ -1211,7 +1433,7 @@ style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) { std::vector<const BookmarkNode*> nodes = - [weakSelf.bookmarksTableView getEditNodesInVector]; + [weakSelf getEditNodesInVector]; [weakSelf openAllNodes:nodes inIncognito:YES newTab:NO]; }]; @@ -1348,6 +1570,71 @@ return alert; } +#pragma mark - Favicon Handling + +- (void)updateCellAtIndexPath:(NSIndexPath*)indexPath + withImage:(UIImage*)image + backgroundColor:(UIColor*)backgroundColor + textColor:(UIColor*)textColor + fallbackText:(NSString*)fallbackText { + BookmarkTableCell* cell = + [self.sharedState.tableView cellForRowAtIndexPath:indexPath]; + if (!cell) { + return; + } + + if (image) { + [cell setImage:image]; + } else { + [cell setPlaceholderText:fallbackText + textColor:textColor + backgroundColor:backgroundColor]; + } +} + +- (void)updateCellAtIndexPath:(NSIndexPath*)indexPath + withLargeIconResult:(const favicon_base::LargeIconResult&)result + fallbackText:(NSString*)fallbackText { + UIImage* favIcon = nil; + UIColor* backgroundColor = nil; + UIColor* textColor = nil; + + if (result.bitmap.is_valid()) { + scoped_refptr<base::RefCountedMemory> data = result.bitmap.bitmap_data; + favIcon = [UIImage + imageWithData:[NSData dataWithBytes:data->front() length:data->size()]]; + fallbackText = nil; + // Update the time when the icon was last requested - postpone thus the + // automatic eviction of the favicon from the favicon database. + IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) + ->TouchIconFromGoogleServer(result.bitmap.icon_url); + } else if (result.fallback_icon_style) { + backgroundColor = + skia::UIColorFromSkColor(result.fallback_icon_style->background_color); + textColor = + skia::UIColorFromSkColor(result.fallback_icon_style->text_color); + } + + [self updateCellAtIndexPath:indexPath + withImage:favIcon + backgroundColor:backgroundColor + textColor:textColor + fallbackText:fallbackText]; +} + +// Cancels all async loads of favicons. Subclasses should call this method when +// the bookmark model is going through significant changes, then manually call +// loadFaviconAtIndexPath: for everything that needs to be loaded; or +// just reload relevant cells. +- (void)cancelAllFaviconLoads { + _faviconTaskTracker.TryCancelAll(); +} + +- (void)cancelLoadingFaviconAtIndexPath:(NSIndexPath*)indexPath { + _faviconTaskTracker.TryCancel( + _faviconLoadTasks[IntegerPair(indexPath.section, indexPath.item)]); +} + #pragma mark - UIGestureRecognizerDelegate and gesture handling - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer { @@ -1458,12 +1745,6 @@ self.sharedState.tableView.scrollIndicatorInsets = contentInsets; } -#pragma mark - SigninPresenter - -- (void)showSignin:(ShowSigninCommand*)command { - [self.dispatcher showSignin:command baseViewController:self]; -} - #pragma mark - BookmarkHomeSharedStateObserver - (void)sharedStateDidClearEditNodes:(BookmarkHomeSharedState*)sharedState { @@ -1542,11 +1823,10 @@ } // Cancel previous load attempts. - [self.bookmarksTableView cancelLoadingFaviconAtIndexPath:indexPath]; + [self cancelLoadingFaviconAtIndexPath:indexPath]; // Load the favicon from cache. If not found, try fetching it from a Google // Server. - [self.bookmarksTableView loadFaviconAtIndexPath:indexPath - continueToGoogleServer:YES]; + [self loadFaviconAtIndexPath:indexPath continueToGoogleServer:YES]; } return cell;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h index f267306..ec415b3a 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.h
@@ -8,14 +8,9 @@ #import <UIKit/UIKit.h> #include <set> -#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_promo_item.h" - @class BookmarkHomeSharedState; @class BookmarkTableView; class GURL; -@protocol SigninPresenter; -@class SigninPromoViewConfigurator; -@class SigninPromoViewMediator; namespace bookmarks { class BookmarkNode; @@ -26,11 +21,7 @@ } // Delegate to handle actions on the table. -@protocol BookmarkTableViewDelegate<BookmarkHomePromoItemDelegate> - -// Returns the SigninPromoViewMediator to use for the sign-in promo view in the -// bookmark table view. -@property(nonatomic, readonly) SigninPromoViewMediator* signinPromoViewMediator; +@protocol BookmarkTableViewDelegate // Tells the delegate that a URL was selected for navigation. - (void)bookmarkTableView:(BookmarkTableView*)view @@ -45,9 +36,6 @@ selectedNodesForDeletion: (const std::set<const bookmarks::BookmarkNode*>&)nodes; -// Returns true if a bookmarks promo cell should be shown. -- (BOOL)bookmarkTableViewShouldShowPromoCell:(BookmarkTableView*)view; - // Tells the delegate that nodes were selected in edit mode. - (void)bookmarkTableView:(BookmarkTableView*)view selectedEditNodes: @@ -92,42 +80,11 @@ - (instancetype)init NS_UNAVAILABLE; + (instancetype) new NS_UNAVAILABLE; -// Called when something outside the view causes the promo state to change. -- (void)promoStateChangedAnimated:(BOOL)animated; - -// Configures the sign-in promo view using |configurator|, and reloads the table -// view if |identityChanged| is YES. -- (void)configureSigninPromoWithConfigurator: - (SigninPromoViewConfigurator*)configurator - identityChanged:(BOOL)identityChanged; - -// Called when adding a new folder -- (void)addNewFolder; - -// Returns a vector of edit nodes. -- (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector; - -// Returns if current root node allows new folder to be created on it. -- (BOOL)allowsNewFolder; - -// Returns the row position that is visible. -- (CGFloat)contentPosition; - -// Scrolls the table view to the desired row position. -- (void)setContentPosition:(CGFloat)position; - -// Called when back or done button of navigation bar is tapped. -- (void)navigateAway; - -// TODO(crbug.com/840381): Temporarily made public while migrating code -// out of BookmarkTableView. -- (void)loadFaviconAtIndexPath:(NSIndexPath*)indexPath - continueToGoogleServer:(BOOL)continueToGoogleServer; -- (void)cancelLoadingFaviconAtIndexPath:(NSIndexPath*)indexPath; -- (void)cancelAllFaviconLoads; -- (void)restoreRowSelection; +// Methods to show and hide the loading spinner. - (void)showLoadingSpinnerBackground; - (void)hideLoadingSpinnerBackground; + +// Methods to show and hide the "no bookmarks" background. - (void)showEmptyBackground; - (void)hideEmptyBackground;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm index 31c807a65b..f1c71c4 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_table_view.mm
@@ -17,19 +17,13 @@ #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" #include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" -#import "ios/chrome/browser/ui/authentication/signin_promo_view.h" -#import "ios/chrome/browser/ui/authentication/signin_promo_view_configurator.h" -#import "ios/chrome/browser/ui/authentication/signin_promo_view_consumer.h" -#import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_empty_background.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_shared_state.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_node_item.h" -#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_home_promo_item.h" #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_cell.h" -#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_signin_promo_cell.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h" @@ -42,45 +36,9 @@ #error "This file requires ARC support." #endif -namespace { - -// NetworkTrafficAnnotationTag for fetching favicon from a Google server. -const net::NetworkTrafficAnnotationTag kTrafficAnnotation = - net::DefineNetworkTrafficAnnotation("bookmarks_get_large_icon", R"( - semantics { - sender: "Bookmarks" - description: - "Sends a request to a Google server to retrieve the favicon bitmap " - "for a bookmark." - trigger: - "A request can be sent if Chrome does not have a favicon for a " - "bookmark." - data: "Page URL and desired icon size." - destination: GOOGLE_OWNED_SERVICE - } - policy { - cookies_allowed: NO - setting: "This feature cannot be disabled by settings." - policy_exception_justification: "Not implemented." - } - )"); - -} // namespace - using bookmarks::BookmarkNode; -// Used to store a pair of NSIntegers when storing a NSIndexPath in C++ -// collections. -using IntegerPair = std::pair<NSInteger, NSInteger>; - -@interface BookmarkTableView () { - // Map of favicon load tasks for each index path. Used to keep track of - // pending favicon load operations so that they can be cancelled upon cell - // reuse. Keys are (section, item) pairs of cell index paths. - std::map<IntegerPair, base::CancelableTaskTracker::TaskId> _faviconLoadTasks; - // Task tracker used for async favicon loads. - base::CancelableTaskTracker _faviconTaskTracker; -} +@interface BookmarkTableView () // State used by this table view. @property(nonatomic, strong) BookmarkHomeSharedState* sharedState; @@ -119,9 +77,6 @@ DCHECK_EQ(self.sharedState.bookmarkModel, ios::BookmarkModelFactory::GetForBrowserState(browserState)); - // Set promo state before the tableview is created. - [self promoStateChangedAnimated:NO]; - // Create and setup tableview. self.sharedState.tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain]; @@ -135,228 +90,8 @@ return self; } -- (void)dealloc { - _faviconTaskTracker.TryCancelAll(); -} - #pragma mark - Public -- (void)promoStateChangedAnimated:(BOOL)animated { - // We show promo cell only on the root view, that is when showing - // the permanent nodes. - BOOL promoVisible = - ((self.sharedState.tableViewDisplayedRootNode == - self.sharedState.bookmarkModel->root_node()) && - [self.delegate bookmarkTableViewShouldShowPromoCell:self]); - - if (promoVisible == self.sharedState.promoVisible) { - return; - } - self.sharedState.promoVisible = promoVisible; - - SigninPromoViewMediator* mediator = self.delegate.signinPromoViewMediator; - if (self.sharedState.promoVisible) { - DCHECK(![self.sharedState.tableViewModel - hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]); - [self.sharedState.tableViewModel - insertSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo - atIndex:0]; - BookmarkHomePromoItem* item = - [[BookmarkHomePromoItem alloc] initWithType:BookmarkHomeItemTypePromo]; - item.delegate = self.delegate; - [self.sharedState.tableViewModel - addItem:item - toSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo]; - [mediator signinPromoViewVisible]; - } else { - if (![mediator isInvalidClosedOrNeverVisible]) { - // When the sign-in view is closed, the promo state changes, but - // -[SigninPromoViewMediator signinPromoViewHidden] should not be called. - [mediator signinPromoViewHidden]; - } - - DCHECK([self.sharedState.tableViewModel - hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]); - [self.sharedState.tableViewModel - removeSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo]; - } - [self.sharedState.tableView reloadData]; -} - -- (void)configureSigninPromoWithConfigurator: - (SigninPromoViewConfigurator*)configurator - identityChanged:(BOOL)identityChanged { - if (![self.sharedState.tableViewModel - hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]) { - return; - } - - NSIndexPath* indexPath = [self.sharedState.tableViewModel - indexPathForItemType:BookmarkHomeItemTypePromo - sectionIdentifier:BookmarkHomeSectionIdentifierPromo]; - BookmarkTableSigninPromoCell* signinPromoCell = - base::mac::ObjCCast<BookmarkTableSigninPromoCell>( - [self.sharedState.tableView cellForRowAtIndexPath:indexPath]); - if (!signinPromoCell) { - return; - } - // Should always reconfigure the cell size even if it has to be reloaded, - // to make sure it has the right size to compute the cell size. - [configurator configureSigninPromoView:signinPromoCell.signinPromoView]; - if (identityChanged) { - // The section should be reload to update the cell height. - NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:indexPath.section]; - [self.sharedState.tableView reloadSections:indexSet - withRowAnimation:UITableViewRowAnimationNone]; - } -} - -- (void)addNewFolder { - [self.sharedState.editingFolderCell stopEdit]; - if (!self.sharedState.tableViewDisplayedRootNode) { - return; - } - self.sharedState.addingNewFolder = YES; - base::string16 folderTitle = base::SysNSStringToUTF16( - l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_GROUP_DEFAULT_NAME)); - self.sharedState.editingFolderNode = - self.sharedState.bookmarkModel->AddFolder( - self.sharedState.tableViewDisplayedRootNode, - self.sharedState.tableViewDisplayedRootNode->child_count(), - folderTitle); - - BookmarkHomeNodeItem* nodeItem = [[BookmarkHomeNodeItem alloc] - initWithType:BookmarkHomeItemTypeBookmark - bookmarkNode:self.sharedState.editingFolderNode]; - [self.sharedState.tableViewModel - addItem:nodeItem - toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks]; - - // Insert the new folder cell at the end of the table. - NSIndexPath* newRowIndexPath = - [self.sharedState.tableViewModel indexPathForItem:nodeItem]; - NSMutableArray* newRowIndexPaths = - [[NSMutableArray alloc] initWithObjects:newRowIndexPath, nil]; - [self.sharedState.tableView beginUpdates]; - [self.sharedState.tableView - insertRowsAtIndexPaths:newRowIndexPaths - withRowAnimation:UITableViewRowAnimationNone]; - [self.sharedState.tableView endUpdates]; - - // Scroll to the end of the table - [self.sharedState.tableView - scrollToRowAtIndexPath:newRowIndexPath - atScrollPosition:UITableViewScrollPositionBottom - animated:YES]; -} - -- (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector { - // Create a vector of edit nodes in the same order as the nodes in folder. - std::vector<const bookmarks::BookmarkNode*> nodes; - int childCount = self.sharedState.tableViewDisplayedRootNode->child_count(); - for (int i = 0; i < childCount; ++i) { - const BookmarkNode* node = - self.sharedState.tableViewDisplayedRootNode->GetChild(i); - if (self.sharedState.editNodes.find(node) != - self.sharedState.editNodes.end()) { - nodes.push_back(node); - } - } - return nodes; -} - -- (BOOL)allowsNewFolder { - // When the current root node has been removed remotely (becomes NULL), - // creating new folder is forbidden. - return self.sharedState.tableViewDisplayedRootNode != NULL; -} - -- (CGFloat)contentPosition { - if (self.sharedState.tableViewDisplayedRootNode == - self.sharedState.bookmarkModel->root_node()) { - return 0; - } - // Divided the scroll position by cell height so that it will stay correct in - // case the cell height is changed in future. - return self.sharedState.tableView.contentOffset.y / - [BookmarkHomeSharedState cellHeightPt]; -} - -- (void)setContentPosition:(CGFloat)position { - // The scroll position was divided by the cell height when stored. - [self.sharedState.tableView - setContentOffset:CGPointMake( - 0, - position * [BookmarkHomeSharedState cellHeightPt])]; -} - -- (void)navigateAway { - [self.sharedState.editingFolderCell stopEdit]; -} - -#pragma mark - UIView - -- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { - [super traitCollectionDidChange:previousTraitCollection]; - // Stop edit of current bookmark folder name, if any. - [self.sharedState.editingFolderCell stopEdit]; -} - -// Row selection of the tableView will be cleared after reloadData. This -// function is used to restore the row selection. It also updates editNodes in -// case some selected nodes are removed. -- (void)restoreRowSelection { - // Create a new editNodes set to check if some selected nodes are removed. - std::set<const bookmarks::BookmarkNode*> newEditNodes; - - // Add selected nodes to editNodes only if they are not removed (still exist - // in the table). - NSArray<TableViewItem*>* items = [self.sharedState.tableViewModel - itemsInSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks]; - for (TableViewItem* item in items) { - BookmarkHomeNodeItem* nodeItem = - base::mac::ObjCCastStrict<BookmarkHomeNodeItem>(item); - const BookmarkNode* node = nodeItem.bookmarkNode; - if (self.sharedState.editNodes.find(node) != - self.sharedState.editNodes.end()) { - newEditNodes.insert(node); - // Reselect the row of this node. - NSIndexPath* itemPath = - [self.sharedState.tableViewModel indexPathForItem:nodeItem]; - [self.sharedState.tableView - selectRowAtIndexPath:itemPath - animated:NO - scrollPosition:UITableViewScrollPositionNone]; - } - } - - // if editNodes is changed, update it and tell BookmarkTableViewDelegate. - if (self.sharedState.editNodes.size() != newEditNodes.size()) { - self.sharedState.editNodes = newEditNodes; - [self.delegate bookmarkTableView:self - selectedEditNodes:self.sharedState.editNodes]; - } -} - -- (BOOL)shouldShowPromoCell { - return self.sharedState.promoVisible; -} - -// Returns the bookmark node associated with |indexPath|. -- (const BookmarkNode*)nodeAtIndexPath:(NSIndexPath*)indexPath { - TableViewItem* item = - [self.sharedState.tableViewModel itemAtIndexPath:indexPath]; - - if (item.type == BookmarkHomeItemTypeBookmark) { - BookmarkHomeNodeItem* nodeItem = - base::mac::ObjCCastStrict<BookmarkHomeNodeItem>(item); - return nodeItem.bookmarkNode; - } - - NOTREACHED(); - return nullptr; -} - // Shows loading spinner background view. - (void)showLoadingSpinnerBackground { if (!self.spinnerView) { @@ -403,148 +138,4 @@ self.sharedState.tableView.backgroundView = nil; } -- (void)updateCellAtIndexPath:(NSIndexPath*)indexPath - withImage:(UIImage*)image - backgroundColor:(UIColor*)backgroundColor - textColor:(UIColor*)textColor - fallbackText:(NSString*)fallbackText { - BookmarkTableCell* cell = - [self.sharedState.tableView cellForRowAtIndexPath:indexPath]; - if (!cell) { - return; - } - - if (image) { - [cell setImage:image]; - } else { - [cell setPlaceholderText:fallbackText - textColor:textColor - backgroundColor:backgroundColor]; - } -} - -- (void)updateCellAtIndexPath:(NSIndexPath*)indexPath - withLargeIconResult:(const favicon_base::LargeIconResult&)result - fallbackText:(NSString*)fallbackText { - UIImage* favIcon = nil; - UIColor* backgroundColor = nil; - UIColor* textColor = nil; - - if (result.bitmap.is_valid()) { - scoped_refptr<base::RefCountedMemory> data = result.bitmap.bitmap_data; - favIcon = [UIImage - imageWithData:[NSData dataWithBytes:data->front() length:data->size()]]; - fallbackText = nil; - // Update the time when the icon was last requested - postpone thus the - // automatic eviction of the favicon from the favicon database. - IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) - ->TouchIconFromGoogleServer(result.bitmap.icon_url); - } else if (result.fallback_icon_style) { - backgroundColor = - skia::UIColorFromSkColor(result.fallback_icon_style->background_color); - textColor = - skia::UIColorFromSkColor(result.fallback_icon_style->text_color); - } - - [self updateCellAtIndexPath:indexPath - withImage:favIcon - backgroundColor:backgroundColor - textColor:textColor - fallbackText:fallbackText]; -} - -// Cancels all async loads of favicons. Subclasses should call this method when -// the bookmark model is going through significant changes, then manually call -// loadFaviconAtIndexPath: for everything that needs to be loaded; or -// just reload relevant cells. -- (void)cancelAllFaviconLoads { - _faviconTaskTracker.TryCancelAll(); -} - -- (void)cancelLoadingFaviconAtIndexPath:(NSIndexPath*)indexPath { - _faviconTaskTracker.TryCancel( - _faviconLoadTasks[IntegerPair(indexPath.section, indexPath.item)]); -} - -// Asynchronously loads favicon for given index path. The loads are cancelled -// upon cell reuse automatically. When the favicon is not found in cache, try -// loading it from a Google server if |continueToGoogleServer| is YES, -// otherwise, use the fall back icon style. -- (void)loadFaviconAtIndexPath:(NSIndexPath*)indexPath - continueToGoogleServer:(BOOL)continueToGoogleServer { - const bookmarks::BookmarkNode* node = [self nodeAtIndexPath:indexPath]; - if (node->is_folder()) { - return; - } - - CGFloat scale = [UIScreen mainScreen].scale; - CGFloat desiredFaviconSizeInPixel = - scale * [BookmarkHomeSharedState desiredFaviconSizePt]; - CGFloat minFaviconSizeInPixel = - scale * [BookmarkHomeSharedState minFaviconSizePt]; - - // Start loading a favicon. - __weak BookmarkTableView* weakSelf = self; - GURL blockURL(node->url()); - NSString* fallbackText = - base::SysUTF16ToNSString(favicon::GetFallbackIconText(blockURL)); - void (^faviconLoadedFromCacheBlock)(const favicon_base::LargeIconResult&) = ^( - const favicon_base::LargeIconResult& result) { - BookmarkTableView* strongSelf = weakSelf; - if (!strongSelf) { - return; - } - // TODO(crbug.com/697329) When fetching icon from server to replace existing - // cache is allowed, fetch icon from server here when cached icon is smaller - // than the desired size. - if (!result.bitmap.is_valid() && continueToGoogleServer && - strongSelf.sharedState.faviconDownloadCount < - [BookmarkHomeSharedState maxDownloadFaviconCount]) { - void (^faviconLoadedFromServerBlock)( - favicon_base::GoogleFaviconServerRequestStatus status) = - ^(const favicon_base::GoogleFaviconServerRequestStatus status) { - if (status == - favicon_base::GoogleFaviconServerRequestStatus::SUCCESS) { - BookmarkTableView* strongSelf = weakSelf; - // GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache - // is not cancellable. So need to check if node has been changed - // before proceeding to favicon update. - if (!strongSelf || - [strongSelf nodeAtIndexPath:indexPath] != node) { - return; - } - // Favicon should be ready in cache now. Fetch it again. - [strongSelf loadFaviconAtIndexPath:indexPath - continueToGoogleServer:NO]; - } - }; // faviconLoadedFromServerBlock - - strongSelf.sharedState.faviconDownloadCount++; - IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) - ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( - favicon::FaviconServerFetcherParams::CreateForMobile( - node->url(), minFaviconSizeInPixel, - desiredFaviconSizeInPixel), - /*may_page_url_be_private=*/true, kTrafficAnnotation, - base::BindBlockArc(faviconLoadedFromServerBlock)); - } - [strongSelf updateCellAtIndexPath:indexPath - withLargeIconResult:result - fallbackText:fallbackText]; - }; // faviconLoadedFromCacheBlock - - base::CancelableTaskTracker::TaskId taskId = - IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) - ->GetLargeIconOrFallbackStyle( - node->url(), minFaviconSizeInPixel, desiredFaviconSizeInPixel, - base::BindBlockArc(faviconLoadedFromCacheBlock), - &_faviconTaskTracker); - _faviconLoadTasks[IntegerPair(indexPath.section, indexPath.item)] = taskId; -} - -- (BOOL)isUrlOrFolder:(const BookmarkNode*)node { - return node->type() == BookmarkNode::URL || - node->type() == BookmarkNode::FOLDER; -} - @end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h b/ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h new file mode 100644 index 0000000..4750ad6 --- /dev/null +++ b/ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UI_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UI_CONSTANTS_H_ + +#import <Foundation/Foundation.h> + +// Accessibility identifier of the BookmarkEditVC toolbar delete button. +extern NSString* const kBookmarkEditDeleteButtonIdentifier; +// Accessibility identifier of the BookmarkFolderEditorVC toolbar delete button. +extern NSString* const kBookmarkFolderEditorDeleteButtonIdentifier; + +#endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UI_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.mm b/ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.mm new file mode 100644 index 0000000..13453c41 --- /dev/null +++ b/ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.mm
@@ -0,0 +1,14 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +NSString* const kBookmarkEditDeleteButtonIdentifier = + @"kBookmarkEditDeleteButtonIdentifier"; +NSString* const kBookmarkFolderEditorDeleteButtonIdentifier = + @"kBookmarkFolderEditorDeleteButtonIdentifier";
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index cb116ca..4e5796e 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -21,6 +21,7 @@ #import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h" +#import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/legacy/toolbar_controller_constants.h" @@ -215,7 +216,8 @@ // Clear the bookmark via the UI. [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(kStarLitLabel)] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Delete_action")] + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + kBookmarkEditDeleteButtonIdentifier)] performAction:grey_tap()]; // Verify the bookmark is not in the BookmarkModel. @@ -1654,7 +1656,9 @@ [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Editor")] assertWithMatcher:grey_notNil()]; - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Delete Folder")] + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID( + kBookmarkFolderEditorDeleteButtonIdentifier)] performAction:grey_tap()]; // Wait for Undo toast to go away from screen. @@ -2068,7 +2072,9 @@ performAction:grey_tap()]; // Delete it. - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Delete Folder")] + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID( + kBookmarkFolderEditorDeleteButtonIdentifier)] performAction:grey_tap()]; // Wait until it's gone.
diff --git a/ios/chrome/browser/ui/bookmarks/cells/BUILD.gn b/ios/chrome/browser/ui/bookmarks/cells/BUILD.gn index 4a7bb6c0..24ea2ba9 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/BUILD.gn +++ b/ios/chrome/browser/ui/bookmarks/cells/BUILD.gn
@@ -18,10 +18,6 @@ "bookmark_table_signin_promo_cell.mm", "bookmark_text_field_item.h", "bookmark_text_field_item.mm", - "legacy_bookmark_parent_folder_item.h", - "legacy_bookmark_parent_folder_item.mm", - "legacy_bookmark_text_field_item.h", - "legacy_bookmark_text_field_item.mm", ] deps = [ @@ -31,7 +27,6 @@ "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/authentication:authentication_ui", - "//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/icons", "//ios/chrome/browser/ui/table_view:styler",
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.h b/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.h index 2911634..f148073 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.h +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.h
@@ -17,8 +17,8 @@ @end -// Cell class associated to BookmarkParentFolderItem. -@interface BookmarkParentFolderCell : UITableViewCell +// Legacy Cell class associated to BookmarkParentFolderItem. +@interface LegacyBookmarkParentFolderCell : UITableViewCell // Label that displays the item's title. @property(nonatomic, readonly, strong) UILabel* parentFolderNameLabel;
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.mm b/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.mm index da67b89..793f81b 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.mm +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item.mm
@@ -24,7 +24,7 @@ self = [super initWithType:type]; if (self) { self.accessibilityIdentifier = @"Change Folder"; - self.cellClass = [BookmarkParentFolderCell class]; + self.cellClass = [LegacyBookmarkParentFolderCell class]; } return self; } @@ -34,19 +34,19 @@ - (void)configureCell:(UITableViewCell*)tableCell withStyler:(ChromeTableViewStyler*)styler { [super configureCell:tableCell withStyler:styler]; - BookmarkParentFolderCell* cell = - base::mac::ObjCCastStrict<BookmarkParentFolderCell>(tableCell); + LegacyBookmarkParentFolderCell* cell = + base::mac::ObjCCastStrict<LegacyBookmarkParentFolderCell>(tableCell); cell.parentFolderNameLabel.text = self.title; } @end -@interface BookmarkParentFolderCell () +@interface LegacyBookmarkParentFolderCell () @property(nonatomic, readwrite, strong) UILabel* parentFolderNameLabel; @property(nonatomic, strong) UILabel* decorationLabel; @end -@implementation BookmarkParentFolderCell +@implementation LegacyBookmarkParentFolderCell @synthesize parentFolderNameLabel = _parentFolderNameLabel; @synthesize decorationLabel = _decorationLabel;
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item_unittest.mm b/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item_unittest.mm index 55d823c..a34862f 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_parent_folder_item_unittest.mm
@@ -21,8 +21,8 @@ TEST_F(BookmarkParentFolderItemTest, LabelGetsTitle) { BookmarkParentFolderItem* item = [[BookmarkParentFolderItem alloc] initWithType:0]; - BookmarkParentFolderCell* cell = - [[BookmarkParentFolderCell alloc] initWithFrame:CGRectZero]; + LegacyBookmarkParentFolderCell* cell = + [[LegacyBookmarkParentFolderCell alloc] initWithFrame:CGRectZero]; ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; item.title = @"Foo";
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h index 51fd641..2122d93 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h
@@ -34,7 +34,7 @@ @end -@interface BookmarkTextFieldCell : UITableViewCell +@interface LegacyBookmarkTextFieldCell : UITableViewCell // Text field to display the title or the URL of the bookmark node. @property(nonatomic, readonly, strong) UITextField<TextFieldStyling>* textField;
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm index e7364e49..e7540e7 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm
@@ -23,7 +23,7 @@ - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; if (self) { - self.cellClass = [BookmarkTextFieldCell class]; + self.cellClass = [LegacyBookmarkTextFieldCell class]; } return self; } @@ -34,8 +34,8 @@ withStyler:(ChromeTableViewStyler*)styler { [super configureCell:tableCell withStyler:styler]; - BookmarkTextFieldCell* cell = - base::mac::ObjCCastStrict<BookmarkTextFieldCell>(tableCell); + LegacyBookmarkTextFieldCell* cell = + base::mac::ObjCCastStrict<LegacyBookmarkTextFieldCell>(tableCell); cell.textField.text = self.text; cell.textField.placeholder = self.placeholder; cell.textField.tag = self.type; @@ -58,12 +58,12 @@ @end -@interface BookmarkTextFieldCell () +@interface LegacyBookmarkTextFieldCell () @property(nonatomic, readwrite, strong) UITextField<TextFieldStyling>* textField; @end -@implementation BookmarkTextFieldCell +@implementation LegacyBookmarkTextFieldCell @synthesize textField = _textField;
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item_unittest.mm b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item_unittest.mm index eebf1ed1..a11a219 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item_unittest.mm
@@ -20,8 +20,8 @@ TEST_F(BookmarkTextFieldItemTest, DelegateGetsTextFieldEvents) { BookmarkTextFieldItem* item = [[BookmarkTextFieldItem alloc] initWithType:0]; - BookmarkTextFieldCell* cell = - [[BookmarkTextFieldCell alloc] initWithFrame:CGRectZero]; + LegacyBookmarkTextFieldCell* cell = + [[LegacyBookmarkTextFieldCell alloc] initWithFrame:CGRectZero]; id mockDelegate = [OCMockObject mockForProtocol:@protocol(BookmarkTextFieldItemDelegate)]; ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; @@ -36,8 +36,8 @@ TEST_F(BookmarkTextFieldItemTest, TextFieldGetsText) { BookmarkTextFieldItem* item = [[BookmarkTextFieldItem alloc] initWithType:0]; - BookmarkTextFieldCell* cell = - [[BookmarkTextFieldCell alloc] initWithFrame:CGRectZero]; + LegacyBookmarkTextFieldCell* cell = + [[LegacyBookmarkTextFieldCell alloc] initWithFrame:CGRectZero]; ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; item.text = @"Foo";
diff --git a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.h b/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.h deleted file mode 100644 index 0d36c90..0000000 --- a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_CELLS_LEGACY_BOOKMARK_PARENT_FOLDER_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_BOOKMARKS_CELLS_LEGACY_BOOKMARK_PARENT_FOLDER_ITEM_H_ - -#import <UIKit/UIKit.h> - -#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" -#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" - -// Item to display the name of the parent folder of a bookmark node. -@interface LegacyBookmarkParentFolderItem : CollectionViewItem - -// The title of the bookmark folder it represents. -@property(nonatomic, copy) NSString* title; - -@end - -// Cell class associated to LegacyBookmarkParentFolderItem. -@interface LegacyBookmarkParentFolderCell : MDCCollectionViewCell - -// Label that displays the item's title. -@property(nonatomic, readonly, strong) UILabel* parentFolderNameLabel; - -@end - -#endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_CELLS_LEGACY_BOOKMARK_PARENT_FOLDER_ITEM_H_
diff --git a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.mm b/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.mm deleted file mode 100644 index 76e1f6c5..0000000 --- a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.mm +++ /dev/null
@@ -1,124 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_parent_folder_item.h" - -#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" -#import "ios/chrome/browser/ui/icons/chrome_icon.h" -#import "ios/chrome/browser/ui/uikit_ui_util.h" -#include "ios/chrome/grit/ios_strings.h" -#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" -#include "ui/base/l10n/l10n_util_mac.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface LegacyBookmarkParentFolderCell () -@property(nonatomic, readwrite, strong) UILabel* parentFolderNameLabel; -@property(nonatomic, strong) UILabel* decorationLabel; -@end - -@implementation LegacyBookmarkParentFolderItem - -@synthesize title = _title; - -- (instancetype)initWithType:(NSInteger)type { - self = [super initWithType:type]; - if (self) { - self.accessibilityIdentifier = @"Change Folder"; - self.cellClass = [LegacyBookmarkParentFolderCell class]; - } - return self; -} - -#pragma mark CollectionViewItem - -- (void)configureCell:(LegacyBookmarkParentFolderCell*)cell { - [super configureCell:cell]; - cell.parentFolderNameLabel.text = self.title; -} - -@end - -@implementation LegacyBookmarkParentFolderCell - -@synthesize parentFolderNameLabel = _parentFolderNameLabel; -@synthesize decorationLabel = _decorationLabel; - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (!self) - return nil; - - self.isAccessibilityElement = YES; - self.accessibilityTraits |= UIAccessibilityTraitButton; - - const CGFloat kHorizontalPadding = 15; - const CGFloat kVerticalPadding = 8; - const CGFloat kParentFolderLabelTopPadding = 7; - - _decorationLabel = [[UILabel alloc] init]; - _decorationLabel.translatesAutoresizingMaskIntoConstraints = NO; - _decorationLabel.text = l10n_util::GetNSString(IDS_IOS_BOOKMARK_GROUP_BUTTON); - _decorationLabel.font = [[MDCTypography fontLoader] regularFontOfSize:12]; - _decorationLabel.textColor = bookmark_utils_ios::lightTextColor(); - [self.contentView addSubview:_decorationLabel]; - - _parentFolderNameLabel = [[UILabel alloc] init]; - _parentFolderNameLabel.translatesAutoresizingMaskIntoConstraints = NO; - _parentFolderNameLabel.font = - [[MDCTypography fontLoader] regularFontOfSize:16]; - _parentFolderNameLabel.textColor = - [UIColor colorWithWhite:33.0 / 255.0 alpha:1.0]; - _parentFolderNameLabel.textAlignment = NSTextAlignmentNatural; - [self.contentView addSubview:_parentFolderNameLabel]; - - UIImageView* navigationChevronImage = [[UIImageView alloc] init]; - UIImage* image = TintImage([ChromeIcon chevronIcon], [UIColor grayColor]); - navigationChevronImage.image = image; - navigationChevronImage.translatesAutoresizingMaskIntoConstraints = NO; - [self.contentView addSubview:navigationChevronImage]; - - // Set up the constraints. - [NSLayoutConstraint activateConstraints:@[ - [_decorationLabel.topAnchor constraintEqualToAnchor:self.topAnchor - constant:kVerticalPadding], - [_decorationLabel.leadingAnchor constraintEqualToAnchor:self.leadingAnchor - constant:kHorizontalPadding], - [_parentFolderNameLabel.topAnchor - constraintEqualToAnchor:_decorationLabel.bottomAnchor - constant:kParentFolderLabelTopPadding], - [_parentFolderNameLabel.leadingAnchor - constraintEqualToAnchor:_decorationLabel.leadingAnchor], - [navigationChevronImage.centerYAnchor - constraintEqualToAnchor:_parentFolderNameLabel.centerYAnchor], - [navigationChevronImage.leadingAnchor - constraintEqualToAnchor:_parentFolderNameLabel.trailingAnchor], - [navigationChevronImage.widthAnchor - constraintEqualToConstant:navigationChevronImage.image.size.width], - [navigationChevronImage.trailingAnchor - constraintEqualToAnchor:self.trailingAnchor - constant:-kHorizontalPadding], - ]]; - - self.shouldHideSeparator = YES; - return self; -} - -- (void)prepareForReuse { - [super prepareForReuse]; - self.parentFolderNameLabel.text = nil; -} - -- (NSString*)accessibilityLabel { - return self.parentFolderNameLabel.text; -} - -- (NSString*)accessibilityHint { - return l10n_util::GetNSString( - IDS_IOS_BOOKMARK_EDIT_PARENT_FOLDER_BUTTON_HINT); -} - -@end
diff --git a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.h b/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.h deleted file mode 100644 index b2fc511..0000000 --- a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_CELLS_LEGACY_BOOKMARK_TEXT_FIELD_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_BOOKMARKS_CELLS_LEGACY_BOOKMARK_TEXT_FIELD_ITEM_H_ - -#import <UIKit/UIKit.h> - -#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" -#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" - -@class LegacyBookmarkTextFieldItem; -@protocol TextFieldStyling; - -// Delegates the cell's text field's events. -@protocol LegacyBookmarkTextFieldItemDelegate<UITextFieldDelegate> - -// Called when the |text| of the item was changed via the textfield. The item's -// |text| is up-to-date when this is called. -- (void)textDidChangeForItem:(LegacyBookmarkTextFieldItem*)item; - -@end - -@interface LegacyBookmarkTextFieldItem : CollectionViewItem - -// The text field content. -@property(nonatomic, copy) NSString* text; - -// The text field placeholder. -@property(nonatomic, copy) NSString* placeholder; - -// Receives the text field events. -@property(nonatomic, weak) id<LegacyBookmarkTextFieldItemDelegate> delegate; - -@end - -@interface LegacyBookmarkTextFieldCell : MDCCollectionViewCell - -// Text field to display the title or the URL of the bookmark node. -@property(nonatomic, readonly, strong) UITextField<TextFieldStyling>* textField; - -@end - -#endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_CELLS_LEGACY_BOOKMARK_TEXT_FIELD_ITEM_H_
diff --git a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.mm b/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.mm deleted file mode 100644 index b6acb9b..0000000 --- a/ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.mm +++ /dev/null
@@ -1,103 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/bookmarks/cells/legacy_bookmark_text_field_item.h" - -#include "base/logging.h" -#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" -#import "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#import "ios/public/provider/chrome/browser/ui/text_field_styling.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface LegacyBookmarkTextFieldCell () -@property(nonatomic, readwrite, strong) - UITextField<TextFieldStyling>* textField; -@end - -@implementation LegacyBookmarkTextFieldItem - -@synthesize text = _text; -@synthesize placeholder = _placeholder; -@synthesize delegate = _delegate; - -- (instancetype)initWithType:(NSInteger)type { - self = [super initWithType:type]; - if (self) { - self.cellClass = [LegacyBookmarkTextFieldCell class]; - } - return self; -} - -#pragma mark CollectionViewItem - -- (void)configureCell:(LegacyBookmarkTextFieldCell*)cell { - [super configureCell:cell]; - cell.textField.text = self.text; - cell.textField.placeholder = self.placeholder; - cell.textField.tag = self.type; - [cell.textField addTarget:self - action:@selector(textFieldDidChange:) - forControlEvents:UIControlEventEditingChanged]; - cell.textField.delegate = self.delegate; - cell.textField.accessibilityLabel = self.text; - cell.textField.accessibilityIdentifier = - [NSString stringWithFormat:@"%@_textField", self.accessibilityIdentifier]; -} - -#pragma mark UIControlEventEditingChanged - -- (void)textFieldDidChange:(UITextField*)textField { - DCHECK_EQ(textField.tag, self.type); - self.text = textField.text; - [self.delegate textDidChangeForItem:self]; -} - -@end - -@implementation LegacyBookmarkTextFieldCell - -@synthesize textField = _textField; - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - _textField = - ios::GetChromeBrowserProvider()->CreateStyledTextField(CGRectZero); - _textField.translatesAutoresizingMaskIntoConstraints = NO; - _textField.textColor = bookmark_utils_ios::darkTextColor(); - _textField.clearButtonMode = UITextFieldViewModeWhileEditing; - _textField.placeholderStyle = - TextFieldStylingPlaceholderFloatingPlaceholder; - [self.contentView addSubview:_textField]; - const CGFloat kHorizontalPadding = 15; - const CGFloat kTopPadding = 8; - [NSLayoutConstraint activateConstraints:@[ - [_textField.leadingAnchor constraintEqualToAnchor:self.leadingAnchor - constant:kHorizontalPadding], - [_textField.topAnchor constraintEqualToAnchor:self.topAnchor - constant:kTopPadding], - [_textField.trailingAnchor constraintEqualToAnchor:self.trailingAnchor - constant:-kHorizontalPadding], - ]]; - - self.shouldHideSeparator = YES; - } - return self; -} - -- (void)prepareForReuse { - [super prepareForReuse]; - [self.textField resignFirstResponder]; - [self.textField removeTarget:nil - action:NULL - forControlEvents:UIControlEventAllEvents]; - self.textField.delegate = nil; - self.textField.text = nil; - self.textField.textValidator = nil; -} - -@end
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm index f3fb6ea5..43a18ab 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm
@@ -129,12 +129,12 @@ } void FullscreenWebStateObserver::SetIsLoading(bool loading) { - if (IsUIRefreshPhase1Enabled()) { - if (loading) - controller_->ResetModel(); - } else { - loading_disabler_ = - loading ? std::make_unique<ScopedFullscreenDisabler>(controller_) - : nullptr; - } + if (IsUIRefreshPhase1Enabled()) + return; + + if (!!loading_disabler_.get() == loading) + return; + loading_disabler_ = + loading ? std::make_unique<ScopedFullscreenDisabler>(controller_) + : nullptr; }
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 5adfb43..e7fdd899 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -147,7 +147,7 @@ "//ios/chrome/browser/find_in_page:unit_tests", "//ios/chrome/browser/geolocation:unit_tests", "//ios/chrome/browser/history:unit_tests", - "//ios/chrome/browser/itunes_links:unit_tests", + "//ios/chrome/browser/itunes_urls:unit_tests", "//ios/chrome/browser/language:unit_tests", "//ios/chrome/browser/metrics:unit_tests", "//ios/chrome/browser/metrics:unit_tests_internal",
diff --git a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc index fff8665..85e0fea 100644 --- a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc +++ b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc
@@ -21,6 +21,7 @@ #include "media/base/cdm_key_information.h" #include "media/base/decoder_buffer.h" #include "media/base/decrypt_config.h" +#include "media/base/encryption_pattern.h" #include "media/cdm/api/content_decryption_module_ext.h" #include "media/cdm/json_web_key.h" #include "media/cdm/library_cdm/cdm_host_proxy.h" @@ -95,23 +96,32 @@ output_buffer->set_timestamp( base::TimeDelta::FromMicroseconds(input_buffer.timestamp)); - // TODO(crbug.com/658026): Support other schemes. - if (input_buffer.encryption_scheme == cdm::EncryptionScheme::kCenc) { - DCHECK_GT(input_buffer.iv_size, 0u); - DCHECK_GT(input_buffer.key_id_size, 0u); - std::vector<media::SubsampleEntry> subsamples; - for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) { - subsamples.push_back( - media::SubsampleEntry(input_buffer.subsamples[i].clear_bytes, - input_buffer.subsamples[i].cipher_bytes)); - } + if (input_buffer.encryption_scheme == cdm::EncryptionScheme::kUnencrypted) + return output_buffer; + DCHECK_GT(input_buffer.iv_size, 0u); + DCHECK_GT(input_buffer.key_id_size, 0u); + std::vector<media::SubsampleEntry> subsamples; + for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) { + subsamples.push_back( + media::SubsampleEntry(input_buffer.subsamples[i].clear_bytes, + input_buffer.subsamples[i].cipher_bytes)); + } + + const std::string key_id_string( + reinterpret_cast<const char*>(input_buffer.key_id), + input_buffer.key_id_size); + const std::string iv_string(reinterpret_cast<const char*>(input_buffer.iv), + input_buffer.iv_size); + if (input_buffer.encryption_scheme == cdm::EncryptionScheme::kCenc) { output_buffer->set_decrypt_config(media::DecryptConfig::CreateCencConfig( - std::string(reinterpret_cast<const char*>(input_buffer.key_id), - input_buffer.key_id_size), - std::string(reinterpret_cast<const char*>(input_buffer.iv), - input_buffer.iv_size), - subsamples)); + key_id_string, iv_string, subsamples)); + } else { + DCHECK_EQ(input_buffer.encryption_scheme, cdm::EncryptionScheme::kCbcs); + output_buffer->set_decrypt_config(media::DecryptConfig::CreateCbcsConfig( + key_id_string, iv_string, subsamples, + media::EncryptionPattern(input_buffer.pattern.crypt_byte_block, + input_buffer.pattern.skip_byte_block))); } return output_buffer; @@ -362,36 +372,6 @@ namespace { -bool IsSupportedConfigEncryptionScheme(cdm::EncryptionScheme scheme) { - // TODO(crbug.com/658026): Support other decryption schemes. - switch (scheme) { - case cdm::EncryptionScheme::kUnencrypted: - case cdm::EncryptionScheme::kCenc: - return true; - case cdm::EncryptionScheme::kCbcs: - return false; - } - - NOTREACHED(); - return false; -} - -bool IsSupportedBufferEncryptionScheme(cdm::EncryptionScheme scheme, - cdm::Pattern pattern) { - // TODO(crbug.com/658026): Support other decryption schemes. - switch (scheme) { - case cdm::EncryptionScheme::kUnencrypted: - return true; - case cdm::EncryptionScheme::kCenc: - return pattern.crypt_byte_block == 0 && pattern.skip_byte_block == 0; - case cdm::EncryptionScheme::kCbcs: - return false; - } - - NOTREACHED(); - return false; -} - cdm::InputBuffer_2 ToInputBuffer_2(cdm::InputBuffer_1 encrypted_buffer) { cdm::InputBuffer_2 buffer = {}; buffer.data = encrypted_buffer.data; @@ -707,11 +687,6 @@ if (key_system_ == kExternalClearKeyDecryptOnlyKeySystem) return cdm::kInitializationError; - if (!IsSupportedConfigEncryptionScheme( - audio_decoder_config.encryption_scheme)) { - return cdm::kInitializationError; - } - #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) if (!audio_decoder_) audio_decoder_.reset( @@ -744,11 +719,6 @@ if (key_system_ == kExternalClearKeyDecryptOnlyKeySystem) return cdm::kInitializationError; - if (!IsSupportedConfigEncryptionScheme( - video_decoder_config.encryption_scheme)) { - return cdm::kInitializationError; - } - if (video_decoder_ && video_decoder_->is_initialized()) { DCHECK(!video_decoder_->is_initialized()); return cdm::kInitializationError; @@ -894,11 +864,6 @@ scoped_refptr<DecoderBuffer>* decrypted_buffer) { DCHECK(decrypted_buffer); - if (!IsSupportedBufferEncryptionScheme(encrypted_buffer.encryption_scheme, - encrypted_buffer.pattern)) { - return cdm::kDecryptError; - } - scoped_refptr<DecoderBuffer> buffer = CopyDecoderBufferFrom(encrypted_buffer); // EOS and unencrypted streams can be returned as-is.
diff --git a/mojo/public/cpp/bindings/interface_ptr_set.h b/mojo/public/cpp/bindings/interface_ptr_set.h index 185cbff..17f90b1 100644 --- a/mojo/public/cpp/bindings/interface_ptr_set.h +++ b/mojo/public/cpp/bindings/interface_ptr_set.h
@@ -77,8 +77,10 @@ if (it == ptrs_.end()) return Ptr<Interface>(); Ptr<Interface> ptr; - if (it->second) + if (it->second) { ptr = it->second->Take(); + delete it->second.get(); + } ptrs_.erase(it); return ptr; }
diff --git a/net/BUILD.gn b/net/BUILD.gn index 14dc74c..5e59e77 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -157,7 +157,6 @@ "cert/asn1_util.h", "cert/cert_database.cc", "cert/cert_database.h", - "cert/cert_database_stub.cc", "cert/cert_status_flags.cc", "cert/cert_status_flags.h", "cert/cert_status_flags_list.h", @@ -513,11 +512,7 @@ "base/winsock_util.h", "cert/caching_cert_verifier.cc", "cert/caching_cert_verifier.h", - "cert/cert_database_android.cc", - "cert/cert_database_ios.cc", "cert/cert_database_mac.cc", - "cert/cert_database_nss.cc", - "cert/cert_database_win.cc", "cert/cert_net_fetcher.cc", "cert/cert_net_fetcher.h", "cert/cert_verify_proc.cc", @@ -1902,10 +1897,7 @@ } if (!is_nacl) { - sources -= [ - "base/network_interfaces_nacl.cc", - "cert/cert_database_stub.cc", - ] + sources -= [ "base/network_interfaces_nacl.cc" ] } # Use getifaddrs() on POSIX platforms, except Linux and Android. @@ -1922,7 +1914,6 @@ if (!use_nss_certs) { sources -= [ - "cert/cert_database_nss.cc", "cert/internal/trust_store_nss.cc", "cert/internal/trust_store_nss.h", "cert/known_roots_nss.cc", @@ -2045,7 +2036,6 @@ sources += [ "base/network_interfaces_fuchsia.cc", "base/platform_mime_util_fuchsia.cc", - "cert/cert_database_fuchsia.cc", "cert/test_root_certs_fuchsia.cc", ] deps += [ "//third_party/fuchsia-sdk:netstack" ]
diff --git a/net/base/address_list_unittest.cc b/net/base/address_list_unittest.cc index 7553463..08326902 100644 --- a/net/base/address_list_unittest.cc +++ b/net/base/address_list_unittest.cc
@@ -4,6 +4,7 @@ #include "net/base/address_list.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/sys_byteorder.h" #include "net/base/ip_address.h" @@ -122,9 +123,9 @@ // Construct a list of ip addresses. IPAddressList ip_list; - for (size_t i = 0; i < arraysize(tests); ++i) { + for (const auto& test : tests) { IPAddress ip_address; - ASSERT_TRUE(ip_address.AssignFromIPLiteral(tests[i].ip_address)); + ASSERT_TRUE(ip_address.AssignFromIPLiteral(test.ip_address)); ip_list.push_back(ip_address); } @@ -132,7 +133,7 @@ kCanonicalName); std::string canonical_name; EXPECT_EQ(kCanonicalName, test_list.canonical_name()); - EXPECT_EQ(arraysize(tests), test_list.size()); + EXPECT_EQ(base::size(tests), test_list.size()); } } // namespace
diff --git a/net/base/chunked_upload_data_stream_unittest.cc b/net/base/chunked_upload_data_stream_unittest.cc index 59d515e1..0b57658 100644 --- a/net/base/chunked_upload_data_stream_unittest.cc +++ b/net/base/chunked_upload_data_stream_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/stl_util.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" @@ -23,9 +24,9 @@ namespace { -const char kTestData[] = "0123456789"; -const size_t kTestDataSize = arraysize(kTestData) - 1; -const size_t kTestBufferSize = 1 << 14; // 16KB. +constexpr char kTestData[] = "0123456789"; +constexpr size_t kTestDataSize = base::size(kTestData) - 1; +constexpr size_t kTestBufferSize = 1 << 14; // 16KB. } // namespace
diff --git a/net/base/data_url.cc b/net/base/data_url.cc index 1676fa6..878b1eb 100644 --- a/net/base/data_url.cc +++ b/net/base/data_url.cc
@@ -52,9 +52,8 @@ ++iter; } - static const char kBase64Tag[] = "base64"; - static const char kCharsetTag[] = "charset="; - const size_t kCharsetTagLength = arraysize(kCharsetTag) - 1; + static constexpr base::StringPiece kBase64Tag("base64"); + static constexpr base::StringPiece kCharsetTag("charset="); bool base64_encoded = false; for (; iter != meta_data.cend(); ++iter) { @@ -63,7 +62,7 @@ } else if (charset->empty() && base::StartsWith(*iter, kCharsetTag, base::CompareCase::SENSITIVE)) { - *charset = std::string(iter->substr(kCharsetTagLength)); + *charset = std::string(iter->substr(kCharsetTag.size())); // The grammar for charset is not specially defined in RFC2045 and // RFC2397. It just needs to be a token. if (!HttpUtil::IsToken(*charset))
diff --git a/net/base/data_url_unittest.cc b/net/base/data_url_unittest.cc index 1b2d036c..2b3669a 100644 --- a/net/base/data_url_unittest.cc +++ b/net/base/data_url_unittest.cc
@@ -233,16 +233,16 @@ // TODO(darin): add more interesting tests }; - for (size_t i = 0; i < arraysize(tests); ++i) { + for (const auto& test : tests) { std::string mime_type; std::string charset; std::string data; - bool ok = DataURL::Parse(GURL(tests[i].url), &mime_type, &charset, &data); - EXPECT_EQ(ok, tests[i].is_valid); - if (tests[i].is_valid) { - EXPECT_EQ(tests[i].mime_type, mime_type); - EXPECT_EQ(tests[i].charset, charset); - EXPECT_EQ(tests[i].data, data); + bool ok = DataURL::Parse(GURL(test.url), &mime_type, &charset, &data); + EXPECT_EQ(ok, test.is_valid); + if (test.is_valid) { + EXPECT_EQ(test.mime_type, mime_type); + EXPECT_EQ(test.charset, charset); + EXPECT_EQ(test.data, data); } } }
diff --git a/net/base/directory_listing_unittest.cc b/net/base/directory_listing_unittest.cc index 4f888c0..2fcbb0e6 100644 --- a/net/base/directory_listing_unittest.cc +++ b/net/base/directory_listing_unittest.cc
@@ -43,11 +43,11 @@ ",0,10000,\"9.8 kB\",0,\"\");</script>\n"}, }; - for (size_t i = 0; i < arraysize(test_cases); ++i) { + for (const auto& test_case : test_cases) { const std::string results = GetDirectoryListingEntry( - base::WideToUTF16(test_cases[i].name), test_cases[i].raw_bytes, - test_cases[i].is_dir, test_cases[i].filesize, test_cases[i].time); - EXPECT_EQ(test_cases[i].expected, results); + base::WideToUTF16(test_case.name), test_case.raw_bytes, + test_case.is_dir, test_case.filesize, test_case.time); + EXPECT_EQ(test_case.expected, results); } }
diff --git a/net/base/elements_upload_data_stream_unittest.cc b/net/base/elements_upload_data_stream_unittest.cc index a967d213..92ff1c6 100644 --- a/net/base/elements_upload_data_stream_unittest.cc +++ b/net/base/elements_upload_data_stream_unittest.cc
@@ -17,6 +17,8 @@ #include "base/location.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" +#include "base/strings/string_piece.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "net/base/io_buffer.h" @@ -45,7 +47,7 @@ namespace { const char kTestData[] = "0123456789"; -const size_t kTestDataSize = arraysize(kTestData) - 1; +const size_t kTestDataSize = base::size(kTestData) - 1; const size_t kTestBufferSize = 1 << 14; // 16KB. // Reads data from the upload data stream, and returns the data as string. @@ -284,7 +286,7 @@ // Run Init(). ASSERT_THAT(stream->Init(CompletionCallback(), NetLogWithSource()), IsOk()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); EXPECT_EQ(0U, stream->position()); EXPECT_FALSE(stream->IsEOF()); @@ -322,7 +324,7 @@ ASSERT_THAT(stream->Init(init_callback.callback(), NetLogWithSource()), IsError(ERR_IO_PENDING)); EXPECT_THAT(init_callback.WaitForResult(), IsOk()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); EXPECT_EQ(0U, stream->position()); EXPECT_FALSE(stream->IsEOF()); @@ -533,9 +535,8 @@ // Consume the third and the fourth elements. TestCompletionCallback read_callback3; - ASSERT_EQ( - ERR_IO_PENDING, - stream->Read(buf.get(), kTestDataSize * 2, read_callback3.callback())); + ASSERT_EQ(ERR_IO_PENDING, stream->Read(buf.get(), kTestDataSize * 2, + read_callback3.callback())); EXPECT_EQ(static_cast<int>(kTestDataSize * 2), read_callback3.WaitForResult()); } @@ -606,7 +607,7 @@ IsError(ERR_IO_PENDING)); ASSERT_THAT(init_callback1.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read. EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); @@ -618,7 +619,7 @@ IsError(ERR_IO_PENDING)); ASSERT_THAT(init_callback2.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read again. EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); @@ -650,7 +651,7 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(test_callback.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read. EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); @@ -661,7 +662,7 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(test_callback.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read again. EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); @@ -694,11 +695,11 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(init_callback1.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read some. TestCompletionCallback read_callback1; - std::vector<char> buf(kTestDataSize + kTestDataSize/2); + std::vector<char> buf(kTestDataSize + kTestDataSize / 2); scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); EXPECT_EQ( ERR_IO_PENDING, @@ -713,11 +714,11 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(init_callback2.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read. TestCompletionCallback read_callback2; - std::vector<char> buf2(kTestDataSize*2); + std::vector<char> buf2(kTestDataSize * 2); scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); EXPECT_EQ(ERR_IO_PENDING, stream->Read( @@ -757,11 +758,11 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(init_callback2.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read. TestCompletionCallback read_callback2; - std::vector<char> buf2(kTestDataSize*2); + std::vector<char> buf2(kTestDataSize * 2); scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); EXPECT_EQ(ERR_IO_PENDING, stream->Read( @@ -800,11 +801,11 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(init_callback1.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Start reading. TestCompletionCallback read_callback1; - std::vector<char> buf(kTestDataSize*2); + std::vector<char> buf(kTestDataSize * 2); scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); EXPECT_EQ( ERR_IO_PENDING, @@ -817,11 +818,11 @@ IsError(ERR_IO_PENDING)); EXPECT_THAT(init_callback2.WaitForResult(), IsOk()); EXPECT_FALSE(stream->IsEOF()); - EXPECT_EQ(kTestDataSize*2, stream->size()); + EXPECT_EQ(kTestDataSize * 2, stream->size()); // Read. TestCompletionCallback read_callback2; - std::vector<char> buf2(kTestDataSize*2); + std::vector<char> buf2(kTestDataSize * 2); scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); EXPECT_EQ(ERR_IO_PENDING, stream->Read(
diff --git a/net/base/escape.cc b/net/base/escape.cc index 7427fb63..35d37c7f 100644 --- a/net/base/escape.cc +++ b/net/base/escape.cc
@@ -5,6 +5,7 @@ #include "net/base/escape.h" #include "base/logging.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversion_utils.h" #include "base/strings/utf_string_conversions.h" @@ -143,7 +144,7 @@ // reach max character length number of bytes, or hit an unescaped // character. No need to check length of escaped_text, as // UnescapeUnsignedByteAtIndex checks lengths. - while (num_bytes < arraysize(bytes) && + while (num_bytes < base::size(bytes) && UnescapeUnsignedByteAtIndex(escaped_text, index + num_bytes * 3, &bytes[num_bytes]) && CBU8_IS_TRAIL(bytes[num_bytes])) { @@ -323,9 +324,9 @@ template <class str> void AppendEscapedCharForHTMLImpl(typename str::value_type c, str* output) { - static const struct { + static constexpr struct { char key; - const char* replacement; + base::StringPiece replacement; } kCharsToEscape[] = { { '<', "<" }, { '>', ">" }, @@ -333,17 +334,14 @@ { '"', """ }, { '\'', "'" }, }; - size_t k; - for (k = 0; k < arraysize(kCharsToEscape); ++k) { - if (c == kCharsToEscape[k].key) { - const char* p = kCharsToEscape[k].replacement; - while (*p) - output->push_back(*p++); - break; + for (const auto& char_to_escape : kCharsToEscape) { + if (c == char_to_escape.key) { + output->append(std::begin(char_to_escape.replacement), + std::end(char_to_escape.replacement)); + return; } } - if (k == arraysize(kCharsToEscape)) - output->push_back(c); + output->push_back(c); } template <class str> @@ -522,14 +520,14 @@ if (input.find(base::ASCIIToUTF16("&")) == std::string::npos) return input.as_string(); - base::string16 ampersand_chars[arraysize(kEscapeToChars)]; + base::string16 ampersand_chars[base::size(kEscapeToChars)]; base::string16 text = input.as_string(); for (base::string16::iterator iter = text.begin(); iter != text.end(); ++iter) { if (*iter == '&') { // Potential ampersand encode char. size_t index = iter - text.begin(); - for (size_t i = 0; i < arraysize(kEscapeToChars); i++) { + for (size_t i = 0; i < base::size(kEscapeToChars); i++) { if (ampersand_chars[i].empty()) { ampersand_chars[i] = base::ASCIIToUTF16(kEscapeToChars[i].ampersand_code);
diff --git a/net/base/escape_unittest.cc b/net/base/escape_unittest.cc index 6a33896..f901c27 100644 --- a/net/base/escape_unittest.cc +++ b/net/base/escape_unittest.cc
@@ -56,9 +56,9 @@ {"foo bar", "foo+bar"}, {"foo++", "foo%2B%2B"} }; - for (size_t i = 0; i < arraysize(escape_cases); ++i) { - EscapeCase value = escape_cases[i]; - EXPECT_EQ(value.output, EscapeQueryParamValue(value.input, true)); + for (const auto& escape_case : escape_cases) { + EXPECT_EQ(escape_case.output, + EscapeQueryParamValue(escape_case.input, true)); } const EscapeCase escape_cases_no_plus[] = { @@ -66,9 +66,9 @@ {"foo bar", "foo%20bar"}, {"foo++", "foo%2B%2B"} }; - for (size_t i = 0; i < arraysize(escape_cases_no_plus); ++i) { - EscapeCase value = escape_cases_no_plus[i]; - EXPECT_EQ(value.output, EscapeQueryParamValue(value.input, false)); + for (const auto& escape_case : escape_cases_no_plus) { + EXPECT_EQ(escape_case.output, + EscapeQueryParamValue(escape_case.input, false)); } // Test all the values in we're supposed to be escaping. @@ -312,19 +312,19 @@ L"%ED%ED"}, // Invalid UTF-8 -> kept unescaped. }; - for (size_t i = 0; i < arraysize(unescape_cases); i++) { - std::string unescaped = UnescapeURLComponent(unescape_cases[i].input, - UnescapeRule::NORMAL); - EXPECT_EQ(std::string(unescape_cases[i].url_unescaped), unescaped); + for (const auto& unescape_case : unescape_cases) { + std::string unescaped = + UnescapeURLComponent(unescape_case.input, UnescapeRule::NORMAL); + EXPECT_EQ(std::string(unescape_case.url_unescaped), unescaped); - unescaped = UnescapeURLComponent(unescape_cases[i].input, + unescaped = UnescapeURLComponent(unescape_case.input, UnescapeRule::REPLACE_PLUS_WITH_SPACE); - EXPECT_EQ(std::string(unescape_cases[i].query_unescaped), unescaped); + EXPECT_EQ(std::string(unescape_case.query_unescaped), unescaped); // TODO: Need to test unescape_spaces and unescape_percent. base::string16 decoded = UnescapeAndDecodeUTF8URLComponent( - unescape_cases[i].input, UnescapeRule::NORMAL); - EXPECT_EQ(base::WideToUTF16(unescape_cases[i].decoded), decoded); + unescape_case.input, UnescapeRule::NORMAL); + EXPECT_EQ(base::WideToUTF16(unescape_case.decoded), decoded); } } @@ -371,15 +371,15 @@ {"%ED%B0%80+%E5%A5%BD", 6, 6}, // not convertable to UTF-8 }; - for (size_t i = 0; i < arraysize(adjust_cases); i++) { - size_t offset = adjust_cases[i].input_offset; + for (const auto& adjust_case : adjust_cases) { + size_t offset = adjust_case.input_offset; base::OffsetAdjuster::Adjustments adjustments; UnescapeAndDecodeUTF8URLComponentWithAdjustments( - adjust_cases[i].input, UnescapeRule::NORMAL, &adjustments); + adjust_case.input, UnescapeRule::NORMAL, &adjustments); base::OffsetAdjuster::AdjustOffset(adjustments, &offset); - EXPECT_EQ(adjust_cases[i].output_offset, offset) - << "input=" << adjust_cases[i].input - << " offset=" << adjust_cases[i].input_offset; + EXPECT_EQ(adjust_case.output_offset, offset) + << "input=" << adjust_case.input + << " offset=" << adjust_case.input_offset; } } @@ -434,9 +434,9 @@ { "<hello>", "<hello>" }, { "don\'t mess with me", "don't mess with me" }, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - std::string result = EscapeForHTML(std::string(tests[i].input)); - EXPECT_EQ(std::string(tests[i].expected_output), result); + for (const auto& test : tests) { + std::string result = EscapeForHTML(std::string(test.input)); + EXPECT_EQ(std::string(test.expected_output), result); } } @@ -454,9 +454,9 @@ { ">", ">" }, { "& &", "& &" }, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - base::string16 result = UnescapeForHTML(base::ASCIIToUTF16(tests[i].input)); - EXPECT_EQ(base::ASCIIToUTF16(tests[i].expected_output), result); + for (const auto& test : tests) { + base::string16 result = UnescapeForHTML(base::ASCIIToUTF16(test.input)); + EXPECT_EQ(base::ASCIIToUTF16(test.expected_output), result); } }
diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc index e393965..98b1ac9 100644 --- a/net/base/file_stream_unittest.cc +++ b/net/base/file_stream_unittest.cc
@@ -14,6 +14,7 @@ #include "base/message_loop/message_loop_current.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/synchronization/waitable_event.h" #include "base/test/test_timeouts.h" @@ -41,8 +42,8 @@ namespace { -const char kTestData[] = "0123456789"; -const int kTestDataSize = arraysize(kTestData) - 1; +constexpr char kTestData[] = "0123456789"; +constexpr int kTestDataSize = base::size(kTestData) - 1; // Creates an IOBufferWithSize that contains the kTestDataSize. IOBufferWithSize* CreateTestDataBuffer() {
diff --git a/net/base/filename_util.cc b/net/base/filename_util.cc index 16341dc..2e3ae10d 100644 --- a/net/base/filename_util.cc +++ b/net/base/filename_util.cc
@@ -170,12 +170,12 @@ std::string filename_lower = base::ToLowerASCII(filename); #endif - for (size_t i = 0; i < arraysize(known_devices); ++i) { + for (const char* const device : known_devices) { // Exact match. - if (filename_lower == known_devices[i]) + if (filename_lower == device) return true; // Starts with "DEVICE.". - if (base::StartsWith(filename_lower, std::string(known_devices[i]) + ".", + if (base::StartsWith(filename_lower, std::string(device) + ".", base::CompareCase::SENSITIVE)) { return true; } @@ -188,8 +188,8 @@ "thumbs.db", }; - for (size_t i = 0; i < arraysize(magic_names); ++i) { - if (filename_lower == magic_names[i]) + for (const char* const magic_name : magic_names) { + if (filename_lower == magic_name) return true; }
diff --git a/net/base/filename_util_unittest.cc b/net/base/filename_util_unittest.cc index f7a4c152..ec25e4c 100644 --- a/net/base/filename_util_unittest.cc +++ b/net/base/filename_util_unittest.cc
@@ -128,49 +128,41 @@ } // namespace TEST(FilenameUtilTest, IsSafePortablePathComponent) { - for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { - EXPECT_TRUE( - IsSafePortablePathComponent(base::FilePath(kSafePortableBasenames[i]))) - << kSafePortableBasenames[i]; + for (auto* basename : kSafePortableBasenames) { + EXPECT_TRUE(IsSafePortablePathComponent(base::FilePath(basename))) + << basename; } - for (size_t i = 0; i < arraysize(kUnsafePortableBasenames); ++i) { - EXPECT_FALSE(IsSafePortablePathComponent( - base::FilePath(kUnsafePortableBasenames[i]))) - << kUnsafePortableBasenames[i]; + for (auto* basename : kUnsafePortableBasenames) { + EXPECT_FALSE(IsSafePortablePathComponent(base::FilePath(basename))) + << basename; } - for (size_t i = 0; i < arraysize(kSafePortableRelativePaths); ++i) { - EXPECT_FALSE(IsSafePortablePathComponent( - base::FilePath(kSafePortableRelativePaths[i]))) - << kSafePortableRelativePaths[i]; + for (auto* path : kSafePortableRelativePaths) { + EXPECT_FALSE(IsSafePortablePathComponent(base::FilePath(path))) << path; } } TEST(FilenameUtilTest, IsSafePortableRelativePath) { base::FilePath safe_dirname(FILE_PATH_LITERAL("a")); - for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { + for (auto* basename : kSafePortableBasenames) { + EXPECT_TRUE(IsSafePortableRelativePath(base::FilePath(basename))) + << basename; + EXPECT_TRUE(IsSafePortableRelativePath( + safe_dirname.Append(base::FilePath(basename)))) + << basename; + } + for (auto* path : kSafePortableRelativePaths) { + EXPECT_TRUE(IsSafePortableRelativePath(base::FilePath(path))) << path; EXPECT_TRUE( - IsSafePortableRelativePath(base::FilePath(kSafePortableBasenames[i]))) - << kSafePortableBasenames[i]; - EXPECT_TRUE(IsSafePortableRelativePath( - safe_dirname.Append(base::FilePath(kSafePortableBasenames[i])))) - << kSafePortableBasenames[i]; + IsSafePortableRelativePath(safe_dirname.Append(base::FilePath(path)))) + << path; } - for (size_t i = 0; i < arraysize(kSafePortableRelativePaths); ++i) { - EXPECT_TRUE(IsSafePortableRelativePath( - base::FilePath(kSafePortableRelativePaths[i]))) - << kSafePortableRelativePaths[i]; - EXPECT_TRUE(IsSafePortableRelativePath( - safe_dirname.Append(base::FilePath(kSafePortableRelativePaths[i])))) - << kSafePortableRelativePaths[i]; - } - for (size_t i = 0; i < arraysize(kUnsafePortableBasenames); ++i) { - EXPECT_FALSE( - IsSafePortableRelativePath(base::FilePath(kUnsafePortableBasenames[i]))) - << kUnsafePortableBasenames[i]; - if (!base::FilePath::StringType(kUnsafePortableBasenames[i]).empty()) { + for (auto* basename : kUnsafePortableBasenames) { + EXPECT_FALSE(IsSafePortableRelativePath(base::FilePath(basename))) + << basename; + if (!base::FilePath::StringType(basename).empty()) { EXPECT_FALSE(IsSafePortableRelativePath( - safe_dirname.Append(base::FilePath(kUnsafePortableBasenames[i])))) - << kUnsafePortableBasenames[i]; + safe_dirname.Append(base::FilePath(basename)))) + << basename; } } } @@ -215,15 +207,14 @@ // First, we'll test that we can round-trip all of the above cases of URLs base::FilePath output; - for (size_t i = 0; i < arraysize(round_trip_cases); i++) { + for (const auto& test_case : round_trip_cases) { // convert to the file URL - GURL file_url( - FilePathToFileURL(WStringAsFilePath(round_trip_cases[i].file))); - EXPECT_EQ(round_trip_cases[i].url, file_url.spec()); + GURL file_url(FilePathToFileURL(WStringAsFilePath(test_case.file))); + EXPECT_EQ(test_case.url, file_url.spec()); // Back to the filename. EXPECT_TRUE(FileURLToFilePath(file_url, &output)); - EXPECT_EQ(round_trip_cases[i].file, FilePathAsWString(output)); + EXPECT_EQ(test_case.file, FilePathAsWString(output)); } // Test that various file: URLs get decoded into the correct file type @@ -266,9 +257,9 @@ // {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, #endif }; - for (size_t i = 0; i < arraysize(url_cases); i++) { - FileURLToFilePath(GURL(url_cases[i].url), &output); - EXPECT_EQ(url_cases[i].file, FilePathAsWString(output)); + for (const auto& test_case : url_cases) { + FileURLToFilePath(GURL(test_case.url), &output); + EXPECT_EQ(test_case.file, FilePathAsWString(output)); } // Unfortunately, UTF8ToWide discards invalid UTF8 input. @@ -698,30 +689,28 @@ #endif }; - for (size_t i = 0; i < arraysize(selection_tests); ++i) - RunGenerateFileNameTestCase(&selection_tests[i]); + for (const auto& selection_test : selection_tests) + RunGenerateFileNameTestCase(&selection_test); - for (size_t i = 0; i < arraysize(generation_tests); ++i) - RunGenerateFileNameTestCase(&generation_tests[i]); + for (const auto& generation_test : generation_tests) + RunGenerateFileNameTestCase(&generation_test); - for (size_t i = 0; i < arraysize(generation_tests); ++i) { - GenerateFilenameCase test_case = generation_tests[i]; + for (const auto& generation_test : generation_tests) { + GenerateFilenameCase test_case = generation_test; test_case.referrer_charset = "GBK"; RunGenerateFileNameTestCase(&test_case); } } TEST(FilenameUtilTest, IsReservedNameOnWindows) { - for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { - EXPECT_FALSE(IsReservedNameOnWindows( - base::FilePath(kSafePortableBasenames[i]).value())) - << kSafePortableBasenames[i]; + for (auto* basename : kSafePortableBasenames) { + EXPECT_FALSE(IsReservedNameOnWindows(base::FilePath(basename).value())) + << basename; } - for (size_t i = 0; i < arraysize(kUnsafePortableBasenamesForWin); ++i) { - EXPECT_TRUE(IsReservedNameOnWindows( - base::FilePath(kUnsafePortableBasenamesForWin[i]).value())) - << kUnsafePortableBasenamesForWin[i]; + for (auto* basename : kUnsafePortableBasenamesForWin) { + EXPECT_TRUE(IsReservedNameOnWindows(base::FilePath(basename).value())) + << basename; } }
diff --git a/net/base/host_port_pair_unittest.cc b/net/base/host_port_pair_unittest.cc index 72704a0..4300c2b 100644 --- a/net/base/host_port_pair_unittest.cc +++ b/net/base/host_port_pair_unittest.cc
@@ -42,8 +42,8 @@ "www.google.com:+1", "127.0.0.1:65536", "[2001:db8::42]:65536", }; - for (size_t index = 0; index < arraysize(kBadStrings); ++index) { - HostPortPair foo = HostPortPair::FromString(kBadStrings[index]); + for (const auto* const test : kBadStrings) { + HostPortPair foo = HostPortPair::FromString(test); EXPECT_TRUE(foo.host().empty()); EXPECT_EQ(0, foo.port()); } @@ -57,9 +57,9 @@ } TEST(HostPortPairTest, ToString) { - for (size_t index = 0; index < arraysize(tests); ++index) { - HostPortPair foo(tests[index].host, tests[index].port); - EXPECT_EQ(tests[index].to_string, foo.ToString()); + for (const auto& test : tests) { + HostPortPair foo(test.host, test.port); + EXPECT_EQ(test.to_string, foo.ToString()); } // Test empty hostname. @@ -67,9 +67,9 @@ } TEST(HostPortPairTest, HostForURL) { - for (size_t index = 0; index < arraysize(tests); ++index) { - HostPortPair foo(tests[index].host, tests[index].port); - EXPECT_EQ(tests[index].host_for_url, foo.HostForURL()); + for (const auto& test : tests) { + HostPortPair foo(test.host, test.port); + EXPECT_EQ(test.host_for_url, foo.HostForURL()); } // Test hostname with null character.
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc index b90b3b4..2daddc0 100644 --- a/net/base/ip_address.cc +++ b/net/base/ip_address.cc
@@ -8,6 +8,7 @@ #include <climits> #include "base/containers/stack_container.h" +#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" @@ -20,7 +21,8 @@ // The prefix for IPv6 mapped IPv4 addresses. // https://tools.ietf.org/html/rfc4291#section-2.5.5.2 -const uint8_t kIPv4MappedPrefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF}; +constexpr uint8_t kIPv4MappedPrefix[] = {0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFF, 0xFF}; // Note that this function assumes: // * |ip_address| is at least |prefix_length_in_bits| (bits) long; @@ -359,7 +361,7 @@ base::StackVector<uint8_t, 16> bytes; bytes->insert(bytes->end(), - address.bytes().begin() + arraysize(kIPv4MappedPrefix), + address.bytes().begin() + base::size(kIPv4MappedPrefix), address.bytes().end()); return IPAddress(bytes->data(), bytes->size()); }
diff --git a/net/base/ip_address_unittest.cc b/net/base/ip_address_unittest.cc index 177ab55..652416a 100644 --- a/net/base/ip_address_unittest.cc +++ b/net/base/ip_address_unittest.cc
@@ -7,6 +7,7 @@ #include <vector> #include "base/format_macros.h" +#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,29 +34,29 @@ TEST(IPAddressBytesTest, ConstructIPv4) { uint8_t data[] = {192, 168, 1, 1}; - IPAddressBytes bytes(data, arraysize(data)); - ASSERT_EQ(arraysize(data), bytes.size()); + IPAddressBytes bytes(data, base::size(data)); + ASSERT_EQ(base::size(data), bytes.size()); size_t i = 0; for (uint8_t byte : bytes) EXPECT_EQ(data[i++], byte); - ASSERT_EQ(arraysize(data), i); + ASSERT_EQ(base::size(data), i); } TEST(IPAddressBytesTest, ConstructIPv6) { uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - IPAddressBytes bytes(data, arraysize(data)); - ASSERT_EQ(arraysize(data), bytes.size()); + IPAddressBytes bytes(data, base::size(data)); + ASSERT_EQ(base::size(data), bytes.size()); size_t i = 0; for (uint8_t byte : bytes) EXPECT_EQ(data[i++], byte); - ASSERT_EQ(arraysize(data), i); + ASSERT_EQ(base::size(data), i); } TEST(IPAddressBytesTest, Assign) { uint8_t data[] = {192, 168, 1, 1}; IPAddressBytes copy; - copy.Assign(data, arraysize(data)); - EXPECT_EQ(IPAddressBytes(data, arraysize(data)), copy); + copy.Assign(data, base::size(data)); + EXPECT_EQ(IPAddressBytes(data, base::size(data)), copy); } TEST(IPAddressTest, ConstructIPv4) { @@ -521,20 +522,19 @@ {"10.11.33.44", 16, "::ffff:0a0b:89", true}, {"10.11.33.44", 16, "::ffff:10.12.33.44", false}, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s, %s", i, - tests[i].cidr_literal, - tests[i].ip_literal)); + for (const auto& test : tests) { + SCOPED_TRACE( + base::StringPrintf("%s, %s", test.cidr_literal, test.ip_literal)); IPAddress ip_address; - EXPECT_TRUE(ip_address.AssignFromIPLiteral(tests[i].ip_literal)); + EXPECT_TRUE(ip_address.AssignFromIPLiteral(test.ip_literal)); IPAddress ip_prefix; - EXPECT_TRUE(ip_prefix.AssignFromIPLiteral(tests[i].cidr_literal)); + EXPECT_TRUE(ip_prefix.AssignFromIPLiteral(test.cidr_literal)); - EXPECT_EQ(tests[i].expected_to_match, + EXPECT_EQ(test.expected_to_match, IPAddressMatchesPrefix(ip_address, ip_prefix, - tests[i].prefix_length_in_bits)); + test.prefix_length_in_bits)); } }
diff --git a/net/base/ip_endpoint_unittest.cc b/net/base/ip_endpoint_unittest.cc index b3aa5b1..545f2e6 100644 --- a/net/base/ip_endpoint_unittest.cc +++ b/net/base/ip_endpoint_unittest.cc
@@ -61,15 +61,13 @@ { "::1", "[::1]", true }, { "2001:db8:0::42", "[2001:db8::42]", true }, }; -uint16_t test_count = static_cast<uint16_t>(arraysize(tests)); class IPEndPointTest : public PlatformTest { public: void SetUp() override { // This is where we populate the TestData. - for (int index = 0; index < test_count; ++index) { - EXPECT_TRUE( - tests[index].ip_address.AssignFromIPLiteral(tests[index].host)); + for (auto& test : tests) { + EXPECT_TRUE(test.ip_address.AssignFromIPLiteral(test.host)); } } }; @@ -78,16 +76,17 @@ IPEndPoint endpoint; EXPECT_EQ(0, endpoint.port()); - for (uint16_t index = 0; index < test_count; ++index) { - IPEndPoint endpoint(tests[index].ip_address, 80); + for (const auto& test : tests) { + IPEndPoint endpoint(test.ip_address, 80); EXPECT_EQ(80, endpoint.port()); - EXPECT_EQ(tests[index].ip_address, endpoint.address()); + EXPECT_EQ(test.ip_address, endpoint.address()); } } TEST_F(IPEndPointTest, Assignment) { - for (uint16_t index = 0; index < test_count; ++index) { - IPEndPoint src(tests[index].ip_address, index); + uint16_t port = 0; + for (const auto& test : tests) { + IPEndPoint src(test.ip_address, ++port); IPEndPoint dest = src; EXPECT_EQ(src.port(), dest.port()); @@ -96,8 +95,9 @@ } TEST_F(IPEndPointTest, Copy) { - for (uint16_t index = 0; index < test_count; ++index) { - IPEndPoint src(tests[index].ip_address, index); + uint16_t port = 0; + for (const auto& test : tests) { + IPEndPoint src(test.ip_address, ++port); IPEndPoint dest(src); EXPECT_EQ(src.port(), dest.port()); @@ -106,16 +106,17 @@ } TEST_F(IPEndPointTest, ToFromSockAddr) { - for (uint16_t index = 0; index < test_count; ++index) { - IPEndPoint ip_endpoint(tests[index].ip_address, index); + uint16_t port = 0; + for (const auto& test : tests) { + IPEndPoint ip_endpoint(test.ip_address, ++port); // Convert to a sockaddr. SockaddrStorage storage; EXPECT_TRUE(ip_endpoint.ToSockAddr(storage.addr, &storage.addr_len)); // Basic verification. - socklen_t expected_size = tests[index].ipv6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); + socklen_t expected_size = + test.ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); EXPECT_EQ(expected_size, storage.addr_len); EXPECT_EQ(ip_endpoint.port(), GetPortFromSockaddr(storage.addr, storage.addr_len)); @@ -129,11 +130,12 @@ } TEST_F(IPEndPointTest, ToSockAddrBufTooSmall) { - for (uint16_t index = 0; index < test_count; ++index) { - IPEndPoint ip_endpoint(tests[index].ip_address, index); + uint16_t port = 0; + for (const auto& test : tests) { + IPEndPoint ip_endpoint(test.ip_address, port); SockaddrStorage storage; - storage.addr_len = index; // size is too small! + storage.addr_len = 3; // size is too small! EXPECT_FALSE(ip_endpoint.ToSockAddr(storage.addr, &storage.addr_len)); } } @@ -148,8 +150,9 @@ } TEST_F(IPEndPointTest, Equality) { - for (uint16_t index = 0; index < test_count; ++index) { - IPEndPoint src(tests[index].ip_address, index); + uint16_t port = 0; + for (const auto& test : tests) { + IPEndPoint src(test.ip_address, ++port); IPEndPoint dest(src); EXPECT_TRUE(src == dest); } @@ -191,12 +194,12 @@ IPEndPoint endpoint; EXPECT_EQ(0, endpoint.port()); - for (uint16_t index = 0; index < test_count; ++index) { - uint16_t port = 100 + index; - IPEndPoint endpoint(tests[index].ip_address, port); + uint16_t port = 100; + for (const auto& test : tests) { + ++port; + IPEndPoint endpoint(test.ip_address, port); const std::string result = endpoint.ToString(); - EXPECT_EQ(tests[index].host_normalized + ":" + base::UintToString(port), - result); + EXPECT_EQ(test.host_normalized + ":" + base::UintToString(port), result); } // ToString() shouldn't crash on invalid addresses.
diff --git a/net/base/mime_sniffer.cc b/net/base/mime_sniffer.cc index 39d25ab6..3f60f22 100644 --- a/net/base/mime_sniffer.cc +++ b/net/base/mime_sniffer.cc
@@ -88,7 +88,9 @@ #include "net/base/mime_sniffer.h" +#include "base/containers/span.h" #include "base/logging.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "url/gurl.h" @@ -348,11 +350,12 @@ return false; } -static bool CheckForMagicNumbers(const char* content, size_t size, - const MagicNumber* magic, size_t magic_len, +static bool CheckForMagicNumbers(const char* content, + size_t size, + base::span<const MagicNumber> magic_numbers, std::string* result) { - for (size_t i = 0; i < magic_len; ++i) { - if (MatchMagicNumber(content, size, magic[i], result)) + for (const MagicNumber& magic : magic_numbers) { + if (MatchMagicNumber(content, size, magic, result)) return true; } return false; @@ -390,8 +393,7 @@ break; } // |pos| now points to first non-whitespace character (or at end). - return CheckForMagicNumbers(pos, end - pos, kSniffableTags, - arraysize(kSniffableTags), result); + return CheckForMagicNumbers(pos, end - pos, kSniffableTags, result); } // Returns true and sets result if the content matches any of kMagicNumbers. @@ -403,8 +405,7 @@ *have_enough_content &= TruncateSize(kBytesRequiredForMagic, &size); // Check our big table of Magic Numbers - return CheckForMagicNumbers(content, size, kMagicNumbers, - arraysize(kMagicNumbers), result); + return CheckForMagicNumbers(content, size, kMagicNumbers, result); } // Returns true and sets result if the content matches any of @@ -420,22 +421,21 @@ // Check our table of magic numbers for Office file types. std::string office_version; if (!CheckForMagicNumbers(content, size, kOfficeMagicNumbers, - arraysize(kOfficeMagicNumbers), &office_version)) + &office_version)) return false; OfficeDocType type = DOC_TYPE_NONE; base::StringPiece url_path = url.path_piece(); - for (size_t i = 0; i < arraysize(kOfficeExtensionTypes); ++i) { - if (url_path.length() < kOfficeExtensionTypes[i].extension_len) + for (const auto& office_extension : kOfficeExtensionTypes) { + if (url_path.length() < office_extension.extension_len) continue; - base::StringPiece extension = url_path.substr( - url_path.length() - kOfficeExtensionTypes[i].extension_len); + base::StringPiece extension = + url_path.substr(url_path.length() - office_extension.extension_len); if (base::EqualsCaseInsensitiveASCII( - extension, - base::StringPiece(kOfficeExtensionTypes[i].extension, - kOfficeExtensionTypes[i].extension_len))) { - type = kOfficeExtensionTypes[i].doc_type; + extension, base::StringPiece(office_extension.extension, + office_extension.extension_len))) { + type = office_extension.doc_type; break; } } @@ -522,7 +522,7 @@ // match one, the MIME type was invalid. Set it instead to a safe value. std::string office_version; if (!CheckForMagicNumbers(content, size, kOfficeMagicNumbers, - arraysize(kOfficeMagicNumbers), &office_version)) { + &office_version)) { *result = "application/octet-stream"; } @@ -564,29 +564,25 @@ if (!pos) return false; - static const char kXmlPrefix[] = "<?xml"; - static const size_t kXmlPrefixLength = arraysize(kXmlPrefix) - 1; - static const char kDocTypePrefix[] = "<!DOCTYPE"; - static const size_t kDocTypePrefixLength = arraysize(kDocTypePrefix) - 1; + static constexpr base::StringPiece kXmlPrefix("<?xml"); + static constexpr base::StringPiece kDocTypePrefix("<!DOCTYPE"); - if ((pos + kXmlPrefixLength <= end) && - base::EqualsCaseInsensitiveASCII( - base::StringPiece(pos, kXmlPrefixLength), - base::StringPiece(kXmlPrefix, kXmlPrefixLength))) { + base::StringPiece current(pos, end - pos); + if (base::EqualsCaseInsensitiveASCII(current.substr(0, kXmlPrefix.size()), + kXmlPrefix)) { // Skip XML declarations. ++pos; continue; - } else if ((pos + kDocTypePrefixLength <= end) && - base::EqualsCaseInsensitiveASCII( - base::StringPiece(pos, kDocTypePrefixLength), - base::StringPiece(kDocTypePrefix, kDocTypePrefixLength))) { + } + + if (base::EqualsCaseInsensitiveASCII( + current.substr(0, kDocTypePrefix.size()), kDocTypePrefix)) { // Skip DOCTYPE declarations. ++pos; continue; } - if (CheckForMagicNumbers(pos, end - pos, kMagicXML, arraysize(kMagicXML), - result)) + if (CheckForMagicNumbers(pos, end - pos, kMagicXML, result)) return true; // TODO(evanm): handle RSS 1.0, which is an RDF format and more difficult @@ -628,8 +624,7 @@ // First, we look for a BOM. std::string unused; - if (CheckForMagicNumbers(content, size, kByteOrderMark, - arraysize(kByteOrderMark), &unused)) { + if (CheckForMagicNumbers(content, size, kByteOrderMark, &unused)) { // If there is BOM, we think the buffer is not binary. result->assign("text/plain"); return false; @@ -662,8 +657,8 @@ // Firefox rejects a mime type if it is exactly */* "*/*", }; - for (size_t i = 0; i < arraysize(kUnknownMimeTypes); ++i) { - if (mime_type == kUnknownMimeTypes[i]) + for (const char* const unknown_mime_type : kUnknownMimeTypes) { + if (mime_type == unknown_mime_type) return true; } if (mime_type.find('/') == std::string::npos) { @@ -695,8 +690,7 @@ return false; *have_enough_content &= TruncateSize(kBytesRequiredForMagic, &size); - return CheckForMagicNumbers(content, size, kCRXMagicNumbers, - arraysize(kCRXMagicNumbers), result); + return CheckForMagicNumbers(content, size, kCRXMagicNumbers, result); } bool ShouldSniffMimeType(const GURL& url, const std::string& mime_type) { @@ -738,8 +732,8 @@ "application/vnd.ms-word.document.12", "application/vnd.msword", }; - for (size_t i = 0; i < arraysize(kSniffableTypes); ++i) { - if (mime_type == kSniffableTypes[i]) + for (const char* const sniffable_type : kSniffableTypes) { + if (mime_type == sniffable_type) return true; } if (IsUnknownMimeType(mime_type)) { @@ -847,12 +841,10 @@ size_t size, std::string* result) { // First check the extra table. - if (CheckForMagicNumbers(content, size, kExtraMagicNumbers, - arraysize(kExtraMagicNumbers), result)) + if (CheckForMagicNumbers(content, size, kExtraMagicNumbers, result)) return true; // Finally check the original table. - return CheckForMagicNumbers(content, size, kMagicNumbers, - arraysize(kMagicNumbers), result); + return CheckForMagicNumbers(content, size, kMagicNumbers, result); } bool LooksLikeBinary(const char* content, size_t size) {
diff --git a/net/base/mime_sniffer_unittest.cc b/net/base/mime_sniffer_unittest.cc index 1d3a869..5c200eb6 100644 --- a/net/base/mime_sniffer_unittest.cc +++ b/net/base/mime_sniffer_unittest.cc
@@ -14,27 +14,14 @@ using ::testing::Values; using ::net::SniffMimeType; // It is shadowed by SniffMimeType(), below. -struct SnifferTest { - const char* content; - size_t content_len; - std::string url; - std::string type_hint; - const char* mime_type; -}; - -static void TestArray(SnifferTest* tests, size_t count) { - std::string mime_type; - - for (size_t i = 0; i < count; ++i) { - SniffMimeType(tests[i].content, tests[i].content_len, GURL(tests[i].url), - tests[i].type_hint, ForceSniffFileUrlsForHtml::kDisabled, - &mime_type); - EXPECT_EQ(tests[i].mime_type, mime_type); - } +// Turn |str|, a constant string with one or more embedded NULs, along with +// a NUL terminator, into an std::string() containing just that data. +// Turn |str|, a string with one or more embedded NULs, into an std::string() +template <size_t N> +std::string MakeConstantString(const char (&str)[N]) { + return std::string(str, N - 1); } -// TODO(evanm): convert other tests to use SniffMimeType instead of TestArray, -// so the error messages produced by test failures are more useful. static std::string SniffMimeType(const std::string& content, const std::string& url, const std::string& mime_type_hint) { @@ -66,184 +53,169 @@ } TEST(MimeSnifferTest, BasicSniffingTest) { - SnifferTest tests[] = { - { "<!DOCTYPE html PUBLIC", sizeof("<!DOCTYPE html PUBLIC")-1, - "http://www.example.com/", - "", "text/html" }, - { "<HtMl><Body></body></htMl>", sizeof("<HtMl><Body></body></htMl>")-1, - "http://www.example.com/foo.gif", - "application/octet-stream", "application/octet-stream" }, - { "GIF89a\x1F\x83\x94", sizeof("GIF89a\xAF\x83\x94")-1, - "http://www.example.com/foo", - "text/plain", "image/gif" }, - { "Gif87a\x1F\x83\x94", sizeof("Gif87a\xAF\x83\x94")-1, - "http://www.example.com/foo?param=tt.gif", - "", "application/octet-stream" }, - { "%!PS-Adobe-3.0", sizeof("%!PS-Adobe-3.0")-1, - "http://www.example.com/foo", - "text/plain", "text/plain" }, - { "\x89" "PNG\x0D\x0A\x1A\x0A", sizeof("\x89" "PNG\x0D\x0A\x1A\x0A")-1, - "http://www.example.com/foo", - "application/octet-stream", "application/octet-stream" }, - { "\xFF\xD8\xFF\x23\x49\xAF", sizeof("\xFF\xD8\xFF\x23\x49\xAF")-1, - "http://www.example.com/foo", - "", "image/jpeg" }, - }; - - TestArray(tests, arraysize(tests)); + EXPECT_EQ("text/html", + SniffMimeType(MakeConstantString("<!DOCTYPE html PUBLIC"), + "http://www.example.com/", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("<HtMl><Body></body></htMl>"), + "http://www.example.com/foo.gif", + "application/octet-stream")); + EXPECT_EQ("image/gif", + SniffMimeType(MakeConstantString("GIF89a\x1F\x83\x94"), + "http://www.example.com/foo", "text/plain")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Gif87a\x1F\x83\x94"), + "http://www.example.com/foo?param=tt.gif", "")); + EXPECT_EQ("text/plain", + SniffMimeType(MakeConstantString("%!PS-Adobe-3.0"), + "http://www.example.com/foo", "text/plain")); + EXPECT_EQ( + "application/octet-stream", + SniffMimeType(MakeConstantString("\x89" + "PNG\x0D\x0A\x1A\x0A"), + "http://www.example.com/foo", "application/octet-stream")); + EXPECT_EQ("image/jpeg", + SniffMimeType(MakeConstantString("\xFF\xD8\xFF\x23\x49\xAF"), + "http://www.example.com/foo", "")); } TEST(MimeSnifferTest, ChromeExtensionsTest) { - SnifferTest tests[] = { - // schemes - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.crx", "", "application/x-chrome-extension"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "https://www.example.com/foo.crx", "", "application/x-chrome-extension"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "ftp://www.example.com/foo.crx", "", "application/x-chrome-extension"}, + // schemes + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.crx", "")); + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "https://www.example.com/foo.crx", "")); + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "ftp://www.example.com/foo.crx", "")); - // some other mimetypes that should get converted - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.crx", "text/plain", - "application/x-chrome-extension"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.crx", "application/octet-stream", - "application/x-chrome-extension"}, + // some other mimetypes that should get converted + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.crx", "text/plain")); + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.crx", + "application/octet-stream")); - // success edge cases - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.crx?query=string", "", - "application/x-chrome-extension"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo..crx", "", "application/x-chrome-extension"}, - {"Cr24\x03\x00\x00\x00", sizeof("Cr24\x03\x00\x00\x00") - 1, - "http://www.example.com/foo..crx", "", "application/x-chrome-extension"}, + // success edge cases + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.crx?query=string", "")); + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo..crx", "")); + EXPECT_EQ("application/x-chrome-extension", + SniffMimeType(MakeConstantString("Cr24\x03\x00\x00\x00"), + "http://www.example.com/foo..crx", "")); - // wrong file extension - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.bin", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.bin?monkey", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "invalid-url", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foocrx", "", "application/octet-stream"}, - {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.crx.blech", "", "application/octet-stream"}, + // wrong file extension + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.bin", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.bin?monkey", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "invalid-url", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foocrx", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.crx.blech", "")); - // wrong magic - {"Cr24\x02\x00\x00\x01", sizeof("Cr24\x02\x00\x00\x01") - 1, - "http://www.example.com/foo.crx?monkey", "", "application/octet-stream"}, - {"PADDING_Cr24\x02\x00\x00\x00", - sizeof("PADDING_Cr24\x02\x00\x00\x00") - 1, - "http://www.example.com/foo.crx?monkey", "", "application/octet-stream"}, - }; - - TestArray(tests, arraysize(tests)); + // wrong magic + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Cr24\x02\x00\x00\x01"), + "http://www.example.com/foo.crx?monkey", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("PADDING_Cr24\x02\x00\x00\x00"), + "http://www.example.com/foo.crx?monkey", "")); } TEST(MimeSnifferTest, MozillaCompatibleTest) { - SnifferTest tests[] = { - { " \n <hTmL>\n <hea", sizeof(" \n <hTmL>\n <hea")-1, - "http://www.example.com/", - "", "text/html" }, - { " \n <hTmL>\n <hea", sizeof(" \n <hTmL>\n <hea")-1, - "http://www.example.com/", - "text/plain", "text/plain" }, - { "BMjlakdsfk", sizeof("BMjlakdsfk")-1, - "http://www.example.com/foo", - "", "image/bmp" }, - { "\x00\x00\x30\x00", sizeof("\x00\x00\x30\x00")-1, - "http://www.example.com/favicon.ico", - "", "application/octet-stream" }, - { "#!/bin/sh\nls /\n", sizeof("#!/bin/sh\nls /\n")-1, - "http://www.example.com/foo", - "", "text/plain" }, - { "From: Fred\nTo: Bob\n\nHi\n.\n", - sizeof("From: Fred\nTo: Bob\n\nHi\n.\n")-1, - "http://www.example.com/foo", - "", "text/plain" }, - { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", - sizeof("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")-1, - "http://www.example.com/foo", - "", "text/xml" }, - { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", - sizeof("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")-1, - "http://www.example.com/foo", - "application/octet-stream", "application/octet-stream" }, - }; - - TestArray(tests, arraysize(tests)); + EXPECT_EQ("text/html", SniffMimeType(MakeConstantString(" \n <hTmL>\n <hea"), + "http://www.example.com/", "")); + EXPECT_EQ("text/plain", + SniffMimeType(MakeConstantString(" \n <hTmL>\n <hea"), + "http://www.example.com/", "text/plain")); + EXPECT_EQ("image/bmp", SniffMimeType(MakeConstantString("BMjlakdsfk"), + "http://www.example.com/foo", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("\x00\x00\x30\x00"), + "http://www.example.com/favicon.ico", "")); + EXPECT_EQ("text/plain", SniffMimeType(MakeConstantString("#!/bin/sh\nls /\n"), + "http://www.example.com/foo", "")); + EXPECT_EQ("text/plain", + SniffMimeType(MakeConstantString("From: Fred\nTo: Bob\n\nHi\n.\n"), + "http://www.example.com/foo", "")); + EXPECT_EQ("text/xml", + SniffMimeType(MakeConstantString( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"), + "http://www.example.com/foo", "")); + EXPECT_EQ( + "application/octet-stream", + SniffMimeType( + MakeConstantString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"), + "http://www.example.com/foo", "application/octet-stream")); } TEST(MimeSnifferTest, DontAllowPrivilegeEscalationTest) { - SnifferTest tests[] = { - { "GIF87a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("GIF87a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo", - "", "image/gif" }, - { "GIF87a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("GIF87a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo?q=ttt.html", - "", "image/gif" }, - { "GIF87a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("GIF87a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo#ttt.html", - "", "image/gif" }, - { "a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo", - "", "text/plain" }, - { "a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo?q=ttt.html", - "", "text/plain" }, - { "a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo#ttt.html", - "", "text/plain" }, - { "a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n", - sizeof("a\n<html>\n<body>" - "<script>alert('haxorzed');\n</script>" - "</body></html>\n")-1, - "http://www.example.com/foo.html", - "", "text/plain" }, - }; - - TestArray(tests, arraysize(tests)); + EXPECT_EQ( + "image/gif", + SniffMimeType(MakeConstantString("GIF87a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo", "")); + EXPECT_EQ( + "image/gif", + SniffMimeType(MakeConstantString("GIF87a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo?q=ttt.html", "")); + EXPECT_EQ( + "image/gif", + SniffMimeType(MakeConstantString("GIF87a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo#ttt.html", "")); + EXPECT_EQ( + "text/plain", + SniffMimeType(MakeConstantString("a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo", "")); + EXPECT_EQ( + "text/plain", + SniffMimeType(MakeConstantString("a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo?q=ttt.html", "")); + EXPECT_EQ( + "text/plain", + SniffMimeType(MakeConstantString("a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo#ttt.html", "")); + EXPECT_EQ( + "text/plain", + SniffMimeType(MakeConstantString("a\n<html>\n<body>" + "<script>alert('haxorzed');\n</script>" + "</body></html>\n"), + "http://www.example.com/foo.html", "")); } TEST(MimeSnifferTest, SniffFilesAsHtml) { @@ -261,66 +233,61 @@ } TEST(MimeSnifferTest, UnicodeTest) { - SnifferTest tests[] = { - { "\xEF\xBB\xBF" "Hi there", sizeof("\xEF\xBB\xBF" "Hi there")-1, - "http://www.example.com/foo", - "", "text/plain" }, - { "\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79", - sizeof("\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79")-1, - "http://www.example.com/foo", - "", "text/plain" }, - { "\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9", - sizeof("\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9")-1, - "http://www.example.com/foo", - "", "text/plain" }, - { "\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01", - sizeof("\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01")-1, - "http://www.example.com/foo", - "", "text/plain" }, - }; - - TestArray(tests, arraysize(tests)); + EXPECT_EQ("text/plain", SniffMimeType(MakeConstantString("\xEF\xBB\xBF" + "Hi there"), + "http://www.example.com/foo", "")); + EXPECT_EQ( + "text/plain", + SniffMimeType(MakeConstantString("\xEF\xBB\xBF\xED\x7A\xAD\x7A\x0D\x79"), + "http://www.example.com/foo", "")); + EXPECT_EQ( + "text/plain", + SniffMimeType(MakeConstantString( + "\xFE\xFF\xD0\xA5\xD0\xBE\xD0\xBB\xD1\x83\xD0\xB9"), + "http://www.example.com/foo", "")); + EXPECT_EQ("text/plain", + SniffMimeType( + MakeConstantString( + "\xFE\xFF\x00\x41\x00\x20\xD8\x00\xDC\x00\xD8\x00\xDC\x01"), + "http://www.example.com/foo", "")); } TEST(MimeSnifferTest, FlashTest) { - SnifferTest tests[] = { - { "CWSdd\x00\xB3", sizeof("CWSdd\x00\xB3")-1, - "http://www.example.com/foo", - "", "application/octet-stream" }, - { "FLVjdkl*(#)0sdj\x00", sizeof("FLVjdkl*(#)0sdj\x00")-1, - "http://www.example.com/foo?q=ttt.swf", - "", "application/octet-stream" }, - { "FWS3$9\r\b\x00", sizeof("FWS3$9\r\b\x00")-1, - "http://www.example.com/foo#ttt.swf", - "", "application/octet-stream" }, - { "FLVjdkl*(#)0sdj", sizeof("FLVjdkl*(#)0sdj")-1, - "http://www.example.com/foo.swf", - "", "text/plain" }, - { "FLVjdkl*(#)0s\x01dj", sizeof("FLVjdkl*(#)0s\x01dj")-1, - "http://www.example.com/foo/bar.swf", - "", "application/octet-stream" }, - { "FWS3$9\r\b\x1A", sizeof("FWS3$9\r\b\x1A")-1, - "http://www.example.com/foo.swf?clickTAG=http://www.adnetwork.com/bar", - "", "application/octet-stream" }, - { "FWS3$9\r\x1C\b", sizeof("FWS3$9\r\x1C\b")-1, - "http://www.example.com/foo.swf?clickTAG=http://www.adnetwork.com/bar", - "text/plain", "application/octet-stream" }, - }; - - TestArray(tests, arraysize(tests)); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("CWSdd\x00\xB3"), + "http://www.example.com/foo", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("FLVjdkl*(#)0sdj\x00"), + "http://www.example.com/foo?q=ttt.swf", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("FWS3$9\r\b\x00"), + "http://www.example.com/foo#ttt.swf", "")); + EXPECT_EQ("text/plain", SniffMimeType(MakeConstantString("FLVjdkl*(#)0sdj"), + "http://www.example.com/foo.swf", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("FLVjdkl*(#)0s\x01dj"), + "http://www.example.com/foo/bar.swf", "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("FWS3$9\r\b\x1A"), + "http://www.example.com/foo.swf?clickTAG=http://" + "www.adnetwork.com/bar", + "")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("FWS3$9\r\x1C\b"), + "http://www.example.com/foo.swf?clickTAG=http://" + "www.adnetwork.com/bar", + "text/plain")); } TEST(MimeSnifferTest, XMLTest) { // An easy feed to identify. EXPECT_EQ("application/atom+xml", - SniffMimeType("<?xml?><feed", std::string(), "text/xml")); + SniffMimeType("<?xml?><feed", "", "text/xml")); // Don't sniff out of plain text. - EXPECT_EQ("text/plain", - SniffMimeType("<?xml?><feed", std::string(), "text/plain")); + EXPECT_EQ("text/plain", SniffMimeType("<?xml?><feed", "", "text/plain")); // Simple RSS. EXPECT_EQ("application/rss+xml", - SniffMimeType( - "<?xml version='1.0'?>\r\n<rss", std::string(), "text/xml")); + SniffMimeType("<?xml version='1.0'?>\r\n<rss", "", "text/xml")); // The top of CNN's RSS feed, which we'd like to recognize as RSS. static const char kCNNRSS[] = @@ -332,39 +299,33 @@ "<rss xmlns:feedburner=\"http://rssnamespace.org/feedburner/ext/1.0\" " "version=\"2.0\">"; // CNN's RSS - EXPECT_EQ("application/rss+xml", - SniffMimeType(kCNNRSS, std::string(), "text/xml")); - EXPECT_EQ("text/plain", SniffMimeType(kCNNRSS, std::string(), "text/plain")); + EXPECT_EQ("application/rss+xml", SniffMimeType(kCNNRSS, "", "text/xml")); + EXPECT_EQ("text/plain", SniffMimeType(kCNNRSS, "", "text/plain")); // Don't sniff random XML as something different. - EXPECT_EQ("text/xml", - SniffMimeType("<?xml?><notafeed", std::string(), "text/xml")); + EXPECT_EQ("text/xml", SniffMimeType("<?xml?><notafeed", "", "text/xml")); // Don't sniff random plain-text as something different. - EXPECT_EQ("text/plain", - SniffMimeType("<?xml?><notafeed", std::string(), "text/plain")); + EXPECT_EQ("text/plain", SniffMimeType("<?xml?><notafeed", "", "text/plain")); // We never upgrade to application/xhtml+xml. EXPECT_EQ("text/xml", - SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", - std::string(), "text/xml")); + SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", "", + "text/xml")); EXPECT_EQ("application/xml", - SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", - std::string(), "application/xml")); + SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", "", + "application/xml")); EXPECT_EQ("text/plain", - SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", - std::string(), + SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", "", "text/plain")); EXPECT_EQ("application/rss+xml", - SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", - std::string(), + SniffMimeType("<html xmlns=\"http://www.w3.org/1999/xhtml\">", "", "application/rss+xml")); - EXPECT_EQ("text/xml", - SniffMimeType("<html><head>", std::string(), "text/xml")); + EXPECT_EQ("text/xml", SniffMimeType("<html><head>", "", "text/xml")); EXPECT_EQ("text/xml", SniffMimeType("<foo><rss " "xmlns:feedburner=\"http://rssnamespace.org/" "feedburner/ext/1.0\" version=\"2.0\">", - std::string(), "text/xml")); + "", "text/xml")); } // Test content which is >= 1024 bytes, and includes no open angle bracket. @@ -400,54 +361,55 @@ } TEST(MimeSnifferTest, OfficeTest) { - SnifferTest tests[] = { // Check for URLs incorrectly reported as Microsoft Office files. - { "Hi there", - sizeof("Hi there")-1, - "http://www.example.com/foo.doc", - "application/msword", "application/octet-stream" }, - { "Hi there", - sizeof("Hi there")-1, - "http://www.example.com/foo.xls", - "application/vnd.ms-excel", "application/octet-stream" }, - { "Hi there", - sizeof("Hi there")-1, - "http://www.example.com/foo.ppt", - "application/vnd.ms-powerpoint", "application/octet-stream" }, + EXPECT_EQ( + "application/octet-stream", + SniffMimeType(MakeConstantString("Hi there"), + "http://www.example.com/foo.doc", "application/msword")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Hi there"), + "http://www.example.com/foo.xls", + "application/vnd.ms-excel")); + EXPECT_EQ("application/octet-stream", + SniffMimeType(MakeConstantString("Hi there"), + "http://www.example.com/foo.ppt", + "application/vnd.ms-powerpoint")); // Check for Microsoft Office files incorrectly reported as text. - { "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there", - sizeof("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there")-1, - "http://www.example.com/foo.doc", - "text/plain", "application/msword" }, - { "PK\x03\x04" "Hi there", - sizeof("PK\x03\x04" "Hi there")-1, - "http://www.example.com/foo.doc", - "text/plain", - "application/vnd.openxmlformats-officedocument." - "wordprocessingml.document" }, - { "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there", - sizeof("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there")-1, - "http://www.example.com/foo.xls", - "text/plain", "application/vnd.ms-excel" }, - { "PK\x03\x04" "Hi there", - sizeof("PK\x03\x04" "Hi there")-1, - "http://www.example.com/foo.xls", - "text/plain", - "application/vnd.openxmlformats-officedocument." - "spreadsheetml.sheet" }, - { "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there", - sizeof("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" "Hi there")-1, - "http://www.example.com/foo.ppt", - "text/plain", "application/vnd.ms-powerpoint" }, - { "PK\x03\x04" "Hi there", - sizeof("PK\x03\x04" "Hi there")-1, - "http://www.example.com/foo.ppt", - "text/plain", - "application/vnd.openxmlformats-officedocument." - "presentationml.presentation" }, - }; + EXPECT_EQ( + "application/msword", + SniffMimeType(MakeConstantString("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + "Hi there"), + "http://www.example.com/foo.doc", "text/plain")); + EXPECT_EQ( + "application/vnd.openxmlformats-officedocument." + "wordprocessingml.document", + SniffMimeType(MakeConstantString( - TestArray(tests, arraysize(tests)); + "PK\x03\x04" + "Hi there"), + "http://www.example.com/foo.doc", "text/plain")); + EXPECT_EQ( + "application/vnd.ms-excel", + SniffMimeType(MakeConstantString("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + "Hi there"), + "http://www.example.com/foo.xls", "text/plain")); + EXPECT_EQ( + "application/vnd.openxmlformats-officedocument." + "spreadsheetml.sheet", + SniffMimeType(MakeConstantString("PK\x03\x04" + "Hi there"), + "http://www.example.com/foo.xls", "text/plain")); + EXPECT_EQ( + "application/vnd.ms-powerpoint", + SniffMimeType(MakeConstantString("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + "Hi there"), + "http://www.example.com/foo.ppt", "text/plain")); + EXPECT_EQ( + "application/vnd.openxmlformats-officedocument." + "presentationml.presentation", + SniffMimeType(MakeConstantString("PK\x03\x04" + "Hi there"), + "http://www.example.com/foo.ppt", "text/plain")); } // TODO(thestig) Add more tests for other AV formats. Add another test case for
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc index 59cf91d..568c10e3 100644 --- a/net/base/mime_util.cc +++ b/net/base/mime_util.cc
@@ -9,6 +9,7 @@ #include <unordered_set> #include "base/base64.h" +#include "base/containers/span.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/rand_util.h" @@ -368,16 +369,9 @@ } // See http://www.iana.org/assignments/media-types/media-types.xhtml -static const char* const legal_top_level_types[] = { - "application", - "audio", - "example", - "image", - "message", - "model", - "multipart", - "text", - "video", +static const char* const kLegalTopLevelTypes[] = { + "application", "audio", "example", "image", "message", + "model", "multipart", "text", "video", }; bool MimeUtil::ParseMimeTypeWithoutParameter( @@ -400,8 +394,8 @@ bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const { std::string lower_type = base::ToLowerASCII(type_string); - for (size_t i = 0; i < arraysize(legal_top_level_types); ++i) { - if (lower_type.compare(legal_top_level_types[i]) == 0) + for (const char* const legal_type : kLegalTopLevelTypes) { + if (lower_type.compare(legal_type) == 0) return true; } @@ -519,15 +513,13 @@ struct StandardType { const char* const leading_mime_type; - const char* const* standard_types; - size_t standard_types_len; + base::span<const char* const> standard_types; }; static const StandardType kStandardTypes[] = { - { "image/", kStandardImageTypes, arraysize(kStandardImageTypes) }, - { "audio/", kStandardAudioTypes, arraysize(kStandardAudioTypes) }, - { "video/", kStandardVideoTypes, arraysize(kStandardVideoTypes) }, - { NULL, NULL, 0 } -}; + {"image/", kStandardImageTypes}, + {"audio/", kStandardAudioTypes}, + {"video/", kStandardVideoTypes}, + {nullptr, base::span<const char* const>()}}; // GetExtensionsFromHardCodedMappings() adds file extensions (without a leading // dot) to the set |extensions|, for all MIME types matching |mime_type|. @@ -539,9 +531,8 @@ // // * If |prefix_match = true| then |mime_type| is treated as the prefix for a // (case-insensitive) string. For instance "Text/" would match "text/plain". -template <size_t N> void GetExtensionsFromHardCodedMappings( - const MimeInfo (&mappings)[N], + base::span<const MimeInfo> mappings, const std::string& mime_type, bool prefix_match, std::unordered_set<base::FilePath::StringType>* extensions) { @@ -561,12 +552,11 @@ } void GetExtensionsHelper( - const char* const* standard_types, - size_t standard_types_len, + base::span<const char* const> standard_types, const std::string& leading_mime_type, std::unordered_set<base::FilePath::StringType>* extensions) { - for (size_t i = 0; i < standard_types_len; ++i) { - g_mime_util.Get().GetPlatformExtensionsForMimeType(standard_types[i], + for (auto* standard_type : standard_types) { + g_mime_util.Get().GetPlatformExtensionsForMimeType(standard_type, extensions); } @@ -599,8 +589,8 @@ // following characters are legal for boundaries: '()+_,-./:=? // However the following characters, though legal, cause some sites // to fail: (),./:=+ -const char kMimeBoundaryCharacters[] = - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +constexpr base::StringPiece kMimeBoundaryCharacters( + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); // Size of mime multipart boundary. const size_t kMimeBoundarySize = 69; @@ -621,16 +611,16 @@ // Find the matching StandardType from within kStandardTypes, or fall // through to the last (default) StandardType. - const StandardType* type = NULL; - for (size_t i = 0; i < arraysize(kStandardTypes); ++i) { - type = &(kStandardTypes[i]); + const StandardType* type = nullptr; + for (const StandardType& standard_type : kStandardTypes) { + type = &standard_type; if (type->leading_mime_type && - leading_mime_type == type->leading_mime_type) + leading_mime_type == type->leading_mime_type) { break; + } } DCHECK(type); GetExtensionsHelper(type->standard_types, - type->standard_types_len, leading_mime_type, &unique_extensions); } else { @@ -671,10 +661,8 @@ result.reserve(kMimeBoundarySize); result.append("----MultipartBoundary--"); while (result.size() < (kMimeBoundarySize - 4)) { - // Subtract 2 from the array size to 1) exclude '\0', and 2) turn the size - // into the last index. - const int last_char_index = sizeof(kMimeBoundaryCharacters) - 2; - char c = kMimeBoundaryCharacters[base::RandInt(0, last_char_index)]; + char c = kMimeBoundaryCharacters[base::RandInt( + 0, kMimeBoundaryCharacters.size() - 1)]; result.push_back(c); } result.append("----");
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc index 473920b..f160583 100644 --- a/net/base/mime_util_unittest.cc +++ b/net/base/mime_util_unittest.cc
@@ -47,11 +47,11 @@ std::string mime_type; bool rv; - for (size_t i = 0; i < arraysize(tests); ++i) { - rv = GetMimeTypeFromExtension(tests[i].extension, &mime_type); - EXPECT_EQ(tests[i].valid, rv); + for (const auto& test : tests) { + rv = GetMimeTypeFromExtension(test.extension, &mime_type); + EXPECT_EQ(test.valid, rv); if (rv) - EXPECT_EQ(tests[i].mime_type, mime_type); + EXPECT_EQ(test.mime_type, mime_type); } } @@ -73,12 +73,11 @@ std::string mime_type; bool rv; - for (size_t i = 0; i < arraysize(tests); ++i) { - rv = GetMimeTypeFromFile(base::FilePath(tests[i].file_path), - &mime_type); - EXPECT_EQ(tests[i].valid, rv); + for (const auto& test : tests) { + rv = GetMimeTypeFromFile(base::FilePath(test.file_path), &mime_type); + EXPECT_EQ(test.valid, rv); if (rv) - EXPECT_EQ(tests[i].mime_type, mime_type); + EXPECT_EQ(test.mime_type, mime_type); } }
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index 573ec3a..37f34ec1 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" @@ -709,7 +710,7 @@ "CONNECTION_NONE", "CONNECTION_BLUETOOTH" }; - static_assert(arraysize(kConnectionTypeNames) == + static_assert(base::size(kConnectionTypeNames) == NetworkChangeNotifier::CONNECTION_LAST + 1, "ConnectionType name count should match"); if (type < CONNECTION_UNKNOWN || type > CONNECTION_LAST) {
diff --git a/net/base/network_interfaces_fuchsia.cc b/net/base/network_interfaces_fuchsia.cc index f535143..947cd83 100644 --- a/net/base/network_interfaces_fuchsia.cc +++ b/net/base/network_interfaces_fuchsia.cc
@@ -11,7 +11,7 @@ namespace net { -IPAddress NetAddressToIPAddress(const fuchsia::netstack::NetAddress& addr) { +IPAddress NetAddressToIPAddress(const netstack::NetAddress& addr) { if (addr.ipv4) { return IPAddress(addr.ipv4->addr.data(), addr.ipv4->addr.count()); } @@ -22,25 +22,25 @@ } bool GetNetworkList(NetworkInterfaceList* networks, int policy) { - fuchsia::netstack::NetstackSyncPtr netstack = + netstack::NetstackSyncPtr netstack = base::fuchsia::ComponentContext::GetDefault() - ->ConnectToServiceSync<fuchsia::netstack::Netstack>(); + ->ConnectToServiceSync<netstack::Netstack>(); - fidl::VectorPtr<fuchsia::netstack::NetInterface> interfaces; + fidl::VectorPtr<netstack::NetInterface> interfaces; if (!netstack->GetInterfaces(&interfaces)) return false; for (auto& interface : interfaces.get()) { // Check if the interface is up. - if (!(interface.flags & fuchsia::netstack::NetInterfaceFlagUp)) + if (!(interface.flags & netstack::NetInterfaceFlagUp)) continue; // Skip loopback. - if (interface.features & fuchsia::netstack::interfaceFeatureLoopback) + if (interface.features & netstack::interfaceFeatureLoopback) continue; NetworkChangeNotifier::ConnectionType connection_type = - (interface.features & fuchsia::netstack::interfaceFeatureWlan) + (interface.features & netstack::interfaceFeatureWlan) ? NetworkChangeNotifier::CONNECTION_WIFI : NetworkChangeNotifier::CONNECTION_UNKNOWN;
diff --git a/net/base/network_interfaces_linux_unittest.cc b/net/base/network_interfaces_linux_unittest.cc index 85a7367..fe1984b2 100644 --- a/net/base/network_interfaces_linux_unittest.cc +++ b/net/base/network_interfaces_linux_unittest.cc
@@ -11,6 +11,7 @@ #include <string> #include <unordered_set> +#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "net/base/address_tracker_linux.h" @@ -30,18 +31,17 @@ 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff, 0xfe, 0xe5, 0x00, 0xc3}; -char* CopyInterfaceName(const char* ifname, int ifname_size, char* output) { - EXPECT_LT(ifname_size, IF_NAMESIZE); - memcpy(output, ifname, ifname_size); - return output; -} - char* GetInterfaceName(int interface_index, char* ifname) { - return CopyInterfaceName(kIfnameEm1, arraysize(kIfnameEm1), ifname); + static_assert(base::size(kIfnameEm1) < IF_NAMESIZE, "Invalid interface name"); + memcpy(ifname, kIfnameEm1, base::size(kIfnameEm1)); + return ifname; } char* GetInterfaceNameVM(int interface_index, char* ifname) { - return CopyInterfaceName(kIfnameVmnet, arraysize(kIfnameVmnet), ifname); + static_assert(base::size(kIfnameVmnet) < IF_NAMESIZE, + "Invalid interface name"); + memcpy(ifname, kIfnameVmnet, base::size(kIfnameVmnet)); + return ifname; } TEST(NetworkInterfacesTest, NetworkListTrimmingLinux) {
diff --git a/net/base/network_interfaces_win.cc b/net/base/network_interfaces_win.cc index d4cc641..2a81aeba 100644 --- a/net/base/network_interfaces_win.cc +++ b/net/base/network_interfaces_win.cc
@@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "base/lazy_instance.h" +#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" @@ -105,7 +106,7 @@ // Use an absolute path to load the DLL to avoid DLL preloading attacks. static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; wchar_t path[MAX_PATH] = {0}; - ExpandEnvironmentStrings(kDLL, path, arraysize(path)); + ExpandEnvironmentStrings(kDLL, path, base::size(path)); module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (!module) return;
diff --git a/net/base/port_util_unittest.cc b/net/base/port_util_unittest.cc index 6bd163f..fac64e6d 100644 --- a/net/base/port_util_unittest.cc +++ b/net/base/port_util_unittest.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/stl_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -14,12 +15,12 @@ std::string invalid[] = {"1,2,a", "'1','2'", "1, 2, 3", "1 0,11,12"}; std::string valid[] = {"", "1", "1,2", "1,2,3", "10,11,12,13"}; - for (size_t i = 0; i < arraysize(invalid); ++i) { + for (size_t i = 0; i < base::size(invalid); ++i) { SetExplicitlyAllowedPorts(invalid[i]); EXPECT_EQ(0, static_cast<int>(GetCountOfExplicitlyAllowedPorts())); } - for (size_t i = 0; i < arraysize(valid); ++i) { + for (size_t i = 0; i < base::size(valid); ++i) { SetExplicitlyAllowedPorts(valid[i]); EXPECT_EQ(i, GetCountOfExplicitlyAllowedPorts()); }
diff --git a/net/base/priority_queue_unittest.cc b/net/base/priority_queue_unittest.cc index 3e68acfb..435c08a 100644 --- a/net/base/priority_queue_unittest.cc +++ b/net/base/priority_queue_unittest.cc
@@ -6,6 +6,7 @@ #include <cstddef> +#include "base/stl_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -13,13 +14,13 @@ namespace { typedef PriorityQueue<int>::Priority Priority; -const Priority kPriorities[] = { 2, 1, 2, 0, 4, 3, 1, 4, 0 }; -const Priority kNumPriorities = 5; // max(kPriorities) + 1 -const size_t kNumElements = arraysize(kPriorities); -const int kFirstMinOrder[kNumElements] = { 3, 8, 1, 6, 0, 2, 5, 4, 7 }; -const int kLastMaxOrderErase[kNumElements] = { 7, 4, 5, 2, 0, 6, 1, 8, 3 }; -const int kFirstMaxOrder[kNumElements] = { 4, 7, 5, 0, 2, 1, 6, 3, 8 }; -const int kLastMinOrder[kNumElements] = { 8, 3, 6, 1, 2, 0, 5, 7, 4 }; +constexpr Priority kPriorities[] = {2, 1, 2, 0, 4, 3, 1, 4, 0}; +constexpr Priority kNumPriorities = 5; // max(kPriorities) + 1 +constexpr size_t kNumElements = base::size(kPriorities); +constexpr int kFirstMinOrder[kNumElements] = {3, 8, 1, 6, 0, 2, 5, 4, 7}; +constexpr int kLastMaxOrderErase[kNumElements] = {7, 4, 5, 2, 0, 6, 1, 8, 3}; +constexpr int kFirstMaxOrder[kNumElements] = {4, 7, 5, 0, 2, 1, 6, 3, 8}; +constexpr int kLastMinOrder[kNumElements] = {8, 3, 6, 1, 2, 0, 5, 7, 4}; class PriorityQueueTest : public testing::Test { protected: @@ -124,8 +125,8 @@ const int expected_order[] = { 8, 1, 6, 0, 5, 4, 7 }; - for (size_t i = 0; i < arraysize(expected_order); ++i) { - EXPECT_EQ(expected_order[i], queue_.FirstMin().value()); + for (const auto& value : expected_order) { + EXPECT_EQ(value, queue_.FirstMin().value()); queue_.Erase(queue_.FirstMin()); } CheckEmpty(); @@ -139,8 +140,8 @@ const int expected_order[] = { 10, 3, 8, 12, 11, 1, 6, 9, 0, 2, 5, 4, 7 }; - for (size_t i = 0; i < arraysize(expected_order); ++i) { - EXPECT_EQ(expected_order[i], queue_.FirstMin().value()); + for (const auto& value : expected_order) { + EXPECT_EQ(value, queue_.FirstMin().value()); queue_.Erase(queue_.FirstMin()); } CheckEmpty();
diff --git a/net/base/upload_bytes_element_reader_unittest.cc b/net/base/upload_bytes_element_reader_unittest.cc index 2b6298ea..c4a43385 100644 --- a/net/base/upload_bytes_element_reader_unittest.cc +++ b/net/base/upload_bytes_element_reader_unittest.cc
@@ -21,8 +21,7 @@ class UploadBytesElementReaderTest : public PlatformTest { protected: void SetUp() override { - const char kData[] = "123abc"; - bytes_.assign(kData, kData + arraysize(kData)); + bytes_.assign({'1', '2', '3', 'a', 'b', 'c'}); reader_.reset(new UploadBytesElementReader(&bytes_[0], bytes_.size())); ASSERT_THAT(reader_->Init(CompletionOnceCallback()), IsOk()); EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
diff --git a/net/base/upload_file_element_reader_unittest.cc b/net/base/upload_file_element_reader_unittest.cc index 213c46b..eec7b3fe 100644 --- a/net/base/upload_file_element_reader_unittest.cc +++ b/net/base/upload_file_element_reader_unittest.cc
@@ -38,8 +38,8 @@ protected: void SetUp() override { // Some tests (*.ReadPartially) rely on bytes_.size() being even. - const char kData[] = "123456789abcdefghi"; - bytes_.assign(kData, kData + arraysize(kData) - 1); + bytes_.assign({'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', + 'd', 'e', 'f', 'g', 'h', 'i'}); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
diff --git a/net/base/url_util_unittest.cc b/net/base/url_util_unittest.cc index 67acfd23..bd8125fd 100644 --- a/net/base/url_util_unittest.cc +++ b/net/base/url_util_unittest.cc
@@ -211,16 +211,15 @@ {"[]", false, "", -1}, }; - for (size_t i = 0; i < arraysize(tests); ++i) { + for (const auto& test : tests) { std::string host; int port; - bool ok = ParseHostAndPort(tests[i].input, &host, &port); + bool ok = ParseHostAndPort(test.input, &host, &port); + EXPECT_EQ(test.success, ok); - EXPECT_EQ(tests[i].success, ok); - - if (tests[i].success) { - EXPECT_EQ(tests[i].expected_host, host); - EXPECT_EQ(tests[i].expected_port, port); + if (test.success) { + EXPECT_EQ(test.expected_host, host); + EXPECT_EQ(test.expected_port, port); } } } @@ -236,9 +235,9 @@ { GURL("http://[1::2]/x"), "[1::2]:80"}, { GURL("http://[::a]:33/x"), "[::a]:33"}, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - std::string host_and_port = GetHostAndPort(tests[i].url); - EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); + for (const auto& test : tests) { + std::string host_and_port = GetHostAndPort(test.url); + EXPECT_EQ(std::string(test.expected_host_and_port), host_and_port); } } @@ -254,9 +253,9 @@ { GURL("http://[1::2]/x"), "[1::2]"}, { GURL("http://[::a]:33/x"), "[::a]:33"}, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - std::string host_and_port = GetHostAndOptionalPort(tests[i].url); - EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port); + for (const auto& test : tests) { + std::string host_and_port = GetHostAndOptionalPort(test.url); + EXPECT_EQ(std::string(test.expected_host_and_port), host_and_port); } } @@ -302,9 +301,9 @@ {"1.2.3.4.5.", true}, }; - for (size_t i = 0; i < arraysize(compliant_host_cases); ++i) { - EXPECT_EQ(compliant_host_cases[i].expected_output, - IsCanonicalizedHostCompliant(compliant_host_cases[i].host)); + for (const auto& compliant_host : compliant_host_cases) { + EXPECT_EQ(compliant_host.expected_output, + IsCanonicalizedHostCompliant(compliant_host.host)); } } @@ -471,11 +470,10 @@ "foobar://user:pass@google.com:80/sup?yo", }, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, - tests[i].input_url)); - GURL input_url(GURL(tests[i].input_url)); - GURL expected_url(GURL(tests[i].expected_simplified_url)); + for (const auto& test : tests) { + SCOPED_TRACE(test.input_url); + GURL input_url(GURL(test.input_url)); + GURL expected_url(GURL(test.expected_simplified_url)); EXPECT_EQ(expected_url, SimplifyUrlForRequest(input_url)); } } @@ -522,16 +520,15 @@ "p&ssword", }, }; - for (size_t i = 0; i < arraysize(tests); ++i) { - SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, - tests[i].input_url)); - GURL url(tests[i].input_url); + for (const auto& test : tests) { + SCOPED_TRACE(test.input_url); + GURL url(test.input_url); base::string16 username, password; GetIdentityFromURL(url, &username, &password); - EXPECT_EQ(ASCIIToUTF16(tests[i].expected_username), username); - EXPECT_EQ(ASCIIToUTF16(tests[i].expected_password), password); + EXPECT_EQ(ASCIIToUTF16(test.expected_username), username); + EXPECT_EQ(ASCIIToUTF16(test.expected_password), password); } } @@ -580,9 +577,8 @@ {GURL("http://oggole.com"), false}, }; - for (size_t i = 0; i < arraysize(google_host_cases); ++i) { - EXPECT_EQ(google_host_cases[i].expected_output, - HasGoogleHost(google_host_cases[i].url)); + for (const auto& host : google_host_cases) { + EXPECT_EQ(host.expected_output, HasGoogleHost(host.url)); } }
diff --git a/net/cert/cert_database.cc b/net/cert/cert_database.cc index 51f0005..b20ec55 100644 --- a/net/cert/cert_database.cc +++ b/net/cert/cert_database.cc
@@ -29,4 +29,13 @@ observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged); } +CertDatabase::CertDatabase() + : observer_list_(new base::ObserverListThreadSafe<Observer>) {} + +CertDatabase::~CertDatabase() { +#if defined(OS_MACOSX) && !defined(OS_IOS) + ReleaseNotifier(); +#endif +} + } // namespace net
diff --git a/net/cert/cert_database.h b/net/cert/cert_database.h index b44b78ce..32b74a3 100644 --- a/net/cert/cert_database.h +++ b/net/cert/cert_database.h
@@ -9,8 +9,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "build/build_config.h" #include "net/base/net_export.h" -#include "net/cert/x509_certificate.h" namespace base { template <typename T> struct DefaultSingletonTraits; @@ -21,12 +21,14 @@ namespace net { -// This class provides cross-platform functions to verify and add user -// certificates, and to observe changes to the underlying certificate stores. - -// TODO(gauravsh): This class could be augmented with methods -// for all operations that manipulate the underlying system -// certificate store. +// This class allows callers to observe changes to the underlying certificate +// stores. +// +// TODO(davidben): This class is really just a giant global ObserverList. It +// does not do anything with the platform certificate and, in principle, //net's +// dependency on the platform is abstracted behind the CertVerifier and +// ClientCertStore interfaces. Ideally these signals would originate out of +// those interfaces' platform implementations. class NET_EXPORT CertDatabase { public: @@ -71,21 +73,9 @@ void SetMessageLoopForKeychainEvents(); #endif -#if defined(OS_ANDROID) - // On Android, the system key store may be replaced with a device-specific - // KeyStore used for storing client certificates. When the Java side replaces - // the KeyStore used for client certificates, notifies the observers as if a - // new client certificate was added. - void OnAndroidKeyStoreChanged(); - - // On Android, the system database is used. When the system notifies the - // application that the certificates changed, the observers must be notified. - void OnAndroidKeyChainChanged(); -#endif - // Synthetically injects notifications to all observers. In general, this // should only be called by the creator of the CertDatabase. Used to inject - // notifcations from other DB interfaces. + // notifications from other DB interfaces. void NotifyObserversCertDBChanged(); private: @@ -97,9 +87,11 @@ const scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; #if defined(OS_MACOSX) && !defined(OS_IOS) + void ReleaseNotifier(); + class Notifier; friend class Notifier; - std::unique_ptr<Notifier> notifier_; + Notifier* notifier_ = nullptr; #endif DISALLOW_COPY_AND_ASSIGN(CertDatabase);
diff --git a/net/cert/cert_database_android.cc b/net/cert/cert_database_android.cc deleted file mode 100644 index 5631f7cf..0000000 --- a/net/cert/cert_database_android.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/cert/cert_database.h" - -#include "base/logging.h" -#include "base/observer_list_threadsafe.h" -#include "net/base/net_errors.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) { -} - -CertDatabase::~CertDatabase() {} - -void CertDatabase::OnAndroidKeyStoreChanged() { - NotifyObserversCertDBChanged(); -} - -void CertDatabase::OnAndroidKeyChainChanged() { - observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged); -} - -} // namespace net
diff --git a/net/cert/cert_database_fuchsia.cc b/net/cert/cert_database_fuchsia.cc deleted file mode 100644 index e9f884e..0000000 --- a/net/cert/cert_database_fuchsia.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/cert/cert_database.h" - -#include "base/observer_list_threadsafe.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) {} - -CertDatabase::~CertDatabase() {} - -} // namespace net
diff --git a/net/cert/cert_database_ios.cc b/net/cert/cert_database_ios.cc deleted file mode 100644 index c426ee9..0000000 --- a/net/cert/cert_database_ios.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/cert/cert_database.h" - -#include "base/logging.h" -#include "base/observer_list_threadsafe.h" -#include "net/base/net_errors.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) { -} - -CertDatabase::~CertDatabase() {} - -} // namespace net
diff --git a/net/cert/cert_database_mac.cc b/net/cert/cert_database_mac.cc index 0cfd4154d..12dce73ac 100644 --- a/net/cert/cert_database_mac.cc +++ b/net/cert/cert_database_mac.cc
@@ -116,21 +116,16 @@ } void CertDatabase::SetMessageLoopForKeychainEvents() { - // Shutdown will take care to delete the notifier on the right thread. - if (notifier_.get()) - notifier_.release()->Shutdown(); - - notifier_.reset(new Notifier(this, base::MessageLoopCurrentForUI::Get())); + ReleaseNotifier(); + notifier_ = new Notifier(this, base::MessageLoopCurrentForUI::Get()); } -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) { -} - -CertDatabase::~CertDatabase() { +void CertDatabase::ReleaseNotifier() { // Shutdown will take care to delete the notifier on the right thread. - if (notifier_.get()) - notifier_.release()->Shutdown(); + if (notifier_) { + notifier_->Shutdown(); + notifier_ = nullptr; + } } } // namespace net
diff --git a/net/cert/cert_database_nss.cc b/net/cert/cert_database_nss.cc deleted file mode 100644 index 832f901..0000000 --- a/net/cert/cert_database_nss.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/cert/cert_database.h" - -#include "base/observer_list_threadsafe.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) { -} - -CertDatabase::~CertDatabase() = default; - -} // namespace net
diff --git a/net/cert/cert_database_stub.cc b/net/cert/cert_database_stub.cc deleted file mode 100644 index 63589b60..0000000 --- a/net/cert/cert_database_stub.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/cert/cert_database.h" - -#include "base/observer_list_threadsafe.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) {} - -CertDatabase::~CertDatabase() {} - -} // namespace net
diff --git a/net/cert/cert_database_win.cc b/net/cert/cert_database_win.cc deleted file mode 100644 index 32c9168..0000000 --- a/net/cert/cert_database_win.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright (c) 2010 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 "net/cert/cert_database.h" - -#include "base/observer_list_threadsafe.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) { -} - -CertDatabase::~CertDatabase() {} - -} // namespace net
diff --git a/net/cert/x509_util_android.cc b/net/cert/x509_util_android.cc index 8ee18742..2ef23d21e 100644 --- a/net/cert/x509_util_android.cc +++ b/net/cert/x509_util_android.cc
@@ -11,7 +11,7 @@ void JNI_X509Util_NotifyKeyChainChanged(JNIEnv* env, const JavaParamRef<jclass>& clazz) { - CertDatabase::GetInstance()->OnAndroidKeyChainChanged(); + CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); } } // namespace net
diff --git a/net/docs/bug-triage-suggested-workflow.md b/net/docs/bug-triage-suggested-workflow.md index dcde25f..c955025 100644 --- a/net/docs/bug-triage-suggested-workflow.md +++ b/net/docs/bug-triage-suggested-workflow.md
@@ -29,24 +29,6 @@ * If non-network causes also seem possible, attach those components as well. -## Investigate UMA notifications - -For each alert that fires, determine if it's a real alert and file a bug if so. - -* Don't file if the alert is coincident with a major volume change. The volume - at a particular date can be determined by hovering the mouse over the - appropriate location on the alert line. - -* Don't file if the alert is on a graph with very low volume (< ~200 data - points); it's probably noise, and we probably don't care even if it isn't. - -* Don't file if the graph is really noisy (but eyeball it to decide if there is - an underlying important shift under the noise). - -* Don't file if the alert is in the "Known Ignorable" list: - * SimpleCache on Windows - * DiskCache on Android. - ## Investigating component=Internals>Network bugs * Note that you may want to investigate Needs-Feedback bugs first, as
diff --git a/net/docs/bug-triage.md b/net/docs/bug-triage.md index eb349ad..d9b04143d 100644 --- a/net/docs/bug-triage.md +++ b/net/docs/bug-triage.md
@@ -8,7 +8,6 @@ ### Required, in rough order of priority: * Identify new network bugs on the tracker. -* Investigate UMA notifications. * Investigate recent Internals>Network issues with no subcomponent. * Follow up on Needs-Feedback issues for all network components. * Identify and file bugs for significant new crashers. @@ -33,8 +32,8 @@ * Identify new network bugs on the bug tracker, looking at [this issue tracker query](https://bugs.chromium.org/p/chromium/issues/list?q=status%3Aunconfirmed&sort=-id&num=1000). - * All Unconfirmed issues filed during your triage rotation should be scanned, - and, for suspected network bugs, a network component assigned and a + * All Unconfirmed issues filed during your triage rotation should be scanned + for suspected network bugs, a network component assigned and a chrome://net-export/ log requested. Suggested text: "Please collect and attach a chrome://net-export log. Instructions can be found here: https://sites.google.com/a/chromium.org/dev/for-testers/providing-network-details". @@ -45,24 +44,6 @@ 3:00 pm EST of the last day of the previous triager's rotation until the same time on the last day of their rotation. -* Investigate UMA notifications. - - * UMA notifications ("chirps") are alerts based on UMA histograms that are - sent to chrome-network-debugging@google.com. Triagers should subscribe - to this list. When an alert fires, the triager should determine if the - alert looks to be real and file a bug with the appropriate label if so. - Note that if no label more specific than Internals>Network is - appropriate, the responsibility remains with the triager to continue - investigating the bug, as above. - - * The triager is responsible for looking at any notification previous - triagers did not, so when an issue is investigated, the person who did - so should respond to chrome-network-debugging@google.com with a short - email, describing their conclusions. Future triagers can then use the - fact an alert was responded to as an indicator of which of them need - to be followed up on. Alerts fired before the beginning of the - previous triager's rotation may be ignored. - * Investigate [Unconfirmed / Untriaged Internals>Network issues that don't belong to a more specific network component](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified), prioritizing the most recent issues, ones with the most responsive reporters, and major crashers. This will generally take up the majority of your time as
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc index 5c446dd..9cd0edf 100644 --- a/net/http/http_proxy_client_socket.cc +++ b/net/http/http_proxy_client_socket.cc
@@ -223,7 +223,6 @@ // We reach this case when the user cancels a 407 proxy auth prompt. // See http://crbug.com/8473. DCHECK_EQ(407, response_.headers->response_code()); - LogBlockedTunnelResponse(); return ERR_TUNNEL_CONNECTION_FAILED; } @@ -301,12 +300,6 @@ return OK; } -void HttpProxyClientSocket::LogBlockedTunnelResponse() const { - ProxyClientSocket::LogBlockedTunnelResponse( - response_.headers->response_code(), - is_https_proxy_); -} - void HttpProxyClientSocket::DoCallback(int result) { DCHECK_NE(ERR_IO_PENDING, result); DCHECK(!user_callback_.is_null()); @@ -470,10 +463,8 @@ // sanitize the response. This still allows a rogue HTTPS proxy to // redirect an HTTPS site load to a similar-looking site, but no longer // allows it to impersonate the site the user requested. - if (!is_https_proxy_ || !SanitizeProxyRedirect(&response_)) { - LogBlockedTunnelResponse(); + if (!is_https_proxy_ || !SanitizeProxyRedirect(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - } redirect_has_load_timing_info_ = transport_->GetLoadTimingInfo( http_stream_parser_->IsConnectionReused(), @@ -487,10 +478,8 @@ // authentication code is smart enough to avoid being tricked by an // active network attacker. // The next state is intentionally not set as it should be STATE_NONE; - if (!SanitizeProxyAuth(&response_)) { - LogBlockedTunnelResponse(); + if (!SanitizeProxyAuth(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - } return HandleProxyAuthChallenge(auth_.get(), &response_, net_log_); default: @@ -500,7 +489,6 @@ // 501 response bodies that contain a useful error message. For // example, Squid uses a 404 response to report the DNS error: "The // domain name does not exist." - LogBlockedTunnelResponse(); return ERR_TUNNEL_CONNECTION_FAILED; } }
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h index 15bd9a5..c744158 100644 --- a/net/http/http_proxy_client_socket.h +++ b/net/http/http_proxy_client_socket.h
@@ -114,8 +114,6 @@ int PrepareForAuthRestart(); int DidDrainBodyForAuthRestart(); - void LogBlockedTunnelResponse() const; - void DoCallback(int result); void OnIOComplete(int result);
diff --git a/net/http/proxy_client_socket.cc b/net/http/proxy_client_socket.cc index 1cfa0c3..fe23978 100644 --- a/net/http/proxy_client_socket.cc +++ b/net/http/proxy_client_socket.cc
@@ -57,22 +57,6 @@ } // static -void ProxyClientSocket::LogBlockedTunnelResponse(int http_status_code, - bool is_https_proxy) { - if (is_https_proxy) { - UMA_HISTOGRAM_CUSTOM_ENUMERATION( - "Net.BlockedTunnelResponse.HttpsProxy", - HttpUtil::MapStatusCodeForHistogram(http_status_code), - HttpUtil::GetStatusCodesForHistogram()); - } else { - UMA_HISTOGRAM_CUSTOM_ENUMERATION( - "Net.BlockedTunnelResponse.HttpProxy", - HttpUtil::MapStatusCodeForHistogram(http_status_code), - HttpUtil::GetStatusCodesForHistogram()); - } -} - -// static bool ProxyClientSocket::SanitizeProxyAuth(HttpResponseInfo* response) { DCHECK(response && response->headers.get());
diff --git a/net/http/proxy_client_socket.h b/net/http/proxy_client_socket.h index 7979f77..046ea6c7 100644 --- a/net/http/proxy_client_socket.h +++ b/net/http/proxy_client_socket.h
@@ -74,10 +74,6 @@ HttpResponseInfo* response, const NetLogWithSource& net_log); - // Logs (to the log and in a histogram) a blocked CONNECT response. - static void LogBlockedTunnelResponse(int http_response_code, - bool is_https_proxy); - // When a proxy authentication response is received during tunnel // construction, this method should be called to strip everything // but the auth header from the redirect response. If it returns
diff --git a/net/quic/chromium/quic_proxy_client_socket.cc b/net/quic/chromium/quic_proxy_client_socket.cc index 703c919..baa81021 100644 --- a/net/quic/chromium/quic_proxy_client_socket.cc +++ b/net/quic/chromium/quic_proxy_client_socket.cc
@@ -270,12 +270,6 @@ : ERR_SOCKET_NOT_CONNECTED; } -void QuicProxyClientSocket::LogBlockedTunnelResponse() const { - ProxyClientSocket::LogBlockedTunnelResponse( - response_.headers->response_code(), - /* is_https_proxy = */ true); -} - void QuicProxyClientSocket::OnIOComplete(int result) { DCHECK_NE(STATE_DISCONNECTED, next_state_); int rv = DoLoop(result); @@ -419,10 +413,8 @@ case 302: // Found / Moved Temporarily // Try to return a sanitized response so we can follow auth redirects. // If we can't, fail the tunnel connection. - if (!SanitizeProxyRedirect(&response_)) { - LogBlockedTunnelResponse(); + if (!SanitizeProxyRedirect(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - } redirect_has_load_timing_info_ = GetLoadTimingInfo(&redirect_load_timing_info_); next_state_ = STATE_DISCONNECTED; @@ -430,16 +422,13 @@ case 407: // Proxy Authentication Required next_state_ = STATE_CONNECT_COMPLETE; - if (!SanitizeProxyAuth(&response_)) { - LogBlockedTunnelResponse(); + if (!SanitizeProxyAuth(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - } return HandleProxyAuthChallenge(auth_.get(), &response_, net_log_); default: // Ignore response to avoid letting the proxy impersonate the target // server. (See http://crbug.com/137891.) - LogBlockedTunnelResponse(); return ERR_TUNNEL_CONNECTION_FAILED; } }
diff --git a/net/quic/chromium/quic_proxy_client_socket.h b/net/quic/chromium/quic_proxy_client_socket.h index 6c98e7c..903527d 100644 --- a/net/quic/chromium/quic_proxy_client_socket.h +++ b/net/quic/chromium/quic_proxy_client_socket.h
@@ -91,8 +91,6 @@ STATE_CONNECT_COMPLETE }; - void LogBlockedTunnelResponse() const; - void OnIOComplete(int result); // Callback used during connecting void OnReadComplete(int rv); void OnWriteComplete(int rv);
diff --git a/net/spdy/chromium/header_coalescer.cc b/net/spdy/chromium/header_coalescer.cc index d2f80f7..2b0206a2 100644 --- a/net/spdy/chromium/header_coalescer.cc +++ b/net/spdy/chromium/header_coalescer.cc
@@ -5,6 +5,7 @@ #include "net/spdy/chromium/header_coalescer.h" #include <memory> +#include <string> #include <utility> #include "base/bind.h"
diff --git a/net/spdy/chromium/header_coalescer_test.cc b/net/spdy/chromium/header_coalescer_test.cc index 14bf757..c8c1534e 100644 --- a/net/spdy/chromium/header_coalescer_test.cc +++ b/net/spdy/chromium/header_coalescer_test.cc
@@ -4,6 +4,7 @@ #include "net/spdy/chromium/header_coalescer.h" +#include <string> #include <vector> #include "net/log/test_net_log.h"
diff --git a/net/spdy/chromium/http2_push_promise_index.cc b/net/spdy/chromium/http2_push_promise_index.cc index f0f280c..b8ed939 100644 --- a/net/spdy/chromium/http2_push_promise_index.cc +++ b/net/spdy/chromium/http2_push_promise_index.cc
@@ -3,11 +3,12 @@ // found in the LICENSE file. #include "net/spdy/chromium/http2_push_promise_index.h" -#include "base/trace_event/memory_usage_estimator.h" #include <algorithm> #include <utility> +#include "base/trace_event/memory_usage_estimator.h" + namespace net { Http2PushPromiseIndex::Http2PushPromiseIndex() = default;
diff --git a/net/spdy/chromium/http2_push_promise_index_test.cc b/net/spdy/chromium/http2_push_promise_index_test.cc index 39d9d83..3f5706fa 100644 --- a/net/spdy/chromium/http2_push_promise_index_test.cc +++ b/net/spdy/chromium/http2_push_promise_index_test.cc
@@ -28,7 +28,7 @@ class TestDelegate : public Http2PushPromiseIndex::Delegate { public: TestDelegate() = delete; - TestDelegate(const SpdySessionKey& key) : key_(key) {} + explicit TestDelegate(const SpdySessionKey& key) : key_(key) {} ~TestDelegate() override {} bool ValidatePushedStream(SpdyStreamId stream_id, @@ -417,7 +417,7 @@ // (which then must be |entry2|). std::tie(std::ignore, success) = entries.insert(entry2); EXPECT_FALSE(success); -}; +} TEST(Http2PushPromiseIndexCompareByUrlTest, LookupByURL) { const GURL url1("https://example.com:1"); @@ -463,7 +463,7 @@ EXPECT_TRUE( entries.lower_bound(Http2PushPromiseIndexPeer::UnclaimedPushedStream{ url2, nullptr, kNoPushedStreamFound}) == entries.find(entry2)); -}; +} } // namespace test } // namespace net
diff --git a/net/spdy/chromium/multiplexed_http_stream.cc b/net/spdy/chromium/multiplexed_http_stream.cc index 028b263..f25fa9a 100644 --- a/net/spdy/chromium/multiplexed_http_stream.cc +++ b/net/spdy/chromium/multiplexed_http_stream.cc
@@ -4,6 +4,8 @@ #include "net/spdy/chromium/multiplexed_http_stream.h" +#include <utility> + #include "base/logging.h" #include "net/http/http_raw_request_headers.h" #include "net/third_party/spdy/core/spdy_header_block.h"
diff --git a/net/spdy/chromium/spdy_log_util.cc b/net/spdy/chromium/spdy_log_util.cc index b1d20b7..2ba44f301 100644 --- a/net/spdy/chromium/spdy_log_util.cc +++ b/net/spdy/chromium/spdy_log_util.cc
@@ -4,6 +4,8 @@ #include "net/spdy/chromium/spdy_log_util.h" +#include <utility> + #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "net/http/http_log_util.h"
diff --git a/net/spdy/chromium/spdy_proxy_client_socket.cc b/net/spdy/chromium/spdy_proxy_client_socket.cc index 6a6dcce..a7cbd58 100644 --- a/net/spdy/chromium/spdy_proxy_client_socket.cc +++ b/net/spdy/chromium/spdy_proxy_client_socket.cc
@@ -268,12 +268,6 @@ return spdy_stream_->GetLocalAddress(address); } -void SpdyProxyClientSocket::LogBlockedTunnelResponse() const { - ProxyClientSocket::LogBlockedTunnelResponse( - response_.headers->response_code(), - /* is_https_proxy = */ true); -} - void SpdyProxyClientSocket::RunCallback(CompletionOnceCallback callback, int result) const { std::move(callback).Run(result); @@ -406,10 +400,8 @@ case 302: // Found / Moved Temporarily // Try to return a sanitized response so we can follow auth redirects. // If we can't, fail the tunnel connection. - if (!SanitizeProxyRedirect(&response_)) { - LogBlockedTunnelResponse(); + if (!SanitizeProxyRedirect(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - } redirect_has_load_timing_info_ = spdy_stream_->GetLoadTimingInfo(&redirect_load_timing_info_); @@ -420,16 +412,13 @@ case 407: // Proxy Authentication Required next_state_ = STATE_OPEN; - if (!SanitizeProxyAuth(&response_)) { - LogBlockedTunnelResponse(); + if (!SanitizeProxyAuth(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - } return HandleProxyAuthChallenge(auth_.get(), &response_, net_log_); default: // Ignore response to avoid letting the proxy impersonate the target // server. (See http://crbug.com/137891.) - LogBlockedTunnelResponse(); return ERR_TUNNEL_CONNECTION_FAILED; } }
diff --git a/net/spdy/chromium/spdy_proxy_client_socket.h b/net/spdy/chromium/spdy_proxy_client_socket.h index 2ade4b9a..e05f652 100644 --- a/net/spdy/chromium/spdy_proxy_client_socket.h +++ b/net/spdy/chromium/spdy_proxy_client_socket.h
@@ -116,8 +116,6 @@ STATE_CLOSED }; - void LogBlockedTunnelResponse() const; - // Calls |callback.Run(result)|. Used to run a callback posted to the // message loop. void RunCallback(CompletionOnceCallback callback, int result) const;
diff --git a/net/spdy/chromium/spdy_session.cc b/net/spdy/chromium/spdy_session.cc index 267da7c..9bf6a8e 100644 --- a/net/spdy/chromium/spdy_session.cc +++ b/net/spdy/chromium/spdy_session.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <limits> #include <map> +#include <string> #include <utility> #include "base/bind.h" @@ -1449,21 +1450,21 @@ // 206 Partial Content and 416 Requested Range Not Satisfiable are range // responses. if (status_it->second == "206" || status_it->second == "416") { - SpdyHeaderBlock::const_iterator client_request_range_it = - stream_it->second->request_headers().find("range"); - if (client_request_range_it == stream_it->second->request_headers().end()) { + std::string client_request_range; + if (!request_info.extra_headers.GetHeader(HttpRequestHeaders::kRange, + &client_request_range)) { // Client initiated request is not a range request. // TODO(https://crbug.com/831536): Add histogram. return false; } - std::string pushed_request_range; - if (!request_info.extra_headers.GetHeader(HttpRequestHeaders::kRange, - &pushed_request_range)) { + SpdyHeaderBlock::const_iterator pushed_request_range_it = + stream_it->second->request_headers().find("range"); + if (pushed_request_range_it == stream_it->second->request_headers().end()) { // Pushed request is not a range request. // TODO(https://crbug.com/831536): Add histogram. return false; } - if (client_request_range_it->second != pushed_request_range) { + if (client_request_range != pushed_request_range_it->second) { // Client and pushed request ranges do not match. // TODO(https://crbug.com/831536): Add histogram. return false;
diff --git a/net/spdy/chromium/spdy_session_unittest.cc b/net/spdy/chromium/spdy_session_unittest.cc index 96b77c3..e138343 100644 --- a/net/spdy/chromium/spdy_session_unittest.cc +++ b/net/spdy/chromium/spdy_session_unittest.cc
@@ -5,6 +5,7 @@ #include "net/spdy/chromium/spdy_session.h" #include <algorithm> +#include <string> #include <utility> #include "base/base64.h"
diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn index be500ae..ec20831 100644 --- a/services/audio/BUILD.gn +++ b/services/audio/BUILD.gn
@@ -34,6 +34,8 @@ "debug_recording.h", "delay_buffer.cc", "delay_buffer.h", + "device_notifier.cc", + "device_notifier.h", "group_coordinator.cc", "group_coordinator.h", "group_member.h", @@ -81,12 +83,14 @@ sources = [ "debug_recording_unittest.cc", "delay_buffer_unittest.cc", + "device_notifier_unittest.cc", "group_coordinator_unittest.cc", "input_stream_unittest.cc", "local_muter_unittest.cc", "loopback_stream_unittest.cc", "output_controller_unittest.cc", "output_stream_unittest.cc", + "public/cpp/input_ipc_unittest.cc", "snooper_node_unittest.cc", "stream_factory_unittest.cc", "sync_reader_unittest.cc",
diff --git a/services/audio/device_notifier.cc b/services/audio/device_notifier.cc new file mode 100644 index 0000000..4f07f11 --- /dev/null +++ b/services/audio/device_notifier.cc
@@ -0,0 +1,62 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/audio/device_notifier.h" + +#include <utility> + +#include "base/sequenced_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "services/service_manager/public/cpp/service_context_ref.h" + +namespace audio { + +DeviceNotifier::DeviceNotifier() + : task_runner_(base::SequencedTaskRunnerHandle::Get()), + weak_factory_(this) {} + +DeviceNotifier::~DeviceNotifier() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); +} + +void DeviceNotifier::Bind( + mojom::DeviceNotifierRequest request, + std::unique_ptr<service_manager::ServiceContextRef> context_ref) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + bindings_.AddBinding(this, std::move(request), std::move(context_ref)); + base::SystemMonitor::Get()->AddDevicesChangedObserver(this); +} + +void DeviceNotifier::RegisterListener(mojom::DeviceListenerPtr listener) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + int listener_id = next_listener_id_++; + listener.set_connection_error_handler( + base::BindRepeating(&DeviceNotifier::RemoveListener, + weak_factory_.GetWeakPtr(), listener_id)); + listeners_[listener_id] = std::move(listener); +} + +void DeviceNotifier::OnDevicesChanged( + base::SystemMonitor::DeviceType device_type) { + if (device_type != base::SystemMonitor::DEVTYPE_AUDIO) + return; + + task_runner_->PostTask(FROM_HERE, + base::BindRepeating(&DeviceNotifier::UpdateListeners, + weak_factory_.GetWeakPtr())); +} + +void DeviceNotifier::UpdateListeners() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + for (const auto& listener : listeners_) + listener.second->DevicesChanged(); +} + +void DeviceNotifier::RemoveListener(int listener_id) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + listeners_.erase(listener_id); +} + +} // namespace audio
diff --git a/services/audio/device_notifier.h b/services/audio/device_notifier.h new file mode 100644 index 0000000..e61aaac --- /dev/null +++ b/services/audio/device_notifier.h
@@ -0,0 +1,59 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_AUDIO_DEVICE_NOTIFIER_H_ +#define SERVICES_AUDIO_DEVICE_NOTIFIER_H_ + +#include <memory> + +#include "base/containers/flat_map.h" +#include "base/system_monitor/system_monitor.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/audio/public/mojom/device_notifications.mojom.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace service_manager { +class ServiceContextRef; +} + +namespace audio { + +// This class publishes notifications about changes in the audio devices +// to registered listeners. +class DeviceNotifier final : public base::SystemMonitor::DevicesChangedObserver, + public mojom::DeviceNotifier { + public: + DeviceNotifier(); + ~DeviceNotifier() final; + + void Bind(mojom::DeviceNotifierRequest request, + std::unique_ptr<service_manager::ServiceContextRef> context_ref); + + // mojom::DeviceNotifier implementation. + void RegisterListener(mojom::DeviceListenerPtr listener) final; + + // base::SystemMonitor::DevicesChangedObserver implementation; + void OnDevicesChanged(base::SystemMonitor::DeviceType device_type) final; + + private: + void UpdateListeners(); + void RemoveListener(int listener_id); + + int next_listener_id_ = 0; + base::flat_map<int, mojom::DeviceListenerPtr> listeners_; + mojo::BindingSet<mojom::DeviceNotifier, + std::unique_ptr<service_manager::ServiceContextRef>> + bindings_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + base::WeakPtrFactory<DeviceNotifier> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(DeviceNotifier); +}; + +} // namespace audio + +#endif // SERVICES_AUDIO_DEVICE_NOTIFIER_H_
diff --git a/services/audio/device_notifier_unittest.cc b/services/audio/device_notifier_unittest.cc new file mode 100644 index 0000000..bedb7ae --- /dev/null +++ b/services/audio/device_notifier_unittest.cc
@@ -0,0 +1,100 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/audio/device_notifier.h" + +#include <memory> +#include <utility> + +#include "base/system_monitor/system_monitor.h" +#include "base/test/scoped_task_environment.h" +#include "services/audio/public/mojom/device_notifications.mojom.h" +#include "services/service_manager/public/cpp/service_context_ref.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace audio { + +namespace { + +class MockDeviceListener : public mojom::DeviceListener { + public: + explicit MockDeviceListener(audio::mojom::DeviceListenerRequest request) + : binding_(this, std::move(request)) {} + MOCK_METHOD0(DevicesChanged, void()); + + private: + mojo::Binding<audio::mojom::DeviceListener> binding_; + + DISALLOW_COPY_AND_ASSIGN(MockDeviceListener); +}; + +} // namespace + +class DeviceNotifierTest : public ::testing::Test { + public: + DeviceNotifierTest() + : system_monitor_(std::make_unique<base::SystemMonitor>()), + service_ref_factory_( + base::BindRepeating(&DeviceNotifierTest::OnNoServiceRefs, + base::Unretained(this))) {} + + protected: + MOCK_METHOD0(OnNoServiceRefs, void()); + + void CreateDeviceNotifier() { + device_notifier_ = std::make_unique<DeviceNotifier>(); + device_notifier_->Bind(mojo::MakeRequest(&device_notifier_ptr_), + service_ref_factory_.CreateRef()); + EXPECT_FALSE(service_ref_factory_.HasNoRefs()); + } + + void DestroyDeviceNotifier() { + device_notifier_ptr_.reset(); + scoped_task_environment_.RunUntilIdle(); + EXPECT_TRUE(service_ref_factory_.HasNoRefs()); + } + + base::test::ScopedTaskEnvironment scoped_task_environment_; + mojom::DeviceNotifierPtr device_notifier_ptr_; + + private: + std::unique_ptr<base::SystemMonitor> system_monitor_; + std::unique_ptr<DeviceNotifier> device_notifier_; + service_manager::ServiceContextRefFactory service_ref_factory_; + + DISALLOW_COPY_AND_ASSIGN(DeviceNotifierTest); +}; + +TEST_F(DeviceNotifierTest, DeviceNotifierNotifies) { + EXPECT_CALL(*this, OnNoServiceRefs()); + CreateDeviceNotifier(); + + mojom::DeviceListenerPtr device_listener_ptr; + MockDeviceListener listener(mojo::MakeRequest(&device_listener_ptr)); + + // Simulate audio-device event, but no callback should be invoked before the + // listener is registered. + EXPECT_CALL(listener, DevicesChanged()).Times(0); + base::SystemMonitor::Get()->ProcessDevicesChanged( + base::SystemMonitor::DEVTYPE_AUDIO); + scoped_task_environment_.RunUntilIdle(); + + // Register the listener and simulate an audio-device event. + device_notifier_ptr_->RegisterListener(std::move(device_listener_ptr)); + EXPECT_CALL(listener, DevicesChanged()); + base::SystemMonitor::Get()->ProcessDevicesChanged( + base::SystemMonitor::DEVTYPE_AUDIO); + scoped_task_environment_.RunUntilIdle(); + + // Simulate a video-device event, which should be ignored. + EXPECT_CALL(listener, DevicesChanged()).Times(0); + base::SystemMonitor::Get()->ProcessDevicesChanged( + base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE); + scoped_task_environment_.RunUntilIdle(); + + DestroyDeviceNotifier(); +} + +} // namespace audio
diff --git a/services/audio/manifest.json b/services/audio/manifest.json index 4f6637e2..beb981b 100644 --- a/services/audio/manifest.json +++ b/services/audio/manifest.json
@@ -7,7 +7,8 @@ "provides": { "info": [ "audio::mojom::SystemInfo" ], "debug_recording": [ "audio::mojom::DebugRecording" ], - "stream_factory": [ "audio::mojom::StreamFactory" ] + "stream_factory": [ "audio::mojom::StreamFactory" ], + "device_notifier": [ "audio::mojom::DeviceNotifier" ] }, "requires": { "service_manager": [ "service_manager:all_users" ]
diff --git a/services/audio/public/cpp/BUILD.gn b/services/audio/public/cpp/BUILD.gn index ea40a26..dd06c3e 100644 --- a/services/audio/public/cpp/BUILD.gn +++ b/services/audio/public/cpp/BUILD.gn
@@ -12,6 +12,10 @@ "debug_recording_session.h", "debug_recording_session_factory.cc", "debug_recording_session_factory.h", + "device_factory.cc", + "device_factory.h", + "input_ipc.cc", + "input_ipc.h", ] public_deps = [
diff --git a/services/audio/public/cpp/device_factory.cc b/services/audio/public/cpp/device_factory.cc new file mode 100644 index 0000000..e92fb2f --- /dev/null +++ b/services/audio/public/cpp/device_factory.cc
@@ -0,0 +1,33 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/audio/public/cpp/device_factory.h" + +#include <memory> + +#include "base/bind.h" +#include "services/audio/public/cpp/input_ipc.h" + +namespace audio { + +scoped_refptr<media::AudioCapturerSource> CreateInputDevice( + std::unique_ptr<service_manager::Connector> connector, + const std::string& device_id, + media::mojom::AudioLogPtr log) { + std::unique_ptr<media::AudioInputIPC> ipc = std::make_unique<InputIPC>( + std::move(connector), device_id, std::move(log)); + + return base::MakeRefCounted<media::AudioInputDevice>(std::move(ipc)); +} + +scoped_refptr<media::AudioCapturerSource> CreateInputDevice( + std::unique_ptr<service_manager::Connector> connector, + const std::string& device_id) { + std::unique_ptr<media::AudioInputIPC> ipc = + std::make_unique<InputIPC>(std::move(connector), device_id, nullptr); + + return base::MakeRefCounted<media::AudioInputDevice>(std::move(ipc)); +} + +} // namespace audio
diff --git a/services/audio/public/cpp/device_factory.h b/services/audio/public/cpp/device_factory.h new file mode 100644 index 0000000..a1b2d12 --- /dev/null +++ b/services/audio/public/cpp/device_factory.h
@@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_AUDIO_PUBLIC_CPP_DEVICE_FACTORY_H_ +#define SERVICES_AUDIO_PUBLIC_CPP_DEVICE_FACTORY_H_ + +#include "media/audio/audio_input_device.h" + +#include "services/audio/public/mojom/stream_factory.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace audio { + +scoped_refptr<media::AudioCapturerSource> CreateInputDevice( + std::unique_ptr<service_manager::Connector> connector, + const std::string& device_id); + +scoped_refptr<media::AudioCapturerSource> CreateInputDevice( + std::unique_ptr<service_manager::Connector> connector, + const std::string& device_id, + media::mojom::AudioLogPtr); + +} // namespace audio + +#endif // SERVICES_AUDIO_PUBLIC_CPP_DEVICE_FACTORY_H_
diff --git a/services/audio/public/cpp/fake_stream_factory.h b/services/audio/public/cpp/fake_stream_factory.h index 38d06e5c..811881d 100644 --- a/services/audio/public/cpp/fake_stream_factory.h +++ b/services/audio/public/cpp/fake_stream_factory.h
@@ -24,6 +24,8 @@ return ptr; } + void CloseBinding() { binding_.Close(); } + void CreateInputStream(media::mojom::AudioInputStreamRequest stream_request, media::mojom::AudioInputStreamClientPtr client, media::mojom::AudioInputStreamObserverPtr observer,
diff --git a/services/audio/public/cpp/input_ipc.cc b/services/audio/public/cpp/input_ipc.cc new file mode 100644 index 0000000..fda6852 --- /dev/null +++ b/services/audio/public/cpp/input_ipc.cc
@@ -0,0 +1,123 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/audio/public/cpp/input_ipc.h" + +#include <utility> + +#include "base/bind_helpers.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "services/audio/public/mojom/constants.mojom.h" + +namespace audio { + +InputIPC::InputIPC(std::unique_ptr<service_manager::Connector> connector, + const std::string& device_id, + media::mojom::AudioLogPtr log) + : stream_(), + stream_client_binding_(this), + device_id_(std::move(device_id)), + stream_factory_(), + stream_factory_info_(), + log_(std::move(log)), + weak_factory_(this) { + DETACH_FROM_SEQUENCE(sequence_checker_); + DCHECK(connector); + + connector->BindInterface(audio::mojom::kServiceName, + mojo::MakeRequest(&stream_factory_info_)); +} + +InputIPC::~InputIPC() = default; + +void InputIPC::CreateStream(media::AudioInputIPCDelegate* delegate, + const media::AudioParameters& params, + bool automatic_gain_control, + uint32_t total_segments) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(delegate); + DCHECK(!delegate_); + + delegate_ = delegate; + + if (!stream_factory_.is_bound()) + stream_factory_.Bind(std::move(stream_factory_info_)); + + media::mojom::AudioInputStreamRequest stream_request = + mojo::MakeRequest(&stream_); + + media::mojom::AudioInputStreamClientPtr client; + stream_client_binding_.Bind(mojo::MakeRequest(&client)); + + // Unretained is safe because we own the binding. + stream_client_binding_.set_connection_error_handler( + base::BindOnce(&InputIPC::OnError, base::Unretained(this))); + + // For now we don't care about key presses, so we pass a invalid buffer. + mojo::ScopedSharedBufferHandle invalid_key_press_count_buffer; + + stream_factory_->CreateInputStream( + std::move(stream_request), std::move(client), nullptr, + log_ ? std::move(log_) : nullptr, device_id_, params, total_segments, + automatic_gain_control, std::move(invalid_key_press_count_buffer), + base::BindOnce(&InputIPC::StreamCreated, weak_factory_.GetWeakPtr())); +} + +void InputIPC::StreamCreated(media::mojom::AudioDataPipePtr data_pipe, + bool initially_muted) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(delegate_); + + if (data_pipe.is_null()) { + OnError(); + return; + } + + base::PlatformFile socket_handle; + auto result = + mojo::UnwrapPlatformFile(std::move(data_pipe->socket), &socket_handle); + DCHECK_EQ(result, MOJO_RESULT_OK); + base::SharedMemoryHandle memory_handle; + mojo::UnwrappedSharedMemoryHandleProtection protection; + result = mojo::UnwrapSharedMemoryHandle(std::move(data_pipe->shared_memory), + &memory_handle, nullptr, &protection); + DCHECK_EQ(result, MOJO_RESULT_OK); + DCHECK_EQ(protection, mojo::UnwrappedSharedMemoryHandleProtection::kReadOnly); + + delegate_->OnStreamCreated(memory_handle, socket_handle, initially_muted); +} + +void InputIPC::RecordStream() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(stream_.is_bound()); + stream_->Record(); +} + +void InputIPC::SetVolume(double volume) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(stream_.is_bound()); + stream_->SetVolume(volume); +} + +void InputIPC::CloseStream() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + delegate_ = nullptr; + if (stream_client_binding_.is_bound()) + stream_client_binding_.Close(); + stream_.reset(); +} + +void InputIPC::OnError() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(delegate_); + delegate_->OnError(); +} + +void InputIPC::OnMutedStateChanged(bool is_muted) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(delegate_); + delegate_->OnMuted(is_muted); +} + +} // namespace audio
diff --git a/services/audio/public/cpp/input_ipc.h b/services/audio/public/cpp/input_ipc.h new file mode 100644 index 0000000..06fb0370 --- /dev/null +++ b/services/audio/public/cpp/input_ipc.h
@@ -0,0 +1,73 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_AUDIO_PUBLIC_CPP_INPUT_IPC_H_ +#define SERVICES_AUDIO_PUBLIC_CPP_INPUT_IPC_H_ + +#include <string> + +#include "base/callback_helpers.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/time/time.h" +#include "media/audio/audio_input_ipc.h" +#include "media/mojo/interfaces/audio_input_stream.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/audio/public/mojom/stream_factory.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace audio { + +// InputIPC is a client-side class for handling creation, +// initialization and control of an input stream. May only be used on a single +// thread. +class InputIPC : public media::AudioInputIPC, + public media::mojom::AudioInputStreamClient { + public: + explicit InputIPC(std::unique_ptr<service_manager::Connector> connector, + const std::string& device_id, + media::mojom::AudioLogPtr log); + ~InputIPC() override; + + // AudioInputIPC implementation + void CreateStream(media::AudioInputIPCDelegate* delegate, + const media::AudioParameters& params, + bool automatic_gain_control, + uint32_t total_segments) override; + void RecordStream() override; + void SetVolume(double volume) override; + void CloseStream() override; + + private: + // AudioInputStreamClient implementation. + void OnError() override; + void OnMutedStateChanged(bool is_muted) override; + + void StreamCreated(media::mojom::AudioDataPipePtr data_pipe, bool is_muted); + + SEQUENCE_CHECKER(sequence_checker_); + + media::mojom::AudioInputStreamPtr stream_; + mojo::Binding<AudioInputStreamClient> stream_client_binding_; + media::AudioInputIPCDelegate* delegate_ = nullptr; + + const std::string& device_id_; + + // stream_factory_info_ is bound in the constructor, and later used to + // bind stream_factory_. This is done because the constructor may be called + // from a different thread than the other functions. + audio::mojom::StreamFactoryPtr stream_factory_; + audio::mojom::StreamFactoryPtrInfo stream_factory_info_; + + media::mojom::AudioLogPtr log_; + + base::WeakPtrFactory<InputIPC> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(InputIPC); +}; + +} // namespace audio + +#endif // SERVICES_AUDIO_PUBLIC_CPP_INPUT_IPC_H_
diff --git a/services/audio/public/cpp/input_ipc_unittest.cc b/services/audio/public/cpp/input_ipc_unittest.cc new file mode 100644 index 0000000..9137b1b --- /dev/null +++ b/services/audio/public/cpp/input_ipc_unittest.cc
@@ -0,0 +1,247 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/audio/public/cpp/input_ipc.h" + +#include "base/test/scoped_task_environment.h" +#include "media/mojo/interfaces/audio_data_pipe.mojom.h" +#include "mojo/public/cpp/system/buffer.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "services/audio/public/cpp/device_factory.h" +#include "services/audio/public/mojom/constants.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::StrictMock; + +namespace audio { + +namespace { + +const std::string& kDeviceId = "1234"; +const size_t kShMemSize = 456; +const double kNewVolume = 0.271828; + +class MockStream : public media::mojom::AudioInputStream { + public: + MOCK_METHOD0(Record, void()); + MOCK_METHOD1(SetVolume, void(double)); +}; + +class FakeStreamFactory : public audio::mojom::StreamFactory { + public: + FakeStreamFactory() : binding_(this), stream_(), stream_binding_(&stream_) {} + ~FakeStreamFactory() override = default; + void CreateInputStream(media::mojom::AudioInputStreamRequest stream_request, + media::mojom::AudioInputStreamClientPtr client, + media::mojom::AudioInputStreamObserverPtr observer, + media::mojom::AudioLogPtr log, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + mojo::ScopedSharedBufferHandle key_press_count_buffer, + CreateInputStreamCallback created_callback) { + if (should_fail_) { + std::move(created_callback).Run(nullptr, initially_muted_); + return; + } + + // Keep the client alive to avoid binding errors. + client_ = std::move(client); + + if (stream_binding_.is_bound()) + stream_binding_.Unbind(); + + stream_binding_.Bind(std::move(stream_request)); + + base::SyncSocket socket1, socket2; + base::SyncSocket::CreatePair(&socket1, &socket2); + auto h = mojo::SharedBufferHandle::Create(kShMemSize); + std::move(created_callback) + .Run({base::in_place, + h->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY), + mojo::WrapPlatformFile(socket1.Release())}, + initially_muted_); + } + + MOCK_METHOD7(CreateOutputStream, + void(media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamObserverAssociatedPtrInfo + observer_info, + media::mojom::AudioLogPtr log, + const std::string& output_device_id, + const media::AudioParameters& params, + const base::UnguessableToken& group_id, + CreateOutputStreamCallback created_callback)); + + MOCK_METHOD2(BindMuter, + void(mojom::LocalMuterAssociatedRequest request, + const base::UnguessableToken& group_id)); + + void Bind(mojo::ScopedMessagePipeHandle handle) { + binding_.Bind(audio::mojom::StreamFactoryRequest(std::move(handle))); + } + + mojo::Binding<audio::mojom::StreamFactory> binding_; + StrictMock<MockStream> stream_; + media::mojom::AudioInputStreamClientPtr client_; + mojo::Binding<media::mojom::AudioInputStream> stream_binding_; + bool initially_muted_ = true; + bool should_fail_ = false; +}; + +class MockDelegate : public media::AudioInputIPCDelegate { + public: + MockDelegate() {} + ~MockDelegate() override {} + + void OnStreamCreated(base::SharedMemoryHandle mem_handle, + base::SyncSocket::Handle socket_handle, + bool initially_muted) override { + base::SharedMemory sh_mem( + mem_handle, /*read_only*/ true); // Releases the shared memory handle. + base::SyncSocket socket(socket_handle); // Releases the socket descriptor. + GotOnStreamCreated(initially_muted); + } + + MOCK_METHOD1(GotOnStreamCreated, void(bool initially_muted)); + MOCK_METHOD0(OnError, void()); + MOCK_METHOD1(OnMuted, void(bool)); + MOCK_METHOD0(OnIPCClosed, void()); +}; + +class InputIPCTest : public ::testing::Test { + public: + base::test::ScopedTaskEnvironment scoped_task_environment; + std::unique_ptr<audio::InputIPC> ipc; + const media::AudioParameters audioParameters = + media::AudioParameters(media::AudioParameters::AUDIO_PCM_LINEAR, + media::CHANNEL_LAYOUT_STEREO, + 16000, + 1600); + + protected: + InputIPCTest() + : scoped_task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT, + base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED) {} + std::unique_ptr<StrictMock<FakeStreamFactory>> factory_; + + void SetUp() override { + service_manager::mojom::ConnectorRequest request; + std::unique_ptr<service_manager::Connector> connector = + service_manager::Connector::Create(&request); + + factory_ = std::make_unique<StrictMock<FakeStreamFactory>>(); + { + service_manager::Connector::TestApi test_api(connector.get()); + + test_api.OverrideBinderForTesting( + service_manager::Identity(audio::mojom::kServiceName), + audio::mojom::StreamFactory::Name_, + base::BindRepeating(&FakeStreamFactory::Bind, + base::Unretained(factory_.get()))); + } + ipc = std::make_unique<InputIPC>(std::move(connector), kDeviceId, nullptr); + } +}; + +} // namespace + +TEST_F(InputIPCTest, CreateStreamPropagates) { + StrictMock<MockDelegate> delegate; + EXPECT_CALL(delegate, GotOnStreamCreated(_)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); +} + +TEST_F(InputIPCTest, CreateStreamPropagatesInitiallyMuted) { + StrictMock<MockDelegate> delegate; + + factory_->initially_muted_ = true; + EXPECT_CALL(delegate, GotOnStreamCreated(true)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); + ipc->CloseStream(); + scoped_task_environment.RunUntilIdle(); + + factory_->initially_muted_ = false; + EXPECT_CALL(delegate, GotOnStreamCreated(false)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); + ipc->CloseStream(); + scoped_task_environment.RunUntilIdle(); +} + +TEST_F(InputIPCTest, MutedStateChangesPropagates) { + StrictMock<MockDelegate> delegate; + + EXPECT_CALL(delegate, GotOnStreamCreated(_)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); + + EXPECT_CALL(delegate, OnMuted(true)); + factory_->client_->OnMutedStateChanged(true); + scoped_task_environment.RunUntilIdle(); + + EXPECT_CALL(delegate, OnMuted(false)); + factory_->client_->OnMutedStateChanged(false); + scoped_task_environment.RunUntilIdle(); +} + +TEST_F(InputIPCTest, Record_Records) { + StrictMock<MockDelegate> delegate; + EXPECT_CALL(delegate, GotOnStreamCreated(_)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); + + EXPECT_CALL(factory_->stream_, Record()); + ipc->RecordStream(); + scoped_task_environment.RunUntilIdle(); +} + +TEST_F(InputIPCTest, IsReusable) { + for (int i = 0; i < 5; i++) { + StrictMock<MockDelegate> delegate; + EXPECT_CALL(delegate, GotOnStreamCreated(_)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); + + ipc->CloseStream(); + scoped_task_environment.RunUntilIdle(); + + testing::Mock::VerifyAndClearExpectations(&delegate); + } +} + +TEST_F(InputIPCTest, SetVolume_SetsVolume) { + StrictMock<MockDelegate> delegate; + EXPECT_CALL(delegate, GotOnStreamCreated(_)); + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); + + EXPECT_CALL(factory_->stream_, SetVolume(kNewVolume)); + ipc->SetVolume(kNewVolume); + scoped_task_environment.RunUntilIdle(); +} + +TEST_F(InputIPCTest, FailedStreamCreationNullCallback) { + StrictMock<MockDelegate> delegate; + EXPECT_CALL(delegate, OnError()).Times(2); + factory_->should_fail_ = true; + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); +} + +TEST_F(InputIPCTest, FailedStreamCreationDestuctedFactory) { + StrictMock<MockDelegate> delegate; + EXPECT_CALL(delegate, OnError()); + factory_ = nullptr; + ipc->CreateStream(&delegate, audioParameters, false, 0); + scoped_task_environment.RunUntilIdle(); +} + +} // namespace audio
diff --git a/services/audio/public/mojom/BUILD.gn b/services/audio/public/mojom/BUILD.gn index 2929963..29f89d2 100644 --- a/services/audio/public/mojom/BUILD.gn +++ b/services/audio/public/mojom/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "audio_device_description.mojom", "debug_recording.mojom", + "device_notifications.mojom", "stream_factory.mojom", "system_info.mojom", ]
diff --git a/services/audio/public/mojom/device_notifications.mojom b/services/audio/public/mojom/device_notifications.mojom new file mode 100644 index 0000000..f3d5c75 --- /dev/null +++ b/services/audio/public/mojom/device_notifications.mojom
@@ -0,0 +1,18 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module audio.mojom; + +// This interface is implemented by clients of the audio service (e.g., the +// browser process) to register listeners of audio-device events. +interface DeviceListener { + DevicesChanged(); +}; + +// This interface is exposed by the audio service to allow trusted clients +// (e.g., the browser process) to subscribe to device-change events. +interface DeviceNotifier { + // Registers a listener. Closing the pipe removes the subscription. + RegisterListener(DeviceListener listener); +};
diff --git a/services/audio/service.cc b/services/audio/service.cc index 9684cc0..b00498e 100644 --- a/services/audio/service.cc +++ b/services/audio/service.cc
@@ -9,9 +9,11 @@ #include "base/logging.h" #include "base/macros.h" #include "base/single_thread_task_runner.h" +#include "base/system_monitor/system_monitor.h" #include "build/build_config.h" #include "media/audio/audio_manager.h" #include "services/audio/debug_recording.h" +#include "services/audio/device_notifier.h" #include "services/audio/system_info.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_context_ref.h" @@ -19,9 +21,11 @@ namespace audio { Service::Service(std::unique_ptr<AudioManagerAccessor> audio_manager_accessor, - base::TimeDelta quit_timeout) + base::TimeDelta quit_timeout, + bool device_notifications_enabled) : quit_timeout_(quit_timeout), - audio_manager_accessor_(std::move(audio_manager_accessor)) { + audio_manager_accessor_(std::move(audio_manager_accessor)), + device_notifications_enabled_(device_notifications_enabled) { DCHECK(audio_manager_accessor_); } @@ -41,6 +45,10 @@ &Service::BindDebugRecordingRequest, base::Unretained(this))); registry_.AddInterface<mojom::StreamFactory>(base::BindRepeating( &Service::BindStreamFactoryRequest, base::Unretained(this))); + if (device_notifications_enabled_) { + registry_.AddInterface<mojom::DeviceNotifier>(base::BindRepeating( + &Service::BindDeviceNotifierRequest, base::Unretained(this))); + } } void Service::OnBindInterface( @@ -100,6 +108,19 @@ stream_factory_->Bind(std::move(request), ref_factory_->CreateRef()); } +void Service::BindDeviceNotifierRequest(mojom::DeviceNotifierRequest request) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(ref_factory_); + DCHECK(device_notifications_enabled_); + if (!system_monitor_) { + CHECK(!base::SystemMonitor::Get()); + system_monitor_ = std::make_unique<base::SystemMonitor>(); + } + if (!device_notifier_) + device_notifier_ = std::make_unique<DeviceNotifier>(); + device_notifier_->Bind(std::move(request), ref_factory_->CreateRef()); +} + void Service::MaybeRequestQuitDelayed() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (quit_timeout_ <= base::TimeDelta())
diff --git a/services/audio/service.h b/services/audio/service.h index 9fdc3abb..9c52862 100644 --- a/services/audio/service.h +++ b/services/audio/service.h
@@ -14,12 +14,17 @@ #include "base/threading/thread_checker.h" #include "base/timer/timer.h" #include "services/audio/public/mojom/debug_recording.mojom.h" +#include "services/audio/public/mojom/device_notifications.mojom.h" #include "services/audio/public/mojom/stream_factory.mojom.h" #include "services/audio/public/mojom/system_info.mojom.h" #include "services/audio/stream_factory.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +namespace base { +class SystemMonitor; +} + namespace media { class AudioManager; } // namespace media @@ -30,6 +35,7 @@ namespace audio { class DebugRecording; +class DeviceNotifier; class SystemInfo; class Service : public service_manager::Service { @@ -50,9 +56,12 @@ // Service will attempt to quit if there are no connections to it within // |quit_timeout| interval. If |quit_timeout| is base::TimeDelta() the - // service never quits. + // service never quits. If |device_notifications_enabled| is true, the service + // will make available a DeviceNotifier object that allows clients to + // subscribe to notifications about device changes. Service(std::unique_ptr<AudioManagerAccessor> audio_manager_accessor, - base::TimeDelta quit_timeout); + base::TimeDelta quit_timeout, + bool device_notifications_enabled); ~Service() final; // service_manager::Service implementation. @@ -68,6 +77,7 @@ void BindSystemInfoRequest(mojom::SystemInfoRequest request); void BindDebugRecordingRequest(mojom::DebugRecordingRequest request); void BindStreamFactoryRequest(mojom::StreamFactoryRequest request); + void BindDeviceNotifierRequest(mojom::DeviceNotifierRequest request); void MaybeRequestQuitDelayed(); void MaybeRequestQuit(); @@ -83,9 +93,12 @@ std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_; std::unique_ptr<AudioManagerAccessor> audio_manager_accessor_; + const bool device_notifications_enabled_; + std::unique_ptr<base::SystemMonitor> system_monitor_; std::unique_ptr<SystemInfo> system_info_; std::unique_ptr<DebugRecording> debug_recording_; base::Optional<StreamFactory> stream_factory_; + std::unique_ptr<DeviceNotifier> device_notifier_; service_manager::BinderRegistry registry_;
diff --git a/services/audio/service_factory.cc b/services/audio/service_factory.cc index 6c0475ef..91da2eda 100644 --- a/services/audio/service_factory.cc +++ b/services/audio/service_factory.cc
@@ -4,6 +4,8 @@ #include "services/audio/service_factory.h" +#include <string> + #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" @@ -40,14 +42,15 @@ media::AudioManager* audio_manager) { return std::make_unique<Service>( std::make_unique<InProcessAudioManagerAccessor>(audio_manager), - base::TimeDelta() /* do not quit if all clients disconnected */); + base::TimeDelta() /* do not quit if all clients disconnected */, + false /* enable_device_notifications */); } std::unique_ptr<service_manager::Service> CreateStandaloneService() { return std::make_unique<Service>( std::make_unique<audio::OwningAudioManagerAccessor>( base::BindOnce(&media::AudioManager::Create)), - GetQuitTimeout()); + GetQuitTimeout(), true /* enable_device_notifications */); } } // namespace audio
diff --git a/services/audio/test/in_process_service_test.cc b/services/audio/test/in_process_service_test.cc index 6bcf4e8e..27e0bf7 100644 --- a/services/audio/test/in_process_service_test.cc +++ b/services/audio/test/in_process_service_test.cc
@@ -45,7 +45,7 @@ service_context_ = std::make_unique<service_manager::ServiceContext>( std::make_unique<audio::Service>( std::make_unique<InProcessAudioManagerAccessor>(audio_manager_), - service_quit_timeout_), + service_quit_timeout_, false /* device_notifications_enabled */), std::move(request)); service_context_->SetQuitClosure(base::BindRepeating( &AudioThreadContext::QuitOnAudioThread, base::Unretained(this))); @@ -66,7 +66,7 @@ virtual ~AudioThreadContext() { if (service_context_) service_context_->QuitNow(); - }; + } media::AudioManager* const audio_manager_; const base::TimeDelta service_quit_timeout_;
diff --git a/services/audio/test/service_lifetime_connector_test.cc b/services/audio/test/service_lifetime_connector_test.cc index 6c08a68..2f67607 100644 --- a/services/audio/test/service_lifetime_connector_test.cc +++ b/services/audio/test/service_lifetime_connector_test.cc
@@ -36,7 +36,7 @@ false /*not using a separate audio thread*/)); std::unique_ptr<Service> service_impl = std::make_unique<Service>( std::make_unique<InProcessAudioManagerAccessor>(audio_manager_.get()), - kQuitTimeout); + kQuitTimeout, false /* device_notifications_enabled */); service_ = service_impl.get(); service_->SetQuitClosureForTesting(quit_request_.Get()); connector_factory_ =
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 8545d73..fc40b1c 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -554,6 +554,11 @@ net_log)); } + if (network_context_params->transport_security_persister_path) { + builder->set_transport_security_persister_path( + *network_context_params->transport_security_persister_path); + } + builder->set_data_enabled(network_context_params->enable_data_url_support); #if !BUILDFLAG(DISABLE_FILE_SUPPORT) builder->set_file_enabled(network_context_params->enable_file_url_support);
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index e85bbc5..b461e1e 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -646,6 +646,61 @@ ->GetSupportsSpdy(kSchemeHostPort)); } +// Test that TransportSecurity state is persisted (or not) as expected. +TEST_F(NetworkContextTest, TransportSecurityStatePersisted) { + const char kDomain[] = "foo.test"; + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath transport_security_persister_path = temp_dir.GetPath(); + base::FilePath transport_security_persister_file_path = + transport_security_persister_path.AppendASCII("TransportSecurity"); + EXPECT_FALSE(base::PathExists(transport_security_persister_file_path)); + + for (bool on_disk : {false, true}) { + // Create a NetworkContext. + mojom::NetworkContextParamsPtr context_params = CreateContextParams(); + if (on_disk) { + context_params->transport_security_persister_path = + transport_security_persister_path; + } + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(std::move(context_params)); + + // Add an STS entry. + net::TransportSecurityState::STSState sts_state; + net::TransportSecurityState* state = + network_context->url_request_context()->transport_security_state(); + EXPECT_FALSE(state->GetDynamicSTSState(kDomain, &sts_state)); + state->AddHSTS(kDomain, + base::Time::Now() + base::TimeDelta::FromSecondsD(1000), + false /* include subdomains */); + EXPECT_TRUE(state->GetDynamicSTSState(kDomain, &sts_state)); + ASSERT_EQ(kDomain, sts_state.domain); + + // Destroy the network context, and wait for all tasks to write state to + // disk to finish running. + network_context.reset(); + scoped_task_environment_.RunUntilIdle(); + EXPECT_EQ(on_disk, + base::PathExists(transport_security_persister_file_path)); + + // Create a new NetworkContext,with the same parameters, and check if the + // added STS entry still exists. + context_params = CreateContextParams(); + if (on_disk) { + context_params->transport_security_persister_path = + transport_security_persister_path; + } + network_context = CreateContextWithParams(std::move(context_params)); + // Wait for the entry to load. + scoped_task_environment_.RunUntilIdle(); + state = network_context->url_request_context()->transport_security_state(); + ASSERT_EQ(on_disk, state->GetDynamicSTSState(kDomain, &sts_state)); + if (on_disk) + EXPECT_EQ(kDomain, sts_state.domain); + } +} + // Validates that clearing the HTTP cache when no cache exists does complete. TEST_F(NetworkContextTest, ClearHttpCacheWithNoCache) { mojom::NetworkContextParamsPtr context_params = CreateContextParams();
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index f151fdf0..d2c9d36cd4 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -80,6 +80,11 @@ // logic. If null, an in-memory cache will be used instead. mojo_base.mojom.FilePath? http_server_properties_path; + // The directory in which to store cached transport security properties (like + // HSTS). The file itself will be called "TransportSecurity". If null, or the + // file can't be opened, an in-memory store will be used instead. + mojo_base.mojom.FilePath? transport_security_persister_path; + // Enabled protocols. Note that these apply to all fetches, including those // used to fetch PAC scripts.
diff --git a/services/ui/public/cpp/gpu/context_provider_command_buffer.cc b/services/ui/public/cpp/gpu/context_provider_command_buffer.cc index 3f0507b..312df8f 100644 --- a/services/ui/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/ui/public/cpp/gpu/context_provider_command_buffer.cc
@@ -404,8 +404,7 @@ return nullptr; raster_interface_ = std::make_unique<gpu::raster::RasterImplementationGLES>( - gles2_impl_.get(), gles2_impl_.get(), command_buffer_.get(), - ContextCapabilities()); + gles2_impl_.get(), command_buffer_.get(), ContextCapabilities()); return raster_interface_.get(); }
diff --git a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc index f5d8b2c..18823c2 100644 --- a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc +++ b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc
@@ -92,16 +92,10 @@ request->SetScaleRatio(scale_from, scale_to); if (!data.ReadSource(&request->source_) || !data.ReadArea(&request->area_) || - !data.ReadResultSelection(&request->result_selection_) || - !data.ReadMailbox(&request->mailbox_) || - !data.ReadSyncToken(&request->sync_token_)) { + !data.ReadResultSelection(&request->result_selection_)) { return false; } - // Mailbox and SyncToken always come together. - if (!request->mailbox_ != !request->sync_token_) - return false; - *out_p = std::move(request); return true;
diff --git a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h index 20a4dfc..a95baeb 100644 --- a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h +++ b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h
@@ -46,16 +46,6 @@ return request->result_selection_; } - static const base::Optional<gpu::Mailbox>& mailbox( - const std::unique_ptr<viz::CopyOutputRequest>& request) { - return request->mailbox_; - } - - static const base::Optional<gpu::SyncToken>& sync_token( - const std::unique_ptr<viz::CopyOutputRequest>& request) { - return request->sync_token_; - } - static viz::mojom::CopyOutputResultSenderPtr result_sender( const std::unique_ptr<viz::CopyOutputRequest>& request);
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 70d09bc..c7456d6 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -327,7 +327,6 @@ quit_closure.Run(); }, run_loop_for_result.QuitClosure(), result_rect))); - input->SetMailbox(mailbox, sync_token); EXPECT_FALSE(input->is_scaled()); std::unique_ptr<CopyOutputRequest> output; SerializeAndDeserialize<mojom::CopyOutputRequest>(input, &output); @@ -336,8 +335,6 @@ EXPECT_FALSE(output->is_scaled()); EXPECT_FALSE(output->has_source()); EXPECT_FALSE(output->has_area()); - EXPECT_TRUE(output->has_mailbox()); - EXPECT_EQ(mailbox, output->mailbox()); base::RunLoop run_loop_for_release; output->SendResult(std::make_unique<CopyOutputTextureResult>(
diff --git a/services/viz/public/interfaces/compositing/copy_output_request.mojom b/services/viz/public/interfaces/compositing/copy_output_request.mojom index 220c2e4..045f7529 100644 --- a/services/viz/public/interfaces/compositing/copy_output_request.mojom +++ b/services/viz/public/interfaces/compositing/copy_output_request.mojom
@@ -22,12 +22,6 @@ gfx.mojom.Rect? area; gfx.mojom.Rect? result_selection; - // DEPRECATED: To be removed once tab capture is moved into VIZ. - // http://crbug.com/754872 - // If mailbox is present, then sync_token must also be. - gpu.mojom.Mailbox? mailbox; - gpu.mojom.SyncToken? sync_token; - CopyOutputResultSender result_sender; };
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 799691c..b27afee 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -403,6 +403,99 @@ "chromeos-amd64-generic-rel": { "additional_compile_targets": [ "chromiumos_preflight" + ], + "gtest_tests": [ + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "cacheinvalidation_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "capture_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "crypto_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "google_apis_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "midi_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "sql_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, + "test": "url_unittests" + } ] }, "chromeos-daisy-rel": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 66337b5..1658e5d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -8085,7 +8085,7 @@ } ] }, - "test": "cacheinvalidation_unittests" + "test": "base_unittests" }, { "swarming": { @@ -8098,73 +8098,7 @@ } ] }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-14.04", - "pool": "Chrome-CrOS-VM" - } - ], - "shards": 2 - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-14.04", - "pool": "Chrome-CrOS-VM" - } - ] - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-14.04", - "pool": "Chrome-CrOS-VM" - } - ] - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-14.04", - "pool": "Chrome-CrOS-VM" - } - ] - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1", - "os": "Ubuntu-14.04", - "pool": "Chrome-CrOS-VM" - } - ] - }, - "test": "url_unittests" + "test": "net_unittests" } ], "isolated_scripts": [
diff --git a/testing/buildbot/filters/viz.browser_tests.filter b/testing/buildbot/filters/viz.browser_tests.filter index 0f03cd5..f333d0c9 100644 --- a/testing/buildbot/filters/viz.browser_tests.filter +++ b/testing/buildbot/filters/viz.browser_tests.filter
@@ -26,6 +26,7 @@ #### Compositor Frame Observation Timeouts # WaitForChildFrameSurfaceReady crashes crbug.com/787945 -PDFExtensionHitTestTest.ContextMenuCoordinates* +-PDFExtensionHitTestTest.MouseLeave* -SitePerProcessDevToolsSanityTest.InputDispatchEventsToOOPIF -WebViewTest.InterstitialPageFocusedWidget -WebViewTest.ReloadAfterCrash
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 75ab68df..0112d7f 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -362,17 +362,18 @@ 'chromeos_gtests': { 'cacheinvalidation_unittests': {}, 'capture_unittests': {}, - 'crypto_unittests': { - 'swarming': { - 'shards': 2, - }, - }, + 'crypto_unittests': {}, 'midi_unittests': {}, 'google_apis_unittests': {}, 'sql_unittests': {}, 'url_unittests': {}, }, + 'chromeos_gtests_experimental': { + 'base_unittests': {}, + 'net_unittests': {}, + }, + 'chromeos_isolated_scripts': { 'telemetry_perf_unittests': { 'args': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 34e3722e..5663bcb 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -586,6 +586,18 @@ 'additional_compile_targets': [ 'chromiumos_preflight', ], + 'test_suites': { + 'gtest_tests': 'chromeos_gtests', + }, + 'swarming': { + 'dimension_sets': [ + { + 'kvm': '1', + 'os': 'Ubuntu-14.04', + 'pool': 'Chrome-CrOS-VM', + }, + ], + }, }, 'chromeos-daisy-rel': { 'additional_compile_targets': [ @@ -1430,7 +1442,7 @@ 'chromiumos_preflight', ], 'test_suites': { - 'gtest_tests': 'chromeos_gtests', + 'gtest_tests': 'chromeos_gtests_experimental', 'isolated_scripts': 'chromeos_isolated_scripts', }, 'swarming': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 33c5706..de1ecb1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3875,6 +3875,29 @@ ] } ], + "UkmSamplingRate": [ + { + "platforms": [ + "android", + "chromeos", + "ios", + "linux", + "mac", + "win" + ], + "experiments": [ + { + "name": "Sampled", + "params": { + "_default_sampling": "1" + }, + "enable_features": [ + "UkmSamplingRate" + ] + } + ] + } + ], "UpdateMenuItem": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees index 1cebf926..8a5bc023 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -171,6 +171,7 @@ crbug.com/836897 virtual/threaded/animations/element-animate-positive-delay.html [ Crash ] # These scrollbar tests should pass. +Bug(none) virtual/prefer_compositing_to_lcd_text/scrollbars/ [ Pass ] crbug.com/836912 compositing/rtl/rtl-absolute-overflow.html [ Failure ] crbug.com/836912 compositing/rtl/rtl-and-writing-mode-scrolling.html [ Failure ] crbug.com/836912 compositing/rtl/rtl-fixed-overflow.html [ Failure ] @@ -179,9 +180,52 @@ crbug.com/836912 compositing/rtl/rtl-overflow-invalidation.html [ Failure ] crbug.com/836912 compositing/scrollbars/nested-overlay-scrollbars.html [ Failure ] crbug.com/836912 compositing/squashing/vertical-writing-mode-squashed.html [ Failure ] -crbug.com/836912 scrollbars/scrollbar-added-during-drag.html [ Crash ] -crbug.com/836912 scrollbars/scrollbar-removed-by-viewport-crash.html [ Crash ] +crbug.com/841423 scrollbars/scrollbar-added-during-drag.html [ Crash ] +crbug.com/841423 virtual/prefer_compositing_to_lcd_text/scrollbars/scrollbar-added-during-drag.html [ Crash ] +crbug.com/840017 scrollbars/scrollbar-removed-by-viewport-crash.html [ Crash ] +crbug.com/840017 virtual/prefer_compositing_to_lcd_text/scrollbars/scrollbar-removed-by-viewport-crash.html [ Crash ] crbug.com/841342 scrollbars/border-box-rect-clips-scrollbars.html [ Failure ] +crbug.com/841342 virtual/prefer_compositing_to_lcd_text/scrollbars/border-box-rect-clips-scrollbars.html [ Failure ] +crbug.com/841342 virtual/prefer_compositing_to_lcd_text/scrollbars/custom-scrollbars-paint-outside-iframe.html [ Failure ] + +# These scrolling tests should pass. +Bug(none) virtual/threaded/fast/scrolling [ Pass ] +Bug(none) fast/scrolling [ Pass ] +Bug(none) fast/events [ Pass ] +crbug.com/840017 fast/scrolling/editor-command-scroll-page-scale.html [ Crash ] +crbug.com/840017 fast/scrolling/keyboard-scroll-page-scale.html [ Crash ] +crbug.com/840017 fast/scrolling/overflow-clip-with-page-scale.html [ Crash ] +crbug.com/840017 fast/scrolling/same-page-navigate.html [ Crash ] +crbug.com/840017 fast/scrolling/scroll-without-document-element-renderer.html [ Crash ] +crbug.com/840017 fast/scrolling/scroll-without-document-element.html [ Crash ] +crbug.com/840017 virtual/threaded/fast/scrolling/editor-command-scroll-page-scale.html [ Crash ] +crbug.com/840017 virtual/threaded/fast/scrolling/keyboard-scroll-page-scale.html [ Crash ] +crbug.com/840017 virtual/threaded/fast/scrolling/overflow-clip-with-page-scale.html [ Crash ] +crbug.com/840017 virtual/threaded/fast/scrolling/same-page-navigate.html [ Crash ] +crbug.com/840017 virtual/threaded/fast/scrolling/scroll-without-document-element.html [ Crash ] +crbug.com/840017 virtual/threaded/fast/scrolling/scroll-without-document-element-renderer.html [ Crash ] +crbug.com/840017 fast/events/gesture-pinch-zoom-scroll-bubble.html [ Crash ] +crbug.com/840017 fast/events/gesture-pinch-zoom.html [ Crash ] +crbug.com/840017 fast/events/menu-key-context-menu-document-pinch-zoom.html [ Crash ] +crbug.com/840017 fast/events/page-scaled-mouse-click-iframe.html [ Crash ] +crbug.com/840017 fast/events/page-scaled-mouse-click.html [ Crash ] +crbug.com/840017 fast/events/resize-events.html [ Crash ] +crbug.com/840017 fast/events/scale-and-scroll-body.html [ Crash ] +crbug.com/840017 fast/events/scale-and-scroll-div.html [ Crash ] +crbug.com/840017 fast/events/scale-and-scroll-iframe-body.html [ Crash ] +crbug.com/840017 fast/events/scale-and-scroll-iframe-window.html [ Crash ] +crbug.com/840017 fast/events/scale-and-scroll-window.html [ Crash ] +crbug.com/840017 fast/events/scroll-in-scaled-page-with-overflow-hidden.html [ Crash ] +crbug.com/840017 fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Crash ] +crbug.com/840017 fast/events/touch/page-scaled-touch-gesture-click.html [ Crash ] +crbug.com/840017 fast/events/touch/touch-scaled-scrolled.html [ Crash ] +crbug.com/840017 fast/events/touch/gesture/touch-gesture-fling-with-page-scale.html [ Crash ] +crbug.com/840017 fast/events/touch/gesture/touch-gesture-scroll-div-scaled.html [ Crash ] +crbug.com/836913 virtual/threaded/fast/scrolling/background-paint-scrolled.html [ Failure ] +crbug.com/836913 virtual/threaded/fast/scrolling/hover-during-scroll.html [ Failure ] +crbug.com/841567 virtual/threaded/fast/scrolling/listbox-wheel-event.html [ Failure ] +crbug.com/836913 virtual/threaded/fast/scrolling/overflow-scrollability.html [ Failure ] +crbug.com/836913 virtual/threaded/fast/scrolling/overlay-scrollbars.html [ Failure ] # These visual viewport tests should pass. Bug(none) external/wpt/visual-viewport [ Pass ] @@ -194,7 +238,7 @@ crbug.com/836890 rootscroller/scroll-non-descendant-of-root-scroller.html [ Crash ] crbug.com/836890 rootscroller/set-root-scroller.html [ Crash ] crbug.com/836890 rootscroller/set-rootscroller-before-load.html [ Crash ] -crbug.com/836890 virtual/android/frame-size/intersection-observer-root-uses-frame-size.html [ Crash ] +crbug.com/840017 virtual/android/frame-size/intersection-observer-root-uses-frame-size.html [ Crash ] crbug.com/836890 virtual/android/fullscreen/full-screen-iframe-allowed-video.html [ Failure ] crbug.com/836890 virtual/android/rootscroller/gesture-scroll-document-not-root-scroller.html [ Failure ] crbug.com/836890 virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 17e59858..2120761f 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1060,6 +1060,7 @@ crbug.com/730284 fast/replaced/border-radius-clip.html [ Failure ] # Check failed: layer_list_.empty() || *page_scale_factor == 1 +crbug.com/706066 clipboard/copy-image-at-with-pinch-zoom.html [ Crash Timeout ] crbug.com/706066 compositing/background-color/background-color-outside-document.html [ Crash Timeout ] crbug.com/706066 compositing/overflow/overflow-scaled-descendant-overlapping.html [ Crash Timeout ] crbug.com/706066 compositing/gestures/gesture-tapHighlight-simple-scaled-document.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 34b8779..97631e6 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -59,9 +59,6 @@ # https://crbug.com/786510 - test tries to access cross-origin document body crbug.com/606594 http/tests/local/serviceworker/fetch-request-body-file.html [ Skip ] -# https://crbug.com/607991 - MockWebClipboardImpl not replicated across OOPIFs. -crbug.com/607991 http/tests/misc/copy-resolves-urls.html [ Failure ] - # https://crbug.com/616626 - allow_universal_access_from_file_urls doesn't work with --site-per-process. # https://crbug.com/665058 - EventSender drag-and-drop simulation doesn't support OOPIFs. crbug.com/665058 http/tests/local/drag-over-remote-content.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 6f8dc3d7..f5b48569 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -5,10 +5,11 @@ # Intentional failures to test the layout test system. Bug(intentional) harness-tests/crash.html [ Crash ] Bug(intentional) harness-tests/timeout.html [ Timeout ] -Bug(intentional) external/wpt/infrastructure/reftest/reftest_timeout.html [ Timeout ] +Bug(intentional) external/wpt/infrastructure/reftest/reftest_match_fail.html [ Failure ] Bug(intentional) external/wpt/infrastructure/reftest/reftest_mismatch_fail.html [ Failure ] Bug(intentional) external/wpt/infrastructure/reftest/reftest_ref_timeout.html [ Timeout ] -Bug(intentional) external/wpt/infrastructure/reftest/reftest_match_fail.html [ Failure ] +Bug(intentional) external/wpt/infrastructure/reftest/reftest_timeout.html [ Timeout ] +Bug(intentional) external/wpt/infrastructure/expected-fail/timeout.html [ Timeout ] crbug.com/807686 crbug.com/24182 jquery/manipulation.html [ Timeout Pass ] @@ -2788,6 +2789,7 @@ crbug.com/832071 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_pointerout_received_once-manual.html [ Skip ] crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-016.html [ Failure ] crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-013.html [ Failure ] crbug.com/626703 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-011.html [ Failure ] @@ -3703,6 +3705,8 @@ crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.percent.worker.html [ Failure ] crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.trailingjunk.worker.html [ Failure ] crbug.com/709227 external/wpt/user-timing/invoke_with_timing_attributes.worker.html [ Failure ] +crbug.com/839947 external/wpt/console/console-counting-label-conversion.any.html [ Failure ] +crbug.com/839947 external/wpt/console/console-counting-label-conversion.any.worker.html [ Failure ] # Timeouts crbug.com/709227 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/serialization-via-idb.any.worker.html [ Timeout ] @@ -3711,7 +3715,6 @@ # Crashes crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.html [ Crash ] - # ====== Tests from enabling .any.js/.worker.js tests end here ======== crbug.com/789139 http/tests/devtools/sources/debugger/live-edit-no-reveal.js [ Failure Pass Timeout Crash ] @@ -4201,6 +4204,9 @@ crbug.com/766129 svg/wicd/test-rightsizing-b.xhtml [ Failure Pass ] +crbug.com/841567 virtual/threaded/fast/scrolling/listbox-wheel-event.html [ Failure ] +crbug.com/841567 virtual/threaded/fast/scrolling/hover-during-scroll.html [ Timeout ] + # Workaround crbug.com/817175 . Very difficult to fix with old-world compositing. Pass with SPv2. crbug.com/817175 compositing/overflow/clip-escaping-reverse-order-should-not-crash.html [ Failure ] crbug.com/817175 virtual/disable-spv175/compositing/overflow/clip-escaping-reverse-order-should-not-crash.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 40469be..a339d2f 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -12,8 +12,7 @@ { "prefix": "gpu", "base": "fast/canvas", - "args": ["--enable-accelerated-2d-canvas", - "--disable-display-list-2d-canvas"] + "args": ["--enable-accelerated-2d-canvas"] }, { "prefix": "threaded", @@ -73,6 +72,12 @@ "--enable-prefer-compositing-to-lcd-text"] }, { + "prefix": "threaded", + "base": "fast/scrolling", + "args": ["--enable-threaded-compositing", + "--enable-prefer-compositing-to-lcd-text"] + }, + { "prefix": "gpu-rasterization", "base": "images", "args": ["--force-gpu-rasterization"]
diff --git a/third_party/WebKit/LayoutTests/clipboard/copy-image-at-expected.txt b/third_party/WebKit/LayoutTests/clipboard/copy-image-at-expected.txt new file mode 100644 index 0000000..43e5eeed --- /dev/null +++ b/third_party/WebKit/LayoutTests/clipboard/copy-image-at-expected.txt
@@ -0,0 +1,4 @@ +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/clipboard/copy-image-at-with-pinch-zoom-expected.txt b/third_party/WebKit/LayoutTests/clipboard/copy-image-at-with-pinch-zoom-expected.txt new file mode 100644 index 0000000..43e5eeed --- /dev/null +++ b/third_party/WebKit/LayoutTests/clipboard/copy-image-at-with-pinch-zoom-expected.txt
@@ -0,0 +1,4 @@ +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/clipboard/copy-image-at-with-pinch-zoom.html b/third_party/WebKit/LayoutTests/clipboard/copy-image-at-with-pinch-zoom.html new file mode 100644 index 0000000..4af320a --- /dev/null +++ b/third_party/WebKit/LayoutTests/clipboard/copy-image-at-with-pinch-zoom.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<body> +<canvas style="position:absolute; top:40px; left:40px" width="200" height="200"></canvas> +<script src="../resources/js-test.js"></script> +<script> +testRunner.waitUntilDone(); +testRunner.dumpAsText(); +requestAnimationFrame(() => { + var canvas = document.querySelector("canvas"); + var context = canvas.getContext("2d"); + context.fillStyle = "red"; + context.fillRect(0, 0, 200, 200); + window.internals.setPageScaleFactor(2); + window.internals.setVisualViewportOffset(200, 200); + requestAnimationFrame(() => { + testRunner.copyImageAtAndCapturePixelsAsyncThen(0, 0, (width, height, snapshot) => { + try { + if (width !== 200 || height !== 200) + testFailed("The copied image must be 200x200."); + var topleft = new Uint8Array(snapshot).subarray(0, 4); + if (topleft[0] !== 255 || topleft[1] !== 0 || topleft[2] !== 0 || topleft[3] !== 255) + testFailed("The copied image's top left must be red. " + JSON.stringify(topleft)); + } catch (e) { + testFailed("" + e); + } + testRunner.notifyDone(); + }); + }); +}); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/clipboard/copy-image-at.html b/third_party/WebKit/LayoutTests/clipboard/copy-image-at.html new file mode 100644 index 0000000..85ef14a --- /dev/null +++ b/third_party/WebKit/LayoutTests/clipboard/copy-image-at.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<body> +<canvas style="position:absolute; top:40px; left:40px" width="200" height="200"></canvas> +<script src="../resources/js-test.js"></script> +<script> +testRunner.waitUntilDone(); +testRunner.dumpAsText(); +requestAnimationFrame(() => { + var canvas = document.querySelector("canvas"); + var context = canvas.getContext("2d"); + context.fillStyle = "red"; + context.fillRect(0, 0, 200, 200); + requestAnimationFrame(() => { + testRunner.copyImageAtAndCapturePixelsAsyncThen(50, 50, (width, height, snapshot) => { + try { + if (width !== 200 || height !== 200) + testFailed("The copied image must be 200x200."); + var topleft = new Uint8Array(snapshot).subarray(0, 4); + if (topleft[0] !== 255 || topleft[1] !== 0 || topleft[2] !== 0 || topleft[3] !== 255) + testFailed("The copied image's top left must be red. " + JSON.stringify(topleft)); + } catch (e) { + testFailed("" + e); + } + testRunner.notifyDone(); + }); + }); +}); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 1dfd2edd..1e428ef 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -152361,6 +152361,11 @@ {} ] ], + "html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt": [ + [ + {} + ] + ], "html/semantics/scripting-1/the-script-element/module/import-something-namespace.js": [ [ {} @@ -154521,6 +154526,11 @@ {} ] ], + "infrastructure/metadata/infrastructure/expected-fail/timeout.html.ini": [ + [ + {} + ] + ], "infrastructure/metadata/infrastructure/reftest/reftest_and_fail.html.ini": [ [ {} @@ -168851,6 +168861,11 @@ {} ] ], + "workers/modules/dedicated-worker-import-meta-expected.txt": [ + [ + {} + ] + ], "workers/modules/resources/dynamic-import-and-then-static-import-worker.js": [ [ {} @@ -211086,6 +211101,12 @@ {} ] ], + "infrastructure/expected-fail/timeout.html": [ + [ + "/infrastructure/expected-fail/timeout.html", + {} + ] + ], "infrastructure/server/secure-context.https.any.js": [ [ "/infrastructure/server/secure-context.https.any.html", @@ -354863,8 +354884,12 @@ "bc8e6d649615d09b970e328873bc138093f1c14d", "support" ], + "html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt": [ + "4283a063a51cfb5bbb02028a79be1df50e704852", + "support" + ], "html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html": [ - "9758a62ec1f943c00dcd9b58ca62464c5c78bbb3", + "3328350068373e6ad5cfd06f1180468ea4dccfb8", "testharness" ], "html/semantics/scripting-1/the-script-element/module/import-something-namespace.js": [ @@ -358171,6 +358196,10 @@ "c832afb4826fd43d2fcc4f5e3fd6a773a6ee35f0", "testharness" ], + "infrastructure/expected-fail/timeout.html": [ + "a91279f3455bdaf63412e9487192502da1e51baf", + "testharness" + ], "infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini": [ "0f536ac59a959769966d56c5a546f9f2c2557e97", "support" @@ -358179,6 +358208,10 @@ "7eecbfc4845e6befe54b0f007d587a1a003993dc", "support" ], + "infrastructure/metadata/infrastructure/expected-fail/timeout.html.ini": [ + "03ddb1ea28337dabd61082a566149fa1e94f3e97", + "support" + ], "infrastructure/metadata/infrastructure/reftest/reftest_and_fail.html.ini": [ "b6c1fe38e610a8ffaf843c0c0b791c65fe6d5145", "support" @@ -392543,8 +392576,12 @@ "6bffa3be83d81e2faa93119e710e4fee93fb855e", "testharness" ], + "workers/modules/dedicated-worker-import-meta-expected.txt": [ + "572182b28a89039a4fa5ce5df89da53e083d1307", + "support" + ], "workers/modules/dedicated-worker-import-meta.html": [ - "ba8b24064e23f018ffd3ac9e4184d6f856123bff", + "32cd3419ff904a2440d9a6eaa7cb28f78d4a7e32", "testharness" ], "workers/modules/dedicated-worker-import.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/historical-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/historical-expected.txt deleted file mode 100644 index f2193a15..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/historical-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS Historical Document member: selectedStyleSheetSet -PASS Historical Document member: lastStyleSheetSet -PASS Historical Document member: preferredStyleSheetSet -PASS Historical Document member: styleSheetSets -PASS Historical Document member: enableStyleSheetsForSet -FAIL Historical Document member: selectedStylesheetSet assert_false: expected false got true -FAIL Historical Document member: preferredStylesheetSet assert_false: expected false got true -PASS Historical Element member: cascadedStyle -PASS Historical Element member: defaultStyle -PASS Historical Element member: rawComputedStyle -PASS Historical Element member: usedStyle -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/preferred-stylesheet-order.html b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/preferred-stylesheet-order.html new file mode 100644 index 0000000..dc990131 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/preferred-stylesheet-order.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/cssom/#add-a-css-style-sheet"> +<link rel="help" href="https://drafts.csswg.org/cssom/#create-a-css-style-sheet"> +<link rel="help" href="https://html.spec.whatwg.org/#update-a-style-block"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="t1">This text should be green</div> +<script> +function createStyleElement(text, title) { + var elm = document.createElement("style"); + elm.setAttribute("title", title); + elm.appendChild(document.createTextNode(text)); + return elm; +} + +test(function() { + document.head.appendChild(createStyleElement("#t1 {color:green}", "preferred")); + document.head.appendChild(createStyleElement("#t1 {color:red}", "notpreferred")); + + assert_equals(getComputedStyle(t1).color, "rgb(0, 128, 0)"); +}, "Preferred stylesheet where insertion order is reversed tree order"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/preferred-stylesheet-reversed-order.html b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/preferred-stylesheet-reversed-order.html new file mode 100644 index 0000000..ff3a8b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/preferred-stylesheet-reversed-order.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/cssom/#add-a-css-style-sheet"> +<link rel="help" href="https://drafts.csswg.org/cssom/#create-a-css-style-sheet"> +<link rel="help" href="https://html.spec.whatwg.org/#update-a-style-block"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="t1">This text should be green</div> +<script> +function createStyleElement(text, title) { + var elm = document.createElement("style"); + elm.setAttribute("title", title); + elm.appendChild(document.createTextNode(text)); + return elm; +} + +test(function() { + document.head.insertBefore(createStyleElement("#t1 {color:green}", "preferred"), document.head.firstChild); + document.head.insertBefore(createStyleElement("#t1 {color:red}", "notpreferred"), document.head.firstChild); + + assert_equals(getComputedStyle(t1).color, "rgb(0, 128, 0)"); +}, "Preferred stylesheet where insertion order is tree order"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt new file mode 100644 index 0000000..4c25322 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS import.meta.url in a root inline script +PASS import.meta.url in a root external script +PASS import.meta.url in a dependent external script +FAIL import.meta.url when importing the module with different fragments assert_equals: expected "http://web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js#1" but got "http://web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html index 3c853b2..fa1c7dee 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html
@@ -20,4 +20,26 @@ assert_equals(importMetaOnDependentModule.url, base + "/import-meta-dependent.js"); }, "import.meta.url in a dependent external script"); + +import { importMetaOnRootModule as hashedImportMetaOnRootModule1, + importMetaOnDependentModule as hashedImportMetaOnDependentModule1 } + from "./import-meta-root.js#1"; + +import { importMetaOnRootModule as hashedImportMetaOnRootModule2, + importMetaOnDependentModule as hashedImportMetaOnDependentModule2 } + from "./import-meta-root.js#2"; + +test(() => { + assert_equals(hashedImportMetaOnRootModule1.url, + base + "/import-meta-root.js#1"); + assert_equals(hashedImportMetaOnRootModule2.url, + base + "/import-meta-root.js#2"); + + // Must not be affected + assert_equals(hashedImportMetaOnDependentModule1.url, + base + "/import-meta-dependent.js"); + assert_equals(hashedImportMetaOnDependentModule2.url, + base + "/import-meta-dependent.js"); +}, "import.meta.url when importing the module with different fragments"); + </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/expected-fail/timeout.html b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/expected-fail/timeout.html new file mode 100644 index 0000000..29ff348 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/expected-fail/timeout.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test that should time out</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +async_test() +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/timeout.html.ini b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/timeout.html.ini new file mode 100644 index 0000000..53b281f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/timeout.html.ini
@@ -0,0 +1,4 @@ +[timeout.html] + expected: TIMEOUT + [Test that should time out] + expected: NOTRUN
diff --git a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html index 14d3f822..58135b1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html +++ b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html
@@ -44,8 +44,6 @@ }), 'A_04_01_11_T2'); - -// TODO check selectedStyleSheetSet, lastStyleSheetSet, preferredStyleSheetSet, styleSheetSets </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta-expected.txt new file mode 100644 index 0000000..229c339 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS Test import.meta.url on the top-level module script. +PASS Test import.meta.url on the imported module script. +FAIL Test import.meta.url on the imported module script with a fragment. assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta.html b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta.html index ae59fda..6960cbe 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta.html +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-meta.html
@@ -20,4 +20,19 @@ .then(msg_event => assert_true(msg_event.data.endsWith(script_url))); }, 'Test import.meta.url on the imported module script.'); +promise_test(() => { + const script_url = 'import-meta-url-worker.js'; + const worker = new Worker('resources/dynamic-import-given-url-worker.js', + { type: 'module' }); + worker.postMessage('./' + script_url); + + return new Promise(resolve => worker.onmessage = resolve) + .then(msg_event => assert_true(msg_event.data.endsWith(script_url))) + .then(() => { + worker.postMessage('./' + script_url + '#1'); + return new Promise(resolve => worker.onmessage = resolve); + }) + .then(msg_event => assert_true(msg_event.data.endsWith(script_url))); +}, 'Test import.meta.url on the imported module script with a fragment.'); + </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr-expected.txt b/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr-expected.txt index 887d2abb..cc69d4f8 100644 --- a/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr-expected.txt
@@ -19,10 +19,6 @@ FAIL link.disabled should be true. Was false. PASS link.sheet is non-null. FAIL getComputedStyle(testElement).backgroundColor should be rgb(0, 128, 0). Was rgba(0, 0, 0, 0). -FAIL link.disabled should be true. Was false. -PASS getComputedStyle(testElement).backgroundColor is originalBG -PASS link.disabled is false -FAIL getComputedStyle(testElement).backgroundColor should be rgb(0, 128, 0). Was rgba(0, 0, 0, 0). PASS getComputedStyle(testElement).backgroundColor is originalBG PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr.html b/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr.html index 3e24be2..994a7d0 100644 --- a/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr.html +++ b/third_party/WebKit/LayoutTests/fast/css/link-disabled-attr.html
@@ -75,19 +75,6 @@ shouldBeNonNull("link.sheet"); shouldBe("getComputedStyle(testElement).backgroundColor", "'rgb(0, 128, 0)'"); - // Enabling a stylsheet set modifies disabled status of style sheets. - - document.selectedStyleSheetSet = "nosuchset"; - shouldBeTrue("link.disabled"); - shouldBe("getComputedStyle(testElement).backgroundColor", "originalBG"); - - document.selectedStyleSheetSet = "altset"; - shouldBeFalse("link.disabled"); - shouldBe("getComputedStyle(testElement).backgroundColor", "'rgb(0, 128, 0)'"); - - // Disabling a stylesheet *after* its stylesheet set has been selected - // de-activates it. - link.disabled = true; shouldBe("getComputedStyle(testElement).backgroundColor", "originalBG");
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order-expected.txt b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order-expected.txt deleted file mode 100644 index be77474..0000000 --- a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -Preferred stylesheet where insertion order is reversed tree order - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS getComputedStyle(t1).color is "rgb(0, 128, 0)" -PASS document.preferredStylesheetSet is "preferred" -PASS document.selectedStylesheetSet is "preferred" -PASS successfullyParsed is true - -TEST COMPLETE -This text should be green
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order.html b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order.html deleted file mode 100644 index b28225e..0000000 --- a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-order.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/js-test.js"></script> -<div id="t1">This text should be green</div> -<script> -description("Preferred stylesheet where insertion order is reversed tree order"); - -function createStyleElement(text, title) { - var elm = document.createElement("style"); - elm.setAttribute("title", title); - elm.appendChild(document.createTextNode(text)); - return elm; -} - -document.head.appendChild(createStyleElement("#t1 {color:green}", "preferred")); -document.head.appendChild(createStyleElement("#t1 {color:red}", "notpreferred")); - -shouldBeEqualToString("getComputedStyle(t1).color", "rgb(0, 128, 0)"); -shouldBeEqualToString("document.preferredStylesheetSet", "preferred"); -shouldBeEqualToString("document.selectedStylesheetSet", "preferred"); -</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order-expected.txt b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order-expected.txt deleted file mode 100644 index b78f3a9..0000000 --- a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -Preferred stylesheet where insertion order is tree order - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS getComputedStyle(t1).color is "rgb(0, 128, 0)" -PASS document.preferredStylesheetSet is "preferred" -PASS document.selectedStylesheetSet is "preferred" -PASS successfullyParsed is true - -TEST COMPLETE -This text should be green
diff --git a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order.html b/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order.html deleted file mode 100644 index f3278801..0000000 --- a/third_party/WebKit/LayoutTests/fast/css/preferred-stylesheet-reversed-order.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/js-test.js"></script> -<div id="t1">This text should be green</div> -<script> -description("Preferred stylesheet where insertion order is tree order"); - -function createStyleElement(text, title) { - var elm = document.createElement("style"); - elm.setAttribute("title", title); - elm.appendChild(document.createTextNode(text)); - return elm; -} - -document.head.insertBefore(createStyleElement("#t1 {color:green}", "preferred"), document.head.firstChild); -document.head.insertBefore(createStyleElement("#t1 {color:red}", "notpreferred"), document.head.firstChild); - -shouldBeEqualToString("getComputedStyle(t1).color", "rgb(0, 128, 0)"); -shouldBeEqualToString("document.preferredStylesheetSet", "preferred"); -shouldBeEqualToString("document.selectedStylesheetSet", "preferred"); -</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null-expected.txt index 1769da5..13d0d2f 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null-expected.txt
@@ -5,7 +5,6 @@ TEST SUCCEEDED: The value was the string 'UTF-8'. [tested Document.charset] TEST SUCCEEDED: The value was the string 'UTF-8'. [tested Document.characterSet] TEST SUCCEEDED: The value was the string 'UTF-8'. [tested Document.inputEncoding] -TEST SUCCEEDED: The value was null. [tested Document.selectedStylesheetSet] TEST SUCCEEDED: The value was 'null'. [tested HTMLDocument.title] TEST SUCCEEDED: The value was the empty string. [tested HTMLDocument.cookie]
diff --git a/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null.html b/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null.html index 3c617d0d..4c48a01 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null.html +++ b/third_party/WebKit/LayoutTests/fast/dom/document-attribute-js-null.html
@@ -70,8 +70,7 @@ {name: 'documentURI', expectedNull: 'about:blank'}, {name: 'charset', expectedNull: 'UTF-8'}, {name: 'characterSet', expectedNull: 'UTF-8'}, - {name: 'inputEncoding', expectedNull: 'UTF-8'}, - {name: 'selectedStylesheetSet', expectedNull: null} + {name: 'inputEncoding', expectedNull: 'UTF-8'} ] }, {
diff --git a/third_party/WebKit/LayoutTests/fast/dom/document-preferredStylesheetSet-use-counter.html b/third_party/WebKit/LayoutTests/fast/dom/document-preferredStylesheetSet-use-counter.html deleted file mode 100644 index dad9b77..0000000 --- a/third_party/WebKit/LayoutTests/fast/dom/document-preferredStylesheetSet-use-counter.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE html> -<title>document preferredStylesheetSet UseCounter</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<style> -</style> -<script> -test(function() { - const DocumentGetPreferredStylesheetSet = 2211; // From enums.xml - assert_false(internals.isUseCounted(document, DocumentGetPreferredStylesheetSet)); - document.preferredStylesheetSet; - assert_true(internals.isUseCounted(document, DocumentGetPreferredStylesheetSet)); -}, 'document.preferredStylesheetSet is use counted'); -</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/document-selectedStylesheetSet-use-counter-001.html b/third_party/WebKit/LayoutTests/fast/dom/document-selectedStylesheetSet-use-counter-001.html deleted file mode 100644 index e6dd725..0000000 --- a/third_party/WebKit/LayoutTests/fast/dom/document-selectedStylesheetSet-use-counter-001.html +++ /dev/null
@@ -1,16 +0,0 @@ -<!DOCTYPE html> -<title>document selectedStylesheetSet UseCounters</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<style> -</style> -<script> -test(function() { - const DocumentGetSelectedStylesheetSet = 2212; // From enums.xml - const DocumentSetSelectedStylesheetSet = 2213; // From enums.xml - assert_false(internals.isUseCounted(document, DocumentGetSelectedStylesheetSet)); - document.selectedStylesheetSet; - assert_true(internals.isUseCounted(document, DocumentGetSelectedStylesheetSet)); - assert_false(internals.isUseCounted(document, DocumentSetSelectedStylesheetSet)); -}, 'document get selectedStylesheetSet is use counted'); -</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/document-selectedStylesheetSet-use-counter-002.html b/third_party/WebKit/LayoutTests/fast/dom/document-selectedStylesheetSet-use-counter-002.html deleted file mode 100644 index e6ef8ad..0000000 --- a/third_party/WebKit/LayoutTests/fast/dom/document-selectedStylesheetSet-use-counter-002.html +++ /dev/null
@@ -1,16 +0,0 @@ -<!DOCTYPE html> -<title>document preferredStylesheetSet UseCounter</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<style> -</style> -<script> -test(function() { - const DocumentGetSelectedStylesheetSet = 2212; // From enums.xml - const DocumentSetSelectedStylesheetSet = 2213; // From enums.xml - assert_false(internals.isUseCounted(document, DocumentSetSelectedStylesheetSet)); - document.selectedStylesheetSet = ''; - assert_true(internals.isUseCounted(document, DocumentSetSelectedStylesheetSet)); - assert_false(internals.isUseCounted(document, DocumentGetSelectedStylesheetSet)); -}, 'document set selectedStylesheetSet is use counted'); -</script>
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left-expected.txt b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left-expected.txt index 369b270..8a389fc 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left-expected.txt
@@ -4,11 +4,8 @@ X X PASS elementRect('s1').top is 0 -FAIL elementRect('s1').left should be 347. Was 347.09375. PASS elementRect('s2').top is 20 -FAIL elementRect('s2').left should be 390. Was 389.984375. PASS elementRect('s3').top is 40 -FAIL elementRect('s3').left should be 417. Was 417.1875. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left.html b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left.html index ff7ccbd..e24456a 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left.html +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left.html
@@ -74,13 +74,13 @@ var quiet = true; // PASS output depends on SubPixelLayout.isEnabled() shouldBe("elementRect('s1').top", "0"); -shouldBe("elementRect('s1').left", marginEllipseLeftXIntercept(20, 225, 225, 125), quiet); +shouldBe("elementRect('s1').left", marginEllipseLeftXIntercept(20, 225, 225, 125), quiet, 1); shouldBe("elementRect('s2').top", "20"); -shouldBe("elementRect('s2').left", marginEllipseLeftXIntercept(40, 225, 225, 125), quiet); +shouldBe("elementRect('s2').left", marginEllipseLeftXIntercept(40, 225, 225, 125), quiet, 1); shouldBe("elementRect('s3').top", "40"); -shouldBe("elementRect('s3').left", marginEllipseLeftXIntercept(60, 225, 225, 125), quiet); +shouldBe("elementRect('s3').left", marginEllipseLeftXIntercept(60, 225, 225, 125), quiet, 1); </script> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right-expected.txt b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right-expected.txt index 62c846d5..7085e88 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right-expected.txt
@@ -4,11 +4,8 @@ X X PASS elementRect('s1').top is 0 -FAIL elementRect('s1').right should be 152. Was 152.90625. PASS elementRect('s2').top is 20 -FAIL elementRect('s2').right should be 110. Was 110.015625. PASS elementRect('s3').top is 40 -FAIL elementRect('s3').right should be 82. Was 82.8125. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right.html b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right.html index eb7248e..f8ef26e9 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right.html +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-right.html
@@ -76,13 +76,13 @@ var quiet = true; // PASS output depends on SubPixelLayout.isEnabled() shouldBe("elementRect('s1').top", "0"); -shouldBe("elementRect('s1').right", marginEllipseRightXIntercept(20, 225, 225, 125), quiet); +shouldBe("elementRect('s1').right", marginEllipseRightXIntercept(20, 225, 225, 125), quiet, 1); shouldBe("elementRect('s2').top", "20"); -shouldBe("elementRect('s2').right", marginEllipseRightXIntercept(40, 225, 225, 125), quiet); +shouldBe("elementRect('s2').right", marginEllipseRightXIntercept(40, 225, 225, 125), quiet, 1); shouldBe("elementRect('s3').top", "40"); -shouldBe("elementRect('s3').right", marginEllipseRightXIntercept(60, 225, 225, 125), quiet); +shouldBe("elementRect('s3').right", marginEllipseRightXIntercept(60, 225, 225, 125), quiet, 1); </script> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html b/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html new file mode 100644 index 0000000..1423c2e4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> +.container { + width:200px; + background-color:#eee; +} +.spacer { + height:10px; background-color:black; +} +.nowrap { + white-space: nowrap; +} +</style> +<body> +<p>Spaces in nowrap shold not break when the text before it fits but the space overflows.</p> +<template id=template> + <div class=container> + <img class=spacer /> + <span class=nowrap><span>foo</span> <span>bar</span></span> + </div> +</template> +<script> +run(); +function run() { + let tests = []; + for (let width = 170; width < 180; width++) { + let element = template.content.children[0].cloneNode(true); + let spacer = element.querySelector('img'); + spacer.style.width = width + 'px'; + document.body.appendChild(element); + tests.push({width: width, element: element}); + } + let results = []; + for (let t of tests) { + test(() => { + let nowrap = t.element.querySelector('.nowrap'); + let child1 = nowrap.children[0]; + let child2 = nowrap.children[1]; + assert_equals(child1.offsetTop, child2.offsetTop); + }, `width: ${t.width}`); + } +} +</script> +</body> +
diff --git a/third_party/WebKit/LayoutTests/http/tests/appcache/fallback.html b/third_party/WebKit/LayoutTests/http/tests/appcache/fallback.html index 6a0b7b5..663ba9f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/appcache/fallback.html +++ b/third_party/WebKit/LayoutTests/http/tests/appcache/fallback.html
@@ -143,24 +143,11 @@ { setNetworkEnabled(false); - var req = new XMLHttpRequest; - req.open("GET", testURL); - req.onerror = function() { + if (load(testURL) != load("resources/simple.txt")) { log("FAIL: Loading an URL from fallback namespace when network is disabled returned unexpected response"); hadError = true; - finish(); } - req.onload = function() { - if (req.responseText != "Hello, World!") { - hadError = true; - log("FAIL: Loading an URL from fallback namespace when network is disabled returned unexpected response"); - } - finish(); - } - req.send(""); -} -function finish() { log(hadError ? "FAILURE" : "SUCCESS"); if (window.testRunner) testRunner.notifyDone();
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.png index 8c092715..8b85b370 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.txt deleted file mode 100644 index 5fd4eba..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-inner-bleed-expected.txt +++ /dev/null
@@ -1,63 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x356 - LayoutBlockFlow {HTML} at (0,0) size 800x356 - LayoutBlockFlow {BODY} at (8,8) size 784x340 - LayoutTable {TABLE} at (0,0) size 610x340 - LayoutTableSection {TBODY} at (0,0) size 610x340 - LayoutTableRow {TR} at (0,2) size 610x155 - LayoutTableCell {TD} at (2,2) size 150x155 [r=0 c=0 rs=1 cs=1] - LayoutTableCell {TD} at (154,2) size 150x155 [r=0 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (306,2) size 150x155 [r=0 c=2 rs=1 cs=1] - LayoutTableCell {TD} at (458,2) size 150x155 [r=0 c=3 rs=1 cs=1] - LayoutTableRow {TR} at (0,316) size 610x22 - LayoutTableCell {TD} at (2,316) size 150x22 [r=2 c=0 rs=1 cs=1] - LayoutText {#text} at (58,1) size 34x19 - text run at (58,1) width 34: "PNG" - LayoutTableCell {TD} at (154,316) size 150x22 [r=2 c=1 rs=1 cs=1] - LayoutText {#text} at (58,1) size 34x19 - text run at (58,1) width 34: "SVG" - LayoutTableCell {TD} at (306,316) size 150x22 [r=2 c=2 rs=1 cs=1] - LayoutText {#text} at (58,1) size 34x19 - text run at (58,1) width 34: "PNG" - LayoutTableCell {TD} at (458,316) size 150x22 [r=2 c=3 rs=1 cs=1] - LayoutText {#text} at (58,1) size 34x19 - text run at (58,1) width 34: "SVG" -layer at (31,31) size 108x108 clip at (35,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (183,31) size 108x108 clip at (187,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (335,31) size 108x108 clip at (339,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (487,31) size 108x108 clip at (491,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (8,167) size 610x155 - LayoutTableRow {TR} at (0,159) size 610x155 - LayoutTableCell {TD} at (2,159) size 150x155 [r=1 c=0 rs=1 cs=1] - LayoutTableCell {TD} at (154,159) size 150x155 [r=1 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (306,159) size 150x155 [r=1 c=2 rs=1 cs=1] - LayoutTableCell {TD} at (458,159) size 150x155 [r=1 c=3 rs=1 cs=1] -layer at (31,188) size 108x108 clip at (35,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (183,188) size 108x108 clip at (187,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (335,188) size 108x108 clip at (339,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (487,188) size 108x108 clip at (491,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/mask-with-filter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/mask-with-filter-expected.png index 770e873..21229b8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/mask-with-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/mask-with-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.png index a56937f..b48966d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.txt deleted file mode 100644 index e6330f6..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-inner-bleed-expected.txt +++ /dev/null
@@ -1,63 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x352 - LayoutBlockFlow {HTML} at (0,0) size 800x352 - LayoutBlockFlow {BODY} at (8,8) size 784x336 - LayoutTable {TABLE} at (0,0) size 610x336 - LayoutTableSection {TBODY} at (0,0) size 610x336 - LayoutTableRow {TR} at (0,2) size 610x154 - LayoutTableCell {TD} at (2,2) size 150x154 [r=0 c=0 rs=1 cs=1] - LayoutTableCell {TD} at (154,2) size 150x154 [r=0 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (306,2) size 150x154 [r=0 c=2 rs=1 cs=1] - LayoutTableCell {TD} at (458,2) size 150x154 [r=0 c=3 rs=1 cs=1] - LayoutTableRow {TR} at (0,314) size 610x20 - LayoutTableCell {TD} at (2,314) size 150x20 [r=2 c=0 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x18 - text run at (59,1) width 32: "PNG" - LayoutTableCell {TD} at (154,314) size 150x20 [r=2 c=1 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x18 - text run at (59,1) width 32: "SVG" - LayoutTableCell {TD} at (306,314) size 150x20 [r=2 c=2 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x18 - text run at (59,1) width 32: "PNG" - LayoutTableCell {TD} at (458,314) size 150x20 [r=2 c=3 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x18 - text run at (59,1) width 32: "SVG" -layer at (31,31) size 108x108 clip at (35,35) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (183,31) size 108x108 clip at (187,35) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (335,31) size 108x108 clip at (339,35) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (487,31) size 108x108 clip at (491,35) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (8,166) size 610x154 - LayoutTableRow {TR} at (0,158) size 610x154 - LayoutTableCell {TD} at (2,158) size 150x154 [r=1 c=0 rs=1 cs=1] - LayoutTableCell {TD} at (154,158) size 150x154 [r=1 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (306,158) size 150x154 [r=1 c=2 rs=1 cs=1] - LayoutTableCell {TD} at (458,158) size 150x154 [r=1 c=3 rs=1 cs=1] -layer at (31,187) size 108x108 clip at (35,191) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (183,187) size 108x108 clip at (187,191) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (335,187) size 108x108 clip at (339,191) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (487,187) size 108x108 clip at (491,191) size 100x100 scrollHeight 104 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/mask-with-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/mask-with-filter-expected.png index da7d6c0..bfaa23e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/mask-with-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/mask-with-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.png index 4e6f491c..ea3710c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.txt deleted file mode 100644 index 3e86da1..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-inner-bleed-expected.txt +++ /dev/null
@@ -1,63 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x356 - LayoutBlockFlow {HTML} at (0,0) size 800x356 - LayoutBlockFlow {BODY} at (8,8) size 784x340 - LayoutTable {TABLE} at (0,0) size 610x340 - LayoutTableSection {TBODY} at (0,0) size 610x340 - LayoutTableRow {TR} at (0,2) size 610x155 - LayoutTableCell {TD} at (2,2) size 150x155 [r=0 c=0 rs=1 cs=1] - LayoutTableCell {TD} at (154,2) size 150x155 [r=0 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (306,2) size 150x155 [r=0 c=2 rs=1 cs=1] - LayoutTableCell {TD} at (458,2) size 150x155 [r=0 c=3 rs=1 cs=1] - LayoutTableRow {TR} at (0,316) size 610x22 - LayoutTableCell {TD} at (2,316) size 150x22 [r=2 c=0 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x19 - text run at (59,1) width 32: "PNG" - LayoutTableCell {TD} at (154,316) size 150x22 [r=2 c=1 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x19 - text run at (59,1) width 32: "SVG" - LayoutTableCell {TD} at (306,316) size 150x22 [r=2 c=2 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x19 - text run at (59,1) width 32: "PNG" - LayoutTableCell {TD} at (458,316) size 150x22 [r=2 c=3 rs=1 cs=1] - LayoutText {#text} at (59,1) size 32x19 - text run at (59,1) width 32: "SVG" -layer at (31,31) size 108x108 clip at (35,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (183,31) size 108x108 clip at (187,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (335,31) size 108x108 clip at (339,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (487,31) size 108x108 clip at (491,35) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (8,167) size 610x155 - LayoutTableRow {TR} at (0,159) size 610x155 - LayoutTableCell {TD} at (2,159) size 150x155 [r=1 c=0 rs=1 cs=1] - LayoutTableCell {TD} at (154,159) size 150x155 [r=1 c=1 rs=1 cs=1] - LayoutTableCell {TD} at (306,159) size 150x155 [r=1 c=2 rs=1 cs=1] - LayoutTableCell {TD} at (458,159) size 150x155 [r=1 c=3 rs=1 cs=1] -layer at (31,188) size 108x108 clip at (35,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (183,188) size 108x108 clip at (187,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (335,188) size 108x108 clip at (339,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0 -layer at (487,188) size 108x108 clip at (491,192) size 100x100 scrollHeight 105 - LayoutBlockFlow {DIV} at (21,21) size 108x108 [bgcolor=#FF0000] [border: (4px solid #008000)] - LayoutImage {IMG} at (4,4) size 100x100 - LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/transferFromImageBitmap.html b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/transferFromImageBitmap.html new file mode 100644 index 0000000..05b3784 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/transferFromImageBitmap.html
@@ -0,0 +1,133 @@ +<!DOCTYPE HTML> +<script src="../../../../../resources/testharness.js"></script> +<script src="../../../../../resources/testharnessreport.js"></script> +<script> + +// This test examines the color managed ImageBitmapRenderingContext. +// - We first draw on 2D canvas with different color space and alpha +// properties. +// - Next, the canvas is used as a source image to create an ImageBitmap. +// Different colorSpaceConversion values are tested when creating the +// intermediate ImageBitmap object. +// - Next, ImageBitmap is transferred to an ImageBitmapRenderingContext. +// - Since we cannot read back pixels from ImageBitmapRenderingContext, we +// draw it to another 2D canvas and read back the pixels. +// - Finally, we compare the pixels read from the first 2D canvas with those +// read from the final 2D canvas. We expect them to match with some +// tolerance. + +function testPixels(actualPixels, expectedPixels, testScenario) +{ + var tolerance = 0; + + // When using a linear gamma image bitmap as the intermediate image object + // for sRGB source canvas, {sRGB-> wide gamut -> sRGB} color conversion in + // Skia introduces some variance in color values. Hence, in this case we + // set the tolerance to 8 (6 is the max error observed on Linux for the used + // pixels). For a thorough investigation, please see: + // https://fiddle.skia.org/c/584fbc0b778a32a6cc2ea3ecbf2c6e8e + if (testScenario.colorSpace == "srgb" && + testScenario.pixelFormat == "8-8-8-8" && + ['linear-rgb', 'rec2020', 'p3'].indexOf( + testScenario.colorSpaceConversion) > -1) + tolerance = 8; + + // Otherwise, if the source color space is wide gamut, we set the tolerance + // to 0.01. + else if (testScenario.pixelFormat == "float16") + tolerance = 0.01; + + assert_array_approx_equals(actualPixels, expectedPixels, tolerance); +} + +function generateFillStyle(red, green, blue, alpha) { + return "rgba(" + red + "," + green + "," + blue + "," + alpha + ")"; +} + +function generateExpectedResult(testScenario, canvas) +{ + var ctx = canvas.getContext('2d', {colorSpace: testScenario.colorSpace, + pixelFormat: testScenario.pixelFormat}); + ctx.fillStyle = generateFillStyle(155, 27, 27, testScenario.alpha); + ctx.fillRect(0, 0, 1, 1); + ctx.fillStyle = generateFillStyle(27, 155, 27, testScenario.alpha); + ctx.fillRect(1, 0, 1, 1); + ctx.fillStyle = generateFillStyle(27, 27, 155, testScenario.alpha); + ctx.fillRect(0, 1, 1, 1); + ctx.fillStyle = generateFillStyle(27, 27, 27, testScenario.alpha); + ctx.fillRect(1, 1, 1, 1); + return ctx.getImageData(0, 0, 2, 2).dataUnion; +} + +function generateTestName(testScenario) { + var str = "Testing ImageBitmapRenderingContext:" + + " Source color space: " + testScenario.colorSpace + + ", pixel format: " + testScenario.pixelFormat + + ", alpha: " + testScenario.alpha + + ", intermediate color space: " + + testScenario.colorSpaceConversion; + return str; +} + +function runTransferFromImageBitmapTest(testScenario) { + var canvas = document.createElement("canvas"); + canvas.width = 2; + canvas.height = 2; + var expectedPixels = generateExpectedResult(testScenario, canvas); + + promise_test(function() { + var options = {colorSpaceConversion: testScenario.colorSpaceConversion}; + var promise = createImageBitmap(canvas, options); + return Promise.all([promise]).then(([imagebitmap]) => { + var dstCanvas = document.createElement("canvas"); + dstCanvas.width = 2; + dstCanvas.height = 2; + var dstCtx = dstCanvas.getContext('bitmaprenderer'); + dstCtx.transferFromImageBitmap(imagebitmap); + + // ImageBitmapRenderingContext does not have ImageData, so we draw + // it on another canvas and read back the data. + var finalCanvas = document.createElement("canvas"); + finalCanvas.width = 2; + finalCanvas.height = 2; + var ctx = finalCanvas.getContext('2d', + {colorSpace: testScenario.colorSpace, + pixelFormat: testScenario.pixelFormat}); + ctx.drawImage(dstCanvas, 0, 0); + var actualPixels = ctx.getImageData(0, 0, 2, 2).dataUnion; + testPixels(actualPixels, expectedPixels, testScenario); + }); + }, generateTestName(testScenario)); +} + + +function runAllTests() { + var colorSpaces = [ + {colorSpace: 'srgb', pixelFormat: '8-8-8-8'}, + {colorSpace: 'srgb', pixelFormat: 'float16'}, + {colorSpace: 'rec2020', pixelFormat: 'float16'}, + {colorSpace: 'p3', pixelFormat: 'float16'} + ]; + var alphaValues = [0.5, 1]; + var colorSpaceConversions = [ + 'none', 'default', 'srgb', 'linear-rgb', 'rec2020', 'p3']; + + var testScenarios = []; + for (var i = 0; i < colorSpaces.length; i++) + for (var j = 0; j < alphaValues.length; j++) + for (var k = 0; k < colorSpaceConversions.length; k++) { + var testScenario = {}; + testScenario.colorSpace = colorSpaces[i].colorSpace; + testScenario.pixelFormat = colorSpaces[i].pixelFormat; + testScenario.alpha = alphaValues[j]; + testScenario.colorSpaceConversion = colorSpaceConversions[k]; + testScenarios.push(testScenario); + } + + for (var i = 0; i < testScenarios.length; i++) + runTransferFromImageBitmapTest(testScenarios[i]); +} + +runAllTests(); + +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index 2735c3ea..53c56d4d 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1277,13 +1277,11 @@ getter origin getter plugins getter pointerLockElement - getter preferredStylesheetSet getter readyState getter referrer getter rootElement getter scripts getter scrollingElement - getter selectedStylesheetSet getter styleSheets getter title getter visibilityState @@ -1447,7 +1445,6 @@ setter onwebkitfullscreenchange setter onwebkitfullscreenerror setter onwheel - setter selectedStylesheetSet setter title setter vlinkColor setter xmlStandalone
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline-dispose.html b/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline-dispose.html deleted file mode 100644 index adabe40..0000000 --- a/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline-dispose.html +++ /dev/null
@@ -1,56 +0,0 @@ -<!DOCTYPE html> -<title>Regression test to ensure detaching a ScrollTimeline shouldn't crash</title> -<script src="../../../../resources/testharness.js"></script> -<script src="../../../../resources/testharnessreport.js"></script> - -<script src="resources/animation-worklet-tests.js"></script> - -<style> -#scroller { - overflow: auto; - height: 100px; - width: 100px; -} - -#contents { - height: 1000px; - width: 100%; -} -</style> - -<div id="box"></div> -<div id="scroller"> - <div id="contents"></div> -</div> - -<script> -// This is a regression test for the crash seen when http://crrev.com/ddd9f0ee -// landed. The root of the crash was assuming a WeakMember from a static object -// would still be alive during a USING_PRE_FINALIZER method, which is not true. -async_test(t => { - const box = document.getElementById('box'); - const effect = new KeyframeEffect(box, null); - - let scroller = document.getElementById('scroller'); - let timeline = new ScrollTimeline({ - scrollSource: scroller, - timeRange: 1000, - orientation: 'block' - }); - // Creating the animation will cause the scroller to be registered as being - // used in an attached ScrollTimeline. - let animation = new WorkletAnimation('test_animator', effect, timeline, {}); - - // Now free up everything at once. - scroller.remove(); - animation.cancel(); - scroller = undefined; - timeline = undefined; - animation = undefined; - - requestAnimationFrame(t.step_func_done(() => { - // Force GC - this shouldn't crash. - gc(); - })); -}, 'Disposing of an attached ScrollTimeline should not crash'); -</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline.html b/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline.html index 2a63b1b..c96ed4e 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline.html +++ b/third_party/WebKit/LayoutTests/virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline.html
@@ -16,6 +16,7 @@ overflow: auto; height: 100px; width: 100px; + will-change: transform; /* force compositing */ } #contents {
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/fast/scrolling/README.txt b/third_party/WebKit/LayoutTests/virtual/threaded/fast/scrolling/README.txt new file mode 100644 index 0000000..0df19af2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/threaded/fast/scrolling/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in fast/scrolling with a threaded compositor and +# compositing sub-scrollers even if they'd lose LCD text. See the +# virtual_test_suites() method in tools/blinkpy/web_tests/port/base.py.
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 9ad512d..b18e177 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1600,14 +1600,12 @@ getter plugins getter pointerLockElement getter policy - getter preferredStylesheetSet getter readyState getter referrer getter rootElement getter rootScroller getter scripts getter scrollingElement - getter selectedStylesheetSet getter styleSheets getter timeline getter title @@ -1784,7 +1782,6 @@ setter onwebkitfullscreenerror setter onwheel setter rootScroller - setter selectedStylesheetSet setter title setter vlinkColor setter xmlStandalone
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn index b2d88aa..7d6b8d1 100644 --- a/third_party/blink/common/BUILD.gn +++ b/third_party/blink/common/BUILD.gn
@@ -25,6 +25,7 @@ "message_port/cloneable_message_struct_traits.cc", "message_port/cloneable_message_struct_traits.h", "message_port/message_port_channel.cc", + "message_port/string_message_codec.cc", "message_port/transferable_message.cc", "message_port/transferable_message_struct_traits.cc", "message_port/transferable_message_struct_traits.h", @@ -64,6 +65,7 @@ sources = [ "device_memory/approximated_device_memory_unittest.cc", "feature_policy/feature_policy_unittest.cc", + "message_port/string_message_codec_unittest.cc", "mime_util/mime_util_unittest.cc", "origin_manifest/origin_manifest_unittest.cc", "origin_trials/trial_token_unittest.cc", @@ -78,5 +80,7 @@ "//testing/gtest", "//third_party/blink/public/common:headers", "//third_party/boringssl", + "//v8", + "//v8:v8_libplatform", ] }
diff --git a/third_party/blink/common/DEPS b/third_party/blink/common/DEPS index 3308652..50d39c7 100644 --- a/third_party/blink/common/DEPS +++ b/third_party/blink/common/DEPS
@@ -18,3 +18,6 @@ "+third_party/blink/public/mojom", "+url", ] +specific_include_rules = { + '.*unittest.?.cc': [ "+v8" ], +}
diff --git a/content/browser/android/string_message_codec.cc b/third_party/blink/common/message_port/string_message_codec.cc similarity index 94% rename from content/browser/android/string_message_codec.cc rename to third_party/blink/common/message_port/string_message_codec.cc index 5303ac43..45f5e26 100644 --- a/content/browser/android/string_message_codec.cc +++ b/third_party/blink/common/message_port/string_message_codec.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/android/string_message_codec.h" +#include "third_party/blink/public/common/message_port/string_message_codec.h" #include <vector> #include "base/logging.h" -namespace content { +namespace blink { namespace { const uint32_t kVarIntShift = 7; @@ -46,7 +46,8 @@ } } -void WriteBytes(const char* bytes, size_t num_bytes, +void WriteBytes(const char* bytes, + size_t num_bytes, std::vector<uint8_t>* buffer) { buffer->insert(buffer->end(), bytes, bytes + num_bytes); } @@ -79,7 +80,7 @@ return !(x & 0xFF00); } -} // namespace +} // namespace std::vector<uint8_t> EncodeStringMessage(const base::string16& data) { std::vector<uint8_t> buffer; @@ -142,4 +143,4 @@ return false; } -} // namespace content +} // namespace blink
diff --git a/content/browser/android/string_message_codec_unittest.cc b/third_party/blink/common/message_port/string_message_codec_unittest.cc similarity index 91% rename from content/browser/android/string_message_codec_unittest.cc rename to third_party/blink/common/message_port/string_message_codec_unittest.cc index d32233e3..42435ca 100644 --- a/content/browser/android/string_message_codec_unittest.cc +++ b/third_party/blink/common/message_port/string_message_codec_unittest.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/android/string_message_codec.h" +#include "third_party/blink/public/common/message_port/string_message_codec.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "v8/include/v8.h" -namespace content { +namespace blink { namespace { base::string16 DecodeWithV8(const std::vector<uint8_t>& encoded) { @@ -36,7 +36,7 @@ v8::Local<v8::String> str = value->ToString(context).ToLocalChecked(); result.resize(str->Length()); - str->Write(&result[0], 0, result.size()); + str->Write(reinterpret_cast<uint16_t*>(&result[0]), 0, result.size()); } isolate->Dispose(); delete params.array_buffer_allocator; @@ -59,10 +59,10 @@ v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Local<v8::String> message_as_value = - v8::String::NewFromTwoByte(isolate, - message.data(), - v8::NewStringType::kNormal, - message.size()).ToLocalChecked(); + v8::String::NewFromTwoByte( + isolate, reinterpret_cast<const uint16_t*>(message.data()), + v8::NewStringType::kNormal, message.size()) + .ToLocalChecked(); v8::ValueSerializer serializer(isolate); serializer.WriteHeader(); @@ -136,4 +136,4 @@ } } // namespace -} // namespace content +} // namespace blink
diff --git a/third_party/blink/common/test/run_all_unittests.cc b/third_party/blink/common/test/run_all_unittests.cc index a85d337..aaa1df0 100644 --- a/third_party/blink/common/test/run_all_unittests.cc +++ b/third_party/blink/common/test/run_all_unittests.cc
@@ -8,10 +8,18 @@ #include "base/bind.h" #include "base/test/test_suite.h" +#include "v8/include/libplatform/libplatform.h" +#include "v8/include/v8.h" int main(int argc, char** argv) { base::TestSuite test_suite(argc, argv); + v8::V8::InitializeICUDefaultLocation(argv[0]); + v8::V8::InitializeExternalStartupData(argv[0]); + auto platform = base::WrapUnique(v8::platform::CreateDefaultPlatform()); + v8::V8::InitializePlatform(platform.get()); + v8::V8::Initialize(); + return base::LaunchUnitTests( argc, argv, base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 5f52eb9..f085dd9 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -328,7 +328,6 @@ "platform/web_menu_source_type.h", "platform/web_mixed_content.h", "platform/web_mixed_content_context_type.h", - "platform/web_mock_clipboard.h", "platform/web_mouse_event.h", "platform/web_mouse_wheel_event.h", "platform/web_native_scroll_behavior.h", @@ -382,8 +381,6 @@ "platform/web_scrollbar_behavior.h", "platform/web_scrollbar_buttons_placement.h", "platform/web_scrollbar_overlay_color_theme.h", - "platform/web_scrollbar_theme_geometry.h", - "platform/web_scrollbar_theme_painter.h", "platform/web_security_origin.h", "platform/web_security_style.h", "platform/web_selection_bound.h",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index ceff049..e354c4ca 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -41,6 +41,7 @@ "frame/sandbox_flags.h", "message_port/cloneable_message.h", "message_port/message_port_channel.h", + "message_port/string_message_codec.h", "message_port/transferable_message.h", "mime_util/mime_util.h", "origin_manifest/origin_manifest.h",
diff --git a/content/browser/android/string_message_codec.h b/third_party/blink/public/common/message_port/string_message_codec.h similarity index 69% rename from content/browser/android/string_message_codec.h rename to third_party/blink/public/common/message_port/string_message_codec.h index a613f05..98a6615e 100644 --- a/content/browser/android/string_message_codec.h +++ b/third_party/blink/public/common/message_port/string_message_codec.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_ANDROID_STRING_MESSAGE_CODEC_H_ -#define CONTENT_BROWSER_ANDROID_STRING_MESSAGE_CODEC_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGE_PORT_STRING_MESSAGE_CODEC_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGE_PORT_STRING_MESSAGE_CODEC_H_ #include <vector> #include "base/strings/string16.h" -#include "content/common/content_export.h" +#include "third_party/blink/common/common_export.h" -namespace content { +namespace blink { // To support exposing HTML message ports to Java, it is necessary to be able // to encode and decode message data using the same serialization format as V8. @@ -21,13 +21,13 @@ // handle string messages and this serialization format is static, as it is a // format we currently persist to disk via IndexedDB. -CONTENT_EXPORT std::vector<uint8_t> EncodeStringMessage( +BLINK_COMMON_EXPORT std::vector<uint8_t> EncodeStringMessage( const base::string16& data); -CONTENT_EXPORT bool DecodeStringMessage( +BLINK_COMMON_EXPORT bool DecodeStringMessage( const std::vector<uint8_t>& encoded_data, base::string16* result); -} // namespace content +} // namespace blink -#endif // CONTENT_BROWSER_ANDROID_STRING_MESSAGE_CODEC_H_ +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGE_PORT_STRING_MESSAGE_CODEC_H_
diff --git a/third_party/blink/public/mojom/use_counter/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/css_property_id.mojom index f8abb73d..93d9d3d 100644 --- a/third_party/blink/public/mojom/use_counter/css_property_id.mojom +++ b/third_party/blink/public/mojom/use_counter/css_property_id.mojom
@@ -4,7 +4,7 @@ module blink.mojom; -const int32 kMaximumCSSSampleId = 592; +const int32 kMaximumCSSSampleId = 593; // This CSSSampleId represents page load for CSS histograms. It is recorded once // per page visit for each CSS histogram being logged on the blink side and the
diff --git a/third_party/blink/public/platform/web_compositor_support.h b/third_party/blink/public/platform/web_compositor_support.h index 4dc25f9..d86c764 100644 --- a/third_party/blink/public/platform/web_compositor_support.h +++ b/third_party/blink/public/platform/web_compositor_support.h
@@ -30,7 +30,6 @@ #include "third_party/blink/public/platform/web_float_point.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" #include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_painter.h" #include <memory>
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom index 71480e2..3eee6102 100644 --- a/third_party/blink/public/platform/web_feature.mojom +++ b/third_party/blink/public/platform/web_feature.mojom
@@ -1686,9 +1686,6 @@ kMicrophoneDisabledByFeaturePolicyEstimate = 2208, kCameraDisabledByFeaturePolicyEstimate = 2209, kMidiDisabledByFeaturePolicy = 2210, - kDocumentGetPreferredStylesheetSet = 2211, - kDocumentGetSelectedStylesheetSet = 2212, - kDocumentSetSelectedStylesheetSet = 2213, kGeolocationGetCurrentPosition = 2214, kGeolocationWatchPosition = 2215, kDataUriHasOctothorpe = 2216,
diff --git a/third_party/blink/public/platform/web_mock_clipboard.h b/third_party/blink/public/platform/web_mock_clipboard.h deleted file mode 100644 index 7773402..0000000 --- a/third_party/blink/public/platform/web_mock_clipboard.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MOCK_CLIPBOARD_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MOCK_CLIPBOARD_H_ - -#include "base/containers/span.h" -#include "third_party/blink/public/platform/web_clipboard.h" -#include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_image.h" - -namespace blink { - -// Provides convenience methods for retrieving data from the mock clipboard -// used in layout and unit tests. -class BLINK_PLATFORM_EXPORT WebMockClipboard : public WebClipboard { - public: - virtual WebImage ReadRawImage(mojom::ClipboardBuffer) { return WebImage(); } - - protected: - // Convenience method for WebMockClipoard implementations to create a blob - // from bytes. - WebBlobInfo CreateBlobFromData(base::span<const uint8_t> data, - const WebString& mime_type); -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/public/platform/web_scrollbar.h b/third_party/blink/public/platform/web_scrollbar.h index 73029e8..2900455 100644 --- a/third_party/blink/public/platform/web_scrollbar.h +++ b/third_party/blink/public/platform/web_scrollbar.h
@@ -25,71 +25,13 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCROLLBAR_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCROLLBAR_H_ -#include "third_party/blink/public/platform/web_point.h" -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/public/platform/web_scrollbar_overlay_color_theme.h" -#include "third_party/blink/public/platform/web_size.h" -#include "third_party/blink/public/platform/web_vector.h" - namespace blink { -// A const accessor interface for a WebKit scrollbar -class BLINK_PLATFORM_EXPORT WebScrollbar { +// TODO(jbroman): Clean up these, which are used elsewhere. +class WebScrollbar { public: enum Orientation { kHorizontal, kVertical }; - - enum ScrollDirection { kScrollBackward, kScrollForward }; - - enum ScrollGranularity { - kScrollByLine, - kScrollByPage, - kScrollByDocument, - kScrollByPixel - }; - - enum ScrollbarControlSize { kRegularScrollbar, kSmallScrollbar }; - - enum ScrollbarPart { - kNoPart = 0, - kBackButtonStartPart = 1, - kForwardButtonStartPart = 1 << 1, - kBackTrackPart = 1 << 2, - kThumbPart = 1 << 3, - kForwardTrackPart = 1 << 4, - kBackButtonEndPart = 1 << 5, - kForwardButtonEndPart = 1 << 6, - kScrollbarBGPart = 1 << 7, - kTrackBGPart = 1 << 8, - kAllParts = 0xffffffff - }; - enum class ScrollingMode { kAuto, kAlwaysOff, kAlwaysOn, kLast = kAlwaysOn }; - - virtual ~WebScrollbar() = default; - - // Return true if this is an overlay scrollbar. - virtual bool IsOverlay() const = 0; - - // Gets the current value (i.e. position inside the region). - virtual int Value() const = 0; - - virtual WebPoint Location() const = 0; - virtual WebSize Size() const = 0; - virtual bool Enabled() const = 0; - virtual int Maximum() const = 0; - virtual int TotalSize() const = 0; - virtual bool IsScrollableAreaActive() const = 0; - virtual bool HasTickmarks() const = 0; - virtual void GetTickmarks(WebVector<WebRect>& tickmarks) const = 0; - virtual ScrollbarControlSize GetControlSize() const = 0; - virtual ScrollbarPart PressedPart() const = 0; - virtual ScrollbarPart HoveredPart() const = 0; - virtual WebScrollbarOverlayColorTheme ScrollbarOverlayColorTheme() const = 0; - virtual bool IsCustomScrollbar() const = 0; - virtual Orientation GetOrientation() const = 0; - virtual bool IsLeftSideVerticalScrollbar() const = 0; - virtual float ElasticOverscroll() const = 0; - virtual void SetElasticOverscroll(float) = 0; }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_scrollbar_theme_geometry.h b/third_party/blink/public/platform/web_scrollbar_theme_geometry.h deleted file mode 100644 index 94ac1c1..0000000 --- a/third_party/blink/public/platform/web_scrollbar_theme_geometry.h +++ /dev/null
@@ -1,54 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCROLLBAR_THEME_GEOMETRY_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCROLLBAR_THEME_GEOMETRY_H_ - -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/public/platform/web_size.h" - -namespace blink { - -class WebScrollbar; - -class BLINK_PLATFORM_EXPORT WebScrollbarThemeGeometry { - public: - virtual ~WebScrollbarThemeGeometry() = default; - - virtual bool HasButtons(WebScrollbar*) = 0; - virtual bool HasThumb(WebScrollbar*) = 0; - virtual WebRect TrackRect(WebScrollbar*) = 0; - virtual WebRect ThumbRect(WebScrollbar*) = 0; - virtual WebRect BackButtonStartRect(WebScrollbar*) = 0; - virtual WebRect BackButtonEndRect(WebScrollbar*) = 0; - virtual WebRect ForwardButtonStartRect(WebScrollbar*) = 0; - virtual WebRect ForwardButtonEndRect(WebScrollbar*) = 0; - virtual WebSize NinePatchThumbCanvasSize(WebScrollbar*) = 0; - virtual WebRect NinePatchThumbAperture(WebScrollbar*) = 0; -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/public/platform/web_scrollbar_theme_painter.h b/third_party/blink/public/platform/web_scrollbar_theme_painter.h deleted file mode 100644 index e8aa55c..0000000 --- a/third_party/blink/public/platform/web_scrollbar_theme_painter.h +++ /dev/null
@@ -1,105 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCROLLBAR_THEME_PAINTER_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SCROLLBAR_THEME_PAINTER_H_ - -#include "third_party/blink/public/platform/web_canvas.h" -#include "third_party/blink/public/platform/web_private_ptr.h" -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/public/platform/web_size.h" - -namespace blink { - -class ScrollbarTheme; -class Scrollbar; -class WebScrollbar; - -class WebScrollbarThemePainter { - public: - WebScrollbarThemePainter() : theme_(0), device_scale_factor_(1.0) {} - WebScrollbarThemePainter(const WebScrollbarThemePainter& painter) { - Assign(painter); - } - virtual ~WebScrollbarThemePainter() { Reset(); } - WebScrollbarThemePainter& operator=(const WebScrollbarThemePainter& painter) { - Assign(painter); - return *this; - } - - BLINK_PLATFORM_EXPORT void Assign(const WebScrollbarThemePainter&); - BLINK_PLATFORM_EXPORT void Reset(); - - BLINK_PLATFORM_EXPORT void PaintScrollbarBackground(WebCanvas*, - const WebRect&); - BLINK_PLATFORM_EXPORT void PaintTrackBackground(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintBackTrackPart(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintForwardTrackPart(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintBackButtonStart(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintBackButtonEnd(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintForwardButtonStart(WebCanvas*, - const WebRect&); - BLINK_PLATFORM_EXPORT void PaintForwardButtonEnd(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintTickmarks(WebCanvas*, const WebRect&); - BLINK_PLATFORM_EXPORT void PaintThumb(WebCanvas*, const WebRect&); - - // This opacity is applied on top of the content that is painted for the - // thumb. - BLINK_PLATFORM_EXPORT float ThumbOpacity() const; - - BLINK_PLATFORM_EXPORT bool TrackNeedsRepaint() const; - BLINK_PLATFORM_EXPORT bool ThumbNeedsRepaint() const; - - BLINK_PLATFORM_EXPORT bool UsesNinePatchThumbResource() const; - -#if INSIDE_BLINK - BLINK_PLATFORM_EXPORT WebScrollbarThemePainter(ScrollbarTheme&, - Scrollbar&, - float device_scale_factor); -#endif - - BLINK_PLATFORM_EXPORT float DeviceScaleFactor() const { - return device_scale_factor_; - } - - private: - // The theme is not owned by this class. It is assumed that the theme is a - // static pointer and its lifetime is essentially infinite. The functions - // called from the painter may not be thread-safe, so all calls must be made - // from the same thread that it is created on. - ScrollbarTheme* theme_; - - // It is assumed that the constructor of this paint object is responsible - // for the lifetime of this scrollbar. The painter has to use the real - // scrollbar (and not a WebScrollbar wrapper) due to static_casts for - // LayoutScrollbar and pointer-based HashMap lookups for Lion scrollbars. - WebPrivatePtr<Scrollbar> scrollbar_; - - float device_scale_factor_; -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/public/platform/web_url_loader.h b/third_party/blink/public/platform/web_url_loader.h index 5e0ec2b..ffe1180 100644 --- a/third_party/blink/public/platform/web_url_loader.h +++ b/third_party/blink/public/platform/web_url_loader.h
@@ -56,7 +56,6 @@ // will instead be redirected to a blob, which is passed out in // |downloaded_blob|. virtual void LoadSynchronously( - WebURLLoaderClient*, const WebURLRequest&, WebURLResponse&, base::Optional<WebURLError>&,
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index d5dc388..cd1aff4 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1633,7 +1633,6 @@ "animation/keyframe_effect_model_test.cc", "animation/keyframe_effect_test.cc", "animation/property_handle_test.cc", - "animation/scroll_timeline_test.cc", "animation/timing_calculations_test.cc", "animation/timing_input_test.cc", "clipboard/data_object_test.cc",
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index bb4712b1..020e66b 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -6,18 +6,11 @@ #include "third_party/blink/renderer/core/dom/exception_code.h" #include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" namespace blink { namespace { -using ActiveScrollTimelineSet = PersistentHeapHashCountedSet<WeakMember<Node>>; -ActiveScrollTimelineSet& GetActiveScrollTimelineSet() { - DEFINE_STATIC_LOCAL(ActiveScrollTimelineSet, set, ()); - return set; -} - bool StringToScrollDirection(String scroll_direction, ScrollTimeline::ScrollDirection& result) { // TODO(smcgruer): Support 'auto' value. @@ -53,17 +46,17 @@ return nullptr; } - return new ScrollTimeline(scroll_source, orientation, + return new ScrollTimeline(document, scroll_source, orientation, options.timeRange().GetAsDouble()); } -ScrollTimeline::ScrollTimeline(Element* scroll_source, +ScrollTimeline::ScrollTimeline(const Document& document, + Element* scroll_source, ScrollDirection orientation, double time_range) : scroll_source_(scroll_source), orientation_(orientation), time_range_(time_range) { - DCHECK(scroll_source_); } double ScrollTimeline::currentTime(bool& is_null) { @@ -147,31 +140,9 @@ result.SetDouble(time_range_); } -void ScrollTimeline::AttachAnimation() { - GetActiveScrollTimelineSet().insert(scroll_source_); - scroll_source_->GetDocument() - .GetLayoutView() - ->Compositor() - ->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); -} - -void ScrollTimeline::DetachAnimation() { - GetActiveScrollTimelineSet().erase(scroll_source_); - scroll_source_->GetDocument() - .GetLayoutView() - ->Compositor() - ->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree); -} - void ScrollTimeline::Trace(blink::Visitor* visitor) { visitor->Trace(scroll_source_); AnimationTimeline::Trace(visitor); } -bool ScrollTimeline::HasActiveScrollTimeline(Node* node) { - ActiveScrollTimelineSet& set = GetActiveScrollTimelineSet(); - auto it = set.find(node); - return it != set.end() && it->value > 0; -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.h b/third_party/blink/renderer/core/animation/scroll_timeline.h index f33ef32..06ea148 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.h +++ b/third_party/blink/renderer/core/animation/scroll_timeline.h
@@ -46,22 +46,10 @@ ScrollDirection GetOrientation() const { return orientation_; } - // Must be called when this ScrollTimeline is attached/unattached from an - // animation. - void AttachAnimation(); - void DetachAnimation(); - void Trace(blink::Visitor*) override; - // For the AnimationWorklet origin trial, we need to automatically composite - // elements that are targets of ScrollTimelines (http://crbug.com/776533). We - // expose a static lookup method to enable this. - // - // TODO(crbug.com/839341): Remove once WorkletAnimations can run on main. - static bool HasActiveScrollTimeline(Node* node); - private: - ScrollTimeline(Element*, ScrollDirection, double); + ScrollTimeline(const Document&, Element*, ScrollDirection, double); Member<Element> scroll_source_; ScrollDirection orientation_;
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_test.cc deleted file mode 100644 index 195c6d5..0000000 --- a/third_party/blink/renderer/core/animation/scroll_timeline_test.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/animation/scroll_timeline.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/bindings/core/v8/exception_state.h" -#include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" - -namespace blink { - -using ScrollTimelineTest = RenderingTest; - -TEST_F(ScrollTimelineTest, - AttachingAndDetachingAnimationCausesCompositingUpdate) { - EnableCompositing(); - - SetBodyInnerHTML(R"HTML( - <style>#scroller { overflow: scroll; width: 100px; height: 100px; }</style> - <div id='scroller'></div> - )HTML"); - - LayoutBoxModelObject* scroller = - ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller")); - ASSERT_TRUE(scroller); - - // Invariant: the scroller is not composited by default. - EXPECT_EQ(DocumentLifecycle::kPaintClean, - GetDocument().Lifecycle().GetState()); - EXPECT_EQ(kNotComposited, scroller->Layer()->GetCompositingState()); - - // Create the ScrollTimeline. This shouldn't cause the scrollSource to need - // compositing, as it isn't attached to any animation yet. - ScrollTimelineOptions options; - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); - options.setTimeRange(time_range); - options.setScrollSource(GetElementById("scroller")); - ScrollTimeline* scroll_timeline = - ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); - EXPECT_EQ(DocumentLifecycle::kPaintClean, - GetDocument().Lifecycle().GetState()); - EXPECT_EQ(kNotComposited, scroller->Layer()->GetCompositingState()); - - // Now attach an animation. This should require a compositing update. - scroll_timeline->AttachAnimation(); - - UpdateAllLifecyclePhases(); - EXPECT_NE(scroller->Layer()->GetCompositingState(), kNotComposited); - - // Now detach an animation. This should again require a compositing update. - scroll_timeline->DetachAnimation(); - - UpdateAllLifecyclePhases(); - EXPECT_EQ(scroller->Layer()->GetCompositingState(), kNotComposited); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/css/CSSProperties.json5 b/third_party/blink/renderer/core/css/CSSProperties.json5 index 41b62d0..4871182 100644 --- a/third_party/blink/renderer/core/css/CSSProperties.json5 +++ b/third_party/blink/renderer/core/css/CSSProperties.json5
@@ -4200,6 +4200,12 @@ is_descriptor: true, is_property: false, }, + { + name: "viewport-fit", + is_descriptor: true, + is_property: false, + runtime_flag: "DisplayCutoutViewportFit", + }, // Shorthands {
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser.cc b/third_party/blink/renderer/core/css/parser/css_property_parser.cc index 7e67290..8a78b16 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_property_parser.cc
@@ -270,6 +270,8 @@ case CSSPropertyOrientation: return ConsumeIdent<CSSValueAuto, CSSValuePortrait, CSSValueLandscape>( range); + case CSSPropertyViewportFit: + return ConsumeIdent<CSSValueAuto, CSSValueContain, CSSValueCover>(range); default: NOTREACHED(); break; @@ -325,6 +327,7 @@ *parsed_properties_); return true; } + case CSSPropertyViewportFit: case CSSPropertyMinWidth: case CSSPropertyMaxWidth: case CSSPropertyMinHeight:
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc index a10b48d..202cf64 100644 --- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
@@ -52,6 +52,16 @@ namespace blink { +namespace { + +bool HasViewportFitProperty(const CSSPropertyValueSet* property_set) { + DCHECK(property_set); + return RuntimeEnabledFeatures::DisplayCutoutViewportFitEnabled() && + property_set->HasProperty(CSSPropertyViewportFit); +} + +} // namespace + ViewportStyleResolver::ViewportStyleResolver(Document& document) : document_(document) { DCHECK(document.GetFrame()); @@ -205,6 +215,8 @@ description.min_height = ViewportLengthValue(CSSPropertyMinHeight); description.max_height = ViewportLengthValue(CSSPropertyMaxHeight); description.orientation = ViewportArgumentValue(CSSPropertyOrientation); + if (HasViewportFitProperty(property_set_)) + description.SetViewportFit(ViewportFitValue()); document_->SetViewportDescription(description); @@ -310,6 +322,26 @@ return result; } +ViewportDescription::ViewportFit ViewportStyleResolver::ViewportFitValue() + const { + const CSSValue* value = + property_set_->GetPropertyCSSValue(CSSPropertyViewportFit); + if (value->IsIdentifierValue()) { + switch (ToCSSIdentifierValue(value)->GetValueID()) { + case CSSValueCover: + return ViewportDescription::ViewportFit::kCover; + case CSSValueContain: + return ViewportDescription::ViewportFit::kContain; + case CSSValueAuto: + default: + return ViewportDescription::ViewportFit::kAuto; + } + } + + NOTREACHED(); + return ViewportDescription::ViewportFit::kAuto; +} + void ViewportStyleResolver::InitialStyleChanged() { initial_style_ = nullptr; // We need to recollect if the initial font size changed and media queries
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h index 74677cee..45a122d 100644 --- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/rule_set.h" #include "third_party/blink/renderer/core/css_property_names.h" +#include "third_party/blink/renderer/core/dom/viewport_description.h" #include "third_party/blink/renderer/platform/length.h" namespace blink { @@ -78,6 +79,7 @@ float ViewportArgumentValue(CSSPropertyID) const; Length ViewportLengthValue(CSSPropertyID); + ViewportDescription::ViewportFit ViewportFitValue() const; Member<Document> document_; Member<MutableCSSPropertyValueSet> property_set_;
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 82c200b..905a986 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1101,24 +1101,9 @@ if (!preferred_stylesheet_set_name_.IsEmpty()) return; preferred_stylesheet_set_name_ = name; - // TODO(futhark@chromium.org): Setting the selected set here is wrong if the - // set has been previously set by through Document.selectedStylesheetSet. Our - // current implementation ignores the effect of Document.selectedStylesheetSet - // and either only collects persistent style, or additionally preferred - // style when present. - selected_stylesheet_set_name_ = name; MarkDocumentDirty(); } -void StyleEngine::SetSelectedStylesheetSetName(const String& name) { - selected_stylesheet_set_name_ = name; - // TODO(futhark@chromium.org): Setting Document.selectedStylesheetSet - // currently has no other effect than the ability to read back the set value - // using the same api. If it did have an effect, we should have marked the - // document scope dirty and triggered an update of the active stylesheets - // from here. -} - void StyleEngine::SetHttpDefaultStyle(const String& content) { if (!content.IsEmpty()) SetPreferredStylesheetSetNameIfNotSet(content);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index e0246d2..4c99c81 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -155,11 +155,7 @@ String PreferredStylesheetSetName() const { return preferred_stylesheet_set_name_; } - String SelectedStylesheetSetName() const { - return selected_stylesheet_set_name_; - } void SetPreferredStylesheetSetNameIfNotSet(const String&); - void SetSelectedStylesheetSetName(const String&); void SetHttpDefaultStyle(const String&); void AddPendingSheet(StyleEngineContext&); @@ -434,7 +430,6 @@ TreeOrderedList tree_boundary_crossing_scopes_; String preferred_stylesheet_set_name_; - String selected_stylesheet_set_name_; bool uses_rem_units_ = false; bool ignore_pending_stylesheets_ = false;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 091955aa..db31d08 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4325,20 +4325,6 @@ return *style_sheet_list_; } -String Document::preferredStylesheetSet() const { - return style_engine_->PreferredStylesheetSetName(); -} - -String Document::selectedStylesheetSet() const { - UseCounter::Count(*this, WebFeature::kDocumentGetSelectedStylesheetSet); - return style_engine_->SelectedStylesheetSetName(); -} - -void Document::setSelectedStylesheetSet(const String& a_string) { - UseCounter::Count(*this, WebFeature::kDocumentSetSelectedStylesheetSet); - GetStyleEngine().SetSelectedStylesheetSetName(a_string); -} - void Document::EvaluateMediaQueryListIfNeeded() { if (!evaluate_media_queries_on_style_recalc_) return;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index d7455a1..f17f46f 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -748,14 +748,6 @@ const LayoutPoint&, const WebMouseEvent&); - /* Newly proposed CSS3 mechanism for selecting alternate - stylesheets using the DOM. May be subject to change as - spec matures. - dwh - */ - String preferredStylesheetSet() const; - String selectedStylesheetSet() const; - void setSelectedStylesheetSet(const String&); - bool SetFocusedElement(Element*, const FocusParams&); void ClearFocusedElement(); Element* FocusedElement() const { return focused_element_.Get(); }
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index 6352393..a51ccaf 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -159,11 +159,6 @@ [SameObject, MeasureAs=DocumentAll] readonly attribute HTMLAllCollection all; - // CSS Object Model (CSSOM) - // https://drafts.csswg.org/cssom/#extensions-to-the-document-interface - attribute DOMString? selectedStylesheetSet; - [MeasureAs=DocumentGetPreferredStylesheetSet] readonly attribute DOMString? preferredStylesheetSet; - [Affects=Nothing] readonly attribute Element? scrollingElement; // Pointer Lock
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc index 0226714..94fa217 100644 --- a/third_party/blink/renderer/core/dom/document_test.cc +++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -1061,4 +1061,123 @@ EXPECT_EQ(GetDocument().ElementFromPoint(1, 12), GetDocument().body()); } +/** + * Tests for viewport-fit propagation. + */ + +class ViewportFitDocumentTest : public DocumentTest { + public: + void SetUp() override { + DocumentTest::SetUp(); + + RuntimeEnabledFeatures::SetDisplayCutoutViewportFitEnabled(true); + GetDocument().GetSettings()->SetViewportMetaEnabled(true); + } +}; + +// Test both meta and @viewport present but no viewport-fit. +TEST_F(ViewportFitDocumentTest, MetaCSSViewportButNoFit) { + SetHtmlInnerHTML( + "<style>@viewport { min-width: 100px; }</style>" + "<meta name='viewport' content='initial-scale=1'>"); + + EXPECT_EQ(ViewportDescription::ViewportFit::kAuto, + GetDocument().GetViewportDescription().GetViewportFit()); +} + +// Test @viewport present but no viewport-fit. +TEST_F(ViewportFitDocumentTest, CSSViewportButNoFit) { + SetHtmlInnerHTML("<style>@viewport { min-width: 100px; }</style>"); + + EXPECT_EQ(ViewportDescription::ViewportFit::kAuto, + GetDocument().GetViewportDescription().GetViewportFit()); +} + +// Test meta viewport present but no viewport-fit. +TEST_F(ViewportFitDocumentTest, MetaViewportButNoFit) { + SetHtmlInnerHTML("<meta name='viewport' content='initial-scale=1'>"); + + EXPECT_EQ(ViewportDescription::ViewportFit::kAuto, + GetDocument().GetViewportDescription().GetViewportFit()); +} + +// This is a test case for testing a combination of viewport-fit meta value, +// viewport CSS value and the expected outcome. +using ViewportTestCase = + std::tuple<const char*, const char*, ViewportDescription::ViewportFit>; + +class ParameterizedViewportFitDocumentTest + : public ViewportFitDocumentTest, + public testing::WithParamInterface<ViewportTestCase> { + protected: + void LoadTestHTML() { + const char* kMetaValue = std::get<0>(GetParam()); + const char* kCSSValue = std::get<1>(GetParam()); + StringBuilder html; + + if (kCSSValue) { + html.Append("<style>@viewport { viewport-fit: "); + html.Append(kCSSValue); + html.Append("; }</style>"); + } + + if (kMetaValue) { + html.Append("<meta name='viewport' content='viewport-fit="); + html.Append(kMetaValue); + html.Append("'>"); + } + + GetDocument().documentElement()->SetInnerHTMLFromString(html.ToString()); + GetDocument().View()->UpdateAllLifecyclePhases(); + } +}; + +TEST_P(ParameterizedViewportFitDocumentTest, EffectiveViewportFit) { + LoadTestHTML(); + EXPECT_EQ(std::get<2>(GetParam()), + GetDocument().GetViewportDescription().GetViewportFit()); +} + +INSTANTIATE_TEST_CASE_P( + All, + ParameterizedViewportFitDocumentTest, + testing::Values( + // Test the default case. + ViewportTestCase(nullptr, + nullptr, + ViewportDescription::ViewportFit::kAuto), + // Test the different values set through CSS. + ViewportTestCase(nullptr, + "auto", + ViewportDescription::ViewportFit::kAuto), + ViewportTestCase(nullptr, + "contain", + ViewportDescription::ViewportFit::kContain), + ViewportTestCase(nullptr, + "cover", + ViewportDescription::ViewportFit::kCover), + ViewportTestCase(nullptr, + "invalid", + ViewportDescription::ViewportFit::kAuto), + // Test the different values set through the meta tag. + ViewportTestCase("auto", + nullptr, + ViewportDescription::ViewportFit::kAuto), + ViewportTestCase("contain", + nullptr, + ViewportDescription::ViewportFit::kContain), + ViewportTestCase("cover", + nullptr, + ViewportDescription::ViewportFit::kCover), + ViewportTestCase("invalid", + nullptr, + ViewportDescription::ViewportFit::kAuto), + // Test that the CSS should override the meta tag. + ViewportTestCase("cover", + "auto", + ViewportDescription::ViewportFit::kAuto), + ViewportTestCase("cover", + "contain", + ViewportDescription::ViewportFit::kContain))); + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/viewport_description.h b/third_party/blink/renderer/core/dom/viewport_description.h index 44b0281..5dacc0f 100644 --- a/third_party/blink/renderer/core/dom/viewport_description.h +++ b/third_party/blink/renderer/core/dom/viewport_description.h
@@ -29,6 +29,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_VIEWPORT_DESCRIPTION_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_VIEWPORT_DESCRIPTION_H_ +#include "base/optional.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/page_scale_constraints.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" @@ -132,7 +133,10 @@ bool max_zoom_is_explicit; bool user_zoom_is_explicit; - ViewportFit viewport_fit = ViewportFit::kAuto; + ViewportFit GetViewportFit() const { + return viewport_fit_.value_or(ViewportFit::kAuto); + } + void SetViewportFit(ViewportFit value) { viewport_fit_ = value; } bool operator==(const ViewportDescription& other) const { // Used for figuring out whether to reset the viewport or not, @@ -148,7 +152,7 @@ min_zoom_is_explicit == other.min_zoom_is_explicit && max_zoom_is_explicit == other.max_zoom_is_explicit && user_zoom_is_explicit == other.user_zoom_is_explicit && - viewport_fit == other.viewport_fit; + viewport_fit_ == other.viewport_fit_; } bool operator!=(const ViewportDescription& other) const { @@ -172,6 +176,8 @@ static float ResolveViewportLength(const Length&, const FloatSize& initial_viewport_size, Direction); + + base::Optional<ViewportFit> viewport_fit_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 41407a51b..a296689 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -50,7 +50,6 @@ #include "third_party/blink/public/platform/web_coalesced_input_event.h" #include "third_party/blink/public/platform/web_float_rect.h" #include "third_party/blink/public/platform/web_keyboard_event.h" -#include "third_party/blink/public/platform/web_mock_clipboard.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/public/platform/web_url.h" @@ -11232,57 +11231,6 @@ helper.Reset(); } -TEST_P(ParameterizedWebFrameTest, CopyImageAt) { - std::string url = base_url_ + "canvas-copy-image.html"; - RegisterMockedURLLoadFromBase(base_url_, "canvas-copy-image.html"); - - FrameTestHelpers::WebViewHelper helper; - WebViewImpl* web_view = helper.InitializeAndLoad(url); - web_view->Resize(WebSize(400, 400)); - - uint64_t sequence = Platform::Current()->Clipboard()->SequenceNumber( - mojom::ClipboardBuffer::kStandard); - - WebLocalFrame* local_frame = web_view->MainFrameImpl(); - local_frame->CopyImageAt(WebPoint(50, 50)); - - EXPECT_NE(sequence, Platform::Current()->Clipboard()->SequenceNumber( - mojom::ClipboardBuffer::kStandard)); - - WebImage image = - static_cast<WebMockClipboard*>(Platform::Current()->Clipboard()) - ->ReadRawImage(mojom::ClipboardBuffer::kStandard); - - EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.GetSkBitmap().getColor(0, 0)); -} - -TEST_P(ParameterizedWebFrameTest, CopyImageAtWithPinchZoom) { - std::string url = base_url_ + "canvas-copy-image.html"; - RegisterMockedURLLoadFromBase(base_url_, "canvas-copy-image.html"); - - FrameTestHelpers::WebViewHelper helper; - WebViewImpl* web_view = helper.InitializeAndLoad(url); - web_view->Resize(WebSize(400, 400)); - web_view->UpdateAllLifecyclePhases(); - web_view->SetPageScaleFactor(2); - web_view->SetVisualViewportOffset(WebFloatPoint(200, 200)); - - uint64_t sequence = Platform::Current()->Clipboard()->SequenceNumber( - mojom::ClipboardBuffer::kStandard); - - WebLocalFrame* local_frame = web_view->MainFrameImpl(); - local_frame->CopyImageAt(WebPoint(0, 0)); - - EXPECT_NE(sequence, Platform::Current()->Clipboard()->SequenceNumber( - mojom::ClipboardBuffer::kStandard)); - - WebImage image = - static_cast<WebMockClipboard*>(Platform::Current()->Clipboard()) - ->ReadRawImage(mojom::ClipboardBuffer::kStandard); - - EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.GetSkBitmap().getColor(0, 0)); -} - TEST_P(ParameterizedWebFrameTest, CopyImageWithImageMap) { SaveImageFromDataURLWebFrameClient client;
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc index 440fe27..08e8de5 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -247,13 +247,16 @@ } WebString ReadClipboard() { + // Run all tasks in a message loop to allow asynchronous clipboard writing + // to happen before reading from it synchronously. + test::RunPendingTasks(); return Platform::Current()->Clipboard()->ReadPlainText( mojom::ClipboardBuffer::kStandard); } void ClearClipboardBuffer() { - Platform::Current()->Clipboard()->WritePlainText(WebString()); - EXPECT_EQ(WebString(), ReadClipboard()); + Platform::Current()->Clipboard()->WritePlainText(WebString("")); + EXPECT_EQ(WebString(""), ReadClipboard()); } void CreateAndHandleKeyboardEvent(WebElement* plugin_container_one_element,
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 3b8e633..afc8278e 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -50,7 +50,6 @@ #include "third_party/blink/public/platform/web_input_event.h" #include "third_party/blink/public/platform/web_keyboard_event.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" -#include "third_party/blink/public/platform/web_mock_clipboard.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 66b7e9b..025d199c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2767,7 +2767,7 @@ else contents_size = ContentsSize(); - IntSize visible_content_size = VisibleContentRect().Size(); + IntSize visible_content_size = VisibleContentSize(); if (contents_size.Height() <= visible_content_size.Height() && contents_size.Width() <= visible_content_size.Width()) return kNotScrollableNoOverflow; @@ -4459,7 +4459,7 @@ // If no scrollbars are present, the content may still be scrollable. if (!scrollbar) { - IntSize scroll_size = ContentsSize() - VisibleContentRect().Size(); + IntSize scroll_size = ContentsSize() - VisibleContentSize(); scroll_size.ClampNegativeToZero(); return orientation == kHorizontalScrollbar ? scroll_size.Width() : scroll_size.Height(); @@ -4585,7 +4585,7 @@ if (HasOverlayScrollbars()) return; - IntSize full_visible_size = VisibleContentRect(kIncludeScrollbars).Size(); + IntSize full_visible_size = VisibleContentSize(kIncludeScrollbars); bool attempt_to_remove_scrollbars = (option == kFirstPass && doc_size.Width() <= full_visible_size.Width() &&
diff --git a/third_party/blink/renderer/core/frame/use_counter.cc b/third_party/blink/renderer/core/frame/use_counter.cc index f52f81f..27709ed 100644 --- a/third_party/blink/renderer/core/frame/use_counter.cc +++ b/third_party/blink/renderer/core/frame/use_counter.cc
@@ -1136,6 +1136,8 @@ return 591; case CSSPropertyGap: return 592; + case CSSPropertyViewportFit: + return 593; // 1. Add new features above this line (don't change the assigned numbers of // the existing items). // 2. Update kMaximumCSSSampleId (defined in
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc index 6dfa9b9a..f8d660b 100644 --- a/third_party/blink/renderer/core/html/html_meta_element.cc +++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -368,8 +368,8 @@ } else if (key_string == "viewport-fit") { if (RuntimeEnabledFeatures::DisplayCutoutViewportFitEnabled()) { bool unknown_value = false; - description->viewport_fit = - ParseViewportFitValueAsEnum(unknown_value, value_string); + description->SetViewportFit( + ParseViewportFitValueAsEnum(unknown_value, value_string)); // If we got an unknown value then report a warning. if (unknown_value) { @@ -451,6 +451,7 @@ description.min_zoom = std::min(description.min_zoom, float(5)); } } + void HTMLMetaElement::ProcessViewportContentAttribute( const String& content, ViewportDescription::Type origin) {
diff --git a/third_party/blink/renderer/core/html/html_meta_element_test.cc b/third_party/blink/renderer/core/html/html_meta_element_test.cc index 7f14a0a..bca197d 100644 --- a/third_party/blink/renderer/core/html/html_meta_element_test.cc +++ b/third_party/blink/renderer/core/html/html_meta_element_test.cc
@@ -24,7 +24,7 @@ ViewportDescription::ViewportFit LoadTestPageAndReturnViewportFit( const String& value) { LoadTestPageWithViewportFitValue(value); - return GetDocument().GetViewportDescription().viewport_fit; + return GetDocument().GetViewportDescription().GetViewportFit(); } private:
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn index 93f5ae5..8cc67ac 100644 --- a/third_party/blink/renderer/core/layout/BUILD.gn +++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -282,6 +282,8 @@ "multi_column_fragmentainer_group.h", "ng/exclusions/ng_exclusion_space.cc", "ng/exclusions/ng_exclusion_space.h", + "ng/exclusions/ng_layout_opportunity.h", + "ng/exclusions/ng_line_layout_opportunity.h", "ng/geometry/ng_bfc_offset.cc", "ng/geometry/ng_bfc_offset.h", "ng/geometry/ng_bfc_rect.cc", @@ -290,7 +292,6 @@ "ng/geometry/ng_border_edges.h", "ng/geometry/ng_box_strut.cc", "ng/geometry/ng_box_strut.h", - "ng/geometry/ng_edge.h", "ng/geometry/ng_logical_offset.cc", "ng/geometry/ng_logical_offset.h", "ng/geometry/ng_logical_rect.cc",
diff --git a/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h b/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h index 0b50205..b948bc2 100644 --- a/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h +++ b/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
@@ -1491,7 +1491,11 @@ bool check_for_break = auto_wrap_; if (width_.CommittedWidth() && !width_.FitsOnLine() && line_break_.GetLineLayoutItem() && curr_ws_ == EWhiteSpace::kNowrap) { - if (width_.FitsOnLine(0, kExcludeWhitespace)) { + // If this nowrap item fits but its trailing spaces does not, and if the + // next item is auto-wrap, break before the next item. + // TODO(kojii): This case should be handled when we read next item. + if (width_.FitsOnLine(0, kExcludeWhitespace) && + (!next_object_ || next_object_.StyleRef().AutoWrap())) { width_.Commit(); line_break_.MoveToStartOf(next_object_); }
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h index 87e23b39..7516573 100644 --- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
@@ -10,6 +10,11 @@ namespace blink { +// This struct represents an 2D-area where a NGFragment can fit within the +// exclusion space. A layout opportunity is produced by the exclusion space by +// calling FindLayoutOpportunity, or AllLayoutOpportunities. +// +// Its coordinates are relative to the BFC. struct CORE_EXPORT NGLayoutOpportunity { NGLayoutOpportunity() : rect(NGBfcOffset(LayoutUnit::Min(), LayoutUnit::Min()),
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h new file mode 100644 index 0000000..ee9f8b1 --- /dev/null +++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h
@@ -0,0 +1,66 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_EXCLUSIONS_NG_LINE_LAYOUT_OPPORTUNITY_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_EXCLUSIONS_NG_LINE_LAYOUT_OPPORTUNITY_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/layout_unit.h" +#include "third_party/blink/renderer/platform/wtf/allocator.h" + +namespace blink { + +// This struct represents a 1D-area where a line can fit. It is only used for +// representing the inline size. +struct CORE_EXPORT NGLineLayoutOpportunity { + STACK_ALLOCATED(); + + NGLineLayoutOpportunity() {} + NGLineLayoutOpportunity(LayoutUnit inline_size) + : line_right_offset(inline_size), float_line_right_offset(inline_size) {} + NGLineLayoutOpportunity(LayoutUnit line_left_offset, + LayoutUnit line_right_offset, + LayoutUnit float_line_left_offset, + LayoutUnit float_line_right_offset, + LayoutUnit bfc_block_offset, + LayoutUnit line_block_size) + : line_left_offset(line_left_offset), + line_right_offset(line_right_offset), + float_line_left_offset(float_line_left_offset), + float_line_right_offset(float_line_right_offset), + bfc_block_offset(bfc_block_offset), + line_block_size(line_block_size) {} + + // The available inline-size of the line, taking shapes into account. Both + // offsets are relative to the BFC coordinate system. + LayoutUnit line_left_offset; + LayoutUnit line_right_offset; + + // The available inline-size of the line *for floats*. This is the same size + // as the layout opportunity which generated this object. Both offsets are + // relative to the BFC coordinate system. + LayoutUnit float_line_left_offset; + LayoutUnit float_line_right_offset; + + LayoutUnit bfc_block_offset; + + // The block-size this line layout opportunity was created with. Should + // *only* be used for re-querying for a new line layout opportunity with the + // same block-size. + LayoutUnit line_block_size; + + LayoutUnit AvailableInlineSize() const { + DCHECK_GE(line_right_offset, line_left_offset); + return line_right_offset - line_left_offset; + } + + LayoutUnit AvailableFloatInlineSize() const { + DCHECK_GE(float_line_right_offset, float_line_left_offset); + return float_line_right_offset - float_line_left_offset; + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_EXCLUSIONS_NG_LINE_LAYOUT_OPPORTUNITY_H_
diff --git a/third_party/blink/renderer/core/layout/ng/geometry/ng_edge.h b/third_party/blink/renderer/core/layout/ng/geometry/ng_edge.h deleted file mode 100644 index e68fec2..0000000 --- a/third_party/blink/renderer/core/layout/ng/geometry/ng_edge.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NGEdge_h -#define NGEdge_h - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/layout_unit.h" - -namespace blink { - -// Struct to represent a simple edge that has start and end. -struct CORE_EXPORT NGEdge { - LayoutUnit start; - LayoutUnit end; -}; - -} // namespace blink - -#endif // NGEdge_h
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index f2c0b8c..9e9bc4a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -618,6 +618,11 @@ exclusion_space = std::make_unique<NGExclusionSpace>(*initial_exclusion_space); + NGLineLayoutOpportunity line_opportunity( + opportunity.rect.LineStartOffset(), opportunity.rect.LineEndOffset(), + opportunity.rect.LineStartOffset(), opportunity.rect.LineEndOffset(), + opportunity.rect.BlockStartOffset(), LayoutUnit()); + NGLineInfo line_info; NGLineBreaker line_breaker( Node(), NGLineBreakerMode::kContent, constraint_space_, @@ -626,14 +631,14 @@ // TODO(ikilpatrick): Does this always succeed when we aren't an empty // inline? - if (!line_breaker.NextLine(opportunity, &line_info)) + if (!line_breaker.NextLine(line_opportunity, &line_info)) break; // If this fragment will be larger than the inline-size of the opportunity, // *and* the opportunity is smaller than the available inline-size, and the // container autowraps, continue to the next opportunity. - if (line_info.Width() > opportunity.rect.InlineSize() && - opportunity.rect.InlineSize() != + if (line_info.Width() > line_opportunity.AvailableInlineSize() && + line_opportunity.AvailableInlineSize() != ConstraintSpace().AvailableSize().inline_size && Node().Style().AutoWrap()) continue;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index fe87e49f..595d60c 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -596,8 +596,7 @@ scoped_refptr<NGInlineBreakToken> break_token; NGLineInfo line_info; NGExclusionSpace empty_exclusion_space; - NGLayoutOpportunity opportunity(NGBfcRect( - NGBfcOffset(), NGBfcOffset(available_inline_size, LayoutUnit::Max()))); + NGLineLayoutOpportunity line_opportunity(available_inline_size); LayoutUnit result; LayoutUnit previous_floats_inline_size = input.float_left_inline_size + input.float_right_inline_size; @@ -608,7 +607,7 @@ &unpositioned_floats, nullptr /* container_builder */, &empty_exclusion_space, 0u, break_token.get()); - if (!line_breaker.NextLine(opportunity, &line_info)) + if (!line_breaker.NextLine(line_opportunity, &line_info)) break; break_token = line_breaker.CreateBreakToken(line_info, nullptr);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc index 76fa8e0..e659d97 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -153,8 +153,9 @@ } // Initialize internal states for the next line. -void NGLineBreaker::PrepareNextLine(const NGLayoutOpportunity& opportunity, - NGLineInfo* line_info) { +void NGLineBreaker::PrepareNextLine( + const NGLineLayoutOpportunity& line_opportunity, + NGLineInfo* line_info) { NGInlineItemResults* item_results = &line_info->Results(); item_results->clear(); line_info->SetStartOffset(offset_); @@ -177,17 +178,12 @@ // regardless of 'text-indent'. line_.position = line_info->TextIndent(); - line_.opportunity = opportunity; - line_.line_left_bfc_offset = opportunity.rect.LineStartOffset(); - line_.line_right_bfc_offset = opportunity.rect.LineEndOffset(); - bfc_block_offset_ = opportunity.rect.BlockStartOffset(); + line_.line_opportunity = line_opportunity; } -bool NGLineBreaker::NextLine(const NGLayoutOpportunity& opportunity, +bool NGLineBreaker::NextLine(const NGLineLayoutOpportunity& line_opportunity, NGLineInfo* line_info) { - bfc_block_offset_ = constraint_space_.BfcOffset().block_offset; - - PrepareNextLine(opportunity, line_info); + PrepareNextLine(line_opportunity, line_info); BreakLine(line_info); if (line_info->Results().IsEmpty()) @@ -294,14 +290,14 @@ } void NGLineBreaker::ComputeLineLocation(NGLineInfo* line_info) const { - LayoutUnit bfc_line_offset = line_.line_left_bfc_offset; + LayoutUnit bfc_line_offset = line_.line_opportunity.line_left_offset; LayoutUnit available_width = line_.AvailableWidth(); // Negative margins can make the position negative, but the inline size is // always positive or 0. - line_info->SetLineBfcOffset({bfc_line_offset, bfc_block_offset_}, - available_width, - line_.position.ClampNegativeToZero()); + line_info->SetLineBfcOffset( + {bfc_line_offset, line_.line_opportunity.bfc_block_offset}, + available_width, line_.position.ClampNegativeToZero()); } NGLineBreaker::LineBreakState NGLineBreaker::HandleText( @@ -397,7 +393,7 @@ // * If offset == item.EndOffset(): the break opportunity at the end fits, // or the first break opportunity is beyond the end. // There may be room for more characters. - // * If width > available_width: The first break opporunity does not fit. + // * If width > available_width: The first break opportunity does not fit. // offset is the first break opportunity, either inside, at the end, or // beyond the end. if (item_result->end_offset < item.EndOffset()) { @@ -643,8 +639,6 @@ // We have this check if there are already UnpositionedFloats as we aren't // allowed to position a float "above" another float which has come before us // in the document. -// -// TODO(glebl): Add the support of clearance for inline floats. void NGLineBreaker::HandleFloat(const NGInlineItem& item, NGLineInfo* line_info, NGInlineItemResult* item_result) { @@ -691,6 +685,8 @@ margins.InlineSum()) .ClampNegativeToZero(); + LayoutUnit bfc_block_offset = line_.line_opportunity.bfc_block_offset; + // The float should be positioned after the current line if: // - It can't fit. // - It will be moved down due to block-start edge alignment. @@ -700,9 +696,9 @@ // the line breaker has run). bool float_after_line = !line_.CanFit(inline_margin_size) || - exclusion_space_->LastFloatBlockStart() > bfc_block_offset_ || + exclusion_space_->LastFloatBlockStart() > bfc_block_offset || exclusion_space_->ClearanceOffset(float_style.Clear()) > - bfc_block_offset_ || + bfc_block_offset || mode_ != NGLineBreakerMode::kContent; // Check if we already have a pending float. That's because a float cannot be @@ -711,30 +707,26 @@ AddUnpositionedFloat(unpositioned_floats_, container_builder_, std::move(unpositioned_float)); } else { - LayoutUnit origin_block_offset = bfc_block_offset_; - NGPositionedFloat positioned_float = PositionFloat( - origin_block_offset, constraint_space_.BfcOffset().block_offset, + bfc_block_offset, constraint_space_.BfcOffset().block_offset, unpositioned_float.get(), constraint_space_, exclusion_space_); positioned_floats_->push_back(positioned_float); DCHECK_EQ(positioned_float.bfc_offset.block_offset, - bfc_block_offset_ + margins.block_start); + bfc_block_offset + margins.block_start); if (float_style.Floating() == EFloat::kLeft) { - line_.line_left_bfc_offset = std::max( - line_.line_left_bfc_offset, + line_.line_opportunity.line_left_offset = std::max( + line_.line_opportunity.line_left_offset, positioned_float.bfc_offset.line_offset + inline_margin_size - margins.LineLeft(TextDirection::kLtr)); } else { - line_.line_right_bfc_offset = - std::min(line_.line_right_bfc_offset, + line_.line_opportunity.line_right_offset = + std::min(line_.line_opportunity.line_right_offset, positioned_float.bfc_offset.line_offset - margins.LineLeft(TextDirection::kLtr)); } - DCHECK_GE(line_.line_left_bfc_offset, LayoutUnit()); - DCHECK_GE(line_.line_right_bfc_offset, LayoutUnit()); DCHECK_GE(line_.AvailableWidth(), LayoutUnit()); } } @@ -930,7 +922,7 @@ } // Let this line overflow. - // If there was a break opporunity, the overflow should stop there. + // If there was a break opportunity, the overflow should stop there. if (break_before) { Rewind(line_info, break_before); return LineBreakState::kTrailing;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h index 01ff0d8..f9a4be8 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -6,7 +6,7 @@ #define NGLineBreaker_h #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h" +#include "third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" #include "third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.h" @@ -47,7 +47,7 @@ // Compute the next line break point and produces NGInlineItemResults for // the line. - bool NextLine(const NGLayoutOpportunity&, NGLineInfo*); + bool NextLine(const NGLineLayoutOpportunity& line_opportunity, NGLineInfo*); // Create an NGInlineBreakToken for the last line returned by NextLine(). scoped_refptr<NGInlineBreakToken> CreateBreakToken( @@ -71,11 +71,7 @@ // that computes position in visual order, this position in logical order. LayoutUnit position; - // The current opportunity. - NGLayoutOpportunity opportunity; - - LayoutUnit line_left_bfc_offset; - LayoutUnit line_right_bfc_offset; + NGLineLayoutOpportunity line_opportunity; // True if this line is the "first formatted line". // https://www.w3.org/TR/CSS22/selector.html#first-formatted-line @@ -95,8 +91,7 @@ bool is_after_forced_break = false; LayoutUnit AvailableWidth() const { - DCHECK_GE(line_right_bfc_offset, line_left_bfc_offset); - return line_right_bfc_offset - line_left_bfc_offset; + return line_opportunity.AvailableInlineSize(); } bool CanFit() const { return position <= AvailableWidth(); } bool CanFit(LayoutUnit extra) const { @@ -116,7 +111,7 @@ void BreakLine(NGLineInfo*); - void PrepareNextLine(const NGLayoutOpportunity&, NGLineInfo*); + void PrepareNextLine(const NGLineLayoutOpportunity&, NGLineInfo*); void UpdatePosition(const NGInlineItemResults&); void ComputeLineLocation(NGLineInfo*) const; @@ -187,8 +182,6 @@ HarfBuzzShaper shaper_; ShapeResultSpacing<String> spacing_; bool previous_line_had_forced_break_ = false; - LayoutUnit bfc_line_offset_; - LayoutUnit bfc_block_offset_; const Hyphenation* hyphenation_ = nullptr; // Keep track of handled float items. See HandleFloat().
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc index 34e1835..f67054c 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -46,16 +46,14 @@ Vector<NGInlineItemResults> lines; NGExclusionSpace exclusion_space; - NGLayoutOpportunity opportunity; - opportunity.rect = - NGBfcRect(NGBfcOffset(), {available_width, LayoutUnit::Max()}); + NGLineLayoutOpportunity line_opportunity(available_width); NGLineInfo line_info; while (!break_token || !break_token->IsFinished()) { NGLineBreaker line_breaker(node, NGLineBreakerMode::kContent, *space, &positioned_floats, &unpositioned_floats, /* container_builder */ nullptr, &exclusion_space, 0u, break_token.get()); - if (!line_breaker.NextLine(opportunity, &line_info)) + if (!line_breaker.NextLine(line_opportunity, &line_info)) break; break_token = line_breaker.CreateBreakToken(line_info, nullptr);
diff --git a/third_party/blink/renderer/core/layout/shapes/box_shape_test.cc b/third_party/blink/renderer/core/layout/shapes/box_shape_test.cc index dffb0d1..371d08e 100644 --- a/third_party/blink/renderer/core/layout/shapes/box_shape_test.cc +++ b/third_party/blink/renderer/core/layout/shapes/box_shape_test.cc
@@ -143,7 +143,7 @@ TEST_EXCLUDED_INTERVAL(shape, LayoutUnit(15), LayoutUnit(6), 0, 100); TEST_EXCLUDED_INTERVAL(shape, LayoutUnit(20), LayoutUnit(50), 0, 100); TEST_EXCLUDED_INTERVAL(shape, LayoutUnit(69), LayoutUnit(5), 0, 100); - TEST_EXCLUDED_INTERVAL(shape, LayoutUnit(85), LayoutUnit(10), 0, 97.320511f); + TEST_EXCLUDED_INTERVAL(shape, LayoutUnit(85), LayoutUnit(10), 0, 97.3125f); } } // anonymous namespace
diff --git a/third_party/blink/renderer/core/layout/shapes/shape.h b/third_party/blink/renderer/core/layout/shapes/shape.h index 778a89ee..b940726 100644 --- a/third_party/blink/renderer/core/layout/shapes/shape.h +++ b/third_party/blink/renderer/core/layout/shapes/shape.h
@@ -51,8 +51,8 @@ logical_right(logical_right), is_valid(true) {} - float logical_left; - float logical_right; + LayoutUnit logical_left; + LayoutUnit logical_right; bool is_valid; };
diff --git a/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc b/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc index 1997812..5ee3148 100644 --- a/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc +++ b/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
@@ -371,8 +371,8 @@ containing_block.Style()->IsLeftToRightDirection() ? containing_block.MarginStartForChild(layout_box_) : containing_block.MarginEndForChild(layout_box_); - LayoutUnit raw_left_margin_box_delta( - segment.logical_left + LogicalLeftOffset() + logical_left_margin); + LayoutUnit raw_left_margin_box_delta = + segment.logical_left + LogicalLeftOffset() + logical_left_margin; LayoutUnit left_margin_box_delta = clampTo<LayoutUnit>( raw_left_margin_box_delta, LayoutUnit(), float_margin_box_width); @@ -380,10 +380,10 @@ containing_block.Style()->IsLeftToRightDirection() ? containing_block.MarginEndForChild(layout_box_) : containing_block.MarginStartForChild(layout_box_); - LayoutUnit raw_right_margin_box_delta( + LayoutUnit raw_right_margin_box_delta = segment.logical_right + LogicalLeftOffset() - containing_block.LogicalWidthForChild(layout_box_) - - logical_right_margin); + logical_right_margin; LayoutUnit right_margin_box_delta = clampTo<LayoutUnit>( raw_right_margin_box_delta, -float_margin_box_width, LayoutUnit());
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 3534d56..3035a74 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -54,8 +54,6 @@ #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_host.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" -#include "third_party/blink/renderer/platform/exported/web_scrollbar_impl.h" -#include "third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h" #include "third_party/blink/renderer/platform/geometry/region.h" #include "third_party/blink/renderer/platform/geometry/transform_state.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -69,8 +67,6 @@ #include "third_party/blink/public/platform/web_compositor_support.h" #include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_geometry.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_painter.h" #include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h" #include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h" @@ -329,10 +325,8 @@ static std::unique_ptr<ScrollingCoordinator::ScrollbarLayerGroup> CreateScrollbarLayer(Scrollbar& scrollbar, float device_scale_factor) { ScrollbarTheme& theme = scrollbar.GetTheme(); - auto scrollbar_delegate = std::make_unique<ScrollbarLayerDelegate>( - WebScrollbarImpl::Create(&scrollbar), - WebScrollbarThemePainter(theme, scrollbar, device_scale_factor), - WebScrollbarThemeGeometryNative::Create(theme)); + auto scrollbar_delegate = + std::make_unique<ScrollbarLayerDelegate>(scrollbar, device_scale_factor); auto layer_group = std::make_unique<ScrollingCoordinator::ScrollbarLayerGroup>();
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 724d23f..e5298a4 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1777,7 +1777,7 @@ FloatSize background_size = relative_compositing_bounds_size; if (BackgroundLayerPaintsFixedRootBackground()) { LocalFrameView* frame_view = ToLayoutView(GetLayoutObject()).GetFrameView(); - background_size = FloatSize(frame_view->VisibleContentRect().Size()); + background_size = FloatSize(frame_view->VisibleContentSize()); } background_layer_->SetPosition(FloatPoint()); if (background_size != background_layer_->Size()) {
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc index b4b2944..bc01240 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h" -#include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/css_property_names.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -178,14 +177,6 @@ if (RequiresCompositingForScrollDependentPosition(layer, ignore_lcd_text)) direct_reasons |= CompositingReason::kScrollDependentPosition; - // TODO(crbug.com/839341): Remove once we support main-thread AnimationWorklet - // and don't need to promote the scroll-source. - if (layer->GetScrollableArea() && layer->GetLayoutObject().GetNode() && - ScrollTimeline::HasActiveScrollTimeline( - layer->GetLayoutObject().GetNode())) { - direct_reasons |= CompositingReason::kScrollTimelineTarget; - } - direct_reasons |= layout_object.AdditionalCompositingReasons(); DCHECK(
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc index 6bf0c566..45c2de470 100644 --- a/third_party/blink/renderer/core/paint/frame_painter.cc +++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -40,8 +40,8 @@ IntRect document_dirty_rect; IntPoint frame_view_location(GetFrameView().Location()); - IntRect visible_area_without_scrollbars( - frame_view_location, GetFrameView().VisibleContentRect().Size()); + IntRect visible_area_without_scrollbars(frame_view_location, + GetFrameView().VisibleContentSize()); IntPoint content_offset = -frame_view_location + GetFrameView().ScrollOffsetInt(); if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() && @@ -95,7 +95,7 @@ IntRect scroll_view_dirty_rect = rect.rect_; IntRect visible_area_with_scrollbars( frame_view_location, - GetFrameView().VisibleContentRect(kIncludeScrollbars).Size()); + GetFrameView().VisibleContentSize(kIncludeScrollbars)); scroll_view_dirty_rect.Intersect(visible_area_with_scrollbars); scroll_view_dirty_rect.MoveBy(-frame_view_location);
diff --git a/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc b/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc index 182e06c6..b964d3eb 100644 --- a/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc +++ b/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/core/xlink_names.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -71,6 +72,9 @@ Pasteboard* pasteboard = Pasteboard::GeneralPasteboard(); pasteboard->WriteHTML(html_to_paste, BlankURL(), "", Pasteboard::kCannotSmartReplace); + // Run all tasks in a message loop to allow asynchronous clipboard writing + // to happen before reading from it synchronously. + test::RunPendingTasks(); EXPECT_TRUE(frame.GetEditor().ExecuteCommand("Paste")); return body->InnerHTMLAsString();
diff --git a/third_party/blink/renderer/core/testing/data/canvas-copy-image.html b/third_party/blink/renderer/core/testing/data/canvas-copy-image.html deleted file mode 100644 index 875ea4d..0000000 --- a/third_party/blink/renderer/core/testing/data/canvas-copy-image.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<canvas style="position:absolute; top:40px; left:40px" width="200" height="200"></canvas> -<script> -var canvas = document.querySelector("canvas"); -var context = canvas.getContext("2d"); -context.fillStyle = "red"; -context.fillRect(0, 0, 200, 200); -</script> -</body> -</html>
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc index b9cc84c..b586099b 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -172,6 +172,27 @@ context_proxy_->TerminateGlobalScope(); } +BeginFrameProviderParams DedicatedWorker::CreateBeginFrameProviderParams() { + DCHECK(GetExecutionContext()->IsContextThread()); + // If we don't have a frame or we are not in Document, some of the SinkIds + // won't be initialized. If that's the case, the Worker will initialize it by + // itself later. + BeginFrameProviderParams begin_frame_provider_params; + if (GetExecutionContext()->IsDocument()) { + LocalFrame* frame = ToDocument(GetExecutionContext())->GetFrame(); + WebLayerTreeView* layer_tree_view = nullptr; + if (frame) { + layer_tree_view = + frame->GetPage()->GetChromeClient().GetWebLayerTreeView(frame); + begin_frame_provider_params.parent_frame_sink_id = + layer_tree_view->GetFrameSinkId(); + } + begin_frame_provider_params.frame_sink_id = + Platform::Current()->GenerateFrameSinkId(); + } + return begin_frame_provider_params; +} + void DedicatedWorker::ContextDestroyed(ExecutionContext*) { DCHECK(GetExecutionContext()->IsContextThread()); if (classic_script_loader_) @@ -260,23 +281,6 @@ settings = WorkerSettings::Copy(worker_global_scope->GetWorkerSettings()); } - BeginFrameProviderParams begin_frame_provider_params; - if (GetExecutionContext()->IsDocument()) { - LocalFrame* frame = ToDocument(GetExecutionContext())->GetFrame(); - WebLayerTreeView* layer_tree_view = nullptr; - // TODO(fserb): what to do when there's no frame? - if (frame) { - layer_tree_view = - frame->GetPage()->GetChromeClient().GetWebLayerTreeView(frame); - begin_frame_provider_params.parent_frame_sink_id = - layer_tree_view->GetFrameSinkId(); - } - begin_frame_provider_params.frame_sink_id = - Platform::Current()->GenerateFrameSinkId(); - } else if (GetExecutionContext()->IsWorkerGlobalScope()) { - // TODO(fserb): copies parent/frame sink_id into new worker or reset it. - } - ScriptType script_type = (options_.type() == "classic") ? ScriptType::kClassic : ScriptType::kModule; return std::make_unique<GlobalScopeCreationParams>( @@ -290,7 +294,7 @@ module_fetch_coordinator_.Get(), ConnectToWorkerInterfaceProvider(GetExecutionContext(), SecurityOrigin::Create(script_url_)), - std::move(begin_frame_provider_params)); + CreateBeginFrameProviderParams()); } const AtomicString& DedicatedWorker::InterfaceName() const {
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.h b/third_party/blink/renderer/core/workers/dedicated_worker.h index 4515550..a35fb9f 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/core/workers/abstract_worker.h" #include "third_party/blink/renderer/core/workers/worker_options.h" +#include "third_party/blink/renderer/platform/graphics/begin_frame_provider.h" #include "third_party/blink/renderer/platform/wtf/forward.h" namespace v8_inspector { @@ -59,6 +60,7 @@ ExceptionState&); static bool CanTransferArrayBuffersAndImageBitmaps() { return true; } void terminate(); + BeginFrameProviderParams CreateBeginFrameProviderParams(); // Implements ContextLifecycleObserver (via AbstractWorker). void ContextDestroyed(ExecutionContext*) override;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h index 329361a3..03ae8ff7 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -70,10 +70,15 @@ void Trace(blink::Visitor*) override; - private: DedicatedWorkerObjectProxy& WorkerObjectProxy() const; }; +DEFINE_TYPE_CASTS(DedicatedWorkerGlobalScope, + ExecutionContext, + context, + context->IsDedicatedWorkerGlobalScope(), + context.IsDedicatedWorkerGlobalScope()); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_DEDICATED_WORKER_GLOBAL_SCOPE_H_
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index 600c54e7..e372b78 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -596,8 +596,6 @@ ResourceLoaderOptions options; options.initiator_info.name = FetchInitiatorTypeNames::xml; FetchParameters params(ResourceRequest(url), options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); Resource* resource = RawResource::FetchSynchronously(params, document->Fetcher()); if (!resource->ErrorOccurred()) {
diff --git a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc index 1605256..cdbc4f8 100644 --- a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc +++ b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
@@ -109,8 +109,6 @@ fetch_options.initiator_info.name = FetchInitiatorTypeNames::xml; FetchParameters params(ResourceRequest(url), fetch_options); params.SetOriginRestriction(FetchParameters::kRestrictToSameOrigin); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); Resource* resource = RawResource::FetchSynchronously(params, g_global_resource_fetcher); if (!g_global_processor)
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index 3a81289..28e2bee 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -231,9 +231,6 @@ AnimationEffect* target_effect = effects_.at(0); target_effect->Attach(this); - - if (timeline_.IsScrollTimeline()) - timeline.GetAsScrollTimeline()->AttachAnimation(); } String WorkletAnimation::playState() { @@ -434,8 +431,6 @@ void WorkletAnimation::Dispose() { DCHECK(IsMainThread()); - if (timeline_.IsScrollTimeline()) - timeline_.GetAsScrollTimeline()->DetachAnimation(); DestroyCompositorAnimation(); }
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 8c6bc64e..9bea4bf 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -570,7 +570,6 @@ "exported/web_media_stream_track.cc", "exported/web_memory_coordinator.cc", "exported/web_mixed_content.cc", - "exported/web_mock_clipboard.cc", "exported/web_network_state_notifier.cc", "exported/web_prerender.cc", "exported/web_prerendering_support.cc", @@ -587,13 +586,6 @@ "exported/web_rtc_stats_response.cc", "exported/web_rtc_void_request.cc", "exported/web_runtime_features.cc", - "exported/web_scrollbar_impl.cc", - "exported/web_scrollbar_impl.h", - "exported/web_scrollbar_theme_client_impl.cc", - "exported/web_scrollbar_theme_client_impl.h", - "exported/web_scrollbar_theme_geometry_native.cc", - "exported/web_scrollbar_theme_geometry_native.h", - "exported/web_scrollbar_theme_painter.cc", "exported/web_security_origin.cc", "exported/web_service_worker_installed_scripts_manager.cc", "exported/web_service_worker_request.cc", @@ -1852,6 +1844,7 @@ "graphics/paint/property_tree_state_test.cc", "graphics/paint_invalidation_reason_test.cc", "graphics/placeholder_image_test.cc", + "graphics/skia/skia_utils_test.cc", "graphics/static_bitmap_image_test.cc", "graphics/video_frame_submitter_test.cc", "histogram_test.cc",
diff --git a/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc b/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc index fadda48..c335b64d 100644 --- a/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc +++ b/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc
@@ -44,8 +44,7 @@ result.text = item.string_data; } else if (item.string_type == blink::kMimeTypeTextHTML) { result.html = item.string_data; - } else if (item.string_type != blink::kMimeTypeTextURIList && - item.string_type != blink::kMimeTypeDownloadURL) { + } else if (item.string_type != blink::kMimeTypeDownloadURL) { result.custom_data.insert(item.string_type, item.string_data); } } @@ -177,7 +176,8 @@ } void WebClipboardImpl::WritePlainText(const WebString& plain_text) { - clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, plain_text); + clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, + EnsureNotNullWTFString(plain_text)); clipboard_->CommitWrite(mojom::ClipboardBuffer::kStandard); } @@ -185,9 +185,10 @@ const WebURL& source_url, const WebString& plain_text, bool write_smart_paste) { - clipboard_->WriteHtml(mojom::ClipboardBuffer::kStandard, html_text, - source_url); - clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, plain_text); + clipboard_->WriteHtml(mojom::ClipboardBuffer::kStandard, + EnsureNotNullWTFString(html_text), source_url); + clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, + EnsureNotNullWTFString(plain_text)); if (write_smart_paste) clipboard_->WriteSmartPasteMarker(mojom::ClipboardBuffer::kStandard);
diff --git a/third_party/blink/renderer/platform/exported/web_mock_clipboard.cc b/third_party/blink/renderer/platform/exported/web_mock_clipboard.cc deleted file mode 100644 index 52d2c5d..0000000 --- a/third_party/blink/renderer/platform/exported/web_mock_clipboard.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/public/platform/web_mock_clipboard.h" - -#include "third_party/blink/renderer/platform/blob/blob_data.h" - -namespace blink { - -WebBlobInfo WebMockClipboard::CreateBlobFromData(base::span<const uint8_t> data, - const WebString& mime_type) { - auto blob_data = BlobData::Create(); - blob_data->SetContentType(mime_type); - blob_data->AppendBytes(data.data(), data.size()); - auto blob_data_handle = - BlobDataHandle::Create(std::move(blob_data), data.size()); - return WebBlobInfo( - blob_data_handle->Uuid(), mime_type, data.size(), - blob_data_handle->CloneBlobPtr().PassInterface().PassHandle()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_impl.cc b/third_party/blink/renderer/platform/exported/web_scrollbar_impl.cc deleted file mode 100644 index 825beb9..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_impl.cc +++ /dev/null
@@ -1,124 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/platform/exported/web_scrollbar_impl.h" - -#include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar.h" - -namespace blink { - -WebScrollbarImpl::WebScrollbarImpl(Scrollbar* scrollbar) - : scrollbar_(scrollbar) {} - -bool WebScrollbarImpl::IsOverlay() const { - return scrollbar_->IsOverlayScrollbar(); -} - -int WebScrollbarImpl::Value() const { - return scrollbar_->Value(); -} - -WebPoint WebScrollbarImpl::Location() const { - return scrollbar_->Location(); -} - -WebSize WebScrollbarImpl::Size() const { - return scrollbar_->Size(); -} - -bool WebScrollbarImpl::Enabled() const { - return scrollbar_->Enabled(); -} - -int WebScrollbarImpl::Maximum() const { - return scrollbar_->Maximum(); -} - -int WebScrollbarImpl::TotalSize() const { - return scrollbar_->TotalSize(); -} - -bool WebScrollbarImpl::IsScrollableAreaActive() const { - return scrollbar_->IsScrollableAreaActive(); -} - -bool WebScrollbarImpl::HasTickmarks() const { - Vector<IntRect> tickmarks; - scrollbar_->GetTickmarks(tickmarks); - - return !tickmarks.IsEmpty(); -} - -void WebScrollbarImpl::GetTickmarks(WebVector<WebRect>& web_tickmarks) const { - Vector<IntRect> tickmarks; - scrollbar_->GetTickmarks(tickmarks); - - WebVector<WebRect> result(tickmarks.size()); - for (size_t i = 0; i < tickmarks.size(); ++i) - result[i] = tickmarks[i]; - - web_tickmarks.Swap(result); -} - -WebScrollbar::ScrollbarControlSize WebScrollbarImpl::GetControlSize() const { - return static_cast<WebScrollbar::ScrollbarControlSize>( - scrollbar_->GetControlSize()); -} - -WebScrollbar::ScrollbarPart WebScrollbarImpl::PressedPart() const { - return static_cast<WebScrollbar::ScrollbarPart>(scrollbar_->PressedPart()); -} - -WebScrollbar::ScrollbarPart WebScrollbarImpl::HoveredPart() const { - return static_cast<WebScrollbar::ScrollbarPart>(scrollbar_->HoveredPart()); -} - -WebScrollbarOverlayColorTheme WebScrollbarImpl::ScrollbarOverlayColorTheme() - const { - return static_cast<WebScrollbarOverlayColorTheme>( - scrollbar_->GetScrollbarOverlayColorTheme()); -} - -WebScrollbar::Orientation WebScrollbarImpl::GetOrientation() const { - return static_cast<WebScrollbar::Orientation>(scrollbar_->Orientation()); -} - -bool WebScrollbarImpl::IsLeftSideVerticalScrollbar() const { - return scrollbar_->IsLeftSideVerticalScrollbar(); -} - -bool WebScrollbarImpl::IsCustomScrollbar() const { - return scrollbar_->IsCustomScrollbar(); -} - -float WebScrollbarImpl::ElasticOverscroll() const { - return scrollbar_->ElasticOverscroll(); -} - -void WebScrollbarImpl::SetElasticOverscroll(float elastic_overscroll) { - scrollbar_->SetElasticOverscroll(elastic_overscroll); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_impl.h b/third_party/blink/renderer/platform/exported/web_scrollbar_impl.h deleted file mode 100644 index b6938a6..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_impl.h +++ /dev/null
@@ -1,82 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_IMPL_H_ - -#include "base/memory/ptr_util.h" -#include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -#include <memory> - -namespace blink { - -class Scrollbar; -class PLATFORM_EXPORT WebScrollbarImpl final : public WebScrollbar { - USING_FAST_MALLOC(WebScrollbarImpl); - WTF_MAKE_NONCOPYABLE(WebScrollbarImpl); - - public: - static std::unique_ptr<WebScrollbarImpl> Create(Scrollbar* scrollbar) { - return base::WrapUnique(new WebScrollbarImpl(scrollbar)); - } - - // Implement WebScrollbar methods - bool IsOverlay() const override; - int Value() const override; - WebPoint Location() const override; - WebSize Size() const override; - bool Enabled() const override; - int Maximum() const override; - int TotalSize() const override; - bool IsScrollableAreaActive() const override; - bool HasTickmarks() const override; - void GetTickmarks(WebVector<WebRect>& tickmarks) const override; - ScrollbarControlSize GetControlSize() const override; - ScrollbarPart PressedPart() const override; - ScrollbarPart HoveredPart() const override; - WebScrollbarOverlayColorTheme ScrollbarOverlayColorTheme() const override; - bool IsCustomScrollbar() const override; - Orientation GetOrientation() const override; - bool IsLeftSideVerticalScrollbar() const override; - float ElasticOverscroll() const override; - void SetElasticOverscroll(float) override; - - private: - explicit WebScrollbarImpl(Scrollbar*); - - // Accessed by main and compositor threads, e.g., the compositor thread - // checks |orientation()|. - // - // TODO: minimize or avoid cross-thread use, if possible. - CrossThreadPersistent<Scrollbar> scrollbar_; -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.cc b/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.cc deleted file mode 100644 index eb44177..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.cc +++ /dev/null
@@ -1,184 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h" - -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" - -namespace blink { - -WebScrollbarThemeClientImpl::WebScrollbarThemeClientImpl( - WebScrollbar& scrollbar) - : scrollbar_(scrollbar) { - ScrollbarTheme::DeprecatedStaticGetTheme().RegisterScrollbar(*this); -} - -WebScrollbarThemeClientImpl::~WebScrollbarThemeClientImpl() { - ScrollbarTheme::DeprecatedStaticGetTheme().UnregisterScrollbar(*this); -} - -int WebScrollbarThemeClientImpl::X() const { - return Location().X(); -} - -int WebScrollbarThemeClientImpl::Y() const { - return Location().Y(); -} - -int WebScrollbarThemeClientImpl::Width() const { - return Size().Width(); -} - -int WebScrollbarThemeClientImpl::Height() const { - return Size().Height(); -} - -IntSize WebScrollbarThemeClientImpl::Size() const { - return scrollbar_.Size(); -} - -IntPoint WebScrollbarThemeClientImpl::Location() const { - return scrollbar_.Location(); -} - -void WebScrollbarThemeClientImpl::SetFrameRect(const IntRect&) { - // Unused by Chromium scrollbar themes. - NOTREACHED(); -} - -IntRect WebScrollbarThemeClientImpl::FrameRect() const { - return IntRect(Location(), Size()); -} - -void WebScrollbarThemeClientImpl::Invalidate() { - // Unused by Chromium scrollbar themes. - NOTREACHED(); -} - -void WebScrollbarThemeClientImpl::InvalidateRect(const IntRect&) { - // Unused by Chromium scrollbar themes. - NOTREACHED(); -} - -ScrollbarOverlayColorTheme -WebScrollbarThemeClientImpl::GetScrollbarOverlayColorTheme() const { - return static_cast<ScrollbarOverlayColorTheme>( - scrollbar_.ScrollbarOverlayColorTheme()); -} - -void WebScrollbarThemeClientImpl::GetTickmarks( - Vector<IntRect>& tickmarks) const { - WebVector<WebRect> web_tickmarks; - scrollbar_.GetTickmarks(web_tickmarks); - tickmarks.resize(web_tickmarks.size()); - for (size_t i = 0; i < web_tickmarks.size(); ++i) - tickmarks[i] = web_tickmarks[i]; -} - -bool WebScrollbarThemeClientImpl::IsScrollableAreaActive() const { - return scrollbar_.IsScrollableAreaActive(); -} - -IntPoint WebScrollbarThemeClientImpl::ConvertFromRootFrame( - const IntPoint& point_in_root_frame) const { - // Unused by Chromium scrollbar themes. - NOTREACHED(); - return point_in_root_frame; -} - -bool WebScrollbarThemeClientImpl::IsCustomScrollbar() const { - return scrollbar_.IsCustomScrollbar(); -} - -ScrollbarOrientation WebScrollbarThemeClientImpl::Orientation() const { - return static_cast<ScrollbarOrientation>(scrollbar_.GetOrientation()); -} - -bool WebScrollbarThemeClientImpl::IsLeftSideVerticalScrollbar() const { - return scrollbar_.IsLeftSideVerticalScrollbar(); -} - -int WebScrollbarThemeClientImpl::Value() const { - return scrollbar_.Value(); -} - -float WebScrollbarThemeClientImpl::CurrentPos() const { - return Value(); -} - -int WebScrollbarThemeClientImpl::VisibleSize() const { - return TotalSize() - Maximum(); -} - -int WebScrollbarThemeClientImpl::TotalSize() const { - return scrollbar_.TotalSize(); -} - -int WebScrollbarThemeClientImpl::Maximum() const { - return scrollbar_.Maximum(); -} - -ScrollbarControlSize WebScrollbarThemeClientImpl::GetControlSize() const { - return static_cast<ScrollbarControlSize>(scrollbar_.GetControlSize()); -} - -ScrollbarPart WebScrollbarThemeClientImpl::PressedPart() const { - return static_cast<ScrollbarPart>(scrollbar_.PressedPart()); -} - -ScrollbarPart WebScrollbarThemeClientImpl::HoveredPart() const { - return static_cast<ScrollbarPart>(scrollbar_.HoveredPart()); -} - -void WebScrollbarThemeClientImpl::StyleChanged() { - NOTREACHED(); -} - -void WebScrollbarThemeClientImpl::SetScrollbarsHiddenIfOverlay(bool hidden) { - NOTREACHED(); -} - -bool WebScrollbarThemeClientImpl::Enabled() const { - return scrollbar_.Enabled(); -} - -void WebScrollbarThemeClientImpl::SetEnabled(bool) { - NOTREACHED(); -} - -bool WebScrollbarThemeClientImpl::IsOverlayScrollbar() const { - return scrollbar_.IsOverlay(); -} - -float WebScrollbarThemeClientImpl::ElasticOverscroll() const { - return scrollbar_.ElasticOverscroll(); -} - -void WebScrollbarThemeClientImpl::SetElasticOverscroll( - float elastic_overscroll) { - return scrollbar_.SetElasticOverscroll(elastic_overscroll); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h b/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h deleted file mode 100644 index 34a7d26..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h +++ /dev/null
@@ -1,89 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_CLIENT_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_CLIENT_IMPL_H_ - -#include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -namespace blink { - -// Adapts a WebScrollbar to the ScrollbarThemeClient interface -class PLATFORM_EXPORT WebScrollbarThemeClientImpl - : public ScrollbarThemeClient { - DISALLOW_NEW(); - WTF_MAKE_NONCOPYABLE(WebScrollbarThemeClientImpl); - - public: - // Caller must retain ownership of this pointer and ensure that its lifetime - // exceeds this instance. - WebScrollbarThemeClientImpl(WebScrollbar&); - ~WebScrollbarThemeClientImpl() override; - - // Implement ScrollbarThemeClient interface - int X() const override; - int Y() const override; - int Width() const override; - int Height() const override; - IntSize Size() const override; - IntPoint Location() const override; - void SetFrameRect(const IntRect&) override; - IntRect FrameRect() const override; - void Invalidate() override; - void InvalidateRect(const IntRect&) override; - ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const override; - void GetTickmarks(Vector<IntRect>&) const override; - bool IsScrollableAreaActive() const override; - IntPoint ConvertFromRootFrame(const IntPoint&) const override; - bool IsCustomScrollbar() const override; - ScrollbarOrientation Orientation() const override; - bool IsLeftSideVerticalScrollbar() const override; - int Value() const override; - float CurrentPos() const override; - int VisibleSize() const override; - int TotalSize() const override; - int Maximum() const override; - ScrollbarControlSize GetControlSize() const override; - ScrollbarPart PressedPart() const override; - ScrollbarPart HoveredPart() const override; - void StyleChanged() override; - void SetScrollbarsHiddenIfOverlay(bool) override; - bool Enabled() const override; - void SetEnabled(bool) override; - bool IsOverlayScrollbar() const override; - float ElasticOverscroll() const override; - void SetElasticOverscroll(float) override; - - private: - WebScrollbar& scrollbar_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_CLIENT_IMPL_H_
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.cc b/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.cc deleted file mode 100644 index 89c9a73..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.cc +++ /dev/null
@@ -1,99 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" - -namespace blink { - -std::unique_ptr<WebScrollbarThemeGeometryNative> -WebScrollbarThemeGeometryNative::Create(ScrollbarTheme& theme) { - return base::WrapUnique(new WebScrollbarThemeGeometryNative(theme)); -} - -WebScrollbarThemeGeometryNative::WebScrollbarThemeGeometryNative( - ScrollbarTheme& theme) - : theme_(theme) {} - -bool WebScrollbarThemeGeometryNative::HasButtons(WebScrollbar* scrollbar) { - return theme_.HasButtons(WebScrollbarThemeClientImpl(*scrollbar)); -} - -bool WebScrollbarThemeGeometryNative::HasThumb(WebScrollbar* scrollbar) { - return theme_.HasThumb(WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::TrackRect(WebScrollbar* scrollbar) { - return theme_.TrackRect(WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::ThumbRect(WebScrollbar* scrollbar) { - return theme_.ThumbRect(WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::BackButtonStartRect( - WebScrollbar* scrollbar) { - return theme_.BackButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kBackButtonStartPart, false); -} - -WebRect WebScrollbarThemeGeometryNative::BackButtonEndRect( - WebScrollbar* scrollbar) { - return theme_.BackButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kBackButtonEndPart, false); -} - -WebRect WebScrollbarThemeGeometryNative::ForwardButtonStartRect( - WebScrollbar* scrollbar) { - return theme_.ForwardButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kForwardButtonStartPart, false); -} - -WebRect WebScrollbarThemeGeometryNative::ForwardButtonEndRect( - WebScrollbar* scrollbar) { - return theme_.ForwardButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kForwardButtonEndPart, false); -} - -WebSize WebScrollbarThemeGeometryNative::NinePatchThumbCanvasSize( - WebScrollbar* scrollbar) { - DCHECK(theme_.UsesNinePatchThumbResource()); - return theme_.NinePatchThumbCanvasSize( - WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::NinePatchThumbAperture( - WebScrollbar* scrollbar) { - DCHECK(theme_.UsesNinePatchThumbResource()); - return theme_.NinePatchThumbAperture(WebScrollbarThemeClientImpl(*scrollbar)); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h b/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h deleted file mode 100644 index b7606dea..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h +++ /dev/null
@@ -1,72 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_GEOMETRY_NATIVE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_GEOMETRY_NATIVE_H_ - -#include <memory> -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_geometry.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -namespace blink { - -class ScrollbarTheme; -class WebScrollbar; - -class PLATFORM_EXPORT WebScrollbarThemeGeometryNative - : public WebScrollbarThemeGeometry { - USING_FAST_MALLOC(WebScrollbarThemeGeometryNative); - WTF_MAKE_NONCOPYABLE(WebScrollbarThemeGeometryNative); - - public: - static std::unique_ptr<WebScrollbarThemeGeometryNative> Create( - ScrollbarTheme&); - - bool HasButtons(WebScrollbar*) override; - bool HasThumb(WebScrollbar*) override; - WebRect TrackRect(WebScrollbar*) override; - WebRect ThumbRect(WebScrollbar*) override; - WebRect BackButtonStartRect(WebScrollbar*) override; - WebRect BackButtonEndRect(WebScrollbar*) override; - WebRect ForwardButtonStartRect(WebScrollbar*) override; - WebRect ForwardButtonEndRect(WebScrollbar*) override; - WebSize NinePatchThumbCanvasSize(WebScrollbar*) override; - WebRect NinePatchThumbAperture(WebScrollbar*) override; - - private: - explicit WebScrollbarThemeGeometryNative(ScrollbarTheme&); - - // The theme is not owned by this class. It is assumed that the theme is a - // static pointer and its lifetime is essentially infinite. Only thread-safe - // functions on the theme can be called by this theme. - ScrollbarTheme& theme_; -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_painter.cc b/third_party/blink/renderer/platform/exported/web_scrollbar_theme_painter.cc deleted file mode 100644 index 6d123b3..0000000 --- a/third_party/blink/renderer/platform/exported/web_scrollbar_theme_painter.cc +++ /dev/null
@@ -1,174 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/public/platform/web_scrollbar_theme_painter.h" - -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" - -namespace blink { - -// WebScrollbarThemeMac uses GraphicsContextCanvas which doesn't quite support -// device clip rects not at the origin. This class translates the recording -// canvas to the origin and then adjusts it back during playback. -class ScopedScrollbarPainter { - public: - ScopedScrollbarPainter(WebScrollbarThemePainter* painter, - WebCanvas* canvas, - const WebRect& rect) - : int_rect_(IntRect(IntPoint(), IntSize(rect.width, rect.height))), - canvas_(canvas), - rect_(rect) { - builder_.Context().SetDeviceScaleFactor(painter->DeviceScaleFactor()); - } - GraphicsContext& Context() { return builder_.Context(); } - const IntRect& Rect() const { return int_rect_; } - - ~ScopedScrollbarPainter() { - canvas_->save(); - canvas_->translate(rect_.x, rect_.y); - canvas_->drawPicture(builder_.EndRecording()); - canvas_->restore(); - } - - protected: - IntRect int_rect_; - PaintRecordBuilder builder_; - WebCanvas* canvas_; - const WebRect& rect_; -}; - -void WebScrollbarThemePainter::Assign(const WebScrollbarThemePainter& painter) { - // This is a pointer to a static object, so no ownership transferral. - theme_ = painter.theme_; - scrollbar_ = painter.scrollbar_; - device_scale_factor_ = painter.device_scale_factor_; -} - -void WebScrollbarThemePainter::Reset() { - scrollbar_ = nullptr; -} - -void WebScrollbarThemePainter::PaintScrollbarBackground(WebCanvas* canvas, - const WebRect& rect) { - SkRect clip = SkRect::MakeXYWH(rect.x, rect.y, rect.width, rect.height); - canvas->clipRect(clip); - - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintScrollbarBackground(painter.Context(), *scrollbar_); -} - -void WebScrollbarThemePainter::PaintTrackBackground(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTrackBackground(painter.Context(), *scrollbar_, painter.Rect()); - if (!theme_->ShouldRepaintAllPartsOnInvalidation()) - scrollbar_->ClearTrackNeedsRepaint(); -} - -void WebScrollbarThemePainter::PaintBackTrackPart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTrackPiece(painter.Context(), *scrollbar_, painter.Rect(), - kBackTrackPart); -} - -void WebScrollbarThemePainter::PaintForwardTrackPart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTrackPiece(painter.Context(), *scrollbar_, painter.Rect(), - kForwardTrackPart); -} - -void WebScrollbarThemePainter::PaintBackButtonStart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kBackButtonStartPart); -} - -void WebScrollbarThemePainter::PaintBackButtonEnd(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kBackButtonEndPart); -} - -void WebScrollbarThemePainter::PaintForwardButtonStart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kForwardButtonStartPart); -} - -void WebScrollbarThemePainter::PaintForwardButtonEnd(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kForwardButtonEndPart); -} - -void WebScrollbarThemePainter::PaintTickmarks(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTickmarks(painter.Context(), *scrollbar_, painter.Rect()); -} - -void WebScrollbarThemePainter::PaintThumb(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintThumb(painter.Context(), *scrollbar_, painter.Rect()); - if (!theme_->ShouldRepaintAllPartsOnInvalidation()) - scrollbar_->ClearThumbNeedsRepaint(); -} - -WebScrollbarThemePainter::WebScrollbarThemePainter(ScrollbarTheme& theme, - Scrollbar& scrollbar, - float device_scale_factor) - : theme_(&theme), - scrollbar_(&scrollbar), - device_scale_factor_(device_scale_factor) {} - -float WebScrollbarThemePainter::ThumbOpacity() const { - return theme_->ThumbOpacity(*scrollbar_); -} - -bool WebScrollbarThemePainter::TrackNeedsRepaint() const { - return scrollbar_->TrackNeedsRepaint(); -} - -bool WebScrollbarThemePainter::ThumbNeedsRepaint() const { - return scrollbar_->ThumbNeedsRepaint(); -} - -bool WebScrollbarThemePainter::UsesNinePatchThumbResource() const { - return theme_->UsesNinePatchThumbResource(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/geometry/int_point.cc b/third_party/blink/renderer/platform/geometry/int_point.cc index 2bfd9fd..3315630a 100644 --- a/third_party/blink/renderer/platform/geometry/int_point.cc +++ b/third_party/blink/renderer/platform/geometry/int_point.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/geometry/int_point.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "ui/gfx/geometry/point.h" namespace blink { @@ -12,6 +13,10 @@ return ostream << point.ToString(); } +IntPoint::operator gfx::Point() const { + return gfx::Point(X(), Y()); +} + String IntPoint::ToString() const { return String::Format("%d,%d", X(), Y()); }
diff --git a/third_party/blink/renderer/platform/geometry/int_point.h b/third_party/blink/renderer/platform/geometry/int_point.h index 6e0072ec..9bbfa8c 100644 --- a/third_party/blink/renderer/platform/geometry/int_point.h +++ b/third_party/blink/renderer/platform/geometry/int_point.h
@@ -43,6 +43,10 @@ #endif #endif +namespace gfx { +class Point; +} + namespace blink { class PLATFORM_EXPORT IntPoint { @@ -100,6 +104,8 @@ operator CGPoint() const; #endif + operator gfx::Point() const; + String ToString() const; private:
diff --git a/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc b/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc index ad518f8..cbc0164 100644 --- a/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc +++ b/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
@@ -16,14 +16,39 @@ const BeginFrameProviderParams& begin_frame_provider_params, BeginFrameProviderClient* client) : needs_begin_frame_(false), + requested_needs_begin_frame_(false), cfs_binding_(this), efs_binding_(this), frame_sink_id_(begin_frame_provider_params.frame_sink_id), parent_frame_sink_id_(begin_frame_provider_params.parent_frame_sink_id), - begin_frame_client_(client) {} + begin_frame_client_(client), + weak_factory_(this) {} -void BeginFrameProvider::CreateCompositorFrameSink() { - DCHECK(frame_sink_id_.is_valid()); +void BeginFrameProvider::ResetCompositorFrameSink() { + compositor_frame_sink_.reset(); + efs_binding_.Close(); + cfs_binding_.Close(); + if (needs_begin_frame_) { + needs_begin_frame_ = false; + RequestBeginFrame(); + } +} + +void BeginFrameProvider::OnMojoConnectionError(uint32_t custom_reason, + const std::string& description) { + if (custom_reason) { + DLOG(ERROR) << description; + } + ResetCompositorFrameSink(); +} + +void BeginFrameProvider::CreateCompositorFrameSinkIfNeeded() { + if (!parent_frame_sink_id_.is_valid() || !frame_sink_id_.is_valid()) { + return; + } + + if (compositor_frame_sink_.is_bound()) + return; mojom::blink::EmbeddedFrameSinkProviderPtr provider; Platform::Current()->GetInterfaceProvider()->GetInterface( @@ -43,33 +68,34 @@ provider->CreateSimpleCompositorFrameSink( parent_frame_sink_id_, frame_sink_id_, std::move(efs_client), std::move(client), mojo::MakeRequest(&compositor_frame_sink_)); + + compositor_frame_sink_.set_connection_error_with_reason_handler( + base::BindOnce(&BeginFrameProvider::OnMojoConnectionError, + weak_factory_.GetWeakPtr())); } void BeginFrameProvider::RequestBeginFrame() { + requested_needs_begin_frame_ = true; if (needs_begin_frame_) return; - if (!compositor_frame_sink_.is_bound()) { - CreateCompositorFrameSink(); - if (!compositor_frame_sink_.is_bound()) { - return; - } - } + CreateCompositorFrameSinkIfNeeded(); needs_begin_frame_ = true; compositor_frame_sink_->SetNeedsBeginFrame(true); } void BeginFrameProvider::OnBeginFrame(const viz::BeginFrameArgs& args) { - // TODO(fserb): we could potentially be nicer here. - DCHECK(compositor_frame_sink_.is_bound()); - - // OnBeginFrame sometimes happens without a request. So we just skip it. + // If there was no need for a BeginFrame, just skip it. if (needs_begin_frame_) { - needs_begin_frame_ = false; - compositor_frame_sink_->SetNeedsBeginFrame(false); + requested_needs_begin_frame_ = false; begin_frame_client_->BeginFrame(); + + if (!requested_needs_begin_frame_) { + needs_begin_frame_ = false; + compositor_frame_sink_->SetNeedsBeginFrame(false); + } } viz::BeginFrameAck ack;
diff --git a/third_party/blink/renderer/platform/graphics/begin_frame_provider.h b/third_party/blink/renderer/platform/graphics/begin_frame_provider.h index aee6fc03..6138658 100644 --- a/third_party/blink/renderer/platform/graphics/begin_frame_provider.h +++ b/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
@@ -32,7 +32,7 @@ const BeginFrameProviderParams& begin_frame_provider_params, BeginFrameProviderClient*); - void CreateCompositorFrameSink(); + void CreateCompositorFrameSinkIfNeeded(); void RequestBeginFrame(); @@ -62,17 +62,25 @@ NOTIMPLEMENTED(); } + void ResetCompositorFrameSink(); + ~BeginFrameProvider() override = default; private: + void OnMojoConnectionError(uint32_t custom_reason, + const std::string& description); + bool needs_begin_frame_; + bool requested_needs_begin_frame_; mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> cfs_binding_; mojo::Binding<mojom::blink::EmbeddedFrameSinkClient> efs_binding_; - const viz::FrameSinkId frame_sink_id_; - const viz::FrameSinkId parent_frame_sink_id_; + viz::FrameSinkId frame_sink_id_; + viz::FrameSinkId parent_frame_sink_id_; viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_; BeginFrameProviderClient* begin_frame_client_; + + base::WeakPtrFactory<BeginFrameProvider> weak_factory_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc index 05efcca2..700122d 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -164,16 +164,11 @@ void UpdateEffectBounds(const FloatRect&, const TransformPaintPropertyNode*); // Starts a clip state by adjusting the transform state, applying - // |combined_clip_rect| which is combined from multiple rectangular - // consecutive clips, and updating the current state. - // |lowest_combined_clip_node| is the lowest node of the combined clips. - void StartCombinedClip( - const FloatRect& combined_clip_rect, - const ClipPaintPropertyNode* lowest_combined_clip_node); - // Starts a clip state by adjusting the transform state, applying the single - // clip node which can't be combined with other clips, and updating the - // current state. - void StartSingleClip(const ClipPaintPropertyNode*); + // |combined_clip_rect| which is combined from one or more consecutive clips, + // and updating the current state. |lowest_combined_clip_node| is the lowest + // node of the combined clips. + void StartClip(const FloatRoundedRect& combined_clip_rect, + const ClipPaintPropertyNode* lowest_combined_clip_node); // Pop one clip state from the top of the stack. void EndClip(); // Pop clip states from the top of the stack until the top is an effect state @@ -274,6 +269,46 @@ SwitchToTransform(chunk_state.Transform()); } +// Tries to combine a clip node's clip rect into |combined_clip_rect|. +// Returns whether the clip has been combined. +static bool CombineClip(const ClipPaintPropertyNode* clip, + FloatRoundedRect& combined_clip_rect) { + // Don't combine into a clip with clip path. + if (clip->Parent()->ClipPath()) + return false; + + // Don't combine clips in different transform spaces. + if (clip->LocalTransformSpace() != clip->Parent()->LocalTransformSpace() && + !GeometryMapper::SourceToDestinationProjection( + clip->Parent()->LocalTransformSpace(), clip->LocalTransformSpace()) + .IsIdentity()) + return false; + + // Don't combine two rounded clip rects. + bool clip_is_rounded = clip->ClipRect().IsRounded(); + bool combined_is_rounded = combined_clip_rect.IsRounded(); + if (clip_is_rounded && combined_is_rounded) + return false; + + // If one is rounded and the other contains the rounded bounds, use the + // rounded as the combined. + if (combined_is_rounded) + return clip->ClipRect().Rect().Contains(combined_clip_rect.Rect()); + if (clip_is_rounded) { + if (combined_clip_rect.Rect().Contains(clip->ClipRect().Rect())) { + combined_clip_rect = clip->ClipRect(); + return true; + } + return false; + } + + // The combined is the intersection if both are rectangular. + DCHECK(!combined_is_rounded && !clip_is_rounded); + combined_clip_rect = FloatRoundedRect( + Intersection(combined_clip_rect.Rect(), clip->ClipRect().Rect())); + return true; +} + void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { if (target_clip == current_clip_) return; @@ -317,49 +352,29 @@ } // Step 3: Now apply the list of clips in top-down order. - base::Optional<FloatRect> pending_combined_clip_rect; - const ClipPaintPropertyNode* lowest_combined_clip_node = nullptr; - for (size_t i = pending_clips.size(); i--;) { + DCHECK(pending_clips.size()); + auto pending_combined_clip_rect = pending_clips.back()->ClipRect(); + const auto* lowest_combined_clip_node = pending_clips.back(); + for (size_t i = pending_clips.size() - 1; i--;) { const auto* sub_clip = pending_clips[i]; - bool has_rounded_clip_or_clip_path = - sub_clip->ClipRect().IsRounded() || sub_clip->ClipPath(); - if (!has_rounded_clip_or_clip_path && pending_combined_clip_rect && - (sub_clip->Parent()->LocalTransformSpace() == - sub_clip->LocalTransformSpace() || - GeometryMapper::SourceToDestinationProjection( - sub_clip->Parent()->LocalTransformSpace(), - sub_clip->LocalTransformSpace()) - .IsIdentity())) { - // Continue to combine rectangular clips in the same transform space. - pending_combined_clip_rect->Intersect(sub_clip->ClipRect().Rect()); + if (CombineClip(sub_clip, pending_combined_clip_rect)) { + // Continue to combine. lowest_combined_clip_node = sub_clip; - continue; - } - - if (pending_combined_clip_rect) { - StartCombinedClip(*pending_combined_clip_rect, lowest_combined_clip_node); - lowest_combined_clip_node = nullptr; - pending_combined_clip_rect.reset(); - } - - if (has_rounded_clip_or_clip_path) { - // The clip can't be combined with others. - StartSingleClip(sub_clip); } else { - // Start to combine clips. - pending_combined_clip_rect = sub_clip->ClipRect().Rect(); + // |sub_clip| can't be combined to previous clips. Output the current + // combined clip, and start new combination. + StartClip(pending_combined_clip_rect, lowest_combined_clip_node); + pending_combined_clip_rect = sub_clip->ClipRect(); lowest_combined_clip_node = sub_clip; } } - - if (pending_combined_clip_rect) - StartCombinedClip(*pending_combined_clip_rect, lowest_combined_clip_node); + StartClip(pending_combined_clip_rect, lowest_combined_clip_node); DCHECK_EQ(current_clip_, target_clip); } -void ConversionContext::StartCombinedClip( - const FloatRect& combined_clip_rect, +void ConversionContext::StartClip( + const FloatRoundedRect& combined_clip_rect, const ClipPaintPropertyNode* lowest_combined_clip_node) { if (lowest_combined_clip_node->LocalTransformSpace() != current_transform_) EndTransform(); @@ -367,8 +382,18 @@ cc_list_.push<cc::SaveOp>(); ApplyTransform(lowest_combined_clip_node->LocalTransformSpace()); const bool antialias = true; - cc_list_.push<cc::ClipRectOp>(combined_clip_rect, SkClipOp::kIntersect, - antialias); + if (combined_clip_rect.IsRounded()) { + cc_list_.push<cc::ClipRRectOp>(combined_clip_rect, SkClipOp::kIntersect, + antialias); + } else { + cc_list_.push<cc::ClipRectOp>(combined_clip_rect.Rect(), + SkClipOp::kIntersect, antialias); + } + if (lowest_combined_clip_node->ClipPath()) { + cc_list_.push<cc::ClipPathOp>( + lowest_combined_clip_node->ClipPath()->GetSkPath(), + SkClipOp::kIntersect, antialias); + } cc_list_.EndPaintOfPairedBegin(); PushState(StateEntry::kClip, 1); @@ -376,30 +401,6 @@ current_transform_ = lowest_combined_clip_node->LocalTransformSpace(); } -void ConversionContext::StartSingleClip(const ClipPaintPropertyNode* clip) { - if (clip->LocalTransformSpace() != current_transform_) - EndTransform(); - cc_list_.StartPaint(); - cc_list_.push<cc::SaveOp>(); - ApplyTransform(clip->LocalTransformSpace()); - const bool antialias = true; - cc_list_.push<cc::ClipRectOp>(static_cast<SkRect>(clip->ClipRect().Rect()), - SkClipOp::kIntersect, antialias); - if (clip->ClipRect().IsRounded()) { - cc_list_.push<cc::ClipRRectOp>(static_cast<SkRRect>(clip->ClipRect()), - SkClipOp::kIntersect, antialias); - } - if (clip->ClipPath()) { - cc_list_.push<cc::ClipPathOp>(clip->ClipPath()->GetSkPath(), - SkClipOp::kIntersect, antialias); - } - cc_list_.EndPaintOfPairedBegin(); - - PushState(StateEntry::kClip, 1); - current_clip_ = clip; - current_transform_ = clip->LocalTransformSpace(); -} - void ConversionContext::SwitchToEffect( const EffectPaintPropertyNode* target_effect) { if (target_effect == current_effect_)
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc index c565d4f..ba85060 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc
@@ -129,6 +129,22 @@ EXPECT_EQ(y, translate->dy); \ } while (false) +#define EXPECT_CLIP(r, op_buffer, index) \ + do { \ + const auto* clip_op = \ + (op_buffer).GetOpAtForTesting<cc::ClipRectOp>(index); \ + ASSERT_NE(nullptr, clip_op); \ + EXPECT_EQ(SkRect(r), clip_op->rect); \ + } while (false) + +#define EXPECT_ROUNDED_CLIP(r, op_buffer, index) \ + do { \ + const auto* clip_op = \ + (op_buffer).GetOpAtForTesting<cc::ClipRRectOp>(index); \ + ASSERT_NE(nullptr, clip_op); \ + EXPECT_EQ(SkRRect(r), clip_op->rrect); \ + } while (false) + // Convenient shorthands. const TransformPaintPropertyNode* t0() { return TransformPaintPropertyNode::Root(); @@ -691,15 +707,12 @@ TEST_F(PaintChunksToCcLayerTest, CombineClips) { FloatRoundedRect clip_rect(0, 0, 100, 100); - FloatSize corner(5, 5); - FloatRoundedRect rounded_clip_rect(clip_rect.Rect(), corner, corner, corner, - corner); auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); auto c1 = CreateClip(c0(), t0(), clip_rect); auto c2 = CreateClip(c1, t0(), clip_rect); auto c3 = CreateClip(c2, t1, clip_rect); auto c4 = CreateClip(c3, t1, clip_rect); - auto c5 = CreateClip(c4, t1, rounded_clip_rect); + auto c5 = CreateClipPathClip(c4, t1, clip_rect); auto c6 = CreateClip(c5, t1, clip_rect); TestChunks chunks; @@ -715,21 +728,65 @@ EXPECT_THAT( *output, PaintRecordMatcher::Make( - {cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c1+c2> - cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 - cc::PaintOpType::ClipRect, // c3+c4> - cc::PaintOpType::Save, cc::PaintOpType::ClipRect, - cc::PaintOpType::ClipRRect, // <c5> - cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c6> - cc::PaintOpType::DrawRecord, // <p0/> - cc::PaintOpType::Restore, // </c6> - cc::PaintOpType::Restore, // </c5> - cc::PaintOpType::Restore, // </c3+c4 t1> - cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 - cc::PaintOpType::ClipRect, // c3> - cc::PaintOpType::DrawRecord, // <p1/> - cc::PaintOpType::Restore, // </c3 t1> - cc::PaintOpType::Restore})); // </c1+c2> + {cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c1+c2> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 + cc::PaintOpType::ClipRect, cc::PaintOpType::ClipPath, // c3+c4+c5> + cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c6> + cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Restore, // </c6> + cc::PaintOpType::Restore, // </c3+c4+c5 t1> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 + cc::PaintOpType::ClipRect, // c3> + cc::PaintOpType::DrawRecord, // <p1/> + cc::PaintOpType::Restore, // </c3 t1> + cc::PaintOpType::Restore})); // </c1+c2> +} + +TEST_F(PaintChunksToCcLayerTest, CombineClipsWithRoundedRects) { + FloatRoundedRect clip_rect(0, 0, 100, 100); + FloatSize corner(5, 5); + FloatRoundedRect big_rounded_clip_rect(FloatRect(0, 0, 200, 200), corner, + corner, corner, corner); + FloatRoundedRect small_rounded_clip_rect(FloatRect(0, 0, 100, 100), corner, + corner, corner, corner); + + auto c1 = CreateClip(c0(), t0(), clip_rect); + auto c2 = CreateClip(c1, t0(), small_rounded_clip_rect); + auto c3 = CreateClip(c2, t0(), clip_rect); + auto c4 = CreateClip(c3, t0(), big_rounded_clip_rect); + auto c5 = CreateClip(c4, t0(), clip_rect); + auto c6 = CreateClip(c5, t0(), big_rounded_clip_rect); + auto c7 = CreateClip(c6, t0(), small_rounded_clip_rect); + + TestChunks chunks; + chunks.AddChunk(t0(), c7.get(), e0()); + + sk_sp<PaintRecord> output = + PaintChunksToCcLayer::Convert( + chunks.chunks, PropertyTreeState(t0(), c0(), e0()), gfx::Vector2dF(), + chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + ->ReleaseAsRecord(); + + EXPECT_THAT( + *output, + PaintRecordMatcher::Make( + {cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c1+c2+c3> + cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c4> + cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c5> + cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c6> + cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c7> + cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Restore, // </c7> + cc::PaintOpType::Restore, // </c6> + cc::PaintOpType::Restore, // </c5> + cc::PaintOpType::Restore, // </c4> + cc::PaintOpType::Restore})); // </c1+c2+c3> + + EXPECT_ROUNDED_CLIP(small_rounded_clip_rect, *output, 1); + EXPECT_ROUNDED_CLIP(big_rounded_clip_rect, *output, 3); + EXPECT_CLIP(clip_rect.Rect(), *output, 5); + EXPECT_ROUNDED_CLIP(big_rounded_clip_rect, *output, 7); + EXPECT_ROUNDED_CLIP(small_rounded_clip_rect, *output, 9); } TEST_F(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) {
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index 4e8166c7..d5f9b73 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -35,7 +35,6 @@ V(WillChangeCompositingHint) \ V(BackdropFilter) \ V(RootScroller) \ - V(ScrollTimelineTarget) \ \ /* Overlap reasons that require knowing what's behind you in paint-order \ before knowing the answer. */ \
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index 1c89c15..017030ae 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -268,6 +268,9 @@ DrawingBuffer::RegisteredBitmap DrawingBuffer::CreateOrRecycleBitmap( cc::SharedBitmapIdRegistrar* bitmap_registrar) { + // When searching for a hit in SharedBitmap, we don't consider the bitmap + // format (RGBA 8888 vs F16). We expect to always have the same bitmap format, + // matching the back storage of the drawing buffer. auto* it = std::remove_if(recycled_bitmaps_.begin(), recycled_bitmaps_.end(), [this](const RegisteredBitmap& registered) { return registered.bitmap->size() != @@ -283,11 +286,14 @@ } viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); + viz::ResourceFormat format = viz::RGBA_8888; + if (use_half_float_storage_) + format = viz::RGBA_F16; std::unique_ptr<base::SharedMemory> shm = viz::bitmap_allocation::AllocateMappedBitmap( - static_cast<gfx::Size>(size_), viz::RGBA_8888); + static_cast<gfx::Size>(size_), format); auto bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( - id, std::move(shm), static_cast<gfx::Size>(size_), viz::RGBA_8888); + id, std::move(shm), static_cast<gfx::Size>(size_), format); RegisteredBitmap registered = { bitmap, bitmap_registrar->RegisterSharedBitmapId(id, bitmap)}; return registered; @@ -363,8 +369,11 @@ op); } + viz::ResourceFormat format = viz::RGBA_8888; + if (use_half_float_storage_) + format = viz::RGBA_F16; *out_resource = viz::TransferableResource::MakeSoftware( - registered.bitmap->id(), static_cast<gfx::Size>(size_), viz::RGBA_8888); + registered.bitmap->id(), static_cast<gfx::Size>(size_), format); out_resource->color_space = storage_color_space_; // This holds a ref on the DrawingBuffer that will keep it alive until the @@ -457,6 +466,8 @@ is_overlay_candidate); out_resource->color_space = sampler_color_space_; out_resource->format = viz::RGBA_8888; + if (use_half_float_storage_) + out_resource->format = viz::RGBA_F16; // This holds a ref on the DrawingBuffer that will keep it alive until the // mailbox is released (and while the release callback is running).
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc index 1eb9dd0..872e01a 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -15,9 +15,12 @@ #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" +#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h" #include "third_party/blink/renderer/platform/graphics/color_behavior.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "ui/gfx/geometry/size.h" namespace blink { @@ -135,17 +138,22 @@ WrapWeakPersistent(this), std::move(image_for_compositor)); *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func)); } else { - const gfx::Size size(image_for_compositor->width(), - image_for_compositor->height()); - RegisteredBitmap registered = CreateOrRecycleBitmap(size, bitmap_registrar); - sk_sp<SkImage> sk_image = image_for_compositor->PaintImageForCurrentFrame().GetSkImage(); if (!sk_image) return false; - SkImageInfo dst_info = SkImageInfo::MakeN32Premul( - size.width(), size.height(), sk_image->refColorSpace()); + const gfx::Size size(image_for_compositor->width(), + image_for_compositor->height()); + viz::ResourceFormat resource_format = viz::RGBA_8888; + if (sk_image->colorType() == SkColorType::kRGBA_F16_SkColorType) + resource_format = viz::RGBA_F16; + RegisteredBitmap registered = + CreateOrRecycleBitmap(size, resource_format, bitmap_registrar); + + SkImageInfo dst_info = + SkImageInfo::Make(size.width(), size.height(), sk_image->colorType(), + kPremul_SkAlphaType, sk_image->refColorSpace()); void* pixels = registered.bitmap->shared_memory()->memory(); // Copy from SkImage into SharedMemory owned by |registered|. @@ -153,25 +161,32 @@ return false; *out_resource = viz::TransferableResource::MakeSoftware( - registered.bitmap->id(), size, viz::RGBA_8888); + registered.bitmap->id(), size, resource_format); + if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) { + out_resource->color_space = + SkColorSpaceToGfxColorSpace(sk_image->refColorSpace()); + } auto func = WTF::Bind(&ImageLayerBridge::ResourceReleasedSoftware, WrapWeakPersistent(this), std::move(registered)); *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func)); } - // TODO(junov): Figure out how to get the color space info. - // out_resource->color_space = ...; - return true; } ImageLayerBridge::RegisteredBitmap ImageLayerBridge::CreateOrRecycleBitmap( const gfx::Size& size, + viz::ResourceFormat format, cc::SharedBitmapIdRegistrar* bitmap_registrar) { - auto* it = std::remove_if(recycled_bitmaps_.begin(), recycled_bitmaps_.end(), - [&size](const RegisteredBitmap& registered) { - return registered.bitmap->size() != size; - }); + auto* it = std::remove_if( + recycled_bitmaps_.begin(), recycled_bitmaps_.end(), + [&size, &format](const RegisteredBitmap& registered) { + unsigned src_bytes_per_pixel = + (registered.bitmap->format() == viz::RGBA_8888) ? 4 : 8; + unsigned target_bytes_per_pixel = (format == viz::RGBA_8888) ? 4 : 8; + return (registered.bitmap->size().GetArea() * src_bytes_per_pixel != + size.GetArea() * target_bytes_per_pixel); + }); recycled_bitmaps_.Shrink(it - recycled_bitmaps_.begin()); if (!recycled_bitmaps_.IsEmpty()) { @@ -184,11 +199,11 @@ // There are no bitmaps to recycle so allocate a new one. viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); std::unique_ptr<base::SharedMemory> shm = - viz::bitmap_allocation::AllocateMappedBitmap(size, viz::RGBA_8888); + viz::bitmap_allocation::AllocateMappedBitmap(size, format); RegisteredBitmap registered; registered.bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( - id, std::move(shm), size, viz::RGBA_8888); + id, std::move(shm), size, format); registered.registration = bitmap_registrar->RegisterSharedBitmapId(id, registered.bitmap);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h index 5b39341..789d0d7 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h
@@ -9,6 +9,7 @@ #include "cc/layers/texture_layer_client.h" #include "cc/resources/shared_bitmap_id_registrar.h" +#include "components/viz/common/resources/resource_format.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" @@ -76,6 +77,7 @@ // recycled bitmaps that are the wrong size. RegisteredBitmap CreateOrRecycleBitmap( const gfx::Size& size, + viz::ResourceFormat format, cc::SharedBitmapIdRegistrar* bitmap_registrar); void ResourceReleasedGpu(scoped_refptr<StaticBitmapImage>,
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc b/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc index 11324c1..5bd931b 100644 --- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc +++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc
@@ -73,7 +73,7 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner, int placeholder_canvas_id, scoped_refptr<blink::StaticBitmapImage> image, - unsigned resource_id) { + viz::ResourceId resource_id) { DCHECK(IsMainThread()); OffscreenCanvasPlaceholder* placeholder_canvas = OffscreenCanvasPlaceholder::GetPlaceholderById(placeholder_canvas_id); @@ -88,7 +88,7 @@ void OffscreenCanvasFrameDispatcher::PostImageToPlaceholderIfNotBlocked( scoped_refptr<StaticBitmapImage> image, - unsigned resource_id) { + viz::ResourceId resource_id) { if (placeholder_canvas_id_ == kInvalidPlaceholderCanvasId) { offscreen_canvas_resource_provider_->ReclaimResource(resource_id); return; @@ -116,7 +116,7 @@ void OffscreenCanvasFrameDispatcher::PostImageToPlaceholder( scoped_refptr<StaticBitmapImage> image, - unsigned resource_id) { + viz::ResourceId resource_id) { scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner = Platform::Current()->CurrentThread()->GetTaskRunner(); @@ -414,7 +414,8 @@ offscreen_canvas_resource_provider_->ReclaimResources(resources); } -void OffscreenCanvasFrameDispatcher::ReclaimResource(unsigned resource_id) { +void OffscreenCanvasFrameDispatcher::ReclaimResource( + viz::ResourceId resource_id) { offscreen_canvas_resource_provider_->ReclaimResource(resource_id); num_unreclaimed_frames_posted_--;
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h b/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h index 3ad0540..0b31b80 100644 --- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h +++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h
@@ -7,6 +7,7 @@ #include <memory> #include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "components/viz/common/resources/resource_id.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" @@ -48,7 +49,7 @@ void DispatchFrame(scoped_refptr<StaticBitmapImage>, double commit_start_time, const SkIRect& damage_rect); - void ReclaimResource(unsigned resource_id); + void ReclaimResource(viz::ResourceId); void Reshape(const IntSize&); // viz::mojom::blink::CompositorFrameSinkClient implementation. @@ -90,10 +91,10 @@ bool VerifyImageSize(const IntSize); void PostImageToPlaceholderIfNotBlocked(scoped_refptr<StaticBitmapImage>, - unsigned resource_id); + viz::ResourceId resource_id); // virtual for testing virtual void PostImageToPlaceholder(scoped_refptr<StaticBitmapImage>, - unsigned resource_id); + viz::ResourceId resource_id); viz::mojom::blink::CompositorFrameSinkPtr sink_; mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_; @@ -105,7 +106,7 @@ // The latest_unposted_resource_id_ always refers to the Id of the frame // resource used by the latest_unposted_image_. scoped_refptr<StaticBitmapImage> latest_unposted_image_; - unsigned latest_unposted_resource_id_; + viz::ResourceId latest_unposted_resource_id_; unsigned num_unreclaimed_frames_posted_; viz::BeginFrameAck current_begin_frame_ack_;
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc index 4fd962d..d46bf03 100644 --- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc +++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
@@ -24,7 +24,7 @@ void releaseFrameToDispatcher( base::WeakPtr<blink::OffscreenCanvasFrameDispatcher> dispatcher, scoped_refptr<blink::Image> oldImage, - unsigned resourceId) { + viz::ResourceId resourceId) { oldImage = nullptr; // Needed to unref'ed on the right thread if (dispatcher) { dispatcher->ReclaimResource(resourceId); @@ -74,7 +74,7 @@ scoped_refptr<StaticBitmapImage> new_frame, base::WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - unsigned resource_id) { + viz::ResourceId resource_id) { DCHECK(IsPlaceholderRegistered()); DCHECK(new_frame); ReleasePlaceholderFrame();
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h index 37820d2..9db25c5a 100644 --- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h +++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h
@@ -9,6 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" +#include "components/viz/common/resources/resource_id.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink { @@ -24,7 +25,7 @@ scoped_refptr<StaticBitmapImage>, base::WeakPtr<OffscreenCanvasFrameDispatcher>, scoped_refptr<base::SingleThreadTaskRunner>, - unsigned resource_id); + viz::ResourceId resource_id); void ReleasePlaceholderFrame(); void SetSuspendOffscreenCanvasAnimation(bool); @@ -48,7 +49,7 @@ scoped_refptr<StaticBitmapImage> placeholder_frame_; base::WeakPtr<OffscreenCanvasFrameDispatcher> frame_dispatcher_; scoped_refptr<base::SingleThreadTaskRunner> frame_dispatcher_task_runner_; - unsigned placeholder_frame_resource_id_ = 0; + viz::ResourceId placeholder_frame_resource_id_ = 0; enum { kNoPlaceholderId = -1,
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc index 84de3f8..591e84cc 100644 --- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h" #include "third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h" #include "third_party/khronos/GLES2/gl2.h" @@ -80,12 +81,12 @@ frame_resource->provider = this; frame_resource->shared_bitmap_id = viz::SharedBitmap::GenerateId(); frame_resource->shared_memory = - viz::bitmap_allocation::AllocateMappedBitmap( - gfx::Size(width_, height_), viz::ResourceFormat::RGBA_8888); + viz::bitmap_allocation::AllocateMappedBitmap(gfx::Size(width_, height_), + resource.format); sink_->DidAllocateSharedBitmap( viz::bitmap_allocation::DuplicateAndCloseMappedBitmap( frame_resource->shared_memory.get(), gfx::Size(width_, height_), - viz::ResourceFormat::RGBA_8888), + resource.format), SharedBitmapIdToGpuMailboxPtr(frame_resource->shared_bitmap_id)); } void* pixels = frame_resource->shared_memory->memory(); @@ -102,6 +103,10 @@ sk_image->refColorSpace()); if (image_info.isEmpty()) return; + + if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) { + image_info = image_info.makeColorType(sk_image->colorType()); + } bool read_pixels_successful = sk_image->readPixels(image_info, pixels, image_info.minRowBytes(), 0, 0); DCHECK(read_pixels_successful);
diff --git a/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc b/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc index 5e245b1..efa048b0 100644 --- a/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc +++ b/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc
@@ -34,6 +34,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" #include "third_party/skia/include/effects/SkCornerPathEffect.h" +#include "ui/gfx/icc_profile.h" #include <algorithm> #include <cmath> @@ -317,6 +318,29 @@ return SkColorSetA(color, rounded_alpha); } +gfx::ColorSpace SkColorSpaceToGfxColorSpace( + const sk_sp<SkColorSpace> color_space) { + if (!color_space) + return gfx::ColorSpace::CreateSRGB(); + + SkMatrix44 toXYZD50; + SkColorSpaceTransferFn transfer_fn; + if (color_space->toXYZD50(&toXYZD50) && + color_space->isNumericalTransferFn(&transfer_fn)) + return gfx::ColorSpace::CreateCustom(toXYZD50, transfer_fn); + + // Use an intermediate ICC profile to convert the color space data structure. + // If this fails, we fall back to sRGB. + sk_sp<SkData> sk_profile = color_space->serialize(); + if (sk_profile) { + gfx::ICCProfile icc_profile = + gfx::ICCProfile::FromData(sk_profile->data(), sk_profile->size()); + if (icc_profile.IsValid()) + return icc_profile.GetColorSpace(); + } + return gfx::ColorSpace::CreateSRGB(); +} + template <typename PrimitiveType> void DrawFocusRingPrimitive(const PrimitiveType&, PaintCanvas*,
diff --git a/third_party/blink/renderer/platform/graphics/skia/skia_utils.h b/third_party/blink/renderer/platform/graphics/skia/skia_utils.h index eec0d2a1..b14892d 100644 --- a/third_party/blink/renderer/platform/graphics/skia/skia_utils.h +++ b/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
@@ -71,6 +71,10 @@ // alpha is in the range [0, 1]. SkColor PLATFORM_EXPORT ScaleAlpha(SkColor, float); +// Convert a SkColorSpace to a gfx::ColorSpace +gfx::ColorSpace PLATFORM_EXPORT +SkColorSpaceToGfxColorSpace(const sk_sp<SkColorSpace>); + // Skia has problems when passed infinite, etc floats, filter them to 0. inline SkScalar WebCoreFloatToSkScalar(float f) { return SkFloatToScalar(std::isfinite(f) ? f : 0);
diff --git a/third_party/blink/renderer/platform/graphics/skia/skia_utils_test.cc b/third_party/blink/renderer/platform/graphics/skia/skia_utils_test.cc new file mode 100644 index 0000000..7de98907 --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/skia/skia_utils_test.cc
@@ -0,0 +1,44 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class SkiaUtilsTest : public testing::Test {}; + +// Tests converting a SkColorSpace to a gfx::ColorSpace +TEST_F(SkiaUtilsTest, SkColorSpaceToGfxColorSpace) { + std::vector<sk_sp<SkColorSpace>> skia_color_spaces; + + SkColorSpace::RenderTargetGamma gammas[] = { + SkColorSpace::kLinear_RenderTargetGamma, + SkColorSpace::kSRGB_RenderTargetGamma}; + + SkColorSpace::Gamut gamuts[] = { + SkColorSpace::kSRGB_Gamut, SkColorSpace::kAdobeRGB_Gamut, + SkColorSpace::kDCIP3_D65_Gamut, SkColorSpace::kRec2020_Gamut, + }; + + skia_color_spaces.push_back((SkColorSpace::MakeSRGB())->makeColorSpin()); + + for (unsigned gamma_itr = 0; gamma_itr < 2; gamma_itr++) { + for (unsigned gamut_itr = 0; gamut_itr < 4; gamut_itr++) { + skia_color_spaces.push_back( + SkColorSpace::MakeRGB(gammas[gamma_itr], gamuts[gamut_itr])); + } + } + + std::vector<gfx::ColorSpace> gfx_color_spaces; + for (unsigned i = 0; i < skia_color_spaces.size(); i++) { + gfx::ColorSpace color_space = + SkColorSpaceToGfxColorSpace(skia_color_spaces[i]); + ASSERT_TRUE(SkColorSpace::Equals(color_space.ToSkColorSpace().get(), + skia_color_spaces[i].get())); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc index bafffea5..45048ff 100644 --- a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
@@ -60,10 +60,9 @@ if (!grcontext) return nullptr; // Can happen if the context is lost. - // TODO(crbug.com/782383): This can return a SkColorSpace, which should be - // passed along. + sk_sp<SkImage> sk_image = paint_image_.GetSkImage(); sk_sp<SkImage> gpu_skimage = - paint_image_.GetSkImage()->makeTextureImage(grcontext, nullptr); + sk_image->makeTextureImage(grcontext, sk_image->colorSpace()); if (!gpu_skimage) return nullptr;
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index a7fea929..140e6513 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -8,16 +8,14 @@ import("//testing/test.gni") declare_args() { - # Enables incremental marking in Oilpan. + # Build Blink with incremental marking infrastructure for Oilpan. # - # Note: Incremental marking is currently considered experimental and also - # enables 'enable_blink_heap_incremental_marking'. See default value below. - enable_blink_heap_incremental_marking = false -} + # To turn on incremental marking also use + # --enable-blink-features=HeapIncrementalMarking + enable_blink_heap_incremental_marking = true -declare_args() { # Enables heap verification. - enable_blink_heap_verification = enable_blink_heap_incremental_marking + enable_blink_heap_verification = false } buildflag_header("blink_heap_buildflags") {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 322d26b..54750ac 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -740,8 +740,8 @@ int64_t encoded_body_length = 0; base::Optional<int64_t> downloaded_file_length; WebBlobInfo downloaded_blob; - loader_->LoadSynchronously(this, request_in, response_out, error_out, - data_out, encoded_data_length, encoded_body_length, + loader_->LoadSynchronously(request_in, response_out, error_out, data_out, + encoded_data_length, encoded_body_length, downloaded_file_length, downloaded_blob); // A message dispatched while synchronously fetching the resource
diff --git a/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc b/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc index ccdce6fa..94509a72 100644 --- a/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc +++ b/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc
@@ -52,7 +52,7 @@ return base::TimeDelta(); // Makes DoWork post an immediate continuation. base::TimeDelta delay = next_run_time - now; - TRACE_EVENT1("renderer.scheduler", "RealTimeDomain::DelayTillNextTask", + TRACE_EVENT1("sequence_manager", "RealTimeDomain::DelayTillNextTask", "delay_ms", delay.InMillisecondsF()); // The next task is sometime in the future. DoWork will make sure it gets
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc index a0e553d..fe6a0aae 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc
@@ -7,12 +7,12 @@ #include <memory> #include <utility> +#include "base/strings/stringprintf.h" #include "base/time/time.h" #include "base/trace_event/blame_context.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" -#include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace blink { namespace scheduler { @@ -467,7 +467,7 @@ void TaskQueueImpl::TraceQueueSize() const { bool is_tracing; TRACE_EVENT_CATEGORY_GROUP_ENABLED( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), &is_tracing); + TRACE_DISABLED_BY_DEFAULT("sequence_manager"), &is_tracing); if (!is_tracing) return; @@ -477,7 +477,7 @@ return; base::AutoLock lock(immediate_incoming_queue_lock_); - TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), GetName(), + TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), GetName(), immediate_incoming_queue().size() + main_thread_only().immediate_work_queue->Size() + main_thread_only().delayed_work_queue->Size() + @@ -513,7 +513,10 @@ DCHECK(main_thread_only().delayed_work_queue); DCHECK(main_thread_only().immediate_work_queue); - state->SetString("task_queue_id", PointerToString(this)); + state->SetString( + "task_queue_id", + base::StringPrintf("0x%" PRIx64, static_cast<uint64_t>( + reinterpret_cast<uintptr_t>(this)))); state->SetBoolean("enabled", IsQueueEnabled()); state->SetString("time_domain_name", main_thread_only().time_domain->GetName()); @@ -539,7 +542,13 @@ "delayed_fence_seconds_from_now", (main_thread_only().delayed_fence.value() - now).InSecondsF()); } - if (AreVerboseSnapshotsEnabled()) { + + bool verbose = false; + TRACE_EVENT_CATEGORY_GROUP_ENABLED( + TRACE_DISABLED_BY_DEFAULT("sequence_manager.verbose_snapshots"), + &verbose); + + if (verbose) { state->BeginArray("immediate_incoming_queue"); QueueAsValueInto(immediate_incoming_queue(), now, state); state->EndArray();
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc index f89e700..7d4cb0f4 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc
@@ -65,9 +65,16 @@ weak_factory_(this) { // TODO(altimin): Create a sequence checker here. DCHECK(controller_->RunsTasksInCurrentSequence()); + + TRACE_EVENT_WARMUP_CATEGORY("sequence_manager"); + TRACE_EVENT_WARMUP_CATEGORY(TRACE_DISABLED_BY_DEFAULT("sequence_manager")); + TRACE_EVENT_WARMUP_CATEGORY( + TRACE_DISABLED_BY_DEFAULT("sequence_manager.debug")); + TRACE_EVENT_WARMUP_CATEGORY( + TRACE_DISABLED_BY_DEFAULT("sequence_manager.verbose_snapshots")); + TRACE_EVENT_OBJECT_CREATED_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", - this); + TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager", this); main_thread_only().selector.SetTaskQueueSelectorObserver(this); RegisterTimeDomain(main_thread_only().real_time_domain.get()); @@ -78,8 +85,7 @@ TaskQueueManagerImpl::~TaskQueueManagerImpl() { TRACE_EVENT_OBJECT_DELETED_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", - this); + TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager", this); // TODO(altimin): restore default task runner automatically when // ThreadController is destroyed. @@ -152,9 +158,8 @@ void TaskQueueManagerImpl::UnregisterTaskQueueImpl( std::unique_ptr<internal::TaskQueueImpl> task_queue) { - TRACE_EVENT1("renderer.scheduler", - "TaskQueueManagerImpl::UnregisterTaskQueue", "queue_name", - task_queue->GetName()); + TRACE_EVENT1("sequence_manager", "TaskQueueManagerImpl::UnregisterTaskQueue", + "queue_name", task_queue->GetName()); DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); main_thread_only().selector.RemoveQueue(task_queue.get()); @@ -185,7 +190,7 @@ } void TaskQueueManagerImpl::WakeUpReadyDelayedQueues(LazyNow* lazy_now) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManagerImpl::WakeUpReadyDelayedQueues"); for (TimeDomain* time_domain : main_thread_only().time_domains) { @@ -260,7 +265,7 @@ CHECK(Validate()); DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); - TRACE_EVENT0("renderer.scheduler", "TaskQueueManagerImpl::TakeTask"); + TRACE_EVENT0("sequence_manager", "TaskQueueManagerImpl::TakeTask"); IncomingImmediateWorkMap queues_to_reload; @@ -280,9 +285,8 @@ bool should_run = main_thread_only().selector.SelectWorkQueueToService(&work_queue); TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"), - "TaskQueueManager", this, - AsValueWithSelectorResult(should_run, work_queue)); + TRACE_DISABLED_BY_DEFAULT("sequence_manager.debug"), "TaskQueueManager", + this, AsValueWithSelectorResult(should_run, work_queue)); if (!should_run) return base::nullopt; @@ -371,7 +375,7 @@ void TaskQueueManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, LazyNow* time_before_task) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManagerImpl::NotifyWillProcessTaskObservers"); if (executing_task->task_queue->GetQuiescenceMonitored()) main_thread_only().task_was_run_on_quiescence_monitored_queue = true; @@ -385,14 +389,14 @@ if (executing_task->task_queue->GetShouldNotifyObservers()) { { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.WillProcessTaskObservers"); for (auto& observer : main_thread_only().task_observers) observer.WillProcessTask(executing_task->pending_task); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueNotifyWillProcessTask"); executing_task->task_queue->NotifyWillProcessTask( executing_task->pending_task); @@ -408,14 +412,14 @@ MonotonicTimeInSeconds(executing_task->task_start_time); { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.WillProcessTaskTimeObservers"); for (auto& observer : main_thread_only().task_time_observers) observer.WillProcessTask(task_start_time_sec); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueOnTaskStarted"); executing_task->task_queue->OnTaskStarted( executing_task->pending_task, executing_task->task_start_time); @@ -431,7 +435,7 @@ void TaskQueueManagerImpl::NotifyDidProcessTask( const ExecutingTask& executing_task, LazyNow* time_after_task) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManagerImpl::NotifyDidProcessTaskObservers"); base::ThreadTicks task_end_thread_time; @@ -448,28 +452,28 @@ if (task_start_time_sec) { task_end_time_sec = MonotonicTimeInSeconds(time_after_task->Now()); - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.DidProcessTaskTimeObservers"); for (auto& observer : main_thread_only().task_time_observers) observer.DidProcessTask(task_start_time_sec, task_end_time_sec); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.DidProcessTaskObservers"); for (auto& observer : main_thread_only().task_observers) observer.DidProcessTask(executing_task.pending_task); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueNotifyDidProcessTask"); executing_task.task_queue->NotifyDidProcessTask( executing_task.pending_task); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueOnTaskCompleted"); if (task_start_time_sec && task_end_time_sec) { executing_task.task_queue->OnTaskCompleted(
diff --git a/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc b/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc index 87c247e8..daa997dc 100644 --- a/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc
@@ -71,7 +71,7 @@ } any_sequence().immediate_do_work_posted = true; - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "ThreadControllerImpl::ScheduleWork::PostTask"); task_runner_->PostTask(FROM_HERE, immediate_do_work_closure_); } @@ -101,7 +101,7 @@ } base::TimeDelta delay = std::max(base::TimeDelta(), run_time - now); - TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "ThreadControllerImpl::ScheduleDelayedWork::PostDelayedTask", "delay_ms", delay.InMillisecondsF()); @@ -234,7 +234,7 @@ any_sequence().nesting_depth++; if (!any_sequence().immediate_do_work_posted) { any_sequence().immediate_do_work_posted = true; - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "ThreadControllerImpl::OnBeginNestedRunLoop::PostTask"); task_runner_->PostTask(FROM_HERE, immediate_do_work_closure_); }
diff --git a/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc b/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc index f78b06c36..b04cb85 100644 --- a/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc
@@ -3,8 +3,9 @@ // found in the LICENSE file. #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" -#include "base/test/simple_test_tick_clock.h" -#include "components/viz/test/ordered_simple_task_runner.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" @@ -84,12 +85,14 @@ class WorkerSchedulerProxyTest : public testing::Test { public: WorkerSchedulerProxyTest() - : mock_main_thread_task_runner_( - new cc::OrderedSimpleTaskRunner(&clock_, true)), + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED), main_thread_scheduler_(std::make_unique<MainThreadSchedulerImpl>( - TaskQueueManagerForTest::Create(nullptr, - mock_main_thread_task_runner_, - &clock_), + TaskQueueManagerForTest::Create( + nullptr, + base::ThreadTaskRunnerHandle::Get(), + task_environment_.GetMockTickClock()), base::nullopt)), page_scheduler_( std::make_unique<PageSchedulerImpl>(nullptr, @@ -97,7 +100,10 @@ false)), frame_scheduler_(page_scheduler_->CreateFrameSchedulerImpl( nullptr, - FrameScheduler::FrameType::kMainFrame)) {} + FrameScheduler::FrameType::kMainFrame)) { + // Null clock triggers some assertions. + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5)); + } ~WorkerSchedulerProxyTest() override { frame_scheduler_.reset(); @@ -106,9 +112,7 @@ } protected: - base::SimpleTestTickClock clock_; - scoped_refptr<cc::OrderedSimpleTaskRunner> mock_main_thread_task_runner_; - + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<MainThreadSchedulerImpl> main_thread_scheduler_; std::unique_ptr<PageSchedulerImpl> page_scheduler_; std::unique_ptr<FrameSchedulerImpl> frame_scheduler_; @@ -133,7 +137,7 @@ DCHECK(worker_thread->GetWorkerScheduler()->throttling_state() == FrameScheduler::ThrottlingState::kNotThrottled); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } // Tests below check that no crashes occur during different shutdown sequences. @@ -153,10 +157,10 @@ FrameScheduler::ThrottlingState::kThrottled); frame_scheduler_.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); worker_thread.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } TEST_F(WorkerSchedulerProxyTest, ThreadDestroyed) { @@ -174,13 +178,13 @@ FrameScheduler::ThrottlingState::kThrottled); worker_thread.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); page_scheduler_->SetPageVisible(true); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); frame_scheduler_.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } } // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc index 9aba100d8..7218bb1 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc
@@ -5,8 +5,9 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include <memory> -#include "base/test/simple_test_tick_clock.h" -#include "components/viz/test/ordered_simple_task_runner.h" +#include "base/run_loop.h" +#include "base/test/test_mock_time_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" @@ -26,19 +27,21 @@ ~AutoAdvancingVirtualTimeDomainTest() override = default; void SetUp() override { - clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); - - mock_task_runner_ = - base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false); - + test_task_runner_ = base::WrapRefCounted(new base::TestMockTimeTaskRunner( + base::TestMockTimeTaskRunner::Type::kBoundToThread)); + // A null clock triggers some assertions. + test_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMilliseconds(5)); scheduler_helper_.reset(new NonMainThreadSchedulerHelper( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), + TaskQueueManagerForTest::Create(nullptr, + base::ThreadTaskRunnerHandle::Get(), + test_task_runner_->GetMockTickClock()), nullptr)); scheduler_helper_->AddTaskTimeObserver(&test_task_time_observer_); task_queue_ = scheduler_helper_->DefaultWorkerTaskQueue(); initial_time_ = base::Time::FromJsTime(100000.0); - initial_time_ticks_ = clock_.NowTicks(); + initial_time_ticks_ = test_task_runner_->NowTicks(); auto_advancing_time_domain_.reset(new AutoAdvancingVirtualTimeDomain( initial_time_, initial_time_ticks_, scheduler_helper_.get(), AutoAdvancingVirtualTimeDomain::BaseTimeOverridePolicy::OVERRIDE)); @@ -51,10 +54,9 @@ scheduler_helper_->UnregisterTimeDomain(auto_advancing_time_domain_.get()); } + scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; base::Time initial_time_; base::TimeTicks initial_time_ticks_; - base::SimpleTestTickClock clock_; - scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; std::unique_ptr<NonMainThreadSchedulerHelper> scheduler_helper_; scoped_refptr<TaskQueue> task_queue_; std::unique_ptr<AutoAdvancingVirtualTimeDomain> auto_advancing_time_domain_; @@ -83,9 +85,9 @@ delay); EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced()); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); - EXPECT_EQ(initial_time_ticks_, clock_.NowTicks()); + EXPECT_EQ(initial_time_ticks_, test_task_runner_->NowTicks()); EXPECT_EQ(initial_time_ticks_ + delay, auto_advancing_time_domain_->CreateLazyNow().Now()); EXPECT_TRUE(task_run); @@ -105,9 +107,9 @@ auto_advancing_time_domain_->SetCanAdvanceVirtualTime(false); EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced()).Times(0); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); - EXPECT_EQ(initial_time_ticks_, clock_.NowTicks()); + EXPECT_EQ(initial_time_ticks_, test_task_runner_->NowTicks()); EXPECT_EQ(initial_time_ticks_, auto_advancing_time_domain_->CreateLazyNow().Now()); EXPECT_FALSE(task_run); @@ -145,7 +147,7 @@ base::BindOnce(DelayedTask, &count, &delayed_task_run_at_count), base::TimeDelta::FromMilliseconds(10)); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1000, count); EXPECT_EQ(102, delayed_task_run_at_count); @@ -164,7 +166,7 @@ base::BindOnce(DelayedTask, &count, &delayed_task_run_at_count), base::TimeDelta::FromMilliseconds(10)); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1000, count); // If the initial count had been higher, the delayed task could have been @@ -206,13 +208,13 @@ bool task_run = false; task_queue_->PostDelayedTask(FROM_HERE, base::BindOnce(NopTask, &task_run), delay); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(base::Time::Now(), initial_time + delay); } TEST_F(AutoAdvancingVirtualTimeDomainTest, BaseTimeTicksOverriden) { - base::TimeTicks initial_time = clock_.NowTicks(); + base::TimeTicks initial_time = test_task_runner_->NowTicks(); EXPECT_EQ(base::TimeTicks::Now(), initial_time); // Make time advance. @@ -220,14 +222,14 @@ bool task_run = false; task_queue_->PostDelayedTask(FROM_HERE, base::BindOnce(NopTask, &task_run), delay); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(base::TimeTicks::Now(), initial_time + delay); } TEST_F(AutoAdvancingVirtualTimeDomainTest, DelayTillNextTaskHandlesPastRunTime) { - base::TimeTicks initial_time = clock_.NowTicks(); + base::TimeTicks initial_time = test_task_runner_->NowTicks(); // Post a task for t+10ms. bool task_run = false;
diff --git a/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc b/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc index bf720bd..f24c423 100644 --- a/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc
@@ -17,14 +17,6 @@ const char kTracingCategoryNameDebug[] = TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"); -namespace { - -// No trace events should be created with this category. -const char kTracingCategoryNameVerboseSnapshots[] = - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.enable_verbose_snapshots"); - -} // namespace - namespace internal { void ValidateTracingCategory(const char* category) { @@ -40,19 +32,11 @@ } // namespace internal -bool AreVerboseSnapshotsEnabled() { - bool result = false; - TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTracingCategoryNameVerboseSnapshots, - &result); - return result; -} - void WarmupTracingCategories() { // No need to warm-up toplevel category here. TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameDefault); TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameInfo); TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameDebug); - TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameVerboseSnapshots); } std::string PointerToString(const void* pointer) {
diff --git a/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h b/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h index f9d4647..75e41431 100644 --- a/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h +++ b/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h
@@ -34,8 +34,6 @@ PLATFORM_EXPORT void WarmupTracingCategories(); -PLATFORM_EXPORT bool AreVerboseSnapshotsEnabled(); - PLATFORM_EXPORT std::string PointerToString(const void* pointer); PLATFORM_EXPORT double TimeDeltaToMilliseconds(const base::TimeDelta& value);
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar.cc b/third_party/blink/renderer/platform/scroll/scrollbar.cc index ffca17f..8c24190 100644 --- a/third_party/blink/renderer/platform/scroll/scrollbar.cc +++ b/third_party/blink/renderer/platform/scroll/scrollbar.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/public/platform/web_gesture_event.h" #include "third_party/blink/public/platform/web_mouse_event.h" #include "third_party/blink/public/platform/web_scrollbar.h" +#include "third_party/blink/public/platform/web_scrollbar_overlay_color_theme.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/platform_chrome_client.h" @@ -644,25 +645,6 @@ STATIC_ASSERT_ENUM(WebScrollbar::kHorizontal, kHorizontalScrollbar); STATIC_ASSERT_ENUM(WebScrollbar::kVertical, kVerticalScrollbar); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByLine, kScrollByLine); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByPage, kScrollByPage); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByDocument, kScrollByDocument); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByPixel, kScrollByPixel); - -STATIC_ASSERT_ENUM(WebScrollbar::kRegularScrollbar, kRegularScrollbar); -STATIC_ASSERT_ENUM(WebScrollbar::kSmallScrollbar, kSmallScrollbar); -STATIC_ASSERT_ENUM(WebScrollbar::kNoPart, kNoPart); -STATIC_ASSERT_ENUM(WebScrollbar::kBackButtonStartPart, kBackButtonStartPart); -STATIC_ASSERT_ENUM(WebScrollbar::kForwardButtonStartPart, - kForwardButtonStartPart); -STATIC_ASSERT_ENUM(WebScrollbar::kBackTrackPart, kBackTrackPart); -STATIC_ASSERT_ENUM(WebScrollbar::kThumbPart, kThumbPart); -STATIC_ASSERT_ENUM(WebScrollbar::kForwardTrackPart, kForwardTrackPart); -STATIC_ASSERT_ENUM(WebScrollbar::kBackButtonEndPart, kBackButtonEndPart); -STATIC_ASSERT_ENUM(WebScrollbar::kForwardButtonEndPart, kForwardButtonEndPart); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollbarBGPart, kScrollbarBGPart); -STATIC_ASSERT_ENUM(WebScrollbar::kTrackBGPart, kTrackBGPart); -STATIC_ASSERT_ENUM(WebScrollbar::kAllParts, kAllParts); STATIC_ASSERT_ENUM(kWebScrollbarOverlayColorThemeDark, kScrollbarOverlayColorThemeDark); STATIC_ASSERT_ENUM(kWebScrollbarOverlayColorThemeLight,
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc b/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc index f1a65fc..9f51af6e 100644 --- a/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc +++ b/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc
@@ -7,22 +7,43 @@ #include "third_party/blink/public/platform/web_point.h" #include "third_party/blink/public/platform/web_rect.h" #include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_geometry.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" +#include "third_party/blink/renderer/platform/scroll/scroll_types.h" +#include "third_party/blink/renderer/platform/scroll/scrollbar.h" +#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" +#include "ui/gfx/skia_util.h" namespace blink { -ScrollbarLayerDelegate::ScrollbarLayerDelegate( - std::unique_ptr<WebScrollbar> scrollbar, - WebScrollbarThemePainter painter, - std::unique_ptr<WebScrollbarThemeGeometry> geometry) - : scrollbar_(std::move(scrollbar)), - painter_(painter), - geometry_(std::move(geometry)) {} +namespace { + +class ScopedScrollbarPainter { + public: + ScopedScrollbarPainter(cc::PaintCanvas& canvas, float device_scale_factor) + : canvas_(canvas) { + builder_.Context().SetDeviceScaleFactor(device_scale_factor); + } + ~ScopedScrollbarPainter() { canvas_.drawPicture(builder_.EndRecording()); } + + GraphicsContext& Context() { return builder_.Context(); } + + private: + cc::PaintCanvas& canvas_; + PaintRecordBuilder builder_; +}; + +} // namespace + +ScrollbarLayerDelegate::ScrollbarLayerDelegate(blink::Scrollbar& scrollbar, + float device_scale_factor) + : scrollbar_(&scrollbar), + theme_(scrollbar.GetTheme()), + device_scale_factor_(device_scale_factor) {} ScrollbarLayerDelegate::~ScrollbarLayerDelegate() = default; cc::ScrollbarOrientation ScrollbarLayerDelegate::Orientation() const { - if (scrollbar_->GetOrientation() == WebScrollbar::kHorizontal) + if (scrollbar_->Orientation() == kHorizontalScrollbar) return cc::HORIZONTAL; return cc::VERTICAL; } @@ -32,109 +53,122 @@ } bool ScrollbarLayerDelegate::HasThumb() const { - return geometry_->HasThumb(scrollbar_.get()); + return theme_.HasThumb(*scrollbar_); } bool ScrollbarLayerDelegate::IsOverlay() const { - return scrollbar_->IsOverlay(); + return scrollbar_->IsOverlayScrollbar(); } gfx::Point ScrollbarLayerDelegate::Location() const { - return static_cast<gfx::Point>(scrollbar_->Location()); + return scrollbar_->Location(); } int ScrollbarLayerDelegate::ThumbThickness() const { - auto thumb_rect = - static_cast<gfx::Rect>(geometry_->ThumbRect(scrollbar_.get())); - if (scrollbar_->GetOrientation() == WebScrollbar::kHorizontal) - return thumb_rect.height(); - return thumb_rect.width(); + IntRect thumb_rect = theme_.ThumbRect(*scrollbar_); + if (scrollbar_->Orientation() == kHorizontalScrollbar) + return thumb_rect.Height(); + return thumb_rect.Width(); } int ScrollbarLayerDelegate::ThumbLength() const { - auto thumb_rect = - static_cast<gfx::Rect>(geometry_->ThumbRect(scrollbar_.get())); - if (scrollbar_->GetOrientation() == WebScrollbar::kHorizontal) - return thumb_rect.width(); - return thumb_rect.height(); + IntRect thumb_rect = theme_.ThumbRect(*scrollbar_); + if (scrollbar_->Orientation() == kHorizontalScrollbar) + return thumb_rect.Width(); + return thumb_rect.Height(); } gfx::Rect ScrollbarLayerDelegate::TrackRect() const { - return static_cast<gfx::Rect>(geometry_->TrackRect(scrollbar_.get())); + return theme_.TrackRect(*scrollbar_); } float ScrollbarLayerDelegate::ThumbOpacity() const { - return painter_.ThumbOpacity(); + return theme_.ThumbOpacity(*scrollbar_); } bool ScrollbarLayerDelegate::NeedsPaintPart(cc::ScrollbarPart part) const { if (part == cc::THUMB) - return painter_.ThumbNeedsRepaint(); - return painter_.TrackNeedsRepaint(); + return scrollbar_->ThumbNeedsRepaint(); + return scrollbar_->TrackNeedsRepaint(); } bool ScrollbarLayerDelegate::UsesNinePatchThumbResource() const { - return painter_.UsesNinePatchThumbResource(); + return theme_.UsesNinePatchThumbResource(); } gfx::Size ScrollbarLayerDelegate::NinePatchThumbCanvasSize() const { - return static_cast<gfx::Size>( - geometry_->NinePatchThumbCanvasSize(scrollbar_.get())); + DCHECK(theme_.UsesNinePatchThumbResource()); + return static_cast<gfx::Size>(theme_.NinePatchThumbCanvasSize(*scrollbar_)); } gfx::Rect ScrollbarLayerDelegate::NinePatchThumbAperture() const { - return static_cast<gfx::Rect>( - geometry_->NinePatchThumbAperture(scrollbar_.get())); + DCHECK(theme_.UsesNinePatchThumbResource()); + return theme_.NinePatchThumbAperture(*scrollbar_); } bool ScrollbarLayerDelegate::HasTickmarks() const { - return scrollbar_->HasTickmarks(); + Vector<IntRect> tickmarks; + scrollbar_->GetTickmarks(tickmarks); + return !tickmarks.IsEmpty(); } void ScrollbarLayerDelegate::PaintPart(cc::PaintCanvas* canvas, cc::ScrollbarPart part, const gfx::Rect& content_rect) { + PaintCanvasAutoRestore auto_restore(canvas, true); + blink::Scrollbar& scrollbar = *scrollbar_; + if (part == cc::THUMB) { - painter_.PaintThumb(canvas, WebRect(content_rect)); + ScopedScrollbarPainter painter(*canvas, device_scale_factor_); + theme_.PaintThumb(painter.Context(), scrollbar, IntRect(content_rect)); + if (!theme_.ShouldRepaintAllPartsOnInvalidation()) + scrollbar.ClearThumbNeedsRepaint(); return; } if (part == cc::TICKMARKS) { - painter_.PaintTickmarks(canvas, WebRect(content_rect)); + ScopedScrollbarPainter painter(*canvas, device_scale_factor_); + theme_.PaintTickmarks(painter.Context(), scrollbar, IntRect(content_rect)); return; } - // The following is a simplification of ScrollbarThemeComposite::paint. - painter_.PaintScrollbarBackground(canvas, WebRect(content_rect)); + canvas->clipRect(gfx::RectToSkRect(content_rect)); + ScopedScrollbarPainter painter(*canvas, device_scale_factor_); + GraphicsContext& context = painter.Context(); - if (geometry_->HasButtons(scrollbar_.get())) { - WebRect back_button_start_paint_rect = - geometry_->BackButtonStartRect(scrollbar_.get()); - painter_.PaintBackButtonStart(canvas, back_button_start_paint_rect); + theme_.PaintScrollbarBackground(context, scrollbar); - WebRect back_button_end_paint_rect = - geometry_->BackButtonEndRect(scrollbar_.get()); - painter_.PaintBackButtonEnd(canvas, back_button_end_paint_rect); - - WebRect forward_button_start_paint_rect = - geometry_->ForwardButtonStartRect(scrollbar_.get()); - painter_.PaintForwardButtonStart(canvas, forward_button_start_paint_rect); - - WebRect forward_button_end_paint_rect = - geometry_->ForwardButtonEndRect(scrollbar_.get()); - painter_.PaintForwardButtonEnd(canvas, forward_button_end_paint_rect); + if (theme_.HasButtons(scrollbar)) { + theme_.PaintButton(context, scrollbar, + theme_.BackButtonRect(scrollbar, kBackButtonStartPart), + kBackButtonStartPart); + theme_.PaintButton(context, scrollbar, + theme_.BackButtonRect(scrollbar, kBackButtonEndPart), + kBackButtonEndPart); + theme_.PaintButton( + context, scrollbar, + theme_.ForwardButtonRect(scrollbar, kForwardButtonStartPart), + kForwardButtonStartPart); + theme_.PaintButton( + context, scrollbar, + theme_.ForwardButtonRect(scrollbar, kForwardButtonEndPart), + kForwardButtonEndPart); } - WebRect track_paint_rect = geometry_->TrackRect(scrollbar_.get()); - painter_.PaintTrackBackground(canvas, track_paint_rect); + IntRect track_paint_rect = theme_.TrackRect(scrollbar); + theme_.PaintTrackBackground(context, scrollbar, track_paint_rect); - bool thumb_present = geometry_->HasThumb(scrollbar_.get()); - if (thumb_present) { - painter_.PaintForwardTrackPart(canvas, track_paint_rect); - painter_.PaintBackTrackPart(canvas, track_paint_rect); + if (theme_.HasThumb(scrollbar)) { + theme_.PaintTrackPiece(painter.Context(), scrollbar, track_paint_rect, + kForwardTrackPart); + theme_.PaintTrackPiece(painter.Context(), scrollbar, track_paint_rect, + kBackTrackPart); } - painter_.PaintTickmarks(canvas, track_paint_rect); + theme_.PaintTickmarks(painter.Context(), scrollbar, track_paint_rect); + + if (!theme_.ShouldRepaintAllPartsOnInvalidation()) + scrollbar.ClearTrackNeedsRepaint(); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h b/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h index e3a016b..819ce5bd 100644 --- a/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h +++ b/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h
@@ -10,20 +10,20 @@ #include "base/macros.h" #include "cc/input/scrollbar.h" #include "cc/paint/paint_canvas.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_painter.h" +#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink { -class WebScrollbar; -class WebScrollbarThemeGeometry; + +class Scrollbar; +class ScrollbarTheme; // Implementation of cc::Scrollbar, providing a delegate to query about // scrollbar state and to paint the image in the scrollbar. class PLATFORM_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar { public: - ScrollbarLayerDelegate(std::unique_ptr<WebScrollbar> scrollbar, - WebScrollbarThemePainter painter, - std::unique_ptr<WebScrollbarThemeGeometry> geometry); + ScrollbarLayerDelegate(blink::Scrollbar& scrollbar, + float device_scale_factor); ~ScrollbarLayerDelegate() override; // cc::Scrollbar implementation. @@ -47,9 +47,12 @@ gfx::Rect NinePatchThumbAperture() const override; private: - std::unique_ptr<WebScrollbar> scrollbar_; - WebScrollbarThemePainter painter_; - std::unique_ptr<WebScrollbarThemeGeometry> geometry_; + // Accessed by main and compositor threads, e.g., the compositor thread + // checks |Orientation()|. + CrossThreadPersistent<blink::Scrollbar> scrollbar_; + + ScrollbarTheme& theme_; + float device_scale_factor_; DISALLOW_COPY_AND_ASSIGN(ScrollbarLayerDelegate); };
diff --git a/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc b/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc index fdf8d3a0..e62fb94 100644 --- a/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc +++ b/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
@@ -104,7 +104,6 @@ } void WebURLLoaderMock::LoadSynchronously( - WebURLLoaderClient* client, const WebURLRequest& request, WebURLResponse& response, base::Optional<WebURLError>& error, @@ -120,7 +119,7 @@ } AssertFallbackLoaderAvailability(request.Url(), default_loader_.get()); using_default_loader_ = true; - default_loader_->LoadSynchronously(client, request, response, error, data, + default_loader_->LoadSynchronously(request, response, error, data, encoded_data_length, encoded_body_length, downloaded_file_length, downloaded_blob); }
diff --git a/third_party/blink/renderer/platform/testing/weburl_loader_mock.h b/third_party/blink/renderer/platform/testing/weburl_loader_mock.h index 7d60dc4c..4907c05 100644 --- a/third_party/blink/renderer/platform/testing/weburl_loader_mock.h +++ b/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
@@ -45,8 +45,7 @@ const WebURLResponse& redirect_response); // WebURLLoader methods: - void LoadSynchronously(WebURLLoaderClient*, - const WebURLRequest&, + void LoadSynchronously(const WebURLRequest&, WebURLResponse&, base::Optional<WebURLError>&, WebData&,
diff --git a/third_party/fuchsia-sdk/fidl_library.gni b/third_party/fuchsia-sdk/fidl_library.gni index 1dd93e0..2cdec6e 100644 --- a/third_party/fuchsia-sdk/fidl_library.gni +++ b/third_party/fuchsia-sdk/fidl_library.gni
@@ -4,18 +4,6 @@ assert(is_fuchsia) -# Template for FIDL libraries. Following parameters can be passed when -# instantiating these templates: -# sources - List of .fidl files. -# name - (optional) Name of the library. Must match the name specified -# in the .fidl files. target_name is used if name is not specified -# explicitly. -# deps - (optional) List of other fild_library() targets that this FIDL -# library depends on. -# namespace - (optional) Namespace for generated code. All classes in the -# generated code are placed under <namespace>::<name>:: namespace. -# 'fuchsia' namespace is used by default. -# template("fidl_library") { pkg_name = target_name @@ -24,16 +12,10 @@ pkg_name = invoker.name } - namespace = "fuchsia" - if (defined(invoker.namespace)) { - namespace = invoker.namespace - } - response_file = "$target_gen_dir/$target_name.rsp" json_representation = "$target_gen_dir/$pkg_name.fidl.json" output_gen_base = "$target_gen_dir/fidl" output_gen_dir = "$output_gen_base/fuchsia/cpp" - output_gen_dir_no_ns = "$output_gen_base/no_ns/fuchsia/cpp" tables_file = "$output_gen_base/$pkg_name.fidl-tables.cc" action("${target_name}_response_file") { @@ -125,7 +107,7 @@ } action("${target_name}_cpp_gen") { - visibility = [ ":${invoker.target_name}_update_namespace" ] + visibility = [ ":${invoker.target_name}" ] deps = [ ":${invoker.target_name}_compile", @@ -136,8 +118,8 @@ ] outputs = [ - "${output_gen_dir_no_ns}/${pkg_name}.h", - "${output_gen_dir_no_ns}/${pkg_name}.cc", + "$output_gen_dir/$pkg_name.h", + "$output_gen_dir/$pkg_name.cc", ] script = "//build/gn_run_binary.py" @@ -149,37 +131,9 @@ "-json", rebase_path("$json_representation"), "-include-base", - rebase_path("$output_gen_base/no_ns"), + rebase_path("$output_gen_base"), "-output-base", - rebase_path("${output_gen_dir_no_ns}/${pkg_name}"), - ] - } - - # Move generated code to a different namespace to avoid conflicts with - # existing code in chromium. - # TODO(sergeyu): Remove this once FIDL-160 is resolved in Fuchsia. - action_foreach("${target_name}_update_namespace") { - visibility = [ ":${invoker.target_name}" ] - - deps = [ - ":${invoker.target_name}_cpp_gen", - ] - - sources = [ - "${output_gen_dir_no_ns}/${pkg_name}.cc", - "${output_gen_dir_no_ns}/${pkg_name}.h", - ] - - outputs = [ - "${output_gen_dir}/{{source_file_part}}", - ] - - script = "//third_party/fuchsia-sdk/update_namespace.py" - args = [ - namespace, - pkg_name, - "{{source}}", - rebase_path("${output_gen_dir}/{{source_file_part}}"), + rebase_path("$output_gen_dir/$pkg_name"), ] } @@ -208,7 +162,7 @@ } deps += [ ":${invoker.target_name}_compile", - ":${invoker.target_name}_update_namespace", + ":${invoker.target_name}_cpp_gen", ] if (!defined(public_deps)) {
diff --git a/third_party/fuchsia-sdk/update_namespace.py b/third_party/fuchsia-sdk/update_namespace.py deleted file mode 100755 index 8af1300..0000000 --- a/third_party/fuchsia-sdk/update_namespace.py +++ /dev/null
@@ -1,39 +0,0 @@ -#!/usr/bin/env python -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Helper script used to update namespace in C++ files generated by fidlgen. This -# is necessary to avoid naming conflicts with existing code in chromium. For -# example ui::Event FIDL interface collides with ui::Event class in chromium. -# This script moves it to fuchsia::ui::Event. -# -# TODO(sergeyu): Remove this script once FIDL files in fuchsia are updated to -# use fuchsia namespace. - -import sys -import re - -def main(namespace, libname, input_file, output_file): - with open(input_file) as f: - text = f.read() - - text = re.sub(r'^namespace\ %s\ \{$' % libname, - r'namespace %s {\nnamespace %s {' % - (namespace, libname), - text, flags=re.MULTILINE) - - text = re.sub(r'}\ \ // namespace\ %s$' % libname, - r'} // namespace %s\n} // namespace %s' - % (libname, namespace), - text, flags=re.MULTILINE) - - text = re.sub(r'(?<![a-z0-9_])%s::' % libname, - r'%s::%s::' % (namespace, libname), - text) - - with open(output_file, "w") as f: - f.write(text) - -if __name__ == "__main__": - sys.exit(main(*sys.argv[1:]))
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json index ca3c042..856ef054 100644 --- a/third_party/polymer/v1_0/bower.json +++ b/third_party/polymer/v1_0/bower.json
@@ -49,7 +49,6 @@ "paper-spinner": "PolymerElements/paper-spinner#2.0.0", "paper-styles": "PolymerElements/paper-styles#2.1.0", "paper-tabs": "PolymerElements/paper-tabs#2.0.0", - "paper-toggle-button": "PolymerElements/paper-toggle-button#2.0.0", "paper-tooltip": "PolymerElements/paper-tooltip#2.0.0", "polymer": "Polymer/polymer#1.11.2", "web-animations-js": "web-animations/web-animations-js#2.2.2"
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/BUILD.gn b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/BUILD.gn deleted file mode 100644 index 27e126e..0000000 --- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/BUILD.gn +++ /dev/null
@@ -1,13 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# NOTE: Created with generate_gn.py, please do not edit. - -import("//third_party/closure_compiler/compile_js.gni") - -js_library("paper-toggle-button-extracted") { - deps = [ - "../paper-behaviors:paper-checked-element-behavior-extracted", - ] -}
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json deleted file mode 100644 index ec1aad1..0000000 --- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json +++ /dev/null
@@ -1,61 +0,0 @@ -{ - "name": "paper-toggle-button", - "version": "2.0.0", - "description": "A material design toggle button control", - "authors": [ - "The Polymer Authors" - ], - "keywords": [ - "web-components", - "polymer", - "toggle", - "control" - ], - "private": true, - "repository": { - "type": "git", - "url": "git://github.com/PolymerElements/paper-toggle-button" - }, - "license": "http://polymer.github.io/LICENSE.txt", - "homepage": "https://github.com/PolymerElements/paper-toggle-button", - "main": "paper-toggle-button.html", - "ignore": [], - "dependencies": { - "polymer": "Polymer/polymer#1.9 - 2", - "iron-checked-element-behavior": "PolymerElements/iron-checked-element-behavior#1 - 2", - "paper-behaviors": "PolymerElements/paper-behaviors#1 - 2", - "paper-styles": "PolymerElements/paper-styles#1 - 2" - }, - "devDependencies": { - "iron-component-page": "PolymerElements/iron-component-page#1 - 2", - "iron-demo-helpers": "PolymerElements/iron-demo-helpers#1 - 2", - "iron-flex-layout": "PolymerElements/iron-flex-layout#1 - 2", - "iron-test-helpers": "PolymerElements/iron-test-helpers#1 - 2", - "web-component-tester": "^6.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" - }, - "variants": { - "1.x": { - "dependencies": { - "polymer": "Polymer/polymer#^1.9", - "iron-checked-element-behavior": "PolymerElements/iron-checked-element-behavior#^1.0.0", - "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0", - "paper-styles": "PolymerElements/paper-styles#^1.1.0" - }, - "devDependencies": { - "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", - "iron-demo-helpers": "PolymerElements/iron-demo-helpers#^1.0.0", - "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0", - "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0", - "web-component-tester": "^4.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" - }, - "resolutions": { - "webcomponentsjs": "^0.7" - } - } - }, - "resolutions": { - "webcomponentsjs": "^1.0.0" - } -}
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/compiled_resources2.gyp b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/compiled_resources2.gyp deleted file mode 100644 index a383b61..0000000 --- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/compiled_resources2.gyp +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# NOTE: Created with generate_compiled_resources_gyp.py, please do not edit. -{ - 'targets': [ - { - 'target_name': 'paper-toggle-button-extracted', - 'dependencies': [ - '../paper-behaviors/compiled_resources2.gyp:paper-checked-element-behavior-extracted', - ], - 'includes': ['../../../../closure_compiler/compile_js2.gypi'], - }, - ], -}
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js deleted file mode 100644 index c36b2f8..0000000 --- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js +++ /dev/null
@@ -1,81 +0,0 @@ -Polymer({ - is: 'paper-toggle-button', - - behaviors: [ - Polymer.PaperCheckedElementBehavior - ], - - hostAttributes: { - role: 'button', - 'aria-pressed': 'false', - tabindex: 0 - }, - - properties: { - /** - * Fired when the checked state changes due to user interaction. - * - * @event change - */ - /** - * Fired when the checked state changes. - * - * @event iron-change - */ - }, - - listeners: { - track: '_ontrack' - }, - - attached: function() { - Polymer.RenderStatus.afterNextRender(this, function() { - Polymer.Gestures.setTouchAction(this, 'pan-y'); - }); - }, - - _ontrack: function(event) { - var track = event.detail; - if (track.state === 'start') { - this._trackStart(track); - } else if (track.state === 'track') { - this._trackMove(track); - } else if (track.state === 'end') { - this._trackEnd(track); - } - }, - - _trackStart: function(track) { - this._width = this.$.toggleBar.offsetWidth / 2; - /* - * keep an track-only check state to keep the dragging behavior smooth - * while toggling activations - */ - this._trackChecked = this.checked; - this.$.toggleButton.classList.add('dragging'); - }, - - _trackMove: function(track) { - var dx = track.dx; - this._x = Math.min(this._width, - Math.max(0, this._trackChecked ? this._width + dx : dx)); - this.translate3d(this._x + 'px', 0, 0, this.$.toggleButton); - this._userActivate(this._x > (this._width / 2)); - }, - - _trackEnd: function(track) { - this.$.toggleButton.classList.remove('dragging'); - this.transform('', this.$.toggleButton); - }, - - // customize the element's ripple - _createRipple: function() { - this._rippleContainer = this.$.toggleButton; - var ripple = Polymer.PaperRippleBehavior._createRipple(); - ripple.id = 'ink'; - ripple.setAttribute('recenters', ''); - ripple.classList.add('circle', 'toggle-ink'); - return ripple; - } - - }); \ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html deleted file mode 100644 index 496e6c14..0000000 --- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html +++ /dev/null
@@ -1,200 +0,0 @@ -<!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---><html><head><link rel="import" href="../polymer/polymer.html"> -<link rel="import" href="../iron-flex-layout/iron-flex-layout.html"> -<link rel="import" href="../paper-styles/color.html"> -<link rel="import" href="../paper-styles/default-theme.html"> -<link rel="import" href="../paper-behaviors/paper-checked-element-behavior.html"> - -<!-- -Material design: [Switch](https://www.google.com/design/spec/components/selection-controls.html#selection-controls-switch) - -`paper-toggle-button` provides a ON/OFF switch that user can toggle the state -by tapping or by dragging the switch. - -Example: - - <paper-toggle-button></paper-toggle-button> - -### Styling - -The following custom properties and mixins are available for styling: - -Custom property | Description | Default -----------------|-------------|---------- -`--paper-toggle-button-unchecked-bar-color` | Slider color when the input is not checked | `#000000` -`--paper-toggle-button-unchecked-button-color` | Button color when the input is not checked | `--paper-grey-50` -`--paper-toggle-button-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--dark-primary-color` -`--paper-toggle-button-checked-bar-color` | Slider button color when the input is checked | `--primary-color` -`--paper-toggle-button-checked-button-color` | Button color when the input is checked | `--primary-color` -`--paper-toggle-button-checked-ink-color` | Selected/focus ripple color when the input is checked | `--primary-color` -`--paper-toggle-button-invalid-bar-color` | Slider button color when the input is invalid | `--error-color` -`--paper-toggle-button-invalid-button-color` | Button color when the input is invalid | `--error-color` -`--paper-toggle-button-invalid-ink-color` | Selected/focus ripple color when the input is invalid | `--error-color` -`--paper-toggle-button-unchecked-bar` | Mixin applied to the slider when the input is not checked | `{}` -`--paper-toggle-button-unchecked-button` | Mixin applied to the slider button when the input is not checked | `{}` -`--paper-toggle-button-unchecked-ink` | Mixin applied to the ripple when the input is not checked | `{}` -`--paper-toggle-button-checked-bar` | Mixin applied to the slider when the input is checked | `{}` -`--paper-toggle-button-checked-button` | Mixin applied to the slider button when the input is checked | `{}` -`--paper-toggle-button-checked-ink` | Mixin applied to the ripple when the input is checked | `{}` -`--paper-toggle-button-label-color` | Label color | `--primary-text-color` -`--paper-toggle-button-label-spacing` | Spacing between the label and the button | `8px` - -This element applies the mixin `--paper-font-common-base` but does not import `paper-styles/typography.html`. -In order to apply the `Roboto` font to this element, make sure you've imported `paper-styles/typography.html`. - -@group Paper Elements -@element paper-toggle-button -@hero hero.svg -@demo demo/index.html ---> - -</head><body><dom-module id="paper-toggle-button"> - <template strip-whitespace=""> - - <style> - :host { - display: inline-block; - @apply --layout-horizontal; - @apply --layout-center; - @apply --paper-font-common-base; - } - - :host([disabled]) { - pointer-events: none; - } - - :host(:focus) { - outline:none; - } - - .toggle-bar { - position: absolute; - height: 100%; - width: 100%; - border-radius: 8px; - pointer-events: none; - opacity: 0.4; - transition: background-color linear .08s; - background-color: var(--paper-toggle-button-unchecked-bar-color, #000000); - - @apply --paper-toggle-button-unchecked-bar; - } - - .toggle-button { - position: absolute; - top: -3px; - left: 0; - height: 20px; - width: 20px; - border-radius: 50%; - box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6); - transition: transform linear .08s, background-color linear .08s; - will-change: transform; - background-color: var(--paper-toggle-button-unchecked-button-color, var(--paper-grey-50)); - - @apply --paper-toggle-button-unchecked-button; - } - - .toggle-button.dragging { - transition: none; - } - - :host([checked]:not([disabled])) .toggle-bar { - opacity: 0.5; - background-color: var(--paper-toggle-button-checked-bar-color, var(--primary-color)); - - @apply --paper-toggle-button-checked-bar; - } - - :host([disabled]) .toggle-bar { - background-color: #000; - opacity: 0.12; - } - - :host([checked]) .toggle-button { - transform: translate(16px, 0); - } - - :host([checked]:not([disabled])) .toggle-button { - background-color: var(--paper-toggle-button-checked-button-color, var(--primary-color)); - - @apply --paper-toggle-button-checked-button; - } - - :host([disabled]) .toggle-button { - background-color: #bdbdbd; - opacity: 1; - } - - .toggle-ink { - position: absolute; - top: -14px; - left: -14px; - right: auto; - bottom: auto; - width: 48px; - height: 48px; - opacity: 0.5; - pointer-events: none; - color: var(--paper-toggle-button-unchecked-ink-color, var(--primary-text-color)); - - @apply --paper-toggle-button-unchecked-ink; - } - - :host([checked]) .toggle-ink { - color: var(--paper-toggle-button-checked-ink-color, var(--primary-color)); - - @apply --paper-toggle-button-checked-ink; - } - - .toggle-container { - display: inline-block; - position: relative; - width: 36px; - height: 14px; - /* The toggle button has an absolute position of -3px; The extra 1px - /* accounts for the toggle button shadow box. */ - margin: 4px 1px; - } - - .toggle-label { - position: relative; - display: inline-block; - vertical-align: middle; - padding-left: var(--paper-toggle-button-label-spacing, 8px); - pointer-events: none; - color: var(--paper-toggle-button-label-color, var(--primary-text-color)); - } - - /* invalid state */ - :host([invalid]) .toggle-bar { - background-color: var(--paper-toggle-button-invalid-bar-color, var(--error-color)); - } - - :host([invalid]) .toggle-button { - background-color: var(--paper-toggle-button-invalid-button-color, var(--error-color)); - } - - :host([invalid]) .toggle-ink { - color: var(--paper-toggle-button-invalid-ink-color, var(--error-color)); - } - </style> - - <div class="toggle-container"> - <div id="toggleBar" class="toggle-bar"></div> - <div id="toggleButton" class="toggle-button"></div> - </div> - - <div class="toggle-label"><slot></slot></div> - - </template> - - </dom-module> -<script src="paper-toggle-button-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/tools/check_grd_for_unused_strings.py b/tools/check_grd_for_unused_strings.py index 2defb2f..d997db6 100755 --- a/tools/check_grd_for_unused_strings.py +++ b/tools/check_grd_for_unused_strings.py
@@ -137,6 +137,7 @@ ui_chromeos_dir = os.path.join(ui_dir, 'chromeos') grd_files = [ os.path.join(ash_base_dir, 'ash_strings.grd'), + os.path.join(ash_base_dir, 'resources', 'ash_resources.grd'), os.path.join(ash_components_dir, 'ash_components_strings.grd'), os.path.join(ash_components_dir, 'resources', 'ash_components_resources.grd'),
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py index 71957a1..d95a129 100755 --- a/tools/code_coverage/coverage.py +++ b/tools/code_coverage/coverage.py
@@ -207,16 +207,18 @@ self._table_entries = [] self._total_entry = {} - template_dir = os.path.join( - os.path.dirname(os.path.realpath(__file__)), 'html_templates') + + source_dir = os.path.dirname(os.path.realpath(__file__)) + template_dir = os.path.join(source_dir, 'html_templates') jinja_env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_dir), trim_blocks=True) self._header_template = jinja_env.get_template('header.html') self._table_template = jinja_env.get_template('table.html') self._footer_template = jinja_env.get_template('footer.html') + self._style_overrides = open( - os.path.join(template_dir, 'style_overrides.css')).read() + os.path.join(source_dir, 'static', 'css', 'style.css')).read() def AddLinkToAnotherReport(self, html_report_path, name, summary): """Adds a link to another html report in this report.
diff --git a/tools/code_coverage/html_templates/style_overrides.css b/tools/code_coverage/static/css/style.css similarity index 100% rename from tools/code_coverage/html_templates/style_overrides.css rename to tools/code_coverage/static/css/style.css
diff --git a/tools/code_coverage/test_suite.txt b/tools/code_coverage/test_suite.txt new file mode 100644 index 0000000..1aac6a0 --- /dev/null +++ b/tools/code_coverage/test_suite.txt
@@ -0,0 +1,81 @@ +accessibility_unittests +angle_unittests +app_shell_unittests +audio_unittests +aura_unittests +base_unittests +battor_agent_unittests +blink_common_unittests +blink_heap_unittests +blink_platform_unittests +boringssl_crypto_tests +boringssl_ssl_tests +breakpad_unittests +browser_tests +cacheinvalidation_unittests +capture_unittests +cast_unittests +cc_blink_unittests +cc_unittests +chrome_app_unittests +components_browsertests +components_unittests +compositor_unittests +content_browsertests +content_unittests +courgette_unittests +crypto_unittests +dbus_unittests +device_unittests +display_unittests +events_unittests +extensions_browsertests +filesystem_service_unittests +gcm_unit_tests +gfx_unittests +gin_unittests +gl_unittests +gn_unittests +google_apis_unittests +gpu_unittests +headless_browsertests +headless_unittests +interactive_ui_tests +ipc_tests +jingle_unittests +keyboard_unittests +leveldb_service_unittests +libjingle_xmpp_unittests +media_blink_unittests +media_mojo_unittests +media_service_unittests +media_unittests +midi_unittests +nacl_loader_unittests +native_theme_unittests +net_unittests +pdf_unittests +pdfium_unittests +ppapi_unittests +printing_unittests +remoting_unittests +sandbox_linux_unittests +service_manager_unittests +services_unittests +skia_unittests +snapshot_unittests +sql_unittests +storage_unittests +swiftshader_unittests +sync_integration_tests +traffic_annotation_auditor_unittests +ui_base_unittests +ui_touch_selection_unittests +unit_tests +url_unittests +views_unittests +viz_unittests +vr_common_unittests +webkit_unit_tests +wm_unittests +wtf_unittests \ No newline at end of file
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index fc16a42e..7e838ac9 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -293,6 +293,9 @@ "ash/public/cpp/resources/ash_public_unscaled_resources.grd": { "includes": [24260], }, + "ash/resources/ash_resources.grd": { + "structures": [24280], + }, "ash/shell/ash_shell_resources.grd": { "includes": [24290], },
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 37116dc..963817fd 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -12270,6 +12270,22 @@ <description>Please enter the description of this user action.</description> </action> +<action name="MobileStackViewIncognitoMode"> + <owner>rlanday@chromium.org</owner> + <description> + User in the Android tab switcher switches from normal mode to incognito + mode. + </description> +</action> + +<action name="MobileStackViewNormalMode"> + <owner>rlanday@chromium.org</owner> + <description> + User in the Android tab switcher switches from incognito mode to normal + mode. + </description> +</action> + <action name="MobileStackViewSwipeCloseTab"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> @@ -12480,6 +12496,13 @@ <description>User pressed the stop icon in the toolbar.</description> </action> +<action name="MobileToolbarSwipeOpenStackView"> + <owner>rlanday@chromium.org</owner> + <description> + User entered the Android tab switcher by swiping down on the toolbar. + </description> +</action> + <action name="MobileToolbarToggleBookmark"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5666630c..f36b47c 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -26464,6 +26464,7 @@ label="OverlayScrollbarFlashAfterAnyScrollUpdate:enabled"/> <int value="-1907565048" label="HtmlBaseUsernameDetector:disabled"/> <int value="-1907342706" label="ReadItLaterInMenu:disabled"/> + <int value="-1895719323" label="VrBrowsingTabsView:enabled"/> <int value="-1892555086" label="disable-compositor-animation-timelines"/> <int value="-1892000374" label="SeccompSandboxAndroid:enabled"/> <int value="-1888273969" label="tab-capture-upscale-quality"/> @@ -26824,6 +26825,7 @@ <int value="-1158993534" label="PrintScaling:enabled"/> <int value="-1156179600" label="OmniboxRichEntitySuggestions:enabled"/> <int value="-1155543191" label="CopylessPaste:disabled"/> + <int value="-1154343236" label="VrBrowsingTabsView:disabled"/> <int value="-1151766565" label="enable-fullscreen-tab-detaching"/> <int value="-1145702446" label="ChromeHomeInactivitySheetExpansion:enabled"/> <int value="-1145246849" label="ThirdPartyDoodles:enabled"/> @@ -29165,6 +29167,7 @@ <int value="590" label="scroll-customization"/> <int value="591" label="row-gap"/> <int value="592" label="gap"/> + <int value="593" label="viewport-fit"/> </enum> <enum name="MappedEditingCommands">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b21cc1d..992647e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -6134,6 +6134,26 @@ </summary> </histogram> +<histogram name="Autofill.InvalidProfileData.UsedForMetrics" enum="Boolean"> + <owner>rogerm@chromium.org</owner> + <summary> + Tracks whether or not autofill suppressed sending votes or calculating + quality metrics because the profile data was marked as invalid. Logged + during field-type validation if/when a field marked as invalid is found to + match the submitted data. + </summary> +</histogram> + +<histogram name="Autofill.InvalidProfileData.UsedForSuggestion" enum="Boolean"> + <owner>rogerm@chromium.org</owner> + <summary> + Tracks whether or not autofill suppressed offering an autofill suggestion + because the profile data was marked as invalid. Logged during autofill + suggestion generation when a suggestion is about to generated based on a + field marked as invalid. + </summary> +</histogram> + <histogram name="Autofill.IsEnabled.PageLoad" enum="BooleanEnabled"> <owner>isherman@chromium.org</owner> <summary>
diff --git a/tools/perf/chrome_telemetry_build/BUILD.gn b/tools/perf/chrome_telemetry_build/BUILD.gn index 2e50671..cb26ff8 100644 --- a/tools/perf/chrome_telemetry_build/BUILD.gn +++ b/tools/perf/chrome_telemetry_build/BUILD.gn
@@ -22,6 +22,7 @@ data_deps += [ "//android_webview:system_webview_apk", "//android_webview/tools/system_webview_shell:system_webview_shell_apk", + "//chrome/android:monochrome_public_apk", ] } } else {
diff --git a/tools/perf/core/results_dashboard.py b/tools/perf/core/results_dashboard.py index 078bed9..458604d 100755 --- a/tools/perf/core/results_dashboard.py +++ b/tools/perf/core/results_dashboard.py
@@ -130,7 +130,6 @@ line = line.strip() if not line: continue - print 'Sending result %d of %d to dashboard.' % (index + 1, total_results) # We need to check whether we're trying to upload histograms. If the JSON # is invalid, we should not try to send this data or re-try it later. # Instead, we'll print an error. @@ -141,6 +140,8 @@ continue data_type = ('histogram' if is_histogramset else 'chartjson') + print 'Sending %s result %d of %d to dashboard.' % ( + data_type, index + 1, total_results) try: if is_histogramset: @@ -490,7 +491,7 @@ # If the remote app rejects the JSON, it's probably malformed, # so we don't want to retry it. raise SendResultsFatalException('Discarding JSON, error:\n%s' % error) - raise SendResultsRetryException() + raise SendResultsRetryException(error) def _Httplib2Request(url, data, oauth_token): data = zlib.compress(data)
diff --git a/tools/resources/find_unused_resources.py b/tools/resources/find_unused_resources.py index eab5ba3..d6e52c8 100755 --- a/tools/resources/find_unused_resources.py +++ b/tools/resources/find_unused_resources.py
@@ -12,7 +12,7 @@ Example: cd /work/chrome/src - tools/resources/find_unused_resouces.py chrome/browser/browser_resources.grd + tools/resources/find_unused_resouces.py ash/resources/ash_resources.grd """ __author__ = 'jamescook@chromium.org (James Cook)'
diff --git a/ui/base/mojo/clipboard_struct_traits.h b/ui/base/mojo/clipboard_struct_traits.h index fb3f501..0024521 100644 --- a/ui/base/mojo/clipboard_struct_traits.h +++ b/ui/base/mojo/clipboard_struct_traits.h
@@ -12,10 +12,11 @@ template <> struct EnumTraits<blink::mojom::ClipboardBuffer, ui::ClipboardType> { - static blink::mojom::ClipboardBuffer ToMojom(ui::ClipboardType) { - // We never intend on converting from ui::Clipboardtype to - // blink::mojom::ClipboardBuffer. - NOTREACHED(); + static blink::mojom::ClipboardBuffer ToMojom( + ui::ClipboardType clipboard_type) { + // We only convert ui::Clipboardtype to blink::mojom::ClipboardBuffer + // in tests, and they use ui::CLIPBOARD_TYPE_COPY_PASTE. + DCHECK(clipboard_type == ui::CLIPBOARD_TYPE_COPY_PASTE); return blink::mojom::ClipboardBuffer::kStandard; }
diff --git a/ui/compositor/test/in_process_context_provider.cc b/ui/compositor/test/in_process_context_provider.cc index 0477487..7bd39cb2 100644 --- a/ui/compositor/test/in_process_context_provider.cc +++ b/ui/compositor/test/in_process_context_provider.cc
@@ -116,7 +116,7 @@ "gpu_toplevel", unique_context_name.c_str()); raster_context_ = std::make_unique<gpu::raster::RasterImplementationGLES>( - context_->GetImplementation(), context_->GetImplementation(), + context_->GetImplementation(), context_->GetImplementation()->command_buffer(), context_->GetImplementation()->capabilities());
diff --git a/ui/gl/gl_surface_osmesa.cc b/ui/gl/gl_surface_osmesa.cc index 0a20986..3894f05 100644 --- a/ui/gl/gl_surface_osmesa.cc +++ b/ui/gl/gl_surface_osmesa.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/numerics/safe_math.h" +#include "base/threading/thread_task_runner_handle.h" #include "third_party/mesa/src/include/GL/osmesa.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" @@ -109,8 +110,10 @@ gfx::SwapResult GLSurfaceOSMesaHeadless::SwapBuffers( const PresentationCallback& callback) { - callback.Run(gfx::PresentationFeedback(base::TimeTicks::Now(), - base::TimeDelta(), 0 /* flags */)); + gfx::PresentationFeedback feedback(base::TimeTicks::Now(), base::TimeDelta(), + 0 /* flags */); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(callback, feedback)); return gfx::SwapResult::SWAP_ACK; }
diff --git a/ui/gl/gl_surface_osmesa_win.cc b/ui/gl/gl_surface_osmesa_win.cc index 6f54b4e..4730ae5 100644 --- a/ui/gl/gl_surface_osmesa_win.cc +++ b/ui/gl/gl_surface_osmesa_win.cc
@@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "base/win/windows_version.h" #include "ui/gl/gl_bindings.h" @@ -113,10 +114,12 @@ constexpr int64_t kRefreshIntervalInMicroseconds = base::Time::kMicrosecondsPerSecond / 60; - callback.Run(gfx::PresentationFeedback( + gfx::PresentationFeedback feedback( base::TimeTicks::Now(), base::TimeDelta::FromMicroseconds(kRefreshIntervalInMicroseconds), - 0 /* flags */)); + 0 /* flags */); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(callback, feedback)); return gfx::SwapResult::SWAP_ACK; }
diff --git a/ui/gl/gl_surface_presentation_helper.cc b/ui/gl/gl_surface_presentation_helper.cc index e9ecc50..1ff7bd1d 100644 --- a/ui/gl/gl_surface_presentation_helper.cc +++ b/ui/gl/gl_surface_presentation_helper.cc
@@ -99,8 +99,7 @@ DCHECK(!pending_frames_.empty()); auto& frame = pending_frames_.back(); frame.result = result; - if (!waiting_for_vsync_parameters_) - CheckPendingFrames(); + ScheduleCheckPendingFrames(false /* align_with_next_vsync */); } void GLSurfacePresentationHelper::CheckPendingFrames() { @@ -230,13 +229,41 @@ } } - if (waiting_for_vsync_parameters_) - return; - if (pending_frames_.empty() && !need_update_vsync) return; + ScheduleCheckPendingFrames(true /* align_with_next_vsync */); +} - waiting_for_vsync_parameters_ = true; +void GLSurfacePresentationHelper::CheckPendingFramesCallback() { + DCHECK(check_pending_frame_scheduled_); + check_pending_frame_scheduled_ = false; + CheckPendingFrames(); +} + +void GLSurfacePresentationHelper::UpdateVSyncCallback( + const base::TimeTicks timebase, + const base::TimeDelta interval) { + DCHECK(check_pending_frame_scheduled_); + check_pending_frame_scheduled_ = false; + vsync_timebase_ = timebase; + vsync_interval_ = interval; + CheckPendingFrames(); +} + +void GLSurfacePresentationHelper::ScheduleCheckPendingFrames( + bool align_with_next_vsync) { + if (check_pending_frame_scheduled_) + return; + check_pending_frame_scheduled_ = true; + + if (!align_with_next_vsync) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&GLSurfacePresentationHelper::CheckPendingFramesCallback, + weak_ptr_factory_.GetWeakPtr())); + return; + } + if (vsync_provider_ && !vsync_provider_->SupportGetVSyncParametersIfAvailable()) { // In this case, the |vsync_provider_| will call the callback when the next @@ -262,20 +289,4 @@ next_vsync - now); } -void GLSurfacePresentationHelper::CheckPendingFramesCallback() { - DCHECK(waiting_for_vsync_parameters_); - waiting_for_vsync_parameters_ = false; - CheckPendingFrames(); -} - -void GLSurfacePresentationHelper::UpdateVSyncCallback( - const base::TimeTicks timebase, - const base::TimeDelta interval) { - DCHECK(waiting_for_vsync_parameters_); - waiting_for_vsync_parameters_ = false; - vsync_timebase_ = timebase; - vsync_interval_ = interval; - CheckPendingFrames(); -} - } // namespace gl
diff --git a/ui/gl/gl_surface_presentation_helper.h b/ui/gl/gl_surface_presentation_helper.h index a1563c9..de7e0ccd 100644 --- a/ui/gl/gl_surface_presentation_helper.h +++ b/ui/gl/gl_surface_presentation_helper.h
@@ -75,6 +75,8 @@ void UpdateVSyncCallback(const base::TimeTicks timebase, const base::TimeDelta interval); + void ScheduleCheckPendingFrames(bool align_with_next_vsync); + gfx::VSyncProvider* const vsync_provider_; scoped_refptr<GLContext> gl_context_; GLSurface* surface_ = nullptr; @@ -82,7 +84,7 @@ base::circular_deque<Frame> pending_frames_; base::TimeTicks vsync_timebase_; base::TimeDelta vsync_interval_; - bool waiting_for_vsync_parameters_ = false; + bool check_pending_frame_scheduled_ = false; base::WeakPtrFactory<GLSurfacePresentationHelper> weak_ptr_factory_;
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp index 46f529a..3c30cbc0 100644 --- a/ui/webui/resources/polymer_resources.grdp +++ b/ui/webui/resources/polymer_resources.grdp
@@ -816,14 +816,6 @@ file="../../../third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_TOGGLE_BUTTON_PAPER_TOGGLE_BUTTON_EXTRACTED_JS" - file="../../../third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button-extracted.js" - type="chrome_html" - compress="gzip" /> - <structure name="IDR_POLYMER_1_0_PAPER_TOGGLE_BUTTON_PAPER_TOGGLE_BUTTON_HTML" - file="../../../third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html" - type="chrome_html" - compress="gzip" /> <structure name="IDR_POLYMER_1_0_PAPER_TOOLTIP_PAPER_TOOLTIP_EXTRACTED_JS" file="../../../third_party/polymer/v1_0/components-chromium/paper-tooltip/paper-tooltip-extracted.js" type="chrome_html"