diff --git a/DEPS b/DEPS index 54f5ae9..b5218cd 100644 --- a/DEPS +++ b/DEPS
@@ -111,7 +111,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': '180125176f24283cfb0fdb62999949445ab4db5b', + 'catapult_revision': '6f19655f67942d3b13000fdc157ddcf914186e7b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -198,7 +198,7 @@ }, 'src/ios/third_party/ochamcrest/src': { - 'url': Var('chromium_git') + '/external/github.com/hamcrest/OCHamcrest.git' + '@' + 'd7ee4ecfb6bd13c3c8d364682b6228ccd86e1e1a', + 'url': Var('chromium_git') + '/external/github.com/hamcrest/OCHamcrest.git' + '@' + '92d9c14d13bb864255e65c09383564653896916b', 'condition': 'checkout_ios', }, @@ -251,7 +251,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '66814c3bbbd2068dd34af9df2f677316bf081752', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '85c606aae820e29d6ccfa5589af365536eaf9ad1', 'condition': 'checkout_linux', }, @@ -279,7 +279,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '9f20d020855c8ee87ba64d53ef94051c06aab860', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '7de54ef0a25f546747ea9f2a536d5cb175abc566', # DevTools node modules. Used on Linux buildbots only. 'src/third_party/devtools-node-modules': { @@ -301,7 +301,7 @@ }, 'src/third_party/ffmpeg': - Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '62ff55193a061c21c039a2ba0b39641136912c2e', + Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '3098b6a24547c66d20ffd8448f6a719f41f87b95', 'src/third_party/findbugs': { 'url': Var('chromium_git') + '/chromium/deps/findbugs.git' + '@' + '57f05238d3ac77ea0a194813d3065dd780c6e566', @@ -425,7 +425,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + 'fe7b869104806752a26a262dc60923639d9a384f', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'caa116c9be96508c18d533dedc95b2df4f8e3812', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + '4956b2dec65352af32dc71bab553acb631c64177',
diff --git a/android_webview/browser/aw_metrics_log_uploader.cc b/android_webview/browser/aw_metrics_log_uploader.cc index c79eeb1..bb2c213 100644 --- a/android_webview/browser/aw_metrics_log_uploader.cc +++ b/android_webview/browser/aw_metrics_log_uploader.cc
@@ -19,8 +19,10 @@ AwMetricsLogUploader::~AwMetricsLogUploader() {} -void AwMetricsLogUploader::UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) { +void AwMetricsLogUploader::UploadLog( + const std::string& compressed_log_data, + const std::string& log_hash, + const metrics::ReportingInfo& reporting_info) { // WebView uses the platform logging mechanism instead of the normal UMA // server. The platform mechanism does its own compression, so undo the // previous compression.
diff --git a/android_webview/browser/aw_metrics_log_uploader.h b/android_webview/browser/aw_metrics_log_uploader.h index 91dabde..0f54732 100644 --- a/android_webview/browser/aw_metrics_log_uploader.h +++ b/android_webview/browser/aw_metrics_log_uploader.h
@@ -22,7 +22,8 @@ // ::metrics::MetricsLogUploader: void UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) override; + const std::string& log_hash, + const metrics::ReportingInfo& reporting_info) override; private: const metrics::MetricsLogUploader::UploadCallback on_upload_complete_;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java index 6bacd361..4edd089 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java
@@ -31,6 +31,8 @@ public static void maybeInitSafeBrowsingFromSettings(final Context appContext) { AwContentsStatics.setSafeBrowsingEnabledByManifest( CommandLine.getInstance().hasSwitch(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) + || CommandLine.getInstance().hasSwitch( + AwSwitches.WEBVIEW_SAFEBROWSING_BLOCK_ALL_RESOURCES) || appHasOptedIn(appContext)); // If GMS is available, we will figure out if the user has opted-in to Safe Browsing and set // the correct value for sSafeBrowsingUserOptIn.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSwitches.java b/android_webview/java/src/org/chromium/android_webview/AwSwitches.java index 77b37c4..48c76d2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSwitches.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSwitches.java
@@ -18,6 +18,12 @@ public static final String WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT = "webview-enable-safebrowsing-support"; + // Enables SafeBrowsing and causes WebView to treat all resources as malicious. Use care: this + // will block all resources from loading. + // No native switch. + public static final String WEBVIEW_SAFEBROWSING_BLOCK_ALL_RESOURCES = + "webview-safebrowsing-block-all-resources"; + // Enables variations AB testing experiments in webview. // Native switch kEnableWebViewVariations. public static final String ENABLE_WEBVIEW_VARIATIONS = "enable-webview-variations";
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 65beaf4..029570b 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -508,6 +508,8 @@ "system/palette/palette_tray.h", "system/palette/palette_utils.cc", "system/palette/palette_utils.h", + "system/palette/palette_welcome_bubble.cc", + "system/palette/palette_welcome_bubble.h", "system/palette/tools/capture_region_mode.cc", "system/palette/tools/capture_region_mode.h", "system/palette/tools/capture_screen_action.cc", @@ -1332,6 +1334,7 @@ "system/palette/mock_palette_tool_delegate.h", "system/palette/palette_tool_manager_unittest.cc", "system/palette/palette_tray_unittest.cc", + "system/palette/palette_welcome_bubble_unittest.cc", "system/palette/tools/create_note_unittest.cc", "system/palette/tools/metalayer_unittest.cc", "system/palette/tools/screenshot_unittest.cc",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index b0d0290..135d0b8 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -463,6 +463,12 @@ <message name="IDS_ASH_STYLUS_TOOLS_TITLE" desc="The title of the stylus tools dialog in the ash shelf."> Stylus tools </message> + <message name="IDS_ASH_STYLUS_WARM_WELCOME_BUBBLE_TITLE" desc="The title of the bubble that pops up the first time a user uses a stylus."> + These are your stylus tools + </message> + <message name="IDS_ASH_STYLUS_WARM_WELCOME_BUBBLE_DESCRIPTION" desc="The description of the bubble that pops up the first time a user uses a stylus. Describes what tools exist in the palette tray."> + Tap the stylus button on the shelf to take a note, screenshot, use the assistant, laser pointer, or magnifying glass. + </message> <message name="IDS_ASH_PALETTE_SETTINGS" desc="The label on the setting button used to open palette setting page."> Stylus settings </message>
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc index ec855427..78a9c51 100644 --- a/ash/public/cpp/ash_pref_names.cc +++ b/ash/public/cpp/ash_pref_names.cc
@@ -69,6 +69,9 @@ // A boolean pref which stores whether a stylus has been seen before. const char kHasSeenStylus[] = "ash.has_seen_stylus"; +// A boolean pref which stores whether a the palette warm welcome bubble +// (displayed when a user first uses a stylus) has been shown before. +const char kShownPaletteWelcomeBubble[] = "ash.shown_palette_welcome_bubble"; // A boolean pref storing the enabled status of the NightLight feature. const char kNightLightEnabled[] = "ash.night_light.enabled";
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h index dac71eb2..d36930a5 100644 --- a/ash/public/cpp/ash_pref_names.h +++ b/ash/public/cpp/ash_pref_names.h
@@ -31,6 +31,7 @@ ASH_PUBLIC_EXPORT extern const char kShouldAlwaysShowAccessibilityMenu[]; ASH_PUBLIC_EXPORT extern const char kHasSeenStylus[]; +ASH_PUBLIC_EXPORT extern const char kShownPaletteWelcomeBubble[]; ASH_PUBLIC_EXPORT extern const char kNightLightEnabled[]; ASH_PUBLIC_EXPORT extern const char kNightLightTemperature[];
diff --git a/ash/shell.cc b/ash/shell.cc index 863a9a8..bd40417 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -81,6 +81,7 @@ #include "ash/system/network/vpn_list.h" #include "ash/system/night_light/night_light_controller.h" #include "ash/system/palette/palette_tray.h" +#include "ash/system/palette/palette_welcome_bubble.h" #include "ash/system/power/peripheral_battery_notifier.h" #include "ash/system/power/power_button_controller.h" #include "ash/system/power/power_event_observer.h" @@ -344,13 +345,14 @@ // static void Shell::RegisterProfilePrefs(PrefRegistrySimple* registry, bool for_test) { AccessibilityController::RegisterProfilePrefs(registry, for_test); - LogoutButtonTray::RegisterProfilePrefs(registry); - NightLightController::RegisterProfilePrefs(registry); - ShelfController::RegisterProfilePrefs(registry); - TrayCapsLock::RegisterProfilePrefs(registry, for_test); BluetoothPowerController::RegisterProfilePrefs(registry); LockScreenController::RegisterProfilePrefs(registry, for_test); + LogoutButtonTray::RegisterProfilePrefs(registry); + NightLightController::RegisterProfilePrefs(registry); + PaletteWelcomeBubble::RegisterProfilePrefs(registry); + ShelfController::RegisterProfilePrefs(registry); TouchDevicesController::RegisterProfilePrefs(registry); + TrayCapsLock::RegisterProfilePrefs(registry, for_test); } views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView(
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 2ec0790..3437da1 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -19,6 +19,7 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/system/palette/palette_tool_manager.h" #include "ash/system/palette/palette_utils.h" +#include "ash/system/palette/palette_welcome_bubble.h" #include "ash/system/tray/system_menu_button.h" #include "ash/system/tray/system_tray_controller.h" #include "ash/system/tray/tray_bubble_wrapper.h" @@ -144,7 +145,7 @@ // StylusWatcher is used to monitor for stylus events, since we only want to // make the palette tray visible for devices without internal styluses once they // start using the stylus. -class PaletteTray::StylusWatcher : views::PointerWatcher { +class PaletteTray::StylusWatcher : public views::PointerWatcher { public: explicit StylusWatcher(PrefService* pref_service) : local_state_pref_service_(pref_service) { @@ -174,6 +175,7 @@ PaletteTray::PaletteTray(Shelf* shelf) : TrayBackgroundView(shelf), palette_tool_manager_(new PaletteToolManager(this)), + welcome_bubble_(std::make_unique<PaletteWelcomeBubble>(this)), scoped_session_observer_(this), weak_factory_(this) { PaletteTool::RegisterToolInstances(palette_tool_manager_.get()); @@ -290,6 +292,11 @@ } else if (stylus_state == ui::StylusState::INSERTED && bubble_) { HidePalette(); } + } else if (stylus_state == ui::StylusState::REMOVED) { + // Show the palette welcome bubble if the auto open palette setting is not + // turned on, if the bubble has not been shown before (|welcome_bubble_| + // will be nullptr if the bubble has been shown before). + welcome_bubble_->ShowIfNeeded(); } // Disable any active modes if the stylus has been inserted.
diff --git a/ash/system/palette/palette_tray.h b/ash/system/palette/palette_tray.h index 88d0eddc..05d7302a 100644 --- a/ash/system/palette/palette_tray.h +++ b/ash/system/palette/palette_tray.h
@@ -32,6 +32,7 @@ namespace ash { class PaletteToolManager; +class PaletteWelcomeBubble; class TrayBubbleWrapper; // The PaletteTray shows the palette in the bottom area of the screen. This @@ -45,6 +46,7 @@ public ui::InputDeviceEventObserver { public: // For testing. + // TODO(crbug.com/774166): Move this to class to its own file. class TestApi { public: explicit TestApi(PaletteTray* palette_tray); @@ -54,6 +56,10 @@ return palette_tray_->palette_tool_manager_.get(); } + PaletteWelcomeBubble* GetWelcomeBubble() { + return palette_tray_->welcome_bubble_.get(); + } + TrayBubbleWrapper* GetTrayBubbleWrapper() { return palette_tray_->bubble_.get(); } @@ -135,6 +141,7 @@ bool DeactivateActiveTool(); std::unique_ptr<PaletteToolManager> palette_tool_manager_; + std::unique_ptr<PaletteWelcomeBubble> welcome_bubble_; std::unique_ptr<TrayBubbleWrapper> bubble_; std::unique_ptr<StylusWatcher> watcher_;
diff --git a/ash/system/palette/palette_tray_unittest.cc b/ash/system/palette/palette_tray_unittest.cc index e8edf38..2d92220 100644 --- a/ash/system/palette/palette_tray_unittest.cc +++ b/ash/system/palette/palette_tray_unittest.cc
@@ -13,10 +13,12 @@ #include "ash/public/cpp/config.h" #include "ash/public/cpp/stylus_utils.h" #include "ash/public/cpp/voice_interaction_state.h" +#include "ash/session/session_controller.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" #include "ash/shell_test_api.h" #include "ash/system/palette/palette_utils.h" +#include "ash/system/palette/palette_welcome_bubble.h" #include "ash/system/palette/test_palette_delegate.h" #include "ash/system/status_area_widget.h" #include "ash/system/status_area_widget_test_helper.h" @@ -30,8 +32,6 @@ #include "components/prefs/pref_service.h" #include "components/session_manager/session_manager_types.h" #include "ui/events/base_event_utils.h" -#include "ui/events/devices/device_data_manager.h" -#include "ui/events/devices/touchscreen_device.h" #include "ui/events/event.h" #include "ui/events/test/device_data_manager_test_api.h" #include "ui/events/test/event_generator.h" @@ -43,6 +43,22 @@ PaletteTrayTest() {} ~PaletteTrayTest() override {} + // Performs a tap on the palette tray button. + void PerformTap() { + ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), + ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + palette_tray_->PerformAction(tap); + } + + // Fake a stylus ejection. Note: this will fail in mus or mash because + // DeviceDataManager is not created. See crbug.com/734812. + void EjectStylus() { + ui::test::DeviceDataManagerTestAPI devices_test_api; + devices_test_api.NotifyObserversStylusStateChanged( + ui::StylusState::REMOVED); + } + + // AshTestBase: void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kAshEnablePaletteOnAllDisplays); @@ -64,19 +80,16 @@ palette_tray_->Initialize(); } - // Performs a tap on the palette tray button. - void PerformTap() { - ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), - ui::GestureEventDetails(ui::ET_GESTURE_TAP)); - palette_tray_->PerformAction(tap); - } - protected: TestPaletteDelegate* test_palette_delegate() { return static_cast<TestPaletteDelegate*>(Shell::Get()->palette_delegate()); } - PrefService* pref_service() { + PrefService* active_user_pref_service() { + return Shell::Get()->session_controller()->GetActivePrefService(); + } + + PrefService* local_state_pref_service() { return Shell::Get()->GetLocalStatePrefService(); } @@ -106,7 +119,7 @@ // should become visible after seeing a stylus event. TEST_F(PaletteTrayTest, PaletteTrayVisibleAfterStylusSeen) { ASSERT_FALSE(palette_tray_->visible()); - ASSERT_FALSE(pref_service()->GetBoolean(prefs::kHasSeenStylus)); + ASSERT_FALSE(local_state_pref_service()->GetBoolean(prefs::kHasSeenStylus)); ASSERT_TRUE(test_api_->IsStylusWatcherActive()); // Send a stylus event. @@ -125,7 +138,7 @@ // visible. TEST_F(PaletteTrayTest, StylusSeenPrefInitiallySet) { ASSERT_FALSE(palette_tray_->visible()); - pref_service()->SetBoolean(prefs::kHasSeenStylus, true); + local_state_pref_service()->SetBoolean(prefs::kHasSeenStylus, true); EXPECT_TRUE(palette_tray_->visible()); EXPECT_FALSE(test_api_->IsStylusWatcherActive()); @@ -551,4 +564,42 @@ EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER)); } +// Verify the palette welcome bubble is shown the first time the stylus is +// removed. +TEST_F(PaletteTrayTestWithInternalStylus, WelcomeBubbleShownOnEject) { + test_palette_delegate()->set_should_show_palette(true); + ASSERT_FALSE(active_user_pref_service()->GetBoolean( + prefs::kShownPaletteWelcomeBubble)); + EXPECT_FALSE(test_api_->GetWelcomeBubble()->BubbleShown()); + + EjectStylus(); + EXPECT_TRUE(test_api_->GetWelcomeBubble()->BubbleShown()); +} + +// Verify if the pref which tracks if the welcome bubble has been shown before +// is true, the welcome bubble is not shown when the stylus is removed. +TEST_F(PaletteTrayTestWithInternalStylus, WelcomeBubbleNotShownIfShownBefore) { + test_palette_delegate()->set_should_show_palette(true); + active_user_pref_service()->SetBoolean(prefs::kShownPaletteWelcomeBubble, + true); + EXPECT_FALSE(test_api_->GetWelcomeBubble()->BubbleShown()); + + EjectStylus(); + EXPECT_FALSE(test_api_->GetWelcomeBubble()->BubbleShown()); +} + +// Verify that the bubble does not get shown if the auto open palette setting is +// true. +TEST_F(PaletteTrayTestWithInternalStylus, + WelcomeBubbleNotShownIfAutoOpenPaletteTrue) { + test_palette_delegate()->set_should_show_palette(true); + test_palette_delegate()->set_should_auto_open_palette(true); + active_user_pref_service()->SetBoolean(prefs::kShownPaletteWelcomeBubble, + false); + EXPECT_FALSE(test_api_->GetWelcomeBubble()->BubbleShown()); + + EjectStylus(); + EXPECT_FALSE(test_api_->GetWelcomeBubble()->BubbleShown()); +} + } // namespace ash
diff --git a/ash/system/palette/palette_welcome_bubble.cc b/ash/system/palette/palette_welcome_bubble.cc new file mode 100644 index 0000000..5b9bf97d --- /dev/null +++ b/ash/system/palette/palette_welcome_bubble.cc
@@ -0,0 +1,178 @@ +// 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 "ash/system/palette/palette_welcome_bubble.h" + +#include "ash/public/cpp/ash_pref_names.h" +#include "ash/public/cpp/shell_window_ids.h" +#include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller.h" +#include "ash/shell.h" +#include "ash/shell_port.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/palette/palette_tray.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "ui/aura/window.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/font.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/bubble/bubble_dialog_delegate.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" + +namespace ash { + +// View which contains two text (one title) and a close button for closing the +// bubble. Controlled by PaletteWelcomeBubble and anchored to a PaletteTray. +class PaletteWelcomeBubble::WelcomeBubbleView + : public views::BubbleDialogDelegateView, + public views::ButtonListener { + public: + WelcomeBubbleView(views::View* anchor, views::BubbleBorder::Arrow arrow) + : views::BubbleDialogDelegateView(anchor, arrow) { + set_close_on_deactivate(true); + set_can_activate(false); + set_accept_events(true); + set_parent_window( + anchor_widget()->GetNativeWindow()->GetRootWindow()->GetChildById( + kShellWindowId_SettingBubbleContainer)); + SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); + + // Add the header which contains the title and close button. + auto* header = new views::View(); + auto* box_layout = new views::BoxLayout(views::BoxLayout::kHorizontal); + header->SetLayoutManager(box_layout); + AddChildView(header); + + // Add the title, which is bolded. + auto* title = new views::Label( + l10n_util::GetStringUTF16(IDS_ASH_STYLUS_WARM_WELCOME_BUBBLE_TITLE)); + title->SetHorizontalAlignment(gfx::ALIGN_LEFT); + title->SetFontList(views::Label::GetDefaultFontList().Derive( + 0, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::BOLD)); + header->AddChildView(title); + box_layout->SetFlexForView(title, 1); + + // Add a button to close the bubble. + close_button_ = new views::ImageButton(this); + close_button_->SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(kWindowControlCloseIcon, SK_ColorBLACK)); + header->AddChildView(close_button_); + + auto* content = new views::Label(l10n_util::GetStringUTF16( + IDS_ASH_STYLUS_WARM_WELCOME_BUBBLE_DESCRIPTION)); + content->SetHorizontalAlignment(gfx::ALIGN_LEFT); + AddChildView(content); + + views::BubbleDialogDelegateView::CreateBubble(this); + } + + ~WelcomeBubbleView() override = default; + + views::ImageButton* close_button() { return close_button_; } + + // ui::BubbleDialogDelegateView: + int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; } + + // views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override { + if (sender == close_button_) + GetWidget()->Close(); + } + + // views::View: + gfx::Size CalculatePreferredSize() const override { + return BubbleDialogDelegateView::CalculatePreferredSize(); + } + + private: + views::ImageButton* close_button_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(WelcomeBubbleView); +}; + +PaletteWelcomeBubble::PaletteWelcomeBubble(PaletteTray* tray) : tray_(tray) { + Shell::Get()->session_controller()->AddObserver(this); +} + +PaletteWelcomeBubble::~PaletteWelcomeBubble() { + if (bubble_view_) { + bubble_view_->GetWidget()->RemoveObserver(this); + ShellPort::Get()->RemovePointerWatcher(this); + } + Shell::Get()->session_controller()->RemoveObserver(this); +} + +// static +void PaletteWelcomeBubble::RegisterProfilePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kShownPaletteWelcomeBubble, false); +} + +void PaletteWelcomeBubble::OnWidgetClosing(views::Widget* widget) { + widget->RemoveObserver(this); + bubble_view_ = nullptr; + active_user_pref_service_->SetBoolean(prefs::kShownPaletteWelcomeBubble, + true); + ShellPort::Get()->RemovePointerWatcher(this); +} + +void PaletteWelcomeBubble::OnPointerEventObserved( + const ui::PointerEvent& event, + const gfx::Point& location_in_screen, + gfx::NativeView target) { + if (bubble_view_ && + !bubble_view_->GetBoundsInScreen().Contains(location_in_screen)) { + bubble_view_->GetWidget()->Close(); + } +} + +void PaletteWelcomeBubble::OnActiveUserPrefServiceChanged( + PrefService* pref_service) { + active_user_pref_service_ = pref_service; +} + +void PaletteWelcomeBubble::ShowIfNeeded() { + DCHECK(active_user_pref_service_); + if (!active_user_pref_service_->GetBoolean( + prefs::kShownPaletteWelcomeBubble) && + !BubbleShown()) { + Show(); + } +} + +views::ImageButton* PaletteWelcomeBubble::GetCloseButtonForTest() { + if (bubble_view_) + return bubble_view_->close_button(); + + return nullptr; +} + +base::Optional<gfx::Rect> PaletteWelcomeBubble::GetBubbleBoundsForTest() { + if (bubble_view_) + return base::make_optional(bubble_view_->GetBoundsInScreen()); + + return base::nullopt; +} + +void PaletteWelcomeBubble::Show() { + if (!bubble_view_) { + DCHECK(tray_); + bubble_view_ = + new WelcomeBubbleView(tray_, views::BubbleBorder::BOTTOM_RIGHT); + } + bubble_view_->GetWidget()->Show(); + bubble_view_->GetWidget()->AddObserver(this); + ShellPort::Get()->AddPointerWatcher(this, + views::PointerWatcherEventTypes::BASIC); +} + +void PaletteWelcomeBubble::Hide() { + if (bubble_view_) + bubble_view_->GetWidget()->Close(); +} + +} // namespace ash
diff --git a/ash/system/palette/palette_welcome_bubble.h b/ash/system/palette/palette_welcome_bubble.h new file mode 100644 index 0000000..db62a12b --- /dev/null +++ b/ash/system/palette/palette_welcome_bubble.h
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_PALETTE_PALETTE_WELCOME_BUBBLE_H_ +#define ASH_SYSTEM_PALETTE_PALETTE_WELCOME_BUBBLE_H_ + +#include "ash/ash_export.h" +#include "ash/session/session_observer.h" +#include "base/macros.h" +#include "base/optional.h" +#include "ui/views/pointer_watcher.h" +#include "ui/views/widget/widget_observer.h" + +class PrefRegistrySimple; +class PrefService; + +namespace views { +class ImageButton; +class Widget; +} // namespace views + +namespace ash { +class PaletteTray; + +// The PaletteWelcomeBubble handles displaying a warm welcome bubble letting +// users know about the PaletteTray the first time a stylus is ejected, or if an +// external stylus is detected. +class ASH_EXPORT PaletteWelcomeBubble : public SessionObserver, + public views::PointerWatcher, + public views::WidgetObserver { + public: + explicit PaletteWelcomeBubble(PaletteTray* tray); + ~PaletteWelcomeBubble() override; + + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + + // Show the welcome bubble iff it has not been shown before. + void ShowIfNeeded(); + + bool BubbleShown() { return bubble_view_ != nullptr; } + + // SessionObserver: + void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; + + // views::WidgetObserver: + void OnWidgetClosing(views::Widget* widget) override; + + // views::PointerWatcher: + void OnPointerEventObserved(const ui::PointerEvent& event, + const gfx::Point& location_in_screen, + gfx::NativeView target) override; + + // Returns the close button on the bubble if it exists. + views::ImageButton* GetCloseButtonForTest(); + + // Returns the bounds of the bubble view if it exists. + base::Optional<gfx::Rect> GetBubbleBoundsForTest(); + + private: + friend class PaletteWelcomeBubbleTest; + class WelcomeBubbleView; + + void Show(); + void Hide(); + + // The PaletteTray this bubble is associated with. Serves as the anchor for + // the bubble. Not owned. + PaletteTray* tray_ = nullptr; + + PrefService* active_user_pref_service_ = nullptr; // Not owned. + + WelcomeBubbleView* bubble_view_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(PaletteWelcomeBubble); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_PALETTE_PALETTE_WELCOME_BUBBLE_H_
diff --git a/ash/system/palette/palette_welcome_bubble_unittest.cc b/ash/system/palette/palette_welcome_bubble_unittest.cc new file mode 100644 index 0000000..b24506d --- /dev/null +++ b/ash/system/palette/palette_welcome_bubble_unittest.cc
@@ -0,0 +1,149 @@ +// 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 "ash/system/palette/palette_welcome_bubble.h" + +#include "ash/public/cpp/ash_pref_names.h" +#include "ash/session/session_controller.h" +#include "ash/session/test_session_controller_client.h" +#include "ash/shell.h" +#include "ash/system/palette/palette_tray.h" +#include "ash/system/status_area_widget.h" +#include "ash/system/status_area_widget_test_helper.h" +#include "ash/test/ash_test_base.h" +#include "base/command_line.h" +#include "components/prefs/pref_service.h" +#include "ui/events/test/event_generator.h" +#include "ui/views/controls/button/image_button.h" + +namespace ash { + +namespace { + +constexpr char kUser1Email[] = "user1@palettewelcome.com"; +constexpr char kUser2Email[] = "user2@palettewelcome.com"; + +} // namespace + +class PaletteWelcomeBubbleTest : public AshTestBase { + public: + PaletteWelcomeBubbleTest() = default; + ~PaletteWelcomeBubbleTest() override = default; + + PrefService* user1_pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUser1Email)); + } + + PrefService* user2_pref_service() { + return Shell::Get()->session_controller()->GetUserPrefServiceForUser( + AccountId::FromUserEmail(kUser2Email)); + } + + void ShowBubble() { welcome_bubble_->Show(); } + void HideBubble() { welcome_bubble_->Hide(); } + + // AshTestBase: + void SetUp() override { + AshTestBase::SetUp(); + + welcome_bubble_ = std::make_unique<PaletteWelcomeBubble>( + StatusAreaWidgetTestHelper::GetStatusAreaWidget()->palette_tray()); + GetSessionControllerClient()->AddUserSession(kUser1Email); + GetSessionControllerClient()->AddUserSession(kUser2Email); + GetSessionControllerClient()->SwitchActiveUser( + AccountId::FromUserEmail(kUser1Email)); + } + + void TearDown() override { + welcome_bubble_.reset(); + AshTestBase::TearDown(); + } + + protected: + std::unique_ptr<PaletteWelcomeBubble> welcome_bubble_; + + private: + DISALLOW_COPY_AND_ASSIGN(PaletteWelcomeBubbleTest); +}; + +// Test the basic Show/Hide functions work. +TEST_F(PaletteWelcomeBubbleTest, Basic) { + EXPECT_FALSE(welcome_bubble_->BubbleShown()); + + ShowBubble(); + EXPECT_TRUE(welcome_bubble_->BubbleShown()); + + HideBubble(); + EXPECT_FALSE(welcome_bubble_->BubbleShown()); + + // Verify that the pref changes after the bubble is hidden. + EXPECT_TRUE( + user1_pref_service()->GetBoolean(prefs::kShownPaletteWelcomeBubble)); +} + +// Verify if the bubble has been show before, it will not be shown again. +TEST_F(PaletteWelcomeBubbleTest, ShowIfNeeded) { + user1_pref_service()->SetBoolean(prefs::kShownPaletteWelcomeBubble, true); + + welcome_bubble_->ShowIfNeeded(); + EXPECT_FALSE(welcome_bubble_->BubbleShown()); +} + +// Verify that tapping the close button on the welcome bubble closes the bubble. +TEST_F(PaletteWelcomeBubbleTest, CloseButton) { + ShowBubble(); + ASSERT_TRUE(welcome_bubble_->BubbleShown()); + ASSERT_TRUE(welcome_bubble_->GetCloseButtonForTest()); + + GetEventGenerator().set_current_location( + welcome_bubble_->GetCloseButtonForTest() + ->GetBoundsInScreen() + .CenterPoint()); + GetEventGenerator().ClickLeftButton(); + EXPECT_FALSE(welcome_bubble_->BubbleShown()); +} + +// Verify that tapping on the screen outside of the welcome bubble closes the +// bubble. +TEST_F(PaletteWelcomeBubbleTest, TapOutsideOfBubble) { + ShowBubble(); + ASSERT_TRUE(welcome_bubble_->BubbleShown()); + ASSERT_TRUE(welcome_bubble_->GetBubbleBoundsForTest().has_value()); + + // The bubble remains open if a tap occurs on the bubble. + GetEventGenerator().set_current_location( + welcome_bubble_->GetBubbleBoundsForTest()->CenterPoint()); + GetEventGenerator().ClickLeftButton(); + EXPECT_TRUE(welcome_bubble_->BubbleShown()); + + // Tap anywhere outside the bubble. + ASSERT_FALSE( + welcome_bubble_->GetBubbleBoundsForTest()->Contains(gfx::Point())); + GetEventGenerator().set_current_location(gfx::Point()); + GetEventGenerator().ClickLeftButton(); + EXPECT_FALSE(welcome_bubble_->BubbleShown()); +} + +// Verify that a second user sees the bubble even after a first user has seen it +// already. +TEST_F(PaletteWelcomeBubbleTest, BubbleShownForSecondUser) { + // Show the bubble for the first user, and verify that the pref is set when + // the bubble is hidden. + ShowBubble(); + EXPECT_TRUE(welcome_bubble_->BubbleShown()); + HideBubble(); + ASSERT_TRUE( + user1_pref_service()->GetBoolean(prefs::kShownPaletteWelcomeBubble)); + + // Switch to the second user, and verify that the bubble will get shown. + GetSessionControllerClient()->SwitchActiveUser( + AccountId::FromUserEmail(kUser2Email)); + EXPECT_FALSE( + user2_pref_service()->GetBoolean(prefs::kShownPaletteWelcomeBubble)); + welcome_bubble_->ShowIfNeeded(); + EXPECT_TRUE(welcome_bubble_->BubbleShown()); +} + +} // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn index 78c04dc..a1dda89 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -294,6 +294,7 @@ "environment.cc", "environment.h", "event_types.h", + "export_template.h", "feature_list.cc", "feature_list.h", "file_descriptor_posix.h", @@ -467,7 +468,6 @@ "memory/discardable_shared_memory.h", "memory/free_deleter.h", "memory/linked_ptr.h", - "memory/manual_constructor.h", "memory/memory_coordinator_client.cc", "memory/memory_coordinator_client.h", "memory/memory_coordinator_client_registry.cc", @@ -1119,6 +1119,7 @@ public_deps = [ ":base_static", ":build_date", + ":cfi_flags", ":debugging_flags", "//base/numerics:base_numerics", ] @@ -1670,6 +1671,18 @@ } } +# Build flags for Control Flow Integrity +# https://www.chromium.org/developers/testing/control-flow-integrity +buildflag_header("cfi_flags") { + header = "cfi_flags.h" + flags = [ + # TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794. + "CFI_CAST_CHECK=$is_cfi && $use_cfi_cast", + "CFI_ENFORCEMENT_TRAP=$is_cfi && !$use_cfi_diag", + "CFI_ENFORCEMENT_DIAGNOSTIC=$is_cfi && $use_cfi_diag && !$use_cfi_recover", + ] +} + buildflag_header("debugging_flags") { header = "debugging_flags.h" header_dir = "base/debug" @@ -2415,15 +2428,6 @@ # data += [ "$root_out_dir/base_unittests.dSYM/" ] } } - - if (use_cfi_cast) { - # TODO(krasin): remove CFI_CAST_CHECK, see https://crbug.com/626794. - defines += [ "CFI_CAST_CHECK" ] - } - - if (use_cfi_diag && !use_cfi_recover) { - defines += [ "CFI_ENFORCEMENT_DIAGNOSTIC" ] - } } action("build_date") {
diff --git a/base/containers/small_map.h b/base/containers/small_map.h index 7ffd6d4a..495332f 100644 --- a/base/containers/small_map.h +++ b/base/containers/small_map.h
@@ -14,7 +14,6 @@ #include "base/containers/hash_tables.h" #include "base/logging.h" -#include "base/memory/manual_constructor.h" namespace base { @@ -67,13 +66,12 @@ // be used by default. If the wrapped map type has a strict weak // ordering "key_compare" (std::map does), that will be used to // implement equality by default. -// MapInit: A functor that takes a ManualConstructor<NormalMap>* and uses it to -// initialize the map. This functor will be called at most once per -// small_map, when the map exceeds the threshold of kArraySize and we -// are about to copy values from the array to the map. The functor -// *must* call one of the Init() methods provided by -// ManualConstructor, since after it runs we assume that the NormalMap -// has been initialized. +// MapInit: A functor that takes a NormalMap* and uses it to initialize the map. +// This functor will be called at most once per small_map, when the map +// exceeds the threshold of kArraySize and we are about to copy values +// from the array to the map. The functor *must* initialize the +// NormalMap* argument with placement new, since after it runs we +// assume that the NormalMap has been initialized. // // example: // base::small_map<std::map<string, int>> days;
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc index 597c81d..03df9db9 100644 --- a/base/debug/stack_trace_posix.cc +++ b/base/debug/stack_trace_posix.cc
@@ -38,6 +38,7 @@ #include "base/debug/proc_maps_linux.h" #endif +#include "base/cfi_flags.h" #include "base/debug/debugger.h" #include "base/logging.h" #include "base/macros.h" @@ -311,7 +312,7 @@ } PrintToStderr("\n"); -#if defined(CFI_ENFORCEMENT_TRAP) +#if BUILDFLAG(CFI_ENFORCEMENT_TRAP) if (signal == SIGILL && info->si_code == ILL_ILLOPN) { PrintToStderr( "CFI: Most likely a control flow integrity violation; for more " @@ -319,7 +320,7 @@ PrintToStderr( "https://www.chromium.org/developers/testing/control-flow-integrity\n"); } -#endif +#endif // BUILDFLAG(CFI_ENFORCEMENT_TRAP) debug::StackTrace().Print();
diff --git a/ipc/export_template.h b/base/export_template.h similarity index 98% rename from ipc/export_template.h rename to base/export_template.h index e743e19..aac8b7c 100644 --- a/ipc/export_template.h +++ b/base/export_template.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 IPC_EXPORT_TEMPLATE_H_ -#define IPC_EXPORT_TEMPLATE_H_ +#ifndef BASE_EXPORT_TEMPLATE_H_ +#define BASE_EXPORT_TEMPLATE_H_ // Synopsis // @@ -160,4 +160,4 @@ #undef EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT #undef EXPORT_TEMPLATE_TEST_MSVC_HACK_MSVC_HACK -#endif // IPC_EXPORT_TEMPLATE_H_ +#endif // BASE_EXPORT_TEMPLATE_H_
diff --git a/base/memory/manual_constructor.h b/base/memory/manual_constructor.h deleted file mode 100644 index e968d04..0000000 --- a/base/memory/manual_constructor.h +++ /dev/null
@@ -1,73 +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. - -// ManualConstructor statically-allocates space in which to store some -// object, but does not initialize it. You can then call the constructor -// and destructor for the object yourself as you see fit. This is useful -// for memory management optimizations, where you want to initialize and -// destroy an object multiple times but only allocate it once. -// -// (When I say ManualConstructor statically allocates space, I mean that -// the ManualConstructor object itself is forced to be the right size.) -// -// For example usage, check out base/containers/small_map.h. - -#ifndef BASE_MEMORY_MANUAL_CONSTRUCTOR_H_ -#define BASE_MEMORY_MANUAL_CONSTRUCTOR_H_ - -#include <stddef.h> - -#include "base/compiler_specific.h" -#include "base/memory/aligned_memory.h" - -namespace base { - -template <typename Type> -class ManualConstructor { - public: - // No constructor or destructor because one of the most useful uses of - // this class is as part of a union, and members of a union cannot have - // constructors or destructors. And, anyway, the whole point of this - // class is to bypass these. - - // Support users creating arrays of ManualConstructor<>s. This ensures that - // the array itself has the correct alignment. - static void* operator new[](size_t size) { - return AlignedAlloc(size, alignof(Type)); - } - static void operator delete[](void* mem) { - AlignedFree(mem); - } - - inline Type* get() { return reinterpret_cast<Type*>(space_); } - inline const Type* get() const { - return reinterpret_cast<const Type*>(space_); - } - - inline Type* operator->() { return get(); } - inline const Type* operator->() const { return get(); } - - inline Type& operator*() { return *get(); } - inline const Type& operator*() const { return *get(); } - - template <typename... Ts> - inline void Init(Ts&&... params) { - new (space_) Type(std::forward<Ts>(params)...); - } - - inline void InitFromMove(ManualConstructor<Type>&& o) { - Init(std::move(*o)); - } - - inline void Destroy() { - get()->~Type(); - } - - private: - alignas(Type) char space_[sizeof(Type)]; -}; - -} // namespace base - -#endif // BASE_MEMORY_MANUAL_CONSTRUCTOR_H_
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 839d8b7..919c94e 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -62,6 +62,9 @@ namespace leveldb { class LevelDBMojoProxy; } +namespace media { +class BlockingUrlProtocol; +} namespace mojo { class SyncCallRestrictions; namespace edk { @@ -213,6 +216,7 @@ FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed); friend class leveldb::LevelDBMojoProxy; + friend class media::BlockingUrlProtocol; friend class net::OCSPScopedAllowBaseSyncPrimitives; ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
diff --git a/base/tools_sanity_unittest.cc b/base/tools_sanity_unittest.cc index 550845c..af2081d3 100644 --- a/base/tools_sanity_unittest.cc +++ b/base/tools_sanity_unittest.cc
@@ -9,6 +9,7 @@ #include <stddef.h> #include "base/atomicops.h" +#include "base/cfi_flags.h" #include "base/debug/asan_invalid_access.h" #include "base/debug/profiler.h" #include "base/message_loop/message_loop.h" @@ -342,7 +343,7 @@ EXPECT_EQ(kMagicValue, shared); } -#if defined(CFI_ENFORCEMENT_TRAP) +#if BUILDFLAG(CFI_ENFORCEMENT_TRAP) #if defined(OS_WIN) #define CFI_ERROR_MSG "EXCEPTION_ILLEGAL_INSTRUCTION" #elif defined(OS_ANDROID) @@ -352,9 +353,9 @@ #else #define CFI_ERROR_MSG "ILL_ILLOPN" #endif -#elif defined(CFI_ENFORCEMENT_DIAGNOSTIC) +#elif BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC) #define CFI_ERROR_MSG "runtime error: control flow integrity check" -#endif // CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC +#endif // BUILDFLAG(CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC) #if defined(CFI_ERROR_MSG) class A { @@ -400,7 +401,7 @@ } // TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794. -#if defined(CFI_CAST_CHECK) +#if BUILDFLAG(CFI_CAST_CHECK) TEST(ToolsSanityTest, BadDerivedCast) { A a; EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG); @@ -418,8 +419,8 @@ A a; EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG); } -#endif // CFI_CAST_CHECK +#endif // BUILDFLAG(CFI_CAST_CHECK) -#endif // CFI_ERROR_MSG +#endif // CFI_ERROR_MSG } // namespace base
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 6d705aa0..038522b 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -138,6 +138,7 @@ is_clang = current_os == "mac" || current_os == "ios" || current_os == "chromeos" || current_os == "fuchsia" || current_os == "android" || + (current_os == "win" && host_os != "win") || (current_os == "linux" && current_cpu != "s390x" && current_cpu != "s390" && current_cpu != "ppc64" && current_cpu != "ppc" && current_cpu != "mips" && current_cpu != "mips64") @@ -245,7 +246,9 @@ _default_toolchain = host_toolchain } else if (target_os == "win") { # On Windows we use the same toolchain for host and target by default. - assert(target_os == host_os, "Win cross-compiles only work on win hosts.") + # Beware, win cross builds mostly don't work yet, see docs/win_cross.md + # TODO(thakis): Allow on Mac as well soon. + assert(host_os != "mac", "https://crbug.com/774209") if (is_clang) { _default_toolchain = "//build/toolchain/win:win_clang_$target_cpu" } else {
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index 7a2990d..26807c06 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -378,8 +378,6 @@ if (use_cfi_recover) { cflags += [ "-fsanitize-recover=cfi" ] } - } else { - defines = [ "CFI_ENFORCEMENT_TRAP" ] } } }
diff --git a/build/toolchain/goma.gni b/build/toolchain/goma.gni index d7c2036f..e9cb9d1 100644 --- a/build/toolchain/goma.gni +++ b/build/toolchain/goma.gni
@@ -17,3 +17,6 @@ goma_dir = getenv("HOME") + "/goma" } } + +assert(!(is_win && host_os != "win") || !use_goma, + "goma does not yet work in win cross builds, b/64390790")
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 319f75ac..eedfc6d 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -214,7 +214,6 @@ "//components/payments/mojom:mojom_parser_java", "//components/policy/android:policy_java", "//components/safe_browsing/android:safe_browsing_java", - "//components/safe_json/android:safe_json_java", "//components/signin/core/browser/android:java", "//components/spellcheck/browser/android:java", "//components/sync/android:sync_java", @@ -232,6 +231,7 @@ "//mojo/public/java:system_java", "//net/android:net_java", "//printing:printing_java", + "//services/data_decoder/public/cpp/android:safe_json_java", "//services/service_manager/public/interfaces:interfaces_java", "//services/service_manager/public/java:service_manager_java", "//services/shape_detection:shape_detection_java",
diff --git a/chrome/android/java/DEPS b/chrome/android/java/DEPS index 6242546..3d789d0 100644 --- a/chrome/android/java/DEPS +++ b/chrome/android/java/DEPS
@@ -12,7 +12,6 @@ "+components/navigation_interception", "+components/offline_items_collection/core/android/java", "+components/payments/content/android/java/src/org/chromium/components/payments", - "+components/safe_json/android/java", "+components/sync/android/java/src/org/chromium/components/sync", "+components/web_contents_delegate_android", "+components/web_restrictions",
diff --git a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml index 1c2a7407..87c8f9e 100644 --- a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml +++ b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml
@@ -34,9 +34,9 @@ android:layout_height="2dp" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" - chrome:colorBackground="@color/google_grey_500" - chrome:colorProgress="@color/google_grey_300" - chrome:colorSecondaryProgress="@color/google_blue_700" /> + chrome:colorBackground="@color/google_grey_300" + chrome:colorProgress="@color/google_blue_500_alpha_38_opaque" + chrome:colorSecondaryProgress="@color/google_blue_500" /> <TextView android:id="@+id/size_free_and_other_apps"
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 98681000..fb1f0131 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -204,5 +204,6 @@ <color name="media_viewer_bg">#000000</color> <color name="image_viewer_bg">#0e0e0e</color> <color name="modern_toolbar_bg">#E6FFFFFF</color> + <color name="google_blue_500_alpha_38_opaque">#B7D1FB</color> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 5981ee6..882ac57 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -515,7 +515,9 @@ if (!DataReductionPromoScreen.launchDataReductionPromo( this, currentModel.isIncognito())) { if (FeatureUtilities.shouldShowChromeHomePromoForStartup()) { - new ChromeHomePromoDialog(this).show(); + new ChromeHomePromoDialog( + this, ChromeHomePromoDialog.ShowReason.STARTUP) + .show(); } else if (getBottomSheet() != null) { getBottomSheet().showHelpBubbleIfNecessary(); } @@ -1614,7 +1616,9 @@ if (getBottomSheet() != null && ChromeFeatureList.isEnabled( ChromeFeatureList.CHROME_HOME_PROMO)) { - new ChromeHomePromoDialog(ChromeTabbedActivity.this).show(); + new ChromeHomePromoDialog(ChromeTabbedActivity.this, + ChromeHomePromoDialog.ShowReason.MENU) + .show(); return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java index 7eb85a1..3aa4da0a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java
@@ -17,6 +17,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.base.StrictModeContext; import org.chromium.chrome.browser.UrlConstants; import java.io.File; @@ -263,7 +264,9 @@ (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); Uri contentUri = null; try { - contentUri = manager.getUriForDownloadedFile(downloadId); + try (StrictModeContext unused = StrictModeContext.allowDiskReads()) { + contentUri = manager.getUriForDownloadedFile(downloadId); + } } catch (SecurityException e) { Log.e(TAG, "unable to get content URI from DownloadManager"); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index ed4261a..f28a95c6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -32,7 +32,6 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.UrlConstants; @@ -53,6 +52,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; import org.chromium.chrome.browser.util.ConversionUtils; +import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.Tracker; @@ -69,6 +69,7 @@ import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Calendar; @@ -126,17 +127,16 @@ public static boolean showDownloadManager(@Nullable Activity activity, @Nullable Tab tab) { // Figure out what tab was last being viewed by the user. if (activity == null) activity = ApplicationStatus.getLastTrackedFocusedActivity(); + + if (openDownloadsManagerInBottomSheet(activity)) return true; + if (tab == null && activity instanceof ChromeTabbedActivity) { tab = ((ChromeTabbedActivity) activity).getActivityTab(); } Context appContext = ContextUtils.getApplicationContext(); - if (activity instanceof ChromeActivity - && ((ChromeActivity) activity).getBottomSheet() != null) { - ((ChromeActivity) activity) - .getBottomSheetContentController() - .showContentAndOpenSheet(R.id.action_downloads); - } else if (DeviceFormFactor.isTablet()) { + + if (DeviceFormFactor.isTablet()) { // Download Home shows up as a tab on tablets. LoadUrlParams params = new LoadUrlParams(UrlConstants.DOWNLOADS_URL); if (tab == null || !tab.isInitialized()) { @@ -184,6 +184,42 @@ } /** + * @param activity The activity the download manager should be displayed in if applicable or + * the last tracked focused activity. + * @return Whether the downloads manager was opened in the Chrome Home bottom sheet. + */ + private static boolean openDownloadsManagerInBottomSheet(Activity activity) { + if (!FeatureUtilities.isChromeHomeEnabled()) return false; + + Context appContext = ContextUtils.getApplicationContext(); + + ChromeTabbedActivity tabbedActivity = null; + if (activity instanceof ChromeTabbedActivity) { + tabbedActivity = (ChromeTabbedActivity) activity; + } else { + // Iterate through all activities looking for an instance of ChromeTabbedActivity. + List<WeakReference<Activity>> list = ApplicationStatus.getRunningActivities(); + for (WeakReference<Activity> ref : list) { + Activity currentActivity = ref.get(); + if (currentActivity instanceof ChromeTabbedActivity) { + tabbedActivity = (ChromeTabbedActivity) currentActivity; + } + } + } + + if (tabbedActivity == null) return false; + + tabbedActivity.getBottomSheetContentController().showContentAndOpenSheet( + R.id.action_downloads); + + // Bring the ChromeTabbedActivity to the front. + Intent intent = new Intent(appContext, tabbedActivity.getClass()); + intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); + activity.startActivity(intent); + return true; + } + + /** * @return Whether or not the Intent corresponds to a DownloadActivity that should show off the * record downloads. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java index f8f43692..87973c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java
@@ -9,9 +9,6 @@ import android.os.Environment; import android.os.StatFs; import android.support.v7.widget.RecyclerView; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -196,21 +193,19 @@ String spaceFree = DownloadUtils.getStringForBytes(context, FREE_STRINGS, mFreeBytes); String spaceUsedByOtherApps = DownloadUtils.getStringForBytes(context, OTHER_STRINGS, bytesUsedByOtherApps); - SpannableString spannable = new SpannableString( + mSpaceFreeAndOtherAppsTextView.setText( context.getResources().getString(R.string.download_manager_ui_space_free_and_other, spaceFree, spaceUsedByOtherApps)); - ForegroundColorSpan colorSpan = new ForegroundColorSpan( - ApiCompatibilityUtils.getColor(context.getResources(), R.color.black_alpha_54)); - spannable.setSpan(colorSpan, 0, spaceFree.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - mSpaceFreeAndOtherAppsTextView.setText(spannable); // Set a minimum size for the download size so that it shows up in the progress bar. - long onePercentOfSystem = fileSystemBytes == 0 ? 0 : fileSystemBytes / 100; - long fudgedBytesUsedByDownloads = Math.max(bytesUsedByDownloads, onePercentOfSystem); + long threePercentOfSystem = fileSystemBytes == 0 ? 0 : fileSystemBytes / 100 * 3; + long fudgedBytesUsedByDownloads = Math.max(bytesUsedByDownloads, threePercentOfSystem); + long fudgedBytesUsedByOtherApps = Math.max(bytesUsedByOtherApps, threePercentOfSystem); // Indicate how much space has been used as a progress bar. The percentage used by // downloads is shown by the non-overlapped area of the primary and secondary progressbar. - int percentageUsedTotal = computePercentage(bytesUsedTotal, fileSystemBytes); + int percentageUsedTotal = computePercentage( + fudgedBytesUsedByDownloads + fudgedBytesUsedByOtherApps, fileSystemBytes); int percentageDownloaded = computePercentage(fudgedBytesUsedByDownloads, fileSystemBytes); mSpaceBar.setProgress(percentageUsedTotal); mSpaceBar.setSecondaryProgress(percentageDownloaded);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 7cbce18..2a54e3a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -420,7 +420,7 @@ NoUnderlineClickableSpan link = new NoUnderlineClickableSpan() { @Override public void onClick(View view) { - new ChromeHomePromoDialog(mActivity).show(); + new ChromeHomePromoDialog(mActivity, ChromeHomePromoDialog.ShowReason.NTP).show(); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncUserDataWiper.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncUserDataWiper.java index 0315af2..00f01fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncUserDataWiper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncUserDataWiper.java
@@ -4,10 +4,12 @@ package org.chromium.chrome.browser.sync; +import org.chromium.base.ContextUtils; import org.chromium.base.Promise; import org.chromium.chrome.browser.bookmarks.BookmarkModel; import org.chromium.chrome.browser.browsing_data.BrowsingDataType; import org.chromium.chrome.browser.browsing_data.TimePeriod; +import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim; import org.chromium.chrome.browser.preferences.privacy.BrowsingDataBridge; import org.chromium.chrome.browser.preferences.privacy.BrowsingDataBridge.OnClearBrowsingDataListener; @@ -30,6 +32,9 @@ public static Promise<Void> wipeSyncUserData() { final Promise<Void> promise = new Promise<>(); + // Partner bookmarks need to be loaded explicitly so that BookmarkModel can be loaded. + PartnerBookmarksShim.kickOffReading(ContextUtils.getApplicationContext()); + final BookmarkModel model = new BookmarkModel(); model.runAfterBookmarkModelLoaded(new Runnable() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java index ea0bbfb..a4fb7a99 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -25,6 +25,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.library_loader.LibraryLoader; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.firstrun.FirstRunUtils; @@ -299,6 +300,8 @@ if (ChromePreferenceManager.getInstance().isChromeHomeUserPreferenceSet()) { isUserPreferenceSet = true; sChromeHomeEnabled = prefManager.isChromeHomeUserEnabled(); + RecordHistogram.recordBooleanHistogram( + "Android.ChromeHome.UserPreference.Enabled", sChromeHomeEnabled); } else { sChromeHomeEnabled = prefManager.isChromeHomeEnabled(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/ChromeHomePromoDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/ChromeHomePromoDialog.java index d297768b..2895d00 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/ChromeHomePromoDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/ChromeHomePromoDialog.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.DialogInterface; import android.os.Bundle; +import android.support.annotation.IntDef; import android.support.v7.widget.SwitchCompat; import android.view.View; import android.widget.CompoundButton; @@ -14,6 +15,7 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.StrictModeContext; import org.chromium.base.SysUtils; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; @@ -24,6 +26,8 @@ import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.widget.PromoDialog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; /** @@ -31,6 +35,32 @@ * activity to bring a user in or out of the feature. */ public class ChromeHomePromoDialog extends PromoDialog { + /** Reasons that the promo was shown. */ + @IntDef({ShowReason.NTP, ShowReason.MENU, ShowReason.STARTUP, ShowReason.BOUNDARY}) + @Retention(RetentionPolicy.SOURCE) + public @interface ShowReason { + int NTP = 0; + int MENU = 1; + int STARTUP = 2; + int BOUNDARY = 3; + } + + /** States the promo was closed in. */ + @IntDef({PromoResult.ENABLED, PromoResult.DISABLED, PromoResult.REMAINED_ENABLED, + PromoResult.REMAINED_DISABLED, PromoResult.BOUNDARY}) + @Retention(RetentionPolicy.SOURCE) + private @interface PromoResult { + int ENABLED = 0; + int DISABLED = 1; + int REMAINED_ENABLED = 2; + int REMAINED_DISABLED = 3; + int BOUNDARY = 4; + } + + /** The reason the promo was shown. */ + @ShowReason + private final int mShowReason; + /** Whether or not the switch in the promo is enabled or disabled. */ private boolean mSwitchStateShouldEnable; @@ -40,10 +70,15 @@ /** * Default constructor. * @param activity The {@link Activity} showing the promo. + * @param showReason The reason that the promo was shown. */ - public ChromeHomePromoDialog(Activity activity) { + public ChromeHomePromoDialog(Activity activity, @ShowReason int showReason) { super(activity); setOnDismissListener(this); + mShowReason = showReason; + + RecordHistogram.recordEnumeratedHistogram("Android.ChromeHome.Promo.ShowReason", showReason, + ChromeHomePromoDialog.ShowReason.BOUNDARY); } @Override @@ -142,6 +177,30 @@ boolean userSetting = mUserMadeSelection ? mSwitchStateShouldEnable : FeatureUtilities.isChromeHomeEnabled(); + String histogramName = null; + switch (mShowReason) { + case ShowReason.MENU: + histogramName = "Android.ChromeHome.Promo.Result.Menu"; + break; + case ShowReason.NTP: + histogramName = "Android.ChromeHome.Promo.Result.NTP"; + break; + case ShowReason.STARTUP: + histogramName = "Android.ChromeHome.Promo.Result.Startup"; + break; + default: + assert false; + } + + @PromoResult + int state; + if (FeatureUtilities.isChromeHomeEnabled()) { + state = userSetting ? PromoResult.REMAINED_ENABLED : PromoResult.DISABLED; + } else { + state = userSetting ? PromoResult.ENABLED : PromoResult.REMAINED_DISABLED; + } + RecordHistogram.recordEnumeratedHistogram(histogramName, state, PromoResult.BOUNDARY); + boolean restartRequired = userSetting != FeatureUtilities.isChromeHomeEnabled(); FeatureUtilities.switchChromeHomeUserSetting(userSetting);
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 81201be..1c478ee 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -110,12 +110,6 @@ #include "components/metrics/leak_detector/leak_detector.h" #endif -#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) -#include "mash/common/config.h" // nogncheck -#include "services/ui/public/interfaces/constants.mojom.h" // nogncheck - -#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) - #if defined(OS_ANDROID) #include "base/android/java_exception_reporter.h" #include "chrome/browser/android/crash/pure_java_exception_handler.h" @@ -1120,22 +1114,3 @@ } return service_manager::ProcessType::kDefault; } - -bool ChromeMainDelegate::ShouldTerminateServiceManagerOnInstanceQuit( - const service_manager::Identity& identity, - int* exit_code) { -#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) - if (identity.name() == mash::common::GetWindowManagerServiceName() || - identity.name() == ui::mojom::kServiceName || - identity.name() == content::mojom::kPackagedServicesServiceName) { - // Quit the main process if an important child (e.g. window manager) dies. - // On Chrome OS the OS-level session_manager will restart the main process. - *exit_code = 1; - LOG(ERROR) << "Main process exiting because service " << identity.name() - << " quit unexpectedly."; - return true; - } -#endif // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) - - return false; -}
diff --git a/chrome/app/chrome_main_delegate.h b/chrome/app/chrome_main_delegate.h index 3bfe602..5510677 100644 --- a/chrome/app/chrome_main_delegate.h +++ b/chrome/app/chrome_main_delegate.h
@@ -52,9 +52,6 @@ #endif bool ShouldEnableProfilerRecording() override; service_manager::ProcessType OverrideProcessType() override; - bool ShouldTerminateServiceManagerOnInstanceQuit( - const service_manager::Identity& identity, - int* exit_code) override; content::ContentBrowserClient* CreateContentBrowserClient() override; content::ContentGpuClient* CreateContentGpuClient() override;
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index acf5d47..d0911772 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10945,17 +10945,6 @@ Completion available: <ph name="COMPLETION_TEXT">$1</ph> </message> </if> - <if expr="enable_vr"> - <message name="IDS_VR_SHELL_EXIT_PROMPT_DESCRIPTION" desc="Text on the exit prompt that shows up when the user tries to use a feature that is not supported in VR"> - This feature is not supported in VR - </message> - <message name="IDS_VR_SHELL_EXIT_PROMPT_DESCRIPTION_SITE_INFO" desc="Text on the exit prompt that shows up when the user clicks on URL bar security icon in VR"> - Site information is not available in VR - </message> - <message name="IDS_VR_SHELL_EXIT_PROMPT_EXIT_VR_BUTTON" desc="Text on the exit button of the exit prompt that shows up when the user clicks on URL bar security icon in VR"> - EXIT VR - </message> - </if> <!-- Ad Blocking UI strings. --> <message name="IDS_ALWAYS_ALLOW_ADS" desc="Explanation associated with a toggle to allow ads after ads have been blocked on the page. To be used on pages where the ad blocking UI is governed by a persistent permissions-based whitelist."> @@ -11099,19 +11088,37 @@ <message name="IDS_SCREEN_CAPTURE_NOTIFICATION_TEXT_2" desc="Text to be shown as a notification when screen capture is in progress."> Sharing screen </message> - <message name="IDS_VR_UNDER_DEVELOPMENT_NOTICE" desc="Text to be shown below the URL bar to announce that this is under development."> - This is an early release. Some features, like search and text entry, are not yet available. - </message> - <message name="IDS_VR_POWERED_BY_CHROME_MESSAGE" desc="A message indicating that the current page is running in Chrome."> - Powered by Chrome - </message> </if> - <!-- VR specific strings --> + <!-- Strings that are only used when VR devices are supported --> + <!-- TODO(ddorwin): Use consistent naming schemes for VR strings. --> <if expr="enable_vr"> <message name="IDS_PRESS_APP_TO_EXIT" desc="Text displayed in a transient bubble to tell users how to return from cinema mode (where the page displayed in a cinema like environment) or presentation mode (where the WebVR page occupies the entire screen) to normal mode."> Press App button to exit </message> + + <!-- VR browser --> + <!-- TODO(https://crbug.com/731802): Only build these when the VR browser is supported. --> + <message name="IDS_VR_SHELL_EXIT_PROMPT_DESCRIPTION" desc="Text on the exit prompt that shows up when the user tries to use a feature that is not supported in VR"> + This feature is not supported in VR + </message> + <message name="IDS_VR_SHELL_EXIT_PROMPT_DESCRIPTION_SITE_INFO" desc="Text on the exit prompt that shows up when the user clicks on URL bar security icon in VR"> + Site information is not available in VR + </message> + <message name="IDS_VR_SHELL_EXIT_PROMPT_EXIT_VR_BUTTON" desc="Text on the exit button of the exit prompt that shows up when the user clicks on URL bar security icon in VR"> + EXIT VR + </message> + <message name="IDS_PAGE_INFO_VR_BROWSER_UNSUPPORTED_MODE" desc="This text is displayed as a large toast to inform the user that they cannot currently browse in VR and they will soon exit VR mode."> + This page contains features not yet supported in VR. Exiting... + </message> + <message name="IDS_VR_UNDER_DEVELOPMENT_NOTICE" desc="Text to be shown below the URL bar to announce that this is under development."> + This is an early release. Some features, like search and text entry, are not yet available. + </message> + + <!-- TODO(https://crbug.com/774199): Make this <if expr="is_android"> --> + <message name="IDS_VR_POWERED_BY_CHROME_MESSAGE" desc="A message indicating that the current page is running in Chrome."> + Powered by Chrome + </message> </if> </messages> </release>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3bb9e57..73f0b2c1 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1217,6 +1217,10 @@ "renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm", "renderer_preferences_util.cc", "renderer_preferences_util.h", + "resource_coordinator/browser_child_process_watcher.cc", + "resource_coordinator/browser_child_process_watcher.h", + "resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.cc", + "resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.h", "resource_coordinator/resource_coordinator_render_process_probe.cc", "resource_coordinator/resource_coordinator_render_process_probe.h", "resource_coordinator/resource_coordinator_web_contents_observer.cc", @@ -1634,7 +1638,6 @@ "//components/rappor:rappor_recorder", "//components/renderer_context_menu", "//components/resources", - "//components/safe_json", "//components/search", "//components/search_engines", "//components/search_provider_logos",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 97b6ad6..8ce2fba7 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -149,6 +149,7 @@ "+third_party/WebKit/public/web/WebMediaPlayerAction.h", "+third_party/WebKit/public/web/WebPluginAction.h", "+third_party/WebKit/public/web/WebTextDirection.h", + "+third_party/WebKit/public/web/WebTriggeringEventInfo.h", "+third_party/WebKit/public/web/window_features.mojom.h", # Unlike other WebKit directories WebKit/common is for the files that
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 998fe3b..6fba5d6 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3327,12 +3327,6 @@ flag_descriptions::kAsyncImageDecodingDescription, kOsAll, MULTI_VALUE_TYPE(kAsyncImageDecodingChoices)}, - {"capture-thumbnail-on-navigating-away", - flag_descriptions::kCaptureThumbnailOnNavigatingAwayName, - flag_descriptions::kCaptureThumbnailOnNavigatingAwayDescription, - kOsDesktop, - FEATURE_VALUE_TYPE(features::kCaptureThumbnailOnNavigatingAway)}, - #if defined(OS_CHROMEOS) {"disable-lock-screen-apps", flag_descriptions::kDisableLockScreenAppsName, flag_descriptions::kDisableLockScreenAppsDescription, kOsCrOS,
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc index 92c823d6..92a8285 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "base/values.h" -#include "components/safe_json/safe_json_parser.h" #include "net/base/load_flags.h" #include "net/base/url_util.h" #include "net/http/http_response_headers.h" @@ -16,6 +15,7 @@ #include "net/http/http_util.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request_status.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" namespace { const char kDigitalAssetLinksBaseURL[] = @@ -70,7 +70,8 @@ std::string response_body; source->GetResponseAsString(&response_body); - safe_json::SafeJsonParser::Parse( + data_decoder::SafeJsonParser::Parse( + /* connector=*/nullptr, // Connector is unused on Android. response_body, base::Bind(&DigitalAssetLinksHandler::OnJSONParseSucceeded, weak_ptr_factory_.GetWeakPtr()),
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc b/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc index 33727128..9a87eef 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc
@@ -10,13 +10,13 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/values.h" -#include "components/safe_json/testing_json_parser.h" #include "content/public/test/test_browser_thread.h" #include "net/base/net_errors.h" #include "net/http/http_status_code.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "testing/gtest/include/gtest/gtest.h" namespace digital_asset_links { @@ -74,7 +74,7 @@ private: base::MessageLoop message_loop_; - safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; content::TestBrowserThread io_thread_; net::TestURLFetcherFactory url_fetcher_factory_;
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 5d798a19..cc0bc99 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -63,6 +63,7 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" +#include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/download_test_observer.h" @@ -3527,6 +3528,38 @@ watcher.Wait(); } +// Makes sure that a webview will display correctly after reloading it after a +// crash. +IN_PROC_BROWSER_TEST_P(WebViewTest, ReloadAfterCrash) { + if (!base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames)) + return; + + // Load guest and wait for it to appear. + LoadAppWithGuest("web_view/simple"); + EXPECT_TRUE(GetGuestWebContents()->GetMainFrame()->GetView()); + WaitForChildFrameSurfaceReady(GetGuestWebContents()->GetMainFrame()); + + // Kill guest. + auto* rph = GetGuestWebContents()->GetMainFrame()->GetProcess(); + content::RenderProcessHostWatcher crash_observer( + rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + EXPECT_TRUE(rph->Shutdown(content::RESULT_CODE_KILLED, false)); + crash_observer.Wait(); + EXPECT_FALSE(GetGuestWebContents()->GetMainFrame()->GetView()); + + // Reload guest and make sure it appears. + content::TestNavigationObserver load_observer(GetGuestWebContents()); + EXPECT_TRUE(ExecuteScript(GetEmbedderWebContents(), + "document.querySelector('webview').reload()")); + load_observer.Wait(); + EXPECT_TRUE(GetGuestWebContents()->GetMainFrame()->GetView()); + + // When the frame passed has a RenderWidgetHostViewChildFrame, + // WaitForChildFrameSurfaceReady will only return when the guest is embedded + // within the root surface. + WaitForChildFrameSurfaceReady(GetGuestWebContents()->GetMainFrame()); +} + IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, LoadWebViewAccessibility) { LoadAppWithGuest("web_view/focus_accessibility"); content::WebContents* web_contents = GetFirstAppWindowWebContents();
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 4d8b991..b8010a4 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -104,7 +104,6 @@ #include "components/prefs/pref_service.h" #include "components/rappor/public/rappor_utils.h" #include "components/rappor/rappor_service_impl.h" -#include "components/safe_json/safe_json_parser.h" #include "components/signin/core/common/profile_management_switches.h" #include "components/subresource_filter/content/browser/content_ruleset_service.h" #include "components/subresource_filter/core/browser/ruleset_service.h"
diff --git a/chrome/browser/browser_process_impl_unittest.cc b/chrome/browser/browser_process_impl_unittest.cc index 5299c8f..66810e4b 100644 --- a/chrome/browser/browser_process_impl_unittest.cc +++ b/chrome/browser/browser_process_impl_unittest.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread.h" +#include "content/public/test/test_service_manager_context.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_WIN) @@ -54,6 +55,10 @@ // managed separately. void StartSecondaryThreads() { base::TaskScheduler::GetInstance()->StartWithDefaultParams(); + // TestServiceManagerContext creation requires the task scheduler to be + // started. + service_manager_context_ = + std::make_unique<content::TestServiceManagerContext>(); io_thread_->StartIOThread(); } @@ -61,6 +66,8 @@ // The UI thread needs to be alive while BrowserProcessImpl is alive, and is // managed separately. void DestroySecondaryThreads() { + // TestServiceManagerContext must be destroyed before the IO thread. + service_manager_context_.reset(); // Spin the runloop to allow posted tasks to be processed. base::RunLoop().RunUntilIdle(); io_thread_.reset(); @@ -83,6 +90,7 @@ #endif std::unique_ptr<content::TestBrowserThread> io_thread_; base::CommandLine command_line_; + std::unique_ptr<content::TestServiceManagerContext> service_manager_context_; std::unique_ptr<BrowserProcessImpl> browser_process_impl_; };
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 64bf982..3886f1b 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -79,6 +79,7 @@ #include "chrome/browser/renderer_host/chrome_render_message_filter.h" #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" #include "chrome/browser/resource_coordinator/background_tab_navigation_throttle.h" +#include "chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.h" #include "chrome/browser/safe_browsing/certificate_reporting_service.h" #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" #include "chrome/browser/safe_browsing/chrome_password_protection_service.h" @@ -322,13 +323,6 @@ #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h" #endif -#if defined(USE_AURA) -#include "services/service_manager/runner/common/client_util.h" -#include "services/ui/public/cpp/gpu/gpu.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/views/mus/mus_client.h" -#endif - #if defined(USE_X11) #include "chrome/browser/chrome_browser_main_extra_parts_x11.h" #endif @@ -925,6 +919,8 @@ main_parts->AddParts(new ChromeBrowserMainExtraPartsX11()); #endif + main_parts->AddParts(new ChromeBrowserMainExtraPartsResourceCoordinator); + main_parts->AddParts(new ChromeBrowserMainExtraPartsProfiling); chrome::AddMetricsExtraParts(main_parts); @@ -1854,7 +1850,7 @@ base::CommandLine* command_line) { #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) // Mash services do their own resource loading. - if (IsMashServiceName(identity.name())) { + if (mash_service_registry::IsMashServiceName(identity.name())) { // This switch is used purely for debugging to make it easier to know what // service a process is running. command_line->AppendSwitchASCII("mash-service-name", identity.name()); @@ -2688,15 +2684,6 @@ return NULL; } -gpu::GpuChannelEstablishFactory* -ChromeContentBrowserClient::GetGpuChannelEstablishFactory() { -#if defined(USE_AURA) - if (views::MusClient::Exists()) - return views::MusClient::Get()->window_tree_client()->gpu(); -#endif - return nullptr; -} - bool ChromeContentBrowserClient::AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, @@ -3115,10 +3102,18 @@ #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMash)) - RegisterOutOfProcessServicesForMash(services); + mash_service_registry::RegisterOutOfProcessServices(services); #endif } +bool ChromeContentBrowserClient::ShouldTerminateOnServiceQuit( + const service_manager::Identity& id) { +#if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES) + return mash_service_registry::ShouldTerminateOnServiceQuit(id.name()); +#endif + return false; +} + std::unique_ptr<base::Value> ChromeContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index f33a3d7..375e69c 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -244,7 +244,6 @@ void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; content::BrowserPpapiHost* GetExternalBrowserPpapiHost( int plugin_process_id) override; - gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory() override; bool AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, @@ -312,6 +311,8 @@ void RegisterInProcessServices(StaticServiceMap* services) override; void RegisterOutOfProcessServices( OutOfProcessServiceMap* services) override; + bool ShouldTerminateOnServiceQuit( + const service_manager::Identity& id) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( base::StringPiece name) override; std::vector<content::ContentBrowserClient::ServiceManifestInfo>
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index b0acc96..6249451 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -48,6 +48,12 @@ #include "chrome/test/base/search_test_utils.h" #endif +#if defined(OS_CHROMEOS) +#include "ash/public/interfaces/constants.mojom.h" +#include "content/public/common/service_names.mojom.h" +#include "services/ui/public/interfaces/constants.mojom.h" +#endif + using content::BrowsingDataFilterBuilder; using testing::_; using ChromeContentBrowserClientTest = testing::Test; @@ -406,3 +412,33 @@ EXPECT_EQ("", client.GetMetricSuffixForURL( GURL("https://www.google.com/search?notaquery=nope"))); } + +#if defined(OS_CHROMEOS) + +// This behavior only matters on Chrome OS, which is why this isn't wrapped in +// ENABLE_MASH_PACKAGED_SERVICES (which is used for Linux Ozone). +TEST(ChromeContentBrowserClientTest, ShouldTerminateOnServiceQuit) { + const struct { + std::string service_name; + bool expect_terminate; + } kTestCases[] = { + // Don't terminate for invalid service names. + {"", false}, + {"unknown-name", false}, + // Don't terminate for some well-known browser services. + {content::mojom::kBrowserServiceName, false}, + {content::mojom::kGpuServiceName, false}, + {content::mojom::kRendererServiceName, false}, + // Do terminate for some mash-specific cases. + {ui::mojom::kServiceName, true}, + {ash::mojom::kServiceName, true}, + }; + ChromeContentBrowserClient client; + for (const auto& test : kTestCases) { + service_manager::Identity id(test.service_name); + EXPECT_EQ(test.expect_terminate, client.ShouldTerminateOnServiceQuit(id)) + << "for service name " << test.service_name; + } +} + +#endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index a7a7e3910..402079b 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -109,7 +109,6 @@ "//components/renderer_context_menu", "//components/safe_browsing:csd_proto", "//components/safe_browsing/db:metadata_proto", - "//components/safe_json", "//components/session_manager/core", "//components/signin/core/browser", "//components/ssl_config", @@ -150,6 +149,7 @@ "//mojo/common", "//net", "//ppapi/proxy:ipc", # For PpapiMsg_LoadPlugin + "//services/data_decoder/public/cpp", "//services/device/public/interfaces", "//services/preferences/public/interfaces", "//services/service_manager/public/cpp",
diff --git a/chrome/browser/chromeos/arc/arc_util.cc b/chrome/browser/chromeos/arc/arc_util.cc index 82cd1ad5..e3da123 100644 --- a/chrome/browser/chromeos/arc/arc_util.cc +++ b/chrome/browser/chromeos/arc/arc_util.cc
@@ -32,7 +32,6 @@ #include "components/user_manager/known_user.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" -#include "google_apis/google_api_keys.h" namespace arc { @@ -41,9 +40,6 @@ constexpr char kLsbReleaseArcVersionKey[] = "CHROMEOS_ARC_ANDROID_SDK_VERSION"; constexpr char kAndroidMSdkVersion[] = "23"; -// Used as client id on bot tests. -constexpr char kDummyClientId[] = "dummytoken"; - // Contains set of profiles for which decline reson was already reported. base::LazyInstance<std::set<base::FilePath>>::DestructorAtExit g_profile_declined_set = LAZY_INSTANCE_INITIALIZER; @@ -237,15 +233,6 @@ return false; } - if ((!google_apis::IsGoogleChromeAPIKeyUsed() && - google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN) != - kDummyClientId) || - google_apis::IsClientIdOverridden()) { - VLOG_IF(1, IsReportingFirstTimeForProfile(profile)) - << "ARC is not supported for non-google client."; - return false; - } - return true; }
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc index 21d9f24e2..1f6c92fb 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
@@ -32,8 +32,9 @@ #include "components/policy/core/common/policy_namespace.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_service.h" -#include "components/safe_json/safe_json_parser.h" +#include "content/public/common/service_manager_connection.h" #include "crypto/sha2.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" namespace arc { @@ -378,7 +379,8 @@ // the callee interface. auto repeating_callback = base::AdaptCallbackForRepeating(std::move(callback)); - safe_json::SafeJsonParser::Parse( + data_decoder::SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), request, base::Bind(&ArcPolicyBridge::OnReportComplianceParseSuccess, weak_ptr_factory_.GetWeakPtr(), repeating_callback),
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc index c3e98198..95c6f5d 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -21,8 +21,9 @@ #include "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" -#include "components/safe_json/testing_json_parser.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_service_manager_context.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -156,8 +157,9 @@ Profile* profile() { return profile_; } private: - safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; content::TestBrowserThreadBundle thread_bundle_; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; + content::TestServiceManagerContext service_manager_context_; std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_; std::unique_ptr<TestingProfileManager> testing_profile_manager_; base::RunLoop run_loop_;
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc index 4596a77..de22ae4 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.cc
@@ -150,6 +150,7 @@ wizard_completed_timeout_(kWizardCompletedTimeout), binding_(this) { arc_bridge_service_->voice_interaction_arc_home()->AddObserver(this); + ArcSessionManager::Get()->AddObserver(this); } ArcVoiceInteractionArcHomeService::~ArcVoiceInteractionArcHomeService() = @@ -158,6 +159,16 @@ void ArcVoiceInteractionArcHomeService::Shutdown() { ResetTimeouts(); arc_bridge_service_->voice_interaction_arc_home()->RemoveObserver(this); + ArcSessionManager::Get()->RemoveObserver(this); +} + +void ArcVoiceInteractionArcHomeService::OnArcPlayStoreEnabledChanged( + bool enabled) { + if (!pending_pai_lock_) + return; + + pending_pai_lock_ = false; + LockPai(); } void ArcVoiceInteractionArcHomeService::LockPai() { @@ -166,6 +177,10 @@ arc::ArcSessionManager::Get()->pai_starter(); if (!pai_starter) { DLOG(ERROR) << "There is no PAI starter."; + // We could be starting before ARC session is started when user initiated + // voice interaction first before ARC is enabled. We will remember this + // and wait for ARC session started to try locking again. + pending_pai_lock_ = true; return; } pai_starter->AcquireLock();
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h index 5268df5..952be2a 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h
@@ -34,7 +34,8 @@ : public KeyedService, public mojom::VoiceInteractionArcHomeHost, public InstanceHolder<mojom::VoiceInteractionArcHomeInstance>::Observer, - public ArcAppListPrefs::Observer { + public ArcAppListPrefs::Observer, + public ArcSessionManager::Observer { public: // Returns singleton instance for the given BrowserContext, // or nullptr if the browser |context| is not allowed to use ARC. @@ -88,6 +89,9 @@ const std::string& intent) override; void OnTaskDestroyed(int32_t task_id) override; + // ArcSessionManager::Observer: + void OnArcPlayStoreEnabledChanged(bool enabled) override; + // Locks/Unlocks Play Auto Install. void LockPai(); void UnlockPai(); @@ -113,6 +117,9 @@ mojo::Binding<mojom::VoiceInteractionArcHomeHost> binding_; + // Whether there is a pending request to lock PAI before it's available. + bool pending_pai_lock_ = false; + DISALLOW_COPY_AND_ASSIGN(ArcVoiceInteractionArcHomeService); };
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc index c797585..d9d00a5 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -112,16 +112,11 @@ return false; } + window_visible_ = visible; IMECandidateWindowHandlerInterface* cw_handler = ui::IMEBridge::Get()->GetCandidateWindowHandler(); - - if (cw_handler) { - if (window_visible_ != visible) - cw_handler->OnCandidateWindowVisibilityChanged(visible); - - cw_handler->UpdateLookupTable(*candidate_window_, visible); - } - window_visible_ = visible; + if (cw_handler) + cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); return true; }
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index 2fd050a..569b0a41 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -17,10 +17,8 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/input_method/input_method_engine_base.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/aura/mus/input_method_mus.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h" -#include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" #include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/mock_ime_input_context_handler.h" @@ -150,16 +148,9 @@ mock_ime_input_context_handler_.reset(new ui::MockIMEInputContextHandler()); ui::IMEBridge::Get()->SetInputContextHandler( mock_ime_input_context_handler_.get()); - - mock_ime_candidate_window_handler_.reset( - new chromeos::MockIMECandidateWindowHandler()); - ui::IMEBridge::Get()->SetCandidateWindowHandler( - mock_ime_candidate_window_handler_.get()); } - ~InputMethodEngineTest() override { ui::IMEBridge::Get()->SetInputContextHandler(NULL); - ui::IMEBridge::Get()->SetCandidateWindowHandler(NULL); engine_.reset(); Shutdown(); } @@ -191,8 +182,6 @@ std::unique_ptr<ui::MockIMEInputContextHandler> mock_ime_input_context_handler_; - std::unique_ptr<chromeos::MockIMECandidateWindowHandler> - mock_ime_candidate_window_handler_; private: DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest); @@ -330,16 +319,5 @@ EXPECT_EQ(ONCOMPOSITIONBOUNDSCHANGED, observer_->GetCallsBitmapAndReset()); } -TEST_F(InputMethodEngineTest, ChangeCandidateWindowVisiblility) { - CreateEngine(true); - FocusIn(ui::TEXT_INPUT_TYPE_TEXT); - engine_->Enable(kTestImeComponentId); - std::string error; - bool is_candidate_window_visible = true; - engine_->SetCandidateWindowVisible(is_candidate_window_visible, &error); - EXPECT_EQ(is_candidate_window_visible, - mock_ime_candidate_window_handler_->is_candidate_window_visible()); -} - } // namespace input_method } // namespace chromeos
diff --git a/chrome/browser/component_updater/sth_set_component_installer_unittest.cc b/chrome/browser/component_updater/sth_set_component_installer_unittest.cc index 5af13717..0172fb1 100644 --- a/chrome/browser/component_updater/sth_set_component_installer_unittest.cc +++ b/chrome/browser/component_updater/sth_set_component_installer_unittest.cc
@@ -17,11 +17,11 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "base/version.h" -#include "components/safe_json/testing_json_parser.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/cert/signed_tree_head.h" #include "net/cert/sth_observer.h" #include "net/test/ct_test_util.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -85,7 +85,7 @@ // |policy_| should be destroyed before the |observer_| as it holds a pointer // to it. std::unique_ptr<STHSetComponentInstallerPolicy> policy_; - safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; private: DISALLOW_COPY_AND_ASSIGN(STHSetComponentInstallerTest);
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc index 02f3d932..232cbbbd 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -41,9 +41,9 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" -#include "components/safe_json/json_sanitizer.h" -#include "components/update_client/update_client_errors.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/service_manager_connection.h" +#include "services/data_decoder/public/cpp/json_sanitizer.h" namespace component_updater { @@ -175,7 +175,8 @@ return; } - safe_json::JsonSanitizer::Sanitize( + data_decoder::JsonSanitizer::Sanitize( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), unsafe_json, base::Bind(&OnWhitelistSanitizationResult, crx_id, task_runner, callback), base::Bind(&OnWhitelistSanitizationError, whitelist_path));
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc index c01c7a0..8317486 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer_unittest.cc
@@ -21,7 +21,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_path_override.h" -#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h" @@ -34,11 +33,13 @@ #include "components/component_updater/component_updater_service.h" #include "components/crx_file/id_util.h" #include "components/prefs/testing_pref_service.h" -#include "components/safe_json/testing_json_parser.h" #include "components/update_client/crx_update_item.h" #include "components/update_client/update_client.h" #include "components/update_client/utils.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_service_manager_context.h" +#include "content/public/test/test_utils.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -281,7 +282,7 @@ void RegisterExistingComponents() { local_state_.Set(prefs::kRegisteredSupervisedUserWhitelists, pref_); installer_->RegisterComponents(); - scoped_task_environment_.RunUntilIdle(); + content::RunAllTasksUntilIdle(); base::RunLoop().RunUntilIdle(); } @@ -294,11 +295,12 @@ EXPECT_EQ(version, component->version.GetString()); } - base::test::ScopedTaskEnvironment scoped_task_environment_; + content::TestBrowserThreadBundle thread_bundle_; TestingProfileManager testing_profile_manager_; base::ScopedPathOverride user_data_dir_override_; - safe_json::TestingJsonParser::ScopedFactoryOverride json_parser_override_; + data_decoder::TestingJsonParser::ScopedFactoryOverride json_parser_override_; TestingPrefServiceSimple local_state_; + content::TestServiceManagerContext service_manager_context_; std::unique_ptr<SupervisedUserWhitelistInstaller> installer_; base::FilePath whitelist_base_directory_; base::FilePath whitelist_directory_; @@ -370,7 +372,7 @@ }, &observer)); - scoped_task_environment_.RunUntilIdle(); + content::RunAllTasksUntilIdle(); observer.Wait(); EXPECT_EQ(whitelist_path_.value(), observer.whitelist_path().value()); @@ -428,7 +430,7 @@ { base::RunLoop run_loop; installer_->UnregisterWhitelist(kClientId, kCrxId); - scoped_task_environment_.RunUntilIdle(); + content::RunAllTasksUntilIdle(); run_loop.RunUntilIdle(); } EXPECT_TRUE(component_update_service_.registered_component()); @@ -442,7 +444,7 @@ // This does the same thing in our case as calling UnregisterWhitelist(), // but it exercises a different code path. profile_attributes_storage()->RemoveProfile(GetProfilePath(kOtherClientId)); - scoped_task_environment_.RunUntilIdle(); + content::RunAllTasksUntilIdle(); run_loop.RunUntilIdle(); } EXPECT_FALSE(component_update_service_.registered_component());
diff --git a/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc b/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc index 6b87c86..386e39a 100644 --- a/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc +++ b/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/ui/browser.h" @@ -17,6 +16,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobars_switches.h" +#include "content/public/test/test_utils.h" namespace { @@ -147,14 +147,8 @@ EXPECT_EQ(0u, GetInfoBarServiceFromTabIndex(i)->infobar_count()); } -// https://crbug.com/764079 -#if defined(OS_LINUX) || defined(OS_MACOSX) -#define MAYBE_InfoBarsDisabled DISABLED_InfoBarsDisabled -#else -#define MAYBE_InfoBarsDisabled InfoBarsDisabled -#endif IN_PROC_BROWSER_TEST_F(GlobalConfirmInfoBarWithInfoBarDisabledTest, - MAYBE_InfoBarsDisabled) { + InfoBarsDisabled) { ASSERT_EQ(1, browser()->tab_strip_model()->count()); auto delegate = base::MakeUnique<TestConfirmInfoBarDelegate>(); @@ -162,7 +156,7 @@ GlobalConfirmInfoBar::Show(std::move(delegate)); // In this case, the deletion is done asynchronously. - base::RunLoop().RunUntilIdle(); + content::RunAllPendingInMessageLoop(); ASSERT_FALSE(global_confirm_info_bar); }
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index af266e74..e2d2c0f 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -847,7 +847,6 @@ "//components/resources", "//components/safe_browsing/common:safe_browsing_prefs", "//components/safe_browsing/db:database_manager", - "//components/safe_json", "//components/search_engines", "//components/sessions", "//components/signin/core/browser", @@ -883,6 +882,7 @@ "//ppapi/features", "//printing/features", "//rlz/features", + "//services/data_decoder/public/cpp", "//services/identity/public/interfaces", "//services/service_manager/public/cpp", "//services/service_manager/public/interfaces",
diff --git a/chrome/browser/extensions/DEPS b/chrome/browser/extensions/DEPS index 4dd7e5e..09e7040 100644 --- a/chrome/browser/extensions/DEPS +++ b/chrome/browser/extensions/DEPS
@@ -13,7 +13,4 @@ # For access to testing command line switches. "+ppapi/shared_impl", - - # For safe_json - "+components/safe_json", ]
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index 038ee70..6e80a0f 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -25,11 +25,11 @@ #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/web_application_info.h" #include "components/favicon/core/favicon_service.h" -#include "components/safe_json/safe_json_parser.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/utility_process_host.h" #include "content/public/browser/utility_process_host_client.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/service_manager_connection.h" #include "extensions/browser/api/management/management_api.h" #include "extensions/browser/api/management/management_api_constants.h" #include "extensions/browser/extension_prefs.h" @@ -37,6 +37,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/common/disable_reason.h" #include "extensions/common/extension.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" namespace { @@ -200,7 +201,8 @@ GetPermissionWarningsByManifestFunctionDelegate( extensions::ManagementGetPermissionWarningsByManifestFunction* function, const std::string& manifest_str) const { - safe_json::SafeJsonParser::Parse( + data_decoder::SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), manifest_str, base::Bind( &extensions::ManagementGetPermissionWarningsByManifestFunction::
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index b51b5d9..b60a4a6 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -163,6 +163,8 @@ } CrxInstaller::~CrxInstaller() { + DCHECK(!service_weak_ || service_weak_->browser_terminating() || + installer_callback_.is_null()); DCHECK_CURRENTLY_ON(BrowserThread::UI); // Ensure |client_| and |install_checker_| data members are destroyed on the // UI thread. The |client_| dialog has a weak reference as |this| is its @@ -183,9 +185,9 @@ source_file_ = source_file.path; - scoped_refptr<SandboxedUnpacker> unpacker(new SandboxedUnpacker( + auto unpacker = base::MakeRefCounted<SandboxedUnpacker>( install_source_, creation_flags_, install_directory_, - installer_task_runner_.get(), this)); + installer_task_runner_.get(), this); if (!installer_task_runner_->PostTask( FROM_HERE, base::BindOnce(&SandboxedUnpacker::StartWithCrx, unpacker, @@ -194,6 +196,29 @@ } } +void CrxInstaller::InstallUnpackedCrx(const std::string& extension_id, + const std::string& public_key, + const base::FilePath& unpacked_dir) { + ExtensionService* service = service_weak_.get(); + if (!service || service->browser_terminating()) + return; + + NotifyCrxInstallBegin(); + + source_file_ = unpacked_dir; + + auto unpacker = base::MakeRefCounted<SandboxedUnpacker>( + install_source_, creation_flags_, install_directory_, + installer_task_runner_.get(), this); + + if (!installer_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&SandboxedUnpacker::StartWithDirectory, unpacker, + extension_id, public_key, unpacked_dir))) { + NOTREACHED(); + } +} + void CrxInstaller::InstallUserScript(const base::FilePath& source_file, const GURL& download_url) { DCHECK(!download_url.is_empty()); @@ -440,11 +465,11 @@ dnr_ruleset_checksum_ = dnr_ruleset_checksum; if (!install_icon.empty()) - install_icon_.reset(new SkBitmap(install_icon)); + install_icon_ = std::make_unique<SkBitmap>(install_icon); if (original_manifest) { - original_manifest_.reset( - new Manifest(Manifest::INVALID_LOCATION, std::move(original_manifest))); + original_manifest_ = std::make_unique<Manifest>( + Manifest::INVALID_LOCATION, std::move(original_manifest)); } // We don't have to delete the unpack dir explicity since it is a child of @@ -860,6 +885,13 @@ if (success) ConfirmReEnable(); + + if (!installer_callback_.is_null() && + !BrowserThread::GetTaskRunnerForThread(BrowserThread::UI) + ->PostTask(FROM_HERE, base::BindOnce(std::move(installer_callback_), + success))) { + NOTREACHED(); + } } void CrxInstaller::CleanupTempFiles() {
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index e76a62c0..9f807616 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h
@@ -21,6 +21,7 @@ #include "chrome/browser/extensions/webstore_installer.h" #include "chrome/common/extensions/extension_constants.h" #include "components/sync/model/string_ordinal.h" +#include "extensions/browser/extension_system.h" #include "extensions/browser/install_flag.h" #include "extensions/browser/preload_check.h" #include "extensions/browser/sandboxed_unpacker.h" @@ -71,6 +72,9 @@ // and won't safely be able to clean up UI thread notification listeners. class CrxInstaller : public SandboxedUnpackerClient { public: + // A callback to be executed when the install finishes. + using InstallerResultCallback = ExtensionSystem::InstallUpdateCallback; + // Used in histograms; do not change order. enum OffStoreInstallAllowReason { OffStoreInstallDisallowed, @@ -101,6 +105,13 @@ void InstallCrx(const base::FilePath& source_file); void InstallCrxFile(const CRXFileInfo& source_file); + // Install the unpacked crx in |unpacked_dir|. + // If |delete_source_| is true, |unpacked_dir| will be removed at the end of + // the installation. + void InstallUnpackedCrx(const std::string& extension_id, + const std::string& public_key, + const base::FilePath& unpacked_dir); + // Convert the specified user script into an extension and install it. void InstallUserScript(const base::FilePath& source_file, const GURL& download_url); @@ -201,6 +212,10 @@ set_install_flag(kInstallFlagDoNotSync, val); } + void set_installer_callback(InstallerResultCallback callback) { + installer_callback_ = std::move(callback); + } + bool did_handle_successfully() const { return did_handle_successfully_; } Profile* profile() { return profile_; } @@ -455,6 +470,9 @@ // Runs the above checks. std::unique_ptr<PreloadCheckGroup> check_group_; + // Invoked when the install is completed. + InstallerResultCallback installer_callback_; + DISALLOW_COPY_AND_ASSIGN(CrxInstaller); };
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index 848b2ee..801da55 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/at_exit.h" #include "base/files/file_path.h" +#include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" @@ -219,7 +220,7 @@ bool strict_manifest_checks) { std::unique_ptr<WebstoreInstaller::Approval> result; - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBlockingForTesting allow_io; base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir); std::string error; std::unique_ptr<base::DictionaryValue> parsed_manifest( @@ -234,6 +235,7 @@ void RunCrxInstaller(const WebstoreInstaller::Approval* approval, std::unique_ptr<ExtensionInstallPrompt> prompt, + CrxInstaller::InstallerResultCallback callback, const base::FilePath& crx_path) { ExtensionService* service = extensions::ExtensionSystem::Get( browser()->profile())->extension_service(); @@ -241,14 +243,35 @@ CrxInstaller::Create(service, std::move(prompt), approval)); installer->set_allow_silent_install(true); installer->set_is_gallery_install(true); + installer->set_installer_callback(std::move(callback)); installer->InstallCrx(crx_path); content::RunMessageLoop(); } + void RunCrxInstallerFromUnpackedDirectory( + std::unique_ptr<ExtensionInstallPrompt> prompt, + CrxInstaller::InstallerResultCallback callback, + const std::string& extension_id, + const std::string& public_key, + const base::FilePath& crx_directory) { + ExtensionService* service = + extensions::ExtensionSystem::Get(browser()->profile()) + ->extension_service(); + scoped_refptr<CrxInstaller> installer( + CrxInstaller::Create(service, std::move(prompt))); + installer->set_allow_silent_install(true); + installer->set_is_gallery_install(true); + installer->set_installer_callback(std::move(callback)); + installer->set_delete_source(true); + installer->InstallUnpackedCrx(extension_id, public_key, crx_directory); + content::RunMessageLoop(); + } + // Installs a crx from |crx_relpath| (a path relative to the extension test // data dir) with expected id |id|. void InstallWithPrompt(const char* ext_relpath, const std::string& id, + CrxInstaller::InstallerResultCallback callback, MockPromptProxy* mock_install_prompt) { base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath); @@ -259,19 +282,22 @@ base::FilePath crx_path = PackExtension(ext_path); EXPECT_FALSE(crx_path.empty()); RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(), - crx_path); + std::move(callback), crx_path); EXPECT_TRUE(mock_install_prompt->did_succeed()); } // Installs an extension and checks that it has scopes granted IFF // |record_oauth2_grant| is true. - void CheckHasEmptyScopesAfterInstall(const std::string& ext_relpath, - bool record_oauth2_grant) { + void CheckHasEmptyScopesAfterInstall( + const std::string& ext_relpath, + CrxInstaller::InstallerResultCallback callback, + bool record_oauth2_grant) { std::unique_ptr<MockPromptProxy> mock_prompt = CreateMockPromptProxyForBrowser(browser()); - InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt.get()); + InstallWithPrompt("browsertest/scopes", std::string(), std::move(callback), + mock_prompt.get()); std::unique_ptr<const PermissionSet> permissions = ExtensionPrefs::Get(browser()->profile()) @@ -344,7 +370,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, BlockedFileTypes) { const Extension* extension = InstallExtension(test_data_dir_.AppendASCII("blocked_file_types.crx"), 1); - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBlockingForTesting allow_io; EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.html"))); EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.nexe"))); EXPECT_FALSE(base::PathExists(extension->path().AppendASCII("test1.EXE"))); @@ -356,7 +382,7 @@ test_data_dir_.AppendASCII("theme_with_extension.crx"), 1); ASSERT_TRUE(extension); const base::FilePath& path = extension->path(); - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBlockingForTesting allow_io; EXPECT_TRUE( base::PathExists(path.AppendASCII("images/theme_frame_camo.PNG"))); EXPECT_TRUE( @@ -415,19 +441,35 @@ // true. #if defined(OS_WIN) #define MAYBE_GrantScopes DISABLED_GrantScopes +#define MAYBE_GrantScopes_WithCallback DISABLED_GrantScopes_WithCallback #else #define MAYBE_GrantScopes GrantScopes +#define MAYBE_GrantScopes_WithCallback GrantScopes_WithCallback #endif IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis, MAYBE_GrantScopes) { - EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes", - true)); + EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall( + "browsertest/scopes", CrxInstaller::InstallerResultCallback(), true)); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis, + MAYBE_GrantScopes_WithCallback) { + EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall( + "browsertest/scopes", + base::BindOnce([](bool success) { EXPECT_TRUE(success); }), true)); } IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis, DoNotGrantScopes) { - EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes", - false)); + EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall( + "browsertest/scopes", CrxInstaller::InstallerResultCallback(), false)); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis, + DoNotGrantScopes_WithCallback) { + EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall( + "browsertest/scopes", + base::BindOnce([](bool success) { EXPECT_TRUE(success); }), false)); } IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) { @@ -572,11 +614,126 @@ GetApproval("crx_installer/v2_no_permission_change/", id, false); RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(), + CrxInstaller::InstallerResultCallback(), test_data_dir_.AppendASCII("crx_installer/v1.crx")); EXPECT_TRUE(mock_prompt->did_succeed()); } +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, + NonStrictManifestCheck_WithCallback) { + std::unique_ptr<MockPromptProxy> mock_prompt = + CreateMockPromptProxyForBrowser(browser()); + + // We want to simulate the case where the webstore sends a more recent + // version of the manifest, but the downloaded .crx file is old since + // the newly published version hasn't fully propagated to all the download + // servers yet. So load the v2 manifest, but then install the v1 crx file. + const std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp"; + std::unique_ptr<WebstoreInstaller::Approval> approval = + GetApproval("crx_installer/v2_no_permission_change/", id, false); + + RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(), + base::BindOnce([](bool success) { EXPECT_TRUE(success); }), + test_data_dir_.AppendASCII("crx_installer/v1.crx")); + + EXPECT_TRUE(mock_prompt->did_succeed()); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, + InstallUnpackedCrx_FolderDoesNotExist) { + base::ScopedAllowBlockingForTesting allow_io; + std::unique_ptr<MockPromptProxy> mock_prompt = + CreateMockPromptProxyForBrowser(browser()); + + base::ScopedTempDir temp_dir; + EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); + + const base::FilePath folder = temp_dir.GetPath().AppendASCII("abcdef"); + EXPECT_FALSE(base::PathExists(folder)); + + const std::string public_key = "123456"; + RunCrxInstallerFromUnpackedDirectory( + mock_prompt->CreatePrompt(), + base::BindOnce([](bool success) { EXPECT_FALSE(success); }), + std::string(), public_key, folder); + + EXPECT_FALSE(mock_prompt->did_succeed()); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, + InstallUnpackedCrx_EmptyFolder) { + base::ScopedAllowBlockingForTesting allow_io; + std::unique_ptr<MockPromptProxy> mock_prompt = + CreateMockPromptProxyForBrowser(browser()); + + base::ScopedTempDir temp_dir; + EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); + EXPECT_TRUE(base::PathExists(temp_dir.GetPath())); + + const std::string public_key = "123456"; + RunCrxInstallerFromUnpackedDirectory( + mock_prompt->CreatePrompt(), + base::BindOnce([](bool success) { EXPECT_FALSE(success); }), + std::string(), public_key, temp_dir.GetPath()); + + EXPECT_FALSE(mock_prompt->did_succeed()); + EXPECT_FALSE(base::PathExists(temp_dir.GetPath())); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, + InstallUnpackedCrx_InvalidPublicKey) { + base::ScopedAllowBlockingForTesting allow_io; + std::unique_ptr<MockPromptProxy> mock_prompt = + CreateMockPromptProxyForBrowser(browser()); + + base::ScopedTempDir temp_dir; + EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); + EXPECT_TRUE(base::PathExists(temp_dir.GetPath())); + + const base::FilePath unpacked_path = + test_data_dir_.AppendASCII("good_unpacked"); + EXPECT_TRUE(base::PathExists(unpacked_path)); + EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir.GetPath(), false)); + + const std::string public_key = "123456"; + RunCrxInstallerFromUnpackedDirectory( + mock_prompt->CreatePrompt(), + base::BindOnce([](bool success) { EXPECT_FALSE(success); }), + std::string(), public_key, temp_dir.GetPath()); + + EXPECT_FALSE(mock_prompt->did_succeed()); + EXPECT_FALSE(base::PathExists(temp_dir.GetPath())); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallUnpackedCrx_Success) { + base::ScopedAllowBlockingForTesting allow_io; + std::unique_ptr<MockPromptProxy> mock_prompt = + CreateMockPromptProxyForBrowser(browser()); + + base::ScopedTempDir temp_dir; + EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); + EXPECT_TRUE(base::PathExists(temp_dir.GetPath())); + + const base::FilePath unpacked_path = + test_data_dir_.AppendASCII("good_unpacked"); + EXPECT_TRUE(base::PathExists(unpacked_path)); + EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir.GetPath(), false)); + + const std::string public_key = + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/" + "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j" + "kDuI7caxEGUucpP7GJRRHnm8Sx+" + "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB"; + RunCrxInstallerFromUnpackedDirectory( + mock_prompt->CreatePrompt(), + base::BindOnce([](bool success) { EXPECT_TRUE(success); }), std::string(), + public_key, temp_dir.GetPath()); + + EXPECT_TRUE(mock_prompt->did_succeed()); + EXPECT_FALSE(base::PathExists(temp_dir.GetPath())); +} + #if defined(OS_CHROMEOS) IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) { // kiosk_only is whitelisted from non-chromeos. @@ -607,7 +764,7 @@ crx_path, 1, extensions::Manifest::EXTERNAL_PREF); base::FilePath extension_path = extension->path(); EXPECT_TRUE(cache_dir.GetPath().IsParent(extension_path)); - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBlockingForTesting allow_io; EXPECT_TRUE(base::PathExists(extension_path)); std::string extension_id = extension->id();
diff --git a/chrome/browser/extensions/webstore_data_fetcher.cc b/chrome/browser/extensions/webstore_data_fetcher.cc index b078dd5..7411412 100644 --- a/chrome/browser/extensions/webstore_data_fetcher.cc +++ b/chrome/browser/extensions/webstore_data_fetcher.cc
@@ -9,12 +9,13 @@ #include "base/bind.h" #include "base/values.h" #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" -#include "components/safe_json/safe_json_parser.h" +#include "content/public/common/service_manager_connection.h" #include "extensions/common/extension_urls.h" #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" namespace { @@ -129,7 +130,8 @@ fetcher->GetResponseAsString(&webstore_json_data); // The parser will call us back via one of the callbacks. - safe_json::SafeJsonParser::Parse( + data_decoder::SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), webstore_json_data, base::Bind(&WebstoreDataFetcher::OnJsonParseSuccess, AsWeakPtr()), base::Bind(&WebstoreDataFetcher::OnJsonParseFailure, AsWeakPtr()));
diff --git a/chrome/browser/extensions/webstore_install_helper.cc b/chrome/browser/extensions/webstore_install_helper.cc index c3792ac..8689510 100644 --- a/chrome/browser/extensions/webstore_install_helper.cc +++ b/chrome/browser/extensions/webstore_install_helper.cc
@@ -7,11 +7,12 @@ #include "base/bind.h" #include "base/values.h" #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" -#include "components/safe_json/safe_json_parser.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/service_manager_connection.h" #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" using content::BrowserThread; @@ -44,7 +45,8 @@ void WebstoreInstallHelper::Start() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - safe_json::SafeJsonParser::Parse( + data_decoder::SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), manifest_, base::Bind(&WebstoreInstallHelper::OnJSONParseSucceeded, this), base::Bind(&WebstoreInstallHelper::OnJSONParseFailed, this));
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 38f31ac..2f548a60 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -89,13 +89,6 @@ "eligibility requirements for showing app banners, such as having a " "manifest, are met."; -const char kCaptureThumbnailOnNavigatingAwayName[] = - "Capture page thumbnail on navigating away"; -const char kCaptureThumbnailOnNavigatingAwayDescription[] = - "Capture a page thumbnail (for use on the New Tab page) when navigating " - "away from the current page, in addition to other times a thumbnail may be " - "captured."; - const char kCastStreamingHwEncodingName[] = "Cast Streaming hardware video encoding"; const char kCastStreamingHwEncodingDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index be689a1..2647220 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -81,9 +81,6 @@ extern const char kBypassAppBannerEngagementChecksName[]; extern const char kBypassAppBannerEngagementChecksDescription[]; -extern const char kCaptureThumbnailOnNavigatingAwayName[]; -extern const char kCaptureThumbnailOnNavigatingAwayDescription[]; - extern const char kCastStreamingHwEncodingName[]; extern const char kCastStreamingHwEncodingDescription[];
diff --git a/chrome/browser/mash_service_registry.cc b/chrome/browser/mash_service_registry.cc index 7e9861a..356b374 100644 --- a/chrome/browser/mash_service_registry.cc +++ b/chrome/browser/mash_service_registry.cc
@@ -18,6 +18,7 @@ #include "components/font_service/public/interfaces/constants.mojom.h" #endif // defined(OS_LINUX) && !defined(OS_ANDROID) +namespace mash_service_registry { namespace { struct Service { @@ -40,7 +41,7 @@ } // namespace -void RegisterOutOfProcessServicesForMash( +void RegisterOutOfProcessServices( content::ContentBrowserClient::OutOfProcessServiceMap* services) { for (size_t i = 0; i < arraysize(kServices); ++i) { (*services)[kServices[i].name] = @@ -55,3 +56,18 @@ } return false; } + +bool ShouldTerminateOnServiceQuit(const std::string& name) { + // Some services going down are treated as catastrophic failures, usually + // because both the browser and the service cache data about each other's + // state that is not rebuilt when the service restarts. + if (name == ui::mojom::kServiceName) + return true; +#if defined(OS_CHROMEOS) + if (name == ash::mojom::kServiceName) + return true; +#endif + return false; +} + +} // namespace mash_service_registry
diff --git a/chrome/browser/mash_service_registry.h b/chrome/browser/mash_service_registry.h index 7fc58de..76e72f1 100644 --- a/chrome/browser/mash_service_registry.h +++ b/chrome/browser/mash_service_registry.h
@@ -9,11 +9,18 @@ #include "content/public/browser/content_browser_client.h" +namespace mash_service_registry { + // Starts one of Mash's embedded services. -void RegisterOutOfProcessServicesForMash( +void RegisterOutOfProcessServices( content::ContentBrowserClient::OutOfProcessServiceMap* services); // Returns true if |name| identifies a mash related service. bool IsMashServiceName(const std::string& name); +// Returns true if the browser should exit when service |name| quits. +bool ShouldTerminateOnServiceQuit(const std::string& name); + +} // namespace mash_service_registry + #endif // CHROME_BROWSER_MASH_SERVICE_REGISTRY_H_
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc index f7bfa4a..34b8af1 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -7,7 +7,6 @@ #include "base/metrics/histogram_macros.h" #include "base/trace_event/memory_dump_request_args.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/metrics/renderer_uptime_tracker.h" #include "chrome/browser/profiles/profile_manager.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/service_manager_connection.h" @@ -33,7 +32,8 @@ void EmitBrowserMemoryMetrics(const ProcessMemoryDumpPtr& pmd, ukm::SourceId ukm_source_id, - ukm::UkmRecorder* ukm_recorder) { + ukm::UkmRecorder* ukm_recorder, + const base::Optional<base::TimeDelta>& uptime) { ukm::builders::Memory_Experimental builder(ukm_source_id); builder.SetProcessType(static_cast<int64_t>( memory_instrumentation::mojom::ProcessType::BROWSER)); @@ -52,6 +52,8 @@ UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Browser.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); builder.SetPrivateMemoryFootprint(pmd->os_dump->private_footprint_kb / 1024); + if (uptime) + builder.SetUptime(uptime.value().InSeconds()); builder.Record(ukm_recorder); } @@ -79,7 +81,8 @@ const ProcessMemoryDumpPtr& pmd, const resource_coordinator::mojom::PageInfoPtr& page_info, ukm::UkmRecorder* ukm_recorder, - int number_of_extensions) { + int number_of_extensions, + const base::Optional<base::TimeDelta>& uptime) { // UMA if (number_of_extensions == 0) { RENDERER_MEMORY_UMA_HISTOGRAMS("Renderer"); @@ -100,6 +103,7 @@ builder.SetBlinkGC(pmd->chrome_dump->blink_gc_total_kb / 1024); builder.SetV8(pmd->chrome_dump->v8_total_kb / 1024); builder.SetNumberOfExtensions(number_of_extensions); + if (!page_info.is_null()) { builder.SetIsVisible(page_info->is_visible); builder.SetTimeSinceLastVisibilityChange( @@ -108,16 +112,16 @@ page_info->time_since_last_navigation.InSeconds()); } - base::TimeDelta uptime = - metrics::RendererUptimeTracker::Get()->GetProcessUptime(pmd->pid); - builder.SetUptime(uptime.InSeconds()); + if (uptime) + builder.SetUptime(uptime.value().InSeconds()); builder.Record(ukm_recorder); } void EmitGpuMemoryMetrics(const ProcessMemoryDumpPtr& pmd, ukm::SourceId ukm_source_id, - ukm::UkmRecorder* ukm_recorder) { + ukm::UkmRecorder* ukm_recorder, + const base::Optional<base::TimeDelta>& uptime) { ukm::builders::Memory_Experimental builder(ukm_source_id); builder.SetProcessType( static_cast<int64_t>(memory_instrumentation::mojom::ProcessType::GPU)); @@ -141,6 +145,8 @@ UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Gpu.PrivateMemoryFootprint", pmd->os_dump->private_footprint_kb / 1024); builder.SetPrivateMemoryFootprint(pmd->os_dump->private_footprint_kb / 1024); + if (uptime) + builder.SetUptime(uptime.value().InSeconds()); builder.Record(ukm_recorder); } @@ -254,6 +260,17 @@ return number_of_extensions; } +base::Optional<base::TimeDelta> ProcessMemoryMetricsEmitter::GetProcessUptime( + const base::Time& now, + base::ProcessId pid) { + auto process_info = process_infos_.find(pid); + if (process_info != process_infos_.end()) { + if (process_info->second->launch_time) + return now - process_info->second->launch_time.value(); + } + return base::Optional<base::TimeDelta>(); +} + void ProcessMemoryMetricsEmitter::CollateResults() { if (memory_dump_in_progress_ || get_process_urls_in_progress_) return; @@ -261,12 +278,14 @@ return; uint32_t private_footprint_total_kb = 0; + base::Time now = base::Time::Now(); for (const ProcessMemoryDumpPtr& pmd : global_dump_->process_dumps) { private_footprint_total_kb += pmd->os_dump->private_footprint_kb; switch (pmd->process_type) { case memory_instrumentation::mojom::ProcessType::BROWSER: { EmitBrowserMemoryMetrics(pmd, ukm::UkmRecorder::GetNewSourceID(), - GetUkmRecorder()); + GetUkmRecorder(), + GetProcessUptime(now, pmd->pid)); break; } case memory_instrumentation::mojom::ProcessType::RENDERER: { @@ -281,14 +300,16 @@ page_info = std::move(process_info->page_infos[0]); } } + int number_of_extensions = GetNumberOfExtensions(pmd->pid); EmitRendererMemoryMetrics(pmd, page_info, GetUkmRecorder(), - number_of_extensions); + number_of_extensions, + GetProcessUptime(now, pmd->pid)); break; } case memory_instrumentation::mojom::ProcessType::GPU: { EmitGpuMemoryMetrics(pmd, ukm::UkmRecorder::GetNewSourceID(), - GetUkmRecorder()); + GetUkmRecorder(), GetProcessUptime(now, pmd->pid)); break; } case memory_instrumentation::mojom::ProcessType::UTILITY:
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.h b/chrome/browser/metrics/process_memory_metrics_emitter.h index dd34380..d322c601 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.h +++ b/chrome/browser/metrics/process_memory_metrics_emitter.h
@@ -9,7 +9,9 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/process/process_handle.h" +#include "base/time/time.h" #include "services/resource_coordinator/public/interfaces/coordination_unit_introspector.mojom.h" #include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h" @@ -60,6 +62,12 @@ // It excludes hosted apps extensions. virtual int GetNumberOfExtensions(base::ProcessId pid); + // Virtual for testing. Returns the process uptime of the given process. Does + // not return a value when the process startup time is not set. + virtual base::Optional<base::TimeDelta> GetProcessUptime( + const base::Time& now, + base::ProcessId pid); + private: friend class base::RefCountedThreadSafe<ProcessMemoryMetricsEmitter>;
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc index b137096..84ff732 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -291,7 +291,7 @@ has_renderer_source = true; CheckUkmRendererSource(source_id, metric_count); } else if (ProcessHasTypeForSource(source_id, ProcessType::GPU)) { - // Not checked yet. + CheckUkmGPUSource(source_id, 1); } else { // This must be Total2. has_total_source = true; @@ -318,10 +318,9 @@ CheckMemoryMetricWithName(source_id, UkmEntry::kPartitionAllocName, true, metric_count); CheckMemoryMetricWithName(source_id, UkmEntry::kV8Name, true, metric_count); - CheckMemoryMetricWithName(source_id, UkmEntry::kUptimeName, true, - metric_count); CheckMemoryMetricWithName(source_id, UkmEntry::kNumberOfExtensionsName, true, metric_count); + CheckTimeMetricWithName(source_id, UkmEntry::kUptimeName, metric_count); } void CheckUkmBrowserSource(ukm::SourceId source_id, @@ -334,6 +333,12 @@ #endif CheckMemoryMetricWithName(source_id, UkmEntry::kPrivateMemoryFootprintName, false, metric_count); + + CheckTimeMetricWithName(source_id, UkmEntry::kUptimeName, metric_count); + } + + void CheckUkmGPUSource(ukm::SourceId source_id, size_t metric_count = 1u) { + CheckTimeMetricWithName(source_id, UkmEntry::kUptimeName, metric_count); } bool ProcessHasTypeForSource(ukm::SourceId source_id,
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc index c157487b..81a142c7 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc
@@ -23,34 +23,6 @@ namespace { -class ScopedMockRendererUptimeTracker : public metrics::RendererUptimeTracker { - public: - ScopedMockRendererUptimeTracker() { - previous_tracker_ = - RendererUptimeTracker::SetMockRendererUptimeTracker(this); - } - - ~ScopedMockRendererUptimeTracker() override { - RendererUptimeTracker* tracker = - RendererUptimeTracker::SetMockRendererUptimeTracker(previous_tracker_); - DCHECK_EQ(this, tracker); - } - - void SetProcessUptime(int pid, base::TimeDelta uptime) { - renderer_uptime_[pid] = uptime; - } - - base::TimeDelta GetProcessUptime(int pid) override { - auto uptime = renderer_uptime_.find(pid); - CHECK(uptime != renderer_uptime_.end()); - return uptime->second; - } - - private: - std::map<int, base::TimeDelta> renderer_uptime_; - RendererUptimeTracker* previous_tracker_; -}; - // Provide fake to surface ReceivedMemoryDump and ReceivedProcessInfos to public // visibility. class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter { @@ -86,6 +58,17 @@ } } + base::Optional<base::TimeDelta> GetProcessUptime( + const base::Time& now, + base::ProcessId pid) override { + switch (pid) { + case 401: + return base::TimeDelta::FromSeconds(21); + default: + return base::TimeDelta::FromSeconds(42); + } + } + private: ~ProcessMemoryMetricsEmitterFake() override {} @@ -135,13 +118,13 @@ {"Resident", 10}, {"Malloc", 20}, {"PrivateMemoryFootprint", 30}, + {"Uptime", 42}, }, base::KEEP_FIRST_OF_DUPES); } void PopulateRendererMetrics(GlobalMemoryDumpPtr& global_dump, base::flat_map<const char*, int64_t>& metrics_mb, - ScopedMockRendererUptimeTracker* uptime_tracker, base::ProcessId pid) { ProcessMemoryDumpPtr pmd( memory_instrumentation::mojom::ProcessMemoryDump::New()); @@ -152,8 +135,6 @@ metrics_mb["PartitionAlloc"] * 1024; pmd->chrome_dump->blink_gc_total_kb = metrics_mb["BlinkGC"] * 1024; pmd->chrome_dump->v8_total_kb = metrics_mb["V8"] * 1024; - uptime_tracker->SetProcessUptime( - pid, base::TimeDelta::FromSeconds(metrics_mb["Uptime"])); OSMemDumpPtr os_dump = GetFakeOSMemDump(metrics_mb["Resident"] * 1024, metrics_mb["PrivateMemoryFootprint"] * 1024); @@ -172,7 +153,7 @@ {"BlinkGC", 150}, {"V8", 160}, {"NumberOfExtensions", 0}, - {"Uptime", 10}}, + {"Uptime", 42}}, base::KEEP_FIRST_OF_DUPES); } @@ -206,20 +187,20 @@ {"Malloc", 220}, {"PrivateMemoryFootprint", 230}, {"CommandBuffer", 240}, + {"Uptime", 42}, }, base::KEEP_FIRST_OF_DUPES); } void PopulateMetrics(GlobalMemoryDumpPtr& global_dump, ProcessType ptype, - base::flat_map<const char*, int64_t>& metrics_mb, - ScopedMockRendererUptimeTracker* uptime_tracker) { + base::flat_map<const char*, int64_t>& metrics_mb) { switch (ptype) { case ProcessType::BROWSER: PopulateBrowserMetrics(global_dump, metrics_mb); return; case ProcessType::RENDERER: - PopulateRendererMetrics(global_dump, metrics_mb, uptime_tracker, 101); + PopulateRendererMetrics(global_dump, metrics_mb, 101); return; case ProcessType::GPU: PopulateGpuMetrics(global_dump, metrics_mb); @@ -337,7 +318,6 @@ } ukm::TestAutoSetUkmRecorder test_ukm_recorder_; - ScopedMockRendererUptimeTracker uptime_tracker_; private: DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterTest); @@ -350,7 +330,7 @@ GlobalMemoryDumpPtr global_dump( memory_instrumentation::mojom::GlobalMemoryDump::New()); - PopulateMetrics(global_dump, GetParam(), expected_metrics, &uptime_tracker_); + PopulateMetrics(global_dump, GetParam(), expected_metrics); scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( new ProcessMemoryMetricsEmitterFake(test_ukm_recorder_)); @@ -371,11 +351,12 @@ base::flat_map<const char*, int64_t> expected_metrics = GetExpectedRendererMetrics(); expected_metrics["NumberOfExtensions"] = 1; + expected_metrics["Uptime"] = 21; uint64_t dump_guid = 333; GlobalMemoryDumpPtr global_dump( memory_instrumentation::mojom::GlobalMemoryDump::New()); - PopulateRendererMetrics(global_dump, expected_metrics, &uptime_tracker_, 401); + PopulateRendererMetrics(global_dump, expected_metrics, 401); scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( new ProcessMemoryMetricsEmitterFake(test_ukm_recorder_)); @@ -398,7 +379,7 @@ std::vector<base::flat_map<const char*, int64_t>> entries_metrics; for (const auto& ptype : entries_ptypes) { auto expected_metrics = GetExpectedProcessMetrics(ptype); - PopulateMetrics(global_dump, ptype, expected_metrics, &uptime_tracker_); + PopulateMetrics(global_dump, ptype, expected_metrics); entries_metrics.push_back(expected_metrics); } @@ -427,7 +408,7 @@ memory_instrumentation::mojom::GlobalMemoryDump::New()); for (const auto& ptype : entries_ptypes[i]) { auto expected_metrics = GetExpectedProcessMetrics(ptype); - PopulateMetrics(global_dump, ptype, expected_metrics, &uptime_tracker_); + PopulateMetrics(global_dump, ptype, expected_metrics); expected_metrics.erase("TimeSinceLastVisible"); entries_metrics.push_back(expected_metrics); } @@ -447,7 +428,7 @@ base::flat_map<const char*, int64_t> expected_metrics = GetExpectedRendererMetrics(); AddPageMetrics(expected_metrics); - PopulateRendererMetrics(global_dump, expected_metrics, &uptime_tracker_, 201); + PopulateRendererMetrics(global_dump, expected_metrics, 201); scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( new ProcessMemoryMetricsEmitterFake(test_ukm_recorder_)); @@ -481,7 +462,7 @@ base::flat_map<const char*, int64_t> expected_metrics = GetExpectedRendererMetrics(); AddPageMetrics(expected_metrics); - PopulateRendererMetrics(global_dump, expected_metrics, &uptime_tracker_, 201); + PopulateRendererMetrics(global_dump, expected_metrics, 201); scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( new ProcessMemoryMetricsEmitterFake(test_ukm_recorder_)); @@ -514,9 +495,9 @@ memory_instrumentation::mojom::GlobalMemoryDump::New()); base::flat_map<const char*, int64_t> expected_metrics = GetExpectedRendererMetrics(); - PopulateRendererMetrics(global_dump, expected_metrics, &uptime_tracker_, 200); - PopulateRendererMetrics(global_dump, expected_metrics, &uptime_tracker_, 201); - PopulateRendererMetrics(global_dump, expected_metrics, &uptime_tracker_, 202); + PopulateRendererMetrics(global_dump, expected_metrics, 200); + PopulateRendererMetrics(global_dump, expected_metrics, 201); + PopulateRendererMetrics(global_dump, expected_metrics, 202); scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter( new ProcessMemoryMetricsEmitterFake(test_ukm_recorder_));
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index 908720e..80ee01e 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -58,15 +58,16 @@ #include "components/ntp_snippets/user_classifier.h" #include "components/offline_pages/features/features.h" #include "components/prefs/pref_service.h" -#include "components/safe_json/safe_json_parser.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/service_manager_connection.h" #include "google_apis/google_api_keys.h" #include "net/url_request/url_request_context_getter.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" #if defined(OS_ANDROID) #include "chrome/browser/android/chrome_feature_list.h" @@ -307,7 +308,9 @@ return base::MakeUnique<BreakingNewsGCMAppHandler>( gcm_driver, instance_id_profile_service->driver(), pref_service, std::move(subscription_manager), - base::Bind(&safe_json::SafeJsonParser::Parse), + base::Bind( + &data_decoder::SafeJsonParser::Parse, + content::ServiceManagerConnection::GetForProcess()->GetConnector()), base::MakeUnique<base::DefaultClock>(), /*token_validation_timer=*/base::MakeUnique<base::OneShotTimer>(), /*forced_subscription_timer=*/base::MakeUnique<base::OneShotTimer>()); @@ -373,7 +376,10 @@ #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) auto suggestions_fetcher = base::MakeUnique<RemoteSuggestionsFetcherImpl>( signin_manager, token_service, request_context, pref_service, - language_histogram, base::Bind(&safe_json::SafeJsonParser::Parse), + language_histogram, + base::Bind( + &data_decoder::SafeJsonParser::Parse, + content::ServiceManagerConnection::GetForProcess()->GetConnector()), GetFetchEndpoint(chrome::GetChannel()), api_key, user_classifier); std::unique_ptr<BreakingNewsListener> breaking_news_raw_data_provider;
diff --git a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc index 4ee513c..c2e9ec77 100644 --- a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc
@@ -20,10 +20,11 @@ #include "components/ntp_snippets/remote/cached_image_fetcher.h" #include "components/ntp_snippets/remote/remote_suggestions_database.h" #include "components/prefs/pref_service.h" -#include "components/safe_json/safe_json_parser.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "content/public/browser/browser_context.h" +#include "content/public/common/service_manager_connection.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" #if defined(OS_ANDROID) #include "chrome/browser/android/chrome_feature_list.h" @@ -98,7 +99,9 @@ auto contextual_suggestions_fetcher = base::MakeUnique<ContextualSuggestionsFetcherImpl>( signin_manager, token_service, request_context, pref_service, - base::Bind(&safe_json::SafeJsonParser::Parse)); + base::Bind(&data_decoder::SafeJsonParser::Parse, + content::ServiceManagerConnection::GetForProcess() + ->GetConnector())); const base::FilePath::CharType kDatabaseFolder[] = FILE_PATH_LITERAL("contextualSuggestionsDatabase"); base::FilePath database_dir(profile->GetPath().Append(kDatabaseFolder));
diff --git a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc index 0368cd6..3cc880ab 100644 --- a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc +++ b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc
@@ -10,13 +10,16 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "components/ntp_tiles/popular_sites_impl.h" -#include "components/safe_json/safe_json_parser.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/service_manager_connection.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" std::unique_ptr<ntp_tiles::PopularSites> ChromePopularSitesFactory::NewForProfile(Profile* profile) { return base::MakeUnique<ntp_tiles::PopularSitesImpl>( profile->GetPrefs(), TemplateURLServiceFactory::GetForProfile(profile), g_browser_process->variations_service(), profile->GetRequestContext(), - base::Bind(safe_json::SafeJsonParser::Parse)); + base::Bind( + data_decoder::SafeJsonParser::Parse, + content::ServiceManagerConnection::GetForProcess()->GetConnector())); }
diff --git a/chrome/browser/plugins/plugins_resource_service.cc b/chrome/browser/plugins/plugins_resource_service.cc index eb38078..647f8adc 100644 --- a/chrome/browser/plugins/plugins_resource_service.cc +++ b/chrome/browser/plugins/plugins_resource_service.cc
@@ -14,7 +14,8 @@ #include "chrome/common/pref_names.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" -#include "components/safe_json/safe_json_parser.h" +#include "content/public/common/service_manager_connection.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" #include "url/gurl.h" namespace { @@ -82,7 +83,9 @@ kCacheUpdateDelayMs, g_browser_process->system_request_context(), switches::kDisableBackgroundNetworking, - base::Bind(safe_json::SafeJsonParser::Parse), + base::Bind(data_decoder::SafeJsonParser::Parse, + content::ServiceManagerConnection::GetForProcess() + ->GetConnector()), kTrafficAnnotation) {} void PluginsResourceService::Init() {
diff --git a/chrome/browser/predictors/loading_test_util.cc b/chrome/browser/predictors/loading_test_util.cc index 7c97a9b..65ed703 100644 --- a/chrome/browser/predictors/loading_test_util.cc +++ b/chrome/browser/predictors/loading_test_util.cc
@@ -204,6 +204,7 @@ config->max_hosts_to_track = 2; config->min_url_visit_count = 2; config->max_resources_per_entry = 4; + config->max_origins_per_entry = 5; config->max_consecutive_misses = 2; config->max_redirect_consecutive_misses = 2; config->min_resource_confidence_to_trigger_prefetch = 0.5;
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h index ada7851..7253988 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.h +++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -188,6 +188,8 @@ FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, NavigationUrlNotInDB); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, NavigationUrlNotInDBAndDBFull); + FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, + NavigationManyResourcesWithDifferentOrigins); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, RedirectUrlNotInDB); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, RedirectUrlInDB); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, OnMainFrameRequest);
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc index 1b1d960..1faf3cc 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -771,6 +771,68 @@ EXPECT_EQ(mock_tables_->origin_table_.data_, expected_origin_data); } +TEST_F(ResourcePrefetchPredictorTest, + NavigationManyResourcesWithDifferentOrigins) { + const int kVisitCount = 4; + AddUrlToHistory("http://www.google.com", kVisitCount); + + URLRequestSummary main_frame = + CreateURLRequestSummary(1, "http://www.google.com"); + + auto gen = [](int i) { + return base::StringPrintf("http://cdn%d.google.com/script.js", i); + }; + std::vector<URLRequestSummary> resources; + const int num_resources = + std::max(predictor_->config_.max_resources_per_entry, + predictor_->config_.max_origins_per_entry) + + 10; + for (int i = 1; i <= num_resources; ++i) { + resources.push_back(CreateURLRequestSummary( + 1, "http://www.google.com", gen(i), content::RESOURCE_TYPE_SCRIPT, + net::MEDIUM, "text/javascript", false)); + } + + auto page_summary = CreatePageRequestSummary( + "http://www.google.com", "http://www.google.com", resources); + + StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_); + EXPECT_CALL(mock_observer, OnNavigationLearned(kVisitCount, page_summary)); + + predictor_->RecordPageRequestSummary( + base::MakeUnique<PageRequestSummary>(page_summary)); + profile_->BlockUntilHistoryProcessesPendingRequests(); + + PrefetchData url_data = CreatePrefetchData("http://www.google.com/"); + for (int i = 1; + i <= static_cast<int>(predictor_->config_.max_resources_per_entry); + ++i) { + InitializeResourceData(url_data.add_resources(), gen(i), + content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, i, + net::MEDIUM, false, false); + } + EXPECT_EQ(mock_tables_->url_resource_table_.data_, + PrefetchDataMap({{url_data.primary_key(), url_data}})); + + PrefetchData host_data = CreatePrefetchData("www.google.com"); + host_data.mutable_resources()->CopyFrom(url_data.resources()); + EXPECT_EQ(mock_tables_->host_resource_table_.data_, + PrefetchDataMap({{host_data.primary_key(), host_data}})); + + OriginData origin_data = CreateOriginData("www.google.com"); + InitializeOriginStat(origin_data.add_origins(), "http://www.google.com/", 1, + 0, 0, 1, false, true); + for (int i = 1; + i <= static_cast<int>(predictor_->config_.max_origins_per_entry) - 1; + ++i) { + InitializeOriginStat(origin_data.add_origins(), + GURL(gen(i)).GetOrigin().spec(), 1, 0, 0, i + 1, false, + true); + } + EXPECT_EQ(mock_tables_->origin_table_.data_, + OriginDataMap({{origin_data.host(), origin_data}})); +} + TEST_F(ResourcePrefetchPredictorTest, RedirectUrlNotInDB) { const int kVisitCount = 4; AddUrlToHistory("https://facebook.com/google", kVisitCount);
diff --git a/chrome/browser/resource_coordinator/browser_child_process_watcher.cc b/chrome/browser/resource_coordinator/browser_child_process_watcher.cc new file mode 100644 index 0000000..e91d89b --- /dev/null +++ b/chrome/browser/resource_coordinator/browser_child_process_watcher.cc
@@ -0,0 +1,68 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/browser_child_process_watcher.h" + +#include "base/process/process.h" +#include "content/public/browser/child_process_data.h" +#include "content/public/common/process_type.h" +#include "content/public/common/service_manager_connection.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" + +namespace resource_coordinator { + +BrowserChildProcessWatcher::BrowserChildProcessWatcher() { + BrowserChildProcessObserver::Add(this); +} + +BrowserChildProcessWatcher::~BrowserChildProcessWatcher() { + BrowserChildProcessObserver::Remove(this); +} + +void BrowserChildProcessWatcher::BrowserChildProcessLaunchedAndConnected( + const content::ChildProcessData& data) { + if (!resource_coordinator::IsResourceCoordinatorEnabled()) + return; + + if (data.process_type == content::PROCESS_TYPE_GPU) { + gpu_process_resource_coordinator_ = + base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), + resource_coordinator::CoordinationUnitType::kProcess); + + base::ProcessId pid = base::GetProcId(data.handle); + gpu_process_resource_coordinator_->SetProperty( + resource_coordinator::mojom::PropertyType::kPID, pid); + + gpu_process_resource_coordinator_->SetProperty( + resource_coordinator::mojom::PropertyType::kLaunchTime, + base::Time::Now().ToTimeT()); + } +} + +void BrowserChildProcessWatcher::BrowserChildProcessHostDisconnected( + const content::ChildProcessData& data) { + if (data.process_type == content::PROCESS_TYPE_GPU) + GPUProcessStopped(); +} + +void BrowserChildProcessWatcher::BrowserChildProcessCrashed( + const content::ChildProcessData& data, + int exit_code) { + if (data.process_type == content::PROCESS_TYPE_GPU) + GPUProcessStopped(); +} + +void BrowserChildProcessWatcher::BrowserChildProcessKilled( + const content::ChildProcessData& data, + int exit_code) { + if (data.process_type == content::PROCESS_TYPE_GPU) + GPUProcessStopped(); +} + +void BrowserChildProcessWatcher::GPUProcessStopped() { + gpu_process_resource_coordinator_.reset(); +} + +} // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/browser_child_process_watcher.h b/chrome/browser/resource_coordinator/browser_child_process_watcher.h new file mode 100644 index 0000000..8e637e1 --- /dev/null +++ b/chrome/browser/resource_coordinator/browser_child_process_watcher.h
@@ -0,0 +1,42 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_BROWSER_CHILD_PROCESS_WATCHER_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_BROWSER_CHILD_PROCESS_WATCHER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "content/public/browser/browser_child_process_observer.h" +#include "content/public/common/service_manager_connection.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_interface.h" + +namespace resource_coordinator { + +class BrowserChildProcessWatcher : public content::BrowserChildProcessObserver { + public: + BrowserChildProcessWatcher(); + ~BrowserChildProcessWatcher() override; + + private: + // BrowserChildProcessObserver overrides. + void BrowserChildProcessLaunchedAndConnected( + const content::ChildProcessData& data) override; + void BrowserChildProcessHostDisconnected( + const content::ChildProcessData& data) override; + void BrowserChildProcessCrashed(const content::ChildProcessData& data, + int exit_code) override; + void BrowserChildProcessKilled(const content::ChildProcessData& data, + int exit_code) override; + + void GPUProcessStopped(); + + std::unique_ptr<resource_coordinator::ResourceCoordinatorInterface> + gpu_process_resource_coordinator_; + + DISALLOW_COPY_AND_ASSIGN(BrowserChildProcessWatcher); +}; + +} // namespace resource_coordinator + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_BROWSER_CHILD_PROCESS_WATCHER_H_
diff --git a/chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.cc b/chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.cc new file mode 100644 index 0000000..d8f9552 --- /dev/null +++ b/chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.cc
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.h" + +#include "base/process/process.h" +#include "chrome/browser/resource_coordinator/browser_child_process_watcher.h" +#include "content/public/common/service_manager_connection.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" + +ChromeBrowserMainExtraPartsResourceCoordinator:: + ChromeBrowserMainExtraPartsResourceCoordinator() = default; +ChromeBrowserMainExtraPartsResourceCoordinator:: + ~ChromeBrowserMainExtraPartsResourceCoordinator() = default; + +void ChromeBrowserMainExtraPartsResourceCoordinator:: + ServiceManagerConnectionStarted( + content::ServiceManagerConnection* connection) { + if (!resource_coordinator::IsResourceCoordinatorEnabled()) + return; + + process_resource_coordinator_ = + base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>( + connection->GetConnector(), + resource_coordinator::CoordinationUnitType::kProcess); + + process_resource_coordinator_->SetProperty( + resource_coordinator::mojom::PropertyType::kPID, + base::Process::Current().Pid()); + + process_resource_coordinator_->SetProperty( + resource_coordinator::mojom::PropertyType::kLaunchTime, + base::Time::Now().ToTimeT()); + + browser_child_process_watcher_ = + base::MakeUnique<resource_coordinator::BrowserChildProcessWatcher>(); +}
diff --git a/chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.h b/chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.h new file mode 100644 index 0000000..2305c5b --- /dev/null +++ b/chrome/browser/resource_coordinator/chrome_browser_main_extra_parts_resource_coordinator.h
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_CHROME_BROWSER_MAIN_EXTRA_PARTS_RESOURCE_COORDINATOR_H_ +#define CHROME_BROWSER_RESOURCE_COORDINATOR_CHROME_BROWSER_MAIN_EXTRA_PARTS_RESOURCE_COORDINATOR_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "chrome/browser/chrome_browser_main_extra_parts.h" +#include "chrome/browser/resource_coordinator/browser_child_process_watcher.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_interface.h" + +class ChromeBrowserMainExtraPartsResourceCoordinator + : public ChromeBrowserMainExtraParts { + public: + ChromeBrowserMainExtraPartsResourceCoordinator(); + ~ChromeBrowserMainExtraPartsResourceCoordinator() override; + + private: + // ChromeBrowserMainExtraParts overrides. + void ServiceManagerConnectionStarted( + content::ServiceManagerConnection* connection) override; + + std::unique_ptr<resource_coordinator::ResourceCoordinatorInterface> + process_resource_coordinator_; + + std::unique_ptr<resource_coordinator::BrowserChildProcessWatcher> + browser_child_process_watcher_; + + DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsResourceCoordinator); +}; + +#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_CHROME_BROWSER_MAIN_EXTRA_PARTS_RESOURCE_COORDINATOR_H_
diff --git a/chrome/browser/safe_json_parser_browsertest.cc b/chrome/browser/safe_json_parser_browsertest.cc index 1432563..4c66ab8 100644 --- a/chrome/browser/safe_json_parser_browsertest.cc +++ b/chrome/browser/safe_json_parser_browsertest.cc
@@ -9,13 +9,14 @@ #include "base/json/json_writer.h" #include "base/values.h" #include "chrome/test/base/in_process_browser_test.h" -#include "components/safe_json/safe_json_parser.h" +#include "content/public/common/service_manager_connection.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" namespace { -using safe_json::SafeJsonParser; +using data_decoder::SafeJsonParser; std::string MaybeToJson(const base::Value* value) { if (!value) @@ -55,7 +56,9 @@ error_callback = base::Bind(&SafeJsonParserTest::ExpectError, base::Unretained(this), error); } - SafeJsonParser::Parse(json, success_callback, error_callback); + SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), + json, success_callback, error_callback); message_loop_runner_->Run(); message_loop_runner_ = nullptr; @@ -89,8 +92,7 @@ scoped_refptr<content::MessageLoopRunner> message_loop_runner_; }; -// Flaky in debug builds: http://crbug.com/611067 -IN_PROC_BROWSER_TEST_F(SafeJsonParserTest, DISABLED_Parse) { +IN_PROC_BROWSER_TEST_F(SafeJsonParserTest, Parse) { TestParse("{}"); TestParse("choke"); TestParse("{\"awesome\": true}");
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc index 969430bd..187b89a7 100644 --- a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc +++ b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc
@@ -16,14 +16,15 @@ #include "chrome/common/chrome_content_client.h" #include "components/google/core/browser/google_url_tracker.h" #include "components/google/core/browser/google_util.h" -#include "components/safe_json/safe_json_parser.h" #include "components/variations/net/variations_http_headers.h" +#include "content/public/common/service_manager_connection.h" #include "net/base/load_flags.h" #include "net/base/url_util.h" #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" namespace { @@ -294,7 +295,8 @@ response = response.substr(strlen(kResponsePreamble)); } - safe_json::SafeJsonParser::Parse( + data_decoder::SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), response, base::Bind(&OneGoogleBarFetcherImpl::JsonParsed, weak_ptr_factory_.GetWeakPtr()),
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc index 491a61b..685262a7 100644 --- a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc +++ b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc
@@ -7,7 +7,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" #include "base/optional.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" @@ -16,12 +15,14 @@ #include "base/time/time.h" #include "chrome/browser/search/one_google_bar/one_google_bar_data.h" #include "components/google/core/browser/google_url_tracker.h" -#include "components/safe_json/testing_json_parser.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_service_manager_context.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_status.h" #include "net/url_request/url_request_test_util.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -108,10 +109,11 @@ private: // variations::AppendVariationHeaders and SafeJsonParser require a - // ThreadTaskRunnerHandle to be set. - base::MessageLoop message_loop_; + // threads and a ServiceManagerConnection to be set. + content::TestBrowserThreadBundle thread_bundle_; + content::TestServiceManagerContext service_manager_context_; - safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; net::TestURLFetcherFactory url_fetcher_factory_;
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc index 2829bf6..9246b59 100644 --- a/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc +++ b/chrome/browser/supervised_user/supervised_user_whitelist_service_unittest.cc
@@ -31,7 +31,7 @@ #include "testing/gtest/include/gtest/gtest.h" #if !defined(OS_ANDROID) -#include "components/safe_json/testing_json_parser.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #endif namespace { @@ -162,7 +162,7 @@ TestingProfile profile_; #if !defined(OS_ANDROID) - safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; + data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_; #endif std::unique_ptr<MockSupervisedUserWhitelistInstaller> installer_;
diff --git a/chrome/browser/thumbnails/thumbnail_service_impl.cc b/chrome/browser/thumbnails/thumbnail_service_impl.cc index 2ca6786..b675587be 100644 --- a/chrome/browser/thumbnails/thumbnail_service_impl.cc +++ b/chrome/browser/thumbnails/thumbnail_service_impl.cc
@@ -4,13 +4,11 @@ #include "chrome/browser/thumbnails/thumbnail_service_impl.h" -#include "base/feature_list.h" #include "base/memory/ref_counted_memory.h" #include "base/time/time.h" #include "chrome/browser/history/history_utils.h" #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/thumbnails/thumbnailing_context.h" -#include "chrome/common/chrome_features.h" #include "content/public/browser/browser_thread.h" #include "url/gurl.h" @@ -83,19 +81,15 @@ if (local_ptr->IsNonForcedFull()) return false; - if (base::FeatureList::IsEnabled( - features::kCaptureThumbnailDependingOnTransitionType)) { - // Skip if the transition type is not interesting: - // Only new segments (roughly "initial navigations", e.g. not clicks on a - // link) can end up in TopSites (see HistoryBackend::UpdateSegments). - // Note that for pages that are already in TopSites, we don't care about - // the transition type, since for those we know we'll need the thumbnail. - if (!ui::PageTransitionCoreTypeIs(transition, - ui::PAGE_TRANSITION_TYPED) && - !ui::PageTransitionCoreTypeIs(transition, - ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { - return false; - } + // Skip if the transition type is not interesting: + // Only new segments (roughly "initial navigations", e.g. not clicks on a + // link) can end up in TopSites (see HistoryBackend::UpdateSegments). + // Note that for pages that are already in TopSites, we don't care about + // the transition type, since for those we know we'll need the thumbnail. + if (!ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) && + !ui::PageTransitionCoreTypeIs(transition, + ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { + return false; } }
diff --git a/chrome/browser/thumbnails/thumbnail_service_unittest.cc b/chrome/browser/thumbnails/thumbnail_service_unittest.cc index 414bfee..a59bf4aae 100644 --- a/chrome/browser/thumbnails/thumbnail_service_unittest.cc +++ b/chrome/browser/thumbnails/thumbnail_service_unittest.cc
@@ -9,10 +9,8 @@ #include "base/bind.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/history/history_utils.h" #include "chrome/browser/history/top_sites_factory.h" -#include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_profile.h" #include "components/history/core/browser/top_sites_impl.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -161,10 +159,6 @@ TEST_F(ThumbnailServiceTest, ShouldAcquireTempThumbnailDependingOnTransitionType) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature( - features::kCaptureThumbnailDependingOnTransitionType); - const GURL kUnknownURL("http://www.google.com/"); const ui::PageTransition interesting_transition = ui::PAGE_TRANSITION_TYPED; const ui::PageTransition uninteresting_transition = ui::PAGE_TRANSITION_LINK;
diff --git a/chrome/browser/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/thumbnails/thumbnail_tab_helper.cc index 687c221..0ef7c193 100644 --- a/chrome/browser/thumbnails/thumbnail_tab_helper.cc +++ b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/thumbnails/thumbnail_tab_helper.h" -#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "base/task_scheduler/post_task.h" #include "base/task_scheduler/task_traits.h" @@ -12,7 +11,6 @@ #include "chrome/browser/thumbnails/thumbnail_service.h" #include "chrome/browser/thumbnails/thumbnail_service_factory.h" #include "chrome/browser/thumbnails/thumbnail_utils.h" -#include "chrome/common/chrome_features.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/notification_details.h" @@ -59,16 +57,13 @@ // UpdateThumbnailIfNecessary(), which updates the thumbnail for the current // tab if needed. The heuristics to judge whether to update the thumbnail are // implemented in ThumbnailService::ShouldAcquirePageThumbnail(). -// There are several triggers that can start the process: +// There are two triggers that can start the process: // - When a renderer is about to be hidden (this usually occurs when the current // tab is closed or another tab is clicked). -// - If features::kCaptureThumbnailOnNavigatingAway is enabled: Just before -// navigating away from the current page. +// - Just before navigating away from the current page. ThumbnailTabHelper::ThumbnailTabHelper(content::WebContents* contents) : content::WebContentsObserver(contents), - capture_on_navigating_away_(base::FeatureList::IsEnabled( - features::kCaptureThumbnailOnNavigatingAway)), page_transition_(ui::PAGE_TRANSITION_LINK), load_interrupted_(false), weak_factory_(this) { @@ -122,12 +117,12 @@ navigation_handle->IsSameDocument()) { return; } - if (capture_on_navigating_away_) { - // At this point, the new navigation has just been started, but the - // WebContents still shows the previous page. Grab a thumbnail before it - // goes away. - UpdateThumbnailIfNecessary(); - } + + // At this point, the new navigation has just been started, but the + // WebContents still shows the previous page. Grab a thumbnail before it + // goes away. + UpdateThumbnailIfNecessary(); + // Reset the page transition to some uninteresting type, since the actual // type isn't available at this point. We'll get it in DidFinishNavigation // (if that happens, which isn't guaranteed).
diff --git a/chrome/browser/thumbnails/thumbnail_tab_helper.h b/chrome/browser/thumbnails/thumbnail_tab_helper.h index 68a40b3..0eb1da5 100644 --- a/chrome/browser/thumbnails/thumbnail_tab_helper.h +++ b/chrome/browser/thumbnails/thumbnail_tab_helper.h
@@ -71,8 +71,6 @@ // Indicates that the given widget has changed is visibility. void WidgetHidden(content::RenderWidgetHost* widget); - const bool capture_on_navigating_away_; - content::NotificationRegistrar registrar_; ui::PageTransition page_transition_;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index f193af5..4872d16 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -73,12 +73,16 @@ "autofill/popup_view_common.h", "blocked_content/blocked_window_params.cc", "blocked_content/blocked_window_params.h", + "blocked_content/console_logger.cc", + "blocked_content/console_logger.h", "blocked_content/popup_blocker_tab_helper.cc", "blocked_content/popup_blocker_tab_helper.h", "blocked_content/popup_opener_tab_helper.cc", "blocked_content/popup_opener_tab_helper.h", "blocked_content/popup_tracker.cc", "blocked_content/popup_tracker.h", + "blocked_content/safe_browsing_triggered_popup_blocker.cc", + "blocked_content/safe_browsing_triggered_popup_blocker.h", "blocked_content/scoped_visibility_tracker.cc", "blocked_content/scoped_visibility_tracker.h", "blocked_content/tab_under_navigation_throttle.cc", @@ -428,9 +432,9 @@ "//components/resources", "//components/safe_browsing/common:safe_browsing_prefs", "//components/safe_browsing/db:database_manager", + "//components/safe_browsing/db:util", "//components/safe_browsing/password_protection", "//components/safe_browsing/web_ui", - "//components/safe_json", "//components/search", "//components/search_engines", "//components/security_interstitials/core",
diff --git a/chrome/browser/ui/android/page_info/page_info_popup_android.cc b/chrome/browser/ui/android/page_info/page_info_popup_android.cc index be6e53a..6a50ce9 100644 --- a/chrome/browser/ui/android/page_info/page_info_popup_android.cc +++ b/chrome/browser/ui/android/page_info/page_info_popup_android.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/ui/page_info/page_info.h" #include "chrome/browser/ui/page_info/page_info_ui.h" +#include "chrome/common/chrome_features.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/security_state/core/security_state.h" @@ -119,6 +120,8 @@ permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_POPUPS); permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_ADS); permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_AUTOPLAY); + if (base::FeatureList::IsEnabled(features::kSoundContentSetting)) + permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_SOUND); std::map<ContentSettingsType, ContentSetting> user_specified_settings_to_display;
diff --git a/chrome/browser/ui/app_list/search/common/json_response_fetcher.cc b/chrome/browser/ui/app_list/search/common/json_response_fetcher.cc index 7975c35..2fbb1a6 100644 --- a/chrome/browser/ui/app_list/search/common/json_response_fetcher.cc +++ b/chrome/browser/ui/app_list/search/common/json_response_fetcher.cc
@@ -9,10 +9,11 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/values.h" -#include "components/safe_json/safe_json_parser.h" +#include "content/public/common/service_manager_connection.h" #include "net/base/load_flags.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" #include "url/gurl.h" namespace app_list { @@ -76,9 +77,11 @@ fetcher->GetResponseAsString(&json_data); // The parser will call us back via one of the callbacks. - safe_json::SafeJsonParser::Parse( - json_data, base::Bind(&JSONResponseFetcher::OnJsonParseSuccess, - weak_factory_.GetWeakPtr()), + data_decoder::SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), + json_data, + base::Bind(&JSONResponseFetcher::OnJsonParseSuccess, + weak_factory_.GetWeakPtr()), base::Bind(&JSONResponseFetcher::OnJsonParseError, weak_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/ui/blocked_content/console_logger.cc b/chrome/browser/ui/blocked_content/console_logger.cc new file mode 100644 index 0000000..4bb56a54 --- /dev/null +++ b/chrome/browser/ui/blocked_content/console_logger.cc
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/console_logger.h" + +#include "base/logging.h" +#include "content/public/browser/render_frame_host.h" + +ConsoleLogger::ConsoleLogger() = default; +ConsoleLogger::~ConsoleLogger() = default; + +void ConsoleLogger::LogInFrame(content::RenderFrameHost* render_frame_host, + content::ConsoleMessageLevel level, + const std::string& message) { + DCHECK(render_frame_host); + render_frame_host->AddMessageToConsole(level, message); +}
diff --git a/chrome/browser/ui/blocked_content/console_logger.h b/chrome/browser/ui/blocked_content/console_logger.h new file mode 100644 index 0000000..810b638 --- /dev/null +++ b/chrome/browser/ui/blocked_content/console_logger.h
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_CONSOLE_LOGGER_H_ +#define CHROME_BROWSER_UI_BLOCKED_CONTENT_CONSOLE_LOGGER_H_ + +#include <string> + +#include "base/macros.h" +#include "content/public/common/console_message_level.h" + +namespace content { +class RenderFrameHost; +} + +// This simple class just forwards console logging to the associated +// RenderFrameHost, to send down to the renderer. It exists for unit tests to +// mock out, allowing unit tests to expect console messages without having to +// write a full browser test. +class ConsoleLogger { + public: + ConsoleLogger(); + virtual ~ConsoleLogger(); + + virtual void LogInFrame(content::RenderFrameHost* render_frame_host, + content::ConsoleMessageLevel level, + const std::string& message); + + private: + DISALLOW_COPY_AND_ASSIGN(ConsoleLogger); +}; + +#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_CONSOLE_LOGGER_H_
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc new file mode 100644 index 0000000..54c7f65 --- /dev/null +++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc
@@ -0,0 +1,142 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h" + +#include <utility> + +#include "base/memory/ptr_util.h" +#include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_macros.h" +#include "chrome/browser/ui/blocked_content/console_logger.h" +#include "components/safe_browsing/db/util.h" +#include "components/safe_browsing/db/v4_protocol_manager_util.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/console_message_level.h" +#include "third_party/WebKit/public/web/WebTriggeringEventInfo.h" + +namespace { + +const char kIgnoreSublistsParam[] = "ignore_sublists"; + +void LogAction(SafeBrowsingTriggeredPopupBlocker::Action action) { + UMA_HISTOGRAM_ENUMERATION("ContentSettings.Popups.StrongBlockerActions", + action, + SafeBrowsingTriggeredPopupBlocker::Action::kCount); +} + +} // namespace + +using safe_browsing::SubresourceFilterLevel; + +const base::Feature kAbusiveExperienceEnforce{ + "AbusiveExperienceEnforce", base::FEATURE_DISABLED_BY_DEFAULT}; + +SafeBrowsingTriggeredPopupBlocker::~SafeBrowsingTriggeredPopupBlocker() = + default; + +SafeBrowsingTriggeredPopupBlocker::SafeBrowsingTriggeredPopupBlocker( + content::WebContents* web_contents, + std::unique_ptr<ConsoleLogger> logger) + : content::WebContentsObserver(web_contents), + scoped_observer_(this), + logger_(std::move(logger)), + ignore_sublists_( + base::GetFieldTrialParamByFeatureAsBool(kAbusiveExperienceEnforce, + kIgnoreSublistsParam, + false /* default_value */)) { + if (auto* observer_manager = + subresource_filter::SubresourceFilterObserverManager::FromWebContents( + web_contents)) { + scoped_observer_.Add(observer_manager); + } +} + +bool SafeBrowsingTriggeredPopupBlocker::ShouldApplyStrongPopupBlocker( + const content::OpenURLParams* open_url_params) { + LogAction(Action::kConsidered); + if (!is_triggered_for_current_committed_load_) + return false; + + bool should_block = true; + if (open_url_params) { + should_block = open_url_params->triggering_event_info == + blink::WebTriggeringEventInfo::kFromUntrustedEvent; + } + + // TODO(csharrison): Log some dry-run style metrics for when the feature is + // not enabled. + if (!base::FeatureList::IsEnabled(kAbusiveExperienceEnforce)) { + return false; + } + + // TODO(csharrison): Migrate SubresourceFilter* popup metrics. + if (should_block) { + LogAction(Action::kBlocked); + logger_->LogInFrame(web_contents()->GetMainFrame(), + content::CONSOLE_MESSAGE_LEVEL_ERROR, + kAbusiveEnforceMessage); + } + return should_block; +} + +void SafeBrowsingTriggeredPopupBlocker::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame()) + return; + + base::Optional<SubresourceFilterLevel> level; + level_for_next_committed_navigation_.swap(level); + + // Only care about main frame navigations that commit. + if (!navigation_handle->HasCommitted() || + navigation_handle->IsSameDocument()) { + return; + } + + is_triggered_for_current_committed_load_ = false; + if (navigation_handle->IsErrorPage()) + return; + + // Log a warning only if we've matched a warn-only safe browsing list. + if (level == SubresourceFilterLevel::ENFORCE) { + is_triggered_for_current_committed_load_ = true; + LogAction(Action::kEnforcedSite); + } else if (level == SubresourceFilterLevel::WARN) { + logger_->LogInFrame(web_contents()->GetMainFrame(), + content::CONSOLE_MESSAGE_LEVEL_WARNING, + kAbusiveWarnMessage); + LogAction(Action::kWarningSite); + } + LogAction(Action::kNavigation); +} + +// This method will always be called before the DidFinishNavigation associated +// with this handle. +void SafeBrowsingTriggeredPopupBlocker::OnSafeBrowsingCheckComplete( + content::NavigationHandle* navigation_handle, + safe_browsing::SBThreatType threat_type, + const safe_browsing::ThreatMetadata& threat_metadata) { + DCHECK(navigation_handle->IsInMainFrame()); + if (threat_type != + safe_browsing::SBThreatType::SB_THREAT_TYPE_SUBRESOURCE_FILTER) + return; + if (ignore_sublists_) { + // No warning for ignore_sublists mode. + level_for_next_committed_navigation_ = SubresourceFilterLevel::ENFORCE; + return; + } + + auto abusive = threat_metadata.subresource_filter_match.find( + safe_browsing::SubresourceFilterType::ABUSIVE); + if (abusive == threat_metadata.subresource_filter_match.end()) + return; + level_for_next_committed_navigation_ = abusive->second; +} + +void SafeBrowsingTriggeredPopupBlocker::OnSubresourceFilterGoingAway() { + scoped_observer_.RemoveAll(); +}
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h new file mode 100644 index 0000000..87e4154 --- /dev/null +++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h
@@ -0,0 +1,112 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER_H_ +#define CHROME_BROWSER_UI_BLOCKED_CONTENT_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER_H_ + +#include <memory> + +#include "base/feature_list.h" +#include "base/macros.h" +#include "base/optional.h" +#include "base/scoped_observer.h" +#include "components/safe_browsing/db/util.h" +#include "components/subresource_filter/content/browser/subresource_filter_observer.h" +#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" +#include "content/public/browser/web_contents_observer.h" + +namespace content { +struct OpenURLParams; +class WebContents; +} // namespace content + +class ConsoleLogger; + +extern const base::Feature kAbusiveExperienceEnforce; + +constexpr char kAbusiveEnforceMessage[] = + "Chrome prevented this site from opening a new tab or window. Learn more " + "at https://www.chromestatus.com/feature/5243055179300864"; +constexpr char kAbusiveWarnMessage[] = + "Chrome might start preventing this site from opening new tabs or " + "windows in the future. Learn more at " + "https://www.chromestatus.com/feature/5243055179300864"; + +// This class observes main frame navigation checks incoming from safe browsing +// (currently implemented by the subresource_filter component). For navigations +// which match the ABUSIVE safe browsing list, this class will help the popup +// tab helper in applying a stronger policy for blocked popups. +class SafeBrowsingTriggeredPopupBlocker + : public content::WebContentsObserver, + public subresource_filter::SubresourceFilterObserver { + public: + // This enum backs a histogram. Please append new entries to the end, and + // update enums.xml when making changes. + enum class Action : int { + // User committed a navigation to a non-error page. + kNavigation, + + // Safe Browsing considered this page abusive and the page should be warned. + // Logged at navigation commit. + kWarningSite, + + // Safe Browsing considered this page abusive and the page should be be + // blocked against. Logged at navigation commit. + kEnforcedSite, + + // The popup blocker called into this object to ask if the strong blocking + // should be applied. + kConsidered, + + // This object responded to the popup blocker in the affirmative, and the + // popup was blocked. + kBlocked, + + // Add new entries before this one + kCount + }; + explicit SafeBrowsingTriggeredPopupBlocker( + content::WebContents* web_contents, + std::unique_ptr<ConsoleLogger> logger); + ~SafeBrowsingTriggeredPopupBlocker() override; + + bool ShouldApplyStrongPopupBlocker( + const content::OpenURLParams* open_url_params); + + private: + // content::WebContentsObserver: + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + // subresource_filter::SubresourceFilterObserver: + void OnSafeBrowsingCheckComplete( + content::NavigationHandle* navigation_handle, + safe_browsing::SBThreatType threat_type, + const safe_browsing::ThreatMetadata& threat_metadata) override; + void OnSubresourceFilterGoingAway() override; + + ScopedObserver<subresource_filter::SubresourceFilterObserverManager, + subresource_filter::SubresourceFilterObserver> + scoped_observer_; + + // Whether the next main frame navigation that commits should trigger the + // stronger popup blocker in enforce or warn mode. + base::Optional<safe_browsing::SubresourceFilterLevel> + level_for_next_committed_navigation_; + + std::unique_ptr<ConsoleLogger> logger_; + + // Whether to ignore the threat pattern type. Useful for flexibility because + // we have to wait until metadata patterns reach Stable before using them + // without error. Governed by a variation param. + bool ignore_sublists_ = false; + + // Whether the current committed page load should trigger the stronger popup + // blocker. + bool is_triggered_for_current_committed_load_ = false; + + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTriggeredPopupBlocker); +}; + +#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER_H_
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc new file mode 100644 index 0000000..15e2e456f --- /dev/null +++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -0,0 +1,346 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h" + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/test/histogram_tester.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/safe_browsing/test_safe_browsing_service.h" +#include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" +#include "chrome/browser/ui/blocked_content/console_logger.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "chrome/test/base/testing_browser_process.h" +#include "components/safe_browsing/db/v4_protocol_manager_util.h" +#include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" +#include "content/public/test/navigation_simulator.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/web/WebTriggeringEventInfo.h" +#include "ui/base/page_transition_types.h" +#include "ui/base/window_open_disposition.h" +#include "url/gurl.h" + +class TestConsoleLogger : public ConsoleLogger { + public: + TestConsoleLogger() {} + ~TestConsoleLogger() override {} + + void LogInFrame(content::RenderFrameHost* render_frame_host, + content::ConsoleMessageLevel level, + const std::string& message) override { + messages_.push_back(message); + } + + const std::vector<std::string>& messages() { return messages_; } + + private: + std::vector<std::string> messages_; + DISALLOW_COPY_AND_ASSIGN(TestConsoleLogger); +}; + +class SafeBrowsingTriggeredPopupBlockerTest + : public ChromeRenderViewHostTestHarness { + public: + SafeBrowsingTriggeredPopupBlockerTest() {} + ~SafeBrowsingTriggeredPopupBlockerTest() override {} + + // ChromeRenderViewHostTestHarness: + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + + // Set up safe browsing service with the fake database manager. + // + // TODO(csharrison): This is a bit ugly. See if the instructions in + // test_safe_browsing_service.h can be adapted to be used in unit tests. + safe_browsing::TestSafeBrowsingServiceFactory sb_service_factory; + fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager(); + sb_service_factory.SetTestDatabaseManager( + fake_safe_browsing_database_.get()); + safe_browsing::SafeBrowsingService::RegisterFactory(&sb_service_factory); + auto* safe_browsing_service = + sb_service_factory.CreateSafeBrowsingService(); + safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); + TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService( + safe_browsing_service); + g_browser_process->safe_browsing_service()->Initialize(); + + // Required for the safe browsing notifications on navigation. + ChromeSubresourceFilterClient::CreateForWebContents(web_contents()); + + scoped_feature_list_ = DefaultFeatureList(); + + auto console_logger = base::MakeUnique<TestConsoleLogger>(); + console_logger_ = console_logger.get(); + popup_blocker_ = base::MakeUnique<SafeBrowsingTriggeredPopupBlocker>( + web_contents(), std::move(console_logger)); + } + + void TearDown() override { + fake_safe_browsing_database_ = nullptr; + TestingBrowserProcess::GetGlobal()->safe_browsing_service()->ShutDown(); + + // Must explicitly set these to null and pump the run loop to ensure that + // all cleanup related to these classes actually happens. + TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(nullptr); + base::RunLoop().RunUntilIdle(); + + ChromeRenderViewHostTestHarness::TearDown(); + } + + virtual std::unique_ptr<base::test::ScopedFeatureList> DefaultFeatureList() { + auto feature_list = base::MakeUnique<base::test::ScopedFeatureList>(); + feature_list->InitAndEnableFeature(kAbusiveExperienceEnforce); + return feature_list; + } + + FakeSafeBrowsingDatabaseManager* fake_safe_browsing_database() { + return fake_safe_browsing_database_.get(); + } + + base::test::ScopedFeatureList* ResetFeatureAndGet() { + scoped_feature_list_ = base::MakeUnique<base::test::ScopedFeatureList>(); + return scoped_feature_list_.get(); + } + + SafeBrowsingTriggeredPopupBlocker* popup_blocker() { + return popup_blocker_.get(); + } + + void MarkUrlAsAbusiveWithLevel(const GURL& url, + safe_browsing::SubresourceFilterLevel level) { + safe_browsing::ThreatMetadata metadata; + metadata.subresource_filter_match + [safe_browsing::SubresourceFilterType::ABUSIVE] = level; + fake_safe_browsing_database()->AddBlacklistedUrl( + url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER, metadata); + } + + void MarkUrlAsAbusiveEnforce(const GURL& url) { + MarkUrlAsAbusiveWithLevel(url, + safe_browsing::SubresourceFilterLevel::ENFORCE); + } + + void MarkUrlAsAbusiveWarning(const GURL& url) { + MarkUrlAsAbusiveWithLevel(url, safe_browsing::SubresourceFilterLevel::WARN); + } + + TestConsoleLogger* console_logger() { return console_logger_; } + + private: + std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_; + scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_; + std::unique_ptr<SafeBrowsingTriggeredPopupBlocker> popup_blocker_; + + // Owned by the popup blocker. + TestConsoleLogger* console_logger_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTriggeredPopupBlockerTest); +}; + +class IgnoreSublistSafeBrowsingTriggeredPopupBlockerTest + : public SafeBrowsingTriggeredPopupBlockerTest { + std::unique_ptr<base::test::ScopedFeatureList> DefaultFeatureList() override { + auto feature_list = base::MakeUnique<base::test::ScopedFeatureList>(); + feature_list->InitAndEnableFeatureWithParameters( + kAbusiveExperienceEnforce, {{"ignore_sublists", "true"}}); + return feature_list; + } +}; + +TEST_F(IgnoreSublistSafeBrowsingTriggeredPopupBlockerTest, + MatchNoSublist_BlocksPopup) { + const GURL url("https://example.test/"); + fake_safe_browsing_database()->AddBlacklistedUrl( + url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER); + NavigateAndCommit(url); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +} + +// ignore_sublists should still block on URLs matching a sublist. +TEST_F(IgnoreSublistSafeBrowsingTriggeredPopupBlockerTest, + MatchSublist_BlocksPopup) { + const GURL url("https://example.test/"); + MarkUrlAsAbusiveEnforce(url); + NavigateAndCommit(url); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, MatchingURL_BlocksPopupAndLogs) { + const GURL url("https://example.test/"); + MarkUrlAsAbusiveEnforce(url); + NavigateAndCommit(url); + EXPECT_TRUE(console_logger()->messages().empty()); + + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + EXPECT_EQ(1u, console_logger()->messages().size()); + EXPECT_EQ(console_logger()->messages().front(), kAbusiveEnforceMessage); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, + MatchingURL_BlocksPopupFromOpenURL) { + const GURL url("https://example.test/"); + MarkUrlAsAbusiveEnforce(url); + NavigateAndCommit(url); + + // If the popup is coming from OpenURL params, the strong popup blocker is + // only going to look at the triggering event info. It will only block the + // popup if we know the triggering event is untrusted. + content::OpenURLParams params( + GURL("https://example.popup/"), content::Referrer(), + WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, + true /* is_renderer_initiated */); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(¶ms)); + + params.triggering_event_info = + blink::WebTriggeringEventInfo::kFromUntrustedEvent; + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(¶ms)); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, NoMatch_NoBlocking) { + const GURL url("https://example.test/"); + NavigateAndCommit(url); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + EXPECT_TRUE(console_logger()->messages().empty()); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, NoFeature_NoBlocking) { + ResetFeatureAndGet()->InitAndDisableFeature(kAbusiveExperienceEnforce); + const GURL url("https://example.test/"); + MarkUrlAsAbusiveEnforce(url); + NavigateAndCommit(url); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, OnlyBlockOnMatchingUrls) { + const GURL url1("https://example.first/"); + const GURL url2("https://example.second/"); + const GURL url3("https://example.third/"); + // Only mark url2 as abusive. + MarkUrlAsAbusiveEnforce(url2); + + NavigateAndCommit(url1); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + + NavigateAndCommit(url2); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + + NavigateAndCommit(url3); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + + NavigateAndCommit(url1); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, + SameDocumentNavigation_MaintainsBlocking) { + const GURL url("https://example.first/"); + const GURL hash_url("https://example.first/#hash"); + + MarkUrlAsAbusiveEnforce(url); + NavigateAndCommit(url); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + + // This is merely a same document navigation, keep the popup blocker. + NavigateAndCommit(hash_url); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, + FailNavigation_MaintainsBlocking) { + const GURL url("https://example.first/"); + const GURL fail_url("https://example.fail/"); + + MarkUrlAsAbusiveEnforce(url); + NavigateAndCommit(url); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + + // Abort the navigation before it commits. + content::NavigationSimulator::NavigateAndFailFromDocument( + fail_url, net::ERR_ABORTED, main_rfh()); + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + + // Committing an error page should probably reset the blocker though, despite + // the fact that it is probably a bug for an error page to spawn popups. + content::NavigationSimulator::NavigateAndFailFromDocument( + fail_url, net::ERR_CONNECTION_RESET, main_rfh()); + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, LogActions) { + base::HistogramTester histogram_tester; + const char kActionHistogram[] = "ContentSettings.Popups.StrongBlockerActions"; + int total_count = 0; + // Call this when a new histogram entry is logged. Call it multiple times if + // multiple entries are logged. + auto check_histogram = [&](SafeBrowsingTriggeredPopupBlocker::Action action, + int expected_count) { + histogram_tester.ExpectBucketCount( + kActionHistogram, static_cast<int>(action), expected_count); + total_count++; + }; + + const GURL url_enforce("https://example.enforce/"); + const GURL url_warn("https://example.warn/"); + const GURL url_nothing("https://example.nothing/"); + MarkUrlAsAbusiveEnforce(url_enforce); + MarkUrlAsAbusiveWarning(url_warn); + + // Navigate to an enforce site. + NavigateAndCommit(url_enforce); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kEnforcedSite, 1); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); + + // Block two popups. + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kBlocked, 1); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); + + EXPECT_TRUE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 2); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kBlocked, 2); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); + + // Navigate to a warn site. + NavigateAndCommit(url_warn); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, 2); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kWarningSite, 1); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); + + // Let one popup through. + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 3); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); + + // Navigate to a site not matched in Safe Browsing. + NavigateAndCommit(url_nothing); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, 3); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); + + // Let one popup through. + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 4); + histogram_tester.ExpectTotalCount(kActionHistogram, total_count); +} + +TEST_F(SafeBrowsingTriggeredPopupBlockerTest, WarningMatch_OnlyLogs) { + const GURL url("https://example.test/"); + + MarkUrlAsAbusiveWarning(url); + NavigateAndCommit(url); + + // Warning should come at navigation commit time, not at popup time. + EXPECT_EQ(1u, console_logger()->messages().size()); + EXPECT_EQ(console_logger()->messages().front(), kAbusiveWarnMessage); + + EXPECT_FALSE(popup_blocker()->ShouldApplyStrongPopupBlocker(nullptr)); +}
diff --git a/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller.mm b/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller.mm index 26ec81b..e642ac1b 100644 --- a/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller.mm +++ b/chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller.mm
@@ -106,6 +106,7 @@ base::scoped_nsobject<NSTextField> usernameField_; // The field contains the password or IDP origin for federated credentials. base::scoped_nsobject<NSTextField> passwordField_; + base::scoped_nsobject<NSTextField> passwordText_; base::scoped_nsobject<NSButton> passwordViewButton_; base::scoped_nsobject<NSButton> saveButton_; base::scoped_nsobject<NSButton> neverButton_; @@ -141,12 +142,17 @@ if (combobox) { FillPasswordCombobox(self.model->pending_password(), visible, combobox); } else { + NSRect oldFrame = [passwordField_ frame]; + CGFloat offsetY = 0; if (visible) { InitEditableLabel(passwordField_.get(), form.password_value); + offsetY = NSMidY([passwordText_ frame]) - NSMidY(oldFrame); } else { InitLabel(passwordField_.get(), base::string16(form.password_value.length(), '*')); + offsetY = NSMaxY([passwordText_ frame]) - NSMaxY(oldFrame); } + [passwordField_ setFrame:NSOffsetRect(oldFrame, 0, offsetY)]; } [[self.view window] makeFirstResponder:(visible ? passwordField_.get() : saveButton_.get())]; @@ -242,25 +248,26 @@ } [container addSubview:passwordField_]; - NSTextField* usernameLabel = + NSTextField* usernameText = Label(l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_USERNAME_LABEL)); - [container addSubview:usernameLabel]; - NSTextField* passwordLabel = - Label(l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_PASSWORD_LABEL)); - [container addSubview:passwordLabel]; + [container addSubview:usernameText]; + passwordText_.reset([Label( + l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_PASSWORD_LABEL)) retain]); + [container addSubview:passwordText_]; // Layout the elements. CGFloat firstColumnSize = - std::max(NSWidth([usernameLabel frame]), NSWidth([passwordLabel frame])); + std::max(NSWidth([usernameText frame]), NSWidth([passwordText_ frame])); // Bottow row. CGFloat rowHeight = std::max(NSHeight([passwordField_ frame]), - NSHeight([passwordLabel frame])); - CGFloat curY = (rowHeight - NSHeight([passwordLabel frame])) / 2; - [passwordLabel setFrameOrigin:NSMakePoint(firstColumnSize - - NSWidth([passwordLabel frame]), + NSHeight([passwordText_ frame])); + CGFloat curY = (rowHeight - NSHeight([passwordText_ frame])) / 2; + [passwordText_ setFrameOrigin:NSMakePoint(firstColumnSize - + NSWidth([passwordText_ frame]), curY)]; - CGFloat curX = NSMaxX([passwordLabel frame]) + kItemLabelSpacing; - curY = (rowHeight - NSHeight([passwordField_ frame])) / 2; + CGFloat curX = NSMaxX([passwordText_ frame]) + kItemLabelSpacing; + // Password field is top-aligned with the label because it's not editable. + curY = NSMaxY([passwordText_ frame]) - NSHeight([passwordField_ frame]); [passwordField_ setFrameOrigin:NSMakePoint(curX, curY)]; CGFloat remainingWidth = kDesiredRowWidth - NSMinX([passwordField_ frame]); if (passwordViewButton_) { @@ -276,11 +283,11 @@ // Next row. CGFloat rowY = rowHeight + kRelatedControlVerticalSpacing; rowHeight = std::max(NSHeight([usernameField_ frame]), - NSHeight([usernameLabel frame])); - curX = firstColumnSize - NSWidth([usernameLabel frame]); - curY = (rowHeight - NSHeight([usernameLabel frame])) / 2 + rowY; - [usernameLabel setFrameOrigin:NSMakePoint(curX, curY)]; - curX = NSMaxX([usernameLabel frame]) + kItemLabelSpacing; + NSHeight([usernameText frame])); + curX = firstColumnSize - NSWidth([usernameText frame]); + curY = (rowHeight - NSHeight([usernameText frame])) / 2 + rowY; + [usernameText setFrameOrigin:NSMakePoint(curX, curY)]; + curX = NSMaxX([usernameText frame]) + kItemLabelSpacing; curY = (rowHeight - NSHeight([usernameField_ frame])) / 2 + rowY; [usernameField_ setFrameOrigin:NSMakePoint(curX, curY)]; remainingWidth = kDesiredRowWidth - NSMinX([usernameField_ frame]);
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.mm b/chrome/browser/ui/cocoa/tabs/tab_view.mm index fa3ecea4..47e42fe7 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_view.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_view.mm
@@ -36,7 +36,8 @@ const SkColor kDarkModeIconColor = SkColorSetARGB(0xFF, 0xC4, 0xC4, 0xC4); bool IsTabStripKeyboardFocusEnabled() { - return base::FeatureList::IsEnabled(features::kTabStripKeyboardFocus); + return base::FeatureList::IsEnabled(features::kTabStripKeyboardFocus) && + [NSApp isFullKeyboardAccessEnabled]; } } // namespace
diff --git a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc index 8226965..cddacd92 100644 --- a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc +++ b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
@@ -93,378 +93,386 @@ ElementsAre(Bucket(0, 1), Bucket(8, 1))); } -// TODO(https://crbug.com/767406): Split this test in readable units. TEST(NTPUserDataLoggerTest, TestLogMostVisitedImpression) { base::StatisticsRecorder::Initialize(); - base::HistogramTester histogram_tester; - TestNTPUserDataLogger logger(GURL("chrome://newtab/")); - base::TimeDelta delta = base::TimeDelta::FromMilliseconds(0); + const base::TimeDelta delta = base::TimeDelta::FromMilliseconds(0); - // Impressions increment the associated bins. - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 3, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 4, TileSource::TOP_SITES, TileTitleSource::TITLE_TAG, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 5, TileSource::TOP_SITES, TileTitleSource::MANIFEST, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 6, TileSource::POPULAR, TileTitleSource::TITLE_TAG, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 7, TileSource::POPULAR_BAKED_IN, TileTitleSource::META_TAG, - TileVisualType::THUMBNAIL, base::Time(), GURL())); + { + base::HistogramTester histogram_tester; - // Repeated impressions for the same bins are ignored. - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 1, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 3, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); + // Impressions increment the associated bins. + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 3, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 4, TileSource::TOP_SITES, TileTitleSource::TITLE_TAG, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 5, TileSource::TOP_SITES, TileTitleSource::MANIFEST, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 6, TileSource::POPULAR, TileTitleSource::TITLE_TAG, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 7, TileSource::POPULAR_BAKED_IN, TileTitleSource::META_TAG, + TileVisualType::THUMBNAIL, base::Time(), GURL())); - // Impressions are silently ignored for tiles >= 8. - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 8, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 9, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); + // Repeated impressions for the same bins are ignored. + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 1, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 3, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); - // The actual histograms are emitted only after the ALL_TILES_LOADED event, so - // at this point everything should still be empty. - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), - IsEmpty()); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - IsEmpty()); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - IsEmpty()); + // Impressions are silently ignored for tiles >= 8. + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 8, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 9, TileSource::TOP_SITES, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); - // Send the ALL_TILES_LOADED event, this should trigger emitting histograms. - logger.LogEvent(NTP_ALL_TILES_LOADED, delta); + // The actual histograms are emitted only after the ALL_TILES_LOADED event, + // so at this point everything should still be empty. + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.server"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.client"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), + IsEmpty()); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), - ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1), - Bucket(4, 1), Bucket(5, 1), Bucket(6, 1), Bucket(7, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), - ElementsAre(Bucket(4, 1), Bucket(5, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.SuggestionsImpression.popular_fetched"), - ElementsAre(Bucket(6, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.SuggestionsImpression.popular_baked_in"), - ElementsAre(Bucket(7, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 7), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 3), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.popular_fetched"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.popular_baked_in"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), - ElementsAre(Bucket(kManifestTitleSource, 1), - Bucket(kMetaTagTitleSource, 1), - Bucket(kTitleTagTitleSource, 2), - Bucket(kInferredTitleSource, 4))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - ElementsAre(Bucket(kInferredTitleSource, 4))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), - ElementsAre(Bucket(kManifestTitleSource, 1), - Bucket(kTitleTagTitleSource, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_fetched"), - ElementsAre(Bucket(kTitleTagTitleSource, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_baked_in"), - ElementsAre(Bucket(kMetaTagTitleSource, 1))); + // Send the ALL_TILES_LOADED event, this should trigger emitting histograms. + logger.LogEvent(NTP_ALL_TILES_LOADED, delta); + + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1), + Bucket(4, 1), Bucket(5, 1), Bucket(6, 1), Bucket(7, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.server"), + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.client"), + ElementsAre(Bucket(4, 1), Bucket(5, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.popular_fetched"), + ElementsAre(Bucket(6, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.popular_baked_in"), + ElementsAre(Bucket(7, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 7), + Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType.server"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 3), + Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.client"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType.popular_fetched"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType.popular_baked_in"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), + ElementsAre(Bucket(kManifestTitleSource, 1), + Bucket(kMetaTagTitleSource, 1), + Bucket(kTitleTagTitleSource, 2), + Bucket(kInferredTitleSource, 4))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), + ElementsAre(Bucket(kInferredTitleSource, 4))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), + ElementsAre(Bucket(kManifestTitleSource, 1), + Bucket(kTitleTagTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_fetched"), + ElementsAre(Bucket(kTitleTagTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_baked_in"), + ElementsAre(Bucket(kMetaTagTitleSource, 1))); + } // After navigating away from the NTP and back, we record again. - logger.NavigatedFromURLToURL(GURL("chrome://newtab/"), - GURL("http://chromium.org")); - logger.NavigatedFromURLToURL(GURL("http://chromium.org"), - GURL("chrome://newtab/")); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + { + base::HistogramTester histogram_tester; - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 1, TileSource::POPULAR, TileTitleSource::MANIFEST, + logger.NavigatedFromURLToURL(GURL("chrome://newtab/"), + GURL("http://chromium.org")); + logger.NavigatedFromURLToURL(GURL("http://chromium.org"), + GURL("chrome://newtab/")); - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 1, TileSource::POPULAR, TileTitleSource::MANIFEST, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::INFERRED, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( + 3, TileSource::TOP_SITES, TileTitleSource::MANIFEST, + TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); + logger.LogEvent(NTP_ALL_TILES_LOADED, delta); - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression( - 3, TileSource::TOP_SITES, TileTitleSource::MANIFEST, - - TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); - logger.LogEvent(NTP_ALL_TILES_LOADED, delta); - - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), - ElementsAre(Bucket(0, 2), Bucket(1, 2), Bucket(2, 2), Bucket(3, 2), - Bucket(4, 1), Bucket(5, 1), Bucket(6, 1), Bucket(7, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.server"), - ElementsAre(Bucket(0, 2), Bucket(1, 1), Bucket(2, 2), Bucket(3, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression.client"), - ElementsAre(Bucket(3, 1), Bucket(4, 1), Bucket(5, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.SuggestionsImpression.popular_fetched"), - ElementsAre(Bucket(1, 1), Bucket(6, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.SuggestionsImpression.popular_baked_in"), - ElementsAre(Bucket(7, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 10), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 5), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.popular_fetched"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileType.popular_baked_in"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), - ElementsAre(Bucket(kManifestTitleSource, 3), - Bucket(kMetaTagTitleSource, 1), - Bucket(kTitleTagTitleSource, 2), - Bucket(kInferredTitleSource, 6))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), - ElementsAre(Bucket(kInferredTitleSource, 6))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), - ElementsAre(Bucket(kManifestTitleSource, 2), - Bucket(kTitleTagTitleSource, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_fetched"), - ElementsAre(Bucket(kManifestTitleSource, 1), - Bucket(kTitleTagTitleSource, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_baked_in"), - ElementsAre(Bucket(kMetaTagTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpression"), + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.server"), + ElementsAre(Bucket(0, 1), Bucket(2, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.client"), + ElementsAre(Bucket(3, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.popular_fetched"), + ElementsAre(Bucket(1, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.SuggestionsImpression.popular_baked_in"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 3), + Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileType.server"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType.client"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType.popular_fetched"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileType.popular_baked_in"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle"), + ElementsAre(Bucket(kManifestTitleSource, 2), + Bucket(kInferredTitleSource, 2))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.server"), + ElementsAre(Bucket(kInferredTitleSource, 2))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitle.client"), + ElementsAre(Bucket(kManifestTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_fetched"), + ElementsAre(Bucket(kManifestTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitle.popular_baked_in"), + IsEmpty()); + } } -// TODO(https://crbug.com/767406): Split this test in readable units. TEST(NTPUserDataLoggerTest, TestLogMostVisitedNavigation) { base::StatisticsRecorder::Initialize(); - base::HistogramTester histogram_tester; - TestNTPUserDataLogger logger(GURL("chrome://newtab/")); - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), - ElementsAre(Bucket(0, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - IsEmpty()); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - IsEmpty()); + { + base::HistogramTester histogram_tester; - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), - ElementsAre(Bucket(0, 1), Bucket(1, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 1), Bucket(1, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - IsEmpty()); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - IsEmpty()); + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 2, TileSource::TOP_SITES, TileTitleSource::MANIFEST, - TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), - ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 1), Bucket(1, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - ElementsAre(Bucket(2, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), + ElementsAre(Bucket(0, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), + ElementsAre(Bucket(0, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), + IsEmpty()); - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 3, TileSource::POPULAR, TileTitleSource::META_TAG, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.MostVisited"), - ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 1), Bucket(1, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - ElementsAre(Bucket(2, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.MostVisited.popular_fetched"), - ElementsAre(Bucket(3, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.TileTypeClicked.popular_fetched"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked"), - ElementsAre(Bucket(kUnknownTitleSource, 2), - Bucket(kManifestTitleSource, 1), - Bucket(kMetaTagTitleSource, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), - ElementsAre(Bucket(kUnknownTitleSource, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), - ElementsAre(Bucket(kManifestTitleSource, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.TileTitleClicked.popular_fetched"), - ElementsAre(Bucket(kMetaTagTitleSource, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), + IsEmpty()); + } - // Navigations always increase. - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 1, TileSource::TOP_SITES, TileTitleSource::TITLE_TAG, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( - 3, TileSource::POPULAR, TileTitleSource::MANIFEST, - TileVisualType::THUMBNAIL, base::Time(), GURL())); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.MostVisited"), - ElementsAre(Bucket(0, 2), Bucket(1, 2), Bucket(2, 2), Bucket(3, 2))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), - ElementsAre(Bucket(0, 2), Bucket(1, 1), Bucket(2, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), - ElementsAre(Bucket(1, 1), Bucket(2, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.MostVisited.popular_fetched"), - ElementsAre(Bucket(3, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 6), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 2))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 3), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1), - Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.TileTypeClicked.popular_fetched"), - ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2))); - EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked"), - ElementsAre(Bucket(kUnknownTitleSource, 4), - Bucket(kManifestTitleSource, 2), - Bucket(kMetaTagTitleSource, 1), - Bucket(kTitleTagTitleSource, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), - ElementsAre(Bucket(kUnknownTitleSource, 4))); - EXPECT_THAT( - histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), - ElementsAre(Bucket(kManifestTitleSource, 1), - Bucket(kTitleTagTitleSource, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "NewTabPage.TileTitleClicked.popular_fetched"), - ElementsAre(Bucket(kManifestTitleSource, 1), - Bucket(kMetaTagTitleSource, 1))); + { + base::HistogramTester histogram_tester; + + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 1, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), + ElementsAre(Bucket(1, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), + ElementsAre(Bucket(1, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), + IsEmpty()); + + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), + IsEmpty()); + } + + { + base::HistogramTester histogram_tester; + + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 2, TileSource::TOP_SITES, TileTitleSource::MANIFEST, + TileVisualType::THUMBNAIL_FAILED, base::Time(), GURL())); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), + ElementsAre(Bucket(2, 1))); + + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL_FAILED, 1))); + } + + { + base::HistogramTester histogram_tester; + + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 3, TileSource::POPULAR, TileTitleSource::META_TAG, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited"), + ElementsAre(Bucket(3, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.MostVisited.popular_fetched"), + ElementsAre(Bucket(3, 1))); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.TileTypeClicked.popular_fetched"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked"), + ElementsAre(Bucket(kMetaTagTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), + IsEmpty()); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), + IsEmpty()); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.TileTitleClicked.popular_fetched"), + ElementsAre(Bucket(kMetaTagTitleSource, 1))); + } + + { + base::HistogramTester histogram_tester; + + // Navigations always increase. + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 0, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 1, TileSource::TOP_SITES, TileTitleSource::TITLE_TAG, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 2, TileSource::SUGGESTIONS_SERVICE, TileTitleSource::UNKNOWN, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + logger.LogMostVisitedNavigation(ntp_tiles::NTPTileImpression( + 3, TileSource::POPULAR, TileTitleSource::MANIFEST, + TileVisualType::THUMBNAIL, base::Time(), GURL())); + + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.MostVisited"), + ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), Bucket(3, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.server"), + ElementsAre(Bucket(0, 1), Bucket(2, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisited.client"), + ElementsAre(Bucket(1, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.MostVisited.popular_fetched"), + ElementsAre(Bucket(3, 1))); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 4))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.server"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 2))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTypeClicked.client"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.TileTypeClicked.popular_fetched"), + ElementsAre(Bucket(ntp_tiles::TileVisualType::THUMBNAIL, 1))); + + EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked"), + ElementsAre(Bucket(kUnknownTitleSource, 2), + Bucket(kManifestTitleSource, 1), + Bucket(kTitleTagTitleSource, 1))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.server"), + ElementsAre(Bucket(kUnknownTitleSource, 2))); + EXPECT_THAT( + histogram_tester.GetAllSamples("NewTabPage.TileTitleClicked.client"), + ElementsAre(Bucket(kTitleTagTitleSource, 1))); + EXPECT_THAT(histogram_tester.GetAllSamples( + "NewTabPage.TileTitleClicked.popular_fetched"), + ElementsAre(Bucket(kManifestTitleSource, 1))); + } } TEST(NTPUserDataLoggerTest, TestLoadTime) {
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc index d7bcf1d..73e7895d 100644 --- a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc +++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc
@@ -92,7 +92,6 @@ DispatchKeyEventPostIMECallback callback) override { std::move(callback).Run(false); } - void SetCandidateWindowVisible(bool visible) override {} mojo::Binding<ui::mojom::TextInputClient> binding_; std::unique_ptr<base::RunLoop> run_loop_;
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc index 00d02153..665d679 100644 --- a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc +++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc
@@ -11,10 +11,6 @@ #include "base/strings/utf_string_conversions.h" -#if defined(OS_CHROMEOS) -#include "ui/base/ime/ime_bridge.h" -#endif - RemoteTextInputClient::RemoteTextInputClient( ui::mojom::TextInputClientPtr remote_client, ui::TextInputType text_input_type, @@ -27,11 +23,7 @@ text_input_mode_(text_input_mode), text_direction_(text_direction), text_input_flags_(text_input_flags), - caret_bounds_(caret_bounds) { -#if defined(OS_CHROMEOS) - ui::IMEBridge::Get()->SetCandidateWindowHandler(this); -#endif -} + caret_bounds_(caret_bounds) {} RemoteTextInputClient::~RemoteTextInputClient() {} @@ -185,21 +177,3 @@ base::OnceCallback<void(bool)>()); return ui::EventDispatchDetails(); } - -void RemoteTextInputClient::UpdateLookupTable( - const ui::CandidateWindow& candidate_window, - bool visible) {} - -void RemoteTextInputClient::UpdatePreeditText(const base::string16& text, - uint32_t cursor_pos, - bool visible) {} - -void RemoteTextInputClient::SetCursorBounds(const gfx::Rect& cursor_bounds, - const gfx::Rect& composition_head) { -} - -void RemoteTextInputClient::OnCandidateWindowVisibilityChanged(bool visible) { -#if defined(OS_CHROMEOS) - remote_client_->SetCandidateWindowVisible(visible); -#endif -}
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h index 2e38097..ba549fd 100644 --- a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h +++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_ #include "services/ui/public/interfaces/ime/ime.mojom.h" -#include "ui/base/ime/chromeos/ime_candidate_window_handler_interface.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/text_input_client.h" @@ -14,8 +13,7 @@ // a remote client. This is intended to be passed to the overrides of // ui::InputMethod::SetFocusedTextInputClient(). class RemoteTextInputClient : public ui::TextInputClient, - public ui::internal::InputMethodDelegate, - chromeos::IMECandidateWindowHandlerInterface { + public ui::internal::InputMethodDelegate { public: RemoteTextInputClient(ui::mojom::TextInputClientPtr remote_client, ui::TextInputType text_input_type, @@ -63,16 +61,6 @@ ui::EventDispatchDetails DispatchKeyEventPostIME( ui::KeyEvent* event) override; - // chromeos::IMECandidateWindowHandlerInterface: - void UpdateLookupTable(const ui::CandidateWindow& candidate_window, - bool visible) override; - void UpdatePreeditText(const base::string16& text, - uint32_t cursor_pos, - bool visible) override; - void SetCursorBounds(const gfx::Rect& cursor_bounds, - const gfx::Rect& composition_head) override; - void OnCandidateWindowVisibilityChanged(bool visible) override; - ui::mojom::TextInputClientPtr remote_client_; ui::TextInputType text_input_type_; ui::TextInputMode text_input_mode_;
diff --git a/chrome/browser/vr/elements/exit_warning_texture.cc b/chrome/browser/vr/elements/exit_warning_texture.cc index f1955caa..663f2a7 100644 --- a/chrome/browser/vr/elements/exit_warning_texture.cc +++ b/chrome/browser/vr/elements/exit_warning_texture.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/vr/elements/exit_warning_texture.h" #include "cc/paint/skia_paint_canvas.h" -#include "components/strings/grit/components_strings.h" +#include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/canvas.h"
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 51e59f5..265fbc9 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -123,18 +123,6 @@ // Enables Basic/Advanced tabs in ClearBrowsingData. const base::Feature kTabsInCbd{"TabsInCBD", base::FEATURE_ENABLED_BY_DEFAULT}; -// If enabled, we'll only take thumbnails of unknown URLs (i.e. URLs that are -// not (yet) part of TopSites) if they have an interesting transition type, i.e. -// one that qualifies for inclusion in TopSites. -const base::Feature kCaptureThumbnailDependingOnTransitionType{ - "CaptureThumbnailDependingOnTransitionType", - base::FEATURE_ENABLED_BY_DEFAULT}; - -// Whether to capture page thumbnails when navigating away from the current page -// (in addition to any other times this might happen). -const base::Feature kCaptureThumbnailOnNavigatingAway{ - "CaptureThumbnailOnNavigatingAway", base::FEATURE_ENABLED_BY_DEFAULT}; - // Whether to trigger app banner installability checks on page load. const base::Feature kCheckInstallabilityForBannerOnLoad{ "CheckInstallabilityForBannerOnLoad", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 5d518a1e..02b9983 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -66,10 +66,6 @@ extern const base::Feature kTabStripKeyboardFocus; #endif // defined(OS_MACOSX) -extern const base::Feature kCaptureThumbnailDependingOnTransitionType; - -extern const base::Feature kCaptureThumbnailOnNavigatingAway; - extern const base::Feature kCheckInstallabilityForBannerOnLoad; extern const base::Feature kClickToOpenPDFPlaceholder;
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index d3e5aa3a..21f7d6f 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1698,14 +1698,11 @@ base::Time chrome_66_not_before = base::Time::FromDoubleT(1464739200); const char* in_future_string = cert_validity_start < chrome_66_not_before ? "in M66" : "in M70"; - std::string port; - if (url.port() != "443") - port = base::StringPrintf(":%s", url.port().c_str()); *console_message = base::StringPrintf( - "The SSL certificate used to load resources from %s://%s%s" + "The SSL certificate used to load resources from %s" " will be distrusted %s. Once distrusted, users will be prevented from " "loading these resources. See https://g.co/chrome/symantecpkicerts for " "more information.", - url.scheme().c_str(), url.host().c_str(), port.c_str(), in_future_string); + url::Origin(url).Serialize().c_str(), in_future_string); return true; }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 56fa72b..0f838fa 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3398,6 +3398,7 @@ "../browser/ui/autofill/autofill_popup_layout_model_unittest.cc", "../browser/ui/autofill/popup_view_common_unittest.cc", "../browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc", + "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc", "../browser/ui/blocked_content/scoped_visibility_tracker_unittest.cc", "../browser/ui/bookmarks/bookmark_editor_unittest.cc", "../browser/ui/bookmarks/bookmark_ui_utils_desktop_unittest.cc", @@ -3555,7 +3556,6 @@ "//components/safe_browsing:features", "//components/safe_browsing/db", "//components/safe_browsing/db:test_database_manager", - "//components/safe_json:test_support", "//components/spellcheck:build_features", "//components/strings", "//components/subresource_filter/core/browser:test_support", @@ -3581,6 +3581,7 @@ "//net", "//net:test_support", "//ppapi/features", + "//services/data_decoder/public/cpp:test_support", "//skia", "//testing/gmock", "//testing/gtest",
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 9804992..8342cfd2 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -254,7 +254,9 @@ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1960 'CorrectEventFiringTest.testShouldFireMouseDownEventWhenClicking', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2076 - 'CorrectEventFiringTest.testShouldReportTheXAndYCoordinatesWhenClicking' + 'CorrectEventFiringTest.testShouldReportTheXAndYCoordinatesWhenClicking', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2077 + 'CorrectEventFiringTest.testShouldEmitClickEventWhenClickingOnATextInputElement', ] )
diff --git a/chrome/test/data/android/render_tests/NewTabPageTest.new_tab_page_scrolled.Nexus_5-19.png b/chrome/test/data/android/render_tests/NewTabPageTest.new_tab_page_scrolled.Nexus_5-19.png index 16ca9405..b9669e7d 100644 --- a/chrome/test/data/android/render_tests/NewTabPageTest.new_tab_page_scrolled.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/NewTabPageTest.new_tab_page_scrolled.Nexus_5-19.png Binary files differ
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 9b68da2..38e2b30b 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -40,7 +40,6 @@ "//chrome/common/profiling", "//chrome/profiling", "//components/payments/content/utility", - "//components/safe_json/utility", "//components/search_engines", "//components/strings", "//components/url_formatter",
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index fa24cc3..c31c46e 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -6,7 +6,6 @@ "+components/payments/content/utility", "+components/printing/service/public/cpp", "+components/printing/service/public/interfaces", - "+components/safe_json", "+components/wifi", "+content/public/child", "+content/public/network",
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 15b164c0..e29b25a 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -22,7 +22,6 @@ #include "chrome/utility/printing/pdf_to_pwg_raster_converter_impl.h" #include "chrome/utility/utility_message_handler.h" #include "components/payments/content/utility/payment_manifest_parser.h" -#include "components/safe_json/utility/safe_json_parser_mojo_impl.h" #include "content/public/common/content_switches.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/simple_connection_filter.h" @@ -292,9 +291,6 @@ #endif // !defined(OS_ANDROID) registry->AddInterface(base::Bind(&payments::PaymentManifestParser::Create), base::ThreadTaskRunnerHandle::Get()); - registry->AddInterface( - base::Bind(&safe_json::SafeJsonParserMojoImpl::Create), - base::ThreadTaskRunnerHandle::Get()); #if defined(OS_WIN) registry->AddInterface(base::Bind(&ShellHandlerImpl::Create), base::ThreadTaskRunnerHandle::Get());
diff --git a/components/BUILD.gn b/components/BUILD.gn index ceb26d5..2efb7edb 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -213,7 +213,6 @@ "//components/safe_browsing/common:unit_tests", "//components/safe_browsing/password_protection:password_protection_unittest", "//components/safe_browsing/triggers:unit_tests", - "//components/safe_json:unit_tests", "//components/security_state/content:unit_tests", "//components/spellcheck/browser:unit_tests", "//components/spellcheck/renderer:unit_tests", @@ -253,8 +252,6 @@ "//components/invalidation/impl", "//components/invalidation/impl:java", "//components/policy/android:policy_java", - "//components/safe_json", - "//components/safe_json/android:safe_json_java", "//components/signin/core/browser", "//components/signin/core/browser/android:java", "//components/spellcheck/browser/android:java",
diff --git a/components/certificate_transparency/BUILD.gn b/components/certificate_transparency/BUILD.gn index ef07c14a..f55ed3d7 100644 --- a/components/certificate_transparency/BUILD.gn +++ b/components/certificate_transparency/BUILD.gn
@@ -20,7 +20,6 @@ "//base", "//components/base32", "//components/prefs", - "//components/safe_json", "//components/url_formatter", "//components/url_matcher", "//net", @@ -43,7 +42,6 @@ "//base/test:test_support", "//components/base32", "//components/prefs:test_support", - "//components/safe_json:test_support", "//net:test_support", "//testing/gmock", "//testing/gtest",
diff --git a/components/certificate_transparency/DEPS b/components/certificate_transparency/DEPS index 575b1501..4a85886 100644 --- a/components/certificate_transparency/DEPS +++ b/components/certificate_transparency/DEPS
@@ -1,7 +1,6 @@ include_rules = [ "+components/base32", "+components/prefs", - "+components/safe_json", "+components/url_formatter", "+components/url_matcher", "+crypto",
diff --git a/components/cronet/ios/BUILD.gn b/components/cronet/ios/BUILD.gn index b2b7eca8..13bffdc 100644 --- a/components/cronet/ios/BUILD.gn +++ b/components/cronet/ios/BUILD.gn
@@ -94,6 +94,8 @@ if (!use_platform_icu_alternatives) { deps += [ "//base:i18n" ] } + + configs += [ "//build/config/compiler:enable_arc" ] } source_set("cronet_sources_with_global_state") { @@ -186,6 +188,7 @@ public_deps = [ "//components/grpc_support", ] + configs += [ "//build/config/compiler:enable_arc" ] } # A static library which contains all dependencies of :cronet_static.
diff --git a/components/cronet/ios/Cronet.mm b/components/cronet/ios/Cronet.mm index eeee8b65..607bbfbd 100644 --- a/components/cronet/ios/Cronet.mm +++ b/components/cronet/ios/Cronet.mm
@@ -23,6 +23,10 @@ #include "net/cert/cert_verifier.h" #include "net/url_request/url_request_context_getter.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // Cronet NSError constants. NSString* const CRNCronetErrorDomain = @"CRNCronetErrorDomain"; NSString* const CRNInvalidArgumentKey = @"CRNInvalidArgumentKey"; @@ -82,11 +86,11 @@ public: CronetHttpProtocolHandlerDelegate(net::URLRequestContextGetter* getter, RequestFilterBlock filter) - : getter_(getter), filter_(filter, base::scoped_policy::RETAIN) {} + : getter_(getter), filter_(filter) {} void SetRequestFilterBlock(RequestFilterBlock filter) { base::AutoLock auto_lock(lock_); - filter_.reset(filter, base::scoped_policy::RETAIN); + filter_.reset(filter); } private:
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm index ce76b280..d03df14 100644 --- a/components/cronet/ios/cronet_environment.mm +++ b/components/cronet/ios/cronet_environment.mm
@@ -56,6 +56,10 @@ #include "url/scheme_host_port.h" #include "url/url_util.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { // Request context getter for Cronet.
diff --git a/components/cronet/tools/generate_accept_languages.py b/components/cronet/tools/generate_accept_languages.py index ec571f7..7d3dee57 100644 --- a/components/cronet/tools/generate_accept_languages.py +++ b/components/cronet/tools/generate_accept_languages.py
@@ -31,7 +31,7 @@ return dict(accept_langs for accept_langs in accept_langs_list if accept_langs) -HEADER = "NSDictionary* acceptLangs = @{" +HEADER = "static NSDictionary* const acceptLangs = @{" def LINE(locale, accept_langs): return ' @"' + locale + '" : @"' + accept_langs + '",' FOOTER = "};"
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css index ffa91e3..f8976f0 100644 --- a/components/flags_ui/resources/flags.css +++ b/components/flags_ui/resources/flags.css
@@ -111,13 +111,12 @@ border-radius: 3px; box-sizing: border-box; font-size: 1em; - padding: 12px 12px 12px 36px; + padding: 12px 36px; width: 100%; } [dir='rtl'] #search { background-position: right 50%; - padding: 12px 36px 12px 12px; } #search:focus { @@ -242,12 +241,6 @@ width: 150px; } -.experiment .platforms::before { - content: '–'; - display: inline; - padding: 0 2px; -} - .experiment-disable-link, .experiment-enable-link { background: white; @@ -441,19 +434,16 @@ @media (max-width: 360px) { #experiment-reset-all { - padding: 8px; + font-size: 0.8em; + padding: 4px 8px; } .experiment-restart-button { padding: 8px; } - .restart-notice { - font-size: 1em; - } - #search { - padding: 8px 4px 8px 36px; + padding: 8px 36px; } } @@ -485,7 +475,7 @@ padding: 0 16px; } - #flagsTemplate > .flex-container:first-child { + #flagsTemplate > .flex-container:first-child:not('.version') { flex-direction: column; text-align: left; } @@ -498,17 +488,35 @@ width: 100%; } - #flagsTemplate > .flex-container #version { - padding-bottom: 16px; - text-align: left; - } - [dir='rtl'] #flagsTemplate > .flex-container #version { text-align: right; } #needs-restart { - padding: 8px 4px; + padding: 8px 12px; + } + + .experiment-restart-button { + padding: 8px 16px; + } + + .restart-notice { + font-size: 1em; + padding: 4px; + } + + /* Hide the overflow description text */ + .experiment p { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; + } + + .searching .experiment p, + .experiment .expand p { + overflow: visible; + white-space: normal; } }
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index 89d2e1a..1b1c3a9a 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -64,7 +64,7 @@ <h3 class="experiment-name" jscontent="name" jsvalues="title: is_default ? '' : 'Experiment enabled'">Name</h3> <p> - <span jsvalues=".innerHTML:description"></span> + <span jsvalues=".innerHTML:description"></span> – <span class="platforms" jscontent="supported_platforms.join(', ')"></span> </p> <a class="permalink" jsvalues="href: '#' + internal_name"
diff --git a/components/flags_ui/resources/flags.js b/components/flags_ui/resources/flags.js index 002c6acc..d571077 100644 --- a/components/flags_ui/resources/flags.js +++ b/components/flags_ui/resources/flags.js
@@ -59,6 +59,17 @@ }); } + var smallScreenCheck = window.matchMedia('(max-width: 480px)'); + // Toggling of experiment description overflow content on smaller screens. + elements = document.querySelectorAll('.experiment .flex:first-child'); + for (var i = 0; i < elements.length; ++i) { + elements[i].onclick = function(e) { + if (smallScreenCheck.matches) { + this.classList.toggle('expand'); + } + }; + } + $('experiment-reset-all').onclick = resetAllFlags; highlightReferencedFlag(); @@ -202,8 +213,8 @@ var FlagSearch = function() { FlagSearch.instance_ = this; - this.experiments_ = []; - this.unavailableExperiments_ = []; + this.experiments_ = Object.assign({}, FlagSearch.SearchContent); + this.unavailableExperiments_ = Object.assign({}, FlagSearch.SearchContent); this.searchBox_ = $('search'); this.noMatchMsg_ = document.querySelectorAll('.no-match'); @@ -216,6 +227,16 @@ FlagSearch.SEARCH_DEBOUNCE_TIME_MS = 150; /** + * Object definition for storing the elements which are searched on. + * @typedef {Object<string, HTMLElement[]>} + */ +FlagSearch.SearchContent = { + link: [], + title: [], + description: [] +}; + +/** * Get the singleton instance of FlagSearch. * @return {Object} Instance of FlagSearch. */ @@ -230,13 +251,22 @@ FlagSearch.prototype = { /** * Initialises the in page search. Adding searchbox listeners and - * collates the permalinks used for string matching. + * collates the text elements used for string matching. */ init: function() { - this.experiments_ = + this.experiments_.link = document.querySelectorAll('#tab-content-available .permalink'); - this.unavailableExperiments_ = + this.experiments_.title = + document.querySelectorAll('#tab-content-available .experiment-name'); + this.experiments_.description = + document.querySelectorAll('#tab-content-available p'); + + this.unavailableExperiments_.link = document.querySelectorAll('#tab-content-unavailable .permalink'); + this.unavailableExperiments_.title = + document.querySelectorAll('#tab-content-unavailable .experiment-name'); + this.unavailableExperiments_.description = + document.querySelectorAll('#tab-content-unavailable p'); if (!this.initialized) { this.searchBox_.addEventListener('keyup', this.debounceSearch.bind(this)); @@ -244,8 +274,14 @@ this.clearSearch.bind(this)); window.addEventListener('keyup', function(e) { - if (e.key == '/') { - this.searchBox_.focus(); + switch(e.key) { + case '/': + this.searchBox_.focus(); + break; + case 'Escape': + case 'Enter': + this.searchBox_.blur(); + break; } }.bind(this)); this.searchBox_.focus(); @@ -264,30 +300,30 @@ /** * Reset existing highlights on an element. * @param {HTMLElement} el The element to remove all highlighted mark up on. - * @param {string} flag The flag name to reset the element's textContent to. + * @param {string} text Text to reset the element's textContent to. */ - resetHighlights: function(el, flag) { + resetHighlights: function(el, text) { if (el.children) { - el.textContent = flag; + el.textContent = text; } }, /** - * Highlights the search term within the permalink flag name. + * Highlights the search term within a given element. * @param {string} searchTerm Search term user entered. - * @param {HTMLElement} el The permalink node where the search tern occurs. + * @param {HTMLElement} el The node containing the text to match against. * @return {boolean} Whether there was a match. */ - highlightMatches: function(searchTerm, el) { + highlightMatchInElement: function(searchTerm, el) { // Experiment container. var parentEl = el.parentNode.parentNode.parentNode; - var flag = el.textContent.toLowerCase(); - var match = flag.indexOf(searchTerm); + var text = el.textContent; + var match = text.toLowerCase().indexOf(searchTerm); parentEl.classList.toggle('hidden', match == -1); if (match == -1) { - this.resetHighlights(el, flag); + this.resetHighlights(el, text); return false; } @@ -297,56 +333,85 @@ if (match > 0) { var textNodePrefix = - document.createTextNode(flag.substring(0, match)); + document.createTextNode(text.substring(0, match)); el.appendChild(textNodePrefix); } var matchEl = document.createElement('mark'); - matchEl.textContent = flag.substr(match, searchTerm.length); + matchEl.textContent = text.substr(match, searchTerm.length); el.appendChild(matchEl); - var matchSuffix = flag.substring(match + searchTerm.length); + var matchSuffix = text.substring(match + searchTerm.length); if (matchSuffix) { var textNodeSuffix = document.createTextNode(matchSuffix); el.appendChild(textNodeSuffix); } } else { - this.resetHighlights(el, flag); + this.resetHighlights(el, text); } return true; }, /** - * Performs a search against the permalinks. + * Goes through all experiment text and highlights the relevant matches. + * Only the first instance of a match in each experiment text block is + * highlighted. This prevents the sea of yellow that happens using the global + * find in page search. + * @param {FlagSearch.SearchContent} searchContent Object containing the + * experiment text elements to search against. + * @param {string} searchTerm + * @return {number} The number of matches found. + */ + highlightAllMatches: function(searchContent, searchTerm) { + var matches = 0; + for (var i = 0, j = searchContent.link.length; i < j; i++) { + if (this.highlightMatchInElement(searchTerm, searchContent.title[i])) { + this.resetHighlights(searchContent.description[i], + searchContent.description[i].textContent); + this.resetHighlights(searchContent.link[i], + searchContent.link[i].textContent); + matches++; + continue; + } + if (this.highlightMatchInElement(searchTerm, + searchContent.description[i])) { + this.resetHighlights(searchContent.title[i], + searchContent.title[i].textContent); + this.resetHighlights(searchContent.link[i], + searchContent.link[i].textContent); + matches++; + continue; + } + // Match links, replace spaces with hyphens as flag names don't + // have spaces. + if (this.highlightMatchInElement(searchTerm.replace(/\s/, '-'), + searchContent.link[i])) { + this.resetHighlights(searchContent.title[i], + searchContent.title[i].textContent); + this.resetHighlights(searchContent.description[i], + searchContent.description[i].textContent); + matches++; + } + } + return matches; + }, + + /** + * Performs a search against the experiment title, description, permalink. * @param {Event} e */ doSearch: function(e) { - // Replace spaces with hyphens as flag names don't have spaces. var searchTerm = - this.searchBox_.value.trim().toLowerCase().replace(/\s/, '-'); - var matches = 0; - var unavailableMatches = 0; + this.searchBox_.value.trim().toLowerCase(); if (searchTerm || searchTerm == '') { - if (searchTerm) { - document.body.classList.add('searching'); - } + document.body.classList.toggle('searching', searchTerm); // Available experiments - for (var i = 0, j = this.experiments_.length; i < j; i++) { - if (this.highlightMatches(searchTerm, this.experiments_[i])) { - matches++; - } - } - this.noMatchMsg_[0].classList.toggle('hidden', matches); - + this.noMatchMsg_[0].classList.toggle('hidden', + this.highlightAllMatches(this.experiments_, searchTerm)); // Unavailable experiments - for (var i = 0, j = this.unavailableExperiments_.length; i < j; i++) { - if (this.highlightMatches(searchTerm, - this.unavailableExperiments_[i])) { - unavailableMatches++; - } - } - this.noMatchMsg_[1].classList.toggle('hidden', unavailableMatches); + this.noMatchMsg_[1].classList.toggle('hidden', + this.highlightAllMatches(this.unavailableExperiments_, searchTerm)); } this.searchIntervalId_ = null;
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index c1bc7f5..87bd855 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -337,6 +337,7 @@ "net/network_metrics_provider_unittest.cc", "persisted_logs_unittest.cc", "persistent_system_profile_unittest.cc", + "reporting_service_unittest.cc", "single_sample_metrics_factory_impl_unittest.cc", "stability_metrics_helper_unittest.cc", "stability_metrics_provider_unittest.cc",
diff --git a/components/metrics/metrics_log_uploader.h b/components/metrics/metrics_log_uploader.h index 3fe7f5e3..14d8816 100644 --- a/components/metrics/metrics_log_uploader.h +++ b/components/metrics/metrics_log_uploader.h
@@ -13,6 +13,8 @@ namespace metrics { +class ReportingInfo; + // MetricsLogUploader is an abstract base class for uploading UMA logs on behalf // of MetricsService. class MetricsLogUploader { @@ -34,7 +36,8 @@ // |log_hash| is expected to be the hex-encoded SHA1 hash of the log data // before compression. virtual void UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) = 0; + const std::string& log_hash, + const ReportingInfo& reporting_info) = 0; }; } // namespace metrics
diff --git a/components/metrics/net/net_metrics_log_uploader.cc b/components/metrics/net/net_metrics_log_uploader.cc index 3830b6291d..e1b4a692 100644 --- a/components/metrics/net/net_metrics_log_uploader.cc +++ b/components/metrics/net/net_metrics_log_uploader.cc
@@ -4,9 +4,11 @@ #include "components/metrics/net/net_metrics_log_uploader.h" +#include "base/base64.h" #include "base/metrics/histogram_macros.h" #include "components/data_use_measurement/core/data_use_user_data.h" #include "components/metrics/metrics_log_uploader.h" +#include "components/metrics/proto/reporting_info.pb.h" #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" @@ -93,6 +95,16 @@ } } +std::string SerializeReportingInfo( + const metrics::ReportingInfo& reporting_info) { + std::string result; + std::string bytes; + bool success = reporting_info.SerializeToString(&bytes); + DCHECK(success); + base::Base64Encode(bytes, &result); + return result; +} + } // namespace namespace metrics { @@ -113,13 +125,16 @@ } void NetMetricsLogUploader::UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) { - UploadLogToURL(compressed_log_data, log_hash, GURL(server_url_)); + const std::string& log_hash, + const ReportingInfo& reporting_info) { + UploadLogToURL(compressed_log_data, log_hash, reporting_info, + GURL(server_url_)); } void NetMetricsLogUploader::UploadLogToURL( const std::string& compressed_log_data, const std::string& log_hash, + const ReportingInfo& reporting_info, const GURL& url) { current_fetch_ = net::URLFetcher::Create(url, net::URLFetcher::POST, this, @@ -146,6 +161,10 @@ DCHECK(!log_hash.empty()); current_fetch_->AddExtraRequestHeader("X-Chrome-UMA-Log-SHA1: " + log_hash); + std::string reporting_info_string = SerializeReportingInfo(reporting_info); + current_fetch_->AddExtraRequestHeader("X-Chrome-UMA-ReportingInfo:" + + reporting_info_string); + // Drop cookies and auth data. current_fetch_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA |
diff --git a/components/metrics/net/net_metrics_log_uploader.h b/components/metrics/net/net_metrics_log_uploader.h index ad531b95..9c240498 100644 --- a/components/metrics/net/net_metrics_log_uploader.h +++ b/components/metrics/net/net_metrics_log_uploader.h
@@ -42,11 +42,14 @@ // MetricsLogUploader: // Uploads a log to the server_url specified in the constructor. void UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) override; + const std::string& log_hash, + const ReportingInfo& reporting_info) override; + private: // Uploads a log to a URL passed as a parameter. void UploadLogToURL(const std::string& compressed_log_data, const std::string& log_hash, + const ReportingInfo& reporting_info, const GURL& url); // net::URLFetcherDelegate:
diff --git a/components/metrics/net/net_metrics_log_uploader_unittest.cc b/components/metrics/net/net_metrics_log_uploader_unittest.cc index 70d94fd..a65ef53 100644 --- a/components/metrics/net/net_metrics_log_uploader_unittest.cc +++ b/components/metrics/net/net_metrics_log_uploader_unittest.cc
@@ -4,8 +4,10 @@ #include "components/metrics/net/net_metrics_log_uploader.h" +#include "base/base64.h" #include "base/bind.h" #include "base/macros.h" +#include "components/metrics/proto/reporting_info.pb.h" #include "net/url_request/test_url_fetcher_factory.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,17 +19,23 @@ } void CreateAndOnUploadCompleteReuseUploader() { + ReportingInfo reporting_info; + reporting_info.set_attempt_count(10); uploader_.reset(new NetMetricsLogUploader( NULL, "http://dummy_server", "dummy_mime", MetricsLogUploader::UMA, base::Bind(&NetMetricsLogUploaderTest::OnUploadCompleteReuseUploader, base::Unretained(this)))); - uploader_->UploadLog("initial_dummy_data", "initial_dummy_hash"); + uploader_->UploadLog("initial_dummy_data", "initial_dummy_hash", + reporting_info); } void OnUploadCompleteReuseUploader(int response_code, int error_code) { ++on_upload_complete_count_; - if (on_upload_complete_count_ == 1) - uploader_->UploadLog("dummy_data", "dummy_hash"); + if (on_upload_complete_count_ == 1) { + ReportingInfo reporting_info; + reporting_info.set_attempt_count(20); + uploader_->UploadLog("dummy_data", "dummy_hash", reporting_info); + } } int on_upload_complete_count() const { @@ -41,16 +49,33 @@ DISALLOW_COPY_AND_ASSIGN(NetMetricsLogUploaderTest); }; +void CheckReportingInfoHeader(net::TestURLFetcher* fetcher, + int expected_attempt_count) { + net::HttpRequestHeaders headers; + fetcher->GetExtraRequestHeaders(&headers); + std::string reporting_info_base64; + EXPECT_TRUE( + headers.GetHeader("X-Chrome-UMA-ReportingInfo", &reporting_info_base64)); + std::string reporting_info_string; + EXPECT_TRUE( + base::Base64Decode(reporting_info_base64, &reporting_info_string)); + ReportingInfo reporting_info; + EXPECT_TRUE(reporting_info.ParseFromString(reporting_info_string)); + EXPECT_EQ(reporting_info.attempt_count(), expected_attempt_count); +} + TEST_F(NetMetricsLogUploaderTest, OnUploadCompleteReuseUploader) { net::TestURLFetcherFactory factory; CreateAndOnUploadCompleteReuseUploader(); // Mimic the initial fetcher callback. net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + CheckReportingInfoHeader(fetcher, 10); fetcher->delegate()->OnURLFetchComplete(fetcher); // Mimic the second fetcher callback. fetcher = factory.GetFetcherByID(0); + CheckReportingInfoHeader(fetcher, 20); fetcher->delegate()->OnURLFetchComplete(fetcher); EXPECT_EQ(on_upload_complete_count(), 2);
diff --git a/components/metrics/reporting_service.cc b/components/metrics/reporting_service.cc index 04fa2750..bd6c76d5 100644 --- a/components/metrics/reporting_service.cc +++ b/components/metrics/reporting_service.cc
@@ -113,8 +113,10 @@ upload_scheduler_->UploadFinished(true); return; } - if (!log_store()->has_staged_log()) + if (!log_store()->has_staged_log()) { + reporting_info_.set_attempt_count(0); log_store()->StageNextLog(); + } // Proceed to stage the log for upload if log size satisfies cellular log // upload constrains. @@ -149,10 +151,12 @@ self_ptr_factory_.GetWeakPtr())); } + reporting_info_.set_attempt_count(reporting_info_.attempt_count() + 1); + const std::string hash = base::HexEncode(log_store()->staged_log_hash().data(), log_store()->staged_log_hash().size()); - log_uploader_->UploadLog(log_store()->staged_log(), hash); + log_uploader_->UploadLog(log_store()->staged_log(), hash, reporting_info_); } void ReportingService::OnLogUploadComplete(int response_code, int error_code) { @@ -161,6 +165,8 @@ DCHECK(log_upload_in_progress_); log_upload_in_progress_ = false; + reporting_info_.set_last_response_code(response_code); + // Log a histogram to track response success vs. failure rates. LogResponseOrErrorCode(response_code, error_code);
diff --git a/components/metrics/reporting_service.h b/components/metrics/reporting_service.h index b1a36f7bb..678e24de 100644 --- a/components/metrics/reporting_service.h +++ b/components/metrics/reporting_service.h
@@ -16,6 +16,7 @@ #include "build/build_config.h" #include "components/metrics/data_use_tracker.h" #include "components/metrics/metrics_log_uploader.h" +#include "components/metrics/proto/reporting_info.pb.h" class PrefService; class PrefRegistrySimple; @@ -131,6 +132,9 @@ // upload has been done yet. base::TimeTicks last_upload_finish_time_; + // Info on current reporting state to send along with reports. + ReportingInfo reporting_info_; + SEQUENCE_CHECKER(sequence_checker_); // Weak pointers factory used to post task on different threads. All weak
diff --git a/components/metrics/reporting_service_unittest.cc b/components/metrics/reporting_service_unittest.cc new file mode 100644 index 0000000..7c2699a --- /dev/null +++ b/components/metrics/reporting_service_unittest.cc
@@ -0,0 +1,142 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/reporting_service.h" + +#include <stdint.h> + +#include <deque> +#include <memory> +#include <string> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/sha1.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/metrics/log_store.h" +#include "components/metrics/test_metrics_service_client.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/zlib/google/compression_utils.h" + +namespace metrics { + +namespace { + +const char kTestUploadUrl[] = "test_url"; +const char kTestMimeType[] = "test_mime_type"; + +class TestLogStore : public LogStore { + public: + TestLogStore() {} + ~TestLogStore() {} + + void AddLog(const std::string& log) { logs_.push_back(log); } + + // LogStore: + bool has_unsent_logs() const override { return !logs_.empty(); } + bool has_staged_log() const override { return !staged_log_hash_.empty(); } + const std::string& staged_log() const override { return logs_.front(); } + const std::string& staged_log_hash() const override { + return staged_log_hash_; + } + void StageNextLog() override { + if (has_unsent_logs()) + staged_log_hash_ = base::SHA1HashString(logs_.front()); + } + void DiscardStagedLog() override { + if (!has_staged_log()) + return; + logs_.pop_front(); + staged_log_hash_.clear(); + } + void PersistUnsentLogs() const override {} + void LoadPersistedUnsentLogs() override {} + + private: + std::string staged_log_hash_; + std::deque<std::string> logs_; +}; + +class TestReportingService : public ReportingService { + public: + TestReportingService(MetricsServiceClient* client, PrefService* local_state) + : ReportingService(client, local_state, 100) { + Initialize(); + } + ~TestReportingService() override {} + + void AddLog(const std::string& log) { log_store_.AddLog(log); } + + private: + // ReportingService: + LogStore* log_store() override { return &log_store_; } + std::string GetUploadUrl() const override { return kTestUploadUrl; } + base::StringPiece upload_mime_type() const override { return kTestMimeType; } + MetricsLogUploader::MetricServiceType service_type() const override { + return MetricsLogUploader::MetricServiceType::UMA; + } + + TestLogStore log_store_; + + DISALLOW_COPY_AND_ASSIGN(TestReportingService); +}; + +class ReportingServiceTest : public testing::Test { + public: + ReportingServiceTest() + : task_runner_(new base::TestSimpleTaskRunner), + task_runner_handle_(task_runner_) { + ReportingService::RegisterPrefs(testing_local_state_.registry()); + } + + ~ReportingServiceTest() override {} + + PrefService* GetLocalState() { return &testing_local_state_; } + + protected: + scoped_refptr<base::TestSimpleTaskRunner> task_runner_; + base::ThreadTaskRunnerHandle task_runner_handle_; + TestMetricsServiceClient client_; + + private: + TestingPrefServiceSimple testing_local_state_; + + DISALLOW_COPY_AND_ASSIGN(ReportingServiceTest); +}; + +} // namespace + +TEST_F(ReportingServiceTest, BasicTest) { + TestReportingService service(&client_, GetLocalState()); + service.AddLog("log1"); + service.AddLog("log2"); + + service.EnableReporting(); + task_runner_->RunPendingTasks(); + client_.uploader()->is_uploading(); + EXPECT_TRUE(client_.uploader()->is_uploading()); + EXPECT_EQ(1, client_.uploader()->reporting_info().attempt_count()); + EXPECT_FALSE(client_.uploader()->reporting_info().has_last_response_code()); + + client_.uploader()->CompleteUpload(404); + task_runner_->RunPendingTasks(); + EXPECT_TRUE(client_.uploader()->is_uploading()); + EXPECT_EQ(2, client_.uploader()->reporting_info().attempt_count()); + EXPECT_EQ(404, client_.uploader()->reporting_info().last_response_code()); + + client_.uploader()->CompleteUpload(200); + task_runner_->RunPendingTasks(); + EXPECT_TRUE(client_.uploader()->is_uploading()); + EXPECT_EQ(1, client_.uploader()->reporting_info().attempt_count()); + EXPECT_EQ(200, client_.uploader()->reporting_info().last_response_code()); + + client_.uploader()->CompleteUpload(200); + EXPECT_EQ(0U, task_runner_->NumPendingTasks()); + EXPECT_FALSE(client_.uploader()->is_uploading()); +} + +} // namespace metrics
diff --git a/components/metrics/test_metrics_log_uploader.cc b/components/metrics/test_metrics_log_uploader.cc index 0eff63f..d1a02af 100644 --- a/components/metrics/test_metrics_log_uploader.cc +++ b/components/metrics/test_metrics_log_uploader.cc
@@ -16,13 +16,16 @@ void TestMetricsLogUploader::CompleteUpload(int response_code) { DCHECK(is_uploading_); is_uploading_ = false; + last_reporting_info_.Clear(); on_upload_complete_.Run(response_code, 0); } void TestMetricsLogUploader::UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) { + const std::string& log_hash, + const ReportingInfo& reporting_info) { DCHECK(!is_uploading_); is_uploading_ = true; + last_reporting_info_ = reporting_info; } } // namespace metrics
diff --git a/components/metrics/test_metrics_log_uploader.h b/components/metrics/test_metrics_log_uploader.h index 5730ee5..a290c8e7 100644 --- a/components/metrics/test_metrics_log_uploader.h +++ b/components/metrics/test_metrics_log_uploader.h
@@ -6,6 +6,7 @@ #define COMPONENTS_METRICS_TEST_METRICS_LOG_UPLOADER_H_ #include "components/metrics/metrics_log_uploader.h" +#include "components/metrics/proto/reporting_info.pb.h" namespace metrics { @@ -21,12 +22,16 @@ // Check if UploadLog has been called. bool is_uploading() const { return is_uploading_; } + const ReportingInfo& reporting_info() const { return last_reporting_info_; } + private: // MetricsLogUploader: void UploadLog(const std::string& compressed_log_data, - const std::string& log_hash) override; + const std::string& log_hash, + const ReportingInfo& reporting_info) override; const MetricsLogUploader::UploadCallback on_upload_complete_; + ReportingInfo last_reporting_info_; bool is_uploading_; DISALLOW_COPY_AND_ASSIGN(TestMetricsLogUploader);
diff --git a/components/nacl/features.gni b/components/nacl/features.gni index de172b4d..4e48271 100644 --- a/components/nacl/features.gni +++ b/components/nacl/features.gni
@@ -8,10 +8,14 @@ # Enables Native Client support. # Temporarily disable nacl on arm64 linux to get rid of compilation errors. # TODO: When mipsel-nacl-clang is available, drop the exclusion. - enable_nacl = !is_ios && !is_android && !is_fuchsia && !is_chromecast && - current_cpu != "mipsel" && current_cpu != "mips64el" && - !(is_linux && target_cpu == "arm64") + enable_nacl = + !is_ios && !is_android && !is_fuchsia && !is_chromecast && + current_cpu != "mipsel" && current_cpu != "mips64el" && + !(is_linux && target_cpu == "arm64") && !(is_win && host_os != "win") # Non-SFI is not yet supported on mipsel enable_nacl_nonsfi = current_cpu != "mipsel" && current_cpu != "mips64el" } + +assert(!(is_win && host_os != "win") || !enable_nacl, + "NaCl doesn't work in win cross builds, crbug.com/774186")
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc index 68f3ffc..32f47bf9 100644 --- a/components/omnibox/browser/shortcuts_provider.cc +++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -198,6 +198,7 @@ const base::string16& find_text, const WordMap& find_words, const base::string16& text, + const bool text_is_search_query, const ACMatchClassifications& original_class) { DCHECK(!find_text.empty()); DCHECK(!find_words.empty()); @@ -212,31 +213,35 @@ // First check whether |text| begins with |find_text| and mark that whole // section as a match if so. base::string16 text_lowercase(base::i18n::ToLower(text)); + const ACMatchClassification::Style& class_of_find_text = + text_is_search_query ? ACMatchClassification::NONE + : ACMatchClassification::MATCH; + const ACMatchClassification::Style& class_of_additional_text = + text_is_search_query ? ACMatchClassification::MATCH + : ACMatchClassification::NONE; ACMatchClassifications match_class; size_t last_position = 0; if (base::StartsWith(text_lowercase, find_text, base::CompareCase::SENSITIVE)) { - match_class.push_back( - ACMatchClassification(0, ACMatchClassification::MATCH)); + match_class.push_back(ACMatchClassification(0, class_of_find_text)); last_position = find_text.length(); // If |text_lowercase| is actually equal to |find_text|, we don't need to // (and in fact shouldn't) put a trailing NONE classification after the end // of the string. if (last_position < text_lowercase.length()) { match_class.push_back( - ACMatchClassification(last_position, ACMatchClassification::NONE)); + ACMatchClassification(last_position, class_of_additional_text)); } } else { // |match_class| should start at position 0. If the first matching word is // found at position 0, this will be popped from the vector further down. - match_class.push_back( - ACMatchClassification(0, ACMatchClassification::NONE)); + match_class.push_back(ACMatchClassification(0, class_of_additional_text)); } // Now, starting with |last_position|, check each character in // |text_lowercase| to see if we have words starting with that character in // |find_words|. If so, check each of them to see if they match the portion - // of |text_lowercase| beginning with |last_position|. Accept the first + // of |text_lowercase| beginning with |last_position|. Accept the first // matching word found (which should be the longest possible match at this // location, given the construction of |find_words|) and add a MATCH region to // |match_class|, moving |last_position| to be after the matching word. If we @@ -255,10 +260,10 @@ match_class.pop_back(); AutocompleteMatch::AddLastClassificationIfNecessary( - &match_class, last_position, ACMatchClassification::MATCH); + &match_class, last_position, class_of_find_text); if (word_end < text_lowercase.length()) { match_class.push_back( - ACMatchClassification(word_end, ACMatchClassification::NONE)); + ACMatchClassification(word_end, class_of_additional_text)); } last_position = word_end; break; @@ -393,7 +398,8 @@ // otherwise prevent inline autocompletion. This allows, for example, the // input of "foo.c" to autocomplete to "foo.com" for a fill_into_edit of // "http://foo.com". - if (AutocompleteMatch::IsSearchType(match.type)) { + const bool is_search_type = AutocompleteMatch::IsSearchType(match.type); + if (is_search_type) { if (match.fill_into_edit.size() >= input.text().size() && std::equal(match.fill_into_edit.begin(), match.fill_into_edit.begin() + input.text().size(), @@ -423,10 +429,12 @@ // Try to mark pieces of the contents and description as matches if they // appear in |input.text()|. if (!terms_map.empty()) { - match.contents_class = ClassifyAllMatchesInString( - term_string, terms_map, match.contents, match.contents_class); + match.contents_class = + ClassifyAllMatchesInString(term_string, terms_map, match.contents, + is_search_type, match.contents_class); match.description_class = ClassifyAllMatchesInString( - term_string, terms_map, match.description, match.description_class); + term_string, terms_map, match.description, + /*text_is_search_query=*/false, match.description_class); } return match; }
diff --git a/components/omnibox/browser/shortcuts_provider.h b/components/omnibox/browser/shortcuts_provider.h index feee948..c6646f94 100644 --- a/components/omnibox/browser/shortcuts_provider.h +++ b/components/omnibox/browser/shortcuts_provider.h
@@ -47,21 +47,34 @@ // equal_range(). static WordMap CreateWordMapForString(const base::string16& text); - // Given |text| and a corresponding base set of classifications - // |original_class|, adds ACMatchClassification::MATCH markers for all - // instances of the words from |find_words| within |text| and returns the - // resulting classifications. (|find_text| is provided as the original string - // used to create |find_words|. This is supplied because it's common for this - // to be a prefix of |text|, so we can quickly check for that and mark that - // entire substring as a match before proceeding with the more generic - // algorithm.) + // Finds all instances of the words from |find_words| within |text|, adds + // classifications to |original_class| according to the logic described below, + // and returns the result. // - // For example, given the |text| - // "Sports and News at sports.somesite.com - visit us!" and |original_class| - // {{0, NONE}, {18, URL}, {37, NONE}} (marking "sports.somesite.com" as a - // URL), calling with |find_text| set to "sp ew" would return - // {{0, MATCH}, {2, NONE}, {12, MATCH}, {14, NONE}, {18, URL|MATCH}, - // {20, URL}, {37, NONE}}. + // - if |text_is_search_query| is false, the function adds + // ACMatchClassification::MATCH markers for all such instances. + // + // For example, given the |text| + // "Sports and News at sports.somesite.com - visit us!" and |original_class| + // {{0, NONE}, {18, URL}, {37, NONE}} (marking "sports.somesite.com" as a + // URL), calling with |find_text| set to "sp ew" would return + // {{0, MATCH}, {2, NONE}, {12, MATCH}, {14, NONE}, {18, URL|MATCH}, + // {20, URL}, {37, NONE}}. + // + // + // - if |text_is_search_query| is true, applies the same logic, but uses + // NONE for the matching text and MATCH for the non-matching text. This is + // done to mimic the behavior of SearchProvider which decorates matches + // according to the approach used by Google Suggest. + // + // For example, given that |text| corresponds to a search query "panama + // canal" and |original class| is {{0, NONE}}, calling with |find_text| set + // to "canal" would return {{0,MATCH}, {7, NONE}}. + // + // |find_text| is provided as the original string used to create + // |find_words|. This is supplied because it's common for this to be a prefix + // of |text|, so we can quickly check for that and mark that entire substring + // as a match before proceeding with the more generic algorithm. // // |find_words| should be as constructed by CreateWordMapForString(find_text). // @@ -71,6 +84,7 @@ const base::string16& find_text, const WordMap& find_words, const base::string16& text, + const bool text_is_search_query, const ACMatchClassifications& original_class); // ShortcutsBackendObserver:
diff --git a/components/omnibox/browser/shortcuts_provider_unittest.cc b/components/omnibox/browser/shortcuts_provider_unittest.cc index 726c219..a910561d 100644 --- a/components/omnibox/browser/shortcuts_provider_unittest.cc +++ b/components/omnibox/browser/shortcuts_provider_unittest.cc
@@ -223,26 +223,30 @@ // convenient. class ClassifyTest { public: - ClassifyTest(const base::string16& text, ACMatchClassifications matches); + ClassifyTest(const base::string16& text, + const bool text_is_query, + ACMatchClassifications matches); ~ClassifyTest(); ACMatchClassifications RunTest(const base::string16& find_text); private: const base::string16 text_; + const bool text_is_query_; const ACMatchClassifications matches_; }; ClassifyTest::ClassifyTest(const base::string16& text, + const bool text_is_query, ACMatchClassifications matches) - : text_(text), matches_(matches) {} + : text_(text), text_is_query_(text_is_query), matches_(matches) {} ClassifyTest::~ClassifyTest() {} ACMatchClassifications ClassifyTest::RunTest(const base::string16& find_text) { return ShortcutsProvider::ClassifyAllMatchesInString( find_text, ShortcutsProvider::CreateWordMapForString(find_text), text_, - matches_); + text_is_query_, matches_); } // ShortcutsProviderTest ------------------------------------------------------ @@ -525,7 +529,7 @@ ACMatchClassifications matches = AutocompleteMatch::ClassificationsFromString("0,0"); ClassifyTest classify_test(ASCIIToUTF16("A man, a plan, a canal Panama"), - matches); + /*text_is_query=*/false, matches); ACMatchClassifications spans_a = classify_test.RunTest(ASCIIToUTF16("man")); // ACMatch spans should be: '--MMM------------------------' @@ -545,7 +549,7 @@ ClassifyTest classify_test2( ASCIIToUTF16("Yahoo! Sports - Sports News, " "Scores, Rumors, Fantasy Games, and more"), - matches); + /*text_is_query=*/false, matches); ACMatchClassifications spans_d = classify_test2.RunTest(ASCIIToUTF16("ne")); // ACMatch spans should match first two letters of the "news". @@ -560,7 +564,8 @@ AutocompleteMatch::ClassificationsToString(spans_e)); matches = AutocompleteMatch::ClassificationsFromString("0,1"); - ClassifyTest classify_test3(ASCIIToUTF16("livescore.goal.com"), matches); + ClassifyTest classify_test3(ASCIIToUTF16("livescore.goal.com"), + /*text_is_query=*/false, matches); ACMatchClassifications spans_f = classify_test3.RunTest(ASCIIToUTF16("go")); // ACMatch spans should match first two letters of the "goal". @@ -569,7 +574,7 @@ matches = AutocompleteMatch::ClassificationsFromString("0,0,13,1"); ClassifyTest classify_test4(ASCIIToUTF16("Email login: mail.somecorp.com"), - matches); + /*text_is_query=*/false, matches); ACMatchClassifications spans_g = classify_test4.RunTest(ASCIIToUTF16("ail")); EXPECT_EQ("0,0,2,2,5,0,13,1,14,3,17,1", @@ -589,14 +594,15 @@ // Some web sites do not have a description. If the string being searched is // empty, the classifications must also be empty: http://crbug.com/148647 // Extra parens in the next line hack around C++03's "most vexing parse". - class ClassifyTest classify_test5((base::string16()), + class ClassifyTest classify_test5((base::string16()), /*text_is_query=*/false, ACMatchClassifications()); ACMatchClassifications spans_j = classify_test5.RunTest(ASCIIToUTF16("man")); ASSERT_EQ(0U, spans_j.size()); // Matches which end at beginning of classification merge properly. matches = AutocompleteMatch::ClassificationsFromString("0,4,9,0"); - ClassifyTest classify_test6(ASCIIToUTF16("html password example"), matches); + ClassifyTest classify_test6(ASCIIToUTF16("html password example"), + /*text_is_query=*/false, matches); // Extra space in the next string avoids having the string be a prefix of the // text above, which would allow for two different valid classification sets, @@ -612,12 +618,27 @@ // Multiple matches with both beginning and end at beginning of // classifications merge properly. matches = AutocompleteMatch::ClassificationsFromString("0,1,11,0"); - ClassifyTest classify_test7(ASCIIToUTF16("http://a.co is great"), matches); + ClassifyTest classify_test7(ASCIIToUTF16("http://a.co is great"), + /*text_is_query=*/false, matches); ACMatchClassifications spans_l = classify_test7.RunTest(ASCIIToUTF16("ht co")); EXPECT_EQ("0,3,2,1,9,3,11,0", AutocompleteMatch::ClassificationsToString(spans_l)); + + // Queries should be classify the same way as google seach autocomplete + // suggestions. + matches = AutocompleteMatch::ClassificationsFromString("0,0"); + ClassifyTest classify_test8(ASCIIToUTF16("panama canal"), + /*text_is_query=*/true, matches); + + ACMatchClassifications spans_m = classify_test8.RunTest(ASCIIToUTF16("pan")); + // ACMatch spans should be: "---MMMMMMMMM"; + EXPECT_EQ("0,0,3,2", AutocompleteMatch::ClassificationsToString(spans_m)); + ACMatchClassifications spans_n = + classify_test8.RunTest(ASCIIToUTF16("canal")); + // ACMatch spans should be: "MMMMMM-----"; + EXPECT_EQ("0,2,7,0", AutocompleteMatch::ClassificationsToString(spans_n)); } TEST_F(ShortcutsProviderTest, CalculateScore) {
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index 1af436c..f5b4de86 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -322,11 +322,6 @@ </message> </if> - <!-- VR browser --> - <message name="IDS_PAGE_INFO_VR_BROWSER_UNSUPPORTED_MODE" desc="This text is displayed as a large toast to inform the user that they cannot currently browse in VR and they will soon exit VR mode."> - This page contains features not yet supported in VR. Exiting... - </message> - <!-- Password Protection --> <if expr="not is_android"> <message name="IDS_PAGE_INFO_CHANGE_PASSWORD_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if user has reuse their google password on current website.">
diff --git a/components/payments/content/utility/fingerprint_parser.cc b/components/payments/content/utility/fingerprint_parser.cc index 98cb171..680a13a 100644 --- a/components/payments/content/utility/fingerprint_parser.cc +++ b/components/payments/content/utility/fingerprint_parser.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/numerics/safe_conversions.h" +#include "base/strings/string_util.h" namespace payments { namespace { @@ -31,6 +32,11 @@ return output; } + if (!base::IsStringASCII(input)) { + LOG(ERROR) << "Fingerprint \"" << input << "\" should be ASCII."; + return output; + } + for (size_t i = 0; i < input.size(); i += 3) { if (i < input.size() - 2 && input[i + 2] != ':') { LOG(ERROR) << "Bytes in fingerprint \"" << input
diff --git a/components/payments/content/utility/fingerprint_parser_unittest.cc b/components/payments/content/utility/fingerprint_parser_unittest.cc index 2c79635..d7e6409c 100644 --- a/components/payments/content/utility/fingerprint_parser_unittest.cc +++ b/components/payments/content/utility/fingerprint_parser_unittest.cc
@@ -74,6 +74,14 @@ .empty()); } +TEST(FingerprintParserTest, MustBeASCII) { + EXPECT_TRUE(FingerprintStringToByteArray("β:01:02:03:04:05:06:07:08:09:" + "A0:A1:A2:A3:A4:A5:A6:A7:A8:A9:" + "B0:B1:B2:B3:B4:B5:B6:B7:B8:B9:" + "C0:C1") + .empty()); +} + TEST(FingerprintParserTest, CorrectParsing) { std::vector<uint8_t> actual_output = FingerprintStringToByteArray( "00:01:02:03:04:05:06:07:08:09:A0:"
diff --git a/components/payments/content/utility/payment_manifest_parser.cc b/components/payments/content/utility/payment_manifest_parser.cc index b616a25e..64a93d8 100644 --- a/components/payments/content/utility/payment_manifest_parser.cc +++ b/components/payments/content/utility/payment_manifest_parser.cc
@@ -27,6 +27,7 @@ const size_t kMaximumNumberOfEntries = 100U; const char* const kDefaultApplications = "default_applications"; const char* const kSupportedOrigins = "supported_origins"; +const char* const kHttpsPrefix = "https://"; // Parses the "default_applications": ["https://some/url"] from |dict| into // |web_app_manifest_urls|. Returns 'false' for invalid data. @@ -50,9 +51,12 @@ for (size_t i = 0; i < apps_number; ++i) { std::string item; - if (!list->GetString(i, &item) || item.empty()) { + if (!list->GetString(i, &item) || item.empty() || + !base::IsStringUTF8(item) || + !base::StartsWith(item, kHttpsPrefix, base::CompareCase::SENSITIVE)) { LOG(ERROR) << "Each entry in \"" << kDefaultApplications - << "\" must be a string."; + << "\" must be UTF8 string that starts with \"" << kHttpsPrefix + << "\"."; web_app_manifest_urls->clear(); return false; } @@ -89,7 +93,7 @@ if (item != "*") { LOG(ERROR) << "\"" << item << "\" is not a valid value for \"" << kSupportedOrigins - << "\". Must be either \"*\" or a list of origins."; + << "\". Must be either \"*\" or a list of RFC6454 origins."; return false; } @@ -115,9 +119,12 @@ for (size_t i = 0; i < supported_origins_number; ++i) { std::string item; - if (!list->GetString(i, &item) || item.empty()) { + if (!list->GetString(i, &item) || item.empty() || + !base::IsStringUTF8(item) || + !base::StartsWith(item, kHttpsPrefix, base::CompareCase::SENSITIVE)) { LOG(ERROR) << "Each entry in \"" << kSupportedOrigins - << "\" must be a string."; + << "\" must be UTF8 string that starts with \"" << kHttpsPrefix + << "\"."; supported_origins->clear(); return false; }
diff --git a/components/payments/content/utility/payment_manifest_parser_unittest.cc b/components/payments/content/utility/payment_manifest_parser_unittest.cc index bd711d10..c8d0132 100644 --- a/components/payments/content/utility/payment_manifest_parser_unittest.cc +++ b/components/payments/content/utility/payment_manifest_parser_unittest.cc
@@ -22,8 +22,9 @@ input, &actual_web_app_urls, &actual_supported_origins, &actual_all_origins_supported); - EXPECT_TRUE(actual_web_app_urls.empty()); - EXPECT_TRUE(actual_supported_origins.empty()); + EXPECT_TRUE(actual_web_app_urls.empty()) << actual_web_app_urls.front(); + EXPECT_TRUE(actual_supported_origins.empty()) + << actual_supported_origins.front(); EXPECT_FALSE(actual_all_origins_supported); } @@ -88,6 +89,11 @@ "{\"default_applications\": [\"https://bobpay.com/app\0json\"]}"); } +TEST(PaymentManifestParserTest, DefaultApplicationsShouldBeUTF8) { + ExpectUnableToParsePaymentMethodManifest( + "{\"default_applications\":[\"https://b\x0f\x7f\xf0\xff!\"]}"); +} + TEST(PaymentManifestParserTest, DefaultApplicationKeyShouldBeLowercase) { ExpectUnableToParsePaymentMethodManifest( "{\"Default_Applications\": [\"https://bobpay.com/app.json\"]}"); @@ -132,6 +138,11 @@ "{\"supported_origins\": [\"https://bob\0pay.com\"]}"); } +TEST(PaymentManifestParserTest, SupportedOriginsShouldBeUTF8) { + ExpectUnableToParsePaymentMethodManifest( + "{\"supported_origins\":[\"https://b\x0f\x7f\xf0\xff!\"]}"); +} + TEST(PaymentManifestParserTest, SupportedOriginsShouldBeHttps) { ExpectUnableToParsePaymentMethodManifest( "{\"supported_origins\": [\"http://bobpay.com\"]}");
diff --git a/components/safe_json/BUILD.gn b/components/safe_json/BUILD.gn deleted file mode 100644 index 37befe20..0000000 --- a/components/safe_json/BUILD.gn +++ /dev/null
@@ -1,71 +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. - -if (is_android) { - import("//build/config/android/rules.gni") -} - -static_library("safe_json") { - sources = [ - "json_sanitizer.cc", - "json_sanitizer.h", - "json_sanitizer_android.cc", - "safe_json_parser.cc", - "safe_json_parser.h", - "safe_json_parser_android.cc", - "safe_json_parser_android.h", - "safe_json_parser_impl.cc", - "safe_json_parser_impl.h", - ] - - deps = [ - "//base", - "//components/safe_json/public/interfaces", - "//components/strings", - "//content/public/browser", - "//content/public/common", - "//ui/base", - ] - - if (is_android) { - sources -= [ - "json_sanitizer.cc", - "safe_json_parser_impl.cc", - "safe_json_parser_impl.h", - ] - deps += [ "android:safe_json_jni_headers" ] - deps -= [ - "//components/safe_json/public/interfaces", - "//content/public/browser", - ] - } -} - -source_set("unit_tests") { - testonly = true - sources = [ - "json_sanitizer_unittest.cc", - "testing_json_parser_unittest.cc", - ] - - deps = [ - ":safe_json", - ":test_support", - "//base", - "//testing/gtest", - ] -} - -static_library("test_support") { - testonly = true - sources = [ - "testing_json_parser.cc", - "testing_json_parser.h", - ] - - deps = [ - ":safe_json", - "//base", - ] -}
diff --git a/components/safe_json/DEPS b/components/safe_json/DEPS deleted file mode 100644 index 64027775..0000000 --- a/components/safe_json/DEPS +++ /dev/null
@@ -1,10 +0,0 @@ -include_rules = [ - "+components/grit/components_resources.h", - "+components/strings/grit/components_strings.h", - "+content/public/browser", - "+content/public/common", - "+content/public/utility", - "+jni", - "+mojo/public/cpp", - "+ui/base", -]
diff --git a/components/safe_json/OWNERS b/components/safe_json/OWNERS deleted file mode 100644 index c8075494..0000000 --- a/components/safe_json/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -bauerb@chromium.org -rsesek@chromium.org - -# TEAM: security-dev@chromium.org
diff --git a/components/safe_json/android/BUILD.gn b/components/safe_json/android/BUILD.gn deleted file mode 100644 index a9f89fe..0000000 --- a/components/safe_json/android/BUILD.gn +++ /dev/null
@@ -1,20 +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("//build/config/android/rules.gni") - -_jni_sources = - [ "java/src/org/chromium/components/safejson/JsonSanitizer.java" ] - -generate_jni("safe_json_jni_headers") { - sources = _jni_sources - jni_package = "safe_json" -} - -android_library("safe_json_java") { - deps = [ - "//base:base_java", - ] - java_files = [] + _jni_sources -}
diff --git a/components/safe_json/public/interfaces/BUILD.gn b/components/safe_json/public/interfaces/BUILD.gn deleted file mode 100644 index bd150aa..0000000 --- a/components/safe_json/public/interfaces/BUILD.gn +++ /dev/null
@@ -1,15 +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("//mojo/public/tools/bindings/mojom.gni") - -mojom("interfaces") { - sources = [ - "safe_json.mojom", - ] - - public_deps = [ - "//mojo/common:common_custom_types", - ] -}
diff --git a/components/safe_json/public/interfaces/OWNERS b/components/safe_json/public/interfaces/OWNERS deleted file mode 100644 index 08850f4..0000000 --- a/components/safe_json/public/interfaces/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/components/safe_json/safe_json_parser.cc b/components/safe_json/safe_json_parser.cc deleted file mode 100644 index 7d2bbfd..0000000 --- a/components/safe_json/safe_json_parser.cc +++ /dev/null
@@ -1,51 +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 "components/safe_json/safe_json_parser.h" - -#include "build/build_config.h" - -#if defined(OS_ANDROID) -#include "components/safe_json/safe_json_parser_android.h" -#else -#include "components/safe_json/safe_json_parser_impl.h" -#endif - -namespace safe_json { - -namespace { - -SafeJsonParser::Factory g_factory = nullptr; - -SafeJsonParser* Create(const std::string& unsafe_json, - const SafeJsonParser::SuccessCallback& success_callback, - const SafeJsonParser::ErrorCallback& error_callback) { - if (g_factory) - return g_factory(unsafe_json, success_callback, error_callback); - -#if defined(OS_ANDROID) - return new SafeJsonParserAndroid(unsafe_json, success_callback, - error_callback); -#else - return new SafeJsonParserImpl(unsafe_json, success_callback, error_callback); -#endif -} - -} // namespace - -// static -void SafeJsonParser::SetFactoryForTesting(Factory factory) { - g_factory = factory; -} - -// static -void SafeJsonParser::Parse(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { - SafeJsonParser* parser = - Create(unsafe_json, success_callback, error_callback); - parser->Start(); -} - -} // namespace safe_json
diff --git a/components/safe_json/utility/BUILD.gn b/components/safe_json/utility/BUILD.gn deleted file mode 100644 index bc7024d6..0000000 --- a/components/safe_json/utility/BUILD.gn +++ /dev/null
@@ -1,15 +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. - -static_library("utility") { - sources = [ - "safe_json_parser_mojo_impl.cc", - "safe_json_parser_mojo_impl.h", - ] - - deps = [ - "//base", - "//components/safe_json/public/interfaces", - ] -}
diff --git a/components/safe_json/utility/safe_json_parser_mojo_impl.cc b/components/safe_json/utility/safe_json_parser_mojo_impl.cc deleted file mode 100644 index 559955e..0000000 --- a/components/safe_json/utility/safe_json_parser_mojo_impl.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/safe_json/utility/safe_json_parser_mojo_impl.h" - -#include <memory> -#include <utility> - -#include "base/json/json_reader.h" -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "mojo/public/cpp/bindings/strong_binding.h" - -namespace safe_json { - -SafeJsonParserMojoImpl::SafeJsonParserMojoImpl() = default; - -SafeJsonParserMojoImpl::~SafeJsonParserMojoImpl() = default; - -// static -void SafeJsonParserMojoImpl::Create( - mojom::SafeJsonParserRequest request) { - mojo::MakeStrongBinding(base::MakeUnique<SafeJsonParserMojoImpl>(), - std::move(request)); -} - -void SafeJsonParserMojoImpl::Parse(const std::string& json, - ParseCallback callback) { - int error_code; - std::string error; - std::unique_ptr<base::Value> value = base::JSONReader::ReadAndReturnError( - json, base::JSON_PARSE_RFC, &error_code, &error); - if (value) { - std::move(callback).Run(std::move(value), base::nullopt); - } else { - std::move(callback).Run(nullptr, base::make_optional(std::move(error))); - } -} - -} // namespace safe_json
diff --git a/components/safe_json/utility/safe_json_parser_mojo_impl.h b/components/safe_json/utility/safe_json_parser_mojo_impl.h deleted file mode 100644 index ab4194d..0000000 --- a/components/safe_json/utility/safe_json_parser_mojo_impl.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_MOJO_IMPL_H_ -#define COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_MOJO_IMPL_H_ - -#include <string> - -#include "base/macros.h" -#include "components/safe_json/public/interfaces/safe_json.mojom.h" - -namespace safe_json { - -class SafeJsonParserMojoImpl : public mojom::SafeJsonParser { - public: - SafeJsonParserMojoImpl(); - ~SafeJsonParserMojoImpl() override; - - static void Create(mojom::SafeJsonParserRequest request); - - private: - // mojom::SafeJsonParser implementation. - void Parse(const std::string& json, ParseCallback callback) override; - - DISALLOW_COPY_AND_ASSIGN(SafeJsonParserMojoImpl); -}; - -} // namespace safe_json - -#endif // COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_MOJO_IMPL_H_
diff --git a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc index 49e98b75..9d1290b 100644 --- a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc +++ b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc
@@ -10,7 +10,8 @@ #include "content/public/browser/browser_thread.h" #include "url/gurl.h" -FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager() {} +FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager() + : weak_factory_(this) {} void FakeSafeBrowsingDatabaseManager::AddBlacklistedUrl( const GURL& url, @@ -61,7 +62,7 @@ content::BrowserThread::IO, FROM_HERE, base::Bind(&FakeSafeBrowsingDatabaseManager:: OnCheckUrlForSubresourceFilterComplete, - base::Unretained(this), base::Unretained(client), url)); + weak_factory_.GetWeakPtr(), base::Unretained(client), url)); return false; }
diff --git a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h index 5c7e52c..764fbdf 100644 --- a/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h +++ b/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h
@@ -9,6 +9,7 @@ #include <set> #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "components/safe_browsing/db/test_database_manager.h" #include "content/public/common/resource_type.h" @@ -64,6 +65,8 @@ bool simulate_timeout_ = false; bool synchronous_failure_ = false; + base::WeakPtrFactory<FakeSafeBrowsingDatabaseManager> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager); };
diff --git a/components/test/BUILD.gn b/components/test/BUILD.gn index f6402ed..57faf38 100644 --- a/components/test/BUILD.gn +++ b/components/test/BUILD.gn
@@ -29,7 +29,6 @@ deps += [ "//components/invalidation/impl", "//components/policy/core/browser", - "//components/safe_json", "//ui/gl:test_support", ]
diff --git a/content/app/content_service_manager_main_delegate.cc b/content/app/content_service_manager_main_delegate.cc index 104f2bd..62dceb5 100644 --- a/content/app/content_service_manager_main_delegate.cc +++ b/content/app/content_service_manager_main_delegate.cc
@@ -109,14 +109,6 @@ command_line->AppendArgNative(arg); } -bool ContentServiceManagerMainDelegate:: - ShouldTerminateServiceManagerOnInstanceQuit( - const service_manager::Identity& identity, - int* exit_code) { - return content_main_params_.delegate - ->ShouldTerminateServiceManagerOnInstanceQuit(identity, exit_code); -} - void ContentServiceManagerMainDelegate::OnServiceManagerInitialized( const base::Closure& quit_closure, service_manager::BackgroundServiceManager* service_manager) {
diff --git a/content/app/content_service_manager_main_delegate.h b/content/app/content_service_manager_main_delegate.h index 7563ce4..4393a8f 100644 --- a/content/app/content_service_manager_main_delegate.h +++ b/content/app/content_service_manager_main_delegate.h
@@ -34,9 +34,6 @@ void AdjustServiceProcessCommandLine( const service_manager::Identity& identity, base::CommandLine* command_line) override; - bool ShouldTerminateServiceManagerOnInstanceQuit( - const service_manager::Identity& identity, - int* exit_code) override; void OnServiceManagerInitialized( const base::Closure& quit_closure, service_manager::BackgroundServiceManager* service_manager) override;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index ac6c6a3..33b3ca9d4 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1437,40 +1437,29 @@ is_mus) { established_gpu_channel = always_uses_gpu = false; } - gpu::GpuChannelEstablishFactory* factory = - GetContentClient()->browser()->GetGpuChannelEstablishFactory(); - if (!factory) { - BrowserGpuChannelHostFactory::Initialize(established_gpu_channel); - factory = BrowserGpuChannelHostFactory::instance(); - } -#if !defined(OS_ANDROID) if (!is_mus) { - // TODO(kylechar): Remove flag along with surface sequences. - // See https://crbug.com/676384. + host_frame_sink_manager_ = base::MakeUnique<viz::HostFrameSinkManager>(); + + // TODO(crbug.com/676384): Remove flag along with surface sequences. auto surface_lifetime_type = - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableSurfaceReferences) + parsed_command_line_.HasSwitch(switches::kDisableSurfaceReferences) ? viz::SurfaceManager::LifetimeType::SEQUENCES : viz::SurfaceManager::LifetimeType::REFERENCES; frame_sink_manager_impl_ = std::make_unique<viz::FrameSinkManagerImpl>(surface_lifetime_type); - host_frame_sink_manager_ = base::MakeUnique<viz::HostFrameSinkManager>(); - // TODO(danakj): Don't make a FrameSinkManagerImpl when display is in the // Gpu process, instead get the mojo pointer from the Gpu process. surface_utils::ConnectWithLocalFrameSinkManager( host_frame_sink_manager_.get(), frame_sink_manager_impl_.get()); - } -#endif - DCHECK(factory); - if (!is_mus) { + // Initialize GpuChannelHostFactory and ImageTransportFactory. + BrowserGpuChannelHostFactory::Initialize(established_gpu_channel); ImageTransportFactory::SetFactory( - std::make_unique<GpuProcessTransportFactory>(GetResizeTaskRunner())); - ImageTransportFactory::GetInstance()->SetGpuChannelEstablishFactory( - factory); + std::make_unique<GpuProcessTransportFactory>( + BrowserGpuChannelHostFactory::instance(), GetResizeTaskRunner())); } + #if defined(USE_AURA) if (env_->mode() == aura::Env::Mode::LOCAL) { env_->set_context_factory(GetContextFactory());
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 45bf6b1..5a0f33bf 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -231,13 +231,16 @@ }; GpuProcessTransportFactory::GpuProcessTransportFactory( + gpu::GpuChannelEstablishFactory* gpu_channel_factory, scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner) : frame_sink_id_allocator_(kDefaultClientId), renderer_settings_( viz::CreateRendererSettings(CreateBufferToTextureTargetMap())), resize_task_runner_(std::move(resize_task_runner)), task_graph_runner_(new cc::SingleThreadTaskGraphRunner), + gpu_channel_factory_(gpu_channel_factory), callback_factory_(this) { + DCHECK(gpu_channel_factory_); cc::SetClientNameForMetrics("Browser"); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -380,7 +383,6 @@ base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, callback_factory_.GetWeakPtr(), compositor, create_gpu_output_surface, 0)); - DCHECK(gpu_channel_factory_); gpu_channel_factory_->EstablishGpuChannel(callback); } else { EstablishedGpuChannel(compositor, create_gpu_output_surface, 0, nullptr); @@ -501,7 +503,6 @@ base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel, callback_factory_.GetWeakPtr(), compositor, create_gpu_output_surface, num_attempts + 1)); - DCHECK(gpu_channel_factory_); gpu_channel_factory_->EstablishGpuChannel(callback); return; } @@ -905,12 +906,6 @@ return gl_helper_.get(); } -void GpuProcessTransportFactory::SetGpuChannelEstablishFactory( - gpu::GpuChannelEstablishFactory* factory) { - DCHECK(!gpu_channel_factory_ || !factory); - gpu_channel_factory_ = factory; -} - #if defined(OS_MACOSX) void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle( ui::Compositor* compositor, @@ -933,7 +928,6 @@ if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) return nullptr; - DCHECK(gpu_channel_factory_); scoped_refptr<gpu::GpuChannelHost> gpu_channel_host = gpu_channel_factory_->EstablishGpuChannelSync(); if (!gpu_channel_host)
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h index 25340e5..5d640f7 100644 --- a/content/browser/compositor/gpu_process_transport_factory.h +++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -33,6 +33,10 @@ class SurfaceManager; } +namespace gpu { +class GpuChannelEstablishFactory; +} + namespace ui { class ContextProviderCommandBuffer; } @@ -49,7 +53,8 @@ public ui::ContextFactoryPrivate, public ImageTransportFactory { public: - explicit GpuProcessTransportFactory( + GpuProcessTransportFactory( + gpu::GpuChannelEstablishFactory* gpu_channel_factory, scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner); ~GpuProcessTransportFactory() override; @@ -93,8 +98,6 @@ ui::ContextFactoryPrivate* GetContextFactoryPrivate() override; viz::FrameSinkManagerImpl* GetFrameSinkManager() override; viz::GLHelper* GetGLHelper() override; - void SetGpuChannelEstablishFactory( - gpu::GpuChannelEstablishFactory* factory) override; #if defined(OS_MACOSX) void SetCompositorSuspendedForRecycle(ui::Compositor* compositor, bool suspended) override; @@ -145,7 +148,7 @@ scoped_refptr<viz::VulkanInProcessContextProvider> shared_vulkan_context_provider_; - gpu::GpuChannelEstablishFactory* gpu_channel_factory_ = nullptr; + gpu::GpuChannelEstablishFactory* const gpu_channel_factory_; base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_;
diff --git a/content/browser/compositor/image_transport_factory.h b/content/browser/compositor/image_transport_factory.h index 0d11f33b..2530bf3 100644 --- a/content/browser/compositor/image_transport_factory.h +++ b/content/browser/compositor/image_transport_factory.h
@@ -20,10 +20,6 @@ class GLHelper; } -namespace gpu { -class GpuChannelEstablishFactory; -} - namespace content { // This class provides the interface for creating the support for the @@ -56,9 +52,6 @@ // (ImageTransportFactoryObserver::OnLostResources is called). virtual viz::GLHelper* GetGLHelper() = 0; - virtual void SetGpuChannelEstablishFactory( - gpu::GpuChannelEstablishFactory* factory) = 0; - #if defined(OS_MACOSX) // Called with |suspended| as true when the ui::Compositor has been // disconnected from an NSView and may be attached to another one. Called
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.cc b/content/browser/compositor/test/no_transport_image_transport_factory.cc index 04ef61e..3e33c8c 100644 --- a/content/browser/compositor/test/no_transport_image_transport_factory.cc +++ b/content/browser/compositor/test/no_transport_image_transport_factory.cc
@@ -58,7 +58,4 @@ return gl_helper_.get(); } -void NoTransportImageTransportFactory::SetGpuChannelEstablishFactory( - gpu::GpuChannelEstablishFactory* factory) {} - } // namespace content
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.h b/content/browser/compositor/test/no_transport_image_transport_factory.h index a42428a..fb70e199e 100644 --- a/content/browser/compositor/test/no_transport_image_transport_factory.h +++ b/content/browser/compositor/test/no_transport_image_transport_factory.h
@@ -39,8 +39,6 @@ ui::ContextFactory* GetContextFactory() override; ui::ContextFactoryPrivate* GetContextFactoryPrivate() override; viz::GLHelper* GetGLHelper() override; - void SetGpuChannelEstablishFactory( - gpu::GpuChannelEstablishFactory* factory) override; #if defined(OS_MACOSX) void SetCompositorSuspendedForRecycle(ui::Compositor* compositor, bool suspended) override {}
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc index 7d3d5d7b..45f5972 100644 --- a/content/browser/frame_host/frame_tree.cc +++ b/content/browser/frame_host/frame_tree.cc
@@ -26,9 +26,9 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/content_switches_internal.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/input_messages.h" #include "content/common/site_isolation_policy.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" namespace content { @@ -178,8 +178,7 @@ const std::string& frame_name, const std::string& frame_unique_name, const base::UnguessableToken& devtools_frame_token, - blink::WebSandboxFlags sandbox_flags, - const ParsedFeaturePolicyHeader& container_policy, + const FramePolicy& frame_policy, const FrameOwnerProperties& frame_owner_properties) { CHECK_NE(new_routing_id, MSG_ROUTING_NONE); @@ -200,8 +199,8 @@ // empty document in the frame. This needs to happen before the call to // AddChild so that the effective policy is sent to any newly-created // RenderFrameProxy objects when the RenderFrameHost is created. - new_node->SetPendingSandboxFlags(sandbox_flags); - new_node->SetPendingContainerPolicy(container_policy); + new_node->SetPendingSandboxFlags(frame_policy.sandbox_flags); + new_node->SetPendingContainerPolicy(frame_policy.container_policy); new_node->CommitPendingFramePolicy(); // Add the new node to the FrameTree, creating the RenderFrameHost.
diff --git a/content/browser/frame_host/frame_tree.h b/content/browser/frame_host/frame_tree.h index 379ecda1..f3915e3a 100644 --- a/content/browser/frame_host/frame_tree.h +++ b/content/browser/frame_host/frame_tree.h
@@ -21,6 +21,7 @@ namespace content { struct FrameOwnerProperties; +struct FramePolicy; class Navigator; class RenderFrameHostDelegate; class RenderViewHostDelegate; @@ -128,8 +129,7 @@ const std::string& frame_name, const std::string& frame_unique_name, const base::UnguessableToken& devtools_frame_token, - blink::WebSandboxFlags sandbox_flags, - const ParsedFeaturePolicyHeader& container_policy, + const FramePolicy& frame_policy, const FrameOwnerProperties& frame_owner_properties); // Removes a frame from the frame tree. |child|, its children, and objects
diff --git a/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc b/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc index b08c37b..47db159 100644 --- a/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc +++ b/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc
@@ -12,10 +12,10 @@ #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" namespace content { @@ -131,11 +131,11 @@ int consumption = 0; for (int child_num = 1; shape[consumption++] == '('; ++child_num) { int child_id = self_id * 10 + child_num; - tree()->AddFrame( - node, process_id(), child_id, blink::WebTreeScopeType::kDocument, - std::string(), base::StringPrintf("uniqueName%d", child_id), - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + tree()->AddFrame(node, process_id(), child_id, + blink::WebTreeScopeType::kDocument, std::string(), + base::StringPrintf("uniqueName%d", child_id), + base::UnguessableToken::Create(), FramePolicy(), + FrameOwnerProperties()); FrameTreeNode* child = node->child_at(child_num - 1); consumption += CreateSubframes(child, child_id, shape + consumption); }
diff --git a/content/browser/frame_host/frame_tree_unittest.cc b/content/browser/frame_host/frame_tree_unittest.cc index eebf250..dea82c6 100644 --- a/content/browser/frame_host/frame_tree_unittest.cc +++ b/content/browser/frame_host/frame_tree_unittest.cc
@@ -16,6 +16,7 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" @@ -24,7 +25,6 @@ #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" namespace content { @@ -159,34 +159,28 @@ // Simulate attaching a series of frames to build the frame tree. frame_tree->AddFrame(root, process_id, 14, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), + FrameOwnerProperties()); frame_tree->AddFrame(root, process_id, 15, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), + FrameOwnerProperties()); frame_tree->AddFrame(root, process_id, 16, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), + FrameOwnerProperties()); frame_tree->AddFrame(root->child_at(0), process_id, 244, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName3", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(root->child_at(1), process_id, 255, blink::WebTreeScopeType::kDocument, no_children_node, "uniqueName4", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(root->child_at(0), process_id, 245, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName5", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); EXPECT_EQ( "2: [14: [244: [], 245: []], " @@ -198,50 +192,41 @@ frame_tree->AddFrame(child_16, process_id, 264, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName6", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(child_16, process_id, 265, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName7", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(child_16, process_id, 266, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName8", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(child_16, process_id, 267, blink::WebTreeScopeType::kDocument, deep_subtree, "uniqueName9", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(child_16, process_id, 268, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName10", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); FrameTreeNode* child_267 = child_16->child_at(3); frame_tree->AddFrame(child_267, process_id, 365, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName11", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(child_267->child_at(0), process_id, 455, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName12", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame(child_267->child_at(0)->child_at(0), process_id, 555, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName13", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); frame_tree->AddFrame( child_267->child_at(0)->child_at(0)->child_at(0), process_id, 655, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName14", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); // Now that's it's fully built, verify the tree structure is as expected. EXPECT_EQ( @@ -314,26 +299,21 @@ main_test_rfh()->OnCreateChildFrame( 22, blink::WebTreeScopeType::kDocument, "child0", "uniqueName0", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( 23, blink::WebTreeScopeType::kDocument, "child1", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( 24, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* child0 = root->child_at(0); FrameTreeNode* child1 = root->child_at(1); - FrameTreeNode* child2 = root->child_at(2); // Add one grandchild frame. child1->current_frame_host()->OnCreateChildFrame( 33, blink::WebTreeScopeType::kDocument, "grandchild", "uniqueName3", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* grandchild = child1->child_at(0); // Ensure they can be found by FTN id. @@ -371,16 +351,13 @@ FrameTreeNode* root = frame_tree->root(); main_test_rfh()->OnCreateChildFrame( 22, blink::WebTreeScopeType::kDocument, "child0", "uniqueName0", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( 23, blink::WebTreeScopeType::kDocument, "child1", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( 24, blink::WebTreeScopeType::kDocument, "child2", "uniqueName2", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* child0 = root->child_at(0); FrameTreeNode* child1 = root->child_at(1); FrameTreeNode* child2 = root->child_at(2); @@ -388,8 +365,7 @@ // Add one grandchild frame. child1->current_frame_host()->OnCreateChildFrame( 33, blink::WebTreeScopeType::kDocument, "grandchild", "uniqueName3", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* grandchild = child1->child_at(0); // Test PreviousSibling(). @@ -420,16 +396,14 @@ // Simulate attaching a series of frames to build the frame tree. main_test_rfh()->OnCreateChildFrame( 14, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); EXPECT_EQ( "RenderFrameHostChanged(new)(14) -> 2: []\n" "RenderFrameCreated(14) -> 2: [14: []]", activity.GetLog()); main_test_rfh()->OnCreateChildFrame( 18, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); EXPECT_EQ( "RenderFrameHostChanged(new)(18) -> 2: [14: []]\n" "RenderFrameCreated(18) -> 2: [14: [], 18: []]", @@ -449,16 +423,14 @@ main_test_rfh()->OnCreateChildFrame( 22, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); EXPECT_EQ( "RenderFrameHostChanged(new)(22) -> 2: []\n" "RenderFrameCreated(22) -> 2: [22: []]", activity.GetLog()); main_test_rfh()->OnCreateChildFrame( 23, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); EXPECT_EQ( "RenderFrameHostChanged(new)(23) -> 2: [22: []]\n" "RenderFrameCreated(23) -> 2: [22: [], 23: []]", @@ -488,8 +460,7 @@ ASSERT_FALSE(frame_tree->AddFrame( root, process_id + 1, 1, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties())); + FramePolicy(), FrameOwnerProperties())); ASSERT_EQ("2: []", GetTreeState(frame_tree)); } @@ -503,19 +474,16 @@ main_test_rfh()->OnCreateChildFrame( 22, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( 23, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); // Add one grandchild frame. RenderFrameHostImpl* child1_rfh = root->child_at(0)->current_frame_host(); child1_rfh->OnCreateChildFrame( 33, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); // Ensure they can be found by id. int id1 = root->child_at(0)->frame_tree_node_id();
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 56a66a6..e2d3dfa 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -31,6 +31,7 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/render_view_host.h" @@ -50,7 +51,6 @@ #include "content/test/test_web_contents.h" #include "skia/ext/platform_canvas.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" using base::Time; @@ -2223,8 +2223,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); const GURL subframe_url("http://foo1/subframe"); @@ -2300,8 +2299,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name0, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); const GURL url2("http://foo/2"); @@ -2345,8 +2343,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name1, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe2 = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(1)->current_frame_host()); const GURL url3("http://foo/3"); @@ -2390,8 +2387,7 @@ subframe->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name2, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe3 = static_cast<TestRenderFrameHost*>(contents() ->GetFrameTree() @@ -2453,8 +2449,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); const GURL subframe_url("http://foo1/subframe"); @@ -3857,8 +3852,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); const GURL subframe_url("http://www.google.com/#"); @@ -4032,8 +4026,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); const GURL url1_sub("http://foo/subframe");
diff --git a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc index 2475dd9..77663b0 100644 --- a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc +++ b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
@@ -5,6 +5,7 @@ #include <vector> #include "content/common/feature_policy/feature_policy.h" +#include "content/common/frame_policy.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/navigation_simulator.h" @@ -66,8 +67,8 @@ blink::WebFeaturePolicyFeature feature, const std::vector<std::string>& origins) { static_cast<TestRenderFrameHost*>(parent)->OnDidChangeFramePolicy( - child->GetRoutingID(), blink::WebSandboxFlags(), - CreateFPHeader(feature, origins)); + child->GetRoutingID(), + {blink::WebSandboxFlags::kNone, CreateFPHeader(feature, origins)}); } void SimulateNavigation(RenderFrameHost** rfh, const GURL& url) { @@ -178,4 +179,4 @@ EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); } -} // namespace content \ No newline at end of file +} // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 2b2e16f..186cd94 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -83,6 +83,7 @@ #include "content/common/content_security_policy/content_security_policy.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/input/input_handler.mojom.h" #include "content/common/input_messages.h" #include "content/common/inter_process_time_ticks_converter.h" @@ -1312,8 +1313,7 @@ const std::string& frame_name, const std::string& frame_unique_name, const base::UnguessableToken& devtools_frame_token, - blink::WebSandboxFlags sandbox_flags, - const ParsedFeaturePolicyHeader& container_policy, + const FramePolicy& frame_policy, const FrameOwnerProperties& frame_owner_properties) { // TODO(lukasza): Call ReceivedBadMessage when |frame_unique_name| is empty. DCHECK(!frame_unique_name.empty()); @@ -1329,7 +1329,7 @@ // IO thread and not taken from the renderer process. frame_tree_->AddFrame(frame_tree_node_, GetProcess()->GetID(), new_routing_id, scope, frame_name, frame_unique_name, - devtools_frame_token, sandbox_flags, container_policy, + devtools_frame_token, frame_policy, frame_owner_properties); } @@ -2236,8 +2236,7 @@ void RenderFrameHostImpl::OnDidChangeFramePolicy( int32_t frame_routing_id, - blink::WebSandboxFlags flags, - const ParsedFeaturePolicyHeader& container_policy) { + const FramePolicy& frame_policy) { // Ensure that a frame can only update sandbox flags or feature policy for its // immediate children. If this is not the case, the renderer is considered // malicious and is killed. @@ -2247,8 +2246,8 @@ if (!child) return; - child->SetPendingSandboxFlags(flags); - child->SetPendingContainerPolicy(container_policy); + child->SetPendingSandboxFlags(frame_policy.sandbox_flags); + child->SetPendingContainerPolicy(frame_policy.container_policy); // Notify the RenderFrame if it lives in a different process from its parent. // The frame's proxies in other processes also need to learn about the updated @@ -2258,7 +2257,7 @@ RenderFrameHost* child_rfh = child->current_frame_host(); if (child_rfh->GetSiteInstance() != GetSiteInstance()) { child_rfh->Send(new FrameMsg_DidUpdateFramePolicy(child_rfh->GetRoutingID(), - flags, container_policy)); + frame_policy)); } }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index ec9ec44..6c4c072 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -118,6 +118,7 @@ struct ContextMenuParams; struct FileChooserParams; struct FrameOwnerProperties; +struct FramePolicy; struct FileChooserParams; struct ResourceResponse; @@ -276,8 +277,7 @@ const std::string& frame_name, const std::string& frame_unique_name, const base::UnguessableToken& devtools_frame_token, - blink::WebSandboxFlags sandbox_flags, - const ParsedFeaturePolicyHeader& container_policy, + const FramePolicy& frame_policy, const FrameOwnerProperties& frame_owner_properties); // Update this frame's last committed origin. @@ -768,10 +768,8 @@ void OnEnforceInsecureRequestPolicy(blink::WebInsecureRequestPolicy policy); void OnUpdateToUniqueOrigin(bool is_potentially_trustworthy_unique_origin); - void OnDidChangeFramePolicy( - int32_t frame_routing_id, - blink::WebSandboxFlags flags, - const ParsedFeaturePolicyHeader& container_policy); + void OnDidChangeFramePolicy(int32_t frame_routing_id, + const FramePolicy& frame_policy); void OnDidChangeFrameOwnerProperties(int32_t frame_routing_id, const FrameOwnerProperties& properties); void OnUpdateTitle(const base::string16& title,
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 7e44458..d2f738e4 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -555,8 +555,8 @@ if (pair.second->GetSiteInstance() != parent_site_instance) { pair.second->Send(new FrameMsg_DidUpdateFramePolicy( pair.second->GetRoutingID(), - frame_tree_node_->current_replication_state().sandbox_flags, - frame_tree_node_->current_replication_state().container_policy)); + {frame_tree_node_->current_replication_state().sandbox_flags, + frame_tree_node_->current_replication_state().container_policy})); } } }
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index c6ea752..c33d2ca 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -26,6 +26,7 @@ #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/input_messages.h" #include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" @@ -57,7 +58,6 @@ #include "net/base/load_flags.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" #include "ui/base/page_transition_types.h" namespace content { @@ -1950,13 +1950,11 @@ contents()->GetMainFrame()->OnCreateChildFrame( contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); contents()->GetMainFrame()->OnCreateChildFrame( contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName2", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); RenderFrameHostManager* root_manager = contents()->GetFrameTree()->root()->render_manager(); RenderFrameHostManager* iframe1 = @@ -2091,8 +2089,7 @@ contents1->GetMainFrame()->OnCreateChildFrame( contents1->GetMainFrame()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame_name", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); RenderFrameHostManager* iframe = contents()->GetFrameTree()->root()->child_at(0)->render_manager(); NavigationEntryImpl entry(NULL /* instance */, kUrl2, @@ -2141,8 +2138,7 @@ main_rfh->OnCreateChildFrame( main_rfh->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); RenderFrameHostManager* subframe_rfhm = contents()->GetFrameTree()->root()->child_at(0)->render_manager(); @@ -2300,13 +2296,11 @@ int process_id = root1->current_frame_host()->GetProcess()->GetID(); tree1->AddFrame(root1, process_id, 12, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); tree1->AddFrame(root1, process_id, 13, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName1", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); std::unique_ptr<TestWebContents> tab2( @@ -2317,13 +2311,11 @@ process_id = root2->current_frame_host()->GetProcess()->GetID(); tree2->AddFrame(root2, process_id, 22, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName2", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); tree2->AddFrame(root2, process_id, 23, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName3", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); std::unique_ptr<TestWebContents> tab3( @@ -2339,8 +2331,7 @@ process_id = root4->current_frame_host()->GetProcess()->GetID(); tree4->AddFrame(root4, process_id, 42, blink::WebTreeScopeType::kDocument, std::string(), "uniqueName4", - base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); root1->child_at(1)->SetOpener(root1->child_at(1)); @@ -2390,18 +2381,15 @@ main_test_rfh()->OnCreateChildFrame( main_test_rfh()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( main_test_rfh()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame2", "uniqueName2", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); main_test_rfh()->OnCreateChildFrame( main_test_rfh()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame3", "uniqueName3", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* root = contents()->GetFrameTree()->root(); RenderFrameHostManager* child1 = root->child_at(0)->render_manager(); @@ -2491,8 +2479,7 @@ main_test_rfh()->OnCreateChildFrame( main_test_rfh()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* root = contents()->GetFrameTree()->root(); RenderFrameHostManager* child = root->child_at(0)->render_manager(); @@ -3036,8 +3023,7 @@ main_test_rfh()->OnCreateChildFrame( main_test_rfh()->GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, "frame1", "uniqueName1", - base::UnguessableToken::Create(), blink::WebSandboxFlags::kNone, - ParsedFeaturePolicyHeader(), FrameOwnerProperties()); + base::UnguessableToken::Create(), FramePolicy(), FrameOwnerProperties()); FrameTreeNode* root = contents()->GetFrameTree()->root(); RenderFrameHostManager* child = root->child_at(0)->render_manager();
diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc index a842664..9ee3ffc 100644 --- a/content/browser/frame_host/render_frame_message_filter.cc +++ b/content/browser/frame_host/render_frame_message_filter.cc
@@ -21,6 +21,7 @@ #include "content/common/content_constants_internal.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -66,8 +67,7 @@ const std::string& frame_name, const std::string& frame_unique_name, const base::UnguessableToken& devtools_frame_token, - blink::WebSandboxFlags sandbox_flags, - const ParsedFeaturePolicyHeader& container_policy, + const FramePolicy& frame_policy, const FrameOwnerProperties& frame_owner_properties, int new_routing_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -78,8 +78,7 @@ if (render_frame_host) { render_frame_host->OnCreateChildFrame( new_routing_id, scope, frame_name, frame_unique_name, - devtools_frame_token, sandbox_flags, container_policy, - frame_owner_properties); + devtools_frame_token, frame_policy, frame_owner_properties); } } @@ -350,8 +349,8 @@ base::BindOnce(&CreateChildFrameOnUI, render_process_id_, params.parent_routing_id, params.scope, params.frame_name, params.frame_unique_name, *devtools_frame_token, - params.sandbox_flags, params.container_policy, - params.frame_owner_properties, *new_routing_id)); + params.frame_policy, params.frame_owner_properties, + *new_routing_id)); } void RenderFrameMessageFilter::OnCookiesEnabled(int render_frame_id,
diff --git a/content/browser/indexed_db/leveldb/leveldb_database.h b/content/browser/indexed_db/leveldb/leveldb_database.h index c27dea06..039cccc 100644 --- a/content/browser/indexed_db/leveldb/leveldb_database.h +++ b/content/browser/indexed_db/leveldb/leveldb_database.h
@@ -136,7 +136,6 @@ }; // Despite the type name, this object uses LRU eviction. - size_t lru_max_size_ = 0; base::HashingMRUCache<LevelDBIterator*, DetachIteratorOnDestruct> iterator_lru_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 44207cf..6be9bcf 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -49,6 +49,7 @@ #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "cc/base/switches.h" @@ -3909,6 +3910,10 @@ resource_coordinator::mojom::PropertyType::kPID, base::GetProcId(GetHandle())); + GetProcessResourceCoordinator()->SetProperty( + resource_coordinator::mojom::PropertyType::kLaunchTime, + base::Time::Now().ToTimeT()); + #if BUILDFLAG(ENABLE_WEBRTC) if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) { EnableAudioDebugRecordings(
diff --git a/content/browser/renderer_host/render_process_host_unittest.cc b/content/browser/renderer_host/render_process_host_unittest.cc index aaecf1cb..754c076 100644 --- a/content/browser/renderer_host/render_process_host_unittest.cc +++ b/content/browser/renderer_host/render_process_host_unittest.cc
@@ -12,6 +12,8 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "content/common/frame_messages.h" +#include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/browser_side_navigation_policy.h" @@ -24,7 +26,6 @@ #include "content/test/test_render_frame_host.h" #include "content/test/test_render_view_host.h" #include "content/test/test_web_contents.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" namespace content { @@ -131,8 +132,7 @@ main_test_rfh()->OnCreateChildFrame( process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, std::string(), unique_name, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); subframe = static_cast<TestRenderFrameHost*>(
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 41f605f1..6ed5d98 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -269,6 +269,20 @@ service_manager::Identity(mojom::kPackagedServicesServiceName, service_manager::mojom::kRootUserID), std::move(packaged_services_service), nullptr); + service_manager_->SetInstanceQuitCallback( + base::Bind(&OnInstanceQuitOnIOThread)); + } + + static void OnInstanceQuitOnIOThread(const service_manager::Identity& id) { + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI) + ->PostTask(FROM_HERE, base::BindOnce(&OnInstanceQuit, id)); + } + + static void OnInstanceQuit(const service_manager::Identity& id) { + if (GetContentClient()->browser()->ShouldTerminateOnServiceQuit(id)) { + LOG(FATAL) << "Terminating because service '" << id.name() + << "' quit unexpectedly."; + } } void ShutDownOnIOThread() {
diff --git a/content/browser/snapshot_browsertest.cc b/content/browser/snapshot_browsertest.cc index 4525fe4..583c744 100644 --- a/content/browser/snapshot_browsertest.cc +++ b/content/browser/snapshot_browsertest.cc
@@ -249,13 +249,7 @@ } } -// Seen to time out / fail on debug Mac; crbug.com/771119, crbug.com/774050. -#if defined(NDEBUG) && !defined(OS_MACOSX) -#define MAYBE_SyncMultiWindowTest SyncMultiWindowTest -#else -#define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest -#endif -IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) { +IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, SyncMultiWindowTest) { SetupTestServer(); for (int i = 0; i < 3; ++i) {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 7297db4..f985ea2 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1631,12 +1631,7 @@ render_manager->CreateOuterDelegateProxy( outer_contents_frame->GetSiteInstance(), outer_contents_frame_impl); - render_manager->SetRWHViewForInnerContents( - render_manager->GetRenderWidgetHostView()); - - static_cast<RenderWidgetHostViewChildFrame*>( - render_manager->GetRenderWidgetHostView()) - ->RegisterFrameSinkId(); + ReattachToOuterWebContentsFrame(); if (outer_web_contents_impl->frame_tree_.GetFocusedFrame() == outer_contents_frame_impl->frame_tree_node()) { @@ -1644,12 +1639,6 @@ outer_contents_frame->GetSiteInstance()); } - // Set up the the guest's AX tree to point back at the embedder's AX tree. - auto* parent_frame = outer_contents_frame->GetParent(); - GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( - parent_frame->GetAXTreeID()); - GetMainFrame()->UpdateAXTreeData(); - // At this point, we should destroy the TextInputManager which will notify all // the RWHV in this WebContents. The RWHV in this WebContents should use the // TextInputManager owned by the outer WebContents. @@ -1660,6 +1649,24 @@ text_input_manager_.reset(nullptr); } +void WebContentsImpl::ReattachToOuterWebContentsFrame() { + DCHECK(node_.outer_web_contents()); + auto* render_manager = GetRenderManager(); + auto* parent_frame = + node_.OuterContentsFrameTreeNode()->current_frame_host()->GetParent(); + render_manager->SetRWHViewForInnerContents( + render_manager->GetRenderWidgetHostView()); + + static_cast<RenderWidgetHostViewChildFrame*>( + render_manager->GetRenderWidgetHostView()) + ->RegisterFrameSinkId(); + + // Set up the the guest's AX tree to point back at the embedder's AX tree. + GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( + parent_frame->GetAXTreeID()); + GetMainFrame()->UpdateAXTreeData(); +} + void WebContentsImpl::DidChangeVisibleSecurityState() { if (delegate_) { delegate_->VisibleSecurityStateChanged(this); @@ -5533,6 +5540,9 @@ return false; } + if (proxy_routing_id == MSG_ROUTING_NONE && node_.outer_web_contents()) + ReattachToOuterWebContentsFrame(); + SetHistoryOffsetAndLengthForView(render_view_host, controller_.GetLastCommittedEntryIndex(), controller_.GetEntryCount());
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index ae7f760f..afd40fc8 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -1318,6 +1318,9 @@ // is that of the main frame. void SetVisibilityForChildViews(bool visible); + // Reattaches this inner WebContents to its outer WebContents. + void ReattachToOuterWebContentsFrame(); + // Data for core operation --------------------------------------------------- // Delegate for notifying our owner about stuff. Not owned by us.
diff --git a/content/browser/webui/web_ui_controller_factory_registry.cc b/content/browser/webui/web_ui_controller_factory_registry.cc index b151e32..708cf7a 100644 --- a/content/browser/webui/web_ui_controller_factory_registry.cc +++ b/content/browser/webui/web_ui_controller_factory_registry.cc
@@ -14,15 +14,16 @@ namespace content { base::LazyInstance<std::vector<WebUIControllerFactory*>>::DestructorAtExit - g_factories = LAZY_INSTANCE_INITIALIZER; + g_web_ui_controller_factories = LAZY_INSTANCE_INITIALIZER; void WebUIControllerFactory::RegisterFactory(WebUIControllerFactory* factory) { - g_factories.Pointer()->push_back(factory); + g_web_ui_controller_factories.Pointer()->push_back(factory); } void WebUIControllerFactory::UnregisterFactoryForTesting( WebUIControllerFactory* factory) { - std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer(); + std::vector<WebUIControllerFactory*>* factories = + g_web_ui_controller_factories.Pointer(); for (size_t i = 0; i < factories->size(); ++i) { if ((*factories)[i] == factory) { factories->erase(factories->begin() + i); @@ -38,7 +39,8 @@ WebUIController* WebUIControllerFactoryRegistry::CreateWebUIControllerForURL( WebUI* web_ui, const GURL& url) const { - std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer(); + std::vector<WebUIControllerFactory*>* factories = + g_web_ui_controller_factories.Pointer(); for (size_t i = 0; i < factories->size(); ++i) { WebUIController* controller = (*factories)[i]->CreateWebUIControllerForURL( web_ui, url); @@ -50,7 +52,8 @@ WebUI::TypeID WebUIControllerFactoryRegistry::GetWebUIType( BrowserContext* browser_context, const GURL& url) const { - std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer(); + std::vector<WebUIControllerFactory*>* factories = + g_web_ui_controller_factories.Pointer(); for (size_t i = 0; i < factories->size(); ++i) { WebUI::TypeID type = (*factories)[i]->GetWebUIType(browser_context, url); if (type != WebUI::kNoWebUI) @@ -61,7 +64,8 @@ bool WebUIControllerFactoryRegistry::UseWebUIForURL( BrowserContext* browser_context, const GURL& url) const { - std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer(); + std::vector<WebUIControllerFactory*>* factories = + g_web_ui_controller_factories.Pointer(); for (size_t i = 0; i < factories->size(); ++i) { if ((*factories)[i]->UseWebUIForURL(browser_context, url)) return true; @@ -71,7 +75,8 @@ bool WebUIControllerFactoryRegistry::UseWebUIBindingsForURL( BrowserContext* browser_context, const GURL& url) const { - std::vector<WebUIControllerFactory*>* factories = g_factories.Pointer(); + std::vector<WebUIControllerFactory*>* factories = + g_web_ui_controller_factories.Pointer(); for (size_t i = 0; i < factories->size(); ++i) { if ((*factories)[i]->UseWebUIBindingsForURL(browser_context, url)) return true;
diff --git a/content/browser/webui/web_ui_url_loader_factory.cc b/content/browser/webui/web_ui_url_loader_factory.cc index 579df51..61bcfd0 100644 --- a/content/browser/webui/web_ui_url_loader_factory.cc +++ b/content/browser/webui/web_ui_url_loader_factory.cc
@@ -39,7 +39,7 @@ class WebUIURLLoaderFactory; base::LazyInstance<std::map<int, std::unique_ptr<WebUIURLLoaderFactory>>>::Leaky - g_factories = LAZY_INSTANCE_INITIALIZER; + g_web_ui_url_loader_factories = LAZY_INSTANCE_INITIALIZER; void CallOnError(mojom::URLLoaderClientPtrInfo client_info, int error_code) { mojom::URLLoaderClientPtr client; @@ -273,7 +273,7 @@ // FrameTreeNode::Observer implementation: void OnFrameTreeNodeDestroyed(FrameTreeNode* node) override { - g_factories.Get().erase(frame_tree_node_id_); + g_web_ui_url_loader_factories.Get().erase(frame_tree_node_id_); } private: @@ -288,9 +288,10 @@ mojom::URLLoaderFactoryPtr CreateWebUIURLLoader(FrameTreeNode* node) { int ftn_id = node->frame_tree_node_id(); - if (g_factories.Get()[ftn_id].get() == nullptr) - g_factories.Get()[ftn_id] = base::MakeUnique<WebUIURLLoaderFactory>(node); - return g_factories.Get()[ftn_id]->CreateBinding(); + if (g_web_ui_url_loader_factories.Get()[ftn_id].get() == nullptr) + g_web_ui_url_loader_factories.Get()[ftn_id] = + base::MakeUnique<WebUIURLLoaderFactory>(node); + return g_web_ui_url_loader_factories.Get()[ftn_id]->CreateBinding(); } } // namespace content
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index d607aae..9fefd53 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -157,6 +157,8 @@ "frame_messages_forward.h", "frame_owner_properties.cc", "frame_owner_properties.h", + "frame_policy.cc", + "frame_policy.h", "frame_replication_state.cc", "frame_replication_state.h", "gin_java_bridge_messages.h",
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 18c4b420..4763d71 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -27,6 +27,7 @@ #include "content/common/features.h" #include "content/common/frame_message_enums.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/frame_replication_state.h" #include "content/common/navigation_gesture.h" #include "content/common/navigation_params.h" @@ -197,6 +198,11 @@ IPC_STRUCT_TRAITS_MEMBER(required_csp) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(content::FramePolicy) + IPC_STRUCT_TRAITS_MEMBER(sandbox_flags) + IPC_STRUCT_TRAITS_MEMBER(container_policy) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(content::PageImportanceSignals) IPC_STRUCT_TRAITS_MEMBER(had_form_interaction) IPC_STRUCT_TRAITS_END() @@ -560,8 +566,7 @@ IPC_STRUCT_MEMBER(blink::WebTreeScopeType, scope) IPC_STRUCT_MEMBER(std::string, frame_name) IPC_STRUCT_MEMBER(std::string, frame_unique_name) - IPC_STRUCT_MEMBER(blink::WebSandboxFlags, sandbox_flags) - IPC_STRUCT_MEMBER(content::ParsedFeaturePolicyHeader, container_policy) + IPC_STRUCT_MEMBER(content::FramePolicy, frame_policy) IPC_STRUCT_MEMBER(content::FrameOwnerProperties, frame_owner_properties) IPC_STRUCT_END() @@ -848,9 +853,7 @@ // Notifies the frame that its parent has changed the frame's sandbox flags or // container policy. -IPC_MESSAGE_ROUTED2(FrameMsg_DidUpdateFramePolicy, - blink::WebSandboxFlags, - content::ParsedFeaturePolicyHeader) +IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateFramePolicy, content::FramePolicy) // Update a proxy's window.name property. Used when the frame's name is // changed in another process. @@ -1224,11 +1227,10 @@ // Notifies the browser that sandbox flags or container policy have changed for // a subframe of this frame. -IPC_MESSAGE_ROUTED3( +IPC_MESSAGE_ROUTED2( FrameHostMsg_DidChangeFramePolicy, int32_t /* subframe_routing_id */, - blink::WebSandboxFlags /* updated_flags */, - content::ParsedFeaturePolicyHeader /* updated container policy */) + content::FramePolicy /* updated sandbox flags and container policy */) // Notifies the browser that frame owner properties have changed for a subframe // of this frame.
diff --git a/content/common/frame_policy.cc b/content/common/frame_policy.cc new file mode 100644 index 0000000..ddf0c22 --- /dev/null +++ b/content/common/frame_policy.cc
@@ -0,0 +1,22 @@ +// 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 "content/common/frame_policy.h" + +namespace content { + +FramePolicy::FramePolicy() + : sandbox_flags(blink::WebSandboxFlags::kNone), container_policy({}) {} + +FramePolicy::FramePolicy(blink::WebSandboxFlags sandbox_flags, + const ParsedFeaturePolicyHeader& container_policy) + : sandbox_flags(sandbox_flags), container_policy(container_policy) {} + +FramePolicy::FramePolicy(const FramePolicy& lhs) + : sandbox_flags(lhs.sandbox_flags), + container_policy(lhs.container_policy) {} + +FramePolicy::~FramePolicy() {} + +} // namespace content
diff --git a/content/common/frame_policy.h b/content/common/frame_policy.h new file mode 100644 index 0000000..b227b45 --- /dev/null +++ b/content/common/frame_policy.h
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_FRAME_POLICY_H_ +#define CONTENT_COMMON_FRAME_POLICY_H_ + +#include "content/common/content_export.h" +#include "content/common/feature_policy/feature_policy.h" +#include "third_party/WebKit/public/web/WebSandboxFlags.h" + +namespace content { + +// This structure contains the attributes of a frame which determine what +// features are available during the lifetime of the framed document. Currently, +// this includes the sandbox flags and the feature policy container policy. Used +// in the frame tree to track sandbox and feature policy in the browser process, +// and tranferred over IPC during frame replication when site isolation is +// enabled. +// +// Unlike the attributes in FrameOwnerProperties, these attributes are never +// updated after the framed document has been loaded, so two versions of this +// structure are kept in the frame tree for each frame -- the effective policy +// and the pending policy, which will take effect when the frame is next +// navigated. +struct CONTENT_EXPORT FramePolicy { + FramePolicy(); + FramePolicy(blink::WebSandboxFlags sandbox_flags, + const ParsedFeaturePolicyHeader& container_policy); + FramePolicy(const FramePolicy& lhs); + ~FramePolicy(); + + blink::WebSandboxFlags sandbox_flags; + ParsedFeaturePolicyHeader container_policy; +}; + +} // namespace content + +#endif // CONTENT_COMMON_FRAME_POLICY_H_
diff --git a/content/common/input/input_event_struct_traits.cc b/content/common/input/input_event_struct_traits.cc index f5af727..a6ab8dc 100644 --- a/content/common/input/input_event_struct_traits.cc +++ b/content/common/input/input_event_struct_traits.cc
@@ -119,6 +119,9 @@ gesture_event->y = gesture_data->widget_position.y(); gesture_event->global_x = gesture_data->screen_position.x(); gesture_event->global_y = gesture_data->screen_position.y(); + gesture_event->is_source_touch_event_set_non_blocking = + gesture_data->is_source_touch_event_set_non_blocking; + gesture_event->primary_pointer_type = gesture_data->primary_pointer_type; gesture_event->source_device = gesture_data->source_device; gesture_event->unique_touch_event_id = gesture_data->unique_touch_event_id; gesture_event->resending_plugin_id = gesture_data->resending_plugin_id; @@ -424,6 +427,9 @@ gesture_data->screen_position = gesture_event->PositionInScreen(); gesture_data->widget_position = gesture_event->PositionInWidget(); gesture_data->source_device = gesture_event->source_device; + gesture_data->is_source_touch_event_set_non_blocking = + gesture_event->is_source_touch_event_set_non_blocking; + gesture_data->primary_pointer_type = gesture_event->primary_pointer_type; gesture_data->unique_touch_event_id = gesture_event->unique_touch_event_id; gesture_data->resending_plugin_id = gesture_event->resending_plugin_id; switch (gesture_event->GetType()) {
diff --git a/content/common/input/input_handler.mojom b/content/common/input/input_handler.mojom index b7a8296..45f7aaee 100644 --- a/content/common/input/input_handler.mojom +++ b/content/common/input/input_handler.mojom
@@ -107,6 +107,8 @@ gfx.mojom.PointF screen_position; gfx.mojom.PointF widget_position; GestureDevice source_device; + bool is_source_touch_event_set_non_blocking; + PointerType primary_pointer_type; int32 unique_touch_event_id; int32 resending_plugin_id; gfx.mojom.Size? contact_size;
diff --git a/content/public/app/content_main_delegate.cc b/content/public/app/content_main_delegate.cc index ee57df8..dc7c5034 100644 --- a/content/public/app/content_main_delegate.cc +++ b/content/public/app/content_main_delegate.cc
@@ -5,7 +5,6 @@ #include "content/public/app/content_main_delegate.h" #include "build/build_config.h" - #include "content/public/gpu/content_gpu_client.h" #include "content/public/renderer/content_renderer_client.h" #include "content/public/utility/content_utility_client.h" @@ -61,12 +60,6 @@ const service_manager::Identity& identity, base::CommandLine* command_line) {} -bool ContentMainDelegate::ShouldTerminateServiceManagerOnInstanceQuit( - const service_manager::Identity& identity, - int* exit_code) { - return false; -} - void ContentMainDelegate::OnServiceManagerInitialized( const base::Closure& quit_closure, service_manager::BackgroundServiceManager* service_manager) {}
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h index b31cf6c..177cc9f6 100644 --- a/content/public/app/content_main_delegate.h +++ b/content/public/app/content_main_delegate.h
@@ -9,12 +9,19 @@ #include <string> #include <vector> +#include "base/callback_forward.h" #include "build/build_config.h" #include "content/common/content_export.h" -#include "services/service_manager/background/background_service_manager.h" #include "services/service_manager/embedder/process_type.h" -#include "services/service_manager/public/cpp/identity.h" -#include "services/service_manager/public/cpp/service.h" + +namespace base { +class CommandLine; +} + +namespace service_manager { +class BackgroundServiceManager; +class Identity; +} // namespace service_manager namespace content { @@ -95,13 +102,6 @@ const service_manager::Identity& identity, base::CommandLine* command_line); - // Indicates if the Service Manager should be terminated in response to a - // specific service instance quitting. If this returns |true|, the value in - // |*exit_code| will be returned from the Service Manager's process on exit. - virtual bool ShouldTerminateServiceManagerOnInstanceQuit( - const service_manager::Identity& identity, - int* exit_code); - // Allows the embedder to perform arbitrary initialization within the Service // Manager process immediately before the Service Manager runs its main loop. //
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index d7c965f..6e8d39b 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -73,7 +73,7 @@ "content_plugin": [ "browser" ], "content_renderer": [ "browser" ], "content_utility": [ "browser" ], - "data_decoder": [ "image_decoder" ], + "data_decoder": [ "image_decoder", "json_parser" ], "device": [ "device:battery_monitor", "device:generic_sensor",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 15a13c1..824f0c4 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -373,11 +373,6 @@ return nullptr; } -gpu::GpuChannelEstablishFactory* -ContentBrowserClient::GetGpuChannelEstablishFactory() { - return nullptr; -} - bool ContentBrowserClient::AllowPepperSocketAPI( BrowserContext* browser_context, const GURL& url, @@ -489,6 +484,11 @@ return nullptr; } +bool ContentBrowserClient::ShouldTerminateOnServiceQuit( + const service_manager::Identity& id) { + return false; +} + std::vector<ContentBrowserClient::ServiceManifestInfo> ContentBrowserClient::GetExtraServiceManifests() { return std::vector<ContentBrowserClient::ServiceManifestInfo>();
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 842557d5..9ef3e42e 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -59,10 +59,6 @@ class ImageSkia; } -namespace gpu { -class GpuChannelEstablishFactory; -} - namespace media { class AudioLogFactory; class AudioManager; @@ -612,9 +608,6 @@ virtual BrowserPpapiHost* GetExternalBrowserPpapiHost( int plugin_child_id); - // Gets the factory to use to establish a connection to the GPU process. - virtual gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory(); - // Returns true if the socket operation specified by |params| is allowed from // the given |browser_context| and |url|. If |params| is nullptr, this method // checks the basic "socket" permission, which is for those operations that @@ -742,6 +735,11 @@ // to use for the service's host process when launched. virtual void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) {} + // Allows the embedder to terminate the browser if a specific service instance + // quits or crashes. + virtual bool ShouldTerminateOnServiceQuit( + const service_manager::Identity& id); + // Allow the embedder to provide a dictionary loaded from a JSON file // resembling a service manifest whose capabilities section will be merged // with content's own for |name|. Additional entries will be appended to their
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a6bbc2e..973b08f 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -62,6 +62,7 @@ #include "content/common/edit_command.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/frame_replication_state.h" #include "content/common/input_messages.h" #include "content/common/navigation_params.h" @@ -2310,11 +2311,10 @@ frame_->SetOpener(opener); } -void RenderFrameImpl::OnDidUpdateFramePolicy( - blink::WebSandboxFlags flags, - const ParsedFeaturePolicyHeader& container_policy) { - frame_->SetFrameOwnerPolicy(flags, - FeaturePolicyHeaderToWeb(container_policy)); +void RenderFrameImpl::OnDidUpdateFramePolicy(const FramePolicy& frame_policy) { + frame_->SetFrameOwnerPolicy( + frame_policy.sandbox_flags, + FeaturePolicyHeaderToWeb(frame_policy.container_policy)); } void RenderFrameImpl::OnSetFrameOwnerProperties( @@ -3179,8 +3179,8 @@ // browsing context name, only unique name generation. params.frame_unique_name = unique_name_helper_.GenerateNameForNewChildFrame( params.frame_name.empty() ? fallback_name.Utf8() : params.frame_name); - params.sandbox_flags = sandbox_flags; - params.container_policy = FeaturePolicyHeaderFromWeb(container_policy); + params.frame_policy = {sandbox_flags, + FeaturePolicyHeaderFromWeb(container_policy)}; params.frame_owner_properties = ConvertWebFrameOwnerPropertiesToFrameOwnerProperties( frame_owner_properties); @@ -3319,8 +3319,8 @@ blink::WebSandboxFlags flags, const blink::WebParsedFeaturePolicy& container_policy) { Send(new FrameHostMsg_DidChangeFramePolicy( - routing_id_, RenderFrame::GetRoutingIdForWebFrame(child_frame), flags, - FeaturePolicyHeaderFromWeb(container_policy))); + routing_id_, RenderFrame::GetRoutingIdForWebFrame(child_frame), + {flags, FeaturePolicyHeaderFromWeb(container_policy)})); } void RenderFrameImpl::DidSetFeaturePolicyHeader(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 203f8d2..8d80083 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -161,6 +161,7 @@ struct FileChooserFileInfo; struct FileChooserParams; struct FrameOwnerProperties; +struct FramePolicy; struct FrameReplicationState; struct NavigationParams; struct RequestNavigationParams; @@ -984,9 +985,7 @@ void OnSnapshotAccessibilityTree(int callback_id); void OnExtractSmartClipData(uint32_t callback_id, const gfx::Rect& rect); void OnUpdateOpener(int opener_routing_id); - void OnDidUpdateFramePolicy( - blink::WebSandboxFlags flags, - const ParsedFeaturePolicyHeader& container_policy); + void OnDidUpdateFramePolicy(const FramePolicy& frame_policy); void OnSetFrameOwnerProperties( const FrameOwnerProperties& frame_owner_properties); void OnAdvanceFocus(blink::WebFocusType type, int32_t source_routing_id);
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 01f3be91..4749b0fd 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -16,6 +16,7 @@ #include "content/common/content_switches_internal.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/common/frame_replication_state.h" #include "content/common/input_messages.h" #include "content/common/page_messages.h" @@ -294,12 +295,11 @@ // properly if this proxy ever parents a local frame. The proxy's FrameOwner // flags are also updated here with the caveat that the FrameOwner won't learn // about updates to its flags until they take effect. -void RenderFrameProxy::OnDidUpdateFramePolicy( - blink::WebSandboxFlags flags, - const ParsedFeaturePolicyHeader& container_policy) { - web_frame_->SetReplicatedSandboxFlags(flags); - web_frame_->SetFrameOwnerPolicy(flags, - FeaturePolicyHeaderToWeb(container_policy)); +void RenderFrameProxy::OnDidUpdateFramePolicy(const FramePolicy& frame_policy) { + web_frame_->SetReplicatedSandboxFlags(frame_policy.sandbox_flags); + web_frame_->SetFrameOwnerPolicy( + frame_policy.sandbox_flags, + FeaturePolicyHeaderToWeb(frame_policy.container_policy)); } void RenderFrameProxy::MaybeUpdateCompositingHelper() {
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 96095b413..9200a89 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -35,6 +35,7 @@ class RenderWidget; struct ContentSecurityPolicyHeader; struct FrameOwnerProperties; +struct FramePolicy; struct FrameReplicationState; #if defined(USE_AURA) @@ -185,9 +186,7 @@ void OnUpdateOpener(int opener_routing_id); void OnViewChanged(const viz::FrameSinkId& frame_sink_id); void OnDidStopLoading(); - void OnDidUpdateFramePolicy( - blink::WebSandboxFlags flags, - const ParsedFeaturePolicyHeader& container_policy); + void OnDidUpdateFramePolicy(const FramePolicy& frame_policy); void OnDispatchLoad(); void OnCollapse(bool collapsed); void OnDidUpdateName(const std::string& name, const std::string& unique_name);
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 6b30112d5..e3e6748 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -15,6 +15,7 @@ #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/frame_policy.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/stream_handle.h" #include "content/public/common/browser_side_navigation_policy.h" @@ -29,7 +30,6 @@ #include "third_party/WebKit/public/platform/WebMixedContentContextType.h" #include "third_party/WebKit/public/platform/WebPageVisibilityState.h" #include "third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom.h" -#include "third_party/WebKit/public/web/WebSandboxFlags.h" #include "third_party/WebKit/public/web/WebTreeScopeType.h" #include "ui/base/page_transition_types.h" @@ -98,8 +98,7 @@ OnCreateChildFrame(GetProcess()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, frame_name, frame_unique_name, base::UnguessableToken::Create(), - blink::WebSandboxFlags::kNone, ParsedFeaturePolicyHeader(), - FrameOwnerProperties()); + FramePolicy(), FrameOwnerProperties()); return static_cast<TestRenderFrameHost*>( child_creation_observer_.last_created_frame()); }
diff --git a/device/bluetooth/bluetooth_init_win.h b/device/bluetooth/bluetooth_init_win.h index 3d75b2a5..ee58658 100644 --- a/device/bluetooth/bluetooth_init_win.h +++ b/device/bluetooth/bluetooth_init_win.h
@@ -5,12 +5,15 @@ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_INIT_WIN_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_INIT_WIN_H_ -// windows.h needs to be included before BluetoothAPIs.h. +// windows.h needs to be included before bluetoothapis.h. #include <windows.h> -#include <BluetoothAPIs.h> +#include <bluetoothapis.h> #include <delayimp.h> + +// ws2def.h needs to be included before ws2bth.h. #include <ws2def.h> + #include <ws2bth.h> #include "device/bluetooth/bluetooth_export.h"
diff --git a/docs/win_cross.md b/docs/win_cross.md new file mode 100644 index 0000000..678d4d4 --- /dev/null +++ b/docs/win_cross.md
@@ -0,0 +1,55 @@ +# Cross-compiling Chrome/win + +It's possible to build parts of the codebase on a Linux (and soon, Mac) host +while targeting Windows. This document describes how to set that up, and +current restrictions. + +What does *not* work: + +* goma. Sorry. ([internal bug](b/64390790)) +* targets depending on crashpad ([bug](https://crbug.com/762167)) +* targets using .rc files ([bug](https://crbug.com/774193)) +* linking on Mac ([bug](https://crbug.com/774209)), should change soon + +This disqualifies most interesting targets for now, but a few smaller ones +(`base_unittests`, ...) do work. Over time, more things should work. + +## .gclient setup + +1. Tell gclient that you need Windows build dependencies by adding + `target_os = ['win']` to the end of your `.gclient`. (If you already + have a `target_os` line in there, just add `'win'` to the list.) +1. `gclient sync`, follow instructions on screen. + +If you're at Google, this will automatically download the Windows SDK for you. +If you are not at Google, you'll have to figure out how to get the SDK, and +you'll need to put a JSON file describing the SDK layout in a certain location. + +# GN setup + +Add `target_os = "win"` to your args.gn. Then just build, e.g. + + ninja -C out/gnwin base_unittests.exe + +# Running tests on swarming + +You can run the Windows binaries you built on swarming, like so: + + tools/mb/mb.py isolate //out/gnwin base_unittests + tools/swarming_client/isolate.py archive \ + -I https://isolateserver.appspot.com \ + -i out/gnwin/base_unittests.isolate \ + -s out/gnwin/base_unittests.isolated + tools/swarming_client/swarming.py trigger \ + -S https://chromium-swarm.appspot.com \ + -I https://isolateserver.appspot.com \ + -d os Windows -d pool Chrome -s <hash printed by previous command> + +Most tests that build should pass. However, the cross build uses +the lld linker, and a couple of tests fail when using lld. You can look at +https://build.chromium.org/p/chromium.clang/builders/CrWinClangLLD%20tester +to get an idea of which tests fail with lld. + +TODO(thakis): It'd be nice if there was a script for doing this. Maybe make +tools/fuchsa/run-swarmed.py work for win cross builds too, or create +`run_base_unittests` script targets during the build (like Android).
diff --git a/extensions/README.md b/extensions/README.md index db752871..d04c5a9 100644 --- a/extensions/README.md +++ b/extensions/README.md
@@ -13,3 +13,5 @@ * [Features System](/chrome/common/extensions/api/_features.md) * [Bindings System](/extensions/renderer/bindings.md) + +* [Extension events](/extensions/common/events.md)
diff --git a/extensions/browser/extension_system.h b/extensions/browser/extension_system.h index fe42fc2..36804a78 100644 --- a/extensions/browser/extension_system.h +++ b/extensions/browser/extension_system.h
@@ -46,6 +46,9 @@ // their own right. class ExtensionSystem : public KeyedService { public: + // A callback to be executed when InstallUpdate finishes. + using InstallUpdateCallback = base::OnceCallback<void(bool success)>; + ExtensionSystem(); ~ExtensionSystem() override; @@ -125,11 +128,11 @@ const Extension* extension) = 0; // Install an updated version of |extension_id| with the version given in - // temp_dir. Ownership of |temp_dir| in the filesystem is transferred and - // implementors of this function are responsible for cleaning it up on - // errors, etc. + // |unpacked_dir|. Ownership of |unpacked_dir| in the filesystem is + // transferred and implementors of this function are responsible for cleaning + // it up on errors, etc. virtual void InstallUpdate(const std::string& extension_id, - const base::FilePath& temp_dir) = 0; + const base::FilePath& unpacked_dir) = 0; }; } // namespace extensions
diff --git a/extensions/docs/events.md b/extensions/docs/events.md new file mode 100644 index 0000000..96a9940 --- /dev/null +++ b/extensions/docs/events.md
@@ -0,0 +1,124 @@ +# Extension events + +The Chrome extensions system has its own implementation of events (typically +exposed as `chrome.<api>.onFoo`, e.g. `chrome.tabs.onUpdated`). This doc +provides some notes about its implementation, specifically how event listeners +are registered and how they are dispatched. + +## High level overview of extension event dispatching + +An event listener registered in the renderer process is sent to the browser +process (via IPC). The browser process stores the listener information in +`EventListenerMap`. Events are dispatched from the browser process to the +renderer process via IPC. If browser process requires to persist any listener, +it does so by storing the listener information in the prefs. + +## Relevant concepts + +* __Listener contexts__: +Typically denotes the page/script where the listener is registered from, e.g. +an extension's background page or an extension's service worker script. + +* __Lazy contexts__: +Contexts that are not persistent and typically shut down when inactive, e.g. an +event page's background script or an extension service worker script. Non-lazy +contexts are often called "persistent" contexts. + +* __Persistent listeners / Non-lazy listeners__: +Listeners from contexts that are not lazy. + +* __Lazy listeners__: +Listeners from lazy context. +See the scenario description (_Case 1_ and _Case 2_) below for quick explanation +of how registration of a listener from a lazy context can result in two (a lazy +and a non-lazy) listeners. An event can be dispatched to these listeners while +the corresponding lazy context is not running. + +* __Filtered events__: +A listener can specify additional matching criterea that we call event filters. +Some events support filters. IPCs (along with most but not all of the browser/ +or renderer/ code) use `DictionaryValue` to represent an event filter. + + +## Event listener registration + +Event listeners are registered in JavaScript in the renderer process. The +event bindings code handles this registration and the browser process is made +aware of it via IPC. + +In particular, a message filter (`ExtensionMessageFilter`) receives event +registration IPCs and it passes them to `EventRouter` to be stored in +`EventListenerMap`. If the listener is required to be persisted (for lazy +events), they are also recorded in `ExtensionPrefs`. + +Note that when the renderer context is shut down, it removes the listener. The +exception is lazy event listener, which is not removed. + + +### Additional notes about lazy listeners + +When a lazy listener is added for an event, a regular (non-lazy) listener +(call it `L1`) is added for it and in addition to that, a lazy variant of the +listener (call it `L2`) is also added. `L2` helps browser process remember that +the listener should be persisted and it should have lazy behavior. + +## Event dispatching + +`EventRouter` is responsible for dispatching events from the browser process. +When an event is required to be dispatched, `EventRouter` fetches EventListeners +from `EventListenerMap` and dispatches them to appropriate contexts (renderer +or service worker scripts) + +### Additional notes about lazy event dispatching + +Recall that a lazy listener is like a regular listeners, except that it is +registered from a lazy context. A lazy context can be shut down. If an +interesting event ocurrs while a lazy context (with a listener to that event) +is no longer running, then the lazy context is woken up to dispatch the event. + +The following (simplified) steps describe how dispatch is performed. + +#### Case 1: Event dispatched while context (lazy or non-lazy) is running + +* Because `EventListenerMap` will contain an entry for the listener (`L1`), it +will dispatch the event in normal fashion: by sending an IPC to the renderer +through `ExtensionMessageFilter`. + +#### Case 2: Event dispatched while (lazy) context is not running + +* If the context is not running, then `EventListenerMap` will not have any entry +for `L1` (because context shutdown will remove `L1`), but it will have an entry +for the lazy version of it, `L2`. Note that `L2` will exist even if the browser +process is restarted, `EventRouter::OnExtensionLoaded` will have loaded these +lazy events through `EventListenerMap::Load(Un)FilteredLazyListeners`. + +* Realize that `L2` is lazy, so wake up its lazy context. Waking up an event +page context entails spinning up its background page, while waking up a service +worker context means starting the service worker. + +* The lazy context will register `L1` and `L2` again, because the same code that +added the initial listeners will run again. This is an important step that +isn't intuitive. Note that `L2`, since it already exists in the browser process, +is not re-added. + +* Dispatch `L1` (same as _Case 1_ above). + +## Notes about extension service worker (ESW) events + +* ESW events behave similar to event page events, i.e. lazy events. + +* ESW events are registered from worker threads, instead of main renderer +threads. + +* Similarly, event dispatch target is worker thread instead of main renderer +thread. Therefore, at dispatch time, browser process knows about the worker +thread +id in a RenderProcessHost. This is why worker event listener IPCs have +`worker_thread_id` param in them. + +## TODOs + +* Explain filters a bit more, where filter matching is performed and how much of +it lives in the renderer/ process. + +* Describe what "manual" removal of event listeners means.
diff --git a/google_apis/google_api_keys.cc b/google_apis/google_api_keys.cc index 1ba1d296..2e8437ed 100644 --- a/google_apis/google_api_keys.cc +++ b/google_apis/google_api_keys.cc
@@ -360,8 +360,4 @@ #endif } -bool IsClientIdOverridden() { - return GetOAuth2ClientID(CLIENT_MAIN) != GOOGLE_CLIENT_ID_MAIN; -} - } // namespace google_apis
diff --git a/google_apis/google_api_keys.h b/google_apis/google_api_keys.h index b99112e..20d896e 100644 --- a/google_apis/google_api_keys.h +++ b/google_apis/google_api_keys.h
@@ -120,9 +120,6 @@ // Google Chrome. bool IsGoogleChromeAPIKeyUsed(); -// Returns true if client id is overridden. -bool IsClientIdOverridden(); - } // namespace google_apis #endif // GOOGLE_APIS_GOOGLE_API_KEYS_H_
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm index aa43043..3648802d 100644 --- a/ios/chrome/browser/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -194,83 +194,4 @@ [ChromeEarlGrey waitForMainTabCount:2]; } -// Tests "Open in New Tab" on context menu on a link that requires scrolling -// on the page to verify that context menu can be properly triggered in the -// current screen view. -- (void)testContextMenuOpenInNewTabFromTallPage { -// TODO(crbug.com/755888): Reenable this test. - if (!IsIPadIdiom()) { - EARL_GREY_TEST_DISABLED(@"Failing constently on iPhone devices."); - } - - // Set up test simple http server. - std::map<GURL, std::string> responses; - GURL initialURL = - web::test::HttpServer::MakeUrl("http://scenarioContextMenuOpenInNewTab"); - GURL destinationURL = web::test::HttpServer::MakeUrl("http://destination"); - - // The initial page contains a link to the destination page that is below a - // really tall div so that scrolling is required. - responses[initialURL] = - "<div style='height:4000px'></div>" - "<a style='margin-left:50px' href='" + - destinationURL.spec() + "' id='link'>link</a>"; - responses[destinationURL] = kDestinationHtml; - - web::test::SetUpSimpleHttpServer(responses); - [ChromeEarlGrey loadURL:initialURL]; - [ChromeEarlGrey waitForMainTabCount:1]; - - // Scroll down on the web view to make the link visible. - // grey_swipeFastInDirecton will quickly scroll towards the bottom, and then - // grey_scrollToContentEdge guarantees the content edge is reached. Two - // methods are used because the first one is much faster, but doesn't - // guarantee the link becomes visible. - // TODO(crbug.com/702272): Try to replace this with one EarlGrey method call. - [[EarlGrey - selectElementWithMatcher:WebViewScrollView( - chrome_test_util::GetCurrentWebState())] - performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; - [[EarlGrey - selectElementWithMatcher:WebViewScrollView( - chrome_test_util::GetCurrentWebState())] - performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; - - [ChromeEarlGrey waitForWebViewContainingText:kDestinationLinkID]; - - LongPressElementAndTapOnButton(kDestinationLinkID, OpenLinkInNewTabButton()); - - // Earl Grey cannot preperly synchronize some animations, so adding a - // WaitUntilCondition to wait for the new tab opening animation to finish - // and the scroll view to become interactable. - ConditionBlock condition = ^{ - NSError* error = nil; - [[EarlGrey - selectElementWithMatcher:WebViewScrollView( - chrome_test_util::GetCurrentWebState())] - assertWithMatcher:grey_interactable() - error:&error]; - return !error; - }; - GREYAssert(testing::WaitUntilConditionOrTimeout( - testing::kWaitForUIElementTimeout, condition), - @"Web view did not become interactable"); - - // Make the toolbar visible by scrolling up on the web view to select the - // newly opened tab. - [[EarlGrey - selectElementWithMatcher:WebViewScrollView( - chrome_test_util::GetCurrentWebState())] - performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; - [ChromeEarlGreyUI waitForToolbarVisible:YES]; - - SelectTabAtIndexInCurrentMode(1U); - - // Verify url and tab count. - [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( - destinationURL.GetContent())] - assertWithMatcher:grey_notNil()]; - [ChromeEarlGrey waitForMainTabCount:2]; -} - @end
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder.h b/ios/chrome/browser/metrics/tab_usage_recorder.h index b00b5f7..8bef4bd 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder.h +++ b/ios/chrome/browser/metrics/tab_usage_recorder.h
@@ -124,38 +124,41 @@ ~TabUsageRecorder() override; // Called during startup when the tab model is created, or shortly after a - // post-crash launch if the tabs are restored. |tabs| is an array containing - // the tabs being restored in the current tab model. |active_tab| is the tab - // currently in the foreground. - void InitialRestoredTabs(web::WebState* active_tab, - const std::vector<web::WebState*>& tabs); + // post-crash launch if the tabs are restored. |web_states| is an array + // containing/ the tabs being restored in the current tab model. + // |active_web_state| is the tab currently in the foreground. + void InitialRestoredTabs(web::WebState* active_web_state, + const std::vector<web::WebState*>& web_states); // Called when a tab switch is made. Determines what value to record, and // when to reset the page load counter. - void RecordTabSwitched(web::WebState* old_tab, web::WebState* new_tab); + void RecordTabSwitched(web::WebState* old_web_state, + web::WebState* new_web_state); // Called when the tab model which the user is primarily interacting with has - // changed. The |active_tab| is the current tab of the tab model. If the user - // began interacting with |active_tab|, |primary| should be true. If the user - // stopped interacting with |active_tab|, |primary| should be false. - void RecordPrimaryTabModelChange(bool primary, web::WebState* active_tab); + // changed. The |active_web_state| is the current tab of the tab model. If the + // user began interacting with |active_web_state|, |primary_tab_model| should + // be true. If the user stopped interacting with |active_web_state|, + // |primary_tab_model| should be false. + void RecordPrimaryTabModelChange(bool primary_tab_model, + web::WebState* active_web_state); // Called when a page load begins, to keep track of how many page loads // happen before an evicted tab is seen. - void RecordPageLoadStart(web::WebState* tab); + void RecordPageLoadStart(web::WebState* web_state); // Called when a page load finishes, to track the load time for evicted tabs. - void RecordPageLoadDone(web::WebState* tab, bool success); + void RecordPageLoadDone(web::WebState* web_state, bool success); // Called when there is a user-initiated reload. - void RecordReload(web::WebState* tab); + void RecordReload(web::WebState* web_state); // Called when WKWebView's renderer is terminated. |tab| contains the tab // whose renderer was terminated, |tab_visible| indicates whether or not // the tab was visible when the renderer terminated and |application_active| // indicates whether the application was in the foreground or background. - void RendererTerminated(web::WebState* tab, - bool tab_visible, + void RendererTerminated(web::WebState* web_state, + bool web_state_visible, bool application_active); // Called when the app has been backgrounded. @@ -167,7 +170,7 @@ // Resets the page load count. void ResetPageLoads(); - // Size of |evicted_tabs_|. Used for testing. + // Size of |evicted_web_states_|. Used for testing. int EvictedTabsMapSize(); // Resets all tracked data. Used for testing. @@ -187,20 +190,20 @@ void ResetEvictedTab(); // Whether or not a tab can be disregarded by the metrics. - bool ShouldIgnoreTab(web::WebState* tab); + bool ShouldIgnoreWebState(web::WebState* web_state); // Whether or not the tab has already been evicted. - bool TabAlreadyEvicted(web::WebState* tab); + bool WebStateAlreadyEvicted(web::WebState* web_state); // Returns the state of the given tab. Call only once per tab, as it removes - // the tab from |evicted_tabs_|. - TabStateWhenSelected ExtractTabState(web::WebState* tab); + // the tab from |evicted_web_states_|. + TabStateWhenSelected ExtractWebStateState(web::WebState* web_state); // Records various time metrics when a restore of an evicted tab begins. void RecordRestoreStartTime(); // Returns the number of WebState that are still alive (in-memory). - int GetLiveTabsCount() const; + int GetLiveWebStatesCount() const; // Called after a WebState is added to the WebStateList; will create the // observer used to track the WebState's events. @@ -242,26 +245,26 @@ // Keep track of the current tab, but only if it has been evicted. // This is kept as a pointer value only - it should never be dereferenced. - web::WebState* evicted_tab_ = nullptr; + web::WebState* evicted_web_state_ = nullptr; - // State of |evicted_tab_| at the time it became the current tab. - TabStateWhenSelected evicted_tab_state_ = IN_MEMORY; + // State of |evicted_web_state_| at the time it became the current tab. + TabStateWhenSelected evicted_web_state_state_ = IN_MEMORY; // Keep track of the tab last selected when this tab model was switched // away from to another mode (e.g. to incognito). // Kept as a pointer value only - it should never be dereferenced. - web::WebState* mode_switch_tab_ = nullptr; + web::WebState* mode_switch_web_state_ = nullptr; // Keep track of a tab that was created to be immediately selected. It should // not contribute to the "StatusWhenSwitchedBackToForeground" metric. - web::WebState* tab_created_selected_ = nullptr; + web::WebState* web_state_created_selected_ = nullptr; // Keep track of when the evicted tab starts to reload, so that the total // time it takes to reload can be recorded. - base::TimeTicks evicted_tab_reload_start_time_; + base::TimeTicks evicted_web_state_reload_start_time_; // Keep track of the tabs that have a known eviction cause. - std::map<web::WebState*, TabStateWhenSelected> evicted_tabs_; + std::map<web::WebState*, TabStateWhenSelected> evicted_web_states_; // Maps WebStates to the WebStateObserver used to track its events. std::map<web::WebState*, std::unique_ptr<WebStateObserver>>
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder.mm b/ios/chrome/browser/metrics/tab_usage_recorder.mm index 2351c64..db25611 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder.mm
@@ -167,8 +167,8 @@ } void TabUsageRecorder::InitialRestoredTabs( - web::WebState* active_tab, - const std::vector<web::WebState*>& tabs) { + web::WebState* active_web_state, + const std::vector<web::WebState*>& web_states) { #if !defined(NDEBUG) // Debugging check to ensure this is called at most once per run. // Specifically, this function is called in either of two cases: @@ -188,97 +188,99 @@ // Do not set eviction reason on active tab since it will be reloaded without // being processed as a switch to the foreground tab. - for (web::WebState* web_state : tabs) { - if (web_state != active_tab) { - evicted_tabs_[web_state] = EVICTED_DUE_TO_COLD_START; + for (web::WebState* web_state : web_states) { + if (web_state != active_web_state) { + evicted_web_states_[web_state] = EVICTED_DUE_TO_COLD_START; } } } -void TabUsageRecorder::RecordTabSwitched(web::WebState* old_tab, - web::WebState* new_tab) { +void TabUsageRecorder::RecordTabSwitched(web::WebState* old_web_state, + web::WebState* new_web_state) { // If a tab was created to be selected, and is selected shortly thereafter, // it should not add its state to the "kSelectedTabHistogramName" metric. - // |tab_created_selected_| is reset at the first tab switch seen after it was - // created, regardless of whether or not it was the tab selected. - const bool was_just_created = new_tab == tab_created_selected_; - tab_created_selected_ = nullptr; + // |web_state_created_selected_| is reset at the first tab switch seen after + // it was created, regardless of whether or not it was the tab selected. + const bool was_just_created = new_web_state == web_state_created_selected_; + web_state_created_selected_ = nullptr; // Disregard reselecting the same tab, but only if the mode has not changed // since the last time this tab was selected. I.e. going to incognito and // back to normal mode is an event we want to track, but simply going into // stack view and back out, without changing modes, isn't. - if (new_tab == old_tab && new_tab != mode_switch_tab_) + if (new_web_state == old_web_state && new_web_state != mode_switch_web_state_) return; - mode_switch_tab_ = nullptr; + mode_switch_web_state_ = nullptr; // Disregard opening a new tab with no previous tab. Or closing the last tab. - if (!old_tab || !new_tab) + if (!old_web_state || !new_web_state) return; - // Before knowledge of the previous tab, |old_tab|, is lost, see if it is a - // previously-evicted tab still reloading. If it is, record that the + // Before knowledge of the previous tab, |old_web_state|, is lost, see if it + // is a previously-evicted tab still reloading. If it is, record that the // user did not wait for the evicted tab to finish reloading. - if (old_tab == evicted_tab_ && old_tab != new_tab && - evicted_tab_reload_start_time_ != base::TimeTicks()) { + if (old_web_state == evicted_web_state_ && old_web_state != new_web_state && + evicted_web_state_reload_start_time_ != base::TimeTicks()) { UMA_HISTOGRAM_ENUMERATION(kDidUserWaitForEvictedTabReload, USER_DID_NOT_WAIT, USER_BEHAVIOR_COUNT); } ResetEvictedTab(); - if (ShouldIgnoreTab(new_tab) || was_just_created) + if (ShouldIgnoreWebState(new_web_state) || was_just_created) return; // Should never happen. Keeping the check to ensure that the prerender logic // is never overlooked, should behavior at the tab_model level change. DCHECK(!prerender_service_ || - !prerender_service_->IsWebStatePrerendered(new_tab)); + !prerender_service_->IsWebStatePrerendered(new_web_state)); - TabStateWhenSelected tab_state = ExtractTabState(new_tab); - if (tab_state != IN_MEMORY) { + TabStateWhenSelected web_state_state = ExtractWebStateState(new_web_state); + if (web_state_state != IN_MEMORY) { // Keep track of the current 'evicted' tab. - evicted_tab_ = new_tab; - evicted_tab_state_ = tab_state; + evicted_web_state_ = new_web_state; + evicted_web_state_state_ = web_state_state; UMA_HISTOGRAM_COUNTS(kPageLoadsBeforeEvictedTabSelected, page_loads_); ResetPageLoads(); } - UMA_HISTOGRAM_ENUMERATION(kSelectedTabHistogramName, tab_state, + UMA_HISTOGRAM_ENUMERATION(kSelectedTabHistogramName, web_state_state, TAB_STATE_COUNT); } -void TabUsageRecorder::RecordPrimaryTabModelChange(bool primary_tab_model, - web::WebState* active_tab) { +void TabUsageRecorder::RecordPrimaryTabModelChange( + bool primary_tab_model, + web::WebState* active_web_state) { if (primary_tab_model) { // User just came back to this tab model, so record a tab selection even // though the current tab was reselected. - if (mode_switch_tab_ == active_tab) - RecordTabSwitched(active_tab, active_tab); + if (mode_switch_web_state_ == active_web_state) + RecordTabSwitched(active_web_state, active_web_state); } else { // Keep track of the selected tab when this tab model is moved to // background. This way when the tab model is moved to the foreground, and // the current tab reselected, it is handled as a tab selection rather than // a no-op. - mode_switch_tab_ = active_tab; + mode_switch_web_state_ = active_web_state; } } -void TabUsageRecorder::RecordPageLoadStart(web::WebState* tab) { - if (!ShouldIgnoreTab(tab)) { +void TabUsageRecorder::RecordPageLoadStart(web::WebState* web_state) { + if (!ShouldIgnoreWebState(web_state)) { page_loads_++; - if (tab->IsEvicted()) { + if (web_state->IsEvicted()) { // On the iPad, there is no notification that a tab is being re-selected // after changing modes. This catches the case where the pre-incognito // selected tab is selected again when leaving incognito mode. - if (mode_switch_tab_ == tab) - RecordTabSwitched(tab, tab); - if (evicted_tab_ == tab) + if (mode_switch_web_state_ == web_state) + RecordTabSwitched(web_state, web_state); + if (evicted_web_state_ == web_state) RecordRestoreStartTime(); } } else { // If there is a currently-evicted tab reloading, make sure it is recorded // that the user did not wait for it to load. - if (evicted_tab_ && evicted_tab_reload_start_time_ != base::TimeTicks()) { + if (evicted_web_state_ && + evicted_web_state_reload_start_time_ != base::TimeTicks()) { UMA_HISTOGRAM_ENUMERATION(kDidUserWaitForEvictedTabReload, USER_DID_NOT_WAIT, USER_BEHAVIOR_COUNT); } @@ -286,14 +288,15 @@ } } -void TabUsageRecorder::RecordPageLoadDone(web::WebState* tab, bool success) { - if (!tab) +void TabUsageRecorder::RecordPageLoadDone(web::WebState* web_state, + bool success) { + if (!web_state) return; - if (tab == evicted_tab_) { + if (web_state == evicted_web_state_) { if (success) { LOCAL_HISTOGRAM_TIMES( kEvictedTabReloadTime, - base::TimeTicks::Now() - evicted_tab_reload_start_time_); + base::TimeTicks::Now() - evicted_web_state_reload_start_time_); } UMA_HISTOGRAM_ENUMERATION(kEvictedTabReloadSuccessRate, success ? LOAD_SUCCESS : LOAD_FAILURE, @@ -305,29 +308,30 @@ } } -void TabUsageRecorder::RecordReload(web::WebState* tab) { - if (!ShouldIgnoreTab(tab)) { +void TabUsageRecorder::RecordReload(web::WebState* web_state) { + if (!ShouldIgnoreWebState(web_state)) { page_loads_++; } } -void TabUsageRecorder::RendererTerminated(web::WebState* terminated_tab, - bool tab_visible, +void TabUsageRecorder::RendererTerminated(web::WebState* terminated_web_state, + bool web_state_visible, bool application_active) { // Log the tab state for the termination. - const RendererTerminationTabState tab_state = - application_active ? (tab_visible ? FOREGROUND_TAB_FOREGROUND_APP - : BACKGROUND_TAB_FOREGROUND_APP) - : (tab_visible ? FOREGROUND_TAB_BACKGROUND_APP - : BACKGROUND_TAB_BACKGROUND_APP); + const RendererTerminationTabState web_state_state = + application_active ? (web_state_visible ? FOREGROUND_TAB_FOREGROUND_APP + : BACKGROUND_TAB_FOREGROUND_APP) + : (web_state_visible ? FOREGROUND_TAB_BACKGROUND_APP + : BACKGROUND_TAB_BACKGROUND_APP); UMA_HISTOGRAM_ENUMERATION(kRendererTerminationStateHistogram, - static_cast<int>(tab_state), + static_cast<int>(web_state_state), static_cast<int>(TERMINATION_TAB_STATE_COUNT)); - if (!tab_visible) { - DCHECK(!TabAlreadyEvicted(terminated_tab)); - evicted_tabs_[terminated_tab] = EVICTED_DUE_TO_RENDERER_TERMINATION; + if (!web_state_visible) { + DCHECK(!WebStateAlreadyEvicted(terminated_web_state)); + evicted_web_states_[terminated_web_state] = + EVICTED_DUE_TO_RENDERER_TERMINATION; } base::TimeTicks now = base::TimeTicks::Now(); termination_timestamps_.push_back(now); @@ -341,9 +345,10 @@ saw_memory_warning); // Log number of live tabs after the renderer termination. This count does not - // include |terminated_tab|. - int live_tabs_count = GetLiveTabsCount(); - UMA_HISTOGRAM_COUNTS_100(kRendererTerminationAliveRenderers, live_tabs_count); + // include |terminated_web_state|. + int live_web_states_count = GetLiveWebStatesCount(); + UMA_HISTOGRAM_COUNTS_100(kRendererTerminationAliveRenderers, + live_web_states_count); // Clear |termination_timestamps_| of timestamps older than // |kSecondsBeforeRendererTermination| ago. @@ -356,17 +361,18 @@ // Log number of recently alive tabs, where recently alive is defined to mean // alive within the past |kSecondsBeforeRendererTermination|. - NSUInteger recently_live_tabs_count = - live_tabs_count + termination_timestamps_.size(); + NSUInteger recently_live_web_states_count = + live_web_states_count + termination_timestamps_.size(); UMA_HISTOGRAM_COUNTS_100(kRendererTerminationRecentlyAliveRenderers, - recently_live_tabs_count); + recently_live_web_states_count); } void TabUsageRecorder::AppDidEnterBackground() { base::TimeTicks time_now = base::TimeTicks::Now(); LOCAL_HISTOGRAM_TIMES(kTimeAfterLastRestore, time_now - restore_start_time_); - if (evicted_tab_ && evicted_tab_reload_start_time_ != base::TimeTicks()) { + if (evicted_web_state_ && + evicted_web_state_reload_start_time_ != base::TimeTicks()) { UMA_HISTOGRAM_ENUMERATION(kDidUserWaitForEvictedTabReload, USER_LEFT_CHROME, USER_BEHAVIOR_COUNT); ResetEvictedTab(); @@ -382,52 +388,52 @@ } int TabUsageRecorder::EvictedTabsMapSize() { - return evicted_tabs_.size(); + return evicted_web_states_.size(); } void TabUsageRecorder::ResetAll() { ResetEvictedTab(); ResetPageLoads(); - evicted_tabs_.clear(); + evicted_web_states_.clear(); } void TabUsageRecorder::ResetEvictedTab() { - evicted_tab_ = nullptr; - evicted_tab_state_ = IN_MEMORY; - evicted_tab_reload_start_time_ = base::TimeTicks(); + evicted_web_state_ = nullptr; + evicted_web_state_state_ = IN_MEMORY; + evicted_web_state_reload_start_time_ = base::TimeTicks(); } -bool TabUsageRecorder::ShouldIgnoreTab(web::WebState* tab) { +bool TabUsageRecorder::ShouldIgnoreWebState(web::WebState* web_state) { // Do not count chrome:// urls to avoid data noise. For example, if they were // counted, every new tab created would add noise to the page load count. web::NavigationItem* pending_item = - tab->GetNavigationManager()->GetPendingItem(); + web_state->GetNavigationManager()->GetPendingItem(); if (pending_item) return pending_item->GetURL().SchemeIs(kChromeUIScheme); web::NavigationItem* last_committed_item = - tab->GetNavigationManager()->GetLastCommittedItem(); + web_state->GetNavigationManager()->GetLastCommittedItem(); if (last_committed_item) return last_committed_item->GetVirtualURL().SchemeIs(kChromeUIScheme); return false; } -bool TabUsageRecorder::TabAlreadyEvicted(web::WebState* tab) { - auto iter = evicted_tabs_.find(tab); - return iter != evicted_tabs_.end(); +bool TabUsageRecorder::WebStateAlreadyEvicted(web::WebState* web_state) { + auto iter = evicted_web_states_.find(web_state); + return iter != evicted_web_states_.end(); } -TabUsageRecorder::TabStateWhenSelected TabUsageRecorder::ExtractTabState( - web::WebState* tab) { - if (!tab->IsEvicted()) +TabUsageRecorder::TabStateWhenSelected TabUsageRecorder::ExtractWebStateState( + web::WebState* web_state) { + if (!web_state->IsEvicted()) return IN_MEMORY; - auto iter = evicted_tabs_.find(tab); - if (iter != evicted_tabs_.end()) { - TabStateWhenSelected tab_state = iter->second; - evicted_tabs_.erase(iter); - return tab_state; + auto iter = evicted_web_states_.find(web_state); + if (iter != evicted_web_states_.end()) { + TabStateWhenSelected web_state_state = iter->second; + evicted_web_states_.erase(iter); + return web_state_state; } return EVICTED; @@ -438,10 +444,10 @@ // Record the time delta since the last eviction reload was seen. LOCAL_HISTOGRAM_TIMES(kTimeBetweenRestores, time_now - restore_start_time_); restore_start_time_ = time_now; - evicted_tab_reload_start_time_ = time_now; + evicted_web_state_reload_start_time_ = time_now; } -int TabUsageRecorder::GetLiveTabsCount() const { +int TabUsageRecorder::GetLiveWebStatesCount() const { int count = 0; for (int index = 0; index < web_state_list_->count(); ++index) { if (!web_state_list_->GetWebStateAt(index)->IsEvicted()) @@ -458,18 +464,18 @@ } void TabUsageRecorder::OnWebStateDestroyed(web::WebState* web_state) { - if (web_state == tab_created_selected_) - tab_created_selected_ = nullptr; + if (web_state == web_state_created_selected_) + web_state_created_selected_ = nullptr; - if (web_state == evicted_tab_) - evicted_tab_ = nullptr; + if (web_state == evicted_web_state_) + evicted_web_state_ = nullptr; - if (web_state == mode_switch_tab_) - mode_switch_tab_ = nullptr; + if (web_state == mode_switch_web_state_) + mode_switch_web_state_ = nullptr; - auto evicted_tabs_iter = evicted_tabs_.find(web_state); - if (evicted_tabs_iter != evicted_tabs_.end()) - evicted_tabs_.erase(evicted_tabs_iter); + auto evicted_web_states_iter = evicted_web_states_.find(web_state); + if (evicted_web_states_iter != evicted_web_states_.end()) + evicted_web_states_.erase(evicted_web_states_iter); auto web_state_observers_iter = web_state_observers_.find(web_state); if (web_state_observers_iter != web_state_observers_.end()) @@ -481,7 +487,7 @@ int index, bool activating) { if (activating) - tab_created_selected_ = web_state; + web_state_created_selected_ = web_state; OnWebStateInserted(web_state); }
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 73bd6d0..d9262d9 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -178,9 +178,6 @@ OpenInController* _openInController; - // Whether or not this tab is currently being displayed. - BOOL _visible; - // Holds entries that need to be added to the history DB. Prerender tabs do // not write navigation data to the history DB. Instead, they cache history // data in this vector and add it to the DB when the prerender status is @@ -1306,8 +1303,9 @@ } - (void)renderProcessGoneForWebState:(web::WebState*)webState { + DCHECK(webState == _webStateImpl); UIApplicationState state = [UIApplication sharedApplication].applicationState; - if (_visible && state == UIApplicationStateActive) { + if (webState->IsVisible() && state == UIApplicationStateActive) { [_fullScreenController disableFullScreen]; } [self.dialogDelegate cancelDialogForTab:self]; @@ -1389,14 +1387,12 @@ } - (void)wasShown { - _visible = YES; [self updateFullscreenWithToolbarVisible:YES]; if (self.webState) self.webState->WasShown(); } - (void)wasHidden { - _visible = NO; [self updateFullscreenWithToolbarVisible:YES]; if (self.webState) self.webState->WasHidden();
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm index b275058..8d3772d 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
@@ -184,8 +184,7 @@ // call. The cached value is reset when the webview proxy is set. @property(nonatomic, readonly) CGFloat initialHeaderInset; // Initial height of the header view. -// This property is set from the delegate headerHeight and cached on first -// call. The cached value is reset when the webview proxy is set. +// This property is set everytime the user starts pulling. @property(nonatomic, readonly) CGFloat initialHeaderHeight; // Redefined to be read-write. @property(nonatomic, assign, readwrite) OverscrollState overscrollState; @@ -348,6 +347,7 @@ // Set the contentInset to remove the bounce that would fight with drag. [self setScrollViewContentInset:insets]; [self scrollView].scrollIndicatorInsets = insets; + _initialHeaderHeight = [[self delegate] overscrollHeaderHeight]; self.overscrollState = OverscrollState::STARTED_PULLING; } [self updateWithVerticalOffset:-contentOffsetFromExpandedHeader]; @@ -511,7 +511,6 @@ controller:(CRWWebController*)webController { DCHECK([webViewProxy scrollViewProxy]); _initialHeaderInset = 0; - _initialHeaderHeight = 0; _webViewProxy = webViewProxy; [_webViewScrollViewProxy removeObserver:self]; _webViewScrollViewProxy = [webViewProxy scrollViewProxy]; @@ -819,13 +818,6 @@ return _initialHeaderInset; } -- (CGFloat)initialHeaderHeight { - if (_initialHeaderHeight == 0) { - _initialHeaderHeight = [[self delegate] overscrollHeaderHeight]; - } - return _initialHeaderHeight; -} - #pragma mark - Bounce dynamic - (void)startBounceWithInitialVelocity:(CGPoint)velocity {
diff --git a/ios/chrome/browser/ui/webui/web_ui_egtest.mm b/ios/chrome/browser/ui/webui/web_ui_egtest.mm index 9363400..98068a4 100644 --- a/ios/chrome/browser/ui/webui/web_ui_egtest.mm +++ b/ios/chrome/browser/ui/webui/web_ui_egtest.mm
@@ -108,9 +108,9 @@ [ChromeEarlGrey waitForWebViewContainingText:pageTitle]; } -// Tests that clicking on a link for a native page from chrome://chrome-urls -// navigates to that page. -- (void)testChromeURLNavigateToNativePage { +// Tests that clicking on a chrome://terms link from chrome://chrome-urls +// navigates to terms page. +- (void)testChromeURLNavigateToTerms { LoadWebUIUrl(kChromeUIChromeURLsHost); // Tap on chrome://terms link on the page.
diff --git a/ios/third_party/ochamcrest/BUILD.gn b/ios/third_party/ochamcrest/BUILD.gn index 815a85d..7b99321e 100644 --- a/ios/third_party/ochamcrest/BUILD.gn +++ b/ios/third_party/ochamcrest/BUILD.gn
@@ -29,6 +29,8 @@ "src/Source/Core/Helpers/HCInvocationMatcher.m", "src/Source/Core/Helpers/HCRequireNonNilObject.h", "src/Source/Core/Helpers/HCRequireNonNilObject.m", + "src/Source/Core/Helpers/HCRunloopRunner.h", + "src/Source/Core/Helpers/HCRunloopRunner.m", "src/Source/Core/Helpers/HCWrapInMatcher.h", "src/Source/Core/Helpers/HCWrapInMatcher.m", "src/Source/Core/Helpers/NSInvocation+OCHamcrest.h", @@ -147,10 +149,10 @@ "src/Source/Library/Object/HCIsTypeOf.m", "src/Source/Library/Object/HCThrowsException.h", "src/Source/Library/Object/HCThrowsException.m", + "src/Source/Library/Text/HCIsEqualCompressingWhiteSpace.h", + "src/Source/Library/Text/HCIsEqualCompressingWhiteSpace.m", "src/Source/Library/Text/HCIsEqualIgnoringCase.h", "src/Source/Library/Text/HCIsEqualIgnoringCase.m", - "src/Source/Library/Text/HCIsEqualIgnoringWhiteSpace.h", - "src/Source/Library/Text/HCIsEqualIgnoringWhiteSpace.m", "src/Source/Library/Text/HCStringContains.h", "src/Source/Library/Text/HCStringContains.m", "src/Source/Library/Text/HCStringContainsInOrder.h", @@ -175,10 +177,31 @@ "src/Source/Core/Helpers/HCCollect.h", "src/Source/Core/Helpers/HCInvocationMatcher.h", "src/Source/Core/Helpers/HCRequireNonNilObject.h", + "src/Source/Core/Helpers/HCRunloopRunner.h", "src/Source/Core/Helpers/HCWrapInMatcher.h", + "src/Source/Core/Helpers/NSInvocation+OCHamcrest.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCBoolReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCCharReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCDoubleReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCFloatReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCIntReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCLongLongReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCLongReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCObjectReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCReturnTypeHandlerChain.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCReturnValueGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCShortReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCUnsignedCharReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCUnsignedIntReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCUnsignedLongLongReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCUnsignedLongReturnGetter.h", + "src/Source/Core/Helpers/ReturnValueGetters/HCUnsignedShortReturnGetter.h", + "src/Source/Core/Helpers/TestFailureReporters/HCGenericTestFailureReporter.h", + "src/Source/Core/Helpers/TestFailureReporters/HCSenTestFailureReporter.h", "src/Source/Core/Helpers/TestFailureReporters/HCTestFailure.h", "src/Source/Core/Helpers/TestFailureReporters/HCTestFailureReporter.h", "src/Source/Core/Helpers/TestFailureReporters/HCTestFailureReporterChain.h", + "src/Source/Core/Helpers/TestFailureReporters/HCXCTestFailureReporter.h", "src/Source/Library/Collection/HCEvery.h", "src/Source/Library/Collection/HCHasCount.h", "src/Source/Library/Collection/HCIsCollectionContaining.h", @@ -214,8 +237,8 @@ "src/Source/Library/Object/HCIsSame.h", "src/Source/Library/Object/HCIsTypeOf.h", "src/Source/Library/Object/HCThrowsException.h", + "src/Source/Library/Text/HCIsEqualCompressingWhiteSpace.h", "src/Source/Library/Text/HCIsEqualIgnoringCase.h", - "src/Source/Library/Text/HCIsEqualIgnoringWhiteSpace.h", "src/Source/Library/Text/HCStringContains.h", "src/Source/Library/Text/HCStringContainsInOrder.h", "src/Source/Library/Text/HCStringEndsWith.h",
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn index a6390702..3d020c5 100644 --- a/ipc/BUILD.gn +++ b/ipc/BUILD.gn
@@ -22,7 +22,6 @@ component("ipc") { sources = [ - "export_template.h", "ipc_channel.cc", "ipc_channel.h", "ipc_channel_common.cc",
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h index ccb7ce4a..2cab6fb 100644 --- a/ipc/ipc_message_macros.h +++ b/ipc/ipc_message_macros.h
@@ -201,7 +201,7 @@ #include <tuple> -#include "ipc/export_template.h" +#include "base/export_template.h" #include "ipc/ipc_message_templates.h" #include "ipc/ipc_message_utils.h" #include "ipc/param_traits_macros.h"
diff --git a/media/filters/blocking_url_protocol.cc b/media/filters/blocking_url_protocol.cc index 08be12e..c21a7c98 100644 --- a/media/filters/blocking_url_protocol.cc +++ b/media/filters/blocking_url_protocol.cc
@@ -8,7 +8,7 @@ #include "base/bind.h" #include "base/macros.h" -#include "base/threading/scoped_blocking_call.h" +#include "base/threading/thread_restrictions.h" #include "media/base/data_source.h" #include "media/ffmpeg/ffmpeg_common.h" @@ -63,8 +63,7 @@ base::WaitableEvent* events[] = { &aborted_, &read_complete_ }; size_t index; { - base::ScopedBlockingCall scoped_blocking_call( - base::BlockingType::MAY_BLOCK); + base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives; index = base::WaitableEvent::WaitMany(events, arraysize(events)); }
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 4510a29..574e38a9 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -841,8 +841,7 @@ // the BlockingUrlProtocol to handle hops to the render thread for network // reads and seeks. blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::WithBaseSyncPrimitives(), - base::TaskPriority::USER_BLOCKING})), + {base::MayBlock(), base::TaskPriority::USER_BLOCKING})), stopped_(false), pending_read_(false), data_source_(data_source),
diff --git a/mojo/edk/system/mach_port_relay.cc b/mojo/edk/system/mach_port_relay.cc index f05cf22..1ff46f7 100644 --- a/mojo/edk/system/mach_port_relay.cc +++ b/mojo/edk/system/mach_port_relay.cc
@@ -65,7 +65,7 @@ } // namespace // static -bool MachPortRelay::ReceivePorts(PlatformHandleVector* handles) { +void MachPortRelay::ReceivePorts(PlatformHandleVector* handles) { DCHECK(handles); for (size_t i = 0; i < handles->size(); i++) { @@ -74,10 +74,11 @@ if (handle->type != PlatformHandle::Type::MACH_NAME) continue; - if (handle->port == MACH_PORT_NULL) { - handle->type = PlatformHandle::Type::MACH; + handle->type = PlatformHandle::Type::MACH; + + // MACH_PORT_NULL doesn't need translation. + if (handle->port == MACH_PORT_NULL) continue; - } base::mac::ScopedMachReceiveRight message_port(handle->port); base::mac::ScopedMachSendRight received_port( @@ -85,16 +86,13 @@ if (received_port.get() == MACH_PORT_NULL) { ReportChildError(ChildUMAError::ERROR_RECEIVE_MACH_MESSAGE); handle->port = MACH_PORT_NULL; - LOG(ERROR) << "Error receiving mach port"; - return false; + DLOG(ERROR) << "Error receiving mach port"; + continue; } ReportChildError(ChildUMAError::SUCCESS); handle->port = received_port.release(); - handle->type = PlatformHandle::Type::MACH; } - - return true; } MachPortRelay::MachPortRelay(base::PortProvider* port_provider) @@ -107,20 +105,11 @@ port_provider_->RemoveObserver(this); } -bool MachPortRelay::SendPortsToProcess(Channel::Message* message, +void MachPortRelay::SendPortsToProcess(Channel::Message* message, base::ProcessHandle process) { DCHECK(message); mach_port_t task_port = port_provider_->TaskForPid(process); - if (task_port == MACH_PORT_NULL) { - // Callers check the port provider for the task port before calling this - // function, in order to queue pending messages. Therefore, if this fails, - // it should be considered a genuine, bona fide, electrified, six-car error. - ReportBrokerError(BrokerUMAError::ERROR_TASK_FOR_PID); - return false; - } - size_t num_sent = 0; - bool error = false; ScopedPlatformHandleVectorPtr handles = message->TakeHandles(); // Message should have handles, otherwise there's no point in calling this // function. @@ -133,7 +122,19 @@ if (handle->port == MACH_PORT_NULL) { handle->type = PlatformHandle::Type::MACH_NAME; - num_sent++; + continue; + } + + if (task_port == MACH_PORT_NULL) { + // Callers check the port provider for the task port before calling this + // function, in order to queue pending messages. Therefore, if this fails, + // it should be considered a genuine, bona fide, electrified, six-car + // error. + ReportBrokerError(BrokerUMAError::ERROR_TASK_FOR_PID); + + // For MACH_PORT_NULL, use Type::MACH to indicate that no extraction is + // necessary. + handle->port = MACH_PORT_NULL; continue; } @@ -159,72 +160,47 @@ } ReportBrokerError(uma_error); handle->port = MACH_PORT_NULL; - error = true; - break; + continue; } ReportBrokerError(BrokerUMAError::SUCCESS); handle->port = intermediate_port; handle->type = PlatformHandle::Type::MACH_NAME; - num_sent++; } - DCHECK(error || num_sent); message->SetHandles(std::move(handles)); - - return !error; } -bool MachPortRelay::ExtractPortRights(Channel::Message* message, - base::ProcessHandle process) { - DCHECK(message); +void MachPortRelay::ExtractPort(PlatformHandle* handle, + base::ProcessHandle process) { + DCHECK_EQ(handle->type, PlatformHandle::Type::MACH_NAME); + handle->type = PlatformHandle::Type::MACH; + + // No extraction necessary for MACH_PORT_NULL. + if (handle->port == MACH_PORT_NULL) + return; mach_port_t task_port = port_provider_->TaskForPid(process); if (task_port == MACH_PORT_NULL) { ReportBrokerError(BrokerUMAError::ERROR_TASK_FOR_PID); - return false; + handle->port = MACH_PORT_NULL; + return; } - size_t num_received = 0; - bool error = false; - ScopedPlatformHandleVectorPtr handles = message->TakeHandles(); - // Message should have handles, otherwise there's no point in calling this - // function. - DCHECK(handles); - for (size_t i = 0; i < handles->size(); i++) { - PlatformHandle* handle = handles->data() + i; - DCHECK(handle->type != PlatformHandle::Type::MACH); - if (handle->type != PlatformHandle::Type::MACH_NAME) - continue; - - if (handle->port == MACH_PORT_NULL) { - handle->type = PlatformHandle::Type::MACH; - num_received++; - continue; - } - - mach_port_t extracted_right = MACH_PORT_NULL; - mach_msg_type_name_t extracted_right_type; - kern_return_t kr = - mach_port_extract_right(task_port, handle->port, - MACH_MSG_TYPE_MOVE_SEND, - &extracted_right, &extracted_right_type); - if (kr != KERN_SUCCESS) { - ReportBrokerError(BrokerUMAError::ERROR_EXTRACT_SOURCE_RIGHT); - error = true; - break; - } - - ReportBrokerError(BrokerUMAError::SUCCESS); - DCHECK_EQ(static_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND), - extracted_right_type); - handle->port = extracted_right; - handle->type = PlatformHandle::Type::MACH; - num_received++; + mach_port_t extracted_right = MACH_PORT_NULL; + mach_msg_type_name_t extracted_right_type; + kern_return_t kr = + mach_port_extract_right(task_port, handle->port, MACH_MSG_TYPE_MOVE_SEND, + &extracted_right, &extracted_right_type); + if (kr != KERN_SUCCESS) { + ReportBrokerError(BrokerUMAError::ERROR_EXTRACT_SOURCE_RIGHT); + handle->port = MACH_PORT_NULL; + return; } - DCHECK(error || num_received); - message->SetHandles(std::move(handles)); - return !error; + ReportBrokerError(BrokerUMAError::SUCCESS); + DCHECK_EQ(static_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND), + extracted_right_type); + handle->port = extracted_right; } void MachPortRelay::AddObserver(Observer* observer) {
diff --git a/mojo/edk/system/mach_port_relay.h b/mojo/edk/system/mach_port_relay.h index 87bc56cf..f72f7a7d 100644 --- a/mojo/edk/system/mach_port_relay.h +++ b/mojo/edk/system/mach_port_relay.h
@@ -39,12 +39,11 @@ // port and gives ownership of the final Mach port to the caller. Any handles // that are not Mach ports will remain unchanged, and the number and ordering // of handles is preserved. - // Returns |false| on failure and there is no guarantee about whether a Mach - // port is intermediate or final. + // On failure, the Mach port is replaced with MACH_PORT_NULL. // // See SendPortsToProcess() for the definition of intermediate and final Mach // ports. - static bool ReceivePorts(PlatformHandleVector* handles); + static void ReceivePorts(PlatformHandleVector* handles); explicit MachPortRelay(base::PortProvider* port_provider); ~MachPortRelay() override; @@ -55,20 +54,15 @@ // this intermediate port and the message is modified to refer to the name of // the intermediate port. The Mach port received over the intermediate port in // the child is referred to as the final Mach port. - // Returns |false| on failure and |message| may contain a mix of actual Mach - // ports and names. - bool SendPortsToProcess(Channel::Message* message, + // Ports that cannot be brokered are replaced with MACH_PORT_NULL. + void SendPortsToProcess(Channel::Message* message, base::ProcessHandle process); - // Extracts the Mach ports attached to |message| from |process|. - // Any Mach ports attached to |message| are names and not actual Mach ports - // that are valid in this process. For each of those Mach port names, a send - // right is extracted from |process| and the port name is replaced with the - // send right. - // Returns |false| on failure and |message| may contain a mix of actual Mach - // ports and names. - bool ExtractPortRights(Channel::Message* message, - base::ProcessHandle process); + // Given a PlatformHandle of Type::MACH_NAME, extracts the Mach port, and + // updates the contents of the PlatformHandle to have Type::MACH and have the + // actual Mach port. On failure, replaces the contents with Type::MACH and + // MACH_PORT_NULL. + void ExtractPort(PlatformHandle* handle, base::ProcessHandle process); // Observer interface. void AddObserver(Observer* observer);
diff --git a/mojo/edk/system/node_channel.cc b/mojo/edk/system/node_channel.cc index 963fa338..c9a34951 100644 --- a/mojo/edk/system/node_channel.cc +++ b/mojo/edk/system/node_channel.cc
@@ -518,11 +518,8 @@ // RELAY_EVENT_MESSAGE. { MachPortRelay* relay = delegate_->GetMachPortRelay(); - if (handles && !relay) { - if (!MachPortRelay::ReceivePorts(handles.get())) { - LOG(ERROR) << "Error receiving mach ports."; - } - } + if (handles && !relay) + MachPortRelay::ReceivePorts(handles.get()); } #endif // defined(OS_WIN) @@ -819,11 +816,7 @@ while (!pending_writes.empty()) { Channel::MessagePtr message = std::move(pending_writes.front()); pending_writes.pop(); - if (!relay->SendPortsToProcess(message.get(), remote_process_handle)) { - LOG(ERROR) << "Error on sending mach ports. Remote process is likely " - << "gone. Dropping message."; - return; - } + relay->SendPortsToProcess(message.get(), remote_process_handle); base::AutoLock lock(channel_lock_); if (!channel_) { @@ -899,11 +892,7 @@ } } - if (!relay->SendPortsToProcess(message.get(), remote_process_handle)) { - LOG(ERROR) << "Error on sending mach ports. Remote process is likely " - << "gone. Dropping message."; - return; - } + relay->SendPortsToProcess(message.get(), remote_process_handle); } } #endif
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc index ee5ffd1b..af9a4951 100644 --- a/mojo/edk/system/node_controller.cc +++ b/mojo/edk/system/node_controller.cc
@@ -1155,20 +1155,22 @@ } message->SetHandles(std::move(handles)); #else - MachPortRelay* relay = GetMachPortRelay(); - if (!relay) { - LOG(ERROR) << "Receiving Mach ports without a port relay from " - << from_node << ". Dropping message."; - return; + ScopedPlatformHandleVectorPtr handles = message->TakeHandles(); + for (size_t i = 0; i < handles->size(); ++i) { + PlatformHandle* handle = &(*handles)[i]; + if (handle->type == PlatformHandle::Type::MACH_NAME) { + MachPortRelay* relay = GetMachPortRelay(); + if (!relay) { + handle->type = PlatformHandle::Type::MACH; + handle->port = MACH_PORT_NULL; + DLOG(ERROR) << "Receiving Mach ports without a port relay from " + << from_node << "."; + continue; + } + relay->ExtractPort(handle, from_process); + } } - if (!relay->ExtractPortRights(message.get(), from_process)) { - // NodeChannel should ensure that MachPortRelay is ready for the remote - // process. At this point, if the port extraction failed, either something - // went wrong in the mach stuff, or the remote process died. - LOG(ERROR) << "Error on receiving Mach ports " << from_node - << ". Dropping message."; - return; - } + message->SetHandles(std::move(handles)); #endif // defined(OS_WIN) if (destination == name_) {
diff --git a/mojo/public/cpp/system/platform_handle.cc b/mojo/public/cpp/system/platform_handle.cc index 5e6c710f..a2fdd9df 100644 --- a/mojo/public/cpp/system/platform_handle.cc +++ b/mojo/public/cpp/system/platform_handle.cc
@@ -172,7 +172,8 @@ if (result != MOJO_RESULT_OK) return result; - CHECK_EQ(platform_handle.type, MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT); + CHECK(platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT || + platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_INVALID); *port = static_cast<mach_port_t>(platform_handle.value); return MOJO_RESULT_OK; }
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 168bcb80..fb6e48c8 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -190,22 +190,22 @@ { "name": "yahoo", "static_spki_hashes": [ + "DigiCertAssuredIDRoot", + "DigiCertGlobalRoot", + "DigiCertGlobalRootG2", + "DigiCertGlobalRootG3", + "DigiCertTrustedRootG4", + "DigiCertEVRoot", "VeriSignClass2_G2", "VeriSignClass2_G3", "VeriSignClass3_G3", "VeriSignClass3_G4", "VeriSignClass3_G5", "VeriSignUniversal", - "GeoTrustGlobal", - "GeoTrustPrimary", - "GeoTrustPrimary_G2", - "GeoTrustPrimary_G3", - "GeoTrustUniversal", - "DigiCertGlobalRoot", - "DigiCertEVRoot", "YahooBackup1", "YahooBackup2" - ] + ], + "report_uri": "http://csp.yahoo.com/beacon/csp?src=yahoocom-hpkp-report-only" }, { "name": "swehackCom",
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index 1972b8c2..23216f0 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -1650,3 +1650,85 @@ 3zdFfyi/c3LKxf6ZkKYRNCSCL3UXZcLZZhHBwwC9kMMJQohmxwkV7t2imWWbtnTX jQIDAQAB -----END PUBLIC KEY----- + +# DigiCert Global Root G2 +# https://www.digicert.com/CACerts/DigiCertGlobalRootG2.crt +DigiCertGlobalRootG2 +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# DigiCert Global Root G3 +# https://www.digicert.com/CACerts/DigiCertGlobalRootG3.crt +DigiCertGlobalRootG3 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# DigiCert Trusted Root G4 +# https://www.digicert.com/CACerts/DigiCertTrustedRootG4.crt +DigiCertTrustedRootG4 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- +
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 7ee992e6..be53b99 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -32,6 +32,7 @@ #include "net/log/net_log_event_type.h" #include "net/log/net_log_source_type.h" #include "net/ssl/ssl_cert_request_info.h" +#include "net/url_request/network_error_logging_delegate.h" #include "net/url_request/redirect_info.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_error_job.h" @@ -1175,6 +1176,8 @@ if (network_delegate_) network_delegate_->NotifyCompleted(this, job_.get() != NULL, status_.error()); + + MaybeGenerateNetworkErrorLoggingReport(); } void URLRequest::OnCallToDelegate() { @@ -1193,6 +1196,39 @@ net_log_.EndEvent(NetLogEventType::URL_REQUEST_DELEGATE); } +void URLRequest::MaybeGenerateNetworkErrorLoggingReport() { + NetworkErrorLoggingDelegate* delegate = + context()->network_error_logging_delegate(); + if (!delegate) + return; + + // TODO(juliatuttle): Figure out whether we should be ignoring errors from + // non-HTTPS origins. + + // TODO(juliatuttle): Remove this and reconsider interface once there's a + // better story for reporting successes. + if (status().ToNetError() == OK) + return; + + NetworkErrorLoggingDelegate::ErrorDetails details; + + details.uri = url(); + details.referrer = GURL(referrer()); + IPEndPoint endpoint; + if (GetRemoteEndpoint(&endpoint)) + details.server_ip = endpoint.address(); + // TODO(juliatuttle): Plumb this. + details.protocol = kProtoUnknown; + details.status_code = GetResponseCode(); + if (details.status_code == -1) + details.status_code = 0; + details.elapsed_time = + base::TimeTicks::Now() - load_timing_info_.request_start; + details.type = status().ToNetError(); + + delegate->OnNetworkError(details); +} + void URLRequest::GetConnectionAttempts(ConnectionAttempts* out) const { if (job_) job_->GetConnectionAttempts(out);
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index 378fe78..658523a 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -772,6 +772,8 @@ // cancellation. void OnCallToDelegateComplete(); + void MaybeGenerateNetworkErrorLoggingReport(); + // Contextual information used for this request. Cannot be NULL. This contains // most of the dependencies which are shared between requests (disk cache, // cookie store, socket pool, etc.)
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 04fee52c..5e55598 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -7143,7 +7143,9 @@ EXPECT_TRUE(IsCertStatusError(request->ssl_info().cert_status)); EXPECT_TRUE(reporting_service.headers().empty()); } -#endif // BUILDFLAG(ENABLE_REPORTING) + +// Network Error Logging is dependent on the Reporting API, so only run NEL +// tests if Reporting is enabled in the build. namespace { @@ -7284,6 +7286,81 @@ EXPECT_TRUE(nel_delegate.headers().empty()); } +TEST_F(URLRequestTestHTTP, DontForwardErrorToNelNoDelegate) { + URLRequestFailedJob::AddUrlHandler(); + + GURL request_url = + URLRequestFailedJob::GetMockHttpsUrl(ERR_CONNECTION_REFUSED); + + TestNetworkDelegate network_delegate; + TestURLRequestContext context(true); + context.set_network_delegate(&network_delegate); + context.Init(); + + TestDelegate d; + std::unique_ptr<URLRequest> request(context.CreateRequest( + request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); + request->Start(); + base::RunLoop().Run(); + + URLRequestFilter::GetInstance()->ClearHandlers(); +} + +// TODO(juliatuttle): Figure out whether this restriction should be in place, +// and either implement it or remove this test. +TEST_F(URLRequestTestHTTP, DISABLED_DontForwardErrorToNelHttp) { + URLRequestFailedJob::AddUrlHandler(); + + GURL request_url = + URLRequestFailedJob::GetMockHttpUrl(ERR_CONNECTION_REFUSED); + + TestNetworkDelegate network_delegate; + TestNetworkErrorLoggingDelegate nel_delegate; + TestURLRequestContext context(true); + context.set_network_delegate(&network_delegate); + context.set_network_error_logging_delegate(&nel_delegate); + context.Init(); + + TestDelegate d; + std::unique_ptr<URLRequest> request(context.CreateRequest( + request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); + request->Start(); + base::RunLoop().Run(); + + EXPECT_TRUE(nel_delegate.errors().empty()); + + URLRequestFilter::GetInstance()->ClearHandlers(); +} + +TEST_F(URLRequestTestHTTP, ForwardErrorToNelHttps) { + URLRequestFailedJob::AddUrlHandler(); + + GURL request_url = + URLRequestFailedJob::GetMockHttpsUrl(ERR_CONNECTION_REFUSED); + + TestNetworkDelegate network_delegate; + TestNetworkErrorLoggingDelegate nel_delegate; + TestURLRequestContext context(true); + context.set_network_delegate(&network_delegate); + context.set_network_error_logging_delegate(&nel_delegate); + context.Init(); + + TestDelegate d; + std::unique_ptr<URLRequest> request(context.CreateRequest( + request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); + request->Start(); + base::RunLoop().Run(); + + ASSERT_EQ(1u, nel_delegate.errors().size()); + EXPECT_EQ(request_url, nel_delegate.errors()[0].uri); + EXPECT_EQ(0, nel_delegate.errors()[0].status_code); + EXPECT_EQ(ERR_CONNECTION_REFUSED, nel_delegate.errors()[0].type); + + URLRequestFilter::GetInstance()->ClearHandlers(); +} + +#endif // BUILDFLAG(ENABLE_REPORTING) + TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { ASSERT_TRUE(http_test_server()->Start());
diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h index d89c9b1..2b2dc0f 100644 --- a/sandbox/win/src/nt_internals.h +++ b/sandbox/win/src/nt_internals.h
@@ -794,6 +794,11 @@ const unsigned int NtProcessInformationAccessToken = 9; +typedef NTSTATUS(WINAPI* RtlDeriveCapabilitySidsFromNameFunction)( + PCUNICODE_STRING SourceString, + PSID CapabilityGroupSid, + PSID CapabilitySid); + // ----------------------------------------------------------------------- // GDI OPM API and Supported Calls
diff --git a/sandbox/win/src/sid.cc b/sandbox/win/src/sid.cc index 5c77548..3507ad7 100644 --- a/sandbox/win/src/sid.cc +++ b/sandbox/win/src/sid.cc
@@ -16,49 +16,36 @@ namespace { -typedef decltype( - ::DeriveCapabilitySidsFromName) DeriveCapabilitySidsFromNameFunc; - -class SidArray { - public: - SidArray() : count_(0), sids_(nullptr) {} - - ~SidArray() { - if (sids_) { - for (size_t index = 0; index < count_; ++index) { - ::LocalFree(sids_[index]); - } - ::LocalFree(sids_); - } - } - - DWORD count() { return count_; } - PSID* sids() { return sids_; } - PDWORD count_ptr() { return &count_; } - PSID** sids_ptr() { return &sids_; } - - private: - DWORD count_; - PSID* sids_; -}; - -const wchar_t* WellKnownCapabilityToName(WellKnownCapabilities capability) { +DWORD WellKnownCapabilityToRid(WellKnownCapabilities capability) { switch (capability) { case kInternetClient: - return L"internetClient"; + return SECURITY_CAPABILITY_INTERNET_CLIENT; case kInternetClientServer: - return L"internetClientServer"; - case kRegistryRead: - return L"registryRead"; - case kLpacCryptoServices: - return L"lpacCryptoServices"; - case kEnterpriseAuthentication: - return L"enterpriseAuthentication"; + return SECURITY_CAPABILITY_INTERNET_CLIENT_SERVER; case kPrivateNetworkClientServer: - return L"privateNetworkClientServer"; + return SECURITY_CAPABILITY_PRIVATE_NETWORK_CLIENT_SERVER; + case kPicturesLibrary: + return SECURITY_CAPABILITY_PICTURES_LIBRARY; + case kVideosLibrary: + return SECURITY_CAPABILITY_VIDEOS_LIBRARY; + case kMusicLibrary: + return SECURITY_CAPABILITY_MUSIC_LIBRARY; + case kDocumentsLibrary: + return SECURITY_CAPABILITY_DOCUMENTS_LIBRARY; + case kEnterpriseAuthentication: + return SECURITY_CAPABILITY_ENTERPRISE_AUTHENTICATION; + case kSharedUserCertificates: + return SECURITY_CAPABILITY_SHARED_USER_CERTIFICATES; + case kRemovableStorage: + return SECURITY_CAPABILITY_REMOVABLE_STORAGE; + case kAppointments: + return SECURITY_CAPABILITY_APPOINTMENTS; + case kContacts: + return SECURITY_CAPABILITY_CONTACTS; default: - return nullptr; + break; } + return 0; } } // namespace @@ -81,33 +68,39 @@ } Sid Sid::FromKnownCapability(WellKnownCapabilities capability) { - return Sid::FromNamedCapability(WellKnownCapabilityToName(capability)); + DWORD capability_rid = WellKnownCapabilityToRid(capability); + if (!capability_rid) + return Sid(); + SID_IDENTIFIER_AUTHORITY capability_authority = { + SECURITY_APP_PACKAGE_AUTHORITY}; + DWORD sub_authorities[] = {SECURITY_CAPABILITY_BASE_RID, capability_rid}; + return FromSubAuthorities(&capability_authority, 2, sub_authorities); } Sid Sid::FromNamedCapability(const wchar_t* capability_name) { - DeriveCapabilitySidsFromNameFunc* derive_capablity_sids = - (DeriveCapabilitySidsFromNameFunc*)GetProcAddress( - GetModuleHandle(L"kernelbase"), "DeriveCapabilitySidsFromName"); - if (!derive_capablity_sids) + RtlDeriveCapabilitySidsFromNameFunction derive_capability_sids = nullptr; + ResolveNTFunctionPtr("RtlDeriveCapabilitySidsFromName", + &derive_capability_sids); + RtlInitUnicodeStringFunction init_unicode_string = nullptr; + ResolveNTFunctionPtr("RtlInitUnicodeString", &init_unicode_string); + + if (!derive_capability_sids || !init_unicode_string) return Sid(); if (!capability_name || ::wcslen(capability_name) == 0) return Sid(); - SidArray capability_group_sids; - SidArray capability_sids; + UNICODE_STRING name = {}; + init_unicode_string(&name, capability_name); + Sid capability_sid; + Sid group_sid; - if (!derive_capablity_sids(capability_name, capability_group_sids.sids_ptr(), - capability_group_sids.count_ptr(), - capability_sids.sids_ptr(), - capability_sids.count_ptr())) { - return Sid(); - } - - if (capability_sids.count() < 1) + NTSTATUS status = + derive_capability_sids(&name, group_sid.sid_, capability_sid.sid_); + if (!NT_SUCCESS(status)) return Sid(); - return Sid(capability_sids.sids()[0]); + return capability_sid; } Sid Sid::FromSddlString(const wchar_t* sddl_sid) {
diff --git a/sandbox/win/src/sid.h b/sandbox/win/src/sid.h index acaaa74..4ef22e5 100644 --- a/sandbox/win/src/sid.h +++ b/sandbox/win/src/sid.h
@@ -11,13 +11,20 @@ namespace sandbox { +// Known capabilities defined in Windows 8. enum WellKnownCapabilities { kInternetClient, kInternetClientServer, - kRegistryRead, - kLpacCryptoServices, - kEnterpriseAuthentication, kPrivateNetworkClientServer, + kPicturesLibrary, + kVideosLibrary, + kMusicLibrary, + kDocumentsLibrary, + kEnterpriseAuthentication, + kSharedUserCertificates, + kRemovableStorage, + kAppointments, + kContacts, kMaxWellKnownCapability }; @@ -34,7 +41,8 @@ // Create a Sid from an AppContainer capability name. The name can be // completely arbitrary. static Sid FromNamedCapability(const wchar_t* capability_name); - // Create a Sid from a known capability enumeration value. + // Create a Sid from a known capability enumeration value. The Sids + // match with the list defined in Windows 8. static Sid FromKnownCapability(WellKnownCapabilities capability); // Create a Sid from a SDDL format string, such as S-1-1-0. static Sid FromSddlString(const wchar_t* sddl_sid);
diff --git a/sandbox/win/src/sid_unittest.cc b/sandbox/win/src/sid_unittest.cc index 0f4fc9bb..5b01d592 100644 --- a/sandbox/win/src/sid_unittest.cc +++ b/sandbox/win/src/sid_unittest.cc
@@ -35,10 +35,14 @@ return equal; } -struct CapabilityTestEntry { - WellKnownCapabilities capability_; - const wchar_t* capability_name_; - const wchar_t* sddl_sid_; +struct KnownCapabilityTestEntry { + WellKnownCapabilities capability; + const wchar_t* sddl_sid; +}; + +struct NamedCapabilityTestEntry { + const wchar_t* capability_name; + const wchar_t* sddl_sid; }; } // namespace @@ -95,22 +99,38 @@ ASSERT_TRUE(EqualSid(Sid(::WinProxySid), ATL::Sids::Proxy())); } -TEST(SidTest, AppContainer) { - const CapabilityTestEntry capabilities[] = { - {kInternetClient, L"internetClient", L"S-1-15-3-1"}, - {kInternetClientServer, L"internetClientServer", L"S-1-15-3-2"}, - {kRegistryRead, L"registryRead", - L"S-1-15-3-1024-1065365936-1281604716-3511738428-" - "1654721687-432734479-3232135806-4053264122-3456934681"}, - {kLpacCryptoServices, L"lpacCryptoServices", - L"S-1-15-3-1024-3203351429-2120443784-2872670797-" - "1918958302-2829055647-4275794519-765664414-2751773334"}, - {kEnterpriseAuthentication, L"enterpriseAuthentication", L"S-1-15-3-8"}, - {kPrivateNetworkClientServer, L"privateNetworkClientServer", - L"S-1-15-3-3"}}; +TEST(SidTest, KnownCapability) { + if (base::win::GetVersion() < base::win::VERSION_WIN8) + return; - // No support for AppContainer less than Win10 RS2. - if (base::win::GetVersion() < base::win::VERSION_WIN10_RS2) + Sid sid_invalid_well_known = + Sid::FromKnownCapability(kMaxWellKnownCapability); + EXPECT_FALSE(sid_invalid_well_known.IsValid()); + + const KnownCapabilityTestEntry capabilities[] = { + {kInternetClient, L"S-1-15-3-1"}, + {kInternetClientServer, L"S-1-15-3-2"}, + {kPrivateNetworkClientServer, L"S-1-15-3-3"}, + {kPicturesLibrary, L"S-1-15-3-4"}, + {kVideosLibrary, L"S-1-15-3-5"}, + {kMusicLibrary, L"S-1-15-3-6"}, + {kDocumentsLibrary, L"S-1-15-3-7"}, + {kEnterpriseAuthentication, L"S-1-15-3-8"}, + {kSharedUserCertificates, L"S-1-15-3-9"}, + {kRemovableStorage, L"S-1-15-3-10"}, + {kAppointments, L"S-1-15-3-11"}, + {kContacts, L"S-1-15-3-12"}, + }; + + for (auto capability : capabilities) { + EXPECT_TRUE(EqualSid(Sid::FromKnownCapability(capability.capability), + capability.sddl_sid)) + << "Known Capability: " << capability.sddl_sid; + } +} + +TEST(SidTest, NamedCapability) { + if (base::win::GetVersion() < base::win::VERSION_WIN10) return; Sid sid_nullptr = Sid::FromNamedCapability(nullptr); @@ -119,18 +139,22 @@ Sid sid_empty = Sid::FromNamedCapability(L""); EXPECT_FALSE(sid_empty.IsValid()); - WellKnownCapabilities invalid_well_known = - static_cast<WellKnownCapabilities>(kMaxWellKnownCapability + 1); - Sid sid_invalid_well_known = Sid::FromKnownCapability(invalid_well_known); - EXPECT_FALSE(sid_invalid_well_known.IsValid()); + const NamedCapabilityTestEntry capabilities[] = { + {L"internetClient", L"S-1-15-3-1"}, + {L"internetClientServer", L"S-1-15-3-2"}, + {L"registryRead", + L"S-1-15-3-1024-1065365936-1281604716-3511738428-" + "1654721687-432734479-3232135806-4053264122-3456934681"}, + {L"lpacCryptoServices", + L"S-1-15-3-1024-3203351429-2120443784-2872670797-" + "1918958302-2829055647-4275794519-765664414-2751773334"}, + {L"enterpriseAuthentication", L"S-1-15-3-8"}, + {L"privateNetworkClientServer", L"S-1-15-3-3"}}; for (auto capability : capabilities) { - EXPECT_TRUE(EqualSid(Sid::FromNamedCapability(capability.capability_name_), - capability.sddl_sid_)) - << "Named Capability: " << capability.sddl_sid_; - EXPECT_TRUE(EqualSid(Sid::FromKnownCapability(capability.capability_), - capability.sddl_sid_)) - << "Known Capability: " << capability.sddl_sid_; + EXPECT_TRUE(EqualSid(Sid::FromNamedCapability(capability.capability_name), + capability.sddl_sid)) + << "Named Capability: " << capability.sddl_sid; } }
diff --git a/services/BUILD.gn b/services/BUILD.gn index 471cda3..c34651b 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -59,6 +59,7 @@ if (is_android) { deps += [ + "//services/data_decoder/public/cpp/android:safe_json_java", "//services/device:java", # Some tests need to initialize V8.
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn index 6f347b95..e10cd16 100644 --- a/services/data_decoder/BUILD.gn +++ b/services/data_decoder/BUILD.gn
@@ -11,6 +11,8 @@ "data_decoder_service.h", "image_decoder_impl.cc", "image_decoder_impl.h", + "json_parser_impl.cc", + "json_parser_impl.h", ] deps = [ @@ -33,6 +35,8 @@ sources = [ "image_decoder_impl_unittest.cc", + "public/cpp/json_sanitizer_unittest.cc", + "public/cpp/testing_json_parser_unittest.cc", ] deps = [ @@ -40,6 +44,8 @@ "//base", "//gin", "//gin:gin_test", + "//services/data_decoder/public/cpp", + "//services/data_decoder/public/cpp:test_support", "//skia", "//testing/gtest", "//third_party/WebKit/public:blink",
diff --git a/services/data_decoder/DEPS b/services/data_decoder/DEPS index d15dcafe..e1f42c99 100644 --- a/services/data_decoder/DEPS +++ b/services/data_decoder/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+gin", + "+jni", "+skia", "+third_party/WebKit/public", "+third_party/skia",
diff --git a/services/data_decoder/OWNERS b/services/data_decoder/OWNERS index 59dfd4b3..e86a404 100644 --- a/services/data_decoder/OWNERS +++ b/services/data_decoder/OWNERS
@@ -1,2 +1,6 @@ per-file manifest.json=set noparent per-file manifest.json=file://ipc/SECURITY_OWNERS + +bauerb@chromium.org +jcivelli@chromium.org +rsesek@chromium.org
diff --git a/services/data_decoder/data_decoder_service.cc b/services/data_decoder/data_decoder_service.cc index c42316f..63df926 100644 --- a/services/data_decoder/data_decoder_service.cc +++ b/services/data_decoder/data_decoder_service.cc
@@ -10,6 +10,7 @@ #include "base/time/time.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/data_decoder/image_decoder_impl.h" +#include "services/data_decoder/json_parser_impl.h" #include "services/data_decoder/public/interfaces/image_decoder.mojom.h" #include "services/service_manager/public/cpp/service_context.h" @@ -25,6 +26,13 @@ std::move(request)); } +void OnJsonParserRequest(service_manager::ServiceContextRefFactory* ref_factory, + mojom::JsonParserRequest request) { + mojo::MakeStrongBinding( + base::MakeUnique<JsonParserImpl>(ref_factory->CreateRef()), + std::move(request)); +} + } // namespace DataDecoderService::DataDecoderService() : weak_factory_(this) {} @@ -41,6 +49,7 @@ &DataDecoderService::MaybeRequestQuitDelayed, base::Unretained(this)))); registry_.AddInterface( base::Bind(&OnImageDecoderRequest, ref_factory_.get())); + registry_.AddInterface(base::Bind(&OnJsonParserRequest, ref_factory_.get())); } void DataDecoderService::OnBindInterface(
diff --git a/services/data_decoder/image_decoder_impl_unittest.cc b/services/data_decoder/image_decoder_impl_unittest.cc index 88429d7..a3a929bf 100644 --- a/services/data_decoder/image_decoder_impl_unittest.cc +++ b/services/data_decoder/image_decoder_impl_unittest.cc
@@ -129,7 +129,7 @@ // Check that image has been shrunk appropriately EXPECT_LT(request.bitmap().computeByteSize() + base_msg_size, - (uint64_t)kTestMaxImageSize); + static_cast<uint64_t>(kTestMaxImageSize)); // Android does its own image shrinking for memory conservation deeper in // the decode, so more specific tests here won't work. #if !defined(OS_ANDROID)
diff --git a/services/data_decoder/json_parser_impl.cc b/services/data_decoder/json_parser_impl.cc new file mode 100644 index 0000000..7c19f423 --- /dev/null +++ b/services/data_decoder/json_parser_impl.cc
@@ -0,0 +1,34 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/data_decoder/json_parser_impl.h" + +#include <memory> +#include <utility> + +#include "base/json/json_reader.h" +#include "base/memory/ptr_util.h" +#include "base/values.h" + +namespace data_decoder { + +JsonParserImpl::JsonParserImpl( + std::unique_ptr<service_manager::ServiceContextRef> service_ref) + : service_ref_(std::move(service_ref)) {} + +JsonParserImpl::~JsonParserImpl() = default; + +void JsonParserImpl::Parse(const std::string& json, ParseCallback callback) { + int error_code; + std::string error; + std::unique_ptr<base::Value> value = base::JSONReader::ReadAndReturnError( + json, base::JSON_PARSE_RFC, &error_code, &error); + if (value) { + std::move(callback).Run(std::move(value), base::nullopt); + } else { + std::move(callback).Run(nullptr, base::make_optional(std::move(error))); + } +} + +} // namespace data_decoder
diff --git a/services/data_decoder/json_parser_impl.h b/services/data_decoder/json_parser_impl.h new file mode 100644 index 0000000..9656d04 --- /dev/null +++ b/services/data_decoder/json_parser_impl.h
@@ -0,0 +1,33 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_DATA_DECODER_JSON_PARSER_IMPL_H_ +#define SERVICES_DATA_DECODER_JSON_PARSER_IMPL_H_ + +#include <string> + +#include "base/macros.h" +#include "services/data_decoder/public/interfaces/json_parser.mojom.h" +#include "services/service_manager/public/cpp/service_context_ref.h" + +namespace data_decoder { + +class JsonParserImpl : public mojom::JsonParser { + public: + explicit JsonParserImpl( + std::unique_ptr<service_manager::ServiceContextRef> service_ref); + ~JsonParserImpl() override; + + private: + const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; + + // mojom::JsonParser implementation. + void Parse(const std::string& json, ParseCallback callback) override; + + DISALLOW_COPY_AND_ASSIGN(JsonParserImpl); +}; + +} // namespace data_decoder + +#endif // SERVICES_DATA_DECODER_JSON_PARSER_IMPL_H_
diff --git a/services/data_decoder/manifest.json b/services/data_decoder/manifest.json index bc0335b..954d104 100644 --- a/services/data_decoder/manifest.json +++ b/services/data_decoder/manifest.json
@@ -4,7 +4,8 @@ "interface_provider_specs": { "service_manager:connector": { "provides": { - "image_decoder": [ "data_decoder::mojom::ImageDecoder" ] + "image_decoder": [ "data_decoder::mojom::ImageDecoder" ], + "json_parser": [ "data_decoder::mojom::JsonParser" ] }, "requires": { "service_manager": [ "service_manager:all_users" ]
diff --git a/services/data_decoder/public/cpp/BUILD.gn b/services/data_decoder/public/cpp/BUILD.gn index ebab3dc..142508a 100644 --- a/services/data_decoder/public/cpp/BUILD.gn +++ b/services/data_decoder/public/cpp/BUILD.gn
@@ -8,10 +8,43 @@ sources = [ "decode_image.cc", "decode_image.h", + "json_sanitizer.cc", + "json_sanitizer.h", + "safe_json_parser.cc", + "safe_json_parser.h", + "safe_json_parser_impl.cc", + "safe_json_parser_impl.h", + "safe_json_parser_impl.h", ] public_deps = [ "//services/data_decoder/public/interfaces", "//services/service_manager/public/cpp", ] + + if (is_android) { + sources -= [ "json_sanitizer.cc" ] + sources += [ + "json_sanitizer_android.cc", + "safe_json_parser_android.cc", + "safe_json_parser_android.h", + ] + deps = [ + "android:safe_json_java($default_toolchain)", + "android:safe_json_jni_headers", + ] + } +} + +static_library("test_support") { + testonly = true + sources = [ + "testing_json_parser.cc", + "testing_json_parser.h", + ] + + deps = [ + ":cpp", + "//base", + ] }
diff --git a/services/data_decoder/public/cpp/android/BUILD.gn b/services/data_decoder/public/cpp/android/BUILD.gn new file mode 100644 index 0000000..4a07518 --- /dev/null +++ b/services/data_decoder/public/cpp/android/BUILD.gn
@@ -0,0 +1,22 @@ +# 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("//build/config/android/rules.gni") + +_jni_sources = + [ "java/src/org/chromium/services/data_decoder/JsonSanitizer.java" ] + +generate_jni("safe_json_jni_headers") { + sources = _jni_sources + jni_package = "data_decoder" +} + +if (current_toolchain == default_toolchain) { + android_library("safe_json_java") { + deps = [ + "//base:base_java", + ] + java_files = [] + _jni_sources + } +}
diff --git a/components/safe_json/android/java/src/org/chromium/components/safejson/JsonSanitizer.java b/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java similarity index 98% rename from components/safe_json/android/java/src/org/chromium/components/safejson/JsonSanitizer.java rename to services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java index 641d4ed8..b3c4bfa 100644 --- a/components/safe_json/android/java/src/org/chromium/components/safejson/JsonSanitizer.java +++ b/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.components.safejson; +package org.chromium.services.data_decoder; import android.util.JsonReader; import android.util.JsonToken; @@ -21,12 +21,10 @@ * Sanitizes and normalizes a JSON string by parsing it, checking for wellformedness, and * serializing it again. This class is meant to be used from native code. */ -@JNINamespace("safe_json") +@JNINamespace("data_decoder") public class JsonSanitizer { - // Disallow instantiating the class. - private JsonSanitizer() { - } + private JsonSanitizer() {} /** * The maximum nesting depth to which the native JSON parser restricts input in order to avoid
diff --git a/components/safe_json/json_sanitizer.cc b/services/data_decoder/public/cpp/json_sanitizer.cc similarity index 72% rename from components/safe_json/json_sanitizer.cc rename to services/data_decoder/public/cpp/json_sanitizer.cc index b98283f..9a730c4 100644 --- a/components/safe_json/json_sanitizer.cc +++ b/services/data_decoder/public/cpp/json_sanitizer.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/json_sanitizer.h" +#include "services/data_decoder/public/cpp/json_sanitizer.h" #if defined(OS_ANDROID) #error Build json_sanitizer_android.cc instead of this file on Android. @@ -18,15 +18,16 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "build/build_config.h" -#include "components/safe_json/safe_json_parser.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" -namespace safe_json { +namespace data_decoder { namespace { class OopJsonSanitizer : public JsonSanitizer { public: - OopJsonSanitizer(const std::string& unsafe_json, + OopJsonSanitizer(service_manager::Connector* connector, + const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback); @@ -43,15 +44,15 @@ DISALLOW_COPY_AND_ASSIGN(OopJsonSanitizer); }; -OopJsonSanitizer::OopJsonSanitizer(const std::string& unsafe_json, +OopJsonSanitizer::OopJsonSanitizer(service_manager::Connector* connector, + const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback) : success_callback_(success_callback), error_callback_(error_callback) { - SafeJsonParser::Parse(unsafe_json, - base::Bind(&OopJsonSanitizer::OnParseSuccess, - base::Unretained(this)), - base::Bind(&OopJsonSanitizer::OnParseError, - base::Unretained(this))); + SafeJsonParser::Parse( + connector, unsafe_json, + base::Bind(&OopJsonSanitizer::OnParseSuccess, base::Unretained(this)), + base::Bind(&OopJsonSanitizer::OnParseError, base::Unretained(this))); } void OopJsonSanitizer::OnParseSuccess(std::unique_ptr<base::Value> value) { @@ -84,11 +85,13 @@ } // namespace // static -void JsonSanitizer::Sanitize(const std::string& unsafe_json, +void JsonSanitizer::Sanitize(service_manager::Connector* connector, + const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback) { // OopJsonSanitizer destroys itself when it is finished. - new OopJsonSanitizer(unsafe_json, success_callback, error_callback); + new OopJsonSanitizer(connector, unsafe_json, success_callback, + error_callback); } -} // namespace safe_json +} // namespace data_decoder
diff --git a/components/safe_json/json_sanitizer.h b/services/data_decoder/public/cpp/json_sanitizer.h similarity index 67% rename from components/safe_json/json_sanitizer.h rename to services/data_decoder/public/cpp/json_sanitizer.h index 434f4be..df467978 100644 --- a/components/safe_json/json_sanitizer.h +++ b/services/data_decoder/public/cpp/json_sanitizer.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 COMPONENTS_SAFE_JSON_JSON_SANITIZER_H_ -#define COMPONENTS_SAFE_JSON_JSON_SANITIZER_H_ +#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_JSON_SANITIZER_H_ +#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_JSON_SANITIZER_H_ #include <string> @@ -16,7 +16,11 @@ #include <jni.h> #endif -namespace safe_json { +namespace service_manager { +class Connector; +} + +namespace data_decoder { // Sanitizes and normalizes JSON by parsing it in a safe environment and // re-serializing it. Parsing the sanitized JSON should result in a value @@ -32,7 +36,11 @@ // |success_callback| or the |error_callback| will be called with the result // of the sanitization or an error message, respectively, but not before the // method returns. - static void Sanitize(const std::string& unsafe_json, + // |connector| is the connector provided by the service manager and is used + // to retrieve the JSON decoder service. It's commonly retrieved from a + // service manager connection context object that the embedder provides. + static void Sanitize(service_manager::Connector* connector, + const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback); @@ -44,6 +52,6 @@ DISALLOW_COPY_AND_ASSIGN(JsonSanitizer); }; -} // namespace safe_json +} // namespace data_decoder -#endif // COMPONENTS_SAFE_JSON_JSON_SANITIZER_H_ +#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_JSON_SANITIZER_H_
diff --git a/components/safe_json/json_sanitizer_android.cc b/services/data_decoder/public/cpp/json_sanitizer_android.cc similarity index 94% rename from components/safe_json/json_sanitizer_android.cc rename to services/data_decoder/public/cpp/json_sanitizer_android.cc index 82d9506..6dea4d2 100644 --- a/components/safe_json/json_sanitizer_android.cc +++ b/services/data_decoder/public/cpp/json_sanitizer_android.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/json_sanitizer.h" +#include "services/data_decoder/public/cpp/json_sanitizer.h" #include "base/android/jni_string.h" #include "base/bind.h" @@ -16,7 +16,7 @@ using base::android::JavaParamRef; -namespace safe_json { +namespace data_decoder { namespace { @@ -106,7 +106,8 @@ } // static -void JsonSanitizer::Sanitize(const std::string& unsafe_json, +void JsonSanitizer::Sanitize(service_manager::Connector* connector, + const std::string& unsafe_json, const StringCallback& success_callback, const StringCallback& error_callback) { // JsonSanitizerAndroid does all its work synchronously, but posts any @@ -116,4 +117,4 @@ sanitizer.Sanitize(unsafe_json); } -} // namespace safe_json +} // namespace data_decoder
diff --git a/components/safe_json/json_sanitizer_unittest.cc b/services/data_decoder/public/cpp/json_sanitizer_unittest.cc similarity index 91% rename from components/safe_json/json_sanitizer_unittest.cc rename to services/data_decoder/public/cpp/json_sanitizer_unittest.cc index aac3a49..dbb9824 100644 --- a/components/safe_json/json_sanitizer_unittest.cc +++ b/services/data_decoder/public/cpp/json_sanitizer_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/json_sanitizer.h" +#include "services/data_decoder/public/cpp/json_sanitizer.h" #include <memory> @@ -13,14 +13,14 @@ #include "base/run_loop.h" #include "base/values.h" #include "build/build_config.h" -#include "components/safe_json/safe_json_parser.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" #include "testing/gtest/include/gtest/gtest.h" #if !defined(OS_ANDROID) -#include "components/safe_json/testing_json_parser.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #endif -namespace safe_json { +namespace data_decoder { class JsonSanitizerTest : public ::testing::Test { public: @@ -49,7 +49,7 @@ base::MessageLoop message_loop_; #if !defined(OS_ANDROID) - safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; + TestingJsonParser::ScopedFactoryOverride factory_override_; #endif std::string result_; @@ -71,8 +71,7 @@ std::string error; std::unique_ptr<base::Value> reparsed = base::JSONReader::ReadAndReturnError( result_, base::JSON_PARSE_RFC, &error_code, &error); - EXPECT_TRUE(reparsed) - << "Invalid result: " << error; + EXPECT_TRUE(reparsed) << "Invalid result: " << error; // The parsed values should be equal. EXPECT_TRUE(reparsed->Equals(parsed.get())); @@ -90,7 +89,7 @@ error_.clear(); run_loop_.reset(new base::RunLoop); JsonSanitizer::Sanitize( - json, + nullptr, json, base::Bind(&JsonSanitizerTest::OnSuccess, base::Unretained(this)), base::Bind(&JsonSanitizerTest::OnError, base::Unretained(this))); @@ -184,4 +183,4 @@ CheckError("[\"\\ud83f\\udffe\"]"); } -} // namespace safe_json +} // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/safe_json_parser.cc b/services/data_decoder/public/cpp/safe_json_parser.cc new file mode 100644 index 0000000..94070c4f --- /dev/null +++ b/services/data_decoder/public/cpp/safe_json_parser.cc
@@ -0,0 +1,54 @@ +// 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 "services/data_decoder/public/cpp/safe_json_parser.h" + +#include "build/build_config.h" + +#if defined(OS_ANDROID) +#include "services/data_decoder/public/cpp/safe_json_parser_android.h" +#else +#include "services/data_decoder/public/cpp/safe_json_parser_impl.h" +#endif + +namespace data_decoder { + +namespace { + +SafeJsonParser::Factory g_factory = nullptr; + +SafeJsonParser* Create(service_manager::Connector* connector, + const std::string& unsafe_json, + const SafeJsonParser::SuccessCallback& success_callback, + const SafeJsonParser::ErrorCallback& error_callback) { + if (g_factory) + return g_factory(unsafe_json, success_callback, error_callback); + +#if defined(OS_ANDROID) + return new SafeJsonParserAndroid(unsafe_json, success_callback, + error_callback); +#else + return new SafeJsonParserImpl(connector, unsafe_json, success_callback, + error_callback); +#endif +} + +} // namespace + +// static +void SafeJsonParser::SetFactoryForTesting(Factory factory) { + g_factory = factory; +} + +// static +void SafeJsonParser::Parse(service_manager::Connector* connector, + const std::string& unsafe_json, + const SuccessCallback& success_callback, + const ErrorCallback& error_callback) { + SafeJsonParser* parser = + Create(connector, unsafe_json, success_callback, error_callback); + parser->Start(); +} + +} // namespace data_decoder
diff --git a/components/safe_json/safe_json_parser.h b/services/data_decoder/public/cpp/safe_json_parser.h similarity index 68% rename from components/safe_json/safe_json_parser.h rename to services/data_decoder/public/cpp/safe_json_parser.h index 6b66ba43..c1fee50 100644 --- a/components/safe_json/safe_json_parser.h +++ b/services/data_decoder/public/cpp/safe_json_parser.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 COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_H_ -#define COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_H_ +#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_H_ +#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_H_ #include <memory> #include <string> @@ -14,7 +14,11 @@ class Value; } -namespace safe_json { +namespace service_manager { +class Connector; +} + +namespace data_decoder { // SafeJsonParser parses a given JSON safely via a platform-dependent mechanism // (like parsing it in a utility process or in a memory-safe environment). @@ -32,7 +36,11 @@ // Starts parsing the passed in |unsafe_json| and calls either // |success_callback| or |error_callback| when finished. - static void Parse(const std::string& unsafe_json, + // |connector| is the connector provided by the service manager and is used + // to retrieve the JSON decoder service. It's commonly retrieved from a + // service manager connection context object that the embedder provides. + static void Parse(service_manager::Connector* connector, + const std::string& unsafe_json, const SuccessCallback& success_callback, const ErrorCallback& error_callback); @@ -45,6 +53,6 @@ virtual void Start() = 0; }; -} // namespace safe_json +} // namespace data_decoder -#endif // COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_H_ +#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_H_
diff --git a/components/safe_json/safe_json_parser_android.cc b/services/data_decoder/public/cpp/safe_json_parser_android.cc similarity index 85% rename from components/safe_json/safe_json_parser_android.cc rename to services/data_decoder/public/cpp/safe_json_parser_android.cc index 0994ef5..22cd156 100644 --- a/components/safe_json/safe_json_parser_android.cc +++ b/services/data_decoder/public/cpp/safe_json_parser_android.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/safe_json_parser_android.h" +#include "services/data_decoder/public/cpp/safe_json_parser_android.h" #include <utility> #include "base/bind.h" #include "base/json/json_reader.h" #include "base/values.h" -#include "components/safe_json/json_sanitizer.h" +#include "services/data_decoder/public/cpp/json_sanitizer.h" -namespace safe_json { +namespace data_decoder { SafeJsonParserAndroid::SafeJsonParserAndroid( const std::string& unsafe_json, @@ -25,6 +25,7 @@ void SafeJsonParserAndroid::Start() { JsonSanitizer::Sanitize( + /*connector=*/nullptr, // connector is unused on Android. unsafe_json_, base::Bind(&SafeJsonParserAndroid::OnSanitizationSuccess, base::Unretained(this)), @@ -55,4 +56,4 @@ delete this; } -} // namespace safe_json +} // namespace data_decoder
diff --git a/components/safe_json/safe_json_parser_android.h b/services/data_decoder/public/cpp/safe_json_parser_android.h similarity index 73% rename from components/safe_json/safe_json_parser_android.h rename to services/data_decoder/public/cpp/safe_json_parser_android.h index 520a2db..8c94019 100644 --- a/components/safe_json/safe_json_parser_android.h +++ b/services/data_decoder/public/cpp/safe_json_parser_android.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_ANDROID_H_ -#define COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_ANDROID_H_ +#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_ANDROID_H_ +#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_ANDROID_H_ #include <memory> #include "base/macros.h" -#include "components/safe_json/safe_json_parser.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" -namespace safe_json { +namespace data_decoder { class SafeJsonParserAndroid : public SafeJsonParser { public: @@ -36,6 +36,6 @@ DISALLOW_COPY_AND_ASSIGN(SafeJsonParserAndroid); }; -} // namespace safe_json +} // namespace data_decoder -#endif // COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_ANDROID_H_ +#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_ANDROID_H_
diff --git a/components/safe_json/safe_json_parser_impl.cc b/services/data_decoder/public/cpp/safe_json_parser_impl.cc similarity index 73% rename from components/safe_json/safe_json_parser_impl.cc rename to services/data_decoder/public/cpp/safe_json_parser_impl.cc index 9694dad8..c7efaa59 100644 --- a/components/safe_json/safe_json_parser_impl.cc +++ b/services/data_decoder/public/cpp/safe_json_parser_impl.cc
@@ -2,38 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/safe_json_parser_impl.h" +#include "services/data_decoder/public/cpp/safe_json_parser_impl.h" #include "base/callback.h" #include "base/sequenced_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/browser_thread.h" -#include "ui/base/l10n/l10n_util.h" +#include "services/data_decoder/public/interfaces/constants.mojom.h" +#include "services/service_manager/public/cpp/connector.h" -namespace safe_json { +namespace data_decoder { -SafeJsonParserImpl::SafeJsonParserImpl(const std::string& unsafe_json, +SafeJsonParserImpl::SafeJsonParserImpl(service_manager::Connector* connector, + const std::string& unsafe_json, const SuccessCallback& success_callback, const ErrorCallback& error_callback) : unsafe_json_(unsafe_json), success_callback_(success_callback), - error_callback_(error_callback) {} + error_callback_(error_callback) { + connector->BindInterface(mojom::kServiceName, &json_parser_ptr_); +} SafeJsonParserImpl::~SafeJsonParserImpl() = default; void SafeJsonParserImpl::Start() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - mojo_json_parser_.reset( - new content::UtilityProcessMojoClient<mojom::SafeJsonParser>( - l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_JSON_PARSER_NAME))); - mojo_json_parser_->set_error_callback(base::Bind( + json_parser_ptr_.set_connection_error_handler(base::Bind( &SafeJsonParserImpl::OnConnectionError, base::Unretained(this))); - mojo_json_parser_->Start(); - - mojo_json_parser_->service()->Parse( + json_parser_ptr_->Parse( std::move(unsafe_json_), base::Bind(&SafeJsonParserImpl::OnParseDone, base::Unretained(this))); } @@ -42,7 +39,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Shut down the utility process. - mojo_json_parser_.reset(); + json_parser_ptr_.reset(); ReportResults(nullptr, "Connection error with the json parser process."); } @@ -52,7 +49,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Shut down the utility process. - mojo_json_parser_.reset(); + json_parser_ptr_.reset(); ReportResults(std::move(result), error.value_or("")); } @@ -73,4 +70,4 @@ delete this; } -} // namespace safe_json +} // namespace data_decoder
diff --git a/components/safe_json/safe_json_parser_impl.h b/services/data_decoder/public/cpp/safe_json_parser_impl.h similarity index 68% rename from components/safe_json/safe_json_parser_impl.h rename to services/data_decoder/public/cpp/safe_json_parser_impl.h index 54da8dc..a17a91ae 100644 --- a/components/safe_json/safe_json_parser_impl.h +++ b/services/data_decoder/public/cpp/safe_json_parser_impl.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 COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_IMPL_H_ -#define COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_IMPL_H_ +#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_IMPL_H_ +#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_IMPL_H_ #include <memory> #include <string> @@ -12,19 +12,23 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/threading/thread_checker.h" -#include "components/safe_json/public/interfaces/safe_json.mojom.h" -#include "components/safe_json/safe_json_parser.h" -#include "content/public/browser/utility_process_mojo_client.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" +#include "services/data_decoder/public/interfaces/json_parser.mojom.h" namespace base { class Value; } -namespace safe_json { +namespace service_manager { +class Connector; +} + +namespace data_decoder { class SafeJsonParserImpl : public SafeJsonParser { public: - SafeJsonParserImpl(const std::string& unsafe_json, + SafeJsonParserImpl(service_manager::Connector* connector, + const std::string& unsafe_json, const SuccessCallback& success_callback, const ErrorCallback& error_callback); @@ -50,14 +54,13 @@ SuccessCallback success_callback_; ErrorCallback error_callback_; - std::unique_ptr<content::UtilityProcessMojoClient<mojom::SafeJsonParser>> - mojo_json_parser_; + mojom::JsonParserPtr json_parser_ptr_; SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(SafeJsonParserImpl); }; -} // namespace safe_json +} // namespace data_decoder -#endif // COMPONENTS_SAFE_JSON_SAFE_JSON_PARSER_IMPL_H_ +#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_PARSER_IMPL_H_
diff --git a/components/safe_json/testing_json_parser.cc b/services/data_decoder/public/cpp/testing_json_parser.cc similarity index 93% rename from components/safe_json/testing_json_parser.cc rename to services/data_decoder/public/cpp/testing_json_parser.cc index c2f9639a..c3eac72 100644 --- a/components/safe_json/testing_json_parser.cc +++ b/services/data_decoder/public/cpp/testing_json_parser.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/testing_json_parser.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include <memory> @@ -14,7 +14,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" -namespace safe_json { +namespace data_decoder { namespace { @@ -58,4 +58,4 @@ : base::Bind(error_callback_, error)); } -} // namespace +} // namespace data_decoder
diff --git a/components/safe_json/testing_json_parser.h b/services/data_decoder/public/cpp/testing_json_parser.h similarity index 79% rename from components/safe_json/testing_json_parser.h rename to services/data_decoder/public/cpp/testing_json_parser.h index 4acde1f..f75b9f7 100644 --- a/components/safe_json/testing_json_parser.h +++ b/services/data_decoder/public/cpp/testing_json_parser.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_SAFE_JSON_TESTING_JSON_PARSER_H_ -#define COMPONENTS_SAFE_JSON_TESTING_JSON_PARSER_H_ +#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_TESTING_JSON_PARSER_H_ +#define SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_TESTING_JSON_PARSER_H_ #include "base/macros.h" -#include "components/safe_json/safe_json_parser.h" +#include "services/data_decoder/public/cpp/safe_json_parser.h" -namespace safe_json { +namespace data_decoder { // An implementation of SafeJsonParser that parses JSON in process. This can be // used in unit tests to avoid having to set up the multiprocess infrastructure @@ -44,6 +44,6 @@ DISALLOW_COPY_AND_ASSIGN(TestingJsonParser); }; -} // namespace +} // namespace data_decoder -#endif // COMPONENTS_SAFE_JSON_TESTING_JSON_PARSER_H_ +#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_SAFE_JSON_TESTING_JSON_PARSER_H_
diff --git a/components/safe_json/testing_json_parser_unittest.cc b/services/data_decoder/public/cpp/testing_json_parser_unittest.cc similarity index 87% rename from components/safe_json/testing_json_parser_unittest.cc rename to services/data_decoder/public/cpp/testing_json_parser_unittest.cc index 63f638fa..f6df1e8 100644 --- a/components/safe_json/testing_json_parser_unittest.cc +++ b/services/data_decoder/public/cpp/testing_json_parser_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/safe_json/testing_json_parser.h" +#include "services/data_decoder/public/cpp/testing_json_parser.h" #include <memory> @@ -13,7 +13,7 @@ #include "base/values.h" #include "testing/gtest/include/gtest/gtest.h" -namespace safe_json { +namespace data_decoder { namespace { const char kTestJson[] = "{\"key\":2}"; @@ -22,7 +22,7 @@ public: void Parse(const std::string& input) { base::RunLoop run_loop; - SafeJsonParser::Parse(input, + SafeJsonParser::Parse(/* connector=*/nullptr, input, base::Bind(&SuccessCallback, base::Unretained(this), run_loop.QuitClosure()), base::Bind(&ErrorCallback, base::Unretained(this), @@ -30,8 +30,8 @@ run_loop.Run(); } - bool did_success() { return did_success_; } - bool did_error() { return did_error_; } + bool did_success() const { return did_success_; } + bool did_error() const { return did_error_; } private: static void SuccessCallback(TestingJsonParserTest* test, @@ -76,4 +76,4 @@ } } // namespace -} // namespace safe_json +} // namespace data_decoder
diff --git a/services/data_decoder/public/interfaces/BUILD.gn b/services/data_decoder/public/interfaces/BUILD.gn index 9d79f22e..7af99699 100644 --- a/services/data_decoder/public/interfaces/BUILD.gn +++ b/services/data_decoder/public/interfaces/BUILD.gn
@@ -7,6 +7,7 @@ mojom("interfaces") { sources = [ "image_decoder.mojom", + "json_parser.mojom", ] public_deps = [
diff --git a/components/safe_json/public/interfaces/safe_json.mojom b/services/data_decoder/public/interfaces/json_parser.mojom similarity index 84% rename from components/safe_json/public/interfaces/safe_json.mojom rename to services/data_decoder/public/interfaces/json_parser.mojom index c5c5d74..502a16b 100644 --- a/components/safe_json/public/interfaces/safe_json.mojom +++ b/services/data_decoder/public/interfaces/json_parser.mojom
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module safe_json.mojom; +module data_decoder.mojom; import "mojo/common/values.mojom"; -interface SafeJsonParser { +interface JsonParser { Parse(string json) => (mojo.common.mojom.Value? result, string? error); };
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc b/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc index f5d2b53..5890753f 100644 --- a/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc +++ b/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc
@@ -7,6 +7,7 @@ #include <vector> #include "base/process/process_handle.h" +#include "base/time/time.h" #include "services/resource_coordinator/coordination_unit/coordination_unit_base.h" #include "services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h" #include "services/resource_coordinator/coordination_unit/page_coordination_unit_impl.h" @@ -33,6 +34,12 @@ process_info->pid = pid; DCHECK_NE(base::kNullProcessId, process_info->pid); + int64_t launch_time; + if (process_cu->GetProperty(mojom::PropertyType::kLaunchTime, + &launch_time)) { + process_info->launch_time = base::Time::FromTimeT(launch_time); + } + std::set<CoordinationUnitBase*> page_cus = process_cu->GetAssociatedCoordinationUnitsOfType( CoordinationUnitType::kPage);
diff --git a/services/resource_coordinator/public/interfaces/coordination_unit_introspector.mojom b/services/resource_coordinator/public/interfaces/coordination_unit_introspector.mojom index e3bdac4b..3767566c 100644 --- a/services/resource_coordinator/public/interfaces/coordination_unit_introspector.mojom +++ b/services/resource_coordinator/public/interfaces/coordination_unit_introspector.mojom
@@ -18,6 +18,7 @@ struct ProcessInfo { mojo.common.mojom.ProcessId pid; array<PageInfo> page_infos; + mojo.common.mojom.Time? launch_time; }; interface CoordinationUnitIntrospector {
diff --git a/services/resource_coordinator/public/interfaces/signals.mojom b/services/resource_coordinator/public/interfaces/signals.mojom index 11f3ad76..36d3e97 100644 --- a/services/resource_coordinator/public/interfaces/signals.mojom +++ b/services/resource_coordinator/public/interfaces/signals.mojom
@@ -23,6 +23,7 @@ kAudible, kCPUUsage, kExpectedTaskQueueingDuration, + kLaunchTime, // Network is considered almost idle when there's no more than 2 network // connections. kNetworkAlmostIdle,
diff --git a/services/service_manager/background/background_service_manager.cc b/services/service_manager/background/background_service_manager.cc index 50c4953..0a71196 100644 --- a/services/service_manager/background/background_service_manager.cc +++ b/services/service_manager/background/background_service_manager.cc
@@ -25,19 +25,6 @@ #include "services/service_manager/standalone/context.h" namespace service_manager { -namespace { - -// Calls |callback| on |callback_task_runner|'s thread. -void CallCallbackWithIdentity( - const scoped_refptr<base::TaskRunner> callback_task_runner, - const base::Callback<void(const Identity&)>& callback, - const Identity& identity) { - DCHECK(callback); - DCHECK(identity.IsValid()); - callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, identity)); -} - -} // namespace BackgroundServiceManager::BackgroundServiceManager( service_manager::ServiceProcessLauncherDelegate* launcher_delegate, @@ -82,29 +69,6 @@ base::Passed(&pid_receiver_request))); } -void BackgroundServiceManager::SetInstanceQuitCallback( - base::Callback<void(const Identity&)> callback) { - DCHECK(callback); - // Hop to the background thread. The provided callback will be called on - // whichever thread called this function. - background_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind( - &BackgroundServiceManager::SetInstanceQuitCallbackOnBackgroundThread, - base::Unretained(this), base::ThreadTaskRunnerHandle::Get(), - callback)); -} - -void BackgroundServiceManager::SetInstanceQuitCallbackOnBackgroundThread( - const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, - const base::Callback<void(const Identity&)>& callback) { - DCHECK(callback_task_runner); - DCHECK(callback); - // Calls |callback| with the identity of the service that is quitting. - context_->service_manager()->SetInstanceQuitCallback( - base::Bind(&CallCallbackWithIdentity, callback_task_runner, callback)); -} - void BackgroundServiceManager::InitializeOnBackgroundThread( service_manager::ServiceProcessLauncherDelegate* launcher_delegate, std::unique_ptr<base::Value> catalog_contents) {
diff --git a/services/service_manager/background/background_service_manager.h b/services/service_manager/background/background_service_manager.h index 551f673..ef62ffa3 100644 --- a/services/service_manager/background/background_service_manager.h +++ b/services/service_manager/background/background_service_manager.h
@@ -7,18 +7,15 @@ #include <memory> -#include "base/callback_forward.h" #include "base/macros.h" #include "base/threading/thread.h" #include "base/values.h" #include "build/build_config.h" -#include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/interfaces/connector.mojom.h" #include "services/service_manager/public/interfaces/service.mojom.h" #include "services/service_manager/runner/host/service_process_launcher_delegate.h" namespace base { -class SingleThreadTaskRunner; class WaitableEvent; } @@ -50,12 +47,6 @@ mojom::ServicePtr service, mojom::PIDReceiverRequest pid_receiver_request); - // Provide a callback to be notified whenever a service is destroyed. - // Typically the creator of BackgroundServiceManager will use this to shut - // down when some set of services it created is destroyed. The |callback| is - // called on whichever thread called this function. - void SetInstanceQuitCallback(base::Callback<void(const Identity&)> callback); - private: void InitializeOnBackgroundThread( service_manager::ServiceProcessLauncherDelegate* launcher_delegate, @@ -66,10 +57,6 @@ const Identity& identity, mojom::ServicePtrInfo service_info, mojom::PIDReceiverRequest pid_receiver_request); - void SetInstanceQuitCallbackOnBackgroundThread( - const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, - const base::Callback<void(const Identity&)>& callback); - void OnInstanceQuitOnBackgroundThread(const Identity& identity); base::Thread background_thread_;
diff --git a/services/service_manager/background/tests/background_service_manager_unittest.cc b/services/service_manager/background/tests/background_service_manager_unittest.cc index a9de8b9..c1514a3 100644 --- a/services/service_manager/background/tests/background_service_manager_unittest.cc +++ b/services/service_manager/background/tests/background_service_manager_unittest.cc
@@ -66,41 +66,5 @@ EXPECT_TRUE(got_result); } -// The out param cannot be last due to base::Bind() currying. -void QuitCallback(bool* callback_called, - const base::Closure& quit_closure, - const Identity& identity) { - EXPECT_EQ(kAppName, identity.name()); - *callback_called = true; - quit_closure.Run(); -} - -// Verifies that quitting a service invokes the quit callback. -TEST(BackgroundServiceManagerTest, SetInstanceQuitCallback) { - BackgroundServiceManager background_service_manager(nullptr, nullptr); - base::MessageLoop message_loop; - mojom::ServicePtr service; - ServiceContext service_context(base::MakeUnique<ServiceImpl>(), - mojo::MakeRequest(&service)); - background_service_manager.RegisterService( - Identity(kTestName, mojom::kRootUserID), std::move(service), nullptr); - - mojom::TestServicePtr test_service; - service_context.connector()->BindInterface(kAppName, &test_service); - - // Set a callback for when the service quits that will quit |run_loop|. - base::RunLoop run_loop; - bool callback_called = false; - background_service_manager.SetInstanceQuitCallback( - base::Bind(&QuitCallback, &callback_called, run_loop.QuitClosure())); - - // Ask the service to quit itself. - test_service->Quit(); - run_loop.Run(); - - // The run loop was quit by the callback and not by something else. - EXPECT_TRUE(callback_called); -} - } // namespace } // namespace service_manager
diff --git a/services/service_manager/embedder/main.cc b/services/service_manager/embedder/main.cc index 87ac6f0..cd6e88f5 100644 --- a/services/service_manager/embedder/main.cc +++ b/services/service_manager/embedder/main.cc
@@ -219,18 +219,6 @@ base::debug::WaitForDebugger(120, true); } -// Quits |run_loop| if the |identity| of the quitting service is critical to the -// system (e.g. the window manager). Used in the main process. -void OnInstanceQuit(MainDelegate* delegate, - base::RunLoop* run_loop, - int* exit_code, - const service_manager::Identity& identity) { - if (delegate->ShouldTerminateServiceManagerOnInstanceQuit(identity, - exit_code)) { - run_loop->Quit(); - } -} - int RunServiceManager(MainDelegate* delegate) { NonEmbedderProcessInit(); @@ -251,10 +239,6 @@ &service_process_launcher_delegate, delegate->CreateServiceCatalog()); base::RunLoop run_loop; - int exit_code = 0; - background_service_manager.SetInstanceQuitCallback( - base::Bind(&OnInstanceQuit, delegate, &run_loop, &exit_code)); - delegate->OnServiceManagerInitialized(run_loop.QuitClosure(), &background_service_manager); run_loop.Run(); @@ -262,7 +246,7 @@ ipc_thread.Stop(); base::TaskScheduler::GetInstance()->Shutdown(); - return exit_code; + return 0; } void InitializeResources() {
diff --git a/services/service_manager/embedder/main_delegate.cc b/services/service_manager/embedder/main_delegate.cc index 08804b4..11b7c3fa 100644 --- a/services/service_manager/embedder/main_delegate.cc +++ b/services/service_manager/embedder/main_delegate.cc
@@ -39,12 +39,6 @@ const Identity& identity, base::CommandLine* command_line) {} -bool MainDelegate::ShouldTerminateServiceManagerOnInstanceQuit( - const Identity& identity, - int* exit_code) { - return false; -} - void MainDelegate::OnServiceManagerInitialized( const base::Closure& quit_closure, BackgroundServiceManager* service_manager) {}
diff --git a/services/service_manager/embedder/main_delegate.h b/services/service_manager/embedder/main_delegate.h index 4b29a413..0c6d11a 100644 --- a/services/service_manager/embedder/main_delegate.h +++ b/services/service_manager/embedder/main_delegate.h
@@ -85,13 +85,6 @@ virtual void AdjustServiceProcessCommandLine(const Identity& identity, base::CommandLine* command_line); - // Allows the embedder to terminate its Service Manager if any specific - // service instances quit. If this returns |true|, |*exit_code| will be - // returned from the Service Manager's process on exit. - virtual bool ShouldTerminateServiceManagerOnInstanceQuit( - const Identity& identity, - int* exit_code); - // Allows the embedder to perform arbitrary initialization within the Service // Manager process immediately before the Service Manager runs its main loop. //
diff --git a/services/service_manager/sandbox/mac/renderer.sb b/services/service_manager/sandbox/mac/renderer.sb index 88ea7847..4a5d5cc 100644 --- a/services/service_manager/sandbox/mac/renderer.sb +++ b/services/service_manager/sandbox/mac/renderer.sb
@@ -40,6 +40,9 @@ (allow file-read-data (subpath "/usr/share/zoneinfo.default")) (allow file-read-data (subpath "/usr/share/zoneinfo"))) +; Allow access to the metadata of the /etc symlink. +(allow file-read-metadata (path "/etc")) +; Allow access to the symlink target as well. (allow file-read-metadata (path "/private/etc")) ; https://crbug.com/605840
diff --git a/services/ui/ime/ime_unittest.cc b/services/ui/ime/ime_unittest.cc index 4c68af5d..9586a97 100644 --- a/services/ui/ime/ime_unittest.cc +++ b/services/ui/ime/ime_unittest.cc
@@ -44,7 +44,6 @@ DispatchKeyEventPostIMECallback callback) override { std::move(callback).Run(false); } - void SetCandidateWindowVisible(bool visible) override {} mojo::Binding<ui::mojom::TextInputClient> binding_; std::unique_ptr<base::RunLoop> run_loop_;
diff --git a/services/ui/public/interfaces/ime/ime.mojom b/services/ui/public/interfaces/ime/ime.mojom index a71fb1b..b9b8169e 100644 --- a/services/ui/public/interfaces/ime/ime.mojom +++ b/services/ui/public/interfaces/ime/ime.mojom
@@ -177,9 +177,6 @@ // Dispatch a key event skipping IME. Returns true if event was consumed. DispatchKeyEventPostIME(ui.mojom.Event event) => (bool stopped_propagation); - // Sending visibility status of candidate pop up window to client. - SetCandidateWindowVisible(bool visible); - // TODO(moshayedi): Add functions corresponding to ui::TextInputClient for: // - Input context information // - Document content operations
diff --git a/testing/buildbot/filters/ash_unittests_mash.filter b/testing/buildbot/filters/ash_unittests_mash.filter index dce8a67..1174b57d 100644 --- a/testing/buildbot/filters/ash_unittests_mash.filter +++ b/testing/buildbot/filters/ash_unittests_mash.filter
@@ -342,6 +342,9 @@ -WorkspaceLayoutManagerKeyboardTest.IgnoreWorkAreaChangeinNonStickyMode # TODO: fix these. They fail because DeviceDataManager isn't created. # http://crbug.com/734812. +-PaletteTrayTestWithInternalStylus.WelcomeBubbleShownOnEject +-PaletteTrayTestWithInternalStylus.WelcomeBubbleNotShownIfShownBefore +-PaletteTrayTestWithInternalStylus.WelcomeBubbleNotShownIfAutoOpenPaletteTrue -TrayIMETest.HidesOnA11yEnabled -TrayIMETest.PerformActionOnDetailedView -VirtualKeyboardAlwaysOnTopControllerTest.NotifyKeyboardBoundsChanged
diff --git a/testing/buildbot/filters/ash_unittests_mus.filter b/testing/buildbot/filters/ash_unittests_mus.filter index 97fcb0b..3a5287f0 100644 --- a/testing/buildbot/filters/ash_unittests_mus.filter +++ b/testing/buildbot/filters/ash_unittests_mus.filter
@@ -1,5 +1,8 @@ # TODO: fix these. They fail because DeviceDataManager isn't created. # http://crbug.com/734812. +-PaletteTrayTestWithInternalStylus.WelcomeBubbleShownOnEject +-PaletteTrayTestWithInternalStylus.WelcomeBubbleNotShownIfShownBefore +-PaletteTrayTestWithInternalStylus.WelcomeBubbleNotShownIfAutoOpenPaletteTrue -TouchCalibratorControllerTest.CustomCalibration -TouchCalibratorControllerTest.CustomCalibrationInvalidTouchId -TouchCalibratorControllerTest.TouchDeviceIdIsSet
diff --git a/testing/buildbot/filters/mus.browser_tests.filter b/testing/buildbot/filters/mus.browser_tests.filter index 46ead00a..777bc35 100644 --- a/testing/buildbot/filters/mus.browser_tests.filter +++ b/testing/buildbot/filters/mus.browser_tests.filter
@@ -34,3 +34,6 @@ -WebViewTests/WebViewSizeTest.Shim_TestAutosizeRemoveAttributes/0 -WebViewTests/WebViewSizeTest.Shim_TestAutosizeRemoveAttributes/1 -WebViewTests/WebViewTest.InterstitialPageFocusedWidget/1 + +# content::WaitForChildFrameSurfaceReady unsupported, https://crbug.com/774269. +-WebViewTests/WebViewTest.ReloadAfterCrash/1
diff --git a/testing/buildbot/filters/site-per-process.browser_tests.filter b/testing/buildbot/filters/site-per-process.browser_tests.filter index 06787d05..43e7746 100644 --- a/testing/buildbot/filters/site-per-process.browser_tests.filter +++ b/testing/buildbot/filters/site-per-process.browser_tests.filter
@@ -6,21 +6,10 @@ -PrerenderBrowserTest.PrerenderLocationReplaceGWSHistograms -ProcessManagementTest.ExtensionProcessBalancing -ProcessManagementTest.ProcessOverflow --RedirectTest.ClientEmptyReferer --ReferrerPolicyTest.HttpsRedirect # crbug.com/671734: WebNavigationApiTest.ServerRedirectSingleProcess from # fails with --site-per-process -WebNavigationApiTest.ServerRedirectSingleProcess -# crbug.com/671712: All 4 IsolatedAppTest tests time out with --site-per-process +# crbug.com/671712: CookieIsolation test fails with --site-per-process -IsolatedAppTest.CookieIsolation --IsolatedAppTest.CrossProcessClientRedirect --IsolatedAppTest.IsolatedAppProcessModel --IsolatedAppTest.SubresourceCookieIsolation - -# crbug.com/669299: Wrong view frame source with --site-per-process --ChromeNavigationBrowserTest.TestViewFrameSource - -# crbug.com/670362: Flaky failure (expected MouseDown not found) --DevToolsPixelOutputTests.TestLatencyInfoInstrumentation
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index fa61f3ad..907b21d 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -305,6 +305,21 @@ ] } ], + "AndroidSigninPromos": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AndroidSigninPromos" + ] + } + ] + } + ], "AndroidSpellChecker": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index caf91fe..7534d9d1 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3766,5 +3766,4 @@ # Sheriff failures 2017-10-13 crbug.com/774437 [ Win10 ] paint/invalidation/selection-partial-invalidation-between-blocks.html [ Pass Failure ] -crbug.com/773957 paint/invalidation/raster-under-invalidation-checking.html [ Failure Pass ] crbug.com/774463 [ Win7 Debug ] fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px-expected.txt new file mode 100644 index 0000000..c5846bc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px-expected.txt
@@ -0,0 +1,12 @@ +This is a testharness.js-based test. +PASS SVGLength, converting from 'px' to other units (detached), unitless +FAIL SVGLength, converting from 'px' to other units (detached), percentage Failed to execute 'convertToSpecifiedUnits' on 'SVGLength': Could not resolve relative length. +FAIL SVGLength, converting from 'px' to other units (detached), ems Failed to execute 'convertToSpecifiedUnits' on 'SVGLength': Could not resolve relative length. +FAIL SVGLength, converting from 'px' to other units (detached), exs Failed to execute 'convertToSpecifiedUnits' on 'SVGLength': Could not resolve relative length. +PASS SVGLength, converting from 'px' to other units (detached), cm +PASS SVGLength, converting from 'px' to other units (detached), mm +PASS SVGLength, converting from 'px' to other units (detached), in +PASS SVGLength, converting from 'px' to other units (detached), pt +PASS SVGLength, converting from 'px' to other units (detached), pc +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLength-px-with-context.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px-with-context.html similarity index 62% rename from third_party/WebKit/LayoutTests/svg/dom/SVGLength-px-with-context.html rename to third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px-with-context.html index f2ed394c..c92ec7c 100644 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLength-px-with-context.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px-with-context.html
@@ -1,7 +1,7 @@ <!DOCTYPE HTML> <title>SVGLength, converting from 'px' to other units (attached)</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <p></p> <script> var cssPixelsPerInch = 96; @@ -20,9 +20,7 @@ window.length = rectElement.x.baseVal; window.svgWidth = svgElement.width.baseVal.value; window.svgHeight = svgElement.height.baseVal.value; - window.fontSize = parseInt(rectElement.style.fontSize); - // TODO(shanmuga.m) : // Since calculateXHeight() triggers force layout, relative length units are resolved. - // So make convertToSpecifiedUnits to update pending style sheet and do relayout if needed. + window.fontSize = 12; window.xHeight = calculateXHeight(); function calculateXHeight() { @@ -47,82 +45,82 @@ }, document.title + ", unitless"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "3px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE); - var referenceValue = Number(2 / svgWidth * 100).toFixed(5); + var referenceValue = 3 / svgWidth * 100; assert_equals(length.valueAsString, referenceValue + "%"); - assert_equals(length.valueInSpecifiedUnits.toFixed(5), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 3); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PERCENTAGE); }, document.title + ", percentage"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "6px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_EMS); - var referenceValue = Number(2 / fontSize).toFixed(6); + var referenceValue = 6 / fontSize; assert_equals(length.valueAsString, referenceValue + "em"); - assert_equals(length.valueInSpecifiedUnits.toFixed(6), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 6); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_EMS); }, document.title + ", ems"); test(function() { length.valueAsString = "2px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_EXS); - var referenceValue = Number(2 / xHeight).toFixed(1); + var referenceValue = 2 / xHeight; // Don't check valueAsString here, it's unreliable across browsers. - assert_equals(length.valueInSpecifiedUnits.toFixed(1), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.1); + assert_approx_equals(length.value, 2.0, 0.1); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_EXS); }, document.title + " , exs"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "48px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_CM); - var referenceValue = Number(2 * 2.54 / cssPixelsPerInch).toFixed(7); - assert_equals(length.valueAsString, referenceValue + "cm"); - assert_equals(length.valueInSpecifiedUnits.toFixed(7), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + var referenceValue = 48 * 2.54 / cssPixelsPerInch; + assert_equals(length.valueAsString, referenceValue.toFixed(2) + "cm"); + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.001); + assert_equals(length.value, 48); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_CM); }, document.title + ", cm"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "48px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_MM); - var referenceValue = Number(2 * 25.4 / cssPixelsPerInch).toFixed(6); - assert_equals(length.valueAsString, referenceValue + "mm"); - assert_equals(length.valueInSpecifiedUnits.toFixed(6), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + var referenceValue = 48 * 25.4 / cssPixelsPerInch; + assert_equals(length.valueAsString, referenceValue.toFixed(1) + "mm"); + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.001); + assert_equals(length.value, 48); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_MM); }, document.title + ", mm"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "48px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_IN); - var referenceValue = Number(2 / cssPixelsPerInch).toFixed(7); + var referenceValue = 48 / cssPixelsPerInch; assert_equals(length.valueAsString, referenceValue + "in"); - assert_equals(length.valueInSpecifiedUnits.toFixed(7), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 48); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_IN); }, document.title + ", in"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "4px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PT); - var referenceValue = Number(2 / cssPixelsPerInch * 72); + var referenceValue = 4 / cssPixelsPerInch * 72; assert_equals(length.valueAsString, referenceValue + "pt"); assert_equals(length.valueInSpecifiedUnits, referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + assert_equals(length.value, 4); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PT); }, document.title + ", pt"); test(function() { - length.valueAsString = "2px"; + length.valueAsString = "16px"; length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PC); - var referenceValue = Number(2 / cssPixelsPerInch * 6).toFixed(3); + var referenceValue = 16 / cssPixelsPerInch * 6; // Don't check valueAsString here, it's unreliable across browsers. - assert_equals(length.valueInSpecifiedUnits.toFixed(3), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 16); assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PC); }, document.title + ", pc"); </script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px.html new file mode 100644 index 0000000..a91e4e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength-px.html
@@ -0,0 +1,122 @@ +<!DOCTYPE HTML> +<title>SVGLength, converting from 'px' to other units (detached)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<p></p> +<script> +var cssPixelsPerInch = 96; +setup(function() { + window.svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svgElement.setAttribute("style", "visibility: hidden; font-size: initial; font-family: initial;"); + window.fontSize = parseInt(getComputedStyle(svgElement).fontSize); + window.xHeight = calculateXHeight(); + + function calculateXHeight() { + // Crude hack to calculate the x-height + var divElement = document.createElement("div"); + divElement.setAttribute("style", "height: 1ex; font-size: initial; font-family: initial;"); + var pElement = document.querySelector("p"); + pElement.appendChild(divElement); + var xHeight = divElement.offsetHeight; + pElement.removeChild(divElement); + return xHeight; + } +}); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "2px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_NUMBER); + assert_equals(length.valueAsString, "2"); + assert_equals(length.value, 2); + assert_equals(length.valueInSpecifiedUnits, 2); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_NUMBER); +}, document.title + ", unitless"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "2px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE); + assert_equals(length.valueAsString, "2%"); + assert_equals(length.value, 2); + assert_equals(length.valueInSpecifiedUnits, 2); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PERCENTAGE); +}, document.title + ", percentage"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "2px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_EMS); + var referenceValue = 2 / fontSize; + assert_equals(length.valueAsString, referenceValue.toFixed(6) + "em"); + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.1); + assert_approx_equals(length.value, 2.0, 0.1); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_EMS); +}, document.title + ", ems"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "2px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_EXS); + var referenceValue = 2 / xHeight; + // Don't check valueAsString here, it's unreliable across browsers. + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.1); + assert_approx_equals(length.value, 2.0, 0.1); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_EXS); +}, document.title + ", exs"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "48px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_CM); + var referenceValue = 48 * 2.54 / cssPixelsPerInch; + assert_equals(length.valueAsString, referenceValue.toFixed(2) + "cm"); + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.01); + assert_equals(length.value, 48); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_CM); +}, document.title + ", cm"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "48px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_MM); + var referenceValue = 48 * 25.4 / cssPixelsPerInch; + assert_equals(length.valueAsString, referenceValue.toFixed(1) + "mm"); + assert_approx_equals(length.valueInSpecifiedUnits, referenceValue, 0.01); + assert_equals(length.value, 48); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_MM); +}, document.title + ", mm"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "48px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_IN); + var referenceValue = 48 / cssPixelsPerInch; + assert_equals(length.valueAsString, referenceValue + "in"); + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 48); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_IN); +}, document.title + ", in"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "4px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PT); + var referenceValue = 4 / cssPixelsPerInch * 72; + assert_equals(length.valueAsString, referenceValue + "pt"); + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 4); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PT); +}, document.title + ", pt"); + +test(function() { + var length = svgElement.createSVGLength(); + length.valueAsString = "16px"; + length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PC); + var referenceValue = 16 / cssPixelsPerInch * 6; + // Don't check valueAsString here, it's unreliable across browsers. + assert_equals(length.valueInSpecifiedUnits, referenceValue); + assert_equals(length.value, 16); + assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PC); +}, document.title + ", pc"); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLength.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html similarity index 97% rename from third_party/WebKit/LayoutTests/svg/dom/SVGLength.html rename to third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html index e215fa5..22256c05 100644 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLength.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLength.html
@@ -1,7 +1,7 @@ <!DOCTYPE HTML> <title>SVGLength interface</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <script> test(function() { var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-appendItem.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-appendItem.html similarity index 95% rename from third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-appendItem.html rename to third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-appendItem.html index b9c98c6..5af8dbf 100644 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-appendItem.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-appendItem.html
@@ -1,7 +1,7 @@ <!DOCTYPE HTML> <title>SVGLengthList, appendItem()</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <script src="resources/SVGLengthList-helper.js"></script> <svg width="200" height="200"> <text id="text1" x="500 50 100 900 1000" y="50">ABC</text> @@ -47,7 +47,7 @@ newLength2.value = 150; assert_equals(newLength2.value, 150); list1.clear(); - + // Shuffle around items in text1 and text2 list using appendItem, to get x=50,100,150,... in both lists. assert_equals(list1.appendItem(list2.getItem(0)).value, 50); assert_equals(list1.appendItem(list2.getItem(1)).value, 100);
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-appendItemFromClearedList.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-appendItemFromClearedList.html similarity index 79% rename from third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-appendItemFromClearedList.html rename to third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-appendItemFromClearedList.html index 2eede91c..e76491ec 100644 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-appendItemFromClearedList.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-appendItemFromClearedList.html
@@ -1,7 +1,7 @@ <!DOCTYPE HTML> <title>SVGLengthList, appendItem() from cleared list</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <script src="resources/SVGLengthList-helper.js"></script> <svg width="200" height="200"> <text id="text1" x="1 2 3">ABC</text> @@ -14,12 +14,12 @@ var list1 = document.getElementById("text1").x.baseVal; var list2 = document.getElementById("text2").x.baseVal; - var itemFromClearedList = list2.getItem(0); + var itemFromClearedList = list2.getItem(0); list2.clear(); assert_equals(list2.numberOfItems, 0); list1.appendItem(itemFromClearedList); - + assert_list(list1, [1, 2, 3, 10]); assert_equals(list2.numberOfItems, 0); });
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-basics.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-basics.html similarity index 98% rename from third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-basics.html rename to third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-basics.html index 2c1a5212..58d0e93 100644 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-basics.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-basics.html
@@ -1,7 +1,7 @@ <!DOCTYPE HTML> <title>SVGLengthList, basics</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"> <text x="500 1000 1500" y="50"> ABC </text> </svg>
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-getItem.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-getItem.html similarity index 87% rename from third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-getItem.html rename to third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-getItem.html index 10a2c13f..c81a2339 100644 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLengthList-getItem.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGLengthList-getItem.html
@@ -1,7 +1,7 @@ <!DOCTYPE HTML> <title>SVGLengthList, getItem()</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <svg width="200" height="200"> <text x="50 100 150" y="50">ABC</text> </svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/resources/SVGLengthList-helper.js b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/resources/SVGLengthList-helper.js new file mode 100644 index 0000000..3cf888b7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/resources/SVGLengthList-helper.js
@@ -0,0 +1,7 @@ +function assert_list(list, expectedValues) { + assert_equals(list.numberOfItems, expectedValues.length); + for (var index = 0; index < expectedValues.length; ++index) + assert_equals(list.getItem(index).value, expectedValues[index]); + + assert_throws("IndexSizeError", function() { list.getItem(expectedValues.length); }); +} \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/contentscripts-navigator-multiple-frames.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/contentscripts-navigator-multiple-frames.html index abdbb4d6..b518c4a7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/contentscripts-navigator-multiple-frames.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/contentscripts-navigator-multiple-frames.html
@@ -1,5 +1,6 @@ <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach-expected.txt index 3050c76..d7282dd0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach-expected.txt
@@ -9,6 +9,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachFrame @@ -19,6 +20,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame (dynamic-frame.html) 127.0.0.1:8000 @@ -36,5 +38,6 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.html index e6432f65..9d19596 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/dynamic-navigator-frame-attach-detach.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach-expected.txt index 7497c3af..0d67051 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach-expected.txt
@@ -9,6 +9,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachFrame @@ -19,6 +20,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame (magic-frame.html) 127.0.0.1:8000 @@ -35,5 +37,6 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach.html index e08fc09..d17a6a9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-attach-detach.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate-expected.txt index 33aaf14..5a4d3de 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate-expected.txt
@@ -10,6 +10,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachFrame @@ -20,6 +21,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame (magic-frame.html) 127.0.0.1:8000 @@ -36,6 +38,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame (empty-frame.html) 127.0.0.1:8000
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate.html index eab1f18..700e2ed 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-frame-navigate.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated-expected.txt index f2ed157..62a47f6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated-expected.txt
@@ -9,6 +9,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachFrame @@ -19,6 +20,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame (sourcemap-frame.html) 127.0.0.1:8000
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated.html index bc0fe32..2892c5e1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-main-frame-navigated.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames-expected.txt index 57f5f7a..558c1f7d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames-expected.txt
@@ -9,6 +9,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: createIframes @@ -19,6 +20,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame1 (magic-frame.html) 127.0.0.1:8000 @@ -41,6 +43,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame2 (magic-frame.html) 127.0.0.1:8000 @@ -57,5 +60,6 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames.html index 219a6c3..f34573ca 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/navigator-multiple-frames.html
@@ -1,5 +1,6 @@ <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator-expected.txt index 6a53eef..fdefdb6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator-expected.txt
@@ -9,6 +9,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachShadow1 @@ -22,6 +23,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) sourcemap-script.js @@ -38,6 +40,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) sourcemap-script.js @@ -54,6 +57,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) sourcemap-script.js @@ -69,6 +73,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) sourcemap-script.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator.html index aff0bdc..f643b1b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/shadowdom-navigator.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames-expected.txt index dfade61..31cd40d0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames-expected.txt
@@ -9,6 +9,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachFrame1 @@ -19,6 +20,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) _test_create-iframe1.js @@ -39,6 +41,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) _test_create-iframe1.js @@ -68,6 +71,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) _test_create-iframe1.js @@ -90,6 +94,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) _test_create-iframe1.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames.html index 796c2545..643dde2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/sourcemap-navigator-multiple-frames.html
@@ -1,5 +1,6 @@ <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator-expected.txt index 41360f0..0bce313f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator-expected.txt
@@ -10,6 +10,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js Running: attachFramesAndWaitForSourceMaps @@ -20,6 +21,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js (no domain) _test_create-iframe1.js @@ -73,6 +75,7 @@ inspector bindings bindings-test.js + debugger-test.js inspector-test.js frame2 (sourcemap-frame.html) 127.0.0.1:8000
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator.html b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator.html index f075ba7..8c9358d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/bindings/suspendtarget-navigator.html
@@ -1,5 +1,6 @@ <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/bindings/bindings-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt index 47f2976..5ab68993 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker-expected.txt
@@ -10,7 +10,7 @@ ======== load ======== == Raw -[expanded] WindowRemoveevent-listeners-framework-with-service-worker.html:53 +[expanded] WindowRemoveevent-listeners-framework-with-service-worker.html:54 useCapture: false passive: false once: false
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html index 18d1eca0..bf2ace9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/event-listeners-framework-with-service-worker.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/elements-test.js"></script> <script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/console-test.js"></script> <script src="../../inspector/service-workers/service-workers-test.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt index 6ac5cc6..adfb0970 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
@@ -5,6 +5,7 @@ devtools/elements/styles styles-do-not-add-inline-stylesheets-in-navigator.html inspector + debugger-test.js elements-test.js inspector-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html index 30656d8..f26a1604 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../../inspector/inspector-test.js"></script> +<script src="../../../inspector/debugger-test.js"></script> <script src="../../../inspector/elements-test.js"></script> <style> </style>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt index 68c226f..a3060af 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add-expected.txt
@@ -7,6 +7,7 @@ Resources: document http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css +script http://127.0.0.1:8000/inspector/debugger-test.js script http://127.0.0.1:8000/inspector/inspector-test.js script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js script http://127.0.0.1:8000/inspector/resources-test.js @@ -14,6 +15,7 @@ Resources URL Map: http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html == http://127.0.0.1:8000/devtools/resource-tree/resource-tree-frame-add.html http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css +http://127.0.0.1:8000/inspector/debugger-test.js == http://127.0.0.1:8000/inspector/debugger-test.js http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js @@ -22,6 +24,7 @@ Frames top Scripts + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -32,6 +35,7 @@ -------- Setting mode: [frame] top resource-tree-frame-add.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -41,6 +45,7 @@ top 127.0.0.1:8000 resource-tree-frame-add.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -56,12 +61,14 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js Sources: -------- Setting mode: [domain] 127.0.0.1:8000 resource-tree-frame-add.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -76,6 +83,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js @@ -87,6 +95,7 @@ script http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css +script http://127.0.0.1:8000/inspector/debugger-test.js script http://127.0.0.1:8000/inspector/inspector-test.js script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js script http://127.0.0.1:8000/inspector/resources-test.js @@ -97,6 +106,7 @@ http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js == http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css +http://127.0.0.1:8000/inspector/debugger-test.js == http://127.0.0.1:8000/inspector/debugger-test.js http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js @@ -111,6 +121,7 @@ styles-navigated.css resource-tree-frame-add-iframe.html Scripts + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -121,6 +132,7 @@ -------- Setting mode: [frame] top resource-tree-frame-add.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -134,6 +146,7 @@ top 127.0.0.1:8000 resource-tree-frame-add.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -154,6 +167,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js resource-tree-frame-add-iframe.html @@ -167,6 +181,7 @@ 127.0.0.1:8000 resource-tree-frame-add-iframe.html resource-tree-frame-add.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -186,6 +201,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html index d161377..5256e04 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-add.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/resources-test.js"></script> <script src="../../inspector/resource-tree/resource-tree-test.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt index ef827ba..5be4b8b 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate-expected.txt
@@ -10,6 +10,7 @@ script http://127.0.0.1:8000/devtools/resource-tree/resources/script-initial.js stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial-2.css stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css +script http://127.0.0.1:8000/inspector/debugger-test.js script http://127.0.0.1:8000/inspector/inspector-test.js script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js script http://127.0.0.1:8000/inspector/resources-test.js @@ -20,6 +21,7 @@ http://127.0.0.1:8000/devtools/resource-tree/resources/script-initial.js == http://127.0.0.1:8000/devtools/resource-tree/resources/script-initial.js http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial-2.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial-2.css http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css +http://127.0.0.1:8000/inspector/debugger-test.js == http://127.0.0.1:8000/inspector/debugger-test.js http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js @@ -34,6 +36,7 @@ styles-initial-2.css resource-tree-frame-navigate-iframe-before.html Scripts + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -44,6 +47,7 @@ -------- Setting mode: [frame] top resource-tree-frame-navigate.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -57,6 +61,7 @@ top 127.0.0.1:8000 resource-tree-frame-navigate.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -77,6 +82,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js iframe (resource-tree-frame-navigate-iframe-before.html) @@ -90,6 +96,7 @@ 127.0.0.1:8000 resource-tree-frame-navigate-iframe-before.html resource-tree-frame-navigate.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -109,6 +116,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js @@ -120,6 +128,7 @@ script http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css stylesheet http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css +script http://127.0.0.1:8000/inspector/debugger-test.js script http://127.0.0.1:8000/inspector/inspector-test.js script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js script http://127.0.0.1:8000/inspector/resources-test.js @@ -130,6 +139,7 @@ http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js == http://127.0.0.1:8000/devtools/resource-tree/resources/script-navigated.js http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-initial.css http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css == http://127.0.0.1:8000/devtools/resource-tree/resources/styles-navigated.css +http://127.0.0.1:8000/inspector/debugger-test.js == http://127.0.0.1:8000/inspector/debugger-test.js http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js @@ -144,6 +154,7 @@ styles-navigated.css resource-tree-frame-navigate-iframe-after.html Scripts + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -154,6 +165,7 @@ -------- Setting mode: [frame] top resource-tree-frame-navigate.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -167,6 +179,7 @@ top 127.0.0.1:8000 resource-tree-frame-navigate.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -187,6 +200,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js iframe (resource-tree-frame-navigate-iframe-after.html) @@ -200,6 +214,7 @@ 127.0.0.1:8000 resource-tree-frame-navigate-iframe-after.html resource-tree-frame-navigate.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -219,6 +234,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html index 33eaafd4..dc973b2d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-frame-navigate.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/resources-test.js"></script> <script src="../../inspector/resource-tree/resource-tree-test.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt index 0924bbf3..2be88e9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports-expected.txt
@@ -5,6 +5,7 @@ document http://127.0.0.1:8000/devtools/resource-tree/resources/import-child.html document http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.html script http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.js +script http://127.0.0.1:8000/inspector/debugger-test.js script http://127.0.0.1:8000/inspector/inspector-test.js script http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js script http://127.0.0.1:8000/inspector/resources-test.js @@ -14,6 +15,7 @@ http://127.0.0.1:8000/devtools/resource-tree/resources/import-child.html == http://127.0.0.1:8000/devtools/resource-tree/resources/import-child.html http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.html == http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.html http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.js == http://127.0.0.1:8000/devtools/resource-tree/resources/import-hello.js +http://127.0.0.1:8000/inspector/debugger-test.js == http://127.0.0.1:8000/inspector/debugger-test.js http://127.0.0.1:8000/inspector/inspector-test.js == http://127.0.0.1:8000/inspector/inspector-test.js http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js == http://127.0.0.1:8000/inspector/resource-tree/resource-tree-test.js http://127.0.0.1:8000/inspector/resources-test.js == http://127.0.0.1:8000/inspector/resources-test.js @@ -22,6 +24,7 @@ Frames top Scripts + debugger-test.js import-hello.js inspector-test.js resource-tree-test.js @@ -35,6 +38,7 @@ import-child.html import-hello.html resource-tree-htmlimports.html + debugger-test.js import-hello.js inspector-test.js resource-tree-test.js @@ -46,6 +50,7 @@ import-child.html import-hello.html resource-tree-htmlimports.html + debugger-test.js import-hello.js inspector-test.js resource-tree-test.js @@ -63,6 +68,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js Sources: @@ -71,6 +77,7 @@ import-child.html import-hello.html resource-tree-htmlimports.html + debugger-test.js import-hello.js inspector-test.js resource-tree-test.js @@ -87,6 +94,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html index 91cbacc..e544fa8 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-htmlimports.html
@@ -5,6 +5,7 @@ <!-- import-hello.html shouldn't be shown twice as it shares same resource as above --> <link rel="import" href="resources/import-hello.html"> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/resources-test.js"></script> <script src="../../inspector/resource-tree/resource-tree-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt index 8874372d..c8d2ecc4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url-expected.txt
@@ -11,6 +11,7 @@ styles-non-unique-url.css resource-tree-non-unique-url-iframe.html Scripts + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -19,6 +20,7 @@ -------- Setting mode: [frame] top resource-tree-non-unique-url.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -30,6 +32,7 @@ top 127.0.0.1:8000 resource-tree-non-unique-url.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -46,6 +49,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js resource-tree-non-unique-url-iframe.html @@ -58,6 +62,7 @@ 127.0.0.1:8000 resource-tree-non-unique-url-iframe.html resource-tree-non-unique-url.html + debugger-test.js inspector-test.js resource-tree-test.js resources-test.js @@ -73,6 +78,7 @@ inspector resource-tree resource-tree-test.js + debugger-test.js inspector-test.js resources-test.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html index f188eb7..a0bbe10 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resource-tree/resource-tree-non-unique-url.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../inspector/inspector-test.js"></script> +<script src="../../inspector/debugger-test.js"></script> <script src="../../inspector/resources-test.js"></script> <script src="../../inspector/resource-tree/resource-tree-test.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/ui-source-code-display-name.html b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/ui-source-code-display-name.html index 1a5c1f4..d407e43 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/ui-source-code-display-name.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-ui/ui-source-code-display-name.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../../inspector/inspector-test.js"></script> +<script src="../../../inspector/debugger-test.js"></script> <script> async function test() { async function dumpUISourceCodeDisplayName(url) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js index c7533259..7aa28191 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js
@@ -451,4 +451,21 @@ } } +InspectorTest.wrapListener = function(func) +{ + function wrapper() + { + var wrapArgs = arguments; + var wrapThis = this; + // Give a chance to other listeners. + setTimeout(apply, 0); + + function apply() + { + func.apply(wrapThis, wrapArgs); + } + } + return wrapper; +} + }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js index 02dd2e8..cb58484 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
@@ -425,6 +425,44 @@ return UI.viewManager.showView("elements.eventListeners"); } +InspectorTest.expandAndDumpEventListeners = function(eventListenersView, callback, force) +{ + function listenersArrived() + { + var listenerTypes = eventListenersView._treeOutline.rootElement().children(); + for (var i = 0; i < listenerTypes.length; ++i) { + listenerTypes[i].expand(); + var listenerItems = listenerTypes[i].children(); + for (var j = 0; j < listenerItems.length; ++j) + listenerItems[j].expand(); + } + InspectorTest.deprecatedRunAfterPendingDispatches(objectsExpanded); + } + + function objectsExpanded() + { + var listenerTypes = eventListenersView._treeOutline.rootElement().children(); + for (var i = 0; i < listenerTypes.length; ++i) { + if (!listenerTypes[i].children().length) + continue; + var eventType = listenerTypes[i]._title; + InspectorTest.addResult(""); + InspectorTest.addResult("======== " + eventType + " ========"); + var listenerItems = listenerTypes[i].children(); + for (var j = 0; j < listenerItems.length; ++j) { + InspectorTest.addResult("== " + listenerItems[j].eventListener().origin()); + InspectorTest.dumpObjectPropertyTreeElement(listenerItems[j]); + } + } + callback(); + } + + if (force) + listenersArrived(); + else + InspectorTest.addSniffer(EventListeners.EventListenersView.prototype, "_eventListenersArrivedForTest", listenersArrived); +} + InspectorTest.expandAndDumpSelectedElementEventListeners = function(callback, force) { InspectorTest.expandAndDumpEventListeners(InspectorTest.eventListenersWidget()._eventListenersView, callback, force);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js index ad38b4b..d0ac1053 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -40,6 +40,9 @@ results = []; } +/** + * TestRunner.evaluateInPage inserts sourceURL by inspecting the call stack. + */ InspectorTest.evaluateInPage = async function(code, callback) { var response = await InspectorTest.RuntimeAgent.invoke_evaluate({ @@ -50,19 +53,6 @@ InspectorTest.safeWrap(callback)(InspectorTest.runtimeModel.createRemoteObject(response.result), response.exceptionDetails); } -InspectorTest.addScriptUISourceCode = function(url, content, isContentScript, worldId) { - content += '\n//# sourceURL=' + url; - if (isContentScript) - content = `testRunner.evaluateScriptInIsolatedWorld(${worldId}, \`${content}\`)`; - InspectorTest.evaluateInPagePromise(content); - return InspectorTest.waitForUISourceCode(url); -}; - -InspectorTest.evaluateInPagePromise = function(code) -{ - return new Promise(succ => InspectorTest.evaluateInPage(code, succ)); -} - InspectorTest.addResult = function(text) { results.push(String(text)); @@ -84,95 +74,6 @@ return ".../" + value.substr(lastIndex); } -InspectorTest.expandAndDumpEventListeners = function(eventListenersView, callback, force) -{ - function listenersArrived() - { - var listenerTypes = eventListenersView._treeOutline.rootElement().children(); - for (var i = 0; i < listenerTypes.length; ++i) { - listenerTypes[i].expand(); - var listenerItems = listenerTypes[i].children(); - for (var j = 0; j < listenerItems.length; ++j) - listenerItems[j].expand(); - } - InspectorTest.deprecatedRunAfterPendingDispatches(objectsExpanded); - } - - function objectsExpanded() - { - var listenerTypes = eventListenersView._treeOutline.rootElement().children(); - for (var i = 0; i < listenerTypes.length; ++i) { - if (!listenerTypes[i].children().length) - continue; - var eventType = listenerTypes[i]._title; - InspectorTest.addResult(""); - InspectorTest.addResult("======== " + eventType + " ========"); - var listenerItems = listenerTypes[i].children(); - for (var j = 0; j < listenerItems.length; ++j) { - InspectorTest.addResult("== " + listenerItems[j].eventListener().origin()); - InspectorTest.dumpObjectPropertyTreeElement(listenerItems[j]); - } - } - callback(); - } - - if (force) - listenersArrived(); - else - InspectorTest.addSniffer(EventListeners.EventListenersView.prototype, "_eventListenersArrivedForTest", listenersArrived); -}; - -InspectorTest.dumpNavigatorView = function(navigatorView, dumpIcons) -{ - dumpNavigatorTreeOutline(navigatorView._scriptsTree); - - function dumpNavigatorTreeElement(prefix, treeElement) - { - var titleText = ''; - if (treeElement._leadingIconsElement && dumpIcons) { - var icons = treeElement._leadingIconsElement.querySelectorAll('[is=ui-icon]'); - icons = Array.prototype.slice.call(icons); - var iconTypes = icons.map(icon => icon._iconType); - if (iconTypes.length) - titleText = titleText + "[" + iconTypes.join(", ") + "] "; - } - titleText += treeElement.title; - if (treeElement._nodeType === Sources.NavigatorView.Types.FileSystem || treeElement._nodeType === Sources.NavigatorView.Types.FileSystemFolder) { - var hasMappedFiles = treeElement.listItemElement.classList.contains("has-mapped-files"); - if (!hasMappedFiles) - titleText += " [dimmed]"; - } - InspectorTest.addResult(prefix + titleText); - treeElement.expand(); - var children = treeElement.children(); - for (var i = 0; i < children.length; ++i) - dumpNavigatorTreeElement(prefix + " ", children[i]); - } - - function dumpNavigatorTreeOutline(treeOutline) - { - var children = treeOutline.rootElement().children(); - for (var i = 0; i < children.length; ++i) - dumpNavigatorTreeElement("", children[i]); - } -} - -InspectorTest.dumpNavigatorViewInAllModes = function(view) -{ - ["frame", "frame/domain", "frame/domain/folder", "domain", "domain/folder"].forEach(InspectorTest.dumpNavigatorViewInMode.bind(InspectorTest, view)); -} - -InspectorTest.dumpNavigatorViewInMode = function(view, mode) -{ - InspectorTest.addResult(view instanceof Sources.SourcesNavigatorView ? "Sources:" : "Content Scripts:"); - view._groupByFrame = mode.includes("frame"); - view._groupByDomain = mode.includes("domain"); - view._groupByFolder = mode.includes("folder"); - view._resetForTest(); - InspectorTest.addResult("-------- Setting mode: [" + mode + "]"); - InspectorTest.dumpNavigatorView(view); -} - InspectorTest.navigate = function(url, callback) { InspectorTest._pageLoadedCallback = InspectorTest.safeWrap(callback); @@ -254,23 +155,6 @@ runner(); } -InspectorTest.wrapListener = function(func) -{ - function wrapper() - { - var wrapArgs = arguments; - var wrapThis = this; - // Give a chance to other listeners. - setTimeout(apply, 0); - - function apply() - { - func.apply(wrapThis, wrapArgs); - } - } - return wrapper; -} - InspectorTest.addConsoleSniffer = function(override, opt_sticky) { InspectorTest.addSniffer(ConsoleModel.ConsoleModel.prototype, "addMessage", override, opt_sticky);
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-pause-in-tight-loop.js b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-pause-in-tight-loop.js index dbdafcb..a6fd1b776 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-pause-in-tight-loop.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-pause-in-tight-loop.js
@@ -12,13 +12,9 @@ var message_id = 1; var ts = Date.now(); while (!terminated) { - // Without this try/catch v8 will optimize the function and break will not work. - try { - if (Date.now() - ts > 1000) { - ts = Date.now(); - console.error('Message #' + message_id++); - } - } catch (e) { + if (Date.now() - ts > 1000) { + ts = Date.now(); + console.error('Message #' + message_id++); } } }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/raster-under-invalidation-checking.html b/third_party/WebKit/LayoutTests/paint/invalidation/raster-under-invalidation-checking.html index fbe5b6c..b52a17c 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/raster-under-invalidation-checking.html +++ b/third_party/WebKit/LayoutTests/paint/invalidation/raster-under-invalidation-checking.html
@@ -1,4 +1,6 @@ <!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script src="resources/text-based-repaint.js"></script> <style> [id^="target"] { width: 60px; @@ -16,8 +18,6 @@ <div style="width: 4000px; height: 20000px"></div> <div id="target4" style="position: relative; top: -10000px; left: 30px"></div> </div> -<script src="../../resources/run-after-layout-and-paint.js"></script> -<script src="resources/text-based-repaint.js"></script> <script> window.testIsAsync = true;
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLength-px.html b/third_party/WebKit/LayoutTests/svg/dom/SVGLength-px.html deleted file mode 100644 index d1b1841..0000000 --- a/third_party/WebKit/LayoutTests/svg/dom/SVGLength-px.html +++ /dev/null
@@ -1,108 +0,0 @@ -<!DOCTYPE HTML> -<title>SVGLength, converting from 'px' to other units (detached)</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script> -var cssPixelsPerInch = 96; -setup(function() { - window.svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); -}); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_NUMBER); - assert_equals(length.valueAsString, "2"); - assert_equals(length.value, 2); - assert_equals(length.valueInSpecifiedUnits, 2); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_NUMBER); -}, document.title + ", unitless"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - // Try converting from px to percentage, should fail as the SVGLength is not associated with a SVGSVGElement, and thus no viewport information is available. - assert_throws("NotSupportedError", function() { length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE); }); - assert_equals(length.valueAsString, "2px"); - assert_equals(length.value, 2); - assert_equals(length.valueInSpecifiedUnits, 2); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PX); -}, document.title + ", percentage"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - // Try converting from px to ems, should fail as the SVGLength is not associated with a SVGSVGElement, and thus no font-size information is available. - assert_throws("NotSupportedError", function() { length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_EMS); }); - assert_equals(length.valueAsString, "2px"); - assert_equals(length.value, 2); - assert_equals(length.valueInSpecifiedUnits, 2); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PX); -}, document.title + ", ems"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - // Try converting from px to exs, should fail as the SVGLength is not associated with a SVGSVGElement, and thus no font-size information is available. - assert_throws("NotSupportedError", function() { length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_EXS); }); - assert_equals(length.valueAsString, "2px"); - assert_equals(length.value, 2); - assert_equals(length.valueInSpecifiedUnits, 2); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PX); -}, document.title + ", exs"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_CM); - var referenceValue = Number(2 * 2.54 / cssPixelsPerInch).toFixed(7); - assert_equals(length.valueAsString, referenceValue + "cm"); - assert_equals(length.valueInSpecifiedUnits.toFixed(7), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_CM); -}, document.title + ", cm"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_MM); - var referenceValue = Number(2 * 25.4 / cssPixelsPerInch).toFixed(6); - assert_equals(length.valueAsString, referenceValue + "mm"); - assert_equals(length.valueInSpecifiedUnits.toFixed(6), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_MM); -}, document.title + ", mm"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_IN); - var referenceValue = Number(2 / cssPixelsPerInch).toFixed(7); - assert_equals(length.valueAsString, referenceValue + "in"); - assert_equals(length.valueInSpecifiedUnits.toFixed(7), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_IN); -}, document.title + ", in"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PT); - var referenceValue = Number(2 / cssPixelsPerInch * 72); - assert_equals(length.valueAsString, referenceValue + "pt"); - assert_equals(length.valueInSpecifiedUnits, referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PT); -}, document.title + ", pt"); - -test(function() { - var length = svgElement.createSVGLength(); - length.valueAsString = "2px"; - length.convertToSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PC); - var referenceValue = Number(2 / cssPixelsPerInch * 6).toFixed(3); - // Don't check valueAsString here, it's unreliable across browsers. - assert_equals(length.valueInSpecifiedUnits.toFixed(3), referenceValue); - assert_equals(length.value.toFixed(1), "2.0"); - assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_PC); -}, document.title + ", pc"); -</script> \ No newline at end of file
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp index 1cb9fb0..a5b6cd1 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp +++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp
@@ -39,16 +39,6 @@ return GetImage() && GetImage()->IsTextureBacked(); } -int CSSStyleImageValue::SourceHeight() { - bool not_used; - return intrinsicHeight(not_used); -} - -int CSSStyleImageValue::SourceWidth() { - bool not_used; - return intrinsicWidth(not_used); -} - RefPtr<Image> CSSStyleImageValue::GetImage() const { if (IsCachePending()) return nullptr;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h index 94142b6..f514c6a 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h +++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
@@ -33,8 +33,6 @@ // CanvasImageSource bool IsCSSImageValue() const final { return true; } - int SourceWidth() final; - int SourceHeight() final; bool WouldTaintOrigin( SecurityOrigin* destination_security_origin) const final { return true;
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index 29348d42..0f76ca55 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -980,7 +980,8 @@ // skip position in non-laid out or invisible node const LayoutObject* const layout_object = - AssociatedLayoutObjectOf(*current_node, current_pos.OffsetInLeafNode()); + AssociatedLayoutObjectOf(*current_node, current_pos.OffsetInLeafNode(), + LayoutObjectSide::kFirstLetterIfOnBoundary); if (!layout_object || layout_object->Style()->Visibility() != EVisibility::kVisible) continue; @@ -1070,26 +1071,9 @@ return true; } -// Returns true if |text_layout_object| has visible first-letter. -bool HasVisibleFirstLetter(const LayoutText& text_layout_object) { - if (!text_layout_object.IsTextFragment()) - return false; - const LayoutTextFragment& layout_text_fragment = - ToLayoutTextFragment(text_layout_object); - if (!layout_text_fragment.IsRemainingTextLayoutObject()) - return false; - const LayoutObject* first_letter_layout_object = - layout_text_fragment.GetFirstLetterPseudoElement()->GetLayoutObject(); - if (!first_letter_layout_object) - return false; - return first_letter_layout_object->Style()->Visibility() == - EVisibility::kVisible; -} - // Returns true when both of the following hold: // (i) |offset_in_node| is not the first offset in |text_layout_object| // (ii) |offset_in_node| and |offset_in_node - 1| are different caret positions -// TODO(editing-dev): Document the behavior when there is ::first-letter. static bool CanBeBackwardCaretPosition(const LayoutText* text_layout_object, int offset_in_node) { const unsigned text_start_offset = text_layout_object->TextStartOffset(); @@ -1097,15 +1081,8 @@ const unsigned text_offset = offset_in_node - text_start_offset; InlineTextBox* const last_text_box = text_layout_object->LastTextBox(); for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { - if (text_offset == box->Start()) { - if (HasVisibleFirstLetter(*text_layout_object)) { - // |offset_in_node| is at start of remaining text of - // |Text| node with :first-letter. - DCHECK_GE(offset_in_node, 1); - return true; - } + if (text_offset == box->Start()) continue; - } if (text_offset <= box->Start() + box->Len()) { if (text_offset > box->Start()) return true;
diff --git a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp index 24e549fe..8ab110a9 100644 --- a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp +++ b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp
@@ -736,17 +736,15 @@ "more information.")); } else if (!web_frame_->Client()->OverrideLegacySymantecCertConsoleMessage( url, cert_validity_start, &console_message)) { - String port = url.Port() == 443 ? "" : String::Format(":%d", url.Port()); - console_message = WebString(String::Format( - "The SSL certificate used to load resources from %s://%s%s" - " will be " - "distrusted in the future. " - "Once distrusted, users will be prevented from " - "loading these resources. See " - "https://g.co/chrome/symantecpkicerts for " - "more information.", - url.Protocol().Utf8().data(), url.Host().Utf8().data(), - port.Utf8().data())); + console_message = WebString( + String::Format("The SSL certificate used to load resources from %s" + " will be " + "distrusted in the future. " + "Once distrusted, users will be prevented from " + "loading these resources. See " + "https://g.co/chrome/symantecpkicerts for " + "more information.", + SecurityOrigin::Create(url)->ToString().Utf8().data())); } num_certificate_warning_messages_++; certificate_warning_hosts_.insert(url.Host());
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h index bba6b9f0..d2e24ff 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -198,8 +198,6 @@ bool IsCanvasElement() const override { return true; } bool IsOpaque() const override; bool IsAccelerated() const override; - int SourceWidth() override { return size_.Width(); } - int SourceHeight() override { return size_.Height(); } // SurfaceLayerBridgeObserver implementation void OnWebLayerReplaced() override;
diff --git a/third_party/WebKit/Source/core/html/TextMetrics.h b/third_party/WebKit/Source/core/html/TextMetrics.h index b6dea140..d0bc91b 100644 --- a/third_party/WebKit/Source/core/html/TextMetrics.h +++ b/third_party/WebKit/Source/core/html/TextMetrics.h
@@ -39,63 +39,63 @@ public: static TextMetrics* Create() { return new TextMetrics; } - float width() const { return width_; } - void SetWidth(float w) { width_ = w; } + double width() const { return width_; } + void SetWidth(double w) { width_ = w; } - float actualBoundingBoxLeft() const { return actual_bounding_box_left_; } - void SetActualBoundingBoxLeft(float actual_bounding_box_left) { + double actualBoundingBoxLeft() const { return actual_bounding_box_left_; } + void SetActualBoundingBoxLeft(double actual_bounding_box_left) { actual_bounding_box_left_ = actual_bounding_box_left; } - float actualBoundingBoxRight() const { return actual_bounding_box_right_; } - void SetActualBoundingBoxRight(float actual_bounding_box_right) { + double actualBoundingBoxRight() const { return actual_bounding_box_right_; } + void SetActualBoundingBoxRight(double actual_bounding_box_right) { actual_bounding_box_right_ = actual_bounding_box_right; } - float fontBoundingBoxAscent() const { return font_bounding_box_ascent_; } - void SetFontBoundingBoxAscent(float font_bounding_box_ascent) { + double fontBoundingBoxAscent() const { return font_bounding_box_ascent_; } + void SetFontBoundingBoxAscent(double font_bounding_box_ascent) { font_bounding_box_ascent_ = font_bounding_box_ascent; } - float fontBoundingBoxDescent() const { return font_bounding_box_descent_; } - void SetFontBoundingBoxDescent(float font_bounding_box_descent) { + double fontBoundingBoxDescent() const { return font_bounding_box_descent_; } + void SetFontBoundingBoxDescent(double font_bounding_box_descent) { font_bounding_box_descent_ = font_bounding_box_descent; } - float actualBoundingBoxAscent() const { return actual_bounding_box_ascent_; } - void SetActualBoundingBoxAscent(float actual_bounding_box_ascent) { + double actualBoundingBoxAscent() const { return actual_bounding_box_ascent_; } + void SetActualBoundingBoxAscent(double actual_bounding_box_ascent) { actual_bounding_box_ascent_ = actual_bounding_box_ascent; } - float actualBoundingBoxDescent() const { + double actualBoundingBoxDescent() const { return actual_bounding_box_descent_; } - void SetActualBoundingBoxDescent(float actual_bounding_box_descent) { + void SetActualBoundingBoxDescent(double actual_bounding_box_descent) { actual_bounding_box_descent_ = actual_bounding_box_descent; } - float emHeightAscent() const { return em_height_ascent_; } - void SetEmHeightAscent(float em_height_ascent) { + double emHeightAscent() const { return em_height_ascent_; } + void SetEmHeightAscent(double em_height_ascent) { em_height_ascent_ = em_height_ascent; } - float emHeightDescent() const { return em_height_descent_; } - void SetEmHeightDescent(float em_height_descent) { + double emHeightDescent() const { return em_height_descent_; } + void SetEmHeightDescent(double em_height_descent) { em_height_descent_ = em_height_descent; } - float hangingBaseline() const { return hanging_baseline_; } - void SetHangingBaseline(float hanging_baseline) { + double hangingBaseline() const { return hanging_baseline_; } + void SetHangingBaseline(double hanging_baseline) { hanging_baseline_ = hanging_baseline; } - float alphabeticBaseline() const { return alphabetic_baseline_; } - void SetAlphabeticBaseline(float alphabetic_baseline) { + double alphabeticBaseline() const { return alphabetic_baseline_; } + void SetAlphabeticBaseline(double alphabetic_baseline) { alphabetic_baseline_ = alphabetic_baseline; } - float ideographicBaseline() const { return ideographic_baseline_; } - void SetIdeographicBaseline(float ideographic_baseline) { + double ideographicBaseline() const { return ideographic_baseline_; } + void SetIdeographicBaseline(double ideographic_baseline) { ideographic_baseline_ = ideographic_baseline; } @@ -117,20 +117,20 @@ ideographic_baseline_(0) {} // x-direction - float width_; - float actual_bounding_box_left_; - float actual_bounding_box_right_; + double width_; + double actual_bounding_box_left_; + double actual_bounding_box_right_; // y-direction - float font_bounding_box_ascent_; - float font_bounding_box_descent_; - float actual_bounding_box_ascent_; - float actual_bounding_box_descent_; - float em_height_ascent_; - float em_height_descent_; - float hanging_baseline_; - float alphabetic_baseline_; - float ideographic_baseline_; + double font_bounding_box_ascent_; + double font_bounding_box_descent_; + double actual_bounding_box_ascent_; + double actual_bounding_box_descent_; + double em_height_ascent_; + double em_height_descent_; + double hanging_baseline_; + double alphabetic_baseline_; + double ideographic_baseline_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/TextMetrics.idl b/third_party/WebKit/Source/core/html/TextMetrics.idl index 68b0ee4..5ee4a071 100644 --- a/third_party/WebKit/Source/core/html/TextMetrics.idl +++ b/third_party/WebKit/Source/core/html/TextMetrics.idl
@@ -25,22 +25,21 @@ // https://html.spec.whatwg.org/#textmetrics -// TODO(foolip): All float types in this interface should be double. // TODO(foolip): Exposed=(Window,Worker) interface TextMetrics { // x-direction readonly attribute float width; // advance width - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxLeft; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxRight; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double actualBoundingBoxLeft; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double actualBoundingBoxRight; // y-direction - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxAscent; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxDescent; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxAscent; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxDescent; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightAscent; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightDescent; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float hangingBaseline; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float alphabeticBaseline; - [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float ideographicBaseline; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double fontBoundingBoxAscent; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double fontBoundingBoxDescent; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double actualBoundingBoxAscent; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double actualBoundingBoxDescent; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double emHeightAscent; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double emHeightDescent; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double hangingBaseline; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double alphabeticBaseline; + [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute double ideographicBaseline; };
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h b/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h index c6a83c8..08b4cfd6 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
@@ -84,9 +84,6 @@ virtual bool IsOpaque() const { return false; } virtual bool IsAccelerated() const = 0; - virtual int SourceWidth() = 0; - virtual int SourceHeight() = 0; - protected: virtual ~CanvasImageSource() {} };
diff --git a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp b/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp index 0cffe51..1cf51db5 100644 --- a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp +++ b/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp
@@ -120,22 +120,6 @@ return CachedImage()->GetResponse().Url(); } -int ImageElementBase::SourceWidth() { - SourceImageStatus status; - RefPtr<Image> image = GetSourceImageForCanvas(&status, kPreferNoAcceleration, - kSnapshotReasonUnknown, - SourceDefaultObjectSize()); - return image->width(); -} - -int ImageElementBase::SourceHeight() { - SourceImageStatus status; - RefPtr<Image> image = GetSourceImageForCanvas(&status, kPreferNoAcceleration, - kSnapshotReasonUnknown, - SourceDefaultObjectSize()); - return image->height(); -} - bool ImageElementBase::IsOpaque() const { Image* image = const_cast<Element&>(GetElement()).ImageContents(); return image && image->CurrentFrameKnownToBeOpaque();
diff --git a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.h b/third_party/WebKit/Source/core/html/canvas/ImageElementBase.h index 27eae2e..20a0299 100644 --- a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.h +++ b/third_party/WebKit/Source/core/html/canvas/ImageElementBase.h
@@ -47,9 +47,6 @@ bool IsAccelerated() const override; - int SourceWidth() override; - int SourceHeight() override; - bool IsSVGSource() const override; bool IsOpaque() const override;
diff --git a/third_party/WebKit/Source/core/html/media/HTMLVideoElement.h b/third_party/WebKit/Source/core/html/media/HTMLVideoElement.h index 6b96b94..ec4886f 100644 --- a/third_party/WebKit/Source/core/html/media/HTMLVideoElement.h +++ b/third_party/WebKit/Source/core/html/media/HTMLVideoElement.h
@@ -128,8 +128,6 @@ FloatSize ElementSize(const FloatSize&) const override; const KURL& SourceURL() const override { return currentSrc(); } bool IsHTMLVideoElement() const override { return true; } - int SourceWidth() override { return videoWidth(); } - int SourceHeight() override { return videoHeight(); } // Video elements currently always go through RAM when used as a canvas image // source. bool IsAccelerated() const override { return false; }
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h index aad917e..8d4726e 100644 --- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h +++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h
@@ -125,8 +125,6 @@ void AdjustDrawRects(FloatRect* src_rect, FloatRect* dst_rect) const override; FloatSize ElementSize(const FloatSize&) const override; bool IsImageBitmap() const override { return true; } - int SourceWidth() override { return image_ ? image_->width() : 0; } - int SourceHeight() override { return image_ ? image_->height() : 0; } bool IsAccelerated() const override; // ImageBitmapSource implementation
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp index 788763c..5007861 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -3559,7 +3559,8 @@ // Punctuation characters are considered as first-letter. For "(1)ab", // "(1)" are first-letter part and "ab" are remaining part. const LayoutObject* AssociatedLayoutObjectOf(const Node& node, - int offset_in_node) { + int offset_in_node, + LayoutObjectSide object_side) { DCHECK_GE(offset_in_node, 0); LayoutObject* layout_object = node.GetLayoutObject(); if (!node.IsTextNode() || !layout_object || @@ -3573,9 +3574,14 @@ layout_text_fragment->Start() + layout_text_fragment->FragmentLength()); return layout_text_fragment; } - if (layout_text_fragment->FragmentLength() && - static_cast<unsigned>(offset_in_node) >= layout_text_fragment->Start()) - return layout_object; + if (layout_text_fragment->FragmentLength()) { + const unsigned threshold = + object_side == LayoutObjectSide::kRemainingTextIfOnBoundary + ? layout_text_fragment->Start() + : layout_text_fragment->Start() + 1; + if (static_cast<unsigned>(offset_in_node) >= threshold) + return layout_object; + } LayoutObject* first_letter_layout_object = layout_text_fragment->GetFirstLetterPseudoElement()->GetLayoutObject(); // TODO(yosin): We're not sure when |firstLetterLayoutObject| has
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h index 888be2a..1642869 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -2790,8 +2790,14 @@ return AdjustScrollForAbsoluteZoom(value, layout_object.StyleRef()); } -CORE_EXPORT const LayoutObject* AssociatedLayoutObjectOf(const Node&, - int offset_in_node); +enum class LayoutObjectSide { + kRemainingTextIfOnBoundary, + kFirstLetterIfOnBoundary +}; +CORE_EXPORT const LayoutObject* AssociatedLayoutObjectOf( + const Node&, + int offset_in_node, + LayoutObjectSide = LayoutObjectSide::kRemainingTextIfOnBoundary); #define DEFINE_LAYOUT_OBJECT_TYPE_CASTS(thisType, predicate) \ DEFINE_TYPE_CASTS(thisType, LayoutObject, object, object->predicate, \
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp index 9158a928..8c25a99 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTextTest.cpp
@@ -7,6 +7,7 @@ #include "core/layout/LayoutTestHelper.h" #include "core/layout/line/InlineTextBox.h" #include "platform/runtime_enabled_features.h" +#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink { @@ -96,8 +97,8 @@ } TEST_F(LayoutTextTest, CaretMinMaxOffsetNG) { - RuntimeEnabledFeatures::SetLayoutNGEnabled(true); - RuntimeEnabledFeatures::SetLayoutNGPaintFragmentsEnabled(true); + ScopedLayoutNGForTest layout_ng(true); + ScopedLayoutNGPaintFragmentsForTest layout_ng_paint_fragments(true); SetBasicBody("foo"); EXPECT_EQ(0, GetBasicText()->CaretMinOffset()); @@ -117,8 +118,8 @@ } TEST_F(LayoutTextTest, ResolvedTextLengthNG) { - RuntimeEnabledFeatures::SetLayoutNGEnabled(true); - RuntimeEnabledFeatures::SetLayoutNGPaintFragmentsEnabled(true); + ScopedLayoutNGForTest layout_ng(true); + ScopedLayoutNGPaintFragmentsForTest layout_ng_paint_fragments(true); SetBasicBody("foo"); EXPECT_EQ(3u, GetBasicText()->ResolvedTextLength());
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h index 4526261..932d6ba 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h
@@ -142,8 +142,6 @@ } bool IsOpaque() const final; bool IsAccelerated() const final; - int SourceWidth() final { return width(); } - int SourceHeight() final { return height(); } DispatchEventResult HostDispatchEvent(Event* event) { return DispatchEvent(event);
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 5631afc..05d5c58c 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -771,9 +771,9 @@ // y direction const FontMetrics& font_metrics = font_data->GetFontMetrics(); - const float ascent = font_metrics.FloatAscent(); - const float descent = font_metrics.FloatDescent(); - const float baseline_y = GetFontBaseline(font_metrics); + const double ascent = font_metrics.FloatAscent(); + const double descent = font_metrics.FloatDescent(); + const double baseline_y = GetFontBaseline(font_metrics); metrics->SetFontBoundingBoxAscent(ascent - baseline_y); metrics->SetFontBoundingBoxDescent(descent + baseline_y);
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp index 9419d995..0e96bf6 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -65,8 +65,6 @@ } bool IsOpaque() const override { return is_opaque_; } bool IsAccelerated() const { return false; } - int SourceWidth() override { return size_.Width(); } - int SourceHeight() override { return size_.Height(); } ~FakeImageSource() override {}
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp index 863d9b91..6b2bd538 100644 --- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp +++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
@@ -88,8 +88,7 @@ // there is a local WebCam associated, there might be sophisticated ways to // detect faces on it. Until then, treat as a normal <video> element. - const FloatSize size(canvas_image_source->SourceWidth(), - canvas_image_source->SourceHeight()); + const FloatSize size(canvas_image_source->ElementSize(FloatSize())); SourceImageStatus source_image_status = kInvalidSourceImageStatus; RefPtr<Image> image = canvas_image_source->GetSourceImageForCanvas(
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp index 536dbdb..36064fd 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp
@@ -136,8 +136,8 @@ return "AudioListener.upY"; case kParamTypeAudioListenerUpZ: return "AudioListener.upZ"; - case kParamTypeConstantSourceValue: - return "ConstantSource.sourceValue"; + case kParamTypeConstantSourceOffset: + return "ConstantSource.offset"; // TODO(hongchan): We can try to return the actual parameter name here if // possible. case kParamTypeAudioWorklet:
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.h b/third_party/WebKit/Source/modules/webaudio/AudioParam.h index 5f1deae..e6075ce 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioParam.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.h
@@ -82,7 +82,7 @@ kParamTypeAudioListenerUpX, kParamTypeAudioListenerUpY, kParamTypeAudioListenerUpZ, - kParamTypeConstantSourceValue, + kParamTypeConstantSourceOffset, kParamTypeAudioWorklet, };
diff --git a/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.cpp index e85d7f68..e6b9b78 100644 --- a/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.cpp
@@ -107,7 +107,7 @@ // ---------------------------------------------------------------- ConstantSourceNode::ConstantSourceNode(BaseAudioContext& context) : AudioScheduledSourceNode(context), - offset_(AudioParam::Create(context, kParamTypeConstantSourceValue, 1)) { + offset_(AudioParam::Create(context, kParamTypeConstantSourceOffset, 1)) { SetHandler(ConstantSourceHandler::Create(*this, context.sampleRate(), offset_->Handler())); }
diff --git a/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h b/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h index 3da1e9e..9f614fd 100644 --- a/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h +++ b/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h
@@ -153,6 +153,10 @@ RuntimeEnabledFeatures::SetLayoutNGEnabled> ScopedLayoutNGForTest; typedef ScopedRuntimeEnabledFeatureForTest< + RuntimeEnabledFeatures::LayoutNGPaintFragmentsEnabled, + RuntimeEnabledFeatures::SetLayoutNGPaintFragmentsEnabled> + ScopedLayoutNGPaintFragmentsForTest; +typedef ScopedRuntimeEnabledFeatureForTest< RuntimeEnabledFeatures::ClientPlaceholdersForServerLoFiEnabled, RuntimeEnabledFeatures::SetClientPlaceholdersForServerLoFiEnabled> ScopedClientPlaceholdersForServerLoFiForTest;
diff --git a/third_party/WebKit/Source/platform/text/BidiResolver.h b/third_party/WebKit/Source/platform/text/BidiResolver.h index 5a38812..3ae9aa0c 100644 --- a/third_party/WebKit/Source/platform/text/BidiResolver.h +++ b/third_party/WebKit/Source/platform/text/BidiResolver.h
@@ -434,60 +434,60 @@ // Isolated spans compute base directionality during their own UBA run. // Do not insert fake embed characters once we enter an isolated span. DCHECK(!InIsolate()); - using namespace WTF::Unicode; - DCHECK(dir == kPopDirectionalFormat || dir == kLeftToRightEmbedding || - dir == kLeftToRightOverride || dir == kRightToLeftEmbedding || - dir == kRightToLeftOverride); + DCHECK(dir == WTF::Unicode::kPopDirectionalFormat || + dir == WTF::Unicode::kLeftToRightEmbedding || + dir == WTF::Unicode::kLeftToRightOverride || + dir == WTF::Unicode::kRightToLeftEmbedding || + dir == WTF::Unicode::kRightToLeftOverride); current_explicit_embedding_sequence_.push_back(BidiEmbedding(dir, source)); } template <class Iterator, class Run, class IsolatedRun> void BidiResolver<Iterator, Run, IsolatedRun>:: CheckDirectionInLowerRaiseEmbeddingLevel() { - using namespace WTF::Unicode; - - DCHECK(status_.eor != kOtherNeutral || eor_.AtEnd()); - DCHECK_NE(status_.last, kNonSpacingMark); - DCHECK_NE(status_.last, kBoundaryNeutral); - DCHECK_NE(status_.last, kRightToLeftEmbedding); - DCHECK_NE(status_.last, kLeftToRightEmbedding); - DCHECK_NE(status_.last, kRightToLeftOverride); - DCHECK_NE(status_.last, kLeftToRightOverride); - DCHECK_NE(status_.last, kPopDirectionalFormat); - if (direction_ == kOtherNeutral) - direction_ = - status_.last_strong == kLeftToRight ? kLeftToRight : kRightToLeft; + DCHECK(status_.eor != WTF::Unicode::kOtherNeutral || eor_.AtEnd()); + DCHECK_NE(status_.last, WTF::Unicode::kNonSpacingMark); + DCHECK_NE(status_.last, WTF::Unicode::kBoundaryNeutral); + DCHECK_NE(status_.last, WTF::Unicode::kRightToLeftEmbedding); + DCHECK_NE(status_.last, WTF::Unicode::kLeftToRightEmbedding); + DCHECK_NE(status_.last, WTF::Unicode::kRightToLeftOverride); + DCHECK_NE(status_.last, WTF::Unicode::kLeftToRightOverride); + DCHECK_NE(status_.last, WTF::Unicode::kPopDirectionalFormat); + if (direction_ == WTF::Unicode::kOtherNeutral) { + direction_ = status_.last_strong == WTF::Unicode::kLeftToRight + ? WTF::Unicode::kLeftToRight + : WTF::Unicode::kRightToLeft; + } } template <class Iterator, class Run, class IsolatedRun> void BidiResolver<Iterator, Run, IsolatedRun>::LowerExplicitEmbeddingLevel( BidiRunList<Run>& runs, WTF::Unicode::CharDirection from) { - using namespace WTF::Unicode; - if (!empty_run_ && eor_ != last_) { CheckDirectionInLowerRaiseEmbeddingLevel(); // bidi.sor ... bidi.eor ... bidi.last eor; need to append the // bidi.sor-bidi.eor run or extend it through bidi.last - if (from == kLeftToRight) { + if (from == WTF::Unicode::kLeftToRight) { // bidi.sor ... bidi.eor ... bidi.last L - if (status_.eor == kEuropeanNumber) { - if (status_.last_strong != kLeftToRight) { - direction_ = kEuropeanNumber; + if (status_.eor == WTF::Unicode::kEuropeanNumber) { + if (status_.last_strong != WTF::Unicode::kLeftToRight) { + direction_ = WTF::Unicode::kEuropeanNumber; AppendRun(runs); } - } else if (status_.eor == kArabicNumber) { - direction_ = kArabicNumber; + } else if (status_.eor == WTF::Unicode::kArabicNumber) { + direction_ = WTF::Unicode::kArabicNumber; AppendRun(runs); - } else if (status_.last_strong != kLeftToRight) { + } else if (status_.last_strong != WTF::Unicode::kLeftToRight) { AppendRun(runs); - direction_ = kLeftToRight; + direction_ = WTF::Unicode::kLeftToRight; } - } else if (status_.eor == kEuropeanNumber || status_.eor == kArabicNumber || - status_.last_strong == kLeftToRight) { + } else if (status_.eor == WTF::Unicode::kEuropeanNumber || + status_.eor == WTF::Unicode::kArabicNumber || + status_.last_strong == WTF::Unicode::kLeftToRight) { AppendRun(runs); - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; } eor_ = last_; } @@ -506,34 +506,34 @@ BidiRunList<Run>& runs, WTF::Unicode::CharDirection from, WTF::Unicode::CharDirection to) { - using namespace WTF::Unicode; - if (!empty_run_ && eor_ != last_) { CheckDirectionInLowerRaiseEmbeddingLevel(); // bidi.sor ... bidi.eor ... bidi.last eor; need to append the // bidi.sor-bidi.eor run or extend it through bidi.last - if (to == kLeftToRight) { + if (to == WTF::Unicode::kLeftToRight) { // bidi.sor ... bidi.eor ... bidi.last L - if (status_.eor == kEuropeanNumber) { - if (status_.last_strong != kLeftToRight) { - direction_ = kEuropeanNumber; + if (status_.eor == WTF::Unicode::kEuropeanNumber) { + if (status_.last_strong != WTF::Unicode::kLeftToRight) { + direction_ = WTF::Unicode::kEuropeanNumber; AppendRun(runs); } - } else if (status_.eor == kArabicNumber) { - direction_ = kArabicNumber; + } else if (status_.eor == WTF::Unicode::kArabicNumber) { + direction_ = WTF::Unicode::kArabicNumber; AppendRun(runs); - } else if (status_.last_strong != kLeftToRight && from == kLeftToRight) { + } else if (status_.last_strong != WTF::Unicode::kLeftToRight && + from == WTF::Unicode::kLeftToRight) { AppendRun(runs); - direction_ = kLeftToRight; + direction_ = WTF::Unicode::kLeftToRight; } - } else if (status_.eor == kArabicNumber || - (status_.eor == kEuropeanNumber && - (status_.last_strong != kLeftToRight || - from == kRightToLeft)) || - (status_.eor != kEuropeanNumber && - status_.last_strong == kLeftToRight && from == kRightToLeft)) { + } else if (status_.eor == WTF::Unicode::kArabicNumber || + (status_.eor == WTF::Unicode::kEuropeanNumber && + (status_.last_strong != WTF::Unicode::kLeftToRight || + from == WTF::Unicode::kRightToLeft)) || + (status_.eor != WTF::Unicode::kEuropeanNumber && + status_.last_strong == WTF::Unicode::kLeftToRight && + from == WTF::Unicode::kRightToLeft)) { AppendRun(runs); - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; } eor_ = last_; } @@ -598,26 +598,25 @@ // content. DCHECK(!InIsolate() || current_explicit_embedding_sequence_.IsEmpty()); - using namespace WTF::Unicode; - unsigned char from_level = Context()->Level(); RefPtr<BidiContext> to_context = Context(); for (size_t i = 0; i < current_explicit_embedding_sequence_.size(); ++i) { BidiEmbedding embedding = current_explicit_embedding_sequence_[i]; - if (embedding.Direction() == kPopDirectionalFormat) { + if (embedding.Direction() == WTF::Unicode::kPopDirectionalFormat) { if (BidiContext* parent_context = to_context->Parent()) to_context = parent_context; } else { - CharDirection direction = - (embedding.Direction() == kRightToLeftEmbedding || - embedding.Direction() == kRightToLeftOverride) - ? kRightToLeft - : kLeftToRight; - bool override = embedding.Direction() == kLeftToRightOverride || - embedding.Direction() == kRightToLeftOverride; + WTF::Unicode::CharDirection direction = + (embedding.Direction() == WTF::Unicode::kRightToLeftEmbedding || + embedding.Direction() == WTF::Unicode::kRightToLeftOverride) + ? WTF::Unicode::kRightToLeft + : WTF::Unicode::kLeftToRight; + bool override = + embedding.Direction() == WTF::Unicode::kLeftToRightOverride || + embedding.Direction() == WTF::Unicode::kRightToLeftOverride; unsigned char level = to_context->Level(); - if (direction == kRightToLeft) + if (direction == WTF::Unicode::kRightToLeft) level = NextGreaterOddLevel(level); else level = NextGreaterEvenLevel(level); @@ -630,13 +629,17 @@ unsigned char to_level = to_context->Level(); - if (to_level > from_level) - RaiseExplicitEmbeddingLevel(runs, - from_level % 2 ? kRightToLeft : kLeftToRight, - to_level % 2 ? kRightToLeft : kLeftToRight); - else if (to_level < from_level) - LowerExplicitEmbeddingLevel(runs, - from_level % 2 ? kRightToLeft : kLeftToRight); + if (to_level > from_level) { + RaiseExplicitEmbeddingLevel( + runs, + from_level % 2 ? WTF::Unicode::kRightToLeft + : WTF::Unicode::kLeftToRight, + to_level % 2 ? WTF::Unicode::kRightToLeft : WTF::Unicode::kLeftToRight); + } else if (to_level < from_level) { + LowerExplicitEmbeddingLevel(runs, from_level % 2 + ? WTF::Unicode::kRightToLeft + : WTF::Unicode::kLeftToRight); + } SetContext(to_context); @@ -649,39 +652,38 @@ inline void BidiResolver<Iterator, Run, IsolatedRun>::UpdateStatusLastFromCurrentDirection( WTF::Unicode::CharDirection dir_current) { - using namespace WTF::Unicode; switch (dir_current) { - case kEuropeanNumberTerminator: - if (status_.last != kEuropeanNumber) - status_.last = kEuropeanNumberTerminator; + case WTF::Unicode::kEuropeanNumberTerminator: + if (status_.last != WTF::Unicode::kEuropeanNumber) + status_.last = WTF::Unicode::kEuropeanNumberTerminator; break; - case kEuropeanNumberSeparator: - case kCommonNumberSeparator: - case kSegmentSeparator: - case kWhiteSpaceNeutral: - case kOtherNeutral: + case WTF::Unicode::kEuropeanNumberSeparator: + case WTF::Unicode::kCommonNumberSeparator: + case WTF::Unicode::kSegmentSeparator: + case WTF::Unicode::kWhiteSpaceNeutral: + case WTF::Unicode::kOtherNeutral: switch (status_.last) { - case kLeftToRight: - case kRightToLeft: - case kRightToLeftArabic: - case kEuropeanNumber: - case kArabicNumber: + case WTF::Unicode::kLeftToRight: + case WTF::Unicode::kRightToLeft: + case WTF::Unicode::kRightToLeftArabic: + case WTF::Unicode::kEuropeanNumber: + case WTF::Unicode::kArabicNumber: status_.last = dir_current; break; default: - status_.last = kOtherNeutral; + status_.last = WTF::Unicode::kOtherNeutral; } break; - case kNonSpacingMark: - case kBoundaryNeutral: - case kRightToLeftEmbedding: - case kLeftToRightEmbedding: - case kRightToLeftOverride: - case kLeftToRightOverride: - case kPopDirectionalFormat: + case WTF::Unicode::kNonSpacingMark: + case WTF::Unicode::kBoundaryNeutral: + case WTF::Unicode::kRightToLeftEmbedding: + case WTF::Unicode::kLeftToRightEmbedding: + case WTF::Unicode::kRightToLeftOverride: + case WTF::Unicode::kLeftToRightOverride: + case WTF::Unicode::kPopDirectionalFormat: // ignore these break; - case kEuropeanNumber: + case WTF::Unicode::kEuropeanNumber: // fall through default: status_.last = dir_current; @@ -790,9 +792,7 @@ VisualDirectionOverride override, bool hard_line_break, bool reorder_runs) { - using namespace WTF::Unicode; - - DCHECK_EQ(direction_, kOtherNeutral); + DCHECK_EQ(direction_, WTF::Unicode::kOtherNeutral); trailing_space_run_ = 0; end_of_line_ = end; @@ -805,8 +805,9 @@ eor_ = current_; Increment(); } - direction_ = - override == kVisualLeftToRightOverride ? kLeftToRight : kRightToLeft; + direction_ = override == kVisualLeftToRightOverride + ? WTF::Unicode::kLeftToRight + : WTF::Unicode::kRightToLeft; AppendRun(runs_); runs_.SetLogicallyLastRun(runs_.LastRun()); if (override == kVisualRightToLeftOverride && runs_.RunCount()) @@ -842,7 +843,7 @@ end_of_run_at_end_of_line_ = last_; last_line_ended = true; } - CharDirection dir_current; + WTF::Unicode::CharDirection dir_current; if (last_line_ended && (hard_line_break || current_.AtEnd())) { BidiContext* c = Context(); if (hard_line_break) { @@ -863,83 +864,84 @@ } } else { dir_current = current_.Direction(); - if (Context()->Override() && dir_current != kRightToLeftEmbedding && - dir_current != kLeftToRightEmbedding && - dir_current != kRightToLeftOverride && - dir_current != kLeftToRightOverride && - dir_current != kPopDirectionalFormat) + if (Context()->Override() && + dir_current != WTF::Unicode::kRightToLeftEmbedding && + dir_current != WTF::Unicode::kLeftToRightEmbedding && + dir_current != WTF::Unicode::kRightToLeftOverride && + dir_current != WTF::Unicode::kLeftToRightOverride && + dir_current != WTF::Unicode::kPopDirectionalFormat) dir_current = Context()->Dir(); - else if (dir_current == kNonSpacingMark) + else if (dir_current == WTF::Unicode::kNonSpacingMark) dir_current = status_.last; } // We ignore all character directionality while in unicode-bidi: isolate // spans. We'll handle ordering the isolated characters in a second pass. if (InIsolate()) - dir_current = kOtherNeutral; + dir_current = WTF::Unicode::kOtherNeutral; - DCHECK(status_.eor != kOtherNeutral || eor_.AtEnd()); + DCHECK(status_.eor != WTF::Unicode::kOtherNeutral || eor_.AtEnd()); switch (dir_current) { // embedding and overrides (X1-X9 in the Bidi specs) - case kRightToLeftEmbedding: - case kLeftToRightEmbedding: - case kRightToLeftOverride: - case kLeftToRightOverride: - case kPopDirectionalFormat: + case WTF::Unicode::kRightToLeftEmbedding: + case WTF::Unicode::kLeftToRightEmbedding: + case WTF::Unicode::kRightToLeftOverride: + case WTF::Unicode::kLeftToRightOverride: + case WTF::Unicode::kPopDirectionalFormat: Embed(dir_current, kFromUnicode); CommitExplicitEmbedding(runs_); break; // strong types - case kLeftToRight: + case WTF::Unicode::kLeftToRight: switch (status_.last) { - case kRightToLeft: - case kRightToLeftArabic: - case kEuropeanNumber: - case kArabicNumber: - if (status_.last != kEuropeanNumber || - status_.last_strong != kLeftToRight) + case WTF::Unicode::kRightToLeft: + case WTF::Unicode::kRightToLeftArabic: + case WTF::Unicode::kEuropeanNumber: + case WTF::Unicode::kArabicNumber: + if (status_.last != WTF::Unicode::kEuropeanNumber || + status_.last_strong != WTF::Unicode::kLeftToRight) AppendRun(runs_); break; - case kLeftToRight: + case WTF::Unicode::kLeftToRight: break; - case kEuropeanNumberSeparator: - case kEuropeanNumberTerminator: - case kCommonNumberSeparator: - case kBoundaryNeutral: - case kBlockSeparator: - case kSegmentSeparator: - case kWhiteSpaceNeutral: - case kOtherNeutral: - if (status_.eor == kEuropeanNumber) { - if (status_.last_strong != kLeftToRight) { + case WTF::Unicode::kEuropeanNumberSeparator: + case WTF::Unicode::kEuropeanNumberTerminator: + case WTF::Unicode::kCommonNumberSeparator: + case WTF::Unicode::kBoundaryNeutral: + case WTF::Unicode::kBlockSeparator: + case WTF::Unicode::kSegmentSeparator: + case WTF::Unicode::kWhiteSpaceNeutral: + case WTF::Unicode::kOtherNeutral: + if (status_.eor == WTF::Unicode::kEuropeanNumber) { + if (status_.last_strong != WTF::Unicode::kLeftToRight) { // the numbers need to be on a higher embedding level, so let's // close that run - direction_ = kEuropeanNumber; + direction_ = WTF::Unicode::kEuropeanNumber; AppendRun(runs_); - if (Context()->Dir() != kLeftToRight) { + if (Context()->Dir() != WTF::Unicode::kLeftToRight) { // the neutrals take the embedding direction, which is R eor_ = last_; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; AppendRun(runs_); } } - } else if (status_.eor == kArabicNumber) { + } else if (status_.eor == WTF::Unicode::kArabicNumber) { // Arabic numbers are always on a higher embedding level, so let's // close that run - direction_ = kArabicNumber; + direction_ = WTF::Unicode::kArabicNumber; AppendRun(runs_); - if (Context()->Dir() != kLeftToRight) { + if (Context()->Dir() != WTF::Unicode::kLeftToRight) { // the neutrals take the embedding direction, which is R eor_ = last_; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; AppendRun(runs_); } - } else if (status_.last_strong != kLeftToRight) { + } else if (status_.last_strong != WTF::Unicode::kLeftToRight) { // last stuff takes embedding dir - if (Context()->Dir() == kRightToLeft) { + if (Context()->Dir() == WTF::Unicode::kRightToLeft) { eor_ = last_; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; } AppendRun(runs_); } @@ -947,37 +949,37 @@ break; } eor_ = current_; - status_.eor = kLeftToRight; - status_.last_strong = kLeftToRight; - direction_ = kLeftToRight; + status_.eor = WTF::Unicode::kLeftToRight; + status_.last_strong = WTF::Unicode::kLeftToRight; + direction_ = WTF::Unicode::kLeftToRight; break; - case kRightToLeftArabic: - case kRightToLeft: + case WTF::Unicode::kRightToLeftArabic: + case WTF::Unicode::kRightToLeft: switch (status_.last) { - case kLeftToRight: - case kEuropeanNumber: - case kArabicNumber: + case WTF::Unicode::kLeftToRight: + case WTF::Unicode::kEuropeanNumber: + case WTF::Unicode::kArabicNumber: AppendRun(runs_); - case kRightToLeft: - case kRightToLeftArabic: + case WTF::Unicode::kRightToLeft: + case WTF::Unicode::kRightToLeftArabic: break; - case kEuropeanNumberSeparator: - case kEuropeanNumberTerminator: - case kCommonNumberSeparator: - case kBoundaryNeutral: - case kBlockSeparator: - case kSegmentSeparator: - case kWhiteSpaceNeutral: - case kOtherNeutral: - if (status_.eor == kEuropeanNumber) { - if (status_.last_strong == kLeftToRight && - Context()->Dir() == kLeftToRight) + case WTF::Unicode::kEuropeanNumberSeparator: + case WTF::Unicode::kEuropeanNumberTerminator: + case WTF::Unicode::kCommonNumberSeparator: + case WTF::Unicode::kBoundaryNeutral: + case WTF::Unicode::kBlockSeparator: + case WTF::Unicode::kSegmentSeparator: + case WTF::Unicode::kWhiteSpaceNeutral: + case WTF::Unicode::kOtherNeutral: + if (status_.eor == WTF::Unicode::kEuropeanNumber) { + if (status_.last_strong == WTF::Unicode::kLeftToRight && + Context()->Dir() == WTF::Unicode::kLeftToRight) eor_ = last_; AppendRun(runs_); - } else if (status_.eor == kArabicNumber) { + } else if (status_.eor == WTF::Unicode::kArabicNumber) { AppendRun(runs_); - } else if (status_.last_strong == kLeftToRight) { - if (Context()->Dir() == kLeftToRight) + } else if (status_.last_strong == WTF::Unicode::kLeftToRight) { + if (Context()->Dir() == WTF::Unicode::kLeftToRight) eor_ = last_; AppendRun(runs_); } @@ -985,123 +987,124 @@ break; } eor_ = current_; - status_.eor = kRightToLeft; + status_.eor = WTF::Unicode::kRightToLeft; status_.last_strong = dir_current; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; break; // weak types: - case kEuropeanNumber: - if (status_.last_strong != kRightToLeftArabic) { + case WTF::Unicode::kEuropeanNumber: + if (status_.last_strong != WTF::Unicode::kRightToLeftArabic) { // if last strong was AL change EN to AN switch (status_.last) { - case kEuropeanNumber: - case kLeftToRight: + case WTF::Unicode::kEuropeanNumber: + case WTF::Unicode::kLeftToRight: break; - case kRightToLeft: - case kRightToLeftArabic: - case kArabicNumber: + case WTF::Unicode::kRightToLeft: + case WTF::Unicode::kRightToLeftArabic: + case WTF::Unicode::kArabicNumber: eor_ = last_; AppendRun(runs_); - direction_ = kEuropeanNumber; + direction_ = WTF::Unicode::kEuropeanNumber; break; - case kEuropeanNumberSeparator: - case kCommonNumberSeparator: - if (status_.eor == kEuropeanNumber) + case WTF::Unicode::kEuropeanNumberSeparator: + case WTF::Unicode::kCommonNumberSeparator: + if (status_.eor == WTF::Unicode::kEuropeanNumber) break; - case kEuropeanNumberTerminator: - case kBoundaryNeutral: - case kBlockSeparator: - case kSegmentSeparator: - case kWhiteSpaceNeutral: - case kOtherNeutral: - if (status_.eor == kEuropeanNumber) { - if (status_.last_strong == kRightToLeft) { + case WTF::Unicode::kEuropeanNumberTerminator: + case WTF::Unicode::kBoundaryNeutral: + case WTF::Unicode::kBlockSeparator: + case WTF::Unicode::kSegmentSeparator: + case WTF::Unicode::kWhiteSpaceNeutral: + case WTF::Unicode::kOtherNeutral: + if (status_.eor == WTF::Unicode::kEuropeanNumber) { + if (status_.last_strong == WTF::Unicode::kRightToLeft) { // ENs on both sides behave like Rs, so the neutrals should be // R. Terminate the EN run. AppendRun(runs_); // Make an R run. - eor_ = status_.last == kEuropeanNumberTerminator + eor_ = status_.last == WTF::Unicode::kEuropeanNumberTerminator ? last_before_et_ : last_; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; AppendRun(runs_); // Begin a new EN run. - direction_ = kEuropeanNumber; + direction_ = WTF::Unicode::kEuropeanNumber; } - } else if (status_.eor == kArabicNumber) { + } else if (status_.eor == WTF::Unicode::kArabicNumber) { // Terminate the AN run. AppendRun(runs_); - if (status_.last_strong == kRightToLeft || - Context()->Dir() == kRightToLeft) { + if (status_.last_strong == WTF::Unicode::kRightToLeft || + Context()->Dir() == WTF::Unicode::kRightToLeft) { // Make an R run. - eor_ = status_.last == kEuropeanNumberTerminator + eor_ = status_.last == WTF::Unicode::kEuropeanNumberTerminator ? last_before_et_ : last_; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; AppendRun(runs_); // Begin a new EN run. - direction_ = kEuropeanNumber; + direction_ = WTF::Unicode::kEuropeanNumber; } - } else if (status_.last_strong == kRightToLeft) { + } else if (status_.last_strong == WTF::Unicode::kRightToLeft) { // Extend the R run to include the neutrals. - eor_ = status_.last == kEuropeanNumberTerminator + eor_ = status_.last == WTF::Unicode::kEuropeanNumberTerminator ? last_before_et_ : last_; - direction_ = kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; AppendRun(runs_); // Begin a new EN run. - direction_ = kEuropeanNumber; + direction_ = WTF::Unicode::kEuropeanNumber; } default: break; } eor_ = current_; - status_.eor = kEuropeanNumber; - if (direction_ == kOtherNeutral) - direction_ = kLeftToRight; + status_.eor = WTF::Unicode::kEuropeanNumber; + if (direction_ == WTF::Unicode::kOtherNeutral) + direction_ = WTF::Unicode::kLeftToRight; break; } - case kArabicNumber: - dir_current = kArabicNumber; + case WTF::Unicode::kArabicNumber: + dir_current = WTF::Unicode::kArabicNumber; switch (status_.last) { - case kLeftToRight: - if (Context()->Dir() == kLeftToRight) + case WTF::Unicode::kLeftToRight: + if (Context()->Dir() == WTF::Unicode::kLeftToRight) AppendRun(runs_); break; - case kArabicNumber: + case WTF::Unicode::kArabicNumber: break; - case kRightToLeft: - case kRightToLeftArabic: - case kEuropeanNumber: + case WTF::Unicode::kRightToLeft: + case WTF::Unicode::kRightToLeftArabic: + case WTF::Unicode::kEuropeanNumber: eor_ = last_; AppendRun(runs_); break; - case kCommonNumberSeparator: - if (status_.eor == kArabicNumber) + case WTF::Unicode::kCommonNumberSeparator: + if (status_.eor == WTF::Unicode::kArabicNumber) break; - case kEuropeanNumberSeparator: - case kEuropeanNumberTerminator: - case kBoundaryNeutral: - case kBlockSeparator: - case kSegmentSeparator: - case kWhiteSpaceNeutral: - case kOtherNeutral: - if (status_.eor == kArabicNumber || - (status_.eor == kEuropeanNumber && - (status_.last_strong == kRightToLeft || - Context()->Dir() == kRightToLeft)) || - (status_.eor != kEuropeanNumber && - status_.last_strong == kLeftToRight && - Context()->Dir() == kRightToLeft)) { + case WTF::Unicode::kEuropeanNumberSeparator: + case WTF::Unicode::kEuropeanNumberTerminator: + case WTF::Unicode::kBoundaryNeutral: + case WTF::Unicode::kBlockSeparator: + case WTF::Unicode::kSegmentSeparator: + case WTF::Unicode::kWhiteSpaceNeutral: + case WTF::Unicode::kOtherNeutral: + if (status_.eor == WTF::Unicode::kArabicNumber || + (status_.eor == WTF::Unicode::kEuropeanNumber && + (status_.last_strong == WTF::Unicode::kRightToLeft || + Context()->Dir() == WTF::Unicode::kRightToLeft)) || + (status_.eor != WTF::Unicode::kEuropeanNumber && + status_.last_strong == WTF::Unicode::kLeftToRight && + Context()->Dir() == WTF::Unicode::kRightToLeft)) { // Terminate the run before the neutrals. AppendRun(runs_); // Begin an R run for the neutrals. - direction_ = kRightToLeft; - } else if (direction_ == kOtherNeutral) { - direction_ = status_.last_strong == kLeftToRight ? kLeftToRight - : kRightToLeft; + direction_ = WTF::Unicode::kRightToLeft; + } else if (direction_ == WTF::Unicode::kOtherNeutral) { + direction_ = status_.last_strong == WTF::Unicode::kLeftToRight + ? WTF::Unicode::kLeftToRight + : WTF::Unicode::kRightToLeft; } eor_ = last_; AppendRun(runs_); @@ -1109,39 +1112,39 @@ break; } eor_ = current_; - status_.eor = kArabicNumber; - if (direction_ == kOtherNeutral) - direction_ = kArabicNumber; + status_.eor = WTF::Unicode::kArabicNumber; + if (direction_ == WTF::Unicode::kOtherNeutral) + direction_ = WTF::Unicode::kArabicNumber; break; - case kEuropeanNumberSeparator: - case kCommonNumberSeparator: + case WTF::Unicode::kEuropeanNumberSeparator: + case WTF::Unicode::kCommonNumberSeparator: break; - case kEuropeanNumberTerminator: - if (status_.last == kEuropeanNumber) { - dir_current = kEuropeanNumber; + case WTF::Unicode::kEuropeanNumberTerminator: + if (status_.last == WTF::Unicode::kEuropeanNumber) { + dir_current = WTF::Unicode::kEuropeanNumber; eor_ = current_; status_.eor = dir_current; - } else if (status_.last != kEuropeanNumberTerminator) { + } else if (status_.last != WTF::Unicode::kEuropeanNumberTerminator) { last_before_et_ = empty_run_ ? eor_ : last_; } break; // boundary neutrals should be ignored - case kBoundaryNeutral: + case WTF::Unicode::kBoundaryNeutral: if (eor_ == last_) eor_ = current_; break; // neutrals - case kBlockSeparator: + case WTF::Unicode::kBlockSeparator: // ### what do we do with newline and paragraph seperators that come to // here? break; - case kSegmentSeparator: + case WTF::Unicode::kSegmentSeparator: // ### implement rule L1 break; - case kWhiteSpaceNeutral: + case WTF::Unicode::kWhiteSpaceNeutral: break; - case kOtherNeutral: + case WTF::Unicode::kOtherNeutral: break; default: break; @@ -1151,14 +1154,15 @@ if (!reached_end_of_line_) { eor_ = end_of_run_at_end_of_line_; switch (status_.eor) { - case kLeftToRight: - case kRightToLeft: - case kArabicNumber: + case WTF::Unicode::kLeftToRight: + case WTF::Unicode::kRightToLeft: + case WTF::Unicode::kArabicNumber: direction_ = status_.eor; break; - case kEuropeanNumber: - direction_ = status_.last_strong == kLeftToRight ? kLeftToRight - : kEuropeanNumber; + case WTF::Unicode::kEuropeanNumber: + direction_ = status_.last_strong == WTF::Unicode::kLeftToRight + ? WTF::Unicode::kLeftToRight + : WTF::Unicode::kEuropeanNumber; break; default: NOTREACHED(); @@ -1173,7 +1177,7 @@ reached_end_of_line_ = state_at_end.reached_end_of_line_; last_before_et_ = state_at_end.last_before_et_; empty_run_ = state_at_end.empty_run_; - direction_ = kOtherNeutral; + direction_ = WTF::Unicode::kOtherNeutral; break; } @@ -1197,7 +1201,7 @@ reached_end_of_line_ = state_at_end.reached_end_of_line_; last_before_et_ = state_at_end.last_before_et_; empty_run_ = state_at_end.empty_run_; - direction_ = kOtherNeutral; + direction_ = WTF::Unicode::kOtherNeutral; break; } }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/try_flag.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/try_flag.py index 93848c0..2f5fdd4 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/try_flag.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/try_flag.py
@@ -91,7 +91,7 @@ self._host.print_('-- %s: %s/results.html' % ( BUILDERS[build.builder_name].version, buildbot.results_url(build.builder_name, build.build_number))) - results = buildbot.fetch_results(build, full=True) + results = buildbot.fetch_results(build, True) results.for_each_test( lambda result, b=build: self._process_result(b, result))
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index caf8190..c488a37 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Tuesday October 03 2017 +Date: Thursday October 12 2017 Branch: master -Commit: fe7b869104806752a26a262dc60923639d9a384f +Commit: caa116c9be96508c18d533dedc95b2df4f8e3812 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni index 9dcb34d..fd7814c 100644 --- a/third_party/libvpx/libvpx_srcs.gni +++ b/third_party/libvpx/libvpx_srcs.gni
@@ -321,6 +321,7 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/convolve.h", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/convolve_ssse3.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_avx2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_txfm_impl_sse2.h", @@ -329,6 +330,7 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse4.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/mem_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/txfm_common_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_asm_stubs.c", @@ -783,6 +785,7 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/convolve.h", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/convolve_ssse3.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_avx2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_txfm_impl_sse2.h", @@ -791,6 +794,7 @@ "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse4.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/mem_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/txfm_common_sse2.h", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_asm_stubs.c",
diff --git a/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h index 90edc5c..0835030 100644 --- a/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h
@@ -135,6 +135,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -180,6 +191,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_horiz)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -225,6 +247,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_vert)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -8794,16 +8827,22 @@ vpx_convolve8_avg = vpx_convolve8_avg_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg = vpx_convolve8_avg_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg = vpx_convolve8_avg_avx2; vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_c; if (flags & HAS_SSE2) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_avx2; vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_c; if (flags & HAS_SSE2) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_avx2; vpx_convolve8_horiz = vpx_convolve8_horiz_c; if (flags & HAS_SSE2) vpx_convolve8_horiz = vpx_convolve8_horiz_sse2;
diff --git a/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h index 659206c5..6e8baa8 100644 --- a/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h
@@ -130,6 +130,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -175,6 +186,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_horiz)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -220,6 +242,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_vert)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -7507,12 +7540,18 @@ vpx_convolve8_avg = vpx_convolve8_avg_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg = vpx_convolve8_avg_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg = vpx_convolve8_avg_avx2; vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_avx2; vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_avx2; vpx_convolve8_horiz = vpx_convolve8_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_horiz = vpx_convolve8_horiz_ssse3;
diff --git a/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h index 90edc5c..0835030 100644 --- a/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h
@@ -135,6 +135,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -180,6 +191,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_horiz)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -225,6 +247,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_vert)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -8794,16 +8827,22 @@ vpx_convolve8_avg = vpx_convolve8_avg_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg = vpx_convolve8_avg_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg = vpx_convolve8_avg_avx2; vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_c; if (flags & HAS_SSE2) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_avx2; vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_c; if (flags & HAS_SSE2) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_avx2; vpx_convolve8_horiz = vpx_convolve8_horiz_c; if (flags & HAS_SSE2) vpx_convolve8_horiz = vpx_convolve8_horiz_sse2;
diff --git a/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h index 659206c5..6e8baa8 100644 --- a/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h
@@ -130,6 +130,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -175,6 +186,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_horiz)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -220,6 +242,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_vert)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -7507,12 +7540,18 @@ vpx_convolve8_avg = vpx_convolve8_avg_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg = vpx_convolve8_avg_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg = vpx_convolve8_avg_avx2; vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_avx2; vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_avx2; vpx_convolve8_horiz = vpx_convolve8_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_horiz = vpx_convolve8_horiz_ssse3;
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 2f71e77..e2f8bf70 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -1,7 +1,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 6 #define VERSION_PATCH 1 -#define VERSION_EXTRA "1264-gfe7b86910" +#define VERSION_EXTRA "1306-gcaa116c9b" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.6.1-1264-gfe7b86910" -#define VERSION_STRING " v1.6.1-1264-gfe7b86910" +#define VERSION_STRING_NOSP "v1.6.1-1306-gcaa116c9b" +#define VERSION_STRING " v1.6.1-1306-gcaa116c9b"
diff --git a/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h index 90edc5c..0835030 100644 --- a/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h
@@ -135,6 +135,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -180,6 +191,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_horiz)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -225,6 +247,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_vert)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -8794,16 +8827,22 @@ vpx_convolve8_avg = vpx_convolve8_avg_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg = vpx_convolve8_avg_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg = vpx_convolve8_avg_avx2; vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_c; if (flags & HAS_SSE2) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_avx2; vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_c; if (flags & HAS_SSE2) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_avx2; vpx_convolve8_horiz = vpx_convolve8_horiz_c; if (flags & HAS_SSE2) vpx_convolve8_horiz = vpx_convolve8_horiz_sse2;
diff --git a/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h index 659206c5..6e8baa8 100644 --- a/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h
@@ -130,6 +130,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -175,6 +186,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_horiz)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -220,6 +242,17 @@ int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_avx2(const uint8_t* src, + ptrdiff_t src_stride, + uint8_t* dst, + ptrdiff_t dst_stride, + const InterpKernel* filter, + int x0_q4, + int x_step_q4, + int y0_q4, + int y_step_q4, + int w, + int h); RTCD_EXTERN void (*vpx_convolve8_avg_vert)(const uint8_t* src, ptrdiff_t src_stride, uint8_t* dst, @@ -7507,12 +7540,18 @@ vpx_convolve8_avg = vpx_convolve8_avg_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg = vpx_convolve8_avg_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg = vpx_convolve8_avg_avx2; vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_horiz = vpx_convolve8_avg_horiz_avx2; vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_sse2; if (flags & HAS_SSSE3) vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_ssse3; + if (flags & HAS_AVX2) + vpx_convolve8_avg_vert = vpx_convolve8_avg_vert_avx2; vpx_convolve8_horiz = vpx_convolve8_horiz_sse2; if (flags & HAS_SSSE3) vpx_convolve8_horiz = vpx_convolve8_horiz_ssse3;
diff --git a/third_party/win_build_output/remc.bat b/third_party/win_build_output/remc.bat new file mode 100755 index 0000000..3c057d2 --- /dev/null +++ b/third_party/win_build_output/remc.bat
@@ -0,0 +1,8 @@ +@REM Copyright 2017 The Chromium Authors. All rights reserved. +@REM Use of this source code is governed by a BSD-style license that can be +@REM found in the LICENSE file. + +ninja -C out\gn ^ + gen/base/trace_event/etw_manifest/chrome_events_win.h ^ + gen/chrome/common/win/eventlog_messages.h ^ + gen/remoting/host/win/remoting_host_messages.h
diff --git a/third_party/win_build_output/remidl.bat b/third_party/win_build_output/remidl.bat new file mode 100755 index 0000000..1e2c39f5 --- /dev/null +++ b/third_party/win_build_output/remidl.bat
@@ -0,0 +1,12 @@ +@REM Copyright 2017 The Chromium Authors. All rights reserved. +@REM Use of this source code is governed by a BSD-style license that can be +@REM found in the LICENSE file. + +@REM midl.exe output is arch-specific, remember to run this for both target_cpu. +ninja -C out\gn ^ + gen/google_update/google_update_idl.h ^ + gen/remoting/host/win/chromoting_lib.h ^ + gen/third_party/iaccessible2/ia2_api_all.h ^ + gen/third_party/isimpledom/ISimpleDOMDocument.h ^ + gen/third_party/isimpledom/ISimpleDOMNode.h ^ + gen/third_party/isimpledom/ISimpleDOMText.h
diff --git a/third_party/zlib/google/zip.cc b/third_party/zlib/google/zip.cc index f0183d3f..abdfcb1 100644 --- a/third_party/zlib/google/zip.cc +++ b/third_party/zlib/google/zip.cc
@@ -4,6 +4,7 @@ #include "third_party/zlib/google/zip.h" +#include <list> #include <string> #include <vector> @@ -25,10 +26,13 @@ #include "third_party/zlib/contrib/minizip/zip.h" #endif +namespace zip { namespace { -bool AddFileToZip(zipFile zip_file, const base::FilePath& src_dir) { - base::File file(src_dir, base::File::FLAG_OPEN | base::File::FLAG_READ); +bool AddFileToZip(zipFile zip_file, + const base::FilePath& src_dir, + FileAccessor* file_accessor) { + base::File file = file_accessor->OpenFileForReading(src_dir); if (!file.IsValid()) { DLOG(ERROR) << "Could not open file for path " << src_dir.value(); return false; @@ -50,8 +54,10 @@ return true; } -bool AddEntryToZip(zipFile zip_file, const base::FilePath& path, - const base::FilePath& root_path) { +bool AddEntryToZip(zipFile zip_file, + const base::FilePath& path, + const base::FilePath& root_path, + FileAccessor* file_accessor) { base::FilePath relative_path; bool result = root_path.AppendRelativePath(path, &relative_path); DCHECK(result); @@ -60,17 +66,17 @@ base::ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/"); #endif - bool is_directory = base::DirectoryExists(path); + bool is_directory = file_accessor->DirectoryExists(path); if (is_directory) str_path += "/"; - zip_fileinfo file_info = zip::internal::GetFileInfoForZipping(path); - if (!zip::internal::ZipOpenNewFileInZip(zip_file, str_path, &file_info)) + if (!zip::internal::ZipOpenNewFileInZip( + zip_file, str_path, file_accessor->GetLastModifiedTime(path))) return false; bool success = true; if (!is_directory) { - success = AddFileToZip(zip_file, path); + success = AddFileToZip(zip_file, path, file_accessor); } if (ZIP_OK != zipCloseFileInZip(zip_file)) { @@ -81,17 +87,151 @@ return success; } +bool IsHiddenFile(const base::FilePath& file_path) { + return file_path.BaseName().value()[0] == '.'; +} + bool ExcludeNoFilesFilter(const base::FilePath& file_path) { return true; } bool ExcludeHiddenFilesFilter(const base::FilePath& file_path) { - return file_path.BaseName().value()[0] != '.'; + return !IsHiddenFile(file_path); } +class DirectFileAccessor : public FileAccessor { + public: + ~DirectFileAccessor() override = default; + + base::File OpenFileForReading(const base::FilePath& file) override { + return base::File(file, base::File::FLAG_OPEN | base::File::FLAG_READ); + } + + bool DirectoryExists(const base::FilePath& file) override { + return base::DirectoryExists(file); + } + + std::vector<DirectoryContentEntry> ListDirectoryContent( + const base::FilePath& dir) { + std::vector<DirectoryContentEntry> files; + base::FileEnumerator file_enumerator( + dir, false /* recursive */, + base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); + for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); + path = file_enumerator.Next()) { + files.push_back(DirectoryContentEntry(path, base::DirectoryExists(path))); + } + return files; + } + + base::Time GetLastModifiedTime(const base::FilePath& path) override { + base::File::Info file_info; + if (!base::GetFileInfo(path, &file_info)) { + LOG(ERROR) << "Failed to retrieve file modification time for " + << path.value(); + } + return file_info.last_modified; + } +}; + } // namespace -namespace zip { +ZipParams::ZipParams(const base::FilePath& src_dir, + const base::FilePath& dest_file) + : src_dir_(src_dir), + dest_file_(dest_file), + file_accessor_(new DirectFileAccessor()) {} + +#if defined(OS_POSIX) +// Does not take ownership of |fd|. +ZipParams::ZipParams(const base::FilePath& src_dir, int dest_fd) + : src_dir_(src_dir), + dest_fd_(dest_fd), + file_accessor_(new DirectFileAccessor()) {} +#endif + +bool Zip(const ZipParams& params) { + DCHECK(params.file_accessor()->DirectoryExists(params.src_dir())); + + zipFile zip_file = nullptr; +#if defined(OS_POSIX) + int dest_fd = params.dest_fd(); + if (dest_fd != base::kInvalidPlatformFile) { + DCHECK(params.dest_file().empty()); + zip_file = internal::OpenFdForZipping(dest_fd, APPEND_STATUS_CREATE); + if (!zip_file) { + DLOG(ERROR) << "Couldn't create ZIP file for FD " << dest_fd; + return false; + } + } +#endif + if (!zip_file) { + const base::FilePath& dest_file = params.dest_file(); + DCHECK(!dest_file.empty()); + zip_file = internal::OpenForZipping(dest_file.AsUTF8Unsafe(), + APPEND_STATUS_CREATE); + if (!zip_file) { + DLOG(WARNING) << "Couldn't create ZIP file at path " << dest_file; + return false; + } + } + + // Using a pointer to avoid copies of a potentially large array. + const std::vector<base::FilePath>* files_to_add = ¶ms.files_to_zip(); + std::vector<base::FilePath> all_files; + if (files_to_add->empty()) { + // Include all files from the src_dir (modulo the src_dir itself and + // filtered and hidden files). + + files_to_add = &all_files; + // Using a list so we can call push_back while iterating. + std::list<FileAccessor::DirectoryContentEntry> entries; + entries.push_back(FileAccessor::DirectoryContentEntry( + params.src_dir(), true /* is directory*/)); + const FilterCallback& filter_callback = params.filter_callback(); + for (auto iter = entries.begin(); iter != entries.end(); ++iter) { + const base::FilePath& entry_path = iter->path; + if (iter != entries.begin() && // Don't filter the root dir. + ((!params.include_hidden_files() && IsHiddenFile(entry_path)) || + (filter_callback && !filter_callback.Run(entry_path)))) { + continue; + } + + if (iter != entries.begin()) { // Exclude the root dir from the ZIP file. + // Make the path relative for AddEntryToZip. + base::FilePath relative_path; + bool success = + params.src_dir().AppendRelativePath(entry_path, &relative_path); + DCHECK(success); + all_files.push_back(relative_path); + } + + if (iter->is_directory) { + std::vector<FileAccessor::DirectoryContentEntry> subentries = + params.file_accessor()->ListDirectoryContent(entry_path); + entries.insert(entries.end(), subentries.begin(), subentries.end()); + } + } + } + + bool success = true; + for (auto iter = files_to_add->begin(); iter != files_to_add->end(); ++iter) { + const base::FilePath& path = params.src_dir().Append(*iter); + if (!AddEntryToZip(zip_file, path, params.src_dir(), + params.file_accessor())) { + // TODO(hshi): clean up the partial zip file when error occurs. + success = false; + break; + } + } + + if (ZIP_OK != zipClose(zip_file, NULL)) { + DLOG(ERROR) << "Error closing zip file " << params.dest_file().value(); + return false; + } + + return success; +} bool Unzip(const base::FilePath& src_file, const base::FilePath& dest_dir) { return UnzipWithFilterCallback(src_file, dest_dir, @@ -140,36 +280,9 @@ const base::FilePath& dest_file, const FilterCallback& filter_cb) { DCHECK(base::DirectoryExists(src_dir)); - - zipFile zip_file = internal::OpenForZipping(dest_file.AsUTF8Unsafe(), - APPEND_STATUS_CREATE); - - if (!zip_file) { - DLOG(WARNING) << "couldn't create file " << dest_file.value(); - return false; - } - - bool success = true; - base::FileEnumerator file_enumerator(src_dir, true /* recursive */, - base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); - for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); - path = file_enumerator.Next()) { - if (!filter_cb.Run(path)) { - continue; - } - - if (!AddEntryToZip(zip_file, path, src_dir)) { - success = false; - break; - } - } - - if (ZIP_OK != zipClose(zip_file, NULL)) { - DLOG(ERROR) << "Error closing zip file " << dest_file.value(); - return false; - } - - return success; + ZipParams params(src_dir, dest_file); + params.set_filter_callback(filter_cb); + return Zip(params); } bool Zip(const base::FilePath& src_dir, const base::FilePath& dest_file, @@ -188,31 +301,9 @@ const std::vector<base::FilePath>& src_relative_paths, int dest_fd) { DCHECK(base::DirectoryExists(src_dir)); - zipFile zip_file = internal::OpenFdForZipping(dest_fd, APPEND_STATUS_CREATE); - - if (!zip_file) { - DLOG(ERROR) << "couldn't create file for fd " << dest_fd; - return false; - } - - bool success = true; - for (std::vector<base::FilePath>::const_iterator iter = - src_relative_paths.begin(); - iter != src_relative_paths.end(); ++iter) { - const base::FilePath& path = src_dir.Append(*iter); - if (!AddEntryToZip(zip_file, path, src_dir)) { - // TODO(hshi): clean up the partial zip file when error occurs. - success = false; - break; - } - } - - if (ZIP_OK != zipClose(zip_file, NULL)) { - DLOG(ERROR) << "Error closing zip file for fd " << dest_fd; - success = false; - } - - return success; + ZipParams params(src_dir, dest_fd); + params.set_files_to_zip(src_relative_paths); + return Zip(params); } #endif // defined(OS_POSIX)
diff --git a/third_party/zlib/google/zip.h b/third_party/zlib/google/zip.h index 68bed0b..1884f4d 100644 --- a/third_party/zlib/google/zip.h +++ b/third_party/zlib/google/zip.h
@@ -9,10 +9,110 @@ #include "base/callback.h" #include "base/files/file_path.h" +#include "base/files/platform_file.h" +#include "base/time/time.h" #include "build/build_config.h" +namespace base { +class File; +} + namespace zip { +// Abstraction for file access operation required by Zip(). +// Can be passed to the ZipParams for providing custom access to the files, +// for example over IPC. +// If none is provided, the files are accessed directly. +class FileAccessor { + public: + virtual ~FileAccessor() = default; + + struct DirectoryContentEntry { + DirectoryContentEntry(const base::FilePath& path, bool is_directory) + : path(path), is_directory(is_directory) {} + base::FilePath path; + bool is_directory = false; + }; + + virtual base::File OpenFileForReading(const base::FilePath& path) = 0; + virtual bool DirectoryExists(const base::FilePath& path) = 0; + virtual std::vector<DirectoryContentEntry> ListDirectoryContent( + const base::FilePath& dir_path) = 0; + virtual base::Time GetLastModifiedTime(const base::FilePath& path) = 0; +}; + +class ZipParams { + public: + ZipParams(const base::FilePath& src_dir, const base::FilePath& dest_file); +#if defined(OS_POSIX) + // Does not take ownership of |dest_fd|. + ZipParams(const base::FilePath& src_dir, int dest_fd); + + int dest_fd() const { return dest_fd_; } +#endif + + const base::FilePath& src_dir() const { return src_dir_; } + + const base::FilePath& dest_file() const { return dest_file_; } + + // Restricts the files actually zipped to the paths listed in + // |src_relative_paths|. They must be relative to the |src_dir| passed in the + // constructor and will be used as the file names in the created zip file. All + // source paths must be under |src_dir| in the file system hierarchy. + void set_files_to_zip(const std::vector<base::FilePath>& src_relative_paths) { + src_files_ = src_relative_paths; + } + const std::vector<base::FilePath>& files_to_zip() const { return src_files_; } + + using FilterCallback = base::Callback<bool(const base::FilePath&)>; + void set_filter_callback(FilterCallback filter_callback) { + filter_callback_ = filter_callback; + } + const FilterCallback& filter_callback() const { return filter_callback_; } + + void set_include_hidden_files(bool include_hidden_files) { + include_hidden_files_ = include_hidden_files; + } + bool include_hidden_files() const { return include_hidden_files_; } + + // Sets a custom file accessor for file operations. Default is to directly + // access the files (with fopen and the rest). + // Useful in cases where running in a sandbox process and file access has to + // go through IPC, for example. + void set_file_accessor(std::unique_ptr<FileAccessor> file_accessor) { + file_accessor_ = std::move(file_accessor); + } + FileAccessor* file_accessor() const { return file_accessor_.get(); } + + private: + base::FilePath src_dir_; + + base::FilePath dest_file_; +#if defined(OS_POSIX) + int dest_fd_ = base::kInvalidPlatformFile; +#endif + + // The relative paths to the files that should be included in the zip file. If + // this is empty, all files in |src_dir_| are included. + std::vector<base::FilePath> src_files_; + + // Filter used to exclude files from the ZIP file. Only effective when + // |src_files_| is empty. + FilterCallback filter_callback_; + + // Whether hidden files should be included in the ZIP file. Only effective + // when |src_files_| is empty. + bool include_hidden_files_ = true; + + // Abstraction around file system access used to read files. An implementation + // that accesses files directly is provided by default. + std::unique_ptr<FileAccessor> file_accessor_; +}; + +// Zip files specified into a ZIP archives. The source files and ZIP destination +// files (as well as other settings) are specified in |params|. +bool Zip(const ZipParams& params); + // Zip the contents of src_dir into dest_file. src_path must be a directory. // An entry will *not* be created in the zip for the root folder -- children // of src_dir will be at the root level of the created zip. For each file in
diff --git a/third_party/zlib/google/zip_internal.cc b/third_party/zlib/google/zip_internal.cc index 77f2b17..314740f5 100644 --- a/third_party/zlib/google/zip_internal.cc +++ b/third_party/zlib/google/zip_internal.cc
@@ -8,11 +8,8 @@ #include <algorithm> -#include "base/files/file_util.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "build/build_config.h" #if defined(USE_SYSTEM_MINIZIP) #include <minizip/ioapi.h> @@ -346,40 +343,32 @@ } #endif -zip_fileinfo GetFileInfoForZipping(const base::FilePath& path) { - base::Time file_time; - base::File::Info file_info; - if (base::GetFileInfo(path, &file_info)) - file_time = file_info.last_modified; - return TimeToZipFileInfo(file_time); -} - bool ZipOpenNewFileInZip(zipFile zip_file, const std::string& str_path, - const zip_fileinfo* file_info) { + base::Time last_modified_time) { // Section 4.4.4 http://www.pkware.com/documents/casestudies/APPNOTE.TXT // Setting the Language encoding flag so the file is told to be in utf-8. const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11; - if (ZIP_OK != zipOpenNewFileInZip4( - zip_file, // file - str_path.c_str(), // filename - file_info, // zipfi - NULL, // extrafield_local, - 0u, // size_extrafield_local - NULL, // extrafield_global - 0u, // size_extrafield_global - NULL, // comment - Z_DEFLATED, // method - Z_DEFAULT_COMPRESSION, // level - 0, // raw - -MAX_WBITS, // windowBits - DEF_MEM_LEVEL, // memLevel - Z_DEFAULT_STRATEGY, // strategy - NULL, // password - 0, // crcForCrypting - 0, // versionMadeBy - LANGUAGE_ENCODING_FLAG)) { // flagBase + zip_fileinfo file_info = TimeToZipFileInfo(last_modified_time); + if (ZIP_OK != zipOpenNewFileInZip4(zip_file, // file + str_path.c_str(), // filename + &file_info, // zip_fileinfo + NULL, // extrafield_local, + 0u, // size_extrafield_local + NULL, // extrafield_global + 0u, // size_extrafield_global + NULL, // comment + Z_DEFLATED, // method + Z_DEFAULT_COMPRESSION, // level + 0, // raw + -MAX_WBITS, // windowBits + DEF_MEM_LEVEL, // memLevel + Z_DEFAULT_STRATEGY, // strategy + NULL, // password + 0, // crcForCrypting + 0, // versionMadeBy + LANGUAGE_ENCODING_FLAG)) { // flagBase DLOG(ERROR) << "Could not open zip file entry " << str_path; return false; }
diff --git a/third_party/zlib/google/zip_internal.h b/third_party/zlib/google/zip_internal.h index 0ebf0c94..49fb902a 100644 --- a/third_party/zlib/google/zip_internal.h +++ b/third_party/zlib/google/zip_internal.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/time/time.h" #include "build/build_config.h" #if defined(OS_WIN) @@ -59,13 +60,10 @@ zipFile OpenFdForZipping(int zip_fd, int append_flag); #endif -// Returns a zip_fileinfo with the last modification date of |path| set. -zip_fileinfo GetFileInfoForZipping(const base::FilePath& path); - // Wrapper around zipOpenNewFileInZip4 which passes most common options. bool ZipOpenNewFileInZip(zipFile zip_file, const std::string& str_path, - const zip_fileinfo* file_info); + base::Time last_modified_time); const int kZipMaxPath = 256; const int kZipBufSize = 8192;
diff --git a/third_party/zlib/google/zip_unittest.cc b/third_party/zlib/google/zip_unittest.cc index 2d969d7..b6cf285 100644 --- a/third_party/zlib/google/zip_unittest.cc +++ b/third_party/zlib/google/zip_unittest.cc
@@ -5,6 +5,7 @@ #include <stddef.h> #include <stdint.h> +#include <map> #include <set> #include <string> #include <vector> @@ -14,6 +15,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/macros.h" #include "base/path_service.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -25,6 +27,103 @@ namespace { +bool CreateFile(const std::string& content, + base::FilePath* file_path, + base::File* file) { + if (!base::CreateTemporaryFile(file_path)) + return false; + + if (base::WriteFile(*file_path, content.data(), content.size()) == -1) + return false; + + *file = base::File( + *file_path, base::File::Flags::FLAG_OPEN | base::File::Flags::FLAG_READ); + return file->IsValid(); +} + +// A virtual file system containing: +// /test +// /test/foo.txt +// /test/bar/bar1.txt +// /test/bar/bar2.txt +// Used to test providing a custom zip::FileAccessor when unzipping. +class VirtualFileSystem : public zip::FileAccessor { + public: + static constexpr char kFooContent[] = "This is foo."; + static constexpr char kBar1Content[] = "This is bar."; + static constexpr char kBar2Content[] = "This is bar too."; + + VirtualFileSystem() { + base::FilePath test_dir(FILE_PATH_LITERAL("/test")); + base::FilePath foo_txt_path = test_dir.Append(FILE_PATH_LITERAL("foo.txt")); + + base::FilePath file_path; + base::File file; + bool success = CreateFile(kFooContent, &file_path, &file); + DCHECK(success); + files_[foo_txt_path] = std::move(file); + + base::FilePath bar_dir = test_dir.Append(FILE_PATH_LITERAL("bar")); + base::FilePath bar1_txt_path = + bar_dir.Append(FILE_PATH_LITERAL("bar1.txt")); + success = CreateFile(kBar1Content, &file_path, &file); + DCHECK(success); + files_[bar1_txt_path] = std::move(file); + + base::FilePath bar2_txt_path = + bar_dir.Append(FILE_PATH_LITERAL("bar2.txt")); + success = CreateFile(kBar2Content, &file_path, &file); + DCHECK(success); + files_[bar2_txt_path] = std::move(file); + + file_tree_[test_dir] = std::vector<DirectoryContentEntry>{ + DirectoryContentEntry(foo_txt_path, /*is_dir=*/false), + DirectoryContentEntry(bar_dir, /*is_dir=*/true)}; + file_tree_[bar_dir] = std::vector<DirectoryContentEntry>{ + DirectoryContentEntry(bar1_txt_path, /*is_dir=*/false), + DirectoryContentEntry(bar2_txt_path, /*is_dir=*/false)}; + } + ~VirtualFileSystem() override = default; + + private: + base::File OpenFileForReading(const base::FilePath& file) override { + auto iter = files_.find(file); + if (iter == files_.end()) { + NOTREACHED(); + return base::File(); + } + return std::move(iter->second); + } + + bool DirectoryExists(const base::FilePath& file) override { + return file_tree_.count(file) == 1 && files_.count(file) == 0; + } + + std::vector<DirectoryContentEntry> ListDirectoryContent( + const base::FilePath& dir) override { + auto iter = file_tree_.find(dir); + if (iter == file_tree_.end()) { + NOTREACHED(); + return std::vector<DirectoryContentEntry>(); + } + return iter->second; + } + + base::Time GetLastModifiedTime(const base::FilePath& path) override { + return base::Time::FromDoubleT(172097977); // Some random date. + } + + std::map<base::FilePath, std::vector<DirectoryContentEntry>> file_tree_; + std::map<base::FilePath, base::File> files_; + + DISALLOW_COPY_AND_ASSIGN(VirtualFileSystem); +}; + +// static +constexpr char VirtualFileSystem::kFooContent[]; +constexpr char VirtualFileSystem::kBar1Content[]; +constexpr char VirtualFileSystem::kBar2Content[]; + // Make the test a PlatformTest to setup autorelease pools properly on Mac. class ZipTest : public PlatformTest { protected: @@ -40,15 +139,15 @@ test_dir_ = temp_dir_.GetPath(); base::FilePath zip_path(test_dir_); - zip_contents_.insert(zip_path.AppendASCII("foo.txt")); - zip_path = zip_path.AppendASCII("foo"); + zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("foo.txt"))); + zip_path = zip_path.Append(FILE_PATH_LITERAL("foo")); zip_contents_.insert(zip_path); - zip_contents_.insert(zip_path.AppendASCII("bar.txt")); - zip_path = zip_path.AppendASCII("bar"); + zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("bar.txt"))); + zip_path = zip_path.Append(FILE_PATH_LITERAL("bar")); zip_contents_.insert(zip_path); - zip_contents_.insert(zip_path.AppendASCII("baz.txt")); - zip_contents_.insert(zip_path.AppendASCII("quux.txt")); - zip_contents_.insert(zip_path.AppendASCII(".hidden")); + zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("baz.txt"))); + zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("quux.txt"))); + zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL(".hidden"))); // Include a subset of files in |zip_file_list_| to test ZipFiles(). zip_file_list_.push_back(base::FilePath(FILE_PATH_LITERAL("foo.txt"))); @@ -86,18 +185,42 @@ ASSERT_TRUE(base::PathExists(path)) << "no file " << path.value(); ASSERT_TRUE(zip::Unzip(path, test_dir_)); + base::FilePath original_dir; + ASSERT_TRUE(GetTestDataDirectory(&original_dir)); + original_dir = original_dir.AppendASCII("test"); + base::FileEnumerator files(test_dir_, true, base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); - base::FilePath next_path = files.Next(); + base::FilePath unzipped_entry_path = files.Next(); size_t count = 0; - while (!next_path.value().empty()) { - if (next_path.value().find(FILE_PATH_LITERAL(".svn")) == - base::FilePath::StringType::npos) { - EXPECT_EQ(zip_contents_.count(next_path), 1U) << - "Couldn't find " << next_path.value(); - count++; + while (!unzipped_entry_path.value().empty()) { + EXPECT_EQ(zip_contents_.count(unzipped_entry_path), 1U) + << "Couldn't find " << unzipped_entry_path.value(); + count++; + + if (base::PathExists(unzipped_entry_path) && + !base::DirectoryExists(unzipped_entry_path)) { + // It's a file, check its contents are what we zipped. + // TODO(774156): figure out why the commented out EXPECT_TRUE below + // fails on the build bots (but not on the try-bots). + base::FilePath relative_path; + bool append_relative_path_success = + test_dir_.AppendRelativePath(unzipped_entry_path, &relative_path); + if (!append_relative_path_success) { + LOG(ERROR) << "Append relative path failed, params: " + << test_dir_.value() << " and " + << unzipped_entry_path.value(); + } + base::FilePath original_path = original_dir.Append(relative_path); + LOG(ERROR) << "Comparing original " << original_path.value() + << " and unzipped file " << unzipped_entry_path.value() + << " result: " + << base::ContentsEqual(original_path, unzipped_entry_path); + // EXPECT_TRUE(base::ContentsEqual(original_path, unzipped_entry_path)) + // << "Contents differ between original " << original_path.value() + // << " and unzipped file " << unzipped_entry_path.value(); } - next_path = files.Next(); + unzipped_entry_path = files.Next(); } size_t expected_count = 0; @@ -335,4 +458,29 @@ } } +TEST_F(ZipTest, ZipWithFileAccessor) { + base::FilePath zip_file; + ASSERT_TRUE(base::CreateTemporaryFile(&zip_file)); + zip::ZipParams params(base::FilePath(FILE_PATH_LITERAL("/test")), zip_file); + params.set_file_accessor(std::make_unique<VirtualFileSystem>()); + ASSERT_TRUE(zip::Zip(params)); + + base::ScopedTempDir scoped_temp_dir; + ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); + const base::FilePath& temp_dir = scoped_temp_dir.GetPath(); + ASSERT_TRUE(zip::Unzip(zip_file, temp_dir)); + base::FilePath bar_dir = temp_dir.Append(FILE_PATH_LITERAL("bar")); + EXPECT_TRUE(base::DirectoryExists(bar_dir)); + std::string file_content; + EXPECT_TRUE(base::ReadFileToString( + temp_dir.Append(FILE_PATH_LITERAL("foo.txt")), &file_content)); + EXPECT_EQ(VirtualFileSystem::kFooContent, file_content); + EXPECT_TRUE(base::ReadFileToString( + bar_dir.Append(FILE_PATH_LITERAL("bar1.txt")), &file_content)); + EXPECT_EQ(VirtualFileSystem::kBar1Content, file_content); + EXPECT_TRUE(base::ReadFileToString( + bar_dir.Append(FILE_PATH_LITERAL("bar2.txt")), &file_content)); + EXPECT_EQ(VirtualFileSystem::kBar2Content, file_content); +} + } // namespace
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index 6b91efc..92967f3 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -70,7 +70,6 @@ <classpathentry kind="src" path="components/policy/android/junit/src"/> <classpathentry kind="src" path="components/precache/android/java/src"/> <classpathentry kind="src" path="components/precache/android/javatests/src"/> - <classpathentry kind="src" path="components/safe_json/android/java/src"/> <classpathentry kind="src" path="components/signin/core/browser/android/java/src"/> <classpathentry kind="src" path="components/signin/core/browser/android/javatests/src"/> <classpathentry kind="src" path="components/sync/android/java/src"/> @@ -113,6 +112,7 @@ <classpathentry kind="src" path="remoting/android/java/src"/> <classpathentry kind="src" path="remoting/android/javatests/src"/> <classpathentry kind="src" path="services/service_manager/public/java/src"/> + <classpathentry kind="src" path="services/data_decoder/public/cpp/android/src"/> <classpathentry kind="src" path="testing/android/appurify_support/java/src"/> <classpathentry kind="src" path="testing/android/broker/java/src"/> <classpathentry kind="src" path="testing/android/driver/java/src"/> @@ -273,7 +273,6 @@ <classpathentry kind="lib" path="out/Debug/lib.java/components/policy/android/policy_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/payments/content/payment_request_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/precache/android/precache_java.jar"/> - <classpathentry kind="lib" path="out/Debug/lib.java/components/safe_json/android/safe_json_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/service_tab_launcher/service_tab_launcher_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/signin/core/browser/android/java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/variations/android/variations_java.jar"/> @@ -292,6 +291,7 @@ <classpathentry kind="lib" path="out/Debug/lib.java/mojo/public/java/system.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/net/android/net_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/printing/printing_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/services/data_decoder/public/android/safe_json_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/services/service_manager/public/interfaces/interfaces_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/sync/android/sync_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/sync/test_support_proto_java.jar"/>
diff --git a/tools/gdb/gdb_chrome.py b/tools/gdb/gdb_chrome.py index ef42a2c..6b956ed9 100644 --- a/tools/gdb/gdb_chrome.py +++ b/tools/gdb/gdb_chrome.py
@@ -217,15 +217,6 @@ pp_set.add_printer('base::Time', '^base::Time$', TimePrinter) -class ManualConstructorPrinter(object): - def __init__(self, val): - self.val = val - - def to_string(self): - return self.val['space_'].cast(self.val.type.template_argument(0)) -pp_set.add_printer('base::ManualConstructor', '^base::ManualConstructor<.*>$', ManualConstructorPrinter) - - class FlatTreePrinter(object): def __init__(self, val): self.val = val
diff --git a/tools/gn/value.h b/tools/gn/value.h index 3103509b..13beb6fd 100644 --- a/tools/gn/value.h +++ b/tools/gn/value.h
@@ -120,8 +120,8 @@ private: // This are a lot of objects associated with every Value that need // initialization and tear down every time. It might be more efficient to - // create a union of ManualConstructor objects (see small_map) and only - // use the one we care about. + // create a union of objects (see small_map) and only use the one we care + // about. Type type_; std::string string_value_; bool boolean_value_;
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 1e460c6c..32408cf 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -605,13 +605,7 @@ 'linux_chromium_rel_ng': 'gpu_tests_release_trybot', 'linux_chromium_tsan_rel_ng': 'tsan_disable_nacl_release_trybot', 'linux_chromium_ubsan_rel_ng': 'ubsan_vptr_release_trybot', - - # These are 'release_bot' rather than 'release_trybot' because - # 'release_trybot' includes 'dcheck_always_on', which might cause - # some layout test results to be different than for normal release - # builds (and we only store baselines for release builds). - 'linux_layout_tests_layout_ng': 'release_bot', - + 'linux_layout_tests_layout_ng': 'release_trybot', 'linux_mojo': 'release_trybot', 'linux_mojo_chromeos': 'chromeos_with_codecs_release_trybot', 'linux_nacl_sdk_build': 'release_bot',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d4c4d919..095e7d09 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -4410,6 +4410,20 @@ <int value="4" label="Browser Startup"/> </enum> +<enum name="ChromeHomePromoResult"> + <int value="0" label="Enabled Chome Home"/> + <int value="1" label="Disabled Chome Home"/> + <int value="2" label="Chrome Home remained enabled"/> + <int value="3" label="Chrome Home remained disabled"/> + <int value="4" label="No action"/> +</enum> + +<enum name="ChromeHomePromoShowReason"> + <int value="0" label="NTP"/> + <int value="1" label="Menu"/> + <int value="2" label="Startup"/> +</enum> + <enum name="ChromeNotifierServiceActionType"> <int value="0" label="Unknown"/> <int value="1" label="First service enabled"/> @@ -37463,6 +37477,14 @@ <int value="1" label="Leave the current page"/> </enum> +<enum name="StrongPopupBlockerAction"> + <int value="0" label="Navigation commit"/> + <int value="1" label="Commit warn site"/> + <int value="2" label="Commit enforced site"/> + <int value="3" label="Popup considered"/> + <int value="4" label="Popup blocked"/> +</enum> + <enum name="StyleSheetCacheStatus"> <int value="0" label="No usable cache found"/> <int value="1" label="DiskCache served the CSS source"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index af3f7d49..984eca5 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -688,6 +688,43 @@ <summary>The reason the bottom sheet was opened.</summary> </histogram> +<histogram name="Android.ChromeHome.Promo.Result.Menu" + enum="ChromeHomePromoResult"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <summary> + The result of showing the Chrome Home promo when launched from the overflow + menu. This action can only be performed if Chrome Home is enabled. + </summary> +</histogram> + +<histogram name="Android.ChromeHome.Promo.Result.NTP" + enum="ChromeHomePromoResult"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <summary> + The result of showing the Chrome Home promo when launched from the NTP. This + action can only be performed if Chrome Home is disabled. + </summary> +</histogram> + +<histogram name="Android.ChromeHome.Promo.Result.Startup" + enum="ChromeHomePromoResult"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <summary> + The result of showing the Chrome Home promo when launched from startup. This + action can only be performed if Chrome Home is disabled. + </summary> +</histogram> + +<histogram name="Android.ChromeHome.Promo.ShowReason" + enum="ChromeHomePromoShowReason"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <summary>The reason the Chrome Home promo was shown.</summary> +</histogram> + <histogram name="Android.ChromeHome.TimeBetweenCloseAndNextOpen" units="ms"> <owner>mdjones@chromium.org</owner> <owner>twellington@chromium.org</owner> @@ -706,6 +743,18 @@ </summary> </histogram> +<histogram name="Android.ChromeHome.UserPreference.Enabled" + enum="BooleanEnabled"> + <owner>mdjones@chromium.org</owner> + <owner>twellington@chromium.org</owner> + <summary> + Records whether or not the user preference for Chrome Home is set to + enabled. This is recorded whenever the browser is restarted and the state of + Chrome Home is first checked. This metric is only recorded if the user's + preference is set. + </summary> +</histogram> + <histogram name="Android.CompressedResources.ExtractionBlockingTime" units="ms"> <owner>estevenson@chromium.org</owner> <owner>agrieve@chromium.org</owner> @@ -10537,6 +10586,15 @@ </summary> </histogram> +<histogram name="ContentSettings.Popups.StrongBlockerActions" + enum="StrongPopupBlockerAction"> + <owner>csharrison@chromium.org</owner> + <summary> + Counts of various events related to the strong popup blocker (aka abusive + experience enforcement), that is triggered via safe browsing. + </summary> +</histogram> + <histogram name="ContentSuggestions.FetchPendingPlaceholder.VisibleDuration" units="ms"> <obsolete> @@ -85615,6 +85673,14 @@ </summary> </histogram> +<histogram name="ThirdPartyModules.InputMethodEditorsCount" units="counts"> + <owner>pmonette@chromium.org</owner> + <summary> + The number of registered input method editors found on the user's machine. + This is emitted shortly after startup when the IME enumeration takes place. + </summary> +</histogram> + <histogram name="ThirdPartyModules.InstalledPrograms.DataSize" units="KB"> <owner>pmonette@chromium.org</owner> <summary> @@ -85686,7 +85752,9 @@ <histogram name="ThirdPartyModules.ShellExtensionsCount" units="counts"> <owner>pmonette@chromium.org</owner> <summary> - The number of registered shell extensions found on the user's machine. + The number of registered shell extensions found on the user's machine. This + is emitted shortly after startup when the shell extensions enumeration takes + place. </summary> </histogram>
diff --git a/ui/aura/mus/input_method_mus.cc b/ui/aura/mus/input_method_mus.cc index d44addb..3659d86 100644 --- a/ui/aura/mus/input_method_mus.cc +++ b/ui/aura/mus/input_method_mus.cc
@@ -115,7 +115,9 @@ } bool InputMethodMus::IsCandidatePopupOpen() const { - return text_input_client_->is_candidate_window_visible(); + // TODO(moshayedi): crbug.com/637416. Implement this properly when we have a + // mean for displaying candidate list popup. + return false; } ui::EventDispatchDetails InputMethodMus::SendKeyEventToInputMethod(
diff --git a/ui/aura/mus/text_input_client_impl.cc b/ui/aura/mus/text_input_client_impl.cc index 1dffea77..9f926a77 100644 --- a/ui/aura/mus/text_input_client_impl.cc +++ b/ui/aura/mus/text_input_client_impl.cc
@@ -58,8 +58,4 @@ } } -void TextInputClientImpl::SetCandidateWindowVisible(bool visible) { - is_candidate_window_visible_ = visible; -} - } // namespace aura
diff --git a/ui/aura/mus/text_input_client_impl.h b/ui/aura/mus/text_input_client_impl.h index 61dac78..46bf153 100644 --- a/ui/aura/mus/text_input_client_impl.h +++ b/ui/aura/mus/text_input_client_impl.h
@@ -24,10 +24,6 @@ ui::internal::InputMethodDelegate* delegate); ~TextInputClientImpl() override; - bool is_candidate_window_visible() const { - return is_candidate_window_visible_; - } - ui::mojom::TextInputClientPtr CreateInterfacePtrAndBind(); private: @@ -40,12 +36,10 @@ void DispatchKeyEventPostIME( std::unique_ptr<ui::Event> event, DispatchKeyEventPostIMECallback callback) override; - void SetCandidateWindowVisible(bool visible) override; ui::TextInputClient* text_input_client_; mojo::Binding<ui::mojom::TextInputClient> binding_; ui::internal::InputMethodDelegate* delegate_; - bool is_candidate_window_visible_ = false; DISALLOW_COPY_AND_ASSIGN(TextInputClientImpl); };
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index f650f8a..8a192401 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -121,7 +121,6 @@ void DisableDragDropClient() { install_drag_drop_client_ = false; } service_manager::Connector* connector() { return connector_; } - ui::Gpu* gpu() { return gpu_.get(); } CaptureSynchronizer* capture_synchronizer() { return capture_synchronizer_.get(); }
diff --git a/ui/base/ime/chromeos/ime_candidate_window_handler_interface.h b/ui/base/ime/chromeos/ime_candidate_window_handler_interface.h index 86d8c06..3d4cb91 100644 --- a/ui/base/ime/chromeos/ime_candidate_window_handler_interface.h +++ b/ui/base/ime/chromeos/ime_candidate_window_handler_interface.h
@@ -43,9 +43,6 @@ // |is_focused| is true when the text field gains the focus. virtual void FocusStateChanged(bool is_focused) {} - // Called when candidate window changes visibility. - virtual void OnCandidateWindowVisibilityChanged(bool visible) {} - protected: IMECandidateWindowHandlerInterface() {} };
diff --git a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc index 8d5e26b..9ea728c 100644 --- a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc +++ b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc
@@ -4,14 +4,11 @@ #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" -#include "ui/base/ime/ime_bridge.h" - namespace chromeos { MockIMECandidateWindowHandler::MockIMECandidateWindowHandler() : set_cursor_bounds_call_count_(0), update_lookup_table_call_count_(0) { - ui::IMEBridge::Get()->SetCandidateWindowHandler(this); } MockIMECandidateWindowHandler::~MockIMECandidateWindowHandler() { @@ -37,11 +34,6 @@ ++set_cursor_bounds_call_count_; } -void MockIMECandidateWindowHandler::OnCandidateWindowVisibilityChanged( - bool visible) { - is_candidate_window_visible_ = visible; -} - void MockIMECandidateWindowHandler::Reset() { set_cursor_bounds_call_count_ = 0; update_lookup_table_call_count_ = 0;
diff --git a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h index 273fdcee..8250848 100644 --- a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h +++ b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.h
@@ -37,7 +37,6 @@ bool visible) override; void SetCursorBounds(const gfx::Rect& cursor_bounds, const gfx::Rect& composition_head) override; - void OnCandidateWindowVisibilityChanged(bool visible) override; int set_cursor_bounds_call_count() const { return set_cursor_bounds_call_count_; @@ -50,18 +49,12 @@ const UpdateLookupTableArg& last_update_lookup_table_arg() { return last_update_lookup_table_arg_; } - - int is_candidate_window_visible() const { - return is_candidate_window_visible_; - } - // Resets all call count. void Reset(); private: int set_cursor_bounds_call_count_; int update_lookup_table_call_count_; - bool is_candidate_window_visible_ = false; UpdateLookupTableArg last_update_lookup_table_arg_; };
diff --git a/ui/views/layout/grid_layout.cc b/ui/views/layout/grid_layout.cc index 0775b73..e8df98e9 100644 --- a/ui/views/layout/grid_layout.cc +++ b/ui/views/layout/grid_layout.cc
@@ -4,8 +4,8 @@ #include "ui/views/layout/grid_layout.h" -#include "base/logging.h" -#include "base/macros.h" +#include <cmath> + #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "ui/views/border.h" @@ -14,6 +14,23 @@ #include "ui/views/window/dialog_delegate.h" namespace views { +namespace { + +// Used when calculating the minimum size to build up how much each column is +// shrunk. +struct ColumnMinResizeData { + // The column being resized. + Column* column; + + // The remaining amount of space available (the difference between the + // preferred and minimum). + int available = 0; + + // How much to shrink the preferred by. + int delta = 0; +}; + +} // namespace // LayoutElement ------------------------------------------------------ @@ -176,6 +193,7 @@ GridLayout::Alignment h_align() { return h_align_; } GridLayout::Alignment v_align() { return v_align_; } + // LayoutElement: void ResetSize() override; private: @@ -305,9 +323,16 @@ // Identifies the location in the grid of a particular view, along with // placement information and size information. struct ViewState { - ViewState(ColumnSet* column_set, View* view, int start_col, int start_row, - int col_span, int row_span, GridLayout::Alignment h_align, - GridLayout::Alignment v_align, int pref_width, int pref_height) + ViewState(ColumnSet* column_set, + View* view, + int start_col, + int start_row, + int col_span, + int row_span, + GridLayout::Alignment h_align, + GridLayout::Alignment v_align, + int pref_width, + int pref_height) : column_set(column_set), view(view), start_col(start_col), @@ -318,11 +343,8 @@ v_align(v_align), pref_width_fixed(pref_width > 0), pref_height_fixed(pref_height > 0), - pref_width(pref_width), - pref_height(pref_height), - remaining_width(0), - remaining_height(0), - baseline(-1) { + width(pref_width), + height(pref_height) { DCHECK(view && start_col >= 0 && start_row >= 0 && col_span > 0 && row_span > 0 && start_col < column_set->num_columns() && (start_col + col_span) <= column_set->num_columns()); @@ -337,23 +359,29 @@ const GridLayout::Alignment h_align; const GridLayout::Alignment v_align; - // If true, the pref_width/pref_height were explicitly set and the view's - // preferred size is ignored. + // If true, the height/width were explicitly set and the view's preferred and + // minimum size is ignored. const bool pref_width_fixed; const bool pref_height_fixed; - // The preferred width/height. These are reset during the layout process. - int pref_width; - int pref_height; + // The width/height. This is one of possible three values: + // . an explicitly set value (if pref_X_fixed is true). If an explicitly set + // value was provided, then this value never changes. + // . the preferred width. + // . the minimum width. + // If the value wasn't explicitly set, then whether the value is the preferred + // or minimum depends upon the pass. + int width; + int height; // Used during layout. Gives how much width/height has not yet been // distributed to the columns/rows the view is in. - int remaining_width; - int remaining_height; + int remaining_width = 0; + int remaining_height = 0; // The baseline. Only used if the view is vertically aligned along the // baseline. - int baseline; + int baseline = -1; }; static bool CompareByColumnSpan(const ViewState* v1, const ViewState* v2) { @@ -579,22 +607,39 @@ LayoutElement::CalculateLocationsFromSize(&columns_); } -void ColumnSet::CalculateSize() { - gfx::Size pref; - // Reset the preferred and remaining sizes. +void ColumnSet::CalculateSize(SizeCalculationType type) { +#if DCHECK_IS_ON() + // SizeCalculationType::MINIMUM must be preceeded by a request for + // SizeCalculationType::PREFERRED. + DCHECK(type == SizeCalculationType::PREFERRED || + last_calculation_type_ == PREFERRED); + last_calculation_type_ = type; +#endif + // Reset the size and remaining sizes. for (auto* view_state : view_states_) { if (!view_state->pref_width_fixed || !view_state->pref_height_fixed) { - pref = view_state->view->GetPreferredSize(); + gfx::Size size; + if (type == SizeCalculationType::MINIMUM && CanUseMinimum(*view_state)) { + // If the min size is bigger than the preferred, use the preferred. + // This relies on MINIMUM being calculated immediately after PREFERRED, + // which the rest of this code relies on as well. + size = view_state->view->GetMinimumSize(); + if (size.width() > view_state->width) + size.set_width(view_state->width); + if (size.height() > view_state->height) + size.set_height(view_state->height); + } else { + size = view_state->view->GetPreferredSize(); + } if (!view_state->pref_width_fixed) - view_state->pref_width = pref.width(); + view_state->width = size.width(); if (!view_state->pref_height_fixed) - view_state->pref_height = pref.height(); + view_state->height = size.height(); } - view_state->remaining_width = pref.width(); - view_state->remaining_height = pref.height(); + view_state->remaining_width = view_state->width; + view_state->remaining_height = view_state->height; } - // Let layout element reset the sizes for us. LayoutElement::ResetSizes(&columns_); // Distribute the size of each view with a col span == 1. @@ -603,7 +648,7 @@ (*view_state_iterator)->col_span == 1; ++view_state_iterator) { ViewState* view_state = *view_state_iterator; Column* column = columns_[view_state->start_col].get(); - column->AdjustSize(view_state->pref_width); + column->AdjustSize(view_state->width); view_state->remaining_width -= column->Size(); } @@ -626,10 +671,103 @@ } } -void ColumnSet::Resize(int delta) { +void ColumnSet::Resize(int delta, bool honors_min_width) { + if (delta < 0 && honors_min_width) { + // DistributeDelta() assumes resizable columns can equally be shrunk. That + // isn't desired when given a size smaller than the prefered. Instead the + // columns need to be resized but bounded by the minimum. ResizeUsingMin() + // does this. + ResizeUsingMin(delta); + return; + } + LayoutElement::DistributeDelta(delta, &columns_); } +void ColumnSet::ResizeUsingMin(int total_delta) { + DCHECK_LE(total_delta, 0); + + // |total_delta| is negative, but easier to do operations when positive. + total_delta = std::abs(total_delta); + + std::vector<int> preferred_column_sizes(columns_.size()); + for (size_t i = 0; i < columns_.size(); ++i) + preferred_column_sizes[i] = columns_[i]->Size(); + + // Recalculate the sizes using the min. + CalculateSize(ColumnSet::SizeCalculationType::MINIMUM); + + // Build up the set of columns that can be shrunk in |resize_data|, this + // iteration also resets the size of the column back to the preferred size. + std::vector<ColumnMinResizeData> resize_data; + float total_percent = 0; + for (size_t i = 0; i < columns_.size(); ++i) { + Column* column = columns_[i].get(); + const int available = + std::max(0, preferred_column_sizes[i] - + std::max(column->min_width_, column->Size())); + DCHECK_GE(available, 0); + // Set the size back to preferred. We'll reset the size if necessary later. + column->SetSize(preferred_column_sizes[i]); + if (column->ResizePercent() <= 0 || available == 0) + continue; + resize_data.push_back({column, available, 0}); + total_percent += column->ResizePercent(); + } + if (resize_data.empty()) + return; + + // Loop through the columns updating the amount available and the amount to + // resize. This may take multiple iterations if the column min is hit. + // Generally there are not that many columns in a GridLayout, so this code is + // not optimized. Any time the column hits the min it is removed from + // |resize_data|. + while (!resize_data.empty() && total_delta > 0) { + float next_iteration_total_percent = total_percent; + int next_iteration_delta = total_delta; +#if DCHECK_IS_ON() + const int initial_delta = total_delta; +#endif + for (size_t i = resize_data.size(); i > 0; --i) { + ColumnMinResizeData& data = resize_data[i - 1]; + int delta = + std::min(data.available, + static_cast<int>(total_delta * data.column->ResizePercent() / + total_percent)); + // Make sure at least one column in resized (rounding errors may prevent + // that). + if (i == 1 && delta == 0 && next_iteration_delta == total_delta) + delta = 1; + next_iteration_delta -= delta; + data.delta += delta; + data.available -= delta; + if (data.available == 0) { + data.column->SetSize(data.column->Size() - data.delta); + next_iteration_total_percent -= data.column->ResizePercent(); + resize_data.erase(resize_data.begin() + (i - 1)); + } + } +#if DCHECK_IS_ON() + DCHECK(next_iteration_delta < initial_delta); +#endif + total_delta = next_iteration_delta; + total_percent = next_iteration_total_percent; + } + + for (const ColumnMinResizeData& data : resize_data) + data.column->SetSize(data.column->Size() - data.delta); +} + +bool ColumnSet::CanUseMinimum(const ViewState& view_state) const { + for (int i = 0; i < view_state.col_span; ++i) { + if (columns_[i + view_state.start_col]->ResizePercent() <= 0 || + columns_[i + view_state.start_col]->size_type_ == GridLayout::FIXED) { + return false; + } + } + return true; +} + // GridLayout ------------------------------------------------------------- // static @@ -766,16 +904,15 @@ column_set->columns_[view_state->start_col]->Location() + insets.left(); int width = column_set->GetColumnWidth(view_state->start_col, view_state->col_span); - CalculateSize(view_state->pref_width, view_state->h_align, - &x, &width); + CalculateSize(view_state->width, view_state->h_align, &x, &width); int y = rows_[view_state->start_row]->Location() + insets.top(); int height = LayoutElement::TotalSize(view_state->start_row, view_state->row_span, &rows_); if (view_state->v_align == BASELINE && view_state->baseline != -1) { y += rows_[view_state->start_row]->max_ascent() - view_state->baseline; - height = view_state->pref_height; + height = view_state->height; } else { - CalculateSize(view_state->pref_height, view_state->v_align, &y, &height); + CalculateSize(view_state->height, view_state->v_align, &y, &height); } view->SetBounds(x, y, width, height); } @@ -825,7 +962,7 @@ // preferred heights are derived from their width, as such we need to // calculate the size of the columns first. for (const auto& column_set : column_sets_) { - column_set->CalculateSize(); + column_set->CalculateSize(ColumnSet::SizeCalculationType::PREFERRED); pref->set_width(std::max(pref->width(), column_set->LayoutWidth())); } const gfx::Insets& insets = host_->GetInsets(); @@ -835,8 +972,8 @@ width = width ? width : pref->width(); for (const auto& column_set : column_sets_) { // We're doing a layout, divvy up any extra space. - column_set->Resize(width - column_set->LayoutWidth() - insets.left() - - insets.right()); + column_set->Resize(width - column_set->LayoutWidth() - insets.width(), + honors_min_width_); // And reset the x coordinates. column_set->ResetColumnXCoordinates(); } @@ -851,7 +988,7 @@ // . If the width the view will be given is different than it's pref, ask // for the height given a particularly width. for (const auto& view_state : view_states_) { - view_state->remaining_height = view_state->pref_height; + view_state->remaining_height = view_state->height; if (view_state->v_align == BASELINE) view_state->baseline = view_state->view->GetBaseline(); @@ -862,13 +999,11 @@ int actual_width = view_state->column_set->GetColumnWidth(view_state->start_col, view_state->col_span); - if (actual_width != view_state->pref_width && - !view_state->pref_height_fixed) { + if (actual_width != view_state->width && !view_state->pref_height_fixed) { // The width this view will get differs from its preferred. Some Views // pref height varies with its width; ask for the preferred again. - view_state->pref_height = - view_state->view->GetHeightForWidth(actual_width); - view_state->remaining_height = view_state->pref_height; + view_state->height = view_state->view->GetHeightForWidth(actual_width); + view_state->remaining_height = view_state->height; } } } @@ -881,9 +1016,9 @@ Row* row = rows_[view_state->start_row].get(); row->AdjustSize(view_state->remaining_height); if (view_state->baseline != -1 && - view_state->baseline <= view_state->pref_height) { + view_state->baseline <= view_state->height) { row->AdjustSizeForBaseline(view_state->baseline, - view_state->pref_height - view_state->baseline); + view_state->height - view_state->baseline); } view_state->remaining_height = 0; }
diff --git a/ui/views/layout/grid_layout.h b/ui/views/layout/grid_layout.h index a2521d4..9028ed69 100644 --- a/ui/views/layout/grid_layout.h +++ b/ui/views/layout/grid_layout.h
@@ -10,6 +10,7 @@ #include <memory> #include <vector> +#include "base/logging.h" #include "base/macros.h" #include "ui/gfx/geometry/size.h" #include "ui/views/layout/layout_manager.h" @@ -57,8 +58,14 @@ // GridLayout allows you to force columns to have the same width. This is // done using the LinkColumnSizes method. // -// AddView takes care of adding the View to the View the GridLayout was +// AddView() takes care of adding the View to the View the GridLayout was // created with. +// +// If the host View is sized smaller than the preferred width and +// set_honors_min_width(true) is called, GridLayout may use the minimum size. +// The minimum size is considered only for Views whose preferred width was not +// explicitly specified and the containing columns are resizable +// (resize_percent > 0) and don't have a fixed width. namespace views { class Column; @@ -105,6 +112,11 @@ ~GridLayout() override; + // See class description for what this does. + // TODO(sky): investigate making this the default, problem is it has subtle + // effects on the layout and some code is relying on old behavior. + void set_honors_min_width(bool value) { honors_min_width_ = value; } + // Creates a new column set with the specified id and returns it. // The id is later used when starting a new row. // GridLayout takes ownership of the ColumnSet and will delete it when @@ -250,6 +262,8 @@ // Minimum preferred size. gfx::Size minimum_size_; + bool honors_min_width_ = false; + DISALLOW_COPY_AND_ASSIGN(GridLayout); }; @@ -343,12 +357,26 @@ // NOTE: this doesn't include the insets. void ResetColumnXCoordinates(); + enum SizeCalculationType { + PREFERRED, + MINIMUM, + }; + // Calculate the preferred width of each view in this column set, as well // as updating the remaining_width. - void CalculateSize(); + void CalculateSize(SizeCalculationType type); - // Distributes delta among the resizable columns. - void Resize(int delta); + // Distributes delta among the resizable columns. |honors_min_width| matches + // that of |GridLayout::honors_min_width_|. + void Resize(int delta, bool honors_min_width); + + // Used when GridLayout is given a size smaller than the preferred width. + // |total_delta| is negative and the difference between the preferred width + // and the target width. + void ResizeUsingMin(int total_delta); + + // Only use the minimum size if all the columns the view is in are resizable. + bool CanUseMinimum(const ViewState& view_state) const; // ID for this columnset. const int id_; @@ -368,6 +396,10 @@ // for a description of what the master column is. std::vector<Column*> master_columns_; +#if DCHECK_IS_ON() + SizeCalculationType last_calculation_type_ = SizeCalculationType::PREFERRED; +#endif + DISALLOW_COPY_AND_ASSIGN(ColumnSet); };
diff --git a/ui/views/layout/grid_layout_unittest.cc b/ui/views/layout/grid_layout_unittest.cc index 686eefb..31bc7c6 100644 --- a/ui/views/layout/grid_layout_unittest.cc +++ b/ui/views/layout/grid_layout_unittest.cc
@@ -27,6 +27,27 @@ return view; } +// View that lets you set the minimum size. +class MinSizeView : public View { + public: + explicit MinSizeView(const gfx::Size& min_size) : min_size_(min_size) {} + ~MinSizeView() override = default; + + // View: + gfx::Size GetMinimumSize() const override { return min_size_; } + + private: + const gfx::Size min_size_; + + DISALLOW_COPY_AND_ASSIGN(MinSizeView); +}; + +View* CreateViewWithMinAndPref(const gfx::Size& min, const gfx::Size& pref) { + MinSizeView* view = new MinSizeView(min); + view->SetPreferredSize(pref); + return view; +} + // A test view that wants to alter its preferred size and re-layout when it gets // added to the View hierarchy. class LayoutOnAddView : public View { @@ -825,4 +846,181 @@ RemoveAll(); } +TEST_F(GridLayoutTest, ColumnMinForcesPreferredWidth) { + // Column's min width is greater than views preferred/min width. This should + // force the preferred width to the min width of the column. + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 5, GridLayout::USE_PREF, 0, + 100); + layout()->StartRow(0, 0); + View* view1 = CreateSizedView(gfx::Size(20, 10)); + layout()->AddView(view1); + + EXPECT_EQ(gfx::Size(100, 10), GetPreferredSize()); +} + +TEST_F(GridLayoutTest, HonorsColumnMin) { + layout()->set_honors_min_width(true); + + // Verifies that a column with a min width is never shrunk smaller than the + // minw width. + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 5, GridLayout::USE_PREF, 0, + 100); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 5, GridLayout::USE_PREF, 0, + 0); + layout()->StartRow(0, 0); + View* view1 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(125, 10)); + layout()->AddView(view1); + + View* view2 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(50, 10)); + layout()->AddView(view2); + + EXPECT_EQ(gfx::Size(175, 10), GetPreferredSize()); + + host().SetBounds(0, 0, 175, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 125, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(125, 0, 50, 10), view2->bounds()); + + host().SetBounds(0, 0, 125, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(100, 0, 25, 10), view2->bounds()); + + host().SetBounds(0, 0, 120, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(100, 0, 20, 10), view2->bounds()); +} + +TEST_F(GridLayoutTest, TwoViewsOneSizeSmallerThanMinimum) { + layout()->set_honors_min_width(true); + // Two columns, equally resizable with two views. Only the first view is + // resizable. + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 5, GridLayout::USE_PREF, 0, + 0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 5, GridLayout::USE_PREF, 0, + 0); + layout()->StartRow(0, 0); + View* view1 = CreateViewWithMinAndPref(gfx::Size(20, 10), gfx::Size(100, 10)); + layout()->AddView(view1); + + View* view2 = + CreateViewWithMinAndPref(gfx::Size(100, 10), gfx::Size(100, 10)); + layout()->AddView(view2); + + host().SetBounds(0, 0, 110, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(20, 0, 100, 10), view2->bounds()); +} + +TEST_F(GridLayoutTest, TwoViewsBothSmallerThanMinimumDifferentResizeWeights) { + layout()->set_honors_min_width(true); + // Two columns, equally resizable with two views. Only the first view is + // resizable. + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 8, GridLayout::USE_PREF, 0, + 0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 2, GridLayout::USE_PREF, 0, + 0); + layout()->StartRow(0, 0); + View* view1 = CreateViewWithMinAndPref(gfx::Size(91, 10), gfx::Size(100, 10)); + layout()->AddView(view1); + + View* view2 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(100, 10)); + layout()->AddView(view2); + + // 200 is the preferred, each should get their preferred width. + host().SetBounds(0, 0, 200, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(100, 0, 100, 10), view2->bounds()); + + // 1 pixel smaller than pref. + host().SetBounds(0, 0, 199, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 99, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(99, 0, 100, 10), view2->bounds()); + + // 10 pixels smaller than pref. + host().SetBounds(0, 0, 190, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 92, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(92, 0, 98, 10), view2->bounds()); + + // 11 pixels smaller than pref. + host().SetBounds(0, 0, 189, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 91, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(91, 0, 98, 10), view2->bounds()); + + // 12 pixels smaller than pref. + host().SetBounds(0, 0, 188, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 91, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(91, 0, 97, 10), view2->bounds()); + + host().SetBounds(0, 0, 5, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 91, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(91, 0, 10, 10), view2->bounds()); +} + +TEST_F(GridLayoutTest, TwoViewsOneColumnUsePrefOtherFixed) { + layout()->set_honors_min_width(true); + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 8, GridLayout::USE_PREF, 0, + 0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 2, GridLayout::FIXED, 100, + 0); + layout()->StartRow(0, 0); + View* view1 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(100, 10)); + layout()->AddView(view1); + View* view2 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(100, 10)); + layout()->AddView(view2); + + host().SetBounds(0, 0, 120, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 10), view1->bounds()); + // Even though column 2 has a resize percent, it's FIXED, so it won't shrink. + EXPECT_EQ(gfx::Rect(20, 0, 100, 10), view2->bounds()); + + host().SetBounds(0, 0, 10, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 10, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(10, 0, 100, 10), view2->bounds()); +} + +TEST_F(GridLayoutTest, TwoViewsBothColumnsResizableOneViewFixedWidthMin) { + layout()->set_honors_min_width(true); + ColumnSet* set = layout()->AddColumnSet(0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, + 0); + set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, + 0); + layout()->StartRow(0, 0); + View* view1 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(100, 10)); + layout()->AddView(view1); + View* view2 = CreateViewWithMinAndPref(gfx::Size(10, 10), gfx::Size(100, 10)); + layout()->AddView(view2, 1, 1, GridLayout::FILL, GridLayout::FILL, 50, 10); + + host().SetBounds(0, 0, 80, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 30, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(30, 0, 50, 10), view2->bounds()); + + host().SetBounds(0, 0, 70, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(20, 0, 50, 10), view2->bounds()); + + host().SetBounds(0, 0, 10, 0); + layout()->Layout(&host()); + EXPECT_EQ(gfx::Rect(0, 0, 10, 10), view1->bounds()); + EXPECT_EQ(gfx::Rect(10, 0, 50, 10), view2->bounds()); +} + } // namespace views
diff --git a/url/BUILD.gn b/url/BUILD.gn index 82eb115a..d33801bc 100644 --- a/url/BUILD.gn +++ b/url/BUILD.gn
@@ -25,6 +25,7 @@ "scheme_host_port.h", "third_party/mozilla/url_parse.cc", "third_party/mozilla/url_parse.h", + "url_canon.cc", "url_canon.h", "url_canon_etc.cc", "url_canon_filesystemurl.cc",
diff --git a/url/url_canon.cc b/url/url_canon.cc new file mode 100644 index 0000000..d51a317 --- /dev/null +++ b/url/url_canon.cc
@@ -0,0 +1,12 @@ +// 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 "url/url_canon.h" + +namespace url { + +template class EXPORT_TEMPLATE_DEFINE(URL_EXPORT) CanonOutputT<char>; +template class EXPORT_TEMPLATE_DEFINE(URL_EXPORT) CanonOutputT<base::char16>; + +} // namespace url
diff --git a/url/url_canon.h b/url/url_canon.h index 887150b0..ede62d3 100644 --- a/url/url_canon.h +++ b/url/url_canon.h
@@ -8,6 +8,7 @@ #include <stdlib.h> #include <string.h> +#include "base/export_template.h" #include "base/strings/string16.h" #include "url/third_party/mozilla/url_parse.h" #include "url/url_export.h" @@ -174,6 +175,11 @@ T fixed_buffer_[fixed_capacity]; }; +// Explicitely instantiate commonly used instatiations. +extern template class EXPORT_TEMPLATE_DECLARE(URL_EXPORT) CanonOutputT<char>; +extern template class EXPORT_TEMPLATE_DECLARE(URL_EXPORT) + CanonOutputT<base::char16>; + // Normally, all canonicalization output is in narrow characters. We support // the templates so it can also be used internally if a wide buffer is // required.