diff --git a/DEPS b/DEPS index 9ed8d756..94ec2f94 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'd818ebf4a31724aa93fd439a2ac4195f69ae3af0', + 'skia_revision': 'ef21d7e47963c716895684f9f397e7cbcdb845ab', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '6856800ecfc8d4d7df19b3035fbb075c090ccd0c', + 'v8_revision': '3166e28a2a19de790e4d7f7e5e0b756f7c5945c7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -129,7 +129,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '09646f2d0497eb4cdcf2f3843585faa9264196f4', + 'pdfium_revision': '65f38c8fae09cf727a9ccc34587ae1ed9027b655', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -165,7 +165,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': '3836c556c4c64a3820bf0656bf2b1cfcf8dbb16a', + 'catapult_revision': '153acbd707c080919d82af77efc800b8891009bd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -540,7 +540,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a3230c43892ec837213dc2625633abf47be3ffaf', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'b71f42943166f8d0e3993e65f05d2f4dc974e38b', 'condition': 'checkout_linux', }, @@ -565,7 +565,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '621c9d28c3d08488bbd378a97f5cbfacdf5853ed', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '605dd3126a6c94eef6868fdaac977765905afb7a', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -913,7 +913,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b56a7a2a1a622584fa9c32b1285589c24f7eec3e', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'ce3f7b384d77f66d760bf07eeadeb4b66f239c98', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -929,6 +929,9 @@ 'src/third_party/pyftpdlib/src': Var('chromium_git') + '/external/pyftpdlib.git' + '@' + '2be6d65e31c7ee6320d059f581f05ae8d89d7e45', + 'src/third_party/quic_trace/src': + Var('chromium_git') + '/external/github.com/google/quic-trace.git' + '@' + 'c9028909ba2356e073de4ea963b56fd81417a46d', + 'src/third_party/pywebsocket/src': Var('chromium_git') + '/external/github.com/google/pywebsocket.git' + '@' + '2d7b73c3acbd0f41dcab487ae5c97c6feae06ce2', @@ -1032,7 +1035,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a5c263cc63ffc2cc189b5214074c8792067c1853', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '5c71e74331bd57dd94be6d66d7490c1a95154e48', + Var('webrtc_git') + '/src.git' + '@' + '312466a20450cc22765ed91a3ed3ca7adcad37c0', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1066,7 +1069,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e8384f5d76c307b86f2adc4d3064d4a040ac9f40', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c9b520351974c3f9cc476336b4596127386e46e4', 'condition': 'checkout_src_internal', },
diff --git a/ash/app_menu/app_menu_model_adapter.cc b/ash/app_menu/app_menu_model_adapter.cc index 16889ffc..f078e82 100644 --- a/ash/app_menu/app_menu_model_adapter.cc +++ b/ash/app_menu/app_menu_model_adapter.cc
@@ -54,8 +54,7 @@ root_ = CreateMenu(); if (features::IsNotificationIndicatorEnabled()) { notification_menu_controller_ = - std::make_unique<NotificationMenuController>(app_id_, root_, - model_.get()); + std::make_unique<NotificationMenuController>(app_id_, root_, this); } menu_runner_ = std::make_unique<views::MenuRunner>(root_, run_types); menu_runner_->RunMenuAt(menu_owner_->GetWidget(), nullptr /* MenuButton */,
diff --git a/ash/app_menu/app_menu_model_adapter.h b/ash/app_menu/app_menu_model_adapter.h index a53870f..9b41100 100644 --- a/ash/app_menu/app_menu_model_adapter.h +++ b/ash/app_menu/app_menu_model_adapter.h
@@ -54,14 +54,13 @@ void ExecuteCommand(int id, int mouse_event_flags) override; void OnMenuClosed(views::MenuItemView* menu) override; + ui::SimpleMenuModel* model() { return model_.get(); } + protected: const std::string& app_id() const { return app_id_; } base::TimeTicks menu_open_time() const { return menu_open_time_; } ui::MenuSourceType source_type() const { return source_type_; } - ui::SimpleMenuModel* model() { return model_.get(); } - const ui::SimpleMenuModel* model() const { return model_.get(); } - // Helper method to record ExecuteCommand() histograms. void RecordExecuteCommandHistogram(int command_id);
diff --git a/ash/app_menu/notification_item_view.cc b/ash/app_menu/notification_item_view.cc index 82c53a4..ccabec0d 100644 --- a/ash/app_menu/notification_item_view.cc +++ b/ash/app_menu/notification_item_view.cc
@@ -9,6 +9,7 @@ #include "ui/gfx/image/image.h" #include "ui/gfx/text_elider.h" #include "ui/message_center/views/proportional_image_view.h" +#include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/label.h" #include "ui/views/controls/menu/menu_config.h" @@ -38,14 +39,31 @@ } // namespace -NotificationItemView::NotificationItemView(const base::string16& title, - const base::string16& message, - const gfx::Image& icon, - const std::string notification_id) - : title_(title), message_(message), notification_id_(notification_id) { +NotificationItemView::NotificationItemView( + NotificationItemView::Delegate* delegate, + message_center::SlideOutController::Delegate* slide_out_controller_delegate, + const base::string16& title, + const base::string16& message, + const gfx::Image& icon, + const std::string& notification_id) + : delegate_(delegate), + slide_out_controller_( + std::make_unique<message_center::SlideOutController>( + this, + slide_out_controller_delegate)), + title_(title), + message_(message), + notification_id_(notification_id) { + DCHECK(delegate_); + DCHECK(slide_out_controller_delegate); + + // Paint to a new layer so |slide_out_controller_| can control the opacity. + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(true); SetBorder(views::CreateEmptyBorder( gfx::Insets(kNotificationVerticalPadding, kNotificationHorizontalPadding, kNotificationVerticalPadding, kIconHorizontalPadding))); + SetBackground(views::CreateSolidBackground(SK_ColorWHITE)); text_container_ = new views::View(); text_container_->SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -100,4 +118,35 @@ kProportionalIconViewSize.height()); } +bool NotificationItemView::OnMousePressed(const ui::MouseEvent& event) { + return true; +} + +bool NotificationItemView::OnMouseDragged(const ui::MouseEvent& event) { + return true; +} + +void NotificationItemView::OnMouseReleased(const ui::MouseEvent& event) { + gfx::Point location(event.location()); + views::View::ConvertPointToScreen(this, &location); + if (!event.IsOnlyLeftMouseButton() || + !GetBoundsInScreen().Contains(location)) { + return; + } + + delegate_->ActivateNotificationAndClose(notification_id_); +} + +void NotificationItemView::OnGestureEvent(ui::GestureEvent* event) { + // Drag gestures are handled by |slide_out_controller_|. + switch (event->type()) { + case ui::ET_GESTURE_TAP: + event->SetHandled(); + delegate_->ActivateNotificationAndClose(notification_id_); + return; + default: + return; + } +} + } // namespace ash
diff --git a/ash/app_menu/notification_item_view.h b/ash/app_menu/notification_item_view.h index bf08818..242ffa1 100644 --- a/ash/app_menu/notification_item_view.h +++ b/ash/app_menu/notification_item_view.h
@@ -5,10 +5,12 @@ #ifndef ASH_APP_MENU_NOTIFICATION_ITEM_VIEW_H_ #define ASH_APP_MENU_NOTIFICATION_ITEM_VIEW_H_ +#include <memory> #include <string> #include "ash/app_menu/app_menu_export.h" #include "base/strings/string16.h" +#include "ui/message_center/views/slide_out_controller.h" #include "ui/views/view.h" namespace gfx { @@ -25,16 +27,32 @@ // The view which contains the details of a notification. class APP_MENU_EXPORT NotificationItemView : public views::View { public: - NotificationItemView(const base::string16& title, + // Used to activate NotificationItemView. + class Delegate { + public: + // Activates the notification corresponding with |notification_id| and + // closes the menu. + virtual void ActivateNotificationAndClose( + const std::string& notification_id) = 0; + }; + + NotificationItemView(NotificationItemView::Delegate* delegate, + message_center::SlideOutController::Delegate* + slide_out_controller_delegate, + const base::string16& title, const base::string16& message, const gfx::Image& icon, - const std::string notification_id); + const std::string& notification_id); ~NotificationItemView() override; // views::View overrides: gfx::Size CalculatePreferredSize() const override; void Layout() override; + bool OnMousePressed(const ui::MouseEvent& event) override; + bool OnMouseDragged(const ui::MouseEvent& event) override; + void OnMouseReleased(const ui::MouseEvent& event) override; + void OnGestureEvent(ui::GestureEvent* event) override; const std::string& notification_id() const { return notification_id_; } const base::string16& title() const { return title_; } @@ -47,6 +65,12 @@ // Holds the notification's icon. Owned by the views hierarchy. message_center::ProportionalImageView* proportional_icon_view_ = nullptr; + // Owned by AppMenuModelAdapter. Used to activate notifications. + Delegate* const delegate_; + + // Controls the sideways gesture drag behavior. + std::unique_ptr<message_center::SlideOutController> slide_out_controller_; + // Notification properties. const base::string16 title_; const base::string16 message_;
diff --git a/ash/app_menu/notification_menu_controller.cc b/ash/app_menu/notification_menu_controller.cc index e45473f..8f2cfce 100644 --- a/ash/app_menu/notification_menu_controller.cc +++ b/ash/app_menu/notification_menu_controller.cc
@@ -4,6 +4,7 @@ #include "ash/app_menu/notification_menu_controller.h" +#include "ash/app_menu/app_menu_model_adapter.h" #include "ash/app_menu/notification_menu_view.h" #include "ash/public/cpp/app_menu_constants.h" #include "ui/views/controls/menu/menu_item_view.h" @@ -14,11 +15,12 @@ NotificationMenuController::NotificationMenuController( const std::string& app_id, views::MenuItemView* root_menu, - ui::SimpleMenuModel* model) + AppMenuModelAdapter* app_menu_model_adapter) : app_id_(app_id), root_menu_(root_menu), - model_(model), + app_menu_model_adapter_(app_menu_model_adapter), message_center_observer_(this) { + DCHECK(app_menu_model_adapter_); message_center_observer_.Add(message_center::MessageCenter::Get()); InitializeNotificationMenuView(); } @@ -60,9 +62,9 @@ // |root_menu_|, and remove the entry from the model. const views::View* container = notification_menu_view_->parent(); root_menu_->RemoveMenuItemAt(root_menu_->GetSubmenu()->GetIndexOf(container)); - // TODO(newcomer): move NOTIFICATION_CONTAINER and other CommandId enums to a - // shared constant file in ash/public/cpp. - model_->RemoveItemAt(model_->GetIndexOfCommandId(NOTIFICATION_CONTAINER)); + app_menu_model_adapter_->model()->RemoveItemAt( + app_menu_model_adapter_->model()->GetIndexOfCommandId( + NOTIFICATION_CONTAINER)); notification_menu_view_ = nullptr; // Notify the root MenuItemView so it knows to resize and re-calculate the @@ -70,6 +72,28 @@ root_menu_->ChildrenChanged(); } +ui::Layer* NotificationMenuController::GetSlideOutLayer() { + return notification_menu_view_ ? notification_menu_view_->GetSlideOutLayer() + : nullptr; +} + +void NotificationMenuController::OnSlideChanged() {} + +void NotificationMenuController::OnSlideOut() { + // Results in |this| being deleted if there are no more notifications to show. + // Only the displayed NotificationItemView can call OnSlideOut. + message_center::MessageCenter::Get()->RemoveNotification( + notification_menu_view_->GetDisplayedNotificationID(), true); +} + +void NotificationMenuController::ActivateNotificationAndClose( + const std::string& notification_id) { + message_center::MessageCenter::Get()->ClickOnNotification(notification_id); + + // Results in |this| being deleted. + app_menu_model_adapter_->Cancel(); +} + void NotificationMenuController::InitializeNotificationMenuView() { DCHECK(!notification_menu_view_); @@ -80,11 +104,12 @@ return; } - model_->AddItem(NOTIFICATION_CONTAINER, base::string16()); + app_menu_model_adapter_->model()->AddItem(NOTIFICATION_CONTAINER, + base::string16()); // Add the container MenuItemView to |root_menu_|. views::MenuItemView* container = root_menu_->AppendMenuItem( NOTIFICATION_CONTAINER, base::string16(), views::MenuItemView::NORMAL); - notification_menu_view_ = new NotificationMenuView(app_id_); + notification_menu_view_ = new NotificationMenuView(this, this, app_id_); container->AddChildView(notification_menu_view_); for (auto* notification :
diff --git a/ash/app_menu/notification_menu_controller.h b/ash/app_menu/notification_menu_controller.h index bfe0693..630bd53 100644 --- a/ash/app_menu/notification_menu_controller.h +++ b/ash/app_menu/notification_menu_controller.h
@@ -6,13 +6,11 @@ #define ASH_APP_MENU_NOTIFICATION_MENU_CONTROLLER_H_ #include "ash/app_menu/app_menu_export.h" +#include "ash/app_menu/notification_item_view.h" #include "base/scoped_observer.h" #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_observer.h" - -namespace ui { -class SimpleMenuModel; -} +#include "ui/message_center/views/slide_out_controller.h" namespace views { class MenuItemView; @@ -20,17 +18,20 @@ namespace ash { +class AppMenuModelAdapter; class NotificationMenuView; // Handles adding/removing NotificationMenuView from the root MenuItemView, // adding the container model entry, and updating the NotificationMenuView // as notifications come and go. class APP_MENU_EXPORT NotificationMenuController - : public message_center::MessageCenterObserver { + : public message_center::MessageCenterObserver, + public message_center::SlideOutController::Delegate, + public NotificationItemView::Delegate { public: NotificationMenuController(const std::string& app_id, views::MenuItemView* root_menu, - ui::SimpleMenuModel* model); + AppMenuModelAdapter* app_menu_model_adapter); ~NotificationMenuController() override; @@ -39,6 +40,15 @@ void OnNotificationRemoved(const std::string& notification_id, bool by_user) override; + // message_center::SlideOutController::Delegate overrides: + ui::Layer* GetSlideOutLayer() override; + void OnSlideChanged() override; + void OnSlideOut() override; + + // NotificationItemView::Delegate overrides: + void ActivateNotificationAndClose( + const std::string& notification_id) override; + private: // Adds a container MenuItemView to |root_menu_|, adds NOTIFICATION_CONTAINER // to |model_|, creates and initializes NotificationMenuView, and adds @@ -51,8 +61,8 @@ // The top level MenuItemView. Owned by |AppMenuModelAdapter::menu_runner_|. views::MenuItemView* const root_menu_; - // Owned by AppMenuModelAdapter. - ui::SimpleMenuModel* const model_; + // Manages showing the menu. Owned by the view requesting a menu. + AppMenuModelAdapter* const app_menu_model_adapter_; // The view which shows all active notifications for |app_id_|. Owned by the // views hierarchy.
diff --git a/ash/app_menu/notification_menu_controller_unittest.cc b/ash/app_menu/notification_menu_controller_unittest.cc index 1d35e5f..5c5c94b 100644 --- a/ash/app_menu/notification_menu_controller_unittest.cc +++ b/ash/app_menu/notification_menu_controller_unittest.cc
@@ -13,7 +13,6 @@ #include "ui/views/controls/menu/submenu_view.h" namespace ash { -namespace test { namespace { constexpr char kTestAppId[] = "test-app-id"; @@ -33,6 +32,23 @@ std::move(notification)); } +class TestAppMenuModelAdapter : public AppMenuModelAdapter { + public: + TestAppMenuModelAdapter(const std::string& app_id, + std::unique_ptr<ui::SimpleMenuModel> model) + : AppMenuModelAdapter(app_id, + std::move(model), + nullptr, + ui::MENU_SOURCE_TYPE_LAST, + base::OnceClosure()) {} + + private: + // AppMenuModelAdapter overrides: + void RecordHistogramOnMenuClosed() override {} + + DISALLOW_COPY_AND_ASSIGN(TestAppMenuModelAdapter); +}; + } // namespace class NotificationMenuControllerTest : public AshTestBase { @@ -50,20 +66,25 @@ } void BuildMenu() { - model_ = std::make_unique<ui::SimpleMenuModel>( - nullptr /*ui::SimpleMenuModel::Delegate not required*/); - model_->AddItem(0, base::ASCIIToUTF16("item 1")); - model_->AddItem(1, base::ASCIIToUTF16("item 2")); + test_app_menu_model_adapter_ = std::make_unique<TestAppMenuModelAdapter>( + kTestAppId, + std::make_unique<ui::SimpleMenuModel>( + nullptr /*ui::SimpleMenuModel::Delegate not required*/)); + test_app_menu_model_adapter_->model()->AddItem( + 0, base::ASCIIToUTF16("item 0")); + test_app_menu_model_adapter_->model()->AddItem( + 1, base::ASCIIToUTF16("item 1")); - delegate_ = std::make_unique<views::MenuModelAdapter>(model_.get()); - root_menu_item_view_ = new views::MenuItemView(delegate_.get()); + root_menu_item_view_ = + new views::MenuItemView(test_app_menu_model_adapter_.get()); host_view_ = std::make_unique<views::View>(); host_view_->AddChildView(root_menu_item_view_); - delegate_->BuildMenu(root_menu_item_view_); + test_app_menu_model_adapter_->BuildMenu(root_menu_item_view_); notification_menu_controller_ = std::make_unique<NotificationMenuController>( - kTestAppId, root_menu_item_view_, model_.get()); + kTestAppId, root_menu_item_view_, + test_app_menu_model_adapter_.get()); } views::MenuItemView* root_menu_item_view() { return root_menu_item_view_; } @@ -74,8 +95,7 @@ // Allows the dtor to access the restricted views::MenuItemView dtor. std::unique_ptr<views::View> host_view_; std::unique_ptr<NotificationMenuController> notification_menu_controller_; - std::unique_ptr<ui::SimpleMenuModel> model_; - std::unique_ptr<views::MenuModelAdapter> delegate_; + std::unique_ptr<TestAppMenuModelAdapter> test_app_menu_model_adapter_; DISALLOW_COPY_AND_ASSIGN(NotificationMenuControllerTest); }; @@ -152,5 +172,4 @@ EXPECT_EQ(2, root_menu_item_view()->GetSubmenu()->child_count()); } -} // namespace test } // namespace ash
diff --git a/ash/app_menu/notification_menu_view.cc b/ash/app_menu/notification_menu_view.cc index ee5237a..cfc8d35 100644 --- a/ash/app_menu/notification_menu_view.cc +++ b/ash/app_menu/notification_menu_view.cc
@@ -15,10 +15,19 @@ namespace ash { -NotificationMenuView::NotificationMenuView(const std::string& app_id) - : app_id_(app_id) { +NotificationMenuView::NotificationMenuView( + + NotificationItemView::Delegate* notification_item_view_delegate, + message_center::SlideOutController::Delegate* slide_out_controller_delegate, + const std::string& app_id) + : app_id_(app_id), + notification_item_view_delegate_(notification_item_view_delegate), + slide_out_controller_delegate_(slide_out_controller_delegate) { + DCHECK(notification_item_view_delegate_); + DCHECK(slide_out_controller_delegate_); DCHECK(!app_id_.empty()) << "Only context menus for applications can show notifications."; + SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); @@ -46,6 +55,7 @@ RemoveChildView(notification_item_views_.front().get()); notification_item_views_.push_front(std::make_unique<NotificationItemView>( + notification_item_view_delegate_, slide_out_controller_delegate_, notification.title(), notification.message(), notification.icon(), notification.id())); notification_item_views_.front()->set_owned_by_client(); @@ -74,4 +84,15 @@ AddChildView(notification_item_views_.front().get()); } +ui::Layer* NotificationMenuView::GetSlideOutLayer() { + if (notification_item_views_.empty()) + return nullptr; + return notification_item_views_.front()->layer(); +} + +const std::string& NotificationMenuView::GetDisplayedNotificationID() { + DCHECK(!notification_item_views_.empty()); + return notification_item_views_.front()->notification_id(); +} + } // namespace ash
diff --git a/ash/app_menu/notification_menu_view.h b/ash/app_menu/notification_menu_view.h index 36216d8..145326f 100644 --- a/ash/app_menu/notification_menu_view.h +++ b/ash/app_menu/notification_menu_view.h
@@ -9,6 +9,8 @@ #include <string> #include "ash/app_menu/app_menu_export.h" +#include "ash/app_menu/notification_item_view.h" +#include "ui/message_center/views/slide_out_controller.h" #include "ui/views/view.h" namespace message_center { @@ -18,13 +20,16 @@ namespace ash { class NotificationMenuHeaderView; -class NotificationItemView; // A view inserted into a container MenuItemView which shows a // NotificationItemView and a NotificationMenuHeaderView. class APP_MENU_EXPORT NotificationMenuView : public views::View { public: - explicit NotificationMenuView(const std::string& app_id); + explicit NotificationMenuView( + NotificationItemView::Delegate* notification_item_view_delegate, + message_center::SlideOutController::Delegate* + slide_out_controller_delegate, + const std::string& app_id); ~NotificationMenuView() override; // Whether |notifications_for_this_app_| is empty. @@ -40,6 +45,12 @@ // next one if available. void RemoveNotificationItemView(const std::string& notification_id); + // Gets the slide out layer, used to move the displayed NotificationItemView. + ui::Layer* GetSlideOutLayer(); + + // Gets the notification id of the displayed NotificationItemView. + const std::string& GetDisplayedNotificationID(); + // views::View overrides: gfx::Size CalculatePreferredSize() const override; @@ -49,6 +60,13 @@ // Identifies the app for this menu. const std::string app_id_; + // Owned by AppMenuModelAdapter. + NotificationItemView::Delegate* const notification_item_view_delegate_; + + // Owned by AppMenuModelAdapter. + message_center::SlideOutController::Delegate* const + slide_out_controller_delegate_; + // The deque of NotificationItemViews. The front item in the deque is the view // which is shown. std::deque<std::unique_ptr<NotificationItemView>> notification_item_views_;
diff --git a/ash/app_menu/notification_menu_view_unittest.cc b/ash/app_menu/notification_menu_view_unittest.cc index 2fa893ef..252f08a 100644 --- a/ash/app_menu/notification_menu_view_unittest.cc +++ b/ash/app_menu/notification_menu_view_unittest.cc
@@ -9,19 +9,57 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/compositor/scoped_animation_duration_scale_mode.h" +#include "ui/events/base_event_utils.h" +#include "ui/events/test/event_generator.h" +#include "ui/gfx/transform.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/views/controls/label.h" #include "ui/views/test/views_test_base.h" #include "ui/views/view.h" +#include "ui/views/widget/widget_delegate.h" namespace ash { -namespace test { namespace { // The app id used in tests. constexpr char kTestAppId[] = "test-app-id"; +class MockNotificationMenuController + : public message_center::SlideOutController::Delegate, + public NotificationItemView::Delegate { + public: + MockNotificationMenuController() = default; + virtual ~MockNotificationMenuController() = default; + + void ActivateNotificationAndClose( + const std::string& notification_id) override { + activation_count_++; + } + + ui::Layer* GetSlideOutLayer() override { + return notification_menu_view_->GetSlideOutLayer(); + } + + void OnSlideChanged() override {} + + void OnSlideOut() override { slide_out_count_++; } + + void set_notification_menu_view( + NotificationMenuView* notification_menu_view) { + notification_menu_view_ = notification_menu_view; + } + + int slide_out_count_ = 0; + int activation_count_ = 0; + + // Owned by NotificationMenuViewTest. + NotificationMenuView* notification_menu_view_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(MockNotificationMenuController); +}; + } // namespace class NotificationMenuViewTest : public views::ViewsTestBase { @@ -32,10 +70,45 @@ // views::ViewsTestBase: void SetUp() override { views::ViewsTestBase::SetUp(); - notification_menu_view_ = - std::make_unique<NotificationMenuView>(kTestAppId); + + zero_duration_scope_ = + std::make_unique<ui::ScopedAnimationDurationScaleMode>( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); + + mock_notification_menu_controller_ = + std::make_unique<MockNotificationMenuController>(); + + notification_menu_view_ = std::make_unique<NotificationMenuView>( + mock_notification_menu_controller_.get(), + mock_notification_menu_controller_.get(), kTestAppId); + notification_menu_view_->set_owned_by_client(); + + // Set the NotificationMenuView so |mock_notification_menu_controller_| + // can get the slide out layer. In production NotificationMenuController is + // the NotificationItemViewDelegate, and it gets a reference to + // NotificationMenuView when it is created. + mock_notification_menu_controller_->set_notification_menu_view( + notification_menu_view()); + test_api_ = std::make_unique<NotificationMenuViewTestAPI>( notification_menu_view_.get()); + + widget_ = std::make_unique<views::Widget>(); + views::Widget::InitParams init_params( + CreateParams(views::Widget::InitParams::TYPE_POPUP)); + init_params.ownership = + views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + init_params.activatable = views::Widget::InitParams::ACTIVATABLE_YES; + widget_->Init(init_params); + widget_->SetContentsView(notification_menu_view_.get()); + widget_->SetSize(notification_menu_view_->GetPreferredSize()); + widget_->Show(); + widget_->Activate(); + } + + void TearDown() override { + widget_->Close(); + views::ViewsTestBase::TearDown(); } message_center::Notification AddNotification( @@ -50,6 +123,7 @@ notifier_id, message_center::RichNotificationData(), nullptr /* delegate */); notification_menu_view_->AddNotificationItemView(notification); + notification_menu_view_->Layout(); return notification; } @@ -64,15 +138,54 @@ EXPECT_EQ(item_view->message(), notification.message()); } + void BeginScroll() { + DispatchGesture(ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN)); + } + + void EndScroll() { + DispatchGesture(ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); + } + + void ScrollBy(int dx) { + DispatchGesture( + ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, dx, 0)); + } + + void DispatchGesture(const ui::GestureEventDetails& details) { + ui::test::EventGenerator generator( + notification_menu_view_->GetWidget()->GetNativeWindow()); + + ui::GestureEvent event( + 0, + test_api()->GetDisplayedNotificationItemView()->GetBoundsInScreen().y(), + 0, ui::EventTimeForNow(), details); + generator.Dispatch(&event); + } + + float GetSlideAmount() const { + return notification_menu_view_->GetSlideOutLayer() + ->transform() + .To2dTranslation() + .x(); + } + NotificationMenuView* notification_menu_view() { return notification_menu_view_.get(); } NotificationMenuViewTestAPI* test_api() { return test_api_.get(); } + MockNotificationMenuController* mock_notification_menu_controller() { + return mock_notification_menu_controller_.get(); + } + private: + std::unique_ptr<MockNotificationMenuController> + mock_notification_menu_controller_; std::unique_ptr<NotificationMenuView> notification_menu_view_; std::unique_ptr<NotificationMenuViewTestAPI> test_api_; + std::unique_ptr<views::Widget> widget_; + std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_scope_; DISALLOW_COPY_AND_ASSIGN(NotificationMenuViewTest); }; @@ -132,5 +245,92 @@ CheckDisplayedNotification(notification_1); } -} // namespace test +// Tests that the displayed NotificationItemView is only dismissed when dragged +// beyond the threshold. +TEST_F(NotificationMenuViewTest, SlideOut) { + AddNotification("notification_id", base::ASCIIToUTF16("title"), + base::ASCIIToUTF16("message")); + + EXPECT_EQ(0, mock_notification_menu_controller()->slide_out_count_); + + BeginScroll(); + // Scroll by a small amount, the notification should move but not slide out. + ScrollBy(-10); + EXPECT_EQ(0, mock_notification_menu_controller()->slide_out_count_); + EXPECT_EQ(-10.f, GetSlideAmount()); + + // End the scroll gesture, the notifications should return to its resting + // place. + EndScroll(); + EXPECT_EQ(0, mock_notification_menu_controller()->slide_out_count_); + EXPECT_EQ(0.f, GetSlideAmount()); + + BeginScroll(); + // Scroll beyond the threshold but do not release the gesture scroll. + ScrollBy(-200); + EXPECT_EQ(-200.f, GetSlideAmount()); + // Release the gesture, the notification should slide out. + EndScroll(); + EXPECT_EQ(1, mock_notification_menu_controller()->slide_out_count_); + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); +} + +// Tests that tapping a notification activates it. +TEST_F(NotificationMenuViewTest, TapNotification) { + AddNotification("notification_id", base::ASCIIToUTF16("title"), + base::ASCIIToUTF16("message")); + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); + DispatchGesture(ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + + EXPECT_EQ(1, mock_notification_menu_controller()->activation_count_); +} + +// Tests that an in bounds mouse release activates a notification. +TEST_F(NotificationMenuViewTest, ClickNotification) { + AddNotification("notification_id", base::ASCIIToUTF16("title"), + base::ASCIIToUTF16("message")); + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); + + const gfx::Point cursor_location = test_api() + ->GetDisplayedNotificationItemView() + ->GetBoundsInScreen() + .origin(); + ui::MouseEvent press(ui::ET_MOUSE_PRESSED, cursor_location, cursor_location, + ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_NONE); + notification_menu_view()->GetWidget()->OnMouseEvent(&press); + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); + + ui::MouseEvent release(ui::ET_MOUSE_RELEASED, cursor_location, + cursor_location, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, ui::EF_NONE); + notification_menu_view()->GetWidget()->OnMouseEvent(&release); + EXPECT_EQ(1, mock_notification_menu_controller()->activation_count_); +} + +// Tests that an out of bounds mouse release does not activate a notification. +TEST_F(NotificationMenuViewTest, OutOfBoundsClick) { + AddNotification("notification_id", base::ASCIIToUTF16("title"), + base::ASCIIToUTF16("message")); + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); + + const gfx::Point cursor_location = test_api() + ->GetDisplayedNotificationItemView() + ->GetBoundsInScreen() + .origin(); + ui::MouseEvent press(ui::ET_MOUSE_PRESSED, cursor_location, cursor_location, + ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_NONE); + notification_menu_view()->GetWidget()->OnMouseEvent(&press); + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); + + const gfx::Point out_of_bounds; + ui::MouseEvent out_of_bounds_release(ui::ET_MOUSE_RELEASED, out_of_bounds, + out_of_bounds, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, ui::EF_NONE); + notification_menu_view()->GetWidget()->OnMouseEvent(&out_of_bounds_release); + + EXPECT_EQ(0, mock_notification_menu_controller()->activation_count_); +} + } // namespace ash
diff --git a/ash/frame/caption_buttons/frame_caption_button.h b/ash/frame/caption_buttons/frame_caption_button.h index 99b3f5d..99ad84d 100644 --- a/ash/frame/caption_buttons/frame_caption_button.h +++ b/ash/frame/caption_buttons/frame_caption_button.h
@@ -25,7 +25,11 @@ class ASH_EXPORT FrameCaptionButton : public views::Button { public: enum Animate { ANIMATE_YES, ANIMATE_NO }; - enum class ColorMode { kDefault, kThemed }; + + enum class ColorMode { + kDefault, // Most windows. + kThemed, // Windows that have been themed by PWA manifest. + }; static const char kViewClassName[];
diff --git a/ash/frame/default_frame_header.cc b/ash/frame/default_frame_header.cc index ce37b32..b6b9bb7d 100644 --- a/ash/frame/default_frame_header.cc +++ b/ash/frame/default_frame_header.cc
@@ -101,11 +101,6 @@ DefaultFrameHeader::~DefaultFrameHeader() = default; -void DefaultFrameHeader::SetThemeColor(SkColor theme_color) { - set_button_color_mode(FrameCaptionButton::ColorMode::kThemed); - SetFrameColorsImpl(theme_color, theme_color); -} - void DefaultFrameHeader::SetWidthInPixels(int width_in_pixels) { if (width_in_pixels_ == width_in_pixels) return; @@ -144,24 +139,6 @@ void DefaultFrameHeader::DoSetFrameColors(SkColor active_frame_color, SkColor inactive_frame_color) { - set_button_color_mode(FrameCaptionButton::ColorMode::kDefault); - SetFrameColorsImpl(active_frame_color, inactive_frame_color); -} - -AshLayoutSize DefaultFrameHeader::GetButtonLayoutSize() const { - return AshLayoutSize::kNonBrowserCaption; -} - -SkColor DefaultFrameHeader::GetTitleColor() const { - return color_utils::IsDark(GetCurrentFrameColor()) ? kLightTitleTextColor - : kTitleTextColor; -} - -/////////////////////////////////////////////////////////////////////////////// -// DefaultFrameHeader, private: - -void DefaultFrameHeader::SetFrameColorsImpl(SkColor active_frame_color, - SkColor inactive_frame_color) { bool updated = false; if (active_frame_color_.target_color() != active_frame_color) { active_frame_color_.SetTargetColor(active_frame_color); @@ -178,6 +155,18 @@ } } +AshLayoutSize DefaultFrameHeader::GetButtonLayoutSize() const { + return AshLayoutSize::kNonBrowserCaption; +} + +SkColor DefaultFrameHeader::GetTitleColor() const { + return color_utils::IsDark(GetCurrentFrameColor()) ? kLightTitleTextColor + : kTitleTextColor; +} + +/////////////////////////////////////////////////////////////////////////////// +// DefaultFrameHeader, private: + SkColor DefaultFrameHeader::GetCurrentFrameColor() const { return mode() == MODE_ACTIVE ? active_frame_color_.target_color() : inactive_frame_color_.target_color();
diff --git a/ash/frame/default_frame_header.h b/ash/frame/default_frame_header.h index c8e1e90..1c176ac 100644 --- a/ash/frame/default_frame_header.h +++ b/ash/frame/default_frame_header.h
@@ -26,8 +26,6 @@ FrameCaptionButtonContainerView* caption_button_container); ~DefaultFrameHeader() override; - void SetThemeColor(SkColor theme_color); - SkColor active_frame_color_for_testing() { return active_frame_color_.target_color(); } @@ -48,10 +46,6 @@ private: FRIEND_TEST_ALL_PREFIXES(DefaultFrameHeaderTest, FrameColors); - // Updates the frame colors and ensures buttons are up to date. - void SetFrameColorsImpl(SkColor active_frame_color, - SkColor inactive_frame_color); - gfx::SlideAnimation* GetAnimationForActiveFrameColorForTest(); SkColor GetActiveFrameColorForPaintForTest(); @@ -72,7 +66,6 @@ gfx::SlideAnimation animation_; SkColor start_color_ = kDefaultFrameColor; SkColor target_color_ = kDefaultFrameColor; - ; SkColor current_color_ = kDefaultFrameColor; DISALLOW_COPY_AND_ASSIGN(ColorAnimator);
diff --git a/ash/frame/frame_header.cc b/ash/frame/frame_header.cc index e84e766..d9bf452 100644 --- a/ash/frame/frame_header.cc +++ b/ash/frame/frame_header.cc
@@ -9,6 +9,7 @@ #include "ash/frame/frame_header_util.h" #include "ash/public/cpp/ash_layout_constants.h" #include "ash/public/cpp/vector_icons/vector_icons.h" +#include "ash/public/cpp/window_properties.h" #include "ash/resources/vector_icons/vector_icons.h" #include "base/logging.h" // DCHECK #include "ui/gfx/canvas.h" @@ -114,7 +115,7 @@ void FrameHeader::SetBackButton(FrameCaptionButton* back_button) { back_button_ = back_button; if (back_button_) { - back_button_->SetColorMode(button_color_mode_); + back_button_->SetColorMode(GetButtonColorMode()); back_button_->SetBackgroundColor(GetCurrentFrameColor()); back_button_->SetImage(CAPTION_BUTTON_ICON_BACK, FrameCaptionButton::ANIMATE_NO, @@ -158,10 +159,12 @@ } void FrameHeader::UpdateCaptionButtonColors() { - caption_button_container_->SetColorMode(button_color_mode_); + auto button_color_mode = GetButtonColorMode(); + + caption_button_container_->SetColorMode(button_color_mode); caption_button_container_->SetBackgroundColor(GetCurrentFrameColor()); if (back_button_) { - back_button_->SetColorMode(button_color_mode_); + back_button_->SetColorMode(button_color_mode); back_button_->SetBackgroundColor(GetCurrentFrameColor()); } } @@ -250,4 +253,11 @@ left_view, caption_button_container_, GetHeaderHeight())); } +FrameCaptionButton::ColorMode FrameHeader::GetButtonColorMode() { + return target_widget()->GetNativeWindow()->GetProperty( + ash::kFrameIsThemedByHostedAppKey) + ? FrameCaptionButton::ColorMode::kThemed + : FrameCaptionButton::ColorMode::kDefault; +} + } // namespace ash
diff --git a/ash/frame/frame_header.h b/ash/frame/frame_header.h index 1a86b47..1120e99 100644 --- a/ash/frame/frame_header.h +++ b/ash/frame/frame_header.h
@@ -100,10 +100,6 @@ void SetCaptionButtonContainer( FrameCaptionButtonContainerView* caption_button_container); - void set_button_color_mode(FrameCaptionButton::ColorMode button_color_mode) { - button_color_mode_ = button_color_mode; - } - views::View* view() { return view_; } FrameCaptionButtonContainerView* caption_button_container() { @@ -135,6 +131,8 @@ gfx::Rect GetTitleBounds() const; + FrameCaptionButton::ColorMode GetButtonColorMode(); + // The widget that the caption buttons act on. This can be different from // |view_|'s widget. views::Widget* target_widget_; @@ -143,8 +141,6 @@ views::View* view_; FrameCaptionButton* back_button_ = nullptr; // May remain nullptr. views::View* left_header_view_ = nullptr; // May remain nullptr. - FrameCaptionButton::ColorMode button_color_mode_ = - FrameCaptionButton::ColorMode::kDefault; FrameCaptionButtonContainerView* caption_button_container_ = nullptr; // The height of the header to paint.
diff --git a/ash/public/cpp/mus_property_mirror_ash.cc b/ash/public/cpp/mus_property_mirror_ash.cc index 4d1090e..f630ffb 100644 --- a/ash/public/cpp/mus_property_mirror_ash.cc +++ b/ash/public/cpp/mus_property_mirror_ash.cc
@@ -87,6 +87,9 @@ MirrorOwnedProperty(window, root_window, kFrameImageOverlayActiveKey); } else if (key == kFrameImageOverlayInactiveKey) { MirrorOwnedProperty(window, root_window, kFrameImageOverlayInactiveKey); + } else if (key == kFrameIsThemedByHostedAppKey) { + root_window->SetProperty(kFrameIsThemedByHostedAppKey, + window->GetProperty(kFrameIsThemedByHostedAppKey)); } }
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index c6c1e9bd..8b73a12 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -60,6 +60,9 @@ ui::mojom::WindowManager::kFrameInactiveColor_Property, aura::PropertyConverter::CreateAcceptAnyValueCallback()); property_converter->RegisterPrimitiveProperty( + kFrameIsThemedByHostedAppKey, mojom::kFrameIsThemedByHostedApp_Property, + aura::PropertyConverter::CreateAcceptAnyValueCallback()); + property_converter->RegisterPrimitiveProperty( kHideShelfWhenFullscreenKey, mojom::kHideShelfWhenFullscreen_Property, aura::PropertyConverter::CreateAcceptAnyValueCallback()); property_converter->RegisterPrimitiveProperty( @@ -150,6 +153,7 @@ DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, kFrameInactiveColorKey, kDefaultFrameColor); +DEFINE_UI_CLASS_PROPERTY_KEY(bool, kFrameIsThemedByHostedAppKey, false); DEFINE_UI_CLASS_PROPERTY_KEY(mojom::WindowPinType, kWindowPinTypeKey, mojom::WindowPinType::NONE);
diff --git a/ash/public/cpp/window_properties.h b/ash/public/cpp/window_properties.h index e6a59d8..4ab5200c 100644 --- a/ash/public/cpp/window_properties.h +++ b/ash/public/cpp/window_properties.h
@@ -159,6 +159,11 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<SkColor>* const kFrameInactiveColorKey; +// True when the frame colors were provided by a hosted app, i.e. by a +// progressive web app manifest. +ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const + kFrameIsThemedByHostedAppKey; + // A property key to store ash::WindowPinType for a window. // When setting this property to PINNED or TRUSTED_PINNED, the window manager // will try to fullscreen the window and pin it on the top of the screen. If the
diff --git a/ash/public/interfaces/window_properties.mojom b/ash/public/interfaces/window_properties.mojom index 8df757b..fdc8524 100644 --- a/ash/public/interfaces/window_properties.mojom +++ b/ash/public/interfaces/window_properties.mojom
@@ -27,6 +27,10 @@ const string kFrameImageOverlayInactive_Property = "ash:frame-image-overlay-inactive"; +// A boolean that tells Ash whether the frame's colors come from a PWA manifest. +const string kFrameIsThemedByHostedApp_Property = + "ash:frame-is-themed-by-hosted-app"; + // True if the shelf should be hidden when this window is put into fullscreen. // Exposed because some windows want to explicitly opt-out of this. const string kHideShelfWhenFullscreen_Property =
diff --git a/ash/window_manager.cc b/ash/window_manager.cc index cbaccef..a27003d 100644 --- a/ash/window_manager.cc +++ b/ash/window_manager.cc
@@ -455,7 +455,7 @@ NonClientFrameController::Get(window); if (!non_client_frame_controller) return; - non_client_frame_controller->SetClientArea(insets, additional_client_areas); + non_client_frame_controller->SetClientArea(insets); } bool WindowManager::IsWindowActive(aura::Window* window) {
diff --git a/ash/wm/non_client_frame_controller.cc b/ash/wm/non_client_frame_controller.cc index c428fac..e19f7e87 100644 --- a/ash/wm/non_client_frame_controller.cc +++ b/ash/wm/non_client_frame_controller.cc
@@ -379,11 +379,7 @@ return GetAshLayoutSize(AshLayoutSize::kNonBrowserCaption).width() * 3; } -void NonClientFrameController::SetClientArea( - const gfx::Insets& insets, - const std::vector<gfx::Rect>& additional_client_areas) { - client_area_insets_ = insets; - additional_client_areas_ = additional_client_areas; +void NonClientFrameController::SetClientArea(const gfx::Insets& insets) { static_cast<WmNativeWidgetAura*>(widget_->native_widget()) ->SetHeaderHeight(insets.top()); }
diff --git a/ash/wm/non_client_frame_controller.h b/ash/wm/non_client_frame_controller.h index f2c19e8..17c041d5 100644 --- a/ash/wm/non_client_frame_controller.h +++ b/ash/wm/non_client_frame_controller.h
@@ -77,8 +77,7 @@ return window_manager_client_; } - void SetClientArea(const gfx::Insets& insets, - const std::vector<gfx::Rect>& additional_client_areas); + void SetClientArea(const gfx::Insets& insets); // Stores |cursor| as this window's active cursor. It does not actually update // the active cursor by calling into CursorManager, but will update the return @@ -119,9 +118,6 @@ bool did_init_native_widget_ = false; - gfx::Insets client_area_insets_; - std::vector<gfx::Rect> additional_client_areas_; - DISALLOW_COPY_AND_ASSIGN(NonClientFrameController); };
diff --git a/base/android/callback_android.cc b/base/android/callback_android.cc index d0f8e9ce..7143664 100644 --- a/base/android/callback_android.cc +++ b/base/android/callback_android.cc
@@ -12,17 +12,17 @@ namespace base { namespace android { -void RunCallbackAndroid(const JavaRef<jobject>& callback, - const JavaRef<jobject>& arg) { +void RunObjectCallbackAndroid(const JavaRef<jobject>& callback, + const JavaRef<jobject>& arg) { Java_Helper_onObjectResultFromNative(AttachCurrentThread(), callback, arg); } -void RunCallbackAndroid(const JavaRef<jobject>& callback, bool arg) { +void RunBooleanCallbackAndroid(const JavaRef<jobject>& callback, bool arg) { Java_Helper_onBooleanResultFromNative(AttachCurrentThread(), callback, static_cast<jboolean>(arg)); } -void RunCallbackAndroid(const JavaRef<jobject>& callback, int arg) { +void RunIntCallbackAndroid(const JavaRef<jobject>& callback, int arg) { Java_Helper_onIntResultFromNative(AttachCurrentThread(), callback, arg); } @@ -33,8 +33,8 @@ Java_Helper_onObjectResultFromNative(env, callback, java_string); } -void RunCallbackAndroid(const JavaRef<jobject>& callback, - const std::vector<uint8_t>& arg) { +void RunByteArrayCallbackAndroid(const JavaRef<jobject>& callback, + const std::vector<uint8_t>& arg) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jbyteArray> j_bytes = ToJavaByteArray(env, arg); Java_Helper_onObjectResultFromNative(env, callback, j_bytes);
diff --git a/base/android/callback_android.h b/base/android/callback_android.h index c4d1b33..8a14c1f 100644 --- a/base/android/callback_android.h +++ b/base/android/callback_android.h
@@ -6,6 +6,7 @@ #define BASE_ANDROID_CALLBACK_ANDROID_H_ #include <jni.h> +#include <string> #include <vector> #include "base/android/scoped_java_ref.h" @@ -16,19 +17,20 @@ namespace base { namespace android { -void BASE_EXPORT RunCallbackAndroid(const JavaRef<jobject>& callback, - const JavaRef<jobject>& arg); +void BASE_EXPORT RunObjectCallbackAndroid(const JavaRef<jobject>& callback, + const JavaRef<jobject>& arg); -void BASE_EXPORT RunCallbackAndroid(const JavaRef<jobject>& callback, - bool arg); +void BASE_EXPORT RunBooleanCallbackAndroid(const JavaRef<jobject>& callback, + bool arg); -void BASE_EXPORT RunCallbackAndroid(const JavaRef<jobject>& callback, int arg); +void BASE_EXPORT RunIntCallbackAndroid(const JavaRef<jobject>& callback, + int arg); void BASE_EXPORT RunStringCallbackAndroid(const JavaRef<jobject>& callback, const std::string& arg); -void BASE_EXPORT RunCallbackAndroid(const JavaRef<jobject>& callback, - const std::vector<uint8_t>& arg); +void BASE_EXPORT RunByteArrayCallbackAndroid(const JavaRef<jobject>& callback, + const std::vector<uint8_t>& arg); } // namespace android } // namespace base
diff --git a/base/profiler/native_stack_sampler.h b/base/profiler/native_stack_sampler.h index 758e195..5d7e9b0 100644 --- a/base/profiler/native_stack_sampler.h +++ b/base/profiler/native_stack_sampler.h
@@ -65,7 +65,7 @@ // Records a set of internal frames and returns them. virtual std::vector<StackSamplingProfiler::InternalFrame> RecordStackFrames( StackBuffer* stackbuffer, - StackSamplingProfiler::SamplingProfileBuilder* profile_builder) = 0; + StackSamplingProfiler::ProfileBuilder* profile_builder) = 0; protected: NativeStackSampler();
diff --git a/base/profiler/native_stack_sampler_mac.cc b/base/profiler/native_stack_sampler_mac.cc index 3e88d79..d45c7a8c 100644 --- a/base/profiler/native_stack_sampler_mac.cc +++ b/base/profiler/native_stack_sampler_mac.cc
@@ -37,7 +37,7 @@ using InternalFrame = StackSamplingProfiler::InternalFrame; using Module = StackSamplingProfiler::Module; using InternalModule = StackSamplingProfiler::InternalModule; -using SamplingProfileBuilder = StackSamplingProfiler::SamplingProfileBuilder; +using ProfileBuilder = StackSamplingProfiler::ProfileBuilder; namespace { @@ -348,7 +348,7 @@ void ProfileRecordingStarting() override; std::vector<InternalFrame> RecordStackFrames( StackBuffer* stack_buffer, - SamplingProfileBuilder* profile_builder) override; + ProfileBuilder* profile_builder) override; private: // Returns the InternalModule containing |instruction_pointer|, adding it to @@ -413,7 +413,7 @@ std::vector<InternalFrame> NativeStackSamplerMac::RecordStackFrames( StackBuffer* stack_buffer, - SamplingProfileBuilder* profile_builder) { + ProfileBuilder* profile_builder) { x86_thread_state64_t thread_state; const std::vector<InternalFrame> empty_internal_frames;
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc index 2207d9f..b9b1773 100644 --- a/base/profiler/native_stack_sampler_win.cc +++ b/base/profiler/native_stack_sampler_win.cc
@@ -36,7 +36,7 @@ using InternalFrame = StackSamplingProfiler::InternalFrame; using Module = StackSamplingProfiler::Module; using InternalModule = StackSamplingProfiler::InternalModule; -using SamplingProfileBuilder = StackSamplingProfiler::SamplingProfileBuilder; +using ProfileBuilder = StackSamplingProfiler::ProfileBuilder; // Stack recording functions -------------------------------------------------- @@ -333,7 +333,7 @@ void* stack_copy_buffer, size_t stack_copy_buffer_size, std::vector<RecordedFrame>* stack, - SamplingProfileBuilder* profile_builder, + ProfileBuilder* profile_builder, NativeStackSamplerTestDelegate* test_delegate) { DCHECK(stack->empty()); @@ -394,7 +394,7 @@ void ProfileRecordingStarting() override; std::vector<InternalFrame> RecordStackFrames( StackBuffer* stack_buffer, - SamplingProfileBuilder* profile_builder) override; + ProfileBuilder* profile_builder) override; private: // Attempts to query the module filename, base address, and id for @@ -435,7 +435,7 @@ std::vector<InternalFrame> NativeStackSamplerWin::RecordStackFrames( StackBuffer* stack_buffer, - SamplingProfileBuilder* profile_builder) { + ProfileBuilder* profile_builder) { DCHECK(stack_buffer); std::vector<RecordedFrame> stack;
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc index 4e4139c..fcd6ace 100644 --- a/base/profiler/stack_sampling_profiler.cc +++ b/base/profiler/stack_sampling_profiler.cc
@@ -136,61 +136,6 @@ StackSamplingProfiler::CallStackProfile::CallStackProfile( const CallStackProfile& other) = default; -// StackSamplingProfiler::SamplingProfileBuilder ------------------------------ - -StackSamplingProfiler::SamplingProfileBuilder::SamplingProfileBuilder( - const CompletedCallback& callback) - : callback_(callback) {} - -StackSamplingProfiler::SamplingProfileBuilder::~SamplingProfileBuilder() = - default; - -void StackSamplingProfiler::SamplingProfileBuilder::RecordAnnotations() { - // The code inside this method must not do anything that could acquire a - // mutex, including allocating memory (which includes LOG messages) because - // that mutex could be held by a stopped thread, thus resulting in deadlock. - sample_.process_milestones = subtle::NoBarrier_Load(&process_milestones_); -} - -void StackSamplingProfiler::SamplingProfileBuilder::OnProfileCompleted( - TimeDelta profile_duration, - TimeDelta sampling_period) { - profile_.profile_duration = profile_duration; - profile_.sampling_period = sampling_period; - - // Run the associated callback, passing the collected profile. - callback_.Run(std::move(profile_)); -} - -void StackSamplingProfiler::SamplingProfileBuilder::OnSampleCompleted( - std::vector<InternalFrame> internal_frames) { - DCHECK_EQ(sample_.frames.size(), 0u); - - // Dedup modules and convert InternalFrames to Frames. - for (const auto& internal_frame : internal_frames) { - const InternalModule& module(internal_frame.internal_module); - if (!module.is_valid) { - sample_.frames.emplace_back(internal_frame.instruction_pointer, - kUnknownModuleIndex); - continue; - } - - auto loc = module_index_.find(module.base_address); - if (loc == module_index_.end()) { - profile_.modules.emplace_back(module.base_address, module.id, - module.filename); - size_t index = profile_.modules.size() - 1; - loc = module_index_.insert(std::make_pair(module.base_address, index)) - .first; - } - sample_.frames.emplace_back(internal_frame.instruction_pointer, - loc->second); - } - - profile_.samples.push_back(std::move(sample_)); - sample_ = Sample(); -} - // StackSamplingProfiler::SamplingThread -------------------------------------- class StackSamplingProfiler::SamplingThread : public Thread { @@ -225,7 +170,7 @@ const SamplingParams& params, WaitableEvent* finished, std::unique_ptr<NativeStackSampler> sampler, - std::unique_ptr<SamplingProfileBuilder> profile_builder) + std::unique_ptr<ProfileBuilder> profile_builder) : collection_id(next_collection_id.GetNext()), target(target), params(params), @@ -246,7 +191,7 @@ std::unique_ptr<NativeStackSampler> native_sampler; // Receives the sampling data and builds a CallStackProfile. - std::unique_ptr<SamplingProfileBuilder> profile_builder; + std::unique_ptr<ProfileBuilder> profile_builder; // The absolute time for the next sample. Time next_sample_time; @@ -765,7 +710,7 @@ StackSamplingProfiler::StackSamplingProfiler( const SamplingParams& params, - std::unique_ptr<SamplingProfileBuilder> profile_builder, + std::unique_ptr<ProfileBuilder> profile_builder, NativeStackSamplerTestDelegate* test_delegate) : StackSamplingProfiler(PlatformThread::CurrentId(), params, @@ -775,7 +720,7 @@ StackSamplingProfiler::StackSamplingProfiler( PlatformThreadId thread_id, const SamplingParams& params, - std::unique_ptr<SamplingProfileBuilder> profile_builder, + std::unique_ptr<ProfileBuilder> profile_builder, NativeStackSamplerTestDelegate* test_delegate) : thread_id_(thread_id), params_(params), @@ -852,6 +797,11 @@ ChangeAtomicFlags(&process_milestones_, 1 << milestone, 0); } +// static +subtle::Atomic32 StackSamplingProfiler::ProcessMilestone() { + return subtle::NoBarrier_Load(&process_milestones_); +} + // StackSamplingProfiler::Frame global functions ------------------------------ bool operator==(const StackSamplingProfiler::Module& a,
diff --git a/base/profiler/stack_sampling_profiler.h b/base/profiler/stack_sampling_profiler.h index fb4bb25..df34df4 100644 --- a/base/profiler/stack_sampling_profiler.h +++ b/base/profiler/stack_sampling_profiler.h
@@ -38,18 +38,12 @@ // // // Create and customize params as desired. // base::StackStackSamplingProfiler::SamplingParams params; -// // Any thread's ID may be passed as the target. -// base::StackSamplingProfiler profiler(base::PlatformThread::CurrentId()), -// params); // -// // To process the profiles, use a custom completed callback: -// base::StackStackSamplingProfiler::CompletedCallback -// thread_safe_callback = ...; -// auto profile_builder = -// std::make_unique<base::StackSamplingProfiler::SamplingProfileBuilder>( -// thread_safe_callback); +// // To process the profiles, use a custom ProfileBuilder subclass: +// class SubProfileBuilder : +// public base::StackSamplingProfiler::ProfileBuilder{...} // base::StackSamplingProfiler profiler(base::PlatformThread::CurrentId()), -// params, std::move(profile_builder)); +// params, std::make_unique<SubProfileBuilder>(...)); // // profiler.Start(); // // ... work being done on the target thread here ... @@ -60,8 +54,8 @@ // altered as desired. // // When a call stack profile is complete, or the profiler is stopped, -// SamplingProfileBuilder's OnProfileCompleted function is called from a thread -// created by the profiler. +// ProfileBuilder's OnProfileCompleted function is called from a thread created +// by the profiler. class BASE_EXPORT StackSamplingProfiler { public: // Module represents the module (DLL or exe) corresponding to a stack frame. @@ -92,7 +86,7 @@ // Different from Module, it has an additional field "is_valid". // // This struct is only used for sampling data transfer from NativeStackSampler - // to SamplingProfileBuilder. + // to ProfileBuilder. struct BASE_EXPORT InternalModule { InternalModule(); InternalModule(uintptr_t base_address, @@ -139,7 +133,7 @@ // information. This is different from Frame which only contains module index. // // This struct is only used for sampling data transfer from NativeStackSampler - // to SamplingProfileBuilder. + // to ProfileBuilder. struct BASE_EXPORT InternalFrame { InternalFrame(uintptr_t instruction_pointer, InternalModule internal_module); @@ -246,6 +240,36 @@ bool simulate_intervening_start); }; + // The ProfileBuilder interface allows the user to record profile information + // on the fly in whatever format is desired. Functions are invoked by the + // profiler on its own thread so must not block or perform expensive + // operations. + class BASE_EXPORT ProfileBuilder { + public: + ProfileBuilder() = default; + virtual ~ProfileBuilder() = default; + + // Metadata associated with the sample to be saved off. + // The code implementing this method must not do anything that could acquire + // a mutex, including allocating memory (which includes LOG messages) + // because that mutex could be held by a stopped thread, thus resulting in + // deadlock. + virtual void RecordAnnotations() = 0; + + // Records a new set of internal frames. Invoked when sampling a sample + // completes. + virtual void OnSampleCompleted( + std::vector<InternalFrame> internal_frames) = 0; + + // Finishes the profile construction with |profile_duration| and + // |sampling_period|. Invoked when sampling a profile completes. + virtual void OnProfileCompleted(TimeDelta profile_duration, + TimeDelta sampling_period) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ProfileBuilder); + }; + // The callback type used to collect a completed profile. The passed |profile| // is move-only. Other threads, including the UI thread, may block on callback // completion so this should run as quickly as possible. @@ -258,55 +282,12 @@ // implementation. using CompletedCallback = Callback<void(CallStackProfile)>; - // SamplingProfileBuilder receives the sampling data from NativeSampler and - // builds a CallStackProfile. - // - // The results of the profile building -- a CallStackProfile, is passed to the - // completed callback. A CallStackProfile contains a set of Samples and - // Modules, and other sampling information. One Sample corresponds to a single - // recorded stack, and the Modules record those modules associated with the - // recorded stack frames. - class BASE_EXPORT SamplingProfileBuilder { - public: - SamplingProfileBuilder(const CompletedCallback& callback); - - ~SamplingProfileBuilder(); - - // Records metadata associated with sample_. - void RecordAnnotations(); - - // Finishes the construction of profile_ with |profile_duration| and - // |sampling_period|. Runs callback_ to pass profile_. Invoked when sampling - // a Profile completes. - void OnProfileCompleted(TimeDelta profile_duration, - TimeDelta sampling_period); - - // Records a new set of frames to sample_. Invoked when sampling a Sample - // completes. - void OnSampleCompleted(std::vector<InternalFrame> internal_frames); - - private: - // The collected stack samples. - CallStackProfile profile_; - - // The current sample being recorded. - Sample sample_; - - // The indexes of internal modules, indexed by module's base_address. - std::map<uintptr_t, size_t> module_index_; - - // Callback made when sampling a profile completes. - const CompletedCallback callback_; - - DISALLOW_COPY_AND_ASSIGN(SamplingProfileBuilder); - }; - // Creates a profiler for the CURRENT thread. An optional |test_delegate| can // be supplied by tests. The caller must ensure that this object gets // destroyed before the current thread exits. StackSamplingProfiler( const SamplingParams& params, - std::unique_ptr<SamplingProfileBuilder> profile_builder, + std::unique_ptr<ProfileBuilder> profile_builder, NativeStackSamplerTestDelegate* test_delegate = nullptr); // Creates a profiler for ANOTHER thread. An optional |test_delegate| can be @@ -317,7 +298,7 @@ StackSamplingProfiler( PlatformThreadId thread_id, const SamplingParams& params, - std::unique_ptr<SamplingProfileBuilder> profile_builder, + std::unique_ptr<ProfileBuilder> profile_builder, NativeStackSamplerTestDelegate* test_delegate = nullptr); // Stops any profiling currently taking place before destroying the profiler. @@ -338,7 +319,7 @@ // are completed or the profiler object is destroyed, whichever occurs first. void Stop(); - // Set the current system state that is recorded with each captured stack + // Sets the current system state that is recorded with each captured stack // frame. This is thread-safe so can be called from anywhere. The parameter // value should be from an enumeration of the appropriate type with values // ranging from 0 to 31, inclusive. This sets bits within Sample field of @@ -346,6 +327,10 @@ // (globally) by the caller(s). static void SetProcessMilestone(int milestone); + // Gets the current system state that is recorded with each captured stack + // frame. This is thread-safe so can be called from anywhere. + static subtle::Atomic32 ProcessMilestone(); + private: friend class TestAPI; @@ -368,7 +353,7 @@ // Receives the sampling data and builds a CallStackProfile. The ownership of // this object will be transferred to the sampling thread when thread sampling // starts. - std::unique_ptr<SamplingProfileBuilder> profile_builder_; + std::unique_ptr<ProfileBuilder> profile_builder_; // This starts "signaled", is reset when sampling begins, and is signaled // when that sampling is complete and the profile_builder_'s
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc index 204c1df8..b0f88362 100644 --- a/base/profiler/stack_sampling_profiler_unittest.cc +++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -12,6 +12,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/files/file_util.h" #include "base/macros.h" @@ -27,6 +28,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" +#include "base/test/bind_test_util.h" #include "base/threading/platform_thread.h" #include "base/threading/simple_thread.h" #include "base/time/time.h" @@ -62,11 +64,13 @@ using SamplingParams = StackSamplingProfiler::SamplingParams; using Frame = StackSamplingProfiler::Frame; -using Frames = std::vector<StackSamplingProfiler::Frame>; +using Frames = std::vector<Frame>; +using InternalFrame = StackSamplingProfiler::InternalFrame; +using InternalFrames = std::vector<InternalFrame>; +using InternalFrameSets = std::vector<std::vector<InternalFrame>>; using Module = StackSamplingProfiler::Module; +using InternalModule = StackSamplingProfiler::InternalModule; using Sample = StackSamplingProfiler::Sample; -using CallStackProfile = StackSamplingProfiler::CallStackProfile; -using SamplingProfileBuilder = StackSamplingProfiler::SamplingProfileBuilder; namespace { @@ -93,8 +97,9 @@ // Signature for a target function that is expected to appear in the stack. See // SignalAndWaitUntilSignaled() below. The return value should be a program // counter pointer near the end of the function. -using TargetFunction = const void*(*)(WaitableEvent*, WaitableEvent*, - const StackConfiguration*); +using TargetFunction = const void* (*)(WaitableEvent*, + WaitableEvent*, + const StackConfiguration*); // A thread to target for profiling, whose stack is guaranteed to contain // SignalAndWaitUntilSignaled() when coordinated with the main thread. @@ -150,7 +155,7 @@ }; // Callback function to be provided when calling through the other library. - static void OtherLibraryCallback(void *arg); + static void OtherLibraryCallback(void* arg); // Returns the current program counter, or a value very close to it. static const void* GetProgramCounter(); @@ -238,18 +243,15 @@ const StackConfiguration* stack_config) { if (stack_config) { // A function whose arguments are a function accepting void*, and a void*. - using InvokeCallbackFunction = void(*)(void (*)(void*), void*); + using InvokeCallbackFunction = void (*)(void (*)(void*), void*); EXPECT_TRUE(stack_config->library); InvokeCallbackFunction function = reinterpret_cast<InvokeCallbackFunction>( GetFunctionPointerFromNativeLibrary(stack_config->library, "InvokeCallbackFunction")); EXPECT_TRUE(function); - TargetFunctionArgs args = { - thread_started_event, - finish_event, - stack_config - }; + TargetFunctionArgs args = {thread_started_event, finish_event, + stack_config}; (*function)(&OtherLibraryCallback, &args); } @@ -259,7 +261,7 @@ } // static -void TargetThread::OtherLibraryCallback(void *arg) { +void TargetThread::OtherLibraryCallback(void* arg) { const TargetFunctionArgs* args = static_cast<TargetFunctionArgs*>(arg); SignalAndWaitUntilSignaled(args->thread_started_event, args->finish_event, args->stack_config); @@ -278,6 +280,92 @@ #endif } +// Profile consists of a set of internal frame sets and other sampling +// information. +struct Profile { + Profile() = default; + Profile(Profile&& other) = default; + Profile(const InternalFrameSets& frame_sets, + int annotation_count, + TimeDelta profile_duration, + TimeDelta sampling_period); + + ~Profile() = default; + + Profile& operator=(Profile&& other) = default; + + // The collected internal frame sets. + InternalFrameSets frame_sets; + + // The number of invocations of RecordAnnotations(). + int annotation_count; + + // Duration of this profile. + TimeDelta profile_duration; + + // Time between samples. + TimeDelta sampling_period; +}; + +Profile::Profile(const InternalFrameSets& frame_sets, + int annotation_count, + TimeDelta profile_duration, + TimeDelta sampling_period) + : frame_sets(frame_sets), + annotation_count(annotation_count), + profile_duration(profile_duration), + sampling_period(sampling_period) {} + +// The callback type used to collect a profile. The passed Profile is move-only. +// Other threads, including the UI thread, may block on callback completion so +// this should run as quickly as possible. +using ProfileCompletedCallback = Callback<void(Profile)>; + +// TestProfileBuilder collects internal frames produced by the profiler. +class TestProfileBuilder : public StackSamplingProfiler::ProfileBuilder { + public: + TestProfileBuilder(const ProfileCompletedCallback& callback); + + ~TestProfileBuilder() override; + + // StackSamplingProfiler::ProfileBuilder: + void RecordAnnotations() override; + void OnSampleCompleted(InternalFrames internal_frames) override; + void OnProfileCompleted(TimeDelta profile_duration, + TimeDelta sampling_period) override; + + private: + // The sets of internal frames recorded. + std::vector<InternalFrames> frame_sets_; + + // The number of invocations of RecordAnnotations(). + int annotation_count_ = 0; + + // Callback made when sampling a profile completes. + const ProfileCompletedCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(TestProfileBuilder); +}; + +TestProfileBuilder::TestProfileBuilder(const ProfileCompletedCallback& callback) + : callback_(callback) {} + +TestProfileBuilder::~TestProfileBuilder() = default; + +void TestProfileBuilder::RecordAnnotations() { + ++annotation_count_; +} + +void TestProfileBuilder::OnSampleCompleted(InternalFrames internal_frames) { + frame_sets_.push_back(std::move(internal_frames)); +} + +void TestProfileBuilder::OnProfileCompleted(TimeDelta profile_duration, + TimeDelta sampling_period) { + callback_.Run(Profile(frame_sets_, annotation_count_, profile_duration, + sampling_period)); +} + // Loads the other library, which defines a function to be called in the // WITH_OTHER_LIBRARY configuration. NativeLibrary LoadOtherLibrary() { @@ -311,7 +399,7 @@ HMODULE module_handle; // Keep trying to get the module handle until the call fails. while (::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(module_base_address), &module_handle) || ::GetLastError() != ERROR_MOD_NOT_FOUND) { @@ -324,21 +412,6 @@ #endif } -// Called on the profiler thread when complete, to collect profile. -void SaveProfile(CallStackProfile* profile, CallStackProfile pending_profile) { - *profile = std::move(pending_profile); -} - -// Called on the profiler thread when complete. Collects the profile produced by -// the profiler, and signals an event to allow the main thread to know that that -// the profiler is done. -void SaveProfileAndSignalEvent(CallStackProfile* profile, - WaitableEvent* event, - CallStackProfile pending_profile) { - *profile = std::move(pending_profile); - event->Signal(); -} - // Executes the function with the target thread running and executing within // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup // and shutdown work before and afterward. @@ -371,15 +444,16 @@ WaitableEvent::InitialState::NOT_SIGNALED), profiler(thread_id, params, - std::make_unique<SamplingProfileBuilder>( - Bind(&SaveProfileAndSignalEvent, - Unretained(&profile), - Unretained(&completed))), + std::make_unique<TestProfileBuilder>( + BindLambdaForTesting([this](Profile result_profile) { + profile = std::move(result_profile); + completed.Signal(); + })), delegate) {} // The order here is important to ensure objects being referenced don't get // destructed until after the objects referencing them. - CallStackProfile profile; + Profile profile; WaitableEvent completed; StackSamplingProfiler profiler; @@ -402,22 +476,22 @@ return profilers; } -// Captures profile as specified by |params| on the TargetThread, and returns -// it in |profile|. Waits up to |profiler_wait_time| for the profiler to -// complete. -void CaptureProfile(const SamplingParams& params, - TimeDelta profiler_wait_time, - CallStackProfile* profile) { - WithTargetThread([¶ms, profile, +// Captures internal frames as specified by |params| on the TargetThread, and +// returns them. Waits up to |profiler_wait_time| for the profiler to complete. +InternalFrameSets CaptureFrameSets(const SamplingParams& params, + TimeDelta profiler_wait_time) { + InternalFrameSets frame_sets; + WithTargetThread([¶ms, &frame_sets, profiler_wait_time](PlatformThreadId target_thread_id) { TestProfilerInfo info(target_thread_id, params); info.profiler.Start(); info.completed.TimedWait(profiler_wait_time); info.profiler.Stop(); info.completed.Wait(); - - *profile = std::move(info.profile); + frame_sets = std::move(info.profile.frame_sets); }); + + return frame_sets; } // Waits for one of multiple samplings to complete. @@ -459,39 +533,39 @@ // Searches through the frames in |sample|, returning an iterator to the first // frame that has an instruction pointer within |target_function|. Returns // sample.end() if no such frames are found. -Frames::const_iterator FindFirstFrameWithinFunction( - const Sample& sample, +InternalFrames::const_iterator FindFirstFrameWithinFunction( + const InternalFrames& frames, TargetFunction target_function) { - uintptr_t function_start = reinterpret_cast<uintptr_t>( - MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( - target_function))); + uintptr_t function_start = + reinterpret_cast<uintptr_t>(MaybeFixupFunctionAddressForILT( + reinterpret_cast<const void*>(target_function))); uintptr_t function_end = reinterpret_cast<uintptr_t>(target_function(nullptr, nullptr, nullptr)); - for (auto it = sample.frames.begin(); it != sample.frames.end(); ++it) { - if ((it->instruction_pointer >= function_start) && - (it->instruction_pointer <= function_end)) { + for (auto it = frames.begin(); it != frames.end(); ++it) { + if (it->instruction_pointer >= function_start && + it->instruction_pointer <= function_end) { return it; } } - return sample.frames.end(); + return frames.end(); } // Formats a sample into a string that can be output for test diagnostics. -std::string FormatSampleForDiagnosticOutput( - const Sample& sample, - const std::vector<Module>& modules) { +std::string FormatSampleForDiagnosticOutput(const InternalFrames& frames) { std::string output; - for (const auto& frame : sample.frames) { + for (const auto& frame : frames) { output += StringPrintf( "0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer), - modules[frame.module_index].filename.AsUTF8Unsafe().c_str()); + frame.internal_module.filename.AsUTF8Unsafe().c_str()); } return output; } // Returns a duration that is longer than the test timeout. We would use // TimeDelta::Max() but https://crbug.com/465948. -TimeDelta AVeryLongTimeDelta() { return TimeDelta::FromDays(1); } +TimeDelta AVeryLongTimeDelta() { + return TimeDelta::FromDays(1); +} // Tests the scenario where the library is unloaded after copying the stack, but // before walking it. If |wait_until_unloaded| is true, ensures that the @@ -527,8 +601,7 @@ NativeLibrary other_library = LoadOtherLibrary(); TargetThread target_thread(StackConfiguration( - StackConfiguration::WITH_OTHER_LIBRARY, - other_library)); + StackConfiguration::WITH_OTHER_LIBRARY, other_library)); PlatformThreadHandle target_thread_handle; EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); @@ -538,10 +611,8 @@ WaitableEvent sampling_thread_completed( WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - CallStackProfile profile; - const StackSamplingProfiler::CompletedCallback callback = - Bind(&SaveProfileAndSignalEvent, Unretained(&profile), - Unretained(&sampling_thread_completed)); + Profile profile; + WaitableEvent stack_copied(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent start_stack_walk(WaitableEvent::ResetPolicy::MANUAL, @@ -550,7 +621,12 @@ wait_until_unloaded); StackSamplingProfiler profiler( target_thread.id(), params, - std::make_unique<SamplingProfileBuilder>(callback), &test_delegate); + std::make_unique<TestProfileBuilder>(BindLambdaForTesting( + [&profile, &sampling_thread_completed](Profile result_profile) { + profile = std::move(result_profile); + sampling_thread_completed.Signal(); + })), + &test_delegate); profiler.Start(); @@ -575,53 +651,54 @@ // Wait for the sampling thread to complete and fill out |profile|. sampling_thread_completed.Wait(); - // Look up the sample. - ASSERT_EQ(1u, profile.samples.size()); - const Sample& sample = profile.samples[0]; + // Look up the frames. + ASSERT_EQ(1u, profile.frame_sets.size()); + const InternalFrames& frames = profile.frame_sets[0]; // Check that the stack contains a frame for // TargetThread::SignalAndWaitUntilSignaled(). - Frames::const_iterator end_frame = FindFirstFrameWithinFunction( - sample, &TargetThread::SignalAndWaitUntilSignaled); - ASSERT_TRUE(end_frame != sample.frames.end()) + InternalFrames::const_iterator end_frame = FindFirstFrameWithinFunction( + frames, &TargetThread::SignalAndWaitUntilSignaled); + ASSERT_TRUE(end_frame != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( &TargetThread::SignalAndWaitUntilSignaled)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); if (wait_until_unloaded) { // The stack should look like this, resulting one frame after - // SignalAndWaitUntilSignaled. The frame in the now-unloaded library is not - // recorded since we can't get module information. + // SignalAndWaitUntilSignaled. The frame in the now-unloaded library is + // not recorded since we can't get module information. // // ... WaitableEvent and system frames ... // TargetThread::SignalAndWaitUntilSignaled // TargetThread::OtherLibraryCallback - EXPECT_EQ(2, sample.frames.end() - end_frame) + EXPECT_EQ(2, frames.end() - end_frame) << "Stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); } else { // We didn't wait for the asynchronous unloading to complete, so the results // are non-deterministic: if the library finished unloading we should have // the same stack as |wait_until_unloaded|, if not we should have the full // stack. The important thing is that we should not crash. - if (sample.frames.end() - end_frame == 2) { + if (frames.end() - end_frame == 2) { // This is the same case as |wait_until_unloaded|. return; } // Check that the stack contains a frame for // TargetThread::CallThroughOtherLibrary(). - Frames::const_iterator other_library_frame = FindFirstFrameWithinFunction( - sample, &TargetThread::CallThroughOtherLibrary); - ASSERT_TRUE(other_library_frame != sample.frames.end()) + InternalFrames::const_iterator other_library_frame = + FindFirstFrameWithinFunction(frames, + &TargetThread::CallThroughOtherLibrary); + ASSERT_TRUE(other_library_frame != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( &TargetThread::CallThroughOtherLibrary)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); // The stack should look like this, resulting in three frames between // SignalAndWaitUntilSignaled and CallThroughOtherLibrary: @@ -633,7 +710,7 @@ // TargetThread::CallThroughOtherLibrary EXPECT_EQ(3, other_library_frame - end_frame) << "Stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); } } @@ -658,8 +735,9 @@ } // namespace -// Checks that the basic expected information is present in a sampled call stack -// profile. +// Checks that the basic expected information is present in sampled internal +// frames. +// // macOS ASAN is not yet supported - crbug.com/718628. #if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) #define MAYBE_Basic Basic @@ -671,59 +749,26 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; - CaptureProfile(params, AVeryLongTimeDelta(), &profile); + InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta()); - // Check that the profile and samples sizes are correct, and the module - // indices are in range. - ASSERT_EQ(1u, profile.samples.size()); - EXPECT_EQ(params.sampling_interval, profile.sampling_period); - const Sample& sample = profile.samples[0]; - EXPECT_EQ(0u, sample.process_milestones); - for (const auto& frame : sample.frames) { - ASSERT_GE(frame.module_index, 0u); - ASSERT_LT(frame.module_index, profile.modules.size()); - } + // Check that the size of the frame sets are correct. + ASSERT_EQ(1u, frame_sets.size()); + const InternalFrames& frames = frame_sets[0]; + + // Check that all the modules are valid. + for (const auto& frame : frames) + EXPECT_TRUE(frame.internal_module.is_valid); // Check that the stack contains a frame for - // TargetThread::SignalAndWaitUntilSignaled() and that the frame has this - // executable's module. - Frames::const_iterator loc = FindFirstFrameWithinFunction( - sample, &TargetThread::SignalAndWaitUntilSignaled); - ASSERT_TRUE(loc != sample.frames.end()) + // TargetThread::SignalAndWaitUntilSignaled(). + InternalFrames::const_iterator loc = FindFirstFrameWithinFunction( + frames, &TargetThread::SignalAndWaitUntilSignaled); + ASSERT_TRUE(loc != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( &TargetThread::SignalAndWaitUntilSignaled)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); - FilePath executable_path; - EXPECT_TRUE(PathService::Get(FILE_EXE, &executable_path)); - EXPECT_EQ(executable_path, - MakeAbsoluteFilePath(profile.modules[loc->module_index].filename)); -} - -// Checks that annotations are recorded in samples. -PROFILER_TEST_F(StackSamplingProfilerTest, Annotations) { - SamplingParams params; - params.sampling_interval = TimeDelta::FromMilliseconds(0); - params.samples_per_profile = 1; - - // Check that a run picks up annotations. - StackSamplingProfiler::SetProcessMilestone(1); - CallStackProfile profile1; - CaptureProfile(params, AVeryLongTimeDelta(), &profile1); - ASSERT_EQ(1u, profile1.samples.size()); - const Sample& sample1 = profile1.samples[0]; - EXPECT_EQ(1u << 1, sample1.process_milestones); - - // Run it a second time but with changed annotations. These annotations - // should appear in the first acquired sample. - StackSamplingProfiler::SetProcessMilestone(2); - CallStackProfile profile2; - CaptureProfile(params, AVeryLongTimeDelta(), &profile2); - ASSERT_EQ(1u, profile2.samples.size()); - const Sample& sample2 = profile2.samples[0]; - EXPECT_EQ(sample1.process_milestones | (1u << 2), sample2.process_milestones); + << FormatSampleForDiagnosticOutput(frames); } // Checks that the profiler handles stacks containing dynamically-allocated @@ -739,52 +784,53 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; + Profile profile; WithTargetThread( [¶ms, &profile](PlatformThreadId target_thread_id) { WaitableEvent sampling_thread_completed( WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - const StackSamplingProfiler::CompletedCallback callback = - Bind(&SaveProfileAndSignalEvent, Unretained(&profile), - Unretained(&sampling_thread_completed)); StackSamplingProfiler profiler( target_thread_id, params, - std::make_unique<SamplingProfileBuilder>(callback)); + std::make_unique<TestProfileBuilder>(BindLambdaForTesting( + [&profile, &sampling_thread_completed](Profile result_profile) { + profile = std::move(result_profile); + sampling_thread_completed.Signal(); + }))); profiler.Start(); sampling_thread_completed.Wait(); }, StackConfiguration(StackConfiguration::WITH_ALLOCA)); - // Look up the sample. - ASSERT_EQ(1u, profile.samples.size()); - const Sample& sample = profile.samples[0]; + // Look up the frames. + ASSERT_EQ(1u, profile.frame_sets.size()); + const InternalFrames& frames = profile.frame_sets[0]; // Check that the stack contains a frame for // TargetThread::SignalAndWaitUntilSignaled(). - Frames::const_iterator end_frame = FindFirstFrameWithinFunction( - sample, &TargetThread::SignalAndWaitUntilSignaled); - ASSERT_TRUE(end_frame != sample.frames.end()) + InternalFrames::const_iterator end_frame = FindFirstFrameWithinFunction( + frames, &TargetThread::SignalAndWaitUntilSignaled); + ASSERT_TRUE(end_frame != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( &TargetThread::SignalAndWaitUntilSignaled)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); // Check that the stack contains a frame for TargetThread::CallWithAlloca(). - Frames::const_iterator alloca_frame = - FindFirstFrameWithinFunction(sample, &TargetThread::CallWithAlloca); - ASSERT_TRUE(alloca_frame != sample.frames.end()) + InternalFrames::const_iterator alloca_frame = + FindFirstFrameWithinFunction(frames, &TargetThread::CallWithAlloca); + ASSERT_TRUE(alloca_frame != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT( reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); // These frames should be adjacent on the stack. EXPECT_EQ(1, alloca_frame - end_frame) << "Stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); } // Checks that a profiler can stop/destruct without ever having started. @@ -794,16 +840,17 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; + Profile profile; WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - const StackSamplingProfiler::CompletedCallback callback = - Bind(&SaveProfileAndSignalEvent, Unretained(&profile), - Unretained(&sampling_completed)); StackSamplingProfiler profiler( target_thread_id, params, - std::make_unique<SamplingProfileBuilder>(callback)); + std::make_unique<TestProfileBuilder>(BindLambdaForTesting( + [&profile, &sampling_completed](Profile result_profile) { + profile = std::move(result_profile); + sampling_completed.Signal(); + }))); profiler.Stop(); // Constructed but never started. EXPECT_FALSE(sampling_completed.IsSignaled()); @@ -885,20 +932,20 @@ }); } -// Checks that no call stack profile is captured if the profiling is stopped +// Checks that no internal frames are captured if the profiling is stopped // during the initial delay. PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInitialDelay) { SamplingParams params; params.initial_delay = TimeDelta::FromSeconds(60); - CallStackProfile profile; - CaptureProfile(params, TimeDelta::FromMilliseconds(0), &profile); + InternalFrameSets frame_sets = + CaptureFrameSets(params, TimeDelta::FromMilliseconds(0)); - EXPECT_TRUE(profile.samples.empty()); + EXPECT_TRUE(frame_sets.empty()); } -// Checks that tasks can be stopped before completion and incomplete call stack -// profile is captured. +// Checks that tasks can be stopped before completion and incomplete internal +// frames are captured. PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) { // Test delegate that counts samples. class SampleRecordedEvent : public NativeStackSamplerTestDelegate { @@ -933,7 +980,7 @@ profiler_info.profiler.Stop(); profiler_info.completed.Wait(); - EXPECT_EQ(1u, profiler_info.profile.samples.size()); + EXPECT_EQ(1u, profiler_info.profile.frame_sets.size()); }); } @@ -942,11 +989,13 @@ SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(10); - CallStackProfile profile; + Profile profile; WithTargetThread([¶ms, &profile](PlatformThreadId target_thread_id) { std::unique_ptr<StackSamplingProfiler> profiler; - auto profile_builder = std::make_unique<SamplingProfileBuilder>( - Bind(&SaveProfile, Unretained(&profile))); + auto profile_builder = std::make_unique<TestProfileBuilder>( + BindLambdaForTesting([&profile](Profile result_profile) { + profile = std::move(result_profile); + })); profiler.reset(new StackSamplingProfiler(target_thread_id, params, std::move(profile_builder))); profiler->Start(); @@ -964,13 +1013,11 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; - CaptureProfile(params, AVeryLongTimeDelta(), &profile); - ASSERT_EQ(1u, profile.samples.size()); + InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta()); + ASSERT_EQ(1u, frame_sets.size()); - profile = CallStackProfile(); - CaptureProfile(params, AVeryLongTimeDelta(), &profile); - ASSERT_EQ(1u, profile.samples.size()); + frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta()); + ASSERT_EQ(1u, frame_sets.size()); } // Checks that a sampler can be started while another is running. @@ -990,7 +1037,35 @@ profiler_infos[0]->profiler.Start(); profiler_infos[1]->profiler.Start(); profiler_infos[1]->completed.Wait(); - EXPECT_EQ(1u, profiler_infos[1]->profile.samples.size()); + EXPECT_EQ(1u, profiler_infos[1]->profile.frame_sets.size()); + }); +} + +// Checks that the profile duration and the sampling interval are calculated +// correctly. Also checks that RecordAnnotations() is invoked each time a sample +// is recorded. +PROFILER_TEST_F(StackSamplingProfilerTest, ProfileGeneralInfo) { + WithTargetThread([](PlatformThreadId target_thread_id) { + SamplingParams params; + params.sampling_interval = TimeDelta::FromMilliseconds(1); + params.samples_per_profile = 3; + + TestProfilerInfo profiler_info(target_thread_id, params); + + profiler_info.profiler.Start(); + profiler_info.completed.Wait(); + EXPECT_EQ(3u, profiler_info.profile.frame_sets.size()); + + // The profile duration should be greater than the total sampling intervals. + EXPECT_GT(profiler_info.profile.profile_duration, + profiler_info.profile.sampling_period * 3); + + EXPECT_EQ(TimeDelta::FromMilliseconds(1), + profiler_info.profile.sampling_period); + + // The number of invocations of RecordAnnotations() should be equal to the + // number of samples recorded. + EXPECT_EQ(3, profiler_info.profile.annotation_count); }); } @@ -1000,9 +1075,8 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; - CaptureProfile(params, AVeryLongTimeDelta(), &profile); - ASSERT_EQ(1u, profile.samples.size()); + InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta()); + ASSERT_EQ(1u, frame_sets.size()); // Capture thread should still be running at this point. ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning()); @@ -1026,9 +1100,8 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; - CaptureProfile(params, AVeryLongTimeDelta(), &profile); - ASSERT_EQ(1u, profile.samples.size()); + InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta()); + ASSERT_EQ(1u, frame_sets.size()); // Capture thread should still be running at this point. ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning()); @@ -1038,9 +1111,8 @@ StackSamplingProfiler::TestAPI::PerformSamplingThreadIdleShutdown(false); // Ensure another capture will start the sampling thread and run. - profile = CallStackProfile(); - CaptureProfile(params, AVeryLongTimeDelta(), &profile); - ASSERT_EQ(1u, profile.samples.size()); + frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta()); + ASSERT_EQ(1u, frame_sets.size()); EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning()); } @@ -1114,7 +1186,7 @@ profiler_info.profiler.Start(); profiler_info.completed.Wait(); - EXPECT_EQ(1u, profiler_info.profile.samples.size()); + EXPECT_EQ(1u, profiler_info.profile.frame_sets.size()); // Perform an idle shutdown but simulate that a new capture is started // before it can actually run. @@ -1132,7 +1204,7 @@ TestProfilerInfo another_info(target_thread_id, params); another_info.profiler.Start(); another_info.completed.Wait(); - EXPECT_EQ(1u, another_info.profile.samples.size()); + EXPECT_EQ(1u, another_info.profile.frame_sets.size()); }); } @@ -1167,9 +1239,9 @@ // Wait for the other profiler to finish. profiler_infos[other_profiler]->completed.Wait(); - // Ensure each got the correct number of samples. - EXPECT_EQ(9u, profiler_infos[0]->profile.samples.size()); - EXPECT_EQ(8u, profiler_infos[1]->profile.samples.size()); + // Ensure each got the correct number of frame sets. + EXPECT_EQ(9u, profiler_infos[0]->profile.frame_sets.size()); + EXPECT_EQ(8u, profiler_infos[1]->profile.frame_sets.size()); }); } @@ -1198,7 +1270,8 @@ // Wait for one profiler to finish. size_t completed_profiler = WaitForSamplingComplete(profiler_infos); - EXPECT_EQ(10u, profiler_infos[completed_profiler]->profile.samples.size()); + EXPECT_EQ(10u, + profiler_infos[completed_profiler]->profile.frame_sets.size()); // Stop and destroy all profilers, always in the same order. Don't crash. for (size_t i = 0; i < profiler_infos.size(); ++i) profiler_infos[i]->profiler.Stop(); @@ -1220,7 +1293,7 @@ params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_profile = 1; - CallStackProfile profile; + Profile profile; { ScopedNativeLibrary other_library(LoadOtherLibrary()); WithTargetThread( @@ -1228,12 +1301,14 @@ WaitableEvent sampling_thread_completed( WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - const StackSamplingProfiler::CompletedCallback callback = - Bind(&SaveProfileAndSignalEvent, Unretained(&profile), - Unretained(&sampling_thread_completed)); StackSamplingProfiler profiler( target_thread_id, params, - std::make_unique<SamplingProfileBuilder>(callback)); + std::make_unique<TestProfileBuilder>( + BindLambdaForTesting([&profile, &sampling_thread_completed]( + Profile result_profile) { + profile = std::move(result_profile); + sampling_thread_completed.Signal(); + }))); profiler.Start(); sampling_thread_completed.Wait(); }, @@ -1241,31 +1316,32 @@ other_library.get())); } - // Look up the sample. - ASSERT_EQ(1u, profile.samples.size()); - const Sample& sample = profile.samples[0]; + // Look up the frames. + ASSERT_EQ(1u, profile.frame_sets.size()); + const InternalFrames& frames = profile.frame_sets[0]; // Check that the stack contains a frame for // TargetThread::CallThroughOtherLibrary(). - Frames::const_iterator other_library_frame = FindFirstFrameWithinFunction( - sample, &TargetThread::CallThroughOtherLibrary); - ASSERT_TRUE(other_library_frame != sample.frames.end()) + InternalFrames::const_iterator other_library_frame = + FindFirstFrameWithinFunction(frames, + &TargetThread::CallThroughOtherLibrary); + ASSERT_TRUE(other_library_frame != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( &TargetThread::CallThroughOtherLibrary)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); // Check that the stack contains a frame for // TargetThread::SignalAndWaitUntilSignaled(). - Frames::const_iterator end_frame = FindFirstFrameWithinFunction( - sample, &TargetThread::SignalAndWaitUntilSignaled); - ASSERT_TRUE(end_frame != sample.frames.end()) + InternalFrames::const_iterator end_frame = FindFirstFrameWithinFunction( + frames, &TargetThread::SignalAndWaitUntilSignaled); + ASSERT_TRUE(end_frame != frames.end()) << "Function at " << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( &TargetThread::SignalAndWaitUntilSignaled)) << " was not found in stack:\n" - << FormatSampleForDiagnosticOutput(sample, profile.modules); + << FormatSampleForDiagnosticOutput(frames); // The stack should look like this, resulting in three frames between // SignalAndWaitUntilSignaled and CallThroughOtherLibrary: @@ -1276,7 +1352,8 @@ // InvokeCallbackFunction (in other library) // TargetThread::CallThroughOtherLibrary EXPECT_EQ(3, other_library_frame - end_frame) - << "Stack:\n" << FormatSampleForDiagnosticOutput(sample, profile.modules); + << "Stack:\n" + << FormatSampleForDiagnosticOutput(frames); } // Checks that a stack that runs through a library that is unloading produces a @@ -1329,35 +1406,37 @@ params2.sampling_interval = TimeDelta::FromMilliseconds(1); params2.samples_per_profile = 8; - CallStackProfile profile1, profile2; + Profile profile1, profile2; WaitableEvent sampling_thread_completed1( WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - const StackSamplingProfiler::CompletedCallback callback1 = - Bind(&SaveProfileAndSignalEvent, Unretained(&profile1), - Unretained(&sampling_thread_completed1)); StackSamplingProfiler profiler1( target_thread1.id(), params1, - std::make_unique<SamplingProfileBuilder>(callback1)); + std::make_unique<TestProfileBuilder>(BindLambdaForTesting( + [&profile1, &sampling_thread_completed1](Profile result_profile) { + profile1 = std::move(result_profile); + sampling_thread_completed1.Signal(); + }))); WaitableEvent sampling_thread_completed2( WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - const StackSamplingProfiler::CompletedCallback callback2 = - Bind(&SaveProfileAndSignalEvent, Unretained(&profile2), - Unretained(&sampling_thread_completed2)); StackSamplingProfiler profiler2( target_thread2.id(), params2, - std::make_unique<SamplingProfileBuilder>(callback2)); + std::make_unique<TestProfileBuilder>(BindLambdaForTesting( + [&profile2, &sampling_thread_completed2](Profile result_profile) { + profile2 = std::move(result_profile); + sampling_thread_completed2.Signal(); + }))); // Finally the real work. profiler1.Start(); profiler2.Start(); sampling_thread_completed1.Wait(); sampling_thread_completed2.Wait(); - EXPECT_EQ(9u, profile1.samples.size()); - EXPECT_EQ(8u, profile2.samples.size()); + EXPECT_EQ(9u, profile1.frame_sets.size()); + EXPECT_EQ(8u, profile2.frame_sets.size()); target_thread1.SignalThreadToFinish(); target_thread2.SignalThreadToFinish(); @@ -1378,10 +1457,11 @@ WaitableEvent::InitialState::NOT_SIGNALED), profiler_(thread_id, params, - std::make_unique<SamplingProfileBuilder>( - Bind(&SaveProfileAndSignalEvent, - Unretained(&profile_), - Unretained(&completed_)))) {} + std::make_unique<TestProfileBuilder>( + BindLambdaForTesting([this](Profile result_profile) { + profile_ = std::move(result_profile); + completed_.Signal(); + }))) {} void Run() override { run_.Wait(); @@ -1392,12 +1472,12 @@ void Wait() { completed_.Wait(); } - CallStackProfile& profile() { return profile_; } + Profile& profile() { return profile_; } private: WaitableEvent run_; - CallStackProfile profile_; + Profile profile_; WaitableEvent completed_; StackSamplingProfiler profiler_; }; @@ -1431,8 +1511,8 @@ // Wait for them both to finish and validate collection. profiler_thread1.Wait(); profiler_thread2.Wait(); - EXPECT_EQ(9u, profiler_thread1.profile().samples.size()); - EXPECT_EQ(8u, profiler_thread2.profile().samples.size()); + EXPECT_EQ(9u, profiler_thread1.profile().frame_sets.size()); + EXPECT_EQ(8u, profiler_thread2.profile().frame_sets.size()); profiler_thread1.Join(); profiler_thread2.Join();
diff --git a/base/task/sequence_manager/task_queue.h b/base/task/sequence_manager/task_queue.h index 3753b94..d6773a0 100644 --- a/base/task/sequence_manager/task_queue.h +++ b/base/task/sequence_manager/task_queue.h
@@ -32,12 +32,12 @@ namespace sequence_manager { namespace internal { -class TaskQueueImpl; class GracefulQueueShutdownHelper; +class SequenceManagerImpl; +class TaskQueueImpl; } // namespace internal class TimeDomain; -class SequenceManagerImpl; class PLATFORM_EXPORT TaskQueue : public SingleThreadTaskRunner { public: @@ -281,8 +281,8 @@ internal::TaskQueueImpl* GetTaskQueueImpl() const { return impl_.get(); } private: + friend class internal::SequenceManagerImpl; friend class internal::TaskQueueImpl; - friend class SequenceManagerImpl; bool IsOnMainThread() const; @@ -304,7 +304,7 @@ const PlatformThreadId thread_id_; - const WeakPtr<SequenceManagerImpl> sequence_manager_; + const WeakPtr<internal::SequenceManagerImpl> sequence_manager_; const scoped_refptr<internal::GracefulQueueShutdownHelper> graceful_queue_shutdown_helper_;
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h index bbf9ae7..f21437d 100644 --- a/base/task/sequence_manager/task_queue_impl.h +++ b/base/task/sequence_manager/task_queue_impl.h
@@ -30,10 +30,10 @@ class LazyNow; class TimeDomain; -class SequenceManagerImpl; namespace internal { +class SequenceManagerImpl; class WorkQueue; class WorkQueueSets;
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h index d6c3487..14bad6a 100644 --- a/base/task/sequence_manager/time_domain.h +++ b/base/task/sequence_manager/time_domain.h
@@ -19,9 +19,9 @@ namespace sequence_manager { class SequenceManager; -class SequenceManagerImpl; namespace internal { +class SequenceManagerImpl; class TaskQueueImpl; } // namespace internal @@ -84,12 +84,13 @@ private: friend class internal::TaskQueueImpl; - friend class SequenceManagerImpl; + friend class internal::SequenceManagerImpl; friend class TestTimeDomain; // Called when the TimeDomain is registered. // TODO(kraynov): Pass SequenceManager in the constructor. - void OnRegisterWithSequenceManager(SequenceManagerImpl* sequence_manager); + void OnRegisterWithSequenceManager( + internal::SequenceManagerImpl* sequence_manager); // Schedule TaskQueue to wake up at certain time, repeating calls with // the same |queue| invalidate previous requests. @@ -125,7 +126,7 @@ } }; - SequenceManagerImpl* sequence_manager_; // Not owned. + internal::SequenceManagerImpl* sequence_manager_; // Not owned. internal::IntrusiveHeap<ScheduledDelayedWakeUp> delayed_wake_up_queue_; ThreadChecker main_thread_checker_;
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 82d1131ce..cd16765 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -311,6 +311,7 @@ SkPixmap pixmap; staging_surface_->peekPixels(&pixmap); gl->BindTexture(backing->texture_target, backing->texture_id); + DCHECK(GLSupportsFormat(pool_resource.format())); gl->TexSubImage2D( backing->texture_target, 0, 0, 0, pool_resource.size().width(), pool_resource.size().height(), GLDataFormat(pool_resource.format()),
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc index 873a432..57f2a6d0 100644 --- a/cc/raster/raster_buffer_provider.cc +++ b/cc/raster/raster_buffer_provider.cc
@@ -38,6 +38,15 @@ case viz::LUMINANCE_F16: case viz::RGBA_F16: case viz::R16_EXT: + case viz::BGR_565: + case viz::RG_88: + case viz::RGBX_8888: + case viz::BGRX_8888: + case viz::RGBX_1010102: + case viz::BGRX_1010102: + case viz::YVU_420: + case viz::YUV_420_BIPLANAR: + case viz::UYVY_422: return false; } NOTREACHED(); @@ -136,6 +145,15 @@ case viz::RED_8: case viz::LUMINANCE_F16: case viz::R16_EXT: + case viz::BGR_565: + case viz::RG_88: + case viz::RGBX_8888: + case viz::BGRX_8888: + case viz::RGBX_1010102: + case viz::BGRX_1010102: + case viz::YVU_420: + case viz::YUV_420_BIPLANAR: + case viz::UYVY_422: NOTREACHED(); return; }
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index 00cc4f7..72dde45 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc
@@ -306,7 +306,6 @@ resource.resource_->size(), resource.resource_->format()); } transferable.format = resource.resource_->format(); - transferable.buffer_format = viz::BufferFormat(transferable.format); transferable.color_space = resource.resource_->color_space(); resource.resource_->set_resource_id(resource_provider_->ImportResource( std::move(transferable),
diff --git a/cc/resources/resource_pool_unittest.cc b/cc/resources/resource_pool_unittest.cc index 6ed88e94..171b177 100644 --- a/cc/resources/resource_pool_unittest.cc +++ b/cc/resources/resource_pool_unittest.cc
@@ -704,7 +704,6 @@ EXPECT_EQ(transfer[0].mailbox_holder.sync_token, sync_token); EXPECT_EQ(transfer[0].mailbox_holder.texture_target, target); EXPECT_EQ(transfer[0].format, format); - EXPECT_EQ(transfer[0].buffer_format, viz::BufferFormat(format)); EXPECT_TRUE(transfer[0].read_lock_fences_enabled); EXPECT_TRUE(transfer[0].is_overlay_candidate);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index b69d9a2..efd246e 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -5087,7 +5087,6 @@ mailbox, GL_LINEAR, texture_alloc.texture_target, sync_token, upload_size, texture_alloc.overlay_candidate); transferable.format = format; - transferable.buffer_format = viz::BufferFormat(format); } else { mojo::ScopedSharedBufferHandle memory_handle = viz::bitmap_allocation::DuplicateAndCloseMappedBitmap(
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 56fb0c75..e0a43dc 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -647,7 +647,7 @@ ] if (enable_feed_in_chrome) { - deps += feed_conformance_test_deps + deps += feed_test_deps } data = [
diff --git a/chrome/android/feed/core/DEPS b/chrome/android/feed/core/DEPS index 3bfdb5b..062b9e0 100644 --- a/chrome/android/feed/core/DEPS +++ b/chrome/android/feed/core/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/background_task_scheduler", "+components/feed", "+content/public/android/java/src/org/chromium/content_public", "+third_party/feed"
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java index a79a5ec..3312351 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java
@@ -33,7 +33,7 @@ return sFeedProcessScope; } - /* + /** * @return The {@link FeedSchedulerBridge} that was given to the {@link FeedProcessScope}. */ public static FeedSchedulerBridge getFeedSchedulerBridge() { @@ -62,6 +62,7 @@ new LoggingApiImpl(), new FeedNetworkBridge(profile), sFeedSchedulerBridge, lifecycleListener, DebugBehavior.SILENT) .build(); - sFeedSchedulerBridge.setRequestManager(sFeedProcessScope.getRequestManager()); + sFeedSchedulerBridge.initializeFeedDependencies( + sFeedProcessScope.getRequestManager(), sFeedProcessScope.getSessionManager()); } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedRefreshTask.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedRefreshTask.java new file mode 100644 index 0000000..36478f42 --- /dev/null +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedRefreshTask.java
@@ -0,0 +1,89 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import android.content.Context; + +import org.chromium.base.ContextUtils; +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.background_task_scheduler.NativeBackgroundTask; +import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; +import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; +import org.chromium.components.background_task_scheduler.TaskIds; +import org.chromium.components.background_task_scheduler.TaskInfo; +import org.chromium.components.background_task_scheduler.TaskParameters; + +/** + * A task implementation that loads native and then tries to refresh the Feed's articles. Failures + * or interruptions are not retried or rescheduled. + */ +public class FeedRefreshTask extends NativeBackgroundTask { + // The amount of "flex" to add around the fetching periods, as a ratio of the period. + private static final double FLEX_FACTOR = 0.1; + + /** + * Schedules a periodic task to wake up every thresholdMs and try to refresh. Allows for a bit + * of flex time before and after thresholdMs. Replaces the previous scheduling of the feed + * refresh task. + * + * @param thresholdMs the target number of milliseconds between each refresh. + */ + public static void scheduleWakeUp(long thresholdMs) { + // The flex given to the BackgroundTaskScheduler is a period of time before the |intervalMs| + // point in time. Because we want to schedule for +/- FLEX_FACTOR around |thresholdMs|, some + // adjustments below are needed. + long intervalMs = (long) (thresholdMs * (1 + FLEX_FACTOR)); + long flexWindowSizeMs = (long) (thresholdMs * 2 * FLEX_FACTOR); + + BackgroundTaskScheduler scheduler = BackgroundTaskSchedulerFactory.getScheduler(); + TaskInfo taskInfo = TaskInfo.createPeriodicTask(TaskIds.FEED_REFRESH_JOB_ID, + FeedRefreshTask.class, intervalMs, flexWindowSizeMs) + .setIsPersisted(true) + .setUpdateCurrent(true) + .setRequiredNetworkType(TaskInfo.NETWORK_TYPE_ANY) + .build(); + scheduler.schedule(ContextUtils.getApplicationContext(), taskInfo); + } + + /** Clears previously scheduled task. */ + public static void cancelWakeUp() { + BackgroundTaskScheduler scheduler = BackgroundTaskSchedulerFactory.getScheduler(); + scheduler.cancel(ContextUtils.getApplicationContext(), TaskIds.FEED_REFRESH_JOB_ID); + } + + @Override + protected int onStartTaskBeforeNativeLoaded( + Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { + // Nothing to setup without native, just wait. + return NativeBackgroundTask.LOAD_NATIVE; + } + + @Override + protected void onStartTaskWithNative( + Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { + FeedProcessScopeFactory.getFeedSchedulerBridge().onFixedTimer(() -> { + // Regardless of success, mark ourselves as completed. + callback.taskFinished(false); + }); + } + + @Override + protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParameters taskParameters) { + // Don't retry, this task is periodic anyways. + return false; + } + + @Override + protected boolean onStopTaskWithNative(Context context, TaskParameters taskParameters) { + // Don't retry, this task is periodic anyways. + return false; + } + + @Override + public void reschedule(Context context) { + ThreadUtils.runOnUiThread( + () -> { FeedProcessScopeFactory.getFeedSchedulerBridge().onTaskReschedule(); }); + } +}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java index 25c69b7..c8a04f0 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java
@@ -4,10 +4,15 @@ package org.chromium.chrome.browser.feed; +import android.support.annotation.NonNull; + +import com.google.android.libraries.feed.api.common.MutationContext; import com.google.android.libraries.feed.api.requestmanager.RequestManager; +import com.google.android.libraries.feed.api.sessionmanager.SessionManager; import com.google.android.libraries.feed.host.scheduler.SchedulerApi; import com.google.search.now.wire.feed.FeedQueryProto.FeedQuery.RequestReason; +import org.chromium.base.Callback; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.profiles.Profile; @@ -20,6 +25,7 @@ public class FeedSchedulerBridge implements SchedulerApi { private long mNativeBridge; private RequestManager mRequestManager; + private SessionManager mSessionManager; /** * Creates a FeedSchedulerBridge for accessing native scheduling logic. @@ -30,24 +36,28 @@ mNativeBridge = nativeInit(profile); } - /* - * Cleans up native half of this bridge. - */ + /** Cleans up the native half of this bridge. */ public void destroy() { assert mNativeBridge != 0; nativeDestroy(mNativeBridge); mNativeBridge = 0; } - /* - * Sets our copy of the RequestManager. Should be done as early as possible, as the scheduler - * will be unable to trigger refreshes until after it has a reference to a RequestManager. When - * this is called, it is assumed that the RequestManager is initialized and can be used. + /** + * Sets our copies for various interfaces provided by the Feed library. Should be done as early + * as possible, as the scheduler will be unable to trigger refreshes until after it has the + * mechanisms to correctly do so. When this is called, it is assumed that the given + * RequestManager and SessionManager are initialized and can be used immediately. * * @param requestManager The interface that allows us make refresh requests. + * @param sessionManager The interface that provides correct consumtion of refresh results. */ - public void setRequestManager(RequestManager requestManager) { + public void initializeFeedDependencies( + @NonNull RequestManager requestManager, @NonNull SessionManager sessionManager) { + assert mRequestManager == null; + assert mSessionManager == null; mRequestManager = requestManager; + mSessionManager = sessionManager; } @Override @@ -98,20 +108,36 @@ nativeOnForegrounded(mNativeBridge); } - public void onFixedTimer() { + public void onFixedTimer(Runnable onCompletion) { assert mNativeBridge != 0; - nativeOnFixedTimer(mNativeBridge); + // Convert to single argument Callback to make invoking from native more convenient. + nativeOnFixedTimer(mNativeBridge, (Void ignored) -> onCompletion.run()); + } + + public void onTaskReschedule() { + assert mNativeBridge != 0; + nativeOnTaskReschedule(mNativeBridge); } @CalledByNative private boolean triggerRefresh() { - if (mRequestManager != null) { - mRequestManager.triggerRefresh(RequestReason.SCHEDULED_REFRESH, ignored -> {}); + if (mRequestManager != null && mSessionManager != null) { + mRequestManager.triggerRefresh(RequestReason.SCHEDULED_REFRESH, + mSessionManager.getUpdateConsumer(MutationContext.EMPTY_CONTEXT)); return true; } return false; } + @CalledByNative + private void scheduleWakeUp(long thresholdMs) { + FeedRefreshTask.scheduleWakeUp(thresholdMs); + } + + @CalledByNative + private void cancelWakeUp() { + FeedRefreshTask.cancelWakeUp(); + } private native long nativeInit(Profile profile); private native void nativeDestroy(long nativeFeedSchedulerBridge); private native int nativeShouldSessionRequestData(long nativeFeedSchedulerBridge, @@ -121,5 +147,7 @@ private native void nativeOnRequestError( long nativeFeedSchedulerBridge, int networkResponseCode); private native void nativeOnForegrounded(long nativeFeedSchedulerBridge); - private native void nativeOnFixedTimer(long nativeFeedSchedulerBridge); + private native void nativeOnFixedTimer( + long nativeFeedSchedulerBridge, Callback<Void> onCompletion); + private native void nativeOnTaskReschedule(long nativeFeedSchedulerBridge); }
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni index 49233be..9dd42da 100644 --- a/chrome/android/feed/feed_java_sources.gni +++ b/chrome/android/feed/feed_java_sources.gni
@@ -15,6 +15,7 @@ "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java", + "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedRefreshTask.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/action/FeedActionHandler.java", @@ -22,12 +23,18 @@ feed_srcjar_deps = [ "//components/feed/core:feed_core_java_enums_srcjar" ] - feed_conformance_test_sources = [ - "//chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNetworkBridgeConformanceTest.java", - "//chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java", + feed_junit_test_java_sources = [ + "junit/src/org/chromium/chrome/browser/feed/FeedImageLoaderTest.java", + "junit/src/org/chromium/chrome/browser/feed/StreamLifecycleManagerTest.java", ] - feed_conformance_test_deps = [ + feed_test_java_sources = [ + "//chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNetworkBridgeConformanceTest.java", + "//chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java", + "//chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedRefreshTaskTest.java", + ] + + feed_test_deps = [ "//third_party/feed:feed_lib_java", "//third_party/feed:feed_conformance_test_lib_android_java", ]
diff --git a/chrome/android/java/res/color/blue_mode_tint.xml b/chrome/android/java/res/color/blue_mode_tint.xml index b918ba4..c51af18 100644 --- a/chrome/android/java/res/color/blue_mode_tint.xml +++ b/chrome/android/java/res/color/blue_mode_tint.xml
@@ -4,5 +4,5 @@ found in the LICENSE file. --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:color="@color/light_active_color"/> + <item android:color="@color/default_icon_color_blue"/> </selector>
diff --git a/chrome/android/java/res/color/blue_when_enabled.xml b/chrome/android/java/res/color/blue_when_enabled.xml index 855d690..0593a59 100644 --- a/chrome/android/java/res/color/blue_when_enabled.xml +++ b/chrome/android/java/res/color/blue_when_enabled.xml
@@ -5,5 +5,5 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="@color/google_grey_300" /> - <item android:color="@color/light_active_color"/> + <item android:color="@color/default_icon_color_blue"/> </selector>
diff --git a/chrome/android/java/res/drawable/checkmark_blue.xml b/chrome/android/java/res/drawable/checkmark_blue.xml index fc7cebc..10403b0 100644 --- a/chrome/android/java/res/drawable/checkmark_blue.xml +++ b/chrome/android/java/res/drawable/checkmark_blue.xml
@@ -14,6 +14,6 @@ android:fillColor="@android:color/white" android:pathData="M4 6H20v12H4z" /> <path - android:fillColor="@color/google_blue_500" + android:fillColor="@color/default_icon_color_blue" android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" /> </vector>
diff --git a/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml b/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml index b775b23a..a236f312 100644 --- a/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml +++ b/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml
@@ -21,7 +21,7 @@ android:name="ic_check" android:pathData="M4.12,12.705 l4.88,4.88 l11.295,-11.29" android:strokeWidth="2" - android:strokeColor="#4285F4"/> + android:strokeColor="@color/default_icon_color_blue"/> </vector> </aapt:attr>
diff --git a/chrome/android/java/res/drawable/infobar_download_complete.xml b/chrome/android/java/res/drawable/infobar_download_complete.xml index 9e516c4..a9eb187c 100644 --- a/chrome/android/java/res/drawable/infobar_download_complete.xml +++ b/chrome/android/java/res/drawable/infobar_download_complete.xml
@@ -20,6 +20,6 @@ <path android:name="check_mark" android:pathData="M5 18h14v2H5v-2zm4.6-2.7L5 10.7l2-1.9 2.6 2.6L17 4l2 2-9.4 9.3z" - android:fillColor="@color/google_blue_500"/> + android:fillColor="@color/default_icon_color_blue"/> </vector> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/infobar_downloading_fill_animation.xml b/chrome/android/java/res/drawable/infobar_downloading_fill_animation.xml index f1e96f4e..e78893d 100644 --- a/chrome/android/java/res/drawable/infobar_downloading_fill_animation.xml +++ b/chrome/android/java/res/drawable/infobar_downloading_fill_animation.xml
@@ -28,7 +28,7 @@ <path android:name="arrow_blue" - android:fillColor="@color/google_blue_500" + android:fillColor="@color/default_icon_color_blue" android:pathData="M30,15 L42,15 L42,30 L52,30 L36,46 L20,30 L30,30 Z" android:strokeColor="#00000000"/> </group> @@ -42,7 +42,7 @@ <path android:name="bar" android:pathData="M12,54 L60,54" - android:strokeColor="@color/google_blue_500" + android:strokeColor="@color/default_icon_color_blue" android:strokeWidth="6"/> </vector> @@ -67,14 +67,14 @@ android:duration="0" android:interpolator="@android:interpolator/linear" android:propertyName="fillColor" - android:valueFrom="@color/google_blue_500" - android:valueTo="@color/google_blue_500"/> + android:valueFrom="@color/default_icon_color_blue" + android:valueTo="@color/default_icon_color_blue"/> <objectAnimator android:duration="@integer/download_infobar_fill_out_delay" android:startOffset="@integer/download_infobar_fill_in_delay" android:interpolator="@android:interpolator/linear" android:propertyName="fillColor" - android:valueFrom="@color/google_blue_500" + android:valueFrom="@color/default_icon_color_blue" android:valueTo="@color/google_blue_50"/> </set> </aapt:attr>
diff --git a/chrome/android/java/res/drawable/infobar_downloading_sweep_animation.xml b/chrome/android/java/res/drawable/infobar_downloading_sweep_animation.xml index 971a65ae..c88e9333 100644 --- a/chrome/android/java/res/drawable/infobar_downloading_sweep_animation.xml +++ b/chrome/android/java/res/drawable/infobar_downloading_sweep_animation.xml
@@ -28,7 +28,7 @@ <path android:name="arrow_blue" - android:fillColor="@color/google_blue_500" + android:fillColor="@color/default_icon_color_blue" android:pathData="M30,15 L42,15 L42,30 L52,30 L36,46 L20,30 L30,30 Z" android:strokeColor="#00000000"/> </group> @@ -97,11 +97,11 @@ android:startOffset="300" android:propertyName="strokeColor" android:valueFrom="@color/google_blue_50" - android:valueTo="@color/google_blue_500"/> + android:valueTo="@color/default_icon_color_blue"/> <objectAnimator android:duration="@integer/download_infobar_sweep_down_delay" android:propertyName="strokeColor" - android:valueFrom="@color/google_blue_500" + android:valueFrom="@color/default_icon_color_blue" android:valueTo="@color/google_blue_50"/> </set> </aapt:attr>
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 8cff29c..4171d72 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
@@ -35,8 +35,8 @@ android:layout_marginTop="8dp" android:layout_marginBottom="8dp" app:colorBackground="@color/google_grey_300" - app:colorProgress="@color/google_blue_500_alpha_38_opaque" - app:colorSecondaryProgress="@color/google_blue_500" /> + app:colorProgress="@color/modern_blue_600_alpha_38_opaque" + app:colorSecondaryProgress="@color/modern_blue_600" /> <TextView android:id="@+id/size_free_and_other_apps"
diff --git a/chrome/android/java/res/layout/keyboard_accessory_action.xml b/chrome/android/java/res/layout/keyboard_accessory_action.xml index 6508df7..8c296a1 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_action.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_action.xml
@@ -18,5 +18,5 @@ android:textAlignment="center" android:textColor="@color/white_alpha_90" android:textSize="@dimen/keyboard_accessory_text_size" - app:buttonColor="@color/google_blue_500" + app:buttonColor="@color/light_active_color" app:buttonRaised="false"/>
diff --git a/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml b/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml index 40ca43d..723e93c 100644 --- a/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml +++ b/chrome/android/java/res/layout/personalized_signin_promo_view_body.xml
@@ -29,7 +29,7 @@ android:layout_marginStart="24dp" android:layout_marginTop="6dp" android:ellipsize="end" - android:maxLines="1" + android:singleLine="true" android:text="@string/signin_promo_continue_as"/> <Button @@ -42,6 +42,6 @@ android:layout_marginStart="24dp" android:layout_marginTop="6dp" android:ellipsize="end" - android:maxLines="1" + android:singleLine="true" android:text="@string/signin_promo_choose_account"/> </merge> \ No newline at end of file
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 07bd8ed..72e16cb 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -21,9 +21,9 @@ <style name="MainThemeBase" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowContentOverlay">@null</item> <item name="android:textColorHighlight">@color/text_highlight_color</item> - <item name="android:textColorLink">@color/light_active_color</item> + <item name="android:textColorLink">@color/default_text_color_link</item> <item name="colorPrimaryDark">@android:color/black</item> - <item name="android:colorAccent" tools:targetApi="21">@color/google_blue_500</item> + <item name="android:colorAccent" tools:targetApi="21">@color/light_active_color</item> <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> <!-- Overriding AppCompat values --> @@ -455,7 +455,7 @@ <style name="DialogWhenLargeBase" parent="Theme.AppCompat.Light.DialogWhenLarge" > <item name="android:windowBackground">@drawable/bg_white_dialog</item> <item name="android:textAppearance">@style/BlackBodyDefault</item> - <item name="android:textColorLink">@color/light_active_color</item> + <item name="android:textColorLink">@color/default_text_color_link</item> <item name="colorPrimaryDark">@android:color/black</item> <item name="colorAccent">@color/light_active_color</item> <item name="buttonStyle">@style/MainButtonStyle</item> @@ -472,7 +472,7 @@ </style> <style name="SigninDialogButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> - <item name="android:textColor">@color/light_active_color</item> + <item name="android:textColor">@color/default_text_color_link</item> </style> <!-- Contextual Search styles --> @@ -538,7 +538,7 @@ <item name="android:textColor">@color/explanation_text_color</item> </style> <style name="EditorDialogSectionAddButtonLabel"> - <item name="android:textColor">@color/light_active_color</item> + <item name="android:textColor">@color/default_text_color_link</item> <item name="android:textSize">14sp</item> <item name="android:textAllCaps">true</item> </style> @@ -594,10 +594,12 @@ they are removed from @style/ButtonCompatBase. --> <style name="SigninButtonBorderlessRegular"> <item name="android:background">?android:attr/selectableItemBackground</item> + <item name="android:paddingStart">0dp</item> + <item name="android:paddingEnd">0dp</item> <item name="android:fontFamily">sans-serif</item> <item name="android:textAllCaps">false</item> <item name="android:textStyle">normal</item> - <item name="android:textColor">@color/light_active_color</item> + <item name="android:textColor">@color/default_text_color_link</item> <item name="android:textSize">14sp</item> </style>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index c14018f..60479bb 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -4,25 +4,48 @@ found in the LICENSE file. --> <resources> - <!-- Common colors --> + <!-- Common text colors --> <color name="default_text_color">@color/black_alpha_87</color> <color name="default_primary_color">#F2F2F2</color> <color name="default_text_color_link">@color/modern_blue_600</color> - <!-- Deprecated. Use dark_mode_tint or default_icon_color for icons instead. --> - <color name="light_normal_color">#5A5A5A</color> - <color name="light_active_color">@color/google_blue_500</color> - <color name="default_icon_color">@color/modern_grey_800</color> - <color name="light_icon_color">@color/modern_grey_500</color> <color name="input_underline_error_color">#D32F2F</color> <color name="explanation_text_color">#909090</color> <color name="text_highlight_color">#C6DAFC</color> - <color name="dark_action_bar_color">#263238</color> <color name="descriptive_text_color">#646464</color> <color name="error_text_color">@color/google_red_700</color> + + <!-- Common control colors for toggles, checkboxes, ratio buttons and accent. --> + <!-- Deprecated. Use dark_mode_tint or default_icon_color for icons instead. --> + <color name="light_normal_color">#5A5A5A</color> + <color name="light_active_color">@color/modern_blue_600</color> + + <!-- Common icon colors for drawables. --> + <color name="default_icon_color">@color/modern_grey_800</color> + <color name="default_icon_color_blue">@color/modern_blue_600</color> + <color name="light_icon_color">@color/modern_grey_500</color> + + <!-- Other common colors --> + <color name="dark_action_bar_color">#263238</color> + <color name="modal_dialog_scrim_color">#7F000000</color> + + <!-- Modern color palette --> + <color name="black_alpha_11">#1D000000</color> + <color name="black_alpha_12">#1F000000</color> + <color name="black_alpha_20">#33000000</color> + <color name="black_alpha_24">#3D000000</color> + <color name="black_alpha_30">#4D000000</color> + <color name="black_alpha_40">#66000000</color> + <color name="black_alpha_65">#A6000000</color> + <color name="white_alpha_50">#80FFFFFF</color> + <color name="white_alpha_90">#E6FFFFFF</color> + + <color name="modern_light_grey">#F1F3F4</color> + <color name="modern_grey_800">#3C4043</color> + <color name="modern_grey_500">#9AA0A6</color> + + <!-- Old color palette --> <color name="google_blue_grey_500">#607D8B</color> <color name="google_blue_50">#E3F2FD</color> - <color name="google_blue_500">#4285F4</color> - <color name="google_blue_700">#3367D6</color> <color name="google_red_700">#C53929</color> <color name="google_green_700">#0B8043</color> <color name="google_grey_50">#FAFAFA</color> @@ -32,23 +55,7 @@ <color name="google_grey_400">#BDBDBD</color> <color name="google_grey_500">#9E9E9E</color> <color name="google_grey_600">#757575</color> - <color name="black_alpha_11">#1D000000</color> - <color name="black_alpha_12">#1F000000</color> - <color name="white_alpha_50">#80FFFFFF</color> - <color name="black_alpha_65">#A6000000</color> - <color name="white_alpha_90">#E6FFFFFF</color> <color name="light_grey">#CCCCCC</color> - <color name="modal_dialog_scrim_color">#7F000000</color> - - <color name="modern_light_grey">#F1F3F4</color> - <color name="modern_grey_800">#3C4043</color> - <color name="modern_grey_500">#9AA0A6</color> - - <!-- New list of common text colors --> - <color name="black_alpha_20">#33000000</color> - <color name="black_alpha_24">#3D000000</color> - <color name="black_alpha_30">#4D000000</color> - <color name="black_alpha_40">#66000000</color> <!-- Infobar colors --> <color name="infobar_accent_blue">@color/modern_blue_600</color> @@ -125,7 +132,7 @@ <color name="snippets_list_header_text_color">#646464</color> <color name="suggestions_modern_bg">@android:color/white</color> <color name="tile_view_text">@color/black_alpha_54</color> - <color name="suggestions_offline_badge_tint">@color/google_blue_500</color> + <color name="suggestions_offline_badge_tint">@color/default_icon_color_blue</color> <!-- Incognito NTP Colors. --> <color name="incognito_emphasis">@android:color/white</color> @@ -200,7 +207,7 @@ <!-- Other colors --> <color name="media_viewer_bg">#000000</color> <color name="image_viewer_bg">#0E0E0E</color> - <color name="google_blue_500_alpha_38_opaque">#B7D1FB</color> + <color name="modern_blue_600_alpha_38_opaque">#A8CAF6</color> <color name="toolbar_shadow_color">@color/black_alpha_11</color> <color name="bottom_system_nav_color">@android:color/white</color> <color name="bottom_system_nav_divider_color">@color/black_alpha_12</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index a2523f5c..189caed 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -193,6 +193,7 @@ public static final String CONTEXTUAL_SUGGESTIONS_BUTTON = "ContextualSuggestionsButton"; public static final String CONTEXTUAL_SUGGESTIONS_SLIM_PEEK_UI = "ContextualSuggestionsSlimPeekUI"; + public static final String CONTEXTUAL_SUGGESTIONS_OPT_OUT = "ContextualSuggestionsOptOut"; public static final String CUSTOM_CONTEXT_MENU = "CustomContextMenu"; public static final String CUSTOM_FEEDBACK_UI = "CustomFeedbackUi"; // Enables the Data Reduction Proxy menu item in the main menu rather than under Settings on
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardSuggestions.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardSuggestions.java index fc22396e..274f22f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardSuggestions.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardSuggestions.java
@@ -153,7 +153,7 @@ Drawable drawable = AppCompatResources.getDrawable(getContext(), suggestion.getIconId()); if (isKeyboardAccessoryHint) { drawable.setColorFilter( - ApiCompatibilityUtils.getColor(getResources(), R.color.google_blue_500), + ApiCompatibilityUtils.getColor(getResources(), R.color.default_icon_color_blue), PorterDuff.Mode.SRC_IN); } else { icon.setContentDescription(suggestion.getLabel());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java index 5adfbe0..23b010f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java
@@ -530,7 +530,7 @@ R.string.contextual_suggestions_in_product_help, R.string.contextual_suggestions_in_product_help, true, rectProvider, R.drawable.ic_logo_googleg_24dp); - mModel.setToolbarArrowTintResourceId(R.color.google_blue_500); + mModel.setToolbarArrowTintResourceId(R.color.default_icon_color_blue); } else { mHelpBubble = new TextBubble(mIphParentView.getContext(), mIphParentView, R.string.contextual_suggestions_in_product_help,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java index 3b903b0..e13f313 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java
@@ -6,6 +6,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.PrefChangeRegistrar; @@ -85,7 +86,8 @@ /** @return Whether the user settings for contextual suggestions should be shown. */ public static boolean shouldShowSettings() { - return isDSEConditionMet() && !AccessibilityUtil.isAccessibilityEnabled(); + return isDSEConditionMet() && !AccessibilityUtil.isAccessibilityEnabled() + && ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_OPT_OUT); } /** @return Whether the settings state is currently enabled. */ @@ -105,7 +107,9 @@ /** @return Whether the state is currently enabled. */ public static boolean getEnabledState() { return getSettingsEnabled() - && PrefServiceBridge.getInstance().getBoolean(Pref.CONTEXTUAL_SUGGESTIONS_ENABLED); + && (PrefServiceBridge.getInstance().getBoolean(Pref.CONTEXTUAL_SUGGESTIONS_ENABLED) + || !ChromeFeatureList.isEnabled( + ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_OPT_OUT)); } public static void recordEnabled(boolean enabled) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java index 6c5159b..043da8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java
@@ -213,7 +213,7 @@ itemView.getResources().getInteger(R.integer.list_item_level_default)); mThumbnail.setImageResource(mIconId); mThumbnail.setTint(AppCompatResources.getColorStateList( - itemView.getContext(), R.color.google_blue_500)); + itemView.getContext(), R.color.default_icon_color_blue)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java index c289eaa..b651fa05 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java
@@ -454,7 +454,7 @@ if (permissionParams.warningTextResource != 0) { permissionParams.iconResource = R.drawable.exclamation_triangle; - permissionParams.iconTintColorResource = R.color.google_blue_700; + permissionParams.iconTintColorResource = R.color.default_icon_color_blue; permissionParams.clickCallback = createPermissionClickCallback(intentOverride, androidPermissions); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java index 60af1e4..b111b48 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
@@ -887,7 +887,7 @@ drawableTint = R.color.error_text_color; } else { drawableId = R.drawable.plus; - drawableTint = R.color.light_active_color; + drawableTint = R.color.default_icon_color_blue; } TintedDrawable tintedDrawable = TintedDrawable.constructTintedDrawable(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java index 9c9e1f8..fceaeb8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java
@@ -43,8 +43,8 @@ // Sets preference icon and tints it to blue. Drawable icon = ApiCompatibilityUtils.getDrawable( getContext().getResources(), R.drawable.permission_background_sync); - icon.setColorFilter(ApiCompatibilityUtils.getColor( - getContext().getResources(), R.color.light_active_color), + icon.setColorFilter(ApiCompatibilityUtils.getColor(getContext().getResources(), + R.color.default_icon_color_blue), PorterDuff.Mode.SRC_IN); setIcon(icon); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java index 6941b20..099666a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java
@@ -80,9 +80,9 @@ RecordHistogram.recordCountHistogram("Tabs.Tasks.TabsInGroupCount", tabsInGroupCount); - double tabsInGroupRatio = tabsInGroupCount * 1.0 / totalTabCount; + double tabsInGroupRatioPercent = tabsInGroupCount * 1.0 / totalTabCount * 100.0; RecordHistogram.recordPercentageHistogram( - "Tabs.Tasks.TabsInGroupRatio", (int) tabsInGroupRatio * 100); + "Tabs.Tasks.TabsInGroupRatio", (int) tabsInGroupRatioPercent); if (tabGroupCount != 0) { int averageGroupSize = tabsInGroupCount / tabGroupCount; @@ -91,14 +91,14 @@ Log.d(TAG, "AverageGroupSize: %d", averageGroupSize); } - double tabGroupDensity = tabGroupCount * 1.0 / totalTabCount; + double tabGroupDensityPercent = tabGroupCount * 1.0 / totalTabCount * 100.0; RecordHistogram.recordPercentageHistogram( - "Tabs.Tasks.TabGroupDensity", (int) tabGroupDensity * 100); + "Tabs.Tasks.TabGroupDensity", (int) tabGroupDensityPercent); Log.d(TAG, "TotalTabCount: %d", totalTabCount); Log.d(TAG, "TabGroupCount: %d", tabGroupCount); Log.d(TAG, "TabsInGroupCount: %d", tabsInGroupCount); - Log.d(TAG, "TabsInGroupRatio: %f", tabsInGroupRatio); - Log.d(TAG, "TabGroupDensity: %f", tabGroupDensity); + Log.d(TAG, "TabsInGroupRatioPercent: %d", (int) tabsInGroupRatioPercent); + Log.d(TAG, "TabGroupDensityPercent: %d", (int) tabGroupDensityPercent); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java index 990b9ce..cb51740 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -68,6 +68,7 @@ import org.chromium.chrome.browser.omnibox.LocationBarPhone; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -1887,7 +1888,8 @@ // Don't inflate the incognito toggle button unless the horizontal tab switcher experiment // is enabled and the user actually enters the tab switcher. if (mIncognitoToggleButton == null && mTabSwitcherState != STATIC_TAB - && usingHorizontalTabSwitcher()) { + && usingHorizontalTabSwitcher() + && PrefServiceBridge.getInstance().isIncognitoModeEnabled()) { ViewStub incognitoToggleButtonStub = findViewById(R.id.incognito_button_stub); mIncognitoToggleButton = (IncognitoToggleButton) incognitoToggleButtonStub.inflate(); mIncognitoToggleButton.setOnClickListener(this); @@ -2789,12 +2791,12 @@ if (mExperimentalButton == null) { ViewStub viewStub = findViewById(R.id.experimental_button_stub); mExperimentalButton = (TintedImageButton) viewStub.inflate(); - mBrowsingModeViews.add(mExperimentalButton); } else { assert mExperimentalButton.getVisibility() == View.GONE : "#disableExperimentalButton() should be called first."; } + mBrowsingModeViews.add(mExperimentalButton); mExperimentalButton.setOnClickListener(onClickListener); mExperimentalButton.setImageResource(drawableResId); mExperimentalButton.setContentDescription( @@ -2810,6 +2812,7 @@ if (mExperimentalButton == null) return; mExperimentalButton.setVisibility(View.GONE); + mBrowsingModeViews.remove(mExperimentalButton); if (mLayoutUpdateHost != null) mLayoutUpdateHost.requestUpdate(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ImageViewTinter.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ImageViewTinter.java index d70282c7..ceca4af 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ImageViewTinter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ImageViewTinter.java
@@ -21,7 +21,7 @@ * <ImageViewTinterInstanceOwner * xmlns:android="http://schemas.android.com/apk/res/android" * xmlns:app="http://schemas.android.com/apk/res-auto" - * app:chrometint="@color/light_active_color" /> + * app:chrometint="@color/default_icon_color_blue" /> */ public class ImageViewTinter { /** Classes that own an ImageViewTinter must implement these functions. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java index e0c6912..d90721c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/PulseDrawable.java
@@ -153,8 +153,8 @@ Resources resources = ContextUtils.getApplicationContext().getResources(); @ColorInt - int color = ApiCompatibilityUtils.getColor( - resources, useLightPulseColor ? R.color.google_grey_100 : R.color.google_blue_500); + int color = ApiCompatibilityUtils.getColor(resources, + useLightPulseColor ? R.color.google_grey_100 : R.color.default_icon_color_blue); if (mState.color == color) return; int alpha = getAlpha();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java index f6706e2..df1a82e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/EditorTextField.java
@@ -94,8 +94,8 @@ if (fieldModel.getActionIconAction() != null) { mActionIcon = (ImageView) mIconsLayer.findViewById(R.id.action_icon); - mActionIcon.setImageDrawable(TintedDrawable.constructTintedDrawable( - context, fieldModel.getActionIconResourceId(), R.color.light_active_color)); + mActionIcon.setImageDrawable(TintedDrawable.constructTintedDrawable(context, + fieldModel.getActionIconResourceId(), R.color.default_icon_color_blue)); mActionIcon.setContentDescription(context.getResources().getString( fieldModel.getActionIconDescriptionForAccessibility())); mActionIcon.setOnClickListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java index 80f8713..bf74f815 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/prefeditor/HintedDropDownAdapterWithPlusIcon.java
@@ -68,7 +68,7 @@ // Create the "+" icon, put it left of the text and add appropriate padding. mTextView.setCompoundDrawablesWithIntrinsicBounds( TintedDrawable.constructTintedDrawable( - getContext(), R.drawable.plus, R.color.light_active_color), + getContext(), R.drawable.plus, R.color.default_icon_color_blue), null, null, null); Resources resources = getContext().getResources(); mTextView.setCompoundDrawablePadding(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java index 7ec55ea..ec38e62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java
@@ -188,8 +188,8 @@ addOnDismissListener(mDismissListener); // Set predefined styles for the TextBubble. - mDrawable.setBubbleColor( - ApiCompatibilityUtils.getColor(mContext.getResources(), R.color.google_blue_500)); + mDrawable.setBubbleColor(ApiCompatibilityUtils.getColor( + mContext.getResources(), R.color.light_active_color)); } /** Shows the bubble. Will have no effect if the bubble is already showing. */
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index d9000ed3..2b862cd 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -2230,11 +2230,8 @@ } if (enable_feed_in_chrome) { - chrome_junit_test_java_sources += [ - "junit/src/org/chromium/chrome/browser/feed/FeedImageLoaderTest.java", - "junit/src/org/chromium/chrome/browser/feed/StreamLifecycleManagerTest.java", - ] - chrome_test_java_sources += feed_conformance_test_sources + chrome_junit_test_java_sources += feed_junit_test_java_sources + chrome_test_java_sources += feed_test_java_sources } # This is enable_arcore, not package_arcore because the apk merger, for
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedRefreshTaskTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedRefreshTaskTest.java new file mode 100644 index 0000000..4e016875 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedRefreshTaskTest.java
@@ -0,0 +1,122 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import android.content.Context; +import android.support.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; +import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; +import org.chromium.components.background_task_scheduler.TaskIds; +import org.chromium.components.background_task_scheduler.TaskInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * Unit tests for {@link FeedSchedulerBridge}. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class FeedRefreshTaskTest { + @Rule + public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + + private static class TestBackgroundTaskScheduler implements BackgroundTaskScheduler { + private List<TaskInfo> mTaskInfoList = new ArrayList<>(); + private List<Integer> mCanceledTaskIds = new ArrayList<>(); + + public List<TaskInfo> getTaskInfoList() { + return mTaskInfoList; + } + + public List<Integer> getCanceledTaskIds() { + return mCanceledTaskIds; + } + + @Override + public boolean schedule(Context context, TaskInfo taskInfo) { + mTaskInfoList.add(taskInfo); + return true; + } + + @Override + public void cancel(Context context, int taskId) { + mCanceledTaskIds.add(taskId); + } + + @Override + public void checkForOSUpgrade(Context context) {} + + @Override + public void reschedule(Context context) {} + } + + private TestBackgroundTaskScheduler mTaskScheduler; + + @Before + public void setUp() throws InterruptedException { + mTaskScheduler = new TestBackgroundTaskScheduler(); + BackgroundTaskSchedulerFactory.setSchedulerForTesting(mTaskScheduler); + mActivityTestRule.startMainActivityOnBlankPage(); + } + + @Test + @SmallTest + public void testSchedule() { + ThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertEquals(0, mTaskScheduler.getTaskInfoList().size()); + FeedRefreshTask.scheduleWakeUp(/*thresholdMs=*/1234); + Assert.assertEquals(1, mTaskScheduler.getTaskInfoList().size()); + TaskInfo actualInfo = mTaskScheduler.getTaskInfoList().get(0); + Assert.assertEquals(TaskIds.FEED_REFRESH_JOB_ID, actualInfo.getTaskId()); + Assert.assertEquals(TaskInfo.NETWORK_TYPE_ANY, actualInfo.getRequiredNetworkType()); + Assert.assertEquals(false, actualInfo.requiresCharging()); + Assert.assertEquals(true, actualInfo.isPeriodic()); + Assert.assertEquals(true, actualInfo.isPersisted()); + Assert.assertEquals(true, actualInfo.shouldUpdateCurrent()); + // 1234 * 1.1 = 1357 + Assert.assertEquals(1357, actualInfo.getPeriodicInfo().getIntervalMs()); + // 1234 * 0.2 = 246 + Assert.assertEquals(246, actualInfo.getPeriodicInfo().getFlexMs()); + }); + } + + @Test + @SmallTest + public void testCancelWakeUp() { + ThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertEquals(0, mTaskScheduler.getCanceledTaskIds().size()); + FeedRefreshTask.cancelWakeUp(); + Assert.assertEquals(1, mTaskScheduler.getCanceledTaskIds().size()); + }); + } + + @Test + @SmallTest + public void testReschedule() { + ThreadUtils.runOnUiThreadBlocking(() -> { + // The FeedSchedulerHost might create a task during its initialization, so clear + // out anything before reschedule() is called. + FeedProcessScopeFactory.getFeedSchedulerBridge(); + mTaskScheduler.getTaskInfoList().clear(); + Assert.assertEquals(0, mTaskScheduler.getTaskInfoList().size()); + + new FeedRefreshTask().reschedule(mActivityTestRule.getActivity()); + Assert.assertEquals(1, mTaskScheduler.getTaskInfoList().size()); + }); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java index e062b49..6e016d0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java
@@ -4,17 +4,14 @@ package org.chromium.chrome.browser.feed; +import static org.mockito.Mockito.mock; + import android.support.test.filters.SmallTest; import android.support.test.rule.UiThreadTestRule; import com.google.android.libraries.feed.api.requestmanager.RequestManager; -import com.google.android.libraries.feed.common.Result; -import com.google.android.libraries.feed.common.functional.Consumer; -import com.google.android.libraries.feed.common.functional.Supplier; +import com.google.android.libraries.feed.api.sessionmanager.SessionManager; import com.google.android.libraries.feed.testing.conformance.scheduler.SchedulerConformanceTest; -import com.google.search.now.feed.client.StreamDataProto.StreamDataOperation; -import com.google.search.now.feed.client.StreamDataProto.StreamToken; -import com.google.search.now.wire.feed.FeedQueryProto.FeedQuery.RequestReason; import org.junit.After; import org.junit.Before; @@ -60,20 +57,6 @@ } }); - private final class NoOpRequestManager implements RequestManager { - @Override - public void loadMore(StreamToken streamToken, - Consumer < Result < List<StreamDataOperation>>> consumer) {} - @Override - public void triggerRefresh(RequestReason reason, - Consumer < Result < List<StreamDataOperation>>> consumer) {} - @Override - public void triggerRefresh(RequestReason reason) {} - @Override - public void setDefaultTriggerRefreshConsumerSupplier( - Supplier < Consumer < Result<List<StreamDataOperation>>>> consumer) {} - } - private boolean mUseRequestManager; public FeedSchedulerBridgeConformanceTest(boolean useRequestManager) { @@ -85,7 +68,9 @@ // The scheduler is declared and tested in SchedulerConformanceTest. scheduler = new FeedSchedulerBridge(Profile.getLastUsedProfile()); if (mUseRequestManager) { - ((FeedSchedulerBridge) scheduler).setRequestManager(new NoOpRequestManager()); + ((FeedSchedulerBridge) scheduler) + .initializeFeedDependencies( + mock(RequestManager.class), mock(SessionManager.class)); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceIntegrationTest.java index b4c593d..f538904 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceIntegrationTest.java
@@ -156,14 +156,6 @@ // Adding an observer should not lead to a callback. Assert.assertEquals(0, mObserver.getRevokedCallCount()); - // First seed the account state (some native classes make the assumption that - // a notification that a token was revoked for a given account was preceded by a - // notifictation that that account was available). - mOAuth2TokenService.fireRefreshTokenAvailable(TEST_ACCOUNT1); - mOAuth2TokenService.fireRefreshTokenAvailable(TEST_ACCOUNT2); - - Assert.assertEquals(2, mObserver.getAvailableCallCount()); - // An observer should be called with the correct account. mOAuth2TokenService.fireRefreshTokenRevoked(TEST_ACCOUNT1); Assert.assertEquals(1, mObserver.getRevokedCallCount()); @@ -174,9 +166,8 @@ mOAuth2TokenService.fireRefreshTokenRevoked(TEST_ACCOUNT2); Assert.assertEquals(1, mObserver.getRevokedCallCount()); - // No other observer interface method should have been called after the initial seeding - // of the accounts. - Assert.assertEquals(2, mObserver.getAvailableCallCount()); + // No other observer interface method should ever have been called. + Assert.assertEquals(0, mObserver.getAvailableCallCount()); Assert.assertEquals(0, mObserver.getLoadedCallCount()); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ImageViewTinterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ImageViewTinterTest.java index 361e627..9ec150a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ImageViewTinterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ImageViewTinterTest.java
@@ -116,8 +116,8 @@ private void checkSetTintWorksCorrectly(ImageViewTinterOwner view) { ImageView imageView = (ImageView) view; - int color = - ApiCompatibilityUtils.getColor(mContext.getResources(), R.color.light_active_color); + int color = ApiCompatibilityUtils.getColor( + mContext.getResources(), R.color.default_icon_color_blue); Assert.assertNull(imageView.getColorFilter()); if (imageView.getDrawable() == null) {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java index b79beb5..9969ef43 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java
@@ -26,6 +26,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; @@ -150,6 +151,7 @@ @Test @SmallTest @Feature({"Sync"}) + @DisabledTest public void testOpeningSettingsDoesntStartEngine() { mSyncTestRule.setUpTestAccountAndSignIn(); mSyncTestRule.stopSync(); @@ -163,6 +165,7 @@ @Test @SmallTest @Feature({"Sync"}) + @DisabledTest public void testDefaultControlStatesWithSyncOffThenOn() { mSyncTestRule.setUpTestAccountAndSignIn(); mSyncTestRule.stopSync(); @@ -514,6 +517,7 @@ @Test @SmallTest @Feature({"Sync"}) + @DisabledTest public void testPassphraseDialogDismissed() { final FakeProfileSyncService pss = overrideProfileSyncService();
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 3b8ee38..0df2628 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2536,6 +2536,10 @@ flag_descriptions::kContextualSuggestionsSlimPeekUIDescription, kOsAndroid, FEATURE_VALUE_TYPE( contextual_suggestions::kContextualSuggestionsSlimPeekUI)}, + {"contextual-suggestions-opt-out", + flag_descriptions::kContextualSuggestionsOptOutName, + flag_descriptions::kContextualSuggestionsOptOutDescription, kOsAndroid, + FEATURE_VALUE_TYPE(contextual_suggestions::kContextualSuggestionsOptOut)}, {"enable-content-suggestions-new-favicon-server", flag_descriptions::kEnableContentSuggestionsNewFaviconServerName, flag_descriptions::kEnableContentSuggestionsNewFaviconServerDescription,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 84c0651..d007da9 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -50,6 +50,7 @@ &contextual_suggestions::kContextualSuggestionsBottomSheet, &contextual_suggestions::kContextualSuggestionsButton, &contextual_suggestions::kContextualSuggestionsSlimPeekUI, + &contextual_suggestions::kContextualSuggestionsOptOut, &features::kClearOldBrowsingData, &features::kClipboardContentSetting, &features::kDownloadsForeground,
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc index 7a97e2d..dc3ea44 100644 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc +++ b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc
@@ -189,7 +189,7 @@ RegisterSyntheticFieldTrials(result); - RunCallbackAndroid(j_callback, j_result); + RunObjectCallbackAndroid(j_callback, j_result); } void ContextualSuggestionsBridge::OnImageFetched( @@ -199,7 +199,7 @@ if (!image.IsEmpty()) j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap()); - RunCallbackAndroid(j_callback, j_bitmap); + RunObjectCallbackAndroid(j_callback, j_bitmap); } } // namespace contextual_suggestions
diff --git a/chrome/browser/android/download/service/download_background_task.cc b/chrome/browser/android/download/service/download_background_task.cc index e46375c..86c394a 100644 --- a/chrome/browser/android/download/service/download_background_task.cc +++ b/chrome/browser/android/download/service/download_background_task.cc
@@ -16,11 +16,6 @@ namespace download { namespace android { -void CallTaskFinishedCallback(const base::android::JavaRef<jobject>& j_callback, - bool needs_reschedule) { - RunCallbackAndroid(j_callback, needs_reschedule); -} - // static void JNI_DownloadBackgroundTask_StartBackgroundTask( JNIEnv* env, @@ -32,7 +27,7 @@ DCHECK(profile); TaskFinishedCallback finish_callback = - base::BindOnce(&CallTaskFinishedCallback, + base::BindOnce(&base::android::RunBooleanCallbackAndroid, base::android::ScopedJavaGlobalRef<jobject>(jcallback)); DownloadService* download_service =
diff --git a/chrome/browser/android/explore_sites/explore_sites_bridge.cc b/chrome/browser/android/explore_sites/explore_sites_bridge.cc index 7d39ada..7b93624 100644 --- a/chrome/browser/android/explore_sites/explore_sites_bridge.cc +++ b/chrome/browser/android/explore_sites/explore_sites_bridge.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/android/explore_sites/explore_sites_bridge.h" +#include <string> +#include <utility> + #include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" @@ -68,7 +71,7 @@ } } - base::android::RunCallbackAndroid(j_callback_ref, j_result_ref); + base::android::RunObjectCallbackAndroid(j_callback_ref, j_result_ref); } void OnGetIconDone(std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, @@ -80,7 +83,7 @@ if (!image.IsEmpty()) { j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap()); } - base::android::RunCallbackAndroid(j_callback_obj, j_bitmap); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_bitmap); // Delete |image_fetcher| when appropriate. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
diff --git a/chrome/browser/android/feed/feed_image_loader_bridge.cc b/chrome/browser/android/feed/feed_image_loader_bridge.cc index 75e050b..7aafff28 100644 --- a/chrome/browser/android/feed/feed_image_loader_bridge.cc +++ b/chrome/browser/android/feed/feed_image_loader_bridge.cc
@@ -75,7 +75,7 @@ if (!image.IsEmpty()) { j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap()); } - RunCallbackAndroid(callback, j_bitmap); + RunObjectCallbackAndroid(callback, j_bitmap); } } // namespace feed
diff --git a/chrome/browser/android/feed/feed_image_loader_bridge.h b/chrome/browser/android/feed/feed_image_loader_bridge.h index b843b45..9c14bbc 100644 --- a/chrome/browser/android/feed/feed_image_loader_bridge.h +++ b/chrome/browser/android/feed/feed_image_loader_bridge.h
@@ -11,30 +11,28 @@ namespace feed { -using base::android::JavaParamRef; -using base::android::ScopedJavaGlobalRef; - class FeedImageManager; // Native counterpart of FeedImageLoaderBridge.java. Holds non-owning pointers // to native implementation, to which operations are delegated. Results are // passed back by a single argument callback so -// base::android::RunCallbackAndroid() can be used. This bridge is instantiated, -// owned, and destroyed from Java. +// base::android::RunObjectCallbackAndroid() can be used. This bridge is +// instantiated, owned, and destroyed from Java. class FeedImageLoaderBridge { public: explicit FeedImageLoaderBridge(FeedImageManager* feed_image_manager); ~FeedImageLoaderBridge(); - void Destroy(JNIEnv* j_env, const JavaParamRef<jobject>& j_this); + void Destroy(JNIEnv* j_env, + const base::android::JavaParamRef<jobject>& j_this); void FetchImage(JNIEnv* j_env, - const JavaParamRef<jobject>& j_this, - const JavaParamRef<jobjectArray>& j_urls, - const JavaParamRef<jobject>& j_callback); + const base::android::JavaParamRef<jobject>& j_this, + const base::android::JavaParamRef<jobjectArray>& j_urls, + const base::android::JavaParamRef<jobject>& j_callback); private: - void OnImageFetched(ScopedJavaGlobalRef<jobject> callback, + void OnImageFetched(base::android::ScopedJavaGlobalRef<jobject> callback, const gfx::Image& image); FeedImageManager* feed_image_manager_;
diff --git a/chrome/browser/android/feed/feed_network_bridge.cc b/chrome/browser/android/feed/feed_network_bridge.cc index 61f6086..7c685e5 100644 --- a/chrome/browser/android/feed/feed_network_bridge.cc +++ b/chrome/browser/android/feed/feed_network_bridge.cc
@@ -38,7 +38,7 @@ ScopedJavaLocalRef<jobject> j_http_response = Java_FeedNetworkBridge_createHttpResponse(env, http_code, j_response_bytes); - base::android::RunCallbackAndroid(j_callback, j_http_response); + base::android::RunObjectCallbackAndroid(j_callback, j_http_response); } } // namespace
diff --git a/chrome/browser/android/feed/feed_network_bridge.h b/chrome/browser/android/feed/feed_network_bridge.h index 44080b9..01b9ea2 100644 --- a/chrome/browser/android/feed/feed_network_bridge.h +++ b/chrome/browser/android/feed/feed_network_bridge.h
@@ -16,8 +16,8 @@ // Native counterpart of FeedNetworkBridge.java. Holds non-owning pointers to // native implementation, to which operations are delegated. Results are passed -// back by a single argument callback so base::android::RunCallbackAndroid() can -// be used. This bridge is instantiated, owned, and destroyed from Java. +// back by a single argument callback so base::android::RunObjectCallbackAndroid +// can be used. This bridge is instantiated, owned, and destroyed from Java. class FeedNetworkBridge { public: explicit FeedNetworkBridge(
diff --git a/chrome/browser/android/feed/feed_scheduler_bridge.cc b/chrome/browser/android/feed/feed_scheduler_bridge.cc index 89ab0c671..69cfecd 100644 --- a/chrome/browser/android/feed/feed_scheduler_bridge.cc +++ b/chrome/browser/android/feed/feed_scheduler_bridge.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/android/feed/feed_scheduler_bridge.h" +#include <utility> + +#include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/bind.h" #include "base/time/time.h" @@ -11,7 +14,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" #include "components/feed/core/feed_host_service.h" -#include "components/feed/core/feed_scheduler_host.h" #include "jni/FeedSchedulerBridge_jni.h" using base::android::JavaRef; @@ -37,8 +39,11 @@ scheduler_host_(scheduler_host), weak_factory_(this) { DCHECK(scheduler_host_); - scheduler_host_->RegisterTriggerRefreshCallback(base::BindRepeating( - &FeedSchedulerBridge::TriggerRefresh, weak_factory_.GetWeakPtr())); + scheduler_host_->Initialize( + base::BindRepeating(&FeedSchedulerBridge::TriggerRefresh, + weak_factory_.GetWeakPtr()), + base::BindRepeating(&FeedSchedulerBridge::ScheduleWakeUp, + weak_factory_.GetWeakPtr())); } FeedSchedulerBridge::~FeedSchedulerBridge() {} @@ -77,9 +82,20 @@ scheduler_host_->OnForegrounded(); } -void FeedSchedulerBridge::OnFixedTimer(JNIEnv* env, - const JavaRef<jobject>& j_this) { - scheduler_host_->OnFixedTimer(); +void FeedSchedulerBridge::OnFixedTimer( + JNIEnv* env, + const JavaRef<jobject>& j_this, + const base::android::JavaRef<jobject>& j_callback) { + base::OnceClosure callback = + base::BindOnce(&base::android::RunObjectCallbackAndroid, + ScopedJavaGlobalRef<jobject>(j_callback), nullptr); + scheduler_host_->OnFixedTimer(std::move(callback)); +} + +void FeedSchedulerBridge::OnTaskReschedule( + JNIEnv* env, + const base::android::JavaRef<jobject>& j_this) { + scheduler_host_->OnTaskReschedule(); } void FeedSchedulerBridge::TriggerRefresh() { @@ -87,4 +103,15 @@ Java_FeedSchedulerBridge_triggerRefresh(env, j_this_); } +void FeedSchedulerBridge::ScheduleWakeUp(base::TimeDelta threshold) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_FeedSchedulerBridge_scheduleWakeUp(env, j_this_, + threshold.InMilliseconds()); +} + +void FeedSchedulerBridge::CancelWakeUp() { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_FeedSchedulerBridge_cancelWakeUp(env, j_this_); +} + } // namespace feed
diff --git a/chrome/browser/android/feed/feed_scheduler_bridge.h b/chrome/browser/android/feed/feed_scheduler_bridge.h index 4465dee..29382c6 100644 --- a/chrome/browser/android/feed/feed_scheduler_bridge.h +++ b/chrome/browser/android/feed/feed_scheduler_bridge.h
@@ -6,10 +6,16 @@ #define CHROME_BROWSER_ANDROID_FEED_FEED_SCHEDULER_BRIDGE_H_ #include <jni.h> +#include <stdint.h> #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/feed/core/feed_scheduler_host.h" + +namespace base { +class TimeDelta; +} // namespace base namespace feed { @@ -43,13 +49,25 @@ void OnForegrounded(JNIEnv* env, const base::android::JavaRef<jobject>& j_this); - void OnFixedTimer(JNIEnv* env, const base::android::JavaRef<jobject>& j_this); + void OnFixedTimer(JNIEnv* env, + const base::android::JavaRef<jobject>& j_this, + const base::android::JavaRef<jobject>& j_callback); + void OnTaskReschedule(JNIEnv* env, + const base::android::JavaRef<jobject>& j_this); + + private: // Callable by native code to invoke Java code. Sends a request to the Feed // library to make the refresh call. void TriggerRefresh(); - private: + // Calls into Java logic to schedule a background task to wake up Chrome and + // call back into the FeedHostScheduler. + void ScheduleWakeUp(base::TimeDelta threshold_ms); + + // Cancels previously scheduled background task. + void CancelWakeUp(); + // Reference to the Java half of this bridge. Always valid. base::android::ScopedJavaGlobalRef<jobject> j_this_;
diff --git a/chrome/browser/android/ntp/ntp_snippets_bridge.cc b/chrome/browser/android/ntp/ntp_snippets_bridge.cc index b2921e1..d83689e 100644 --- a/chrome/browser/android/ntp/ntp_snippets_bridge.cc +++ b/chrome/browser/android/ntp/ntp_snippets_bridge.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/android/ntp/ntp_snippets_bridge.h" #include <jni.h> +#include <set> +#include <string> #include <utility> #include <vector> @@ -377,7 +379,7 @@ if (!image.IsEmpty()) { j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap()); } - RunCallbackAndroid(callback, j_bitmap); + RunObjectCallbackAndroid(callback, j_bitmap); } void NTPSnippetsBridge::OnSuggestionsFetched( @@ -389,14 +391,14 @@ // TODO(fhorschig, dgn): Allow refetch or show notification acc. to status. JNIEnv* env = AttachCurrentThread(); if (status.IsSuccess()) { - RunCallbackAndroid( + RunObjectCallbackAndroid( success_callback, JNI_SnippetsBridge_ToJavaSuggestionList(env, category, suggestions)); } else { // The second parameter here means nothing - it was more convenient to pass // a Callback (which has 1 parameter) over to the native side than a // Runnable (which has no parameters). We ignore the parameter Java-side. - RunCallbackAndroid(failure_callback, 0); + RunIntCallbackAndroid(failure_callback, 0); } }
diff --git a/chrome/browser/android/password_ui_view_android.cc b/chrome/browser/android/password_ui_view_android.cc index c0391a2..b4900f7 100644 --- a/chrome/browser/android/password_ui_view_android.cc +++ b/chrome/browser/android/password_ui_view_android.cc
@@ -240,14 +240,12 @@ *export_target_for_testing_ = serialization_result; } else { if (serialization_result.entries_count) { - base::android::RunCallbackAndroid(success_callback, - serialization_result.entries_count); + base::android::RunIntCallbackAndroid( + success_callback, serialization_result.entries_count); } else { - base::android::RunCallbackAndroid( - error_callback, base::android::ConvertUTF8ToJavaString( - base::android::AttachCurrentThread(), - logging::SystemErrorCodeToString( - serialization_result.error))); + base::android::RunStringCallbackAndroid( + error_callback, + logging::SystemErrorCodeToString(serialization_result.error)); } } break;
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc index 0cb277f4..7b661bbb 100644 --- a/chrome/browser/android/preferences/website_preference_bridge.cc +++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -705,7 +705,7 @@ env, list, host, static_cast<jint>(i->type), i->usage); } - base::android::RunCallbackAndroid(java_callback, list); + base::android::RunObjectCallbackAndroid(java_callback, list); } void OnLocalStorageCleared(const ScopedJavaGlobalRef<jobject>& java_callback) { @@ -776,7 +776,7 @@ env, map, origin, full_origin, info.size, important); } - base::android::RunCallbackAndroid(java_callback, map); + base::android::RunObjectCallbackAndroid(java_callback, map); } } // anonymous namespace
diff --git a/chrome/browser/android/rlz/rlz_ping_handler.cc b/chrome/browser/android/rlz/rlz_ping_handler.cc index e55fd0a..892679161 100644 --- a/chrome/browser/android/rlz/rlz_ping_handler.cc +++ b/chrome/browser/android/rlz/rlz_ping_handler.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/android/rlz/rlz_ping_handler.h" +#include <utility> + #include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" @@ -55,7 +57,7 @@ const base::android::JavaParamRef<jstring>& j_id, const base::android::JavaParamRef<jobject>& j_callback) { if (!j_brand || !j_language || !j_events || !j_id || !j_callback) { - base::android::RunCallbackAndroid(j_callback, false); + base::android::RunBooleanCallbackAndroid(j_callback, false); delete this; return; } @@ -146,7 +148,7 @@ // TODO(yusufo) : Investigate what else can be checked for validity that is // specific to the ping - base::android::RunCallbackAndroid(j_callback_, valid); + base::android::RunBooleanCallbackAndroid(j_callback_, valid); delete this; }
diff --git a/chrome/browser/android/rlz/rlz_ping_handler.h b/chrome/browser/android/rlz/rlz_ping_handler.h index a58c815..ae9f12f 100644 --- a/chrome/browser/android/rlz/rlz_ping_handler.h +++ b/chrome/browser/android/rlz/rlz_ping_handler.h
@@ -8,6 +8,7 @@ #include <jni.h> #include <memory> #include <string> + #include "base/android/scoped_java_ref.h" #include "base/memory/ref_counted.h"
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc index 92b751f..d3ff3cc 100644 --- a/chrome/browser/android/signin/signin_manager_android.cc +++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <vector> - #include "chrome/browser/android/signin/signin_manager_android.h" +#include <utility> +#include <vector> + #include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/android/jni_array.h" @@ -130,7 +131,7 @@ void UserManagementDomainFetched( base::android::ScopedJavaGlobalRef<jobject> callback, const std::string& dm_token, const std::string& client_id) { - base::android::RunCallbackAndroid(callback, !dm_token.empty()); + base::android::RunBooleanCallbackAndroid(callback, !dm_token.empty()); } } // namespace
diff --git a/chrome/browser/android/webapk/webapk_update_manager.cc b/chrome/browser/android/webapk/webapk_update_manager.cc index 2aecc2c7..44d5293 100644 --- a/chrome/browser/android/webapk/webapk_update_manager.cc +++ b/chrome/browser/android/webapk/webapk_update_manager.cc
@@ -31,12 +31,6 @@ namespace { -// Called after saving the update request proto either succeeds or fails. -void OnStoredUpdateRequest(const JavaRef<jobject>& java_callback, - bool success) { - base::android::RunCallbackAndroid(java_callback, success); -} - // Called after the update either succeeds or fails. void OnUpdated(const JavaRef<jobject>& java_callback, WebApkInstallResult result, @@ -128,7 +122,7 @@ base::FilePath(update_request_path), info, primary_icon, badge_icon, webapk_package, std::to_string(java_webapk_version), icon_url_to_murmur2_hash, java_is_manifest_stale, update_reason, - base::BindOnce(&OnStoredUpdateRequest, + base::BindOnce(&base::android::RunBooleanCallbackAndroid, ScopedJavaGlobalRef<jobject>(java_callback))); }
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc index 508fbb1..8b889d4 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc
@@ -18,6 +18,7 @@ #include "base/observer_list.h" #include "base/strings/utf_string_conversions.h" #include "chrome/test/base/testing_profile.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "chromeos/chromeos_switches.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/common/accessibility_helper.mojom.h" @@ -28,7 +29,6 @@ #include "ui/display/display.h" #include "ui/display/manager/managed_display_info.h" #include "ui/message_center/public/cpp/notification.h" -#include "ui/views/test/views_test_base.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -47,7 +47,7 @@ } // namespace -class ArcAccessibilityHelperBridgeTest : public views::ViewsTestBase { +class ArcAccessibilityHelperBridgeTest : public ChromeViewsTestBase { public: class TestArcAccessibilityHelperBridge : public ArcAccessibilityHelperBridge { public: @@ -117,7 +117,7 @@ ArcAccessibilityHelperBridgeTest() = default; void SetUp() override { - views::ViewsTestBase::SetUp(); + ChromeViewsTestBase::SetUp(); testing_profile_ = std::make_unique<TestingProfile>(); bridge_service_ = std::make_unique<ArcBridgeService>(); @@ -135,7 +135,7 @@ bridge_service_.reset(); testing_profile_.reset(); - views::ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } TestArcAccessibilityHelperBridge* accessibility_helper_bridge() {
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc index 110ee7b..9f92722 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
@@ -234,7 +234,7 @@ } void ArcInputMethodManagerService::RemoveArcIMEFromPrefs() { - RemoveArcIMEFromPref(prefs::kLanguageEnabledExtensionImes); + RemoveArcIMEFromPref(prefs::kLanguageEnabledImes); RemoveArcIMEFromPref(prefs::kLanguagePreloadEngines); PrefService* prefs = profile_->GetPrefs();
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc index 75c947e..b32e43e8 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -329,18 +329,15 @@ // Emulate enabling ARC IME from chrome://settings. const std::string& arc_ime_id = std::get<1>(added_extensions[0])[0].id(); - profile()->GetPrefs()->SetString(prefs::kLanguageEnabledExtensionImes, - arc_ime_id); - EXPECT_EQ(arc_ime_id, profile()->GetPrefs()->GetString( - prefs::kLanguageEnabledExtensionImes)); + profile()->GetPrefs()->SetString(prefs::kLanguageEnabledImes, arc_ime_id); + EXPECT_EQ(arc_ime_id, + profile()->GetPrefs()->GetString(prefs::kLanguageEnabledImes)); // Removing the ARC IME should clear the pref std::vector<mojom::ImeInfoPtr> empty_info_array; service()->OnImeInfoChanged(std::move(empty_info_array)); - EXPECT_TRUE(profile() - ->GetPrefs() - ->GetString(prefs::kLanguageEnabledExtensionImes) - .empty()); + EXPECT_TRUE( + profile()->GetPrefs()->GetString(prefs::kLanguageEnabledImes).empty()); added_extensions.clear(); }
diff --git a/chrome/browser/chromeos/drive/debug_info_collector.cc b/chrome/browser/chromeos/drive/debug_info_collector.cc index 1ed296b..7b339ce 100644 --- a/chrome/browser/chromeos/drive/debug_info_collector.cc +++ b/chrome/browser/chromeos/drive/debug_info_collector.cc
@@ -32,7 +32,7 @@ void RunGetResourceEntryCallback(const GetResourceEntryCallback& callback, std::unique_ptr<ResourceEntry> entry, FileError error) { - DCHECK(!callback.is_null()); + DCHECK(callback); if (error != FILE_ERROR_OK) entry.reset(); callback.Run(error, std::move(entry)); @@ -43,7 +43,7 @@ const DebugInfoCollector::ReadDirectoryCallback& callback, std::unique_ptr<ResourceEntryVector> entries, FileError error) { - DCHECK(!callback.is_null()); + DCHECK(callback); if (error != FILE_ERROR_OK) entries.reset(); callback.Run(error, std::move(entries)); @@ -62,14 +62,13 @@ DCHECK(file_system_); } -DebugInfoCollector::~DebugInfoCollector() { -} +DebugInfoCollector::~DebugInfoCollector() = default; void DebugInfoCollector::GetResourceEntry( const base::FilePath& file_path, const GetResourceEntryCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(callback); std::unique_ptr<ResourceEntry> entry(new ResourceEntry); ResourceEntry* entry_ptr = entry.get(); @@ -86,8 +85,8 @@ void DebugInfoCollector::ReadDirectory( const base::FilePath& file_path, const ReadDirectoryCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(callback); std::unique_ptr<ResourceEntryVector> entries(new ResourceEntryVector); ResourceEntryVector* entries_ptr = entries.get(); @@ -104,9 +103,9 @@ void DebugInfoCollector::IterateFileCache( const IterateFileCacheCallback& iteration_callback, const base::Closure& completion_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!iteration_callback.is_null()); - DCHECK(!completion_callback.is_null()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(iteration_callback); + DCHECK(completion_callback); blocking_task_runner_->PostTaskAndReply( FROM_HERE, @@ -117,8 +116,8 @@ void DebugInfoCollector::GetMetadata( const GetFilesystemMetadataCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(callback); // Currently, this is just a proxy to the FileSystem. // TODO(hidehiko): Move the implementation to here to simplify the
diff --git a/chrome/browser/chromeos/drive/debug_info_collector.h b/chrome/browser/chromeos/drive/debug_info_collector.h index 71cc78f..39f5fec 100644 --- a/chrome/browser/chromeos/drive/debug_info_collector.h +++ b/chrome/browser/chromeos/drive/debug_info_collector.h
@@ -58,7 +58,7 @@ FileSystemInterface* file_system_; // Not owned. scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; - base::ThreadChecker thread_checker_; + THREAD_CHECKER(thread_checker_); DISALLOW_COPY_AND_ASSIGN(DebugInfoCollector); };
diff --git a/chrome/browser/chromeos/drive/download_handler.cc b/chrome/browser/chromeos/drive/download_handler.cc index b4cae740..27a6f76 100644 --- a/chrome/browser/chromeos/drive/download_handler.cc +++ b/chrome/browser/chromeos/drive/download_handler.cc
@@ -52,7 +52,7 @@ public: explicit DriveUserData(const base::FilePath& path) : file_path_(path), is_complete_(false) {} - ~DriveUserData() override {} + ~DriveUserData() override = default; const base::FilePath& file_path() const { return file_path_; } const base::FilePath& cache_file_path() const { return cache_file_path_; } @@ -150,8 +150,7 @@ base::TimeDelta::FromSeconds(kFreeDiskSpaceDelayInSeconds)), weak_ptr_factory_(this) {} -DownloadHandler::~DownloadHandler() { -} +DownloadHandler::~DownloadHandler() = default; // static DownloadHandler* DownloadHandler::GetForProfile(Profile* profile) {
diff --git a/chrome/browser/chromeos/drive/drive_file_stream_reader.cc b/chrome/browser/chromeos/drive/drive_file_stream_reader.cc index 03986266..0b4c3ca1 100644 --- a/chrome/browser/chromeos/drive/drive_file_stream_reader.cc +++ b/chrome/browser/chromeos/drive/drive_file_stream_reader.cc
@@ -107,12 +107,11 @@ DCHECK(file_reader_); } -LocalReaderProxy::~LocalReaderProxy() { -} +LocalReaderProxy::~LocalReaderProxy() = default; int LocalReaderProxy::Read(net::IOBuffer* buffer, int buffer_length, const net::CompletionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(file_reader_); if (buffer_length > remaining_length_) { @@ -142,7 +141,7 @@ void LocalReaderProxy::OnReadCompleted(const net::CompletionCallback& callback, int read_result) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(file_reader_); if (read_result >= 0) { @@ -175,7 +174,7 @@ int NetworkReaderProxy::Read(net::IOBuffer* buffer, int buffer_length, const net::CompletionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Check if there is no pending Read operation. DCHECK(!buffer_.get()); DCHECK_EQ(buffer_length_, 0); @@ -183,7 +182,7 @@ // Validate the arguments. DCHECK(buffer); DCHECK_GT(buffer_length, 0); - DCHECK(!callback.is_null()); + DCHECK(callback); if (error_code_ != net::OK) { // An error is already found. Return it immediately. @@ -222,7 +221,7 @@ } void NetworkReaderProxy::OnGetContent(std::unique_ptr<std::string> data) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(data && !data->empty()); if (remaining_offset_ >= static_cast<int64_t>(data->length())) { @@ -257,7 +256,7 @@ } void NetworkReaderProxy::OnCompleted(FileError error) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // The downloading is completed, so we do not need to cancel the job // in the destructor. job_canceller_.Reset(); @@ -339,11 +338,10 @@ weak_ptr_factory_(this) { } -DriveFileStreamReader::~DriveFileStreamReader() { -} +DriveFileStreamReader::~DriveFileStreamReader() = default; bool DriveFileStreamReader::IsInitialized() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return reader_proxy_.get() != nullptr; } @@ -351,8 +349,8 @@ const base::FilePath& drive_file_path, const net::HttpByteRange& byte_range, const InitializeCompletionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(callback); GetFileContent( file_system_getter_, @@ -373,16 +371,16 @@ int DriveFileStreamReader::Read(net::IOBuffer* buffer, int buffer_length, const net::CompletionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(reader_proxy_); DCHECK(buffer); - DCHECK(!callback.is_null()); + DCHECK(callback); return reader_proxy_->Read(buffer, buffer_length, callback); } void DriveFileStreamReader::StoreCancelDownloadClosure( const base::Closure& cancel_download_closure) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); cancel_download_closure_ = cancel_download_closure; } @@ -392,7 +390,7 @@ FileError error, const base::FilePath& local_cache_file_path, std::unique_ptr<ResourceEntry> entry) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // StoreCancelDownloadClosure() should be called before this function. DCHECK(!cancel_download_closure_.is_null()); @@ -447,7 +445,7 @@ std::unique_ptr<ResourceEntry> entry, std::unique_ptr<util::LocalFileReader> file_reader, int open_result) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (open_result != net::OK) { callback.Run(net::ERR_FAILED, std::unique_ptr<ResourceEntry>()); @@ -462,7 +460,7 @@ void DriveFileStreamReader::OnGetContent( google_apis::DriveApiErrorCode error_code, std::unique_ptr<std::string> data) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(reader_proxy_); reader_proxy_->OnGetContent(std::move(data)); } @@ -470,7 +468,7 @@ void DriveFileStreamReader::OnGetFileContentCompletion( const InitializeCompletionCallback& callback, FileError error) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (reader_proxy_) { // If the proxy object available, send the error to it.
diff --git a/chrome/browser/chromeos/drive/drive_file_stream_reader.h b/chrome/browser/chromeos/drive/drive_file_stream_reader.h index ce7e13a..a107814b 100644 --- a/chrome/browser/chromeos/drive/drive_file_stream_reader.h +++ b/chrome/browser/chromeos/drive/drive_file_stream_reader.h
@@ -81,7 +81,7 @@ // The number of remaining bytes to be read. int64_t remaining_length_; - base::ThreadChecker thread_checker_; + THREAD_CHECKER(thread_checker_); // This should remain the last member so it'll be destroyed first and // invalidate its weak pointers before other members are destroyed. @@ -131,7 +131,7 @@ int buffer_length_; net::CompletionCallback callback_; - base::ThreadChecker thread_checker_; + THREAD_CHECKER(thread_checker_); // Keeps the closure to cancel downloading job if necessary. // Will be reset when the job is completed (regardless whether the job is @@ -222,7 +222,7 @@ base::Closure cancel_download_closure_; std::unique_ptr<internal::ReaderProxy> reader_proxy_; - base::ThreadChecker thread_checker_; + THREAD_CHECKER(thread_checker_); // This should remain the last member so it'll be destroyed first and // invalidate its weak pointers before other members are destroyed.
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc index 9a0ace36..dcdd01a6 100644 --- a/chrome/browser/chromeos/drive/drive_integration_service.cc +++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -553,7 +553,7 @@ void DriveIntegrationService::ClearCacheAndRemountFileSystem( const base::Callback<void(bool)>& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); + DCHECK(callback); // TODO(crbug.com/845393): Implement for DriveFS. if (state_ != INITIALIZED || drivefs_holder_) { @@ -589,7 +589,7 @@ const base::Callback<void(bool)>& callback, FileError error) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); + DCHECK(callback); state_ = error == FILE_ERROR_OK ? INITIALIZED : NOT_INITIALIZED; @@ -810,8 +810,7 @@ DependsOn(DownloadCoreServiceFactory::GetInstance()); } -DriveIntegrationServiceFactory::~DriveIntegrationServiceFactory() { -} +DriveIntegrationServiceFactory::~DriveIntegrationServiceFactory() = default; content::BrowserContext* DriveIntegrationServiceFactory::GetBrowserContextToUse( content::BrowserContext* context) const {
diff --git a/chrome/browser/chromeos/drive/file_system_util.cc b/chrome/browser/chromeos/drive/file_system_util.cc index aed7875..27e173f 100644 --- a/chrome/browser/chromeos/drive/file_system_util.cc +++ b/chrome/browser/chromeos/drive/file_system_util.cc
@@ -190,7 +190,7 @@ const base::FilePath& path, const PrepareWritableFileCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); + DCHECK(callback); FileSystemInterface* file_system = GetFileSystemByProfile(profile); if (!file_system || !IsUnderDriveMountPoint(path)) { @@ -209,7 +209,7 @@ const base::FilePath& directory, const FileOperationCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); + DCHECK(callback); if (IsUnderDriveMountPoint(directory)) { FileSystemInterface* file_system = GetFileSystemByProfile(profile); DCHECK(file_system);
diff --git a/chrome/browser/chromeos/drive/file_task_executor.cc b/chrome/browser/chromeos/drive/file_task_executor.cc index b0cad9e..dd9e581 100644 --- a/chrome/browser/chromeos/drive/file_task_executor.cc +++ b/chrome/browser/chromeos/drive/file_task_executor.cc
@@ -74,8 +74,7 @@ current_index_(0), weak_ptr_factory_(this) {} -FileTaskExecutor::~FileTaskExecutor() { -} +FileTaskExecutor::~FileTaskExecutor() = default; void FileTaskExecutor::Execute( const std::vector<FileSystemURL>& file_urls,
diff --git a/chrome/browser/chromeos/drive/fileapi/async_file_util.cc b/chrome/browser/chromeos/drive/fileapi/async_file_util.cc index 572b20a..ba904a59 100644 --- a/chrome/browser/chromeos/drive/fileapi/async_file_util.cc +++ b/chrome/browser/chromeos/drive/fileapi/async_file_util.cc
@@ -110,11 +110,9 @@ } // namespace -AsyncFileUtil::AsyncFileUtil() { -} +AsyncFileUtil::AsyncFileUtil() = default; -AsyncFileUtil::~AsyncFileUtil() { -} +AsyncFileUtil::~AsyncFileUtil() = default; void AsyncFileUtil::CreateOrOpen( std::unique_ptr<storage::FileSystemOperationContext> context,
diff --git a/chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.cc b/chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.cc index fd0339d..e1954149 100644 --- a/chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.cc +++ b/chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.cc
@@ -75,8 +75,7 @@ : async_file_util_(new internal::AsyncFileUtil) { } -FileSystemBackendDelegate::~FileSystemBackendDelegate() { -} +FileSystemBackendDelegate::~FileSystemBackendDelegate() = default; storage::AsyncFileUtil* FileSystemBackendDelegate::GetAsyncFileUtil( storage::FileSystemType type) {
diff --git a/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.cc b/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.cc index 76031bc..47954ea 100644 --- a/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.cc +++ b/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.cc
@@ -36,8 +36,7 @@ DCHECK_GE(offset, 0); } -WebkitFileStreamReaderImpl::~WebkitFileStreamReaderImpl() { -} +WebkitFileStreamReaderImpl::~WebkitFileStreamReaderImpl() = default; int WebkitFileStreamReaderImpl::Read(net::IOBuffer* buffer, int buffer_length, @@ -45,7 +44,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(stream_reader_); DCHECK(buffer); - DCHECK(!callback.is_null()); + DCHECK(callback); if (stream_reader_->IsInitialized()) return stream_reader_->Read(buffer, buffer_length, callback); @@ -68,7 +67,7 @@ const net::Int64CompletionCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(stream_reader_); - DCHECK(!callback.is_null()); + DCHECK(callback); if (stream_reader_->IsInitialized()) { // Returns file_size regardless of |offset_|. @@ -95,7 +94,7 @@ std::unique_ptr<ResourceEntry> entry) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(stream_reader_); - DCHECK(!callback.is_null()); + DCHECK(callback); // TODO(hashimoto): Report ERR_UPLOAD_FILE_CHANGED when modification time // doesn't match. crbug.com/346625 @@ -117,7 +116,7 @@ const net::CompletionCallback& callback, int initialization_result) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(!callback.is_null()); + DCHECK(callback); if (initialization_result != net::OK) { callback.Run(initialization_result); @@ -134,7 +133,7 @@ const net::Int64CompletionCallback& callback, int initialization_result) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(!callback.is_null()); + DCHECK(callback); if (initialization_result != net::OK) { callback.Run(initialization_result);
diff --git a/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc b/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc index 878d3e5..06bb3e7 100644 --- a/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc +++ b/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc
@@ -68,7 +68,7 @@ const net::CompletionCallback& callback) { DCHECK(pending_write_callback_.is_null()); DCHECK(pending_cancel_callback_.is_null()); - DCHECK(!callback.is_null()); + DCHECK(callback); // If the local file is already available, just delegate to it. if (local_file_writer_) @@ -90,7 +90,7 @@ int WebkitFileStreamWriterImpl::Cancel( const net::CompletionCallback& callback) { DCHECK(pending_cancel_callback_.is_null()); - DCHECK(!callback.is_null()); + DCHECK(callback); // If LocalFileWriter is already created, just delegate the cancel to it. if (local_file_writer_) @@ -111,7 +111,7 @@ int WebkitFileStreamWriterImpl::Flush(const net::CompletionCallback& callback) { DCHECK(pending_cancel_callback_.is_null()); - DCHECK(!callback.is_null()); + DCHECK(callback); // If LocalFileWriter is already created, just delegate to it. if (local_file_writer_)
diff --git a/chrome/browser/chromeos/drive/write_on_cache_file.cc b/chrome/browser/chromeos/drive/write_on_cache_file.cc index 3de477a..91ba925c 100644 --- a/chrome/browser/chromeos/drive/write_on_cache_file.cc +++ b/chrome/browser/chromeos/drive/write_on_cache_file.cc
@@ -22,7 +22,7 @@ FileError error) { if (!close_callback.is_null()) close_callback.Run(); - DCHECK(!reply.is_null()); + DCHECK(reply); reply.Run(error); } @@ -61,8 +61,8 @@ const FileOperationCallback& reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(file_system); - DCHECK(!callback.is_null()); - DCHECK(!reply.is_null()); + DCHECK(callback); + DCHECK(reply); file_system->OpenFile( path,
diff --git a/chrome/browser/chromeos/input_method/input_method_syncer.cc b/chrome/browser/chromeos/input_method/input_method_syncer.cc index ccc3049..987fd20 100644 --- a/chrome/browser/chromeos/input_method/input_method_syncer.cc +++ b/chrome/browser/chromeos/input_method/input_method_syncer.cc
@@ -135,10 +135,8 @@ prefs::kLanguagePreloadEnginesSyncable, "", user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); - registry->RegisterStringPref( - prefs::kLanguageEnabledExtensionImesSyncable, - "", - user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterStringPref(prefs::kLanguageEnabledImesSyncable, "", + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref(prefs::kLanguageShouldMergeInputMethods, false); } @@ -151,8 +149,7 @@ prefs_); preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable, prefs_); - enabled_extension_imes_syncable_.Init( - prefs::kLanguageEnabledExtensionImesSyncable, prefs_); + enabled_imes_syncable_.Init(prefs::kLanguageEnabledImesSyncable, prefs_); BooleanPrefMember::NamedChangeCallback callback = base::Bind(&InputMethodSyncer::OnPreferenceChanged, @@ -161,14 +158,13 @@ prefs_, callback); preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs_, callback); - enabled_extension_imes_.Init( - prefs::kLanguageEnabledExtensionImes, prefs_, callback); + enabled_imes_.Init(prefs::kLanguageEnabledImes, prefs_, callback); // If we have already synced but haven't merged input methods yet, do so now. if (prefs_->GetBoolean(prefs::kLanguageShouldMergeInputMethods) && !(preferred_languages_syncable_.GetValue().empty() && preload_engines_syncable_.GetValue().empty() && - enabled_extension_imes_syncable_.GetValue().empty())) { + enabled_imes_syncable_.GetValue().empty())) { MergeSyncedPrefs(); } } @@ -196,17 +192,15 @@ MergeLists(&new_tokens, synced_tokens); preferred_languages_syncable_.SetValue(base::JoinString(new_tokens, ",")); - std::string enabled_extension_imes_syncable = - enabled_extension_imes_syncable_.GetValue(); - synced_tokens = - base::SplitStringPiece(enabled_extension_imes_syncable, ",", - base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - std::string enabled_extension_imes = enabled_extension_imes_.GetValue(); - new_tokens = base::SplitStringPiece( - enabled_extension_imes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + std::string enabled_imes_syncable = enabled_imes_syncable_.GetValue(); + synced_tokens = base::SplitStringPiece( + enabled_imes_syncable, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + std::string enabled_imes = enabled_imes_.GetValue(); + new_tokens = base::SplitStringPiece(enabled_imes, ",", base::TRIM_WHITESPACE, + base::SPLIT_WANT_ALL); MergeLists(&new_tokens, synced_tokens); - enabled_extension_imes_syncable_.SetValue(base::JoinString(new_tokens, ",")); + enabled_imes_syncable_.SetValue(base::JoinString(new_tokens, ",")); // Revert preload engines to legacy component IDs. std::string preload_engines = preload_engines_.GetValue(); @@ -231,10 +225,9 @@ AddSupportedInputMethodValues(preload_engines_.GetValue(), preload_engines_syncable, prefs::kLanguagePreloadEngines)); - enabled_extension_imes_.SetValue( - AddSupportedInputMethodValues(enabled_extension_imes_.GetValue(), - enabled_extension_imes_syncable, - prefs::kLanguageEnabledExtensionImes)); + enabled_imes_.SetValue(AddSupportedInputMethodValues( + enabled_imes_.GetValue(), enabled_imes_syncable, + prefs::kLanguageEnabledImes)); // Remove unsupported locales before updating the local languages preference. std::string languages( @@ -258,7 +251,7 @@ // Check and convert the new tokens. if (pref_name == prefs::kLanguagePreloadEngines || - pref_name == prefs::kLanguageEnabledExtensionImes) { + pref_name == prefs::kLanguageEnabledImes) { input_method::InputMethodManager* manager = input_method::InputMethodManager::Get(); std::unique_ptr<input_method::InputMethodDescriptors> supported_descriptors; @@ -305,7 +298,7 @@ void InputMethodSyncer::OnPreferenceChanged(const std::string& pref_name) { DCHECK(pref_name == prefs::kLanguagePreferredLanguages || pref_name == prefs::kLanguagePreloadEngines || - pref_name == prefs::kLanguageEnabledExtensionImes); + pref_name == prefs::kLanguageEnabledImes); if (merging_ || prefs_->GetBoolean(prefs::kLanguageShouldMergeInputMethods)) return; @@ -313,7 +306,7 @@ // Set the language and input prefs at the same time. Otherwise we may, // e.g., use a stale languages setting but push a new preload engines setting. preferred_languages_syncable_.SetValue(preferred_languages_.GetValue()); - enabled_extension_imes_syncable_.SetValue(enabled_extension_imes_.GetValue()); + enabled_imes_syncable_.SetValue(enabled_imes_.GetValue()); // For preload engines, use legacy xkb IDs so the preference can sync // across Chrome OS and Chromium OS.
diff --git a/chrome/browser/chromeos/input_method/input_method_syncer.h b/chrome/browser/chromeos/input_method/input_method_syncer.h index 0757b01b..f570d1c 100644 --- a/chrome/browser/chromeos/input_method/input_method_syncer.h +++ b/chrome/browser/chromeos/input_method/input_method_syncer.h
@@ -70,14 +70,14 @@ StringPrefMember preferred_languages_; StringPrefMember preload_engines_; - StringPrefMember enabled_extension_imes_; + StringPrefMember enabled_imes_; // These are syncable variants which don't change the device settings. We can // set these to keep track of the user's most recent choices. That way, after // the initial sync, we can add the user's synced choices to the values that // have already been chosen at OOBE. StringPrefMember preferred_languages_syncable_; StringPrefMember preload_engines_syncable_; - StringPrefMember enabled_extension_imes_syncable_; + StringPrefMember enabled_imes_syncable_; sync_preferences::PrefServiceSyncable* prefs_; scoped_refptr<input_method::InputMethodManager::State> ime_state_;
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 7a25af0..053e7f7 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -314,7 +314,7 @@ kFallbackInputMethodLocale); registry->RegisterStringPref(prefs::kLanguagePreloadEngines, hardware_keyboard_id); - registry->RegisterStringPref(prefs::kLanguageEnabledExtensionImes, ""); + registry->RegisterStringPref(prefs::kLanguageEnabledImes, ""); registry->RegisterIntegerPref( prefs::kLanguageRemapSearchKeyTo, @@ -502,8 +502,7 @@ download_default_directory_.Init(prefs::kDownloadDefaultDirectory, prefs, callback); preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, callback); - enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes, - prefs, callback); + enabled_imes_.Init(prefs::kLanguageEnabledImes, prefs, callback); current_input_method_.Init(prefs::kLanguageCurrentInputMethod, prefs, callback); previous_input_method_.Init(prefs::kLanguagePreviousInputMethod, @@ -784,9 +783,9 @@ } if ((reason == REASON_INITIALIZATION) || - (pref_name == prefs::kLanguageEnabledExtensionImes && + (pref_name == prefs::kLanguageEnabledImes && reason == REASON_PREF_CHANGED)) { - std::string value(enabled_extension_imes_.GetValue()); + std::string value(enabled_imes_.GetValue()); std::vector<std::string> split_values; if (!value.empty()) {
diff --git a/chrome/browser/chromeos/preferences.h b/chrome/browser/chromeos/preferences.h index c394702..931d0d5 100644 --- a/chrome/browser/chromeos/preferences.h +++ b/chrome/browser/chromeos/preferences.h
@@ -133,7 +133,7 @@ StringPrefMember previous_input_method_; StringListPrefMember allowed_input_methods_; - StringPrefMember enabled_extension_imes_; + StringPrefMember enabled_imes_; BooleanPrefMember ime_menu_activated_; BooleanPrefMember xkb_auto_repeat_enabled_;
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc index 5139b60..a0c61b2a 100644 --- a/chrome/browser/chromeos/preferences_unittest.cc +++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -232,10 +232,9 @@ preload_engines_.Init(prefs::kLanguagePreloadEngines, pref_service_); preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable, pref_service_); - enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes, - pref_service_); - enabled_extension_imes_syncable_.Init( - prefs::kLanguageEnabledExtensionImesSyncable, pref_service_); + enabled_imes_.Init(prefs::kLanguageEnabledImes, pref_service_); + enabled_imes_syncable_.Init(prefs::kLanguageEnabledImesSyncable, + pref_service_); // Initialize component and 3rd-party input method extensions. InitComponentExtensionIMEManager(); @@ -295,38 +294,37 @@ // Helper function to set local language and input values. void SetLocalValues(const std::string& preferred_languages, const std::string& preload_engines, - const std::string& enabled_extension_imes) { + const std::string& enabled_imes) { preferred_languages_.SetValue(preferred_languages); preload_engines_.SetValue(preload_engines); - enabled_extension_imes_.SetValue(enabled_extension_imes); + enabled_imes_.SetValue(enabled_imes); } // Helper function to set global language and input values. void SetGlobalValues(const std::string& preferred_languages, const std::string& preload_engines, - const std::string& enabled_extension_imes) { + const std::string& enabled_imes) { preferred_languages_syncable_.SetValue(preferred_languages); preload_engines_syncable_.SetValue(preload_engines); - enabled_extension_imes_syncable_.SetValue(enabled_extension_imes); + enabled_imes_syncable_.SetValue(enabled_imes); } // Helper function to check local language and input values. void ExpectLocalValues(const std::string& preferred_languages, const std::string& preload_engines, - const std::string& enabled_extension_imes) { + const std::string& enabled_imes) { EXPECT_EQ(preferred_languages, preferred_languages_.GetValue()); EXPECT_EQ(preload_engines, preload_engines_.GetValue()); - EXPECT_EQ(enabled_extension_imes, enabled_extension_imes_.GetValue()); + EXPECT_EQ(enabled_imes, enabled_imes_.GetValue()); } // Helper function to check global language and input values. void ExpectGlobalValues(const std::string& preferred_languages, const std::string& preload_engines, - const std::string& enabled_extension_imes) { + const std::string& enabled_imes) { EXPECT_EQ(preferred_languages, preferred_languages_syncable_.GetValue()); EXPECT_EQ(preload_engines, preload_engines_syncable_.GetValue()); - EXPECT_EQ(enabled_extension_imes, - enabled_extension_imes_syncable_.GetValue()); + EXPECT_EQ(enabled_imes, enabled_imes_syncable_.GetValue()); } // Translates engine IDs in a CSV string to input method IDs. @@ -342,8 +340,8 @@ StringPrefMember preferred_languages_syncable_; StringPrefMember preload_engines_; StringPrefMember preload_engines_syncable_; - StringPrefMember enabled_extension_imes_; - StringPrefMember enabled_extension_imes_syncable_; + StringPrefMember enabled_imes_; + StringPrefMember enabled_imes_syncable_; private: DISALLOW_COPY_AND_ASSIGN(InputMethodPreferencesTest); @@ -369,9 +367,8 @@ prefs::kLanguagePreferredLanguagesSyncable, base::Value("ru,fi"))); sync_data_list.push_back(CreatePrefSyncData( prefs::kLanguagePreloadEnginesSyncable, base::Value("xkb:se::swe"))); - sync_data_list.push_back( - CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable, - base::Value(kIdentityIMEID))); + sync_data_list.push_back(CreatePrefSyncData( + prefs::kLanguageEnabledImesSyncable, base::Value(kIdentityIMEID))); // Sync for the first time. syncer::SyncableService* sync = @@ -413,10 +410,10 @@ FROM_HERE, syncer::SyncChange::ACTION_UPDATE, CreatePrefSyncData(prefs::kLanguagePreloadEnginesSyncable, base::Value(ToInputMethodIds("xkb:de::ger"))))); - change_list.push_back(syncer::SyncChange( - FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable, - base::Value(kToUpperIMEID)))); + change_list.push_back( + syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, + CreatePrefSyncData(prefs::kLanguageEnabledImesSyncable, + base::Value(kToUpperIMEID)))); sync->ProcessSyncChanges(FROM_HERE, change_list); content::RunAllTasksUntilIdle(); @@ -456,8 +453,8 @@ sync_data_list.push_back( CreatePrefSyncData(prefs::kLanguagePreloadEngines, base::Value(ToInputMethodIds("xkb:ru::rus")))); - sync_data_list.push_back(CreatePrefSyncData( - prefs::kLanguageEnabledExtensionImes, base::Value(kIdentityIMEID))); + sync_data_list.push_back(CreatePrefSyncData(prefs::kLanguageEnabledImes, + base::Value(kIdentityIMEID))); // Sync. syncer::SyncableService* sync = @@ -496,9 +493,8 @@ sync_data_list.push_back( CreatePrefSyncData(prefs::kLanguagePreloadEnginesSyncable, base::Value(ToInputMethodIds("xkb:ru::rus")))); - sync_data_list.push_back( - CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable, - base::Value(kToUpperIMEID))); + sync_data_list.push_back(CreatePrefSyncData( + prefs::kLanguageEnabledImesSyncable, base::Value(kToUpperIMEID))); syncer::SyncableService* sync = pref_service_->GetSyncableService( @@ -553,9 +549,8 @@ prefs::kLanguagePreloadEnginesSyncable, base::Value( "nacl_mozc_us,xkb:ru::rus,xkb:ru::rus,xkb:es::spa,xkb:es::spa"))); - sync_data_list.push_back( - CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable, - base::Value(std::string()))); + sync_data_list.push_back(CreatePrefSyncData( + prefs::kLanguageEnabledImesSyncable, base::Value(std::string()))); // Sync for the first time. syncer::SyncableService* sync = @@ -604,9 +599,8 @@ base::Value("klingon,en-US"))); sync_data_list.push_back(CreatePrefSyncData( prefs::kLanguagePreloadEnginesSyncable, base::Value(preload_engines))); - sync_data_list.push_back( - CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable, - base::Value(kUnknownIMEID))); + sync_data_list.push_back(CreatePrefSyncData( + prefs::kLanguageEnabledImesSyncable, base::Value(kUnknownIMEID))); // Sync for the first time. syncer::SyncableService* sync = @@ -644,9 +638,8 @@ prefs::kLanguagePreferredLanguagesSyncable, base::Value("en-US"))); sync_data_list.push_back(CreatePrefSyncData( prefs::kLanguagePreloadEnginesSyncable, base::Value(preload_engines))); - sync_data_list.push_back( - CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable, - base::Value(kUnknownIMEID))); + sync_data_list.push_back(CreatePrefSyncData( + prefs::kLanguageEnabledImesSyncable, base::Value(kUnknownIMEID))); // Sync for the first time. syncer::SyncableService* sync =
diff --git a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc index 5498a19c..6e38db8f 100644 --- a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc +++ b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
@@ -134,9 +134,8 @@ using DistillablePageUtilsBrowserTestAlways = DistillablePageUtilsBrowserTestOption<kAlwaysTrue>; -// This test should be updated to use QuitClosure. See crbug.com/859151. IN_PROC_BROWSER_TEST_F(DistillablePageUtilsBrowserTestAlways, - DISABLED_TestDelegate) { + TestDelegate) { for (unsigned i = 0; i < sizeof(kAllPaths) / sizeof(kAllPaths[0]); ++i) { testing::InSequence dummy; EXPECT_CALL(holder_, OnResult(true, true, _))
diff --git a/chrome/browser/engagement/site_engagement_helper.cc b/chrome/browser/engagement/site_engagement_helper.cc index a02482e..4e11f961 100644 --- a/chrome/browser/engagement/site_engagement_helper.cc +++ b/chrome/browser/engagement/site_engagement_helper.cc
@@ -67,7 +67,7 @@ SiteEngagementService::Helper::PeriodicTracker::PeriodicTracker( SiteEngagementService::Helper* helper) - : helper_(helper), pause_timer_(new base::Timer(true, false)) {} + : helper_(helper), pause_timer_(new base::OneShotTimer()) {} SiteEngagementService::Helper::PeriodicTracker::~PeriodicTracker() {} @@ -92,7 +92,7 @@ } void SiteEngagementService::Helper::PeriodicTracker::SetPauseTimerForTesting( - std::unique_ptr<base::Timer> timer) { + std::unique_ptr<base::OneShotTimer> timer) { pause_timer_ = std::move(timer); }
diff --git a/chrome/browser/engagement/site_engagement_helper.h b/chrome/browser/engagement/site_engagement_helper.h index 26989252..6a7db7d 100644 --- a/chrome/browser/engagement/site_engagement_helper.h +++ b/chrome/browser/engagement/site_engagement_helper.h
@@ -65,7 +65,7 @@ bool IsTimerRunning(); // Set the timer object for testing. - void SetPauseTimerForTesting(std::unique_ptr<base::Timer> timer); + void SetPauseTimerForTesting(std::unique_ptr<base::OneShotTimer> timer); SiteEngagementService::Helper* helper() { return helper_; } @@ -84,7 +84,7 @@ private: SiteEngagementService::Helper* helper_; - std::unique_ptr<base::Timer> pause_timer_; + std::unique_ptr<base::OneShotTimer> pause_timer_; DISALLOW_COPY_AND_ASSIGN(PeriodicTracker); };
diff --git a/chrome/browser/engagement/site_engagement_helper_unittest.cc b/chrome/browser/engagement/site_engagement_helper_unittest.cc index 52b96f4..53f213c 100644 --- a/chrome/browser/engagement/site_engagement_helper_unittest.cc +++ b/chrome/browser/engagement/site_engagement_helper_unittest.cc
@@ -78,13 +78,13 @@ // Set a pause timer on the input tracker for test purposes. void SetInputTrackerPauseTimer(SiteEngagementService::Helper* helper, - std::unique_ptr<base::Timer> timer) { + std::unique_ptr<base::OneShotTimer> timer) { helper->input_tracker_.SetPauseTimerForTesting(std::move(timer)); } // Set a pause timer on the input tracker for test purposes. void SetMediaTrackerPauseTimer(SiteEngagementService::Helper* helper, - std::unique_ptr<base::Timer> timer) { + std::unique_ptr<base::OneShotTimer> timer) { helper->media_tracker_.SetPauseTimerForTesting(std::move(timer)); } @@ -209,7 +209,7 @@ GURL url2("http://www.google.com/"); content::WebContents* contents = web_contents(); - base::MockTimer* media_tracker_timer = new base::MockTimer(true, false); + base::MockOneShotTimer* media_tracker_timer = new base::MockOneShotTimer(); SiteEngagementService::Helper* helper = GetHelper(contents); SetMediaTrackerPauseTimer(helper, base::WrapUnique(media_tracker_timer)); SiteEngagementService* service = SiteEngagementService::Get(profile()); @@ -387,8 +387,8 @@ GURL url2("http://www.google.com/"); content::WebContents* contents = web_contents(); - base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); - base::MockTimer* media_tracker_timer = new base::MockTimer(true, false); + base::MockOneShotTimer* input_tracker_timer = new base::MockOneShotTimer; + base::MockOneShotTimer* media_tracker_timer = new base::MockOneShotTimer; SiteEngagementService::Helper* helper = GetHelper(contents); SetInputTrackerPauseTimer(helper, base::WrapUnique(input_tracker_timer)); SetMediaTrackerPauseTimer(helper, base::WrapUnique(media_tracker_timer)); @@ -494,8 +494,8 @@ GURL url2("http://www.google.com/"); content::WebContents* contents = web_contents(); - base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); - base::MockTimer* media_tracker_timer = new base::MockTimer(true, false); + base::MockOneShotTimer* input_tracker_timer = new base::MockOneShotTimer(); + base::MockOneShotTimer* media_tracker_timer = new base::MockOneShotTimer(); SiteEngagementService::Helper* helper = GetHelper(contents); SetInputTrackerPauseTimer(helper, base::WrapUnique(input_tracker_timer)); SetMediaTrackerPauseTimer(helper, base::WrapUnique(media_tracker_timer)); @@ -545,7 +545,7 @@ // - Handles a hidden <-> occluded transition like a hidden <-> visible // transition. TEST_F(SiteEngagementHelperTest, Occlusion) { - base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); + base::MockOneShotTimer* input_tracker_timer = new base::MockOneShotTimer(); SiteEngagementService::Helper* helper = GetHelper(web_contents()); SetInputTrackerPauseTimer(helper, base::WrapUnique(input_tracker_timer)); @@ -595,7 +595,7 @@ GURL url2("https://www.example.com/"); content::WebContents* contents = web_contents(); - base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); + base::MockOneShotTimer* input_tracker_timer = new base::MockOneShotTimer(); SiteEngagementService::Helper* helper = GetHelper(contents); SetInputTrackerPauseTimer(helper, base::WrapUnique(input_tracker_timer));
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index ddc74ff..e3a17ea 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -802,8 +802,10 @@ "//chrome/app/theme:theme_resources", "//chrome/app/vector_icons", "//chrome/browser/devtools", + "//chrome/browser/engagement:mojo_bindings", "//chrome/browser/media/router", "//chrome/browser/media/router/discovery", + "//chrome/browser/resource_coordinator:mojo_bindings", "//chrome/browser/safe_browsing", "//chrome/common", "//chrome/common/extensions:mojo_bindings",
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc index dd2042b..1b291578 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.cc +++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -117,15 +117,20 @@ const PermissionsData* permissions_data = extension->permissions_data(); - // If the extension requested all-hosts but has had it withheld, we grant it - // active tab-style permissions, even if it doesn't have the activeTab - // permission in the manifest. + // TODO(devlin): This should be GetLastCommittedURL(). + GURL url = web_contents()->GetVisibleURL(); + + // If the extension requested the host permission to |url| but had it + // withheld, we grant it active tab-style permissions, even if it doesn't have + // the activeTab permission in the manifest. This is necessary for the + // runtime host permissions feature to work. // Note: It's important that we check if the extension has activeTab before // checking ShouldGrantActiveTabOrPrompt() in order to prevent // ShouldGrantActiveTabOrPrompt() from prompting for extensions that don't // request the activeTab permission. - if ((permissions_data->HasWithheldImpliedAllHosts() || - permissions_data->HasAPIPermission(APIPermission::kActiveTab)) && + if ((permissions_data->HasAPIPermission(APIPermission::kActiveTab) || + permissions_data->withheld_permissions().effective_hosts().MatchesURL( + url)) && ShouldGrantActiveTabOrPrompt(extension, web_contents())) { // Gate activeTab for file urls on extensions having explicit access to file // urls. @@ -134,8 +139,7 @@ web_contents()->GetBrowserContext())) { valid_schemes &= ~URLPattern::SCHEME_FILE; } - new_hosts.AddOrigin(valid_schemes, - web_contents()->GetVisibleURL().GetOrigin()); + new_hosts.AddOrigin(valid_schemes, url.GetOrigin()); new_apis.insert(APIPermission::kTab); }
diff --git a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc index dc1b40d..665d030 100644 --- a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc +++ b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -444,7 +444,7 @@ params->opt_args.additional_properties, &replace_selected_text_params)); action->action = ax::mojom::Action::kReplaceSelectedText; - action->value = base::UTF8ToUTF16(replace_selected_text_params.value); + action->value = replace_selected_text_params.value; break; } case api::automation::ACTION_TYPE_SETVALUE: { @@ -453,7 +453,7 @@ api::automation_internal::SetValueParams::Populate( params->opt_args.additional_properties, &set_value_params)); action->action = ax::mojom::Action::kSetValue; - action->value = base::UTF8ToUTF16(set_value_params.value); + action->value = set_value_params.value; break; } // These actions are currently unused by any existing clients of
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc index f579a85..c03f35b 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -870,7 +870,7 @@ ScriptingPermissionsModifier modifier(browser_context(), extension); if (!modifier.CanAffectExtension()) return RespondNow(Error(kCannotChangeHostPermissions)); - modifier.SetWithholdAllUrls(!(*update.run_on_all_urls)); + modifier.SetWithholdHostPermissions(!(*update.run_on_all_urls)); } return RespondNow(NoArguments());
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc index 484ae6e..f020d18 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -85,7 +85,8 @@ bool HasAllUrlsPermission(const Extension* extension, content::BrowserContext* context) { - return !ScriptingPermissionsModifier(context, extension).HasWithheldAllUrls(); + return !ScriptingPermissionsModifier(context, extension) + .HasWithheldHostPermissions(); } bool HasPrefsPermission(bool (*has_pref)(const std::string&, @@ -369,7 +370,7 @@ const std::string& id = extension->id(); ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension)) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); TestExtensionPrefSetting( base::Bind(&HasPrefsPermission, &util::IsIncognitoEnabled, profile(), id), @@ -1309,8 +1310,8 @@ ExtensionBuilder("test").AddPermission("<all_urls>").Build(); service()->AddExtension(extension.get()); ScriptingPermissionsModifier modifier(profile(), extension.get()); - EXPECT_FALSE(modifier.HasWithheldAllUrls()); - modifier.SetWithholdAllUrls(true); + EXPECT_FALSE(modifier.HasWithheldHostPermissions()); + modifier.SetWithholdHostPermissions(true); auto run_add_host_permission = [this, extension](base::StringPiece host, bool should_succeed, @@ -1354,8 +1355,8 @@ ExtensionBuilder("test").AddPermission("<all_urls>").Build(); service()->AddExtension(extension.get()); ScriptingPermissionsModifier modifier(profile(), extension.get()); - EXPECT_FALSE(modifier.HasWithheldAllUrls()); - modifier.SetWithholdAllUrls(true); + EXPECT_FALSE(modifier.HasWithheldHostPermissions()); + modifier.SetWithholdHostPermissions(true); auto run_remove_host_permission = [this, extension]( base::StringPiece host,
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc index a4a9769..eb7997f 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
@@ -534,8 +534,9 @@ ScriptingPermissionsModifier permissions_modifier( browser_context_, base::WrapRefCounted(&extension)); info->run_on_all_urls.is_enabled = permissions_modifier.CanAffectExtension(); - info->run_on_all_urls.is_active = info->run_on_all_urls.is_enabled && - !permissions_modifier.HasWithheldAllUrls(); + info->run_on_all_urls.is_active = + info->run_on_all_urls.is_enabled && + !permissions_modifier.HasWithheldHostPermissions(); // Runtime warnings. std::vector<std::string> warnings =
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc index 8921aaa..5aa2c93 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
@@ -412,7 +412,7 @@ // Revoke the all urls permission. ScriptingPermissionsModifier permissions_modifier(profile(), all_urls_extension); - permissions_modifier.SetWithholdAllUrls(true); + permissions_modifier.SetWithholdHostPermissions(true); // Now the extension want all urls, but not have it granted. info = GenerateExtensionInfo(all_urls_extension->id());
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index 7a82ed16..22c00c0 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
@@ -134,11 +134,11 @@ } // Sorts the third-party IMEs by the order of their associated languages. -std::vector<std::string> GetSortedExtensionIMEs( +std::vector<std::string> GetSortedThirdPartyIMEs( scoped_refptr<InputMethodManager::State> ime_state, - const std::unordered_set<std::string>& extension_ime_set, + const std::unordered_set<std::string>& third_party_ime_set, PrefService* prefs) { - std::vector<std::string> extension_ime_list; + std::vector<std::string> ime_list; std::string preferred_languages = prefs->GetString(prefs::kLanguagePreferredLanguages); std::vector<std::string> enabled_languages = @@ -152,10 +152,10 @@ InputMethodDescriptors descriptors; ime_state->GetInputMethodExtensions(&descriptors); - // Filter out the IMEs not in |extension_ime_set|. + // Filter out the IMEs not in |third_party_ime_set|. auto it = descriptors.begin(); while (it != descriptors.end()) { - if (extension_ime_set.count(it->id()) == 0) + if (third_party_ime_set.count(it->id()) == 0) it = descriptors.erase(it); else it++; @@ -165,9 +165,9 @@ for (const auto& language : enabled_languages) { auto it = descriptors.begin(); while (it != descriptors.end() && descriptors.size()) { - if (extension_ime_set.count(it->id()) && + if (third_party_ime_set.count(it->id()) && base::ContainsValue(it->language_codes(), language)) { - extension_ime_list.push_back(it->id()); + ime_list.push_back(it->id()); // Remove the added descriptor from the candidate list. it = descriptors.erase(it); } else { @@ -176,7 +176,7 @@ } } - return extension_ime_list; + return ime_list; } } // namespace @@ -635,7 +635,7 @@ PrefService* prefs = chrome_details_.GetProfile()->GetPrefs(); const char* pref_name = is_component_extension_ime ? prefs::kLanguagePreloadEngines - : prefs::kLanguageEnabledExtensionImes; + : prefs::kLanguageEnabledImes; // Get the input methods we are adding to. std::unordered_set<std::string> input_method_set( @@ -651,7 +651,7 @@ GetSortedComponentIMEs(manager, ime_state, input_method_set, prefs); } else { input_method_list = - GetSortedExtensionIMEs(ime_state, input_method_set, prefs); + GetSortedThirdPartyIMEs(ime_state, input_method_set, prefs); } std::string input_methods = base::JoinString(input_method_list, ","); @@ -690,7 +690,7 @@ PrefService* prefs = chrome_details_.GetProfile()->GetPrefs(); const char* pref_name = is_component_extension_ime ? prefs::kLanguagePreloadEngines - : prefs::kLanguageEnabledExtensionImes; + : prefs::kLanguageEnabledImes; std::string input_method_ids = prefs->GetString(pref_name); std::vector<std::string> input_method_list = base::SplitString(
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc index c964b72a..e112824 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
@@ -236,26 +236,25 @@ // Initialize relevant prefs. profile()->GetPrefs()->SetString(prefs::kLanguagePreferredLanguages, "en-US"); - StringPrefMember enabled_extension_imes; - enabled_extension_imes.Init(prefs::kLanguageEnabledExtensionImes, - profile()->GetPrefs()); + StringPrefMember enabled_imes; + enabled_imes.Init(prefs::kLanguageEnabledImes, profile()->GetPrefs()); StringPrefMember preload_engines; preload_engines.Init(prefs::kLanguagePreloadEngines, profile()->GetPrefs()); - enabled_extension_imes.SetValue(std::string()); + enabled_imes.SetValue(std::string()); preload_engines.SetValue(std::string()); { - // Add an extension IME. kLanguageEnabledExtensionImes should be updated. + // Add an extension IME. kLanguageEnabledImes should be updated. auto function = base::MakeRefCounted<LanguageSettingsPrivateAddInputMethodFunction>(); api_test_utils::RunFunctionAndReturnSingleResult( function.get(), "[\"" + GetExtensionImeId() + "\"]", profile()); - EXPECT_EQ(GetExtensionImeId(), enabled_extension_imes.GetValue()); + EXPECT_EQ(GetExtensionImeId(), enabled_imes.GetValue()); EXPECT_TRUE(preload_engines.GetValue().empty()); } - enabled_extension_imes.SetValue(std::string()); + enabled_imes.SetValue(std::string()); preload_engines.SetValue(std::string()); { // Add a component extension IME. kLanguagePreloadEngines should be @@ -266,20 +265,20 @@ function.get(), "[\"" + GetComponentExtensionImeId() + "\"]", profile()); - EXPECT_TRUE(enabled_extension_imes.GetValue().empty()); + EXPECT_TRUE(enabled_imes.GetValue().empty()); EXPECT_EQ(GetComponentExtensionImeId(), preload_engines.GetValue()); } - enabled_extension_imes.SetValue(std::string()); + enabled_imes.SetValue(std::string()); preload_engines.SetValue(std::string()); { - // Add an ARC IME. kLanguageEnabledExtensionImes should be updated. + // Add an ARC IME. kLanguageEnabledImes should be updated. auto function = base::MakeRefCounted<LanguageSettingsPrivateAddInputMethodFunction>(); api_test_utils::RunFunctionAndReturnSingleResult( function.get(), "[\"" + GetArcImeId() + "\"]", profile()); - EXPECT_EQ(GetArcImeId(), enabled_extension_imes.GetValue()); + EXPECT_EQ(GetArcImeId(), enabled_imes.GetValue()); EXPECT_TRUE(preload_engines.GetValue().empty()); } @@ -290,13 +289,12 @@ TestInputMethodManager::Initialize(new TestInputMethodManager); // Initialize relevant prefs. - StringPrefMember enabled_extension_imes; - enabled_extension_imes.Init(prefs::kLanguageEnabledExtensionImes, - profile()->GetPrefs()); + StringPrefMember enabled_imes; + enabled_imes.Init(prefs::kLanguageEnabledImes, profile()->GetPrefs()); StringPrefMember preload_engines; preload_engines.Init(prefs::kLanguagePreloadEngines, profile()->GetPrefs()); - enabled_extension_imes.SetValue( + enabled_imes.SetValue( base::JoinString({GetExtensionImeId(), GetArcImeId()}, ",")); preload_engines.SetValue(GetComponentExtensionImeId()); { @@ -306,7 +304,7 @@ api_test_utils::RunFunctionAndReturnSingleResult( function.get(), "[\"" + GetExtensionImeId() + "\"]", profile()); - EXPECT_EQ(GetArcImeId(), enabled_extension_imes.GetValue()); + EXPECT_EQ(GetArcImeId(), enabled_imes.GetValue()); EXPECT_EQ(GetComponentExtensionImeId(), preload_engines.GetValue()); } @@ -318,7 +316,7 @@ function.get(), "[\"" + GetComponentExtensionImeId() + "\"]", profile()); - EXPECT_EQ(GetArcImeId(), enabled_extension_imes.GetValue()); + EXPECT_EQ(GetArcImeId(), enabled_imes.GetValue()); EXPECT_TRUE(preload_engines.GetValue().empty()); } @@ -329,7 +327,7 @@ api_test_utils::RunFunctionAndReturnSingleResult( function.get(), "[\"" + GetArcImeId() + "\"]", profile()); - EXPECT_TRUE(enabled_extension_imes.GetValue().empty()); + EXPECT_TRUE(enabled_imes.GetValue().empty()); EXPECT_TRUE(preload_engines.GetValue().empty()); }
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 4598366..c8c6ac5 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -418,7 +418,7 @@ // Input method settings. (*s_whitelist)[::prefs::kLanguagePreloadEngines] = settings_api::PrefType::PREF_TYPE_STRING; - (*s_whitelist)[::prefs::kLanguageEnabledExtensionImes] = + (*s_whitelist)[::prefs::kLanguageEnabledImes] = settings_api::PrefType::PREF_TYPE_STRING; (*s_whitelist)[::prefs::kLanguageAllowedInputMethods] = settings_api::PrefType::PREF_TYPE_LIST;
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 6648b8fd..0f9c6748 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -805,7 +805,7 @@ LoadExtension(test_data_dir_.AppendASCII("webrequest_activetab")); ASSERT_TRUE(extension) << message_; ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension)) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); EXPECT_TRUE(listener.WaitUntilSatisfied()); // Navigate the browser to a page in a new tab. @@ -916,7 +916,7 @@ LoadExtension(test_data_dir_.AppendASCII("webrequest_activetab")); ASSERT_TRUE(extension) << message_; ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension)) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); EXPECT_TRUE(listener.WaitUntilSatisfied()); ui_test_utils::NavigateToURL( @@ -1832,7 +1832,7 @@ LoadExtension(test_data_dir_.AppendASCII("webrequest_activetab")); ASSERT_TRUE(extension) << message_; ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension)) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); EXPECT_TRUE(listener.WaitUntilSatisfied()); // Navigate the browser to a page in a new tab.
diff --git a/chrome/browser/extensions/extension_action_runner_browsertest.cc b/chrome/browser/extensions/extension_action_runner_browsertest.cc index d64443c9..76631c8 100644 --- a/chrome/browser/extensions/extension_action_runner_browsertest.cc +++ b/chrome/browser/extensions/extension_action_runner_browsertest.cc
@@ -173,7 +173,7 @@ ScriptingPermissionsModifier modifier(profile(), extension); if (withhold_permissions == WITHHOLD_PERMISSIONS && modifier.CanAffectExtension()) { - modifier.SetWithholdAllUrls(true); + modifier.SetWithholdHostPermissions(true); } } @@ -318,13 +318,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionActionRunnerBrowserTest, ActiveScriptsAreDisplayedAndDelayExecution) { - // First, we load up three extensions: + // First, we load up four extensions: // - An extension that injects scripts into all hosts, // - An extension that injects scripts into explicit hosts, // - An extension with a content script that runs on all hosts, // - An extension with a content script that runs on explicit hosts. - // The extensions that operate on explicit hosts have permission; the ones - // that request all hosts require user consent. + // All extensions should require user consent. std::vector<std::unique_ptr<ActiveScriptTester>> testers; testers.push_back(std::make_unique<ActiveScriptTester>( "inject_scripts_all_hosts", @@ -333,7 +332,7 @@ testers.push_back(std::make_unique<ActiveScriptTester>( "inject_scripts_explicit_hosts", CreateExtension(EXPLICIT_HOSTS, EXECUTE_SCRIPT, WITHHOLD_PERMISSIONS), - browser(), DOES_NOT_REQUIRE_CONSENT, EXECUTE_SCRIPT)); + browser(), REQUIRES_CONSENT, EXECUTE_SCRIPT)); testers.push_back(std::make_unique<ActiveScriptTester>( "content_scripts_all_hosts", CreateExtension(ALL_HOSTS, CONTENT_SCRIPT, WITHHOLD_PERMISSIONS), @@ -341,7 +340,7 @@ testers.push_back(std::make_unique<ActiveScriptTester>( "content_scripts_explicit_hosts", CreateExtension(EXPLICIT_HOSTS, CONTENT_SCRIPT, WITHHOLD_PERMISSIONS), - browser(), DOES_NOT_REQUIRE_CONSENT, CONTENT_SCRIPT)); + browser(), REQUIRES_CONSENT, CONTENT_SCRIPT)); // Navigate to an URL (which matches the explicit host specified in the // extension content_scripts_explicit_hosts). All four extensions should @@ -435,7 +434,7 @@ // Enable the extension to run on all urls. ScriptingPermissionsModifier modifier(profile(), extension); - modifier.SetWithholdAllUrls(false); + modifier.SetWithholdHostPermissions(false); EXPECT_TRUE(RunAllPendingInRenderer(web_contents)); // Navigate again - this time, the extension should execute immediately (and @@ -447,7 +446,7 @@ // Revoke all urls permissions. inject_success_listener.Reset(); - modifier.SetWithholdAllUrls(true); + modifier.SetWithholdHostPermissions(true); EXPECT_TRUE(RunAllPendingInRenderer(web_contents)); // Re-navigate; the extension should again need permission to run. @@ -466,7 +465,8 @@ const Extension* extension = LoadExtension( test_data_dir_.AppendASCII("blocked_actions/content_scripts")); ASSERT_TRUE(extension); - ScriptingPermissionsModifier(profile(), extension).SetWithholdAllUrls(true); + ScriptingPermissionsModifier(profile(), extension) + .SetWithholdHostPermissions(true); ui_test_utils::NavigateToURL(browser(), url); content::WebContents* web_contents =
diff --git a/chrome/browser/extensions/extension_action_runner_unittest.cc b/chrome/browser/extensions/extension_action_runner_unittest.cc index 285ef3ff..83e62d55 100644 --- a/chrome/browser/extensions/extension_action_runner_unittest.cc +++ b/chrome/browser/extensions/extension_action_runner_unittest.cc
@@ -118,7 +118,7 @@ PermissionsUpdater(profile()).InitializePermissions(extension_.get()); ScriptingPermissionsModifier(profile(), extension_.get()) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); return extension_.get(); } @@ -354,7 +354,7 @@ // Enable the extension on all urls. ScriptingPermissionsModifier permissions_modifier(profile(), extension); - permissions_modifier.SetWithholdAllUrls(false); + permissions_modifier.SetWithholdHostPermissions(false); EXPECT_FALSE(RequiresUserConsent(extension)); // This should carry across navigations, and websites. @@ -362,7 +362,7 @@ EXPECT_FALSE(RequiresUserConsent(extension)); // Turning off the preference should have instant effect. - permissions_modifier.SetWithholdAllUrls(true); + permissions_modifier.SetWithholdHostPermissions(true); EXPECT_TRUE(RequiresUserConsent(extension)); // And should also persist across navigations and websites.
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc index 51474cd..d88b75a 100644 --- a/chrome/browser/extensions/extension_context_menu_model.cc +++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -374,7 +374,7 @@ content::WebContents* web_contents) const { ScriptingPermissionsModifier modifier(profile_, extension); DCHECK(modifier.CanAffectExtension()); - if (!modifier.HasWithheldAllUrls()) + if (!modifier.HasWithheldHostPermissions()) return PAGE_ACCESS_RUN_ON_ALL_SITES; if (modifier.HasGrantedHostPermission( GetActiveWebContents()->GetLastCommittedURL())) @@ -394,6 +394,8 @@ page_access_submenu_->AddRadioItemWithStringId( PAGE_ACCESS_RUN_ON_CLICK, IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_CLICK, kRadioGroup); + // TODO(https://crbug.com/857235): We should update these options based on + // the withheld permissions for the extension. page_access_submenu_->AddRadioItemWithStringId( PAGE_ACCESS_RUN_ON_ALL_SITES, IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_ALL_SITES, kRadioGroup); @@ -428,18 +430,18 @@ switch (command_id) { case PAGE_ACCESS_RUN_ON_CLICK: if (current_access == PAGE_ACCESS_RUN_ON_ALL_SITES) - modifier.SetWithholdAllUrls(true); + modifier.SetWithholdHostPermissions(true); if (modifier.HasGrantedHostPermission(url)) modifier.RemoveGrantedHostPermission(url); break; case PAGE_ACCESS_RUN_ON_SITE: if (current_access == PAGE_ACCESS_RUN_ON_ALL_SITES) - modifier.SetWithholdAllUrls(true); + modifier.SetWithholdHostPermissions(true); if (!modifier.HasGrantedHostPermission(url)) modifier.GrantHostPermission(url); break; case PAGE_ACCESS_RUN_ON_ALL_SITES: - modifier.SetWithholdAllUrls(false); + modifier.SetWithholdHostPermissions(false); break; default: NOTREACHED();
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc index e79c2786..731c6dae 100644 --- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc +++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -623,7 +623,8 @@ const Extension* extension = AddExtensionWithHostPermission("extension", manifest_keys::kBrowserAction, Manifest::INTERNAL, "*://*/*"); - ScriptingPermissionsModifier(profile(), extension).SetWithholdAllUrls(true); + ScriptingPermissionsModifier(profile(), extension) + .SetWithholdHostPermissions(true); EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id())); const GURL kActiveUrl("http://www.example.com/"); @@ -755,16 +756,15 @@ EXPECT_EQ(2, run_count); EXPECT_TRUE(action_runner->WantsToRun(extension)); - // Install an extension requesting only a single host. Since the extension - // doesn't request all hosts, it shouldn't have withheld permissions, and - // thus shouldn't have the page access submenu. + // Install an extension requesting a single host. The page access submenu + // should still be present. const Extension* single_host_extension = AddExtensionWithHostPermission( "single_host_extension", manifest_keys::kBrowserAction, Manifest::INTERNAL, "http://www.google.com/*"); ExtensionContextMenuModel single_host_menu( single_host_extension, GetBrowser(), ExtensionContextMenuModel::VISIBLE, nullptr); - EXPECT_EQ(-1, single_host_menu.GetIndexOfCommandId( + EXPECT_NE(-1, single_host_menu.GetIndexOfCommandId( ExtensionContextMenuModel::PAGE_ACCESS_SUBMENU)); // Disable the click-to-script feature, and install a new extension requiring
diff --git a/chrome/browser/extensions/forced_extensions/installation_tracker.cc b/chrome/browser/extensions/forced_extensions/installation_tracker.cc index 9ec3545..80db14f 100644 --- a/chrome/browser/extensions/forced_extensions/installation_tracker.cc +++ b/chrome/browser/extensions/forced_extensions/installation_tracker.cc
@@ -19,9 +19,10 @@ namespace extensions { -InstallationTracker::InstallationTracker(ExtensionRegistry* registry, - PrefService* pref_service, - std::unique_ptr<base::Timer> timer) +InstallationTracker::InstallationTracker( + ExtensionRegistry* registry, + PrefService* pref_service, + std::unique_ptr<base::OneShotTimer> timer) : registry_(registry), pref_service_(pref_service), start_time_(base::Time::Now()),
diff --git a/chrome/browser/extensions/forced_extensions/installation_tracker.h b/chrome/browser/extensions/forced_extensions/installation_tracker.h index 89fdc46..37a1d1ba 100644 --- a/chrome/browser/extensions/forced_extensions/installation_tracker.h +++ b/chrome/browser/extensions/forced_extensions/installation_tracker.h
@@ -32,7 +32,7 @@ public: InstallationTracker(ExtensionRegistry* registry, PrefService* pref_service, - std::unique_ptr<base::Timer> timer = + std::unique_ptr<base::OneShotTimer> timer = std::make_unique<base::OneShotTimer>()); ~InstallationTracker() override; @@ -70,7 +70,7 @@ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> observer_; // Tracks installation reporting timeout. - std::unique_ptr<base::Timer> timer_; + std::unique_ptr<base::OneShotTimer> timer_; DISALLOW_COPY_AND_ASSIGN(InstallationTracker); };
diff --git a/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc b/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc index 04bc7f9..2094b6d 100644 --- a/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc +++ b/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc
@@ -36,7 +36,7 @@ ForcedExtensionsInstallationTrackerTest() : prefs_(profile_.GetTestingPrefService()), registry_(ExtensionRegistry::Get(&profile_)) { - auto fake_timer = std::make_unique<base::MockTimer>(true, false); + auto fake_timer = std::make_unique<base::MockOneShotTimer>(); fake_timer_ = fake_timer.get(); tracker_ = std::make_unique<InstallationTracker>(registry_, prefs_, std::move(fake_timer)); @@ -57,7 +57,7 @@ ExtensionRegistry* registry_; base::HistogramTester histogram_tester_; - base::MockTimer* fake_timer_; + base::MockOneShotTimer* fake_timer_; std::unique_ptr<InstallationTracker> tracker_; DISALLOW_COPY_AND_ASSIGN(ForcedExtensionsInstallationTrackerTest);
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc index 77c6810..e725c11 100644 --- a/chrome/browser/extensions/permissions_updater_unittest.cc +++ b/chrome/browser/extensions/permissions_updater_unittest.cc
@@ -268,14 +268,6 @@ URLPatternSet(), URLPatternSet()); }; - auto url_permission_set = [](const GURL& url) { - URLPatternSet set; - URLPattern pattern(URLPattern::SCHEME_ALL, url.spec()); - set.AddPattern(pattern); - return std::make_unique<PermissionSet>( - APIPermissionSet(), ManifestPermissionSet(), set, URLPatternSet()); - }; - auto can_access_page = [](scoped_refptr<const extensions::Extension> extension, const GURL& document_url) -> bool { @@ -340,65 +332,6 @@ } { - // Test revoking non-optional host permissions with click-to-script. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kRuntimeHostPermissions); - ListBuilder optional_permissions; - optional_permissions.Append("tabs"); - ListBuilder required_permissions; - required_permissions.Append("topSites") - .Append("http://*/*") - .Append("http://*.google.com/*"); - scoped_refptr<const Extension> extension = - CreateExtensionWithOptionalPermissions(optional_permissions.Build(), - required_permissions.Build(), - "My Extension"); - PermissionsUpdater updater(profile()); - updater.InitializePermissions(extension.get()); - - ScriptingPermissionsModifier(profile(), extension).SetWithholdAllUrls(true); - - // All-hosts was withheld, so the extension shouldn't have access to any - // site (like foo.com). - const GURL kOrigin("http://foo.com"); - - EXPECT_FALSE(extension->permissions_data() - ->active_permissions() - .HasExplicitAccessToOrigin(kOrigin)); - EXPECT_TRUE(extension->permissions_data() - ->withheld_permissions() - .HasExplicitAccessToOrigin(kOrigin)); - - const GURL kRequiredOrigin("http://www.google.com/"); - EXPECT_TRUE(extension->permissions_data() - ->active_permissions() - .HasExplicitAccessToOrigin(kRequiredOrigin)); - EXPECT_FALSE(updater.GetRevokablePermissions(extension.get()) - ->HasExplicitAccessToOrigin(kRequiredOrigin)); - - // Give the extension access to foo.com. Now, the foo.com permission should - // be revokable. - updater.AddPermissions(extension.get(), *url_permission_set(kOrigin)); - EXPECT_TRUE(extension->permissions_data() - ->active_permissions() - .HasExplicitAccessToOrigin(kOrigin)); - EXPECT_TRUE(updater.GetRevokablePermissions(extension.get()) - ->HasExplicitAccessToOrigin(kOrigin)); - - // Revoke the foo.com permission. The extension should no longer have - // access to foo.com, and the revokable permissions should be empty. - updater.RemovePermissions(extension.get(), *url_permission_set(kOrigin), - PermissionsUpdater::REMOVE_HARD); - EXPECT_FALSE(extension->permissions_data() - ->active_permissions() - .HasExplicitAccessToOrigin(kOrigin)); - EXPECT_TRUE(extension->permissions_data() - ->withheld_permissions() - .HasExplicitAccessToOrigin(kOrigin)); - EXPECT_TRUE(updater.GetRevokablePermissions(extension.get())->IsEmpty()); - } - - { // Make sure policy restriction updates update permission data. URLPatternSet default_policy_blocked_hosts; URLPatternSet default_policy_allowed_hosts; @@ -571,4 +504,166 @@ EXPECT_TRUE(prefs->GetRuntimeGrantedPermissions(extension->id())->IsEmpty()); } +TEST_F(PermissionsUpdaterTest, RevokingPermissionsWithRuntimeHostPermissions) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kRuntimeHostPermissions); + + InitializeEmptyExtensionService(); + + constexpr struct { + const char* permission; + const char* test_url; + } test_cases[] = { + {"http://*/*", "http://foo.com"}, + {"http://google.com/*", "http://google.com"}, + }; + + for (const auto& test_case : test_cases) { + std::string test_name = + base::StringPrintf("%s, %s", test_case.permission, test_case.test_url); + SCOPED_TRACE(test_name); + scoped_refptr<const Extension> extension = + CreateExtensionWithOptionalPermissions( + std::make_unique<base::ListValue>(), + ListBuilder().Append(test_case.permission).Build(), test_name); + PermissionsUpdater updater(profile()); + updater.InitializePermissions(extension.get()); + + ScriptingPermissionsModifier(profile(), extension) + .SetWithholdHostPermissions(true); + + // Host access was withheld, so the extension shouldn't have access to the + // test site. + const GURL kOrigin(test_case.test_url); + + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .HasExplicitAccessToOrigin(kOrigin)); + EXPECT_TRUE(updater.GetRevokablePermissions(extension.get())->IsEmpty()); + EXPECT_TRUE(extension->permissions_data() + ->withheld_permissions() + .HasExplicitAccessToOrigin(kOrigin)); + + URLPatternSet url_pattern_set; + url_pattern_set.AddOrigin(URLPattern::SCHEME_ALL, kOrigin); + const PermissionSet permission_set(APIPermissionSet(), + ManifestPermissionSet(), url_pattern_set, + URLPatternSet()); + // Give the extension access to the test site. Now, the test site permission + // should be revokable. + updater.AddPermissions(extension.get(), permission_set); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .HasExplicitAccessToOrigin(kOrigin)); + EXPECT_TRUE(updater.GetRevokablePermissions(extension.get()) + ->HasExplicitAccessToOrigin(kOrigin)); + + // Revoke the test site permission. The extension should no longer have + // access to test site, and the revokable permissions should be empty. + updater.RemovePermissions(extension.get(), permission_set, + PermissionsUpdater::REMOVE_HARD); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .HasExplicitAccessToOrigin(kOrigin)); + EXPECT_TRUE(extension->permissions_data() + ->withheld_permissions() + .HasExplicitAccessToOrigin(kOrigin)); + EXPECT_TRUE(updater.GetRevokablePermissions(extension.get())->IsEmpty()); + } +} + +TEST_F(PermissionsUpdaterTest, ChromeFaviconIsNotARevokableHost) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kRuntimeHostPermissions); + + InitializeEmptyExtensionService(); + + URLPattern chrome_favicon_pattern(Extension::kValidHostPermissionSchemes, + "chrome://favicon/"); + + { + scoped_refptr<const Extension> extension = + ExtensionBuilder("favicon extension") + .AddPermissions({"https://example.com/*", "chrome://favicon/*"}) + .Build(); + URLPattern example_com_pattern(Extension::kValidHostPermissionSchemes, + "https://example.com/*"); + PermissionsUpdater updater(profile()); + updater.InitializePermissions(extension.get()); + + // To start, the extension should have both example.com and chrome://favicon + // permissions. + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(chrome_favicon_pattern)); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(example_com_pattern)); + + // Only example.com should be revokable - chrome://favicon is not a real + // host permission. + std::unique_ptr<const PermissionSet> revokable_permissions = + updater.GetRevokablePermissions(extension.get()); + EXPECT_FALSE(revokable_permissions->explicit_hosts().ContainsPattern( + chrome_favicon_pattern)); + EXPECT_TRUE(revokable_permissions->explicit_hosts().ContainsPattern( + example_com_pattern)); + + // Withholding host permissions shouldn't withhold example.com. + ScriptingPermissionsModifier(profile(), extension) + .SetWithholdHostPermissions(true); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(chrome_favicon_pattern)); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(example_com_pattern)); + } + { + scoped_refptr<const Extension> extension = + ExtensionBuilder("all urls extension") + .AddPermission("<all_urls>") + .Build(); + URLPattern all_urls_pattern(Extension::kValidHostPermissionSchemes, + "<all_urls>"); + PermissionsUpdater updater(profile()); + updater.InitializePermissions(extension.get()); + + // <all_urls> (strangely) includes the chrome://favicon/ permission. + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(chrome_favicon_pattern)); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(all_urls_pattern)); + + std::unique_ptr<const PermissionSet> revokable_permissions = + updater.GetRevokablePermissions(extension.get()); + // TODO(https://crbug.com/859600): <all_urls> will report containing + // chrome://favicon/, even though it shouldn't since the scheme doesn't + // match. + // EXPECT_FALSE(revokable_permissions->explicit_hosts().ContainsPattern( + // chrome_favicon_pattern)); + EXPECT_TRUE(revokable_permissions->explicit_hosts().ContainsPattern( + all_urls_pattern)); + + ScriptingPermissionsModifier(profile(), extension) + .SetWithholdHostPermissions(true); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(chrome_favicon_pattern)); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .ContainsPattern(all_urls_pattern)); + } +} + } // namespace extensions
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.cc b/chrome/browser/extensions/scripting_permissions_modifier.cc index 8e2b49e9..d8ff8d6 100644 --- a/chrome/browser/extensions/scripting_permissions_modifier.cc +++ b/chrome/browser/extensions/scripting_permissions_modifier.cc
@@ -20,20 +20,13 @@ namespace { -// The entry into the ExtensionPrefs for allowing an extension to script on -// all urls without explicit permission. -const char kExtensionAllowedOnAllUrlsPrefName[] = +// The entry into the ExtensionPrefs indicating that an extension should be +// granted all the requested host permissions without requiring explicit runtime +// permission from the user. The preference name is different for legacy +// reasons. +const char kGrantExtensionAllHostPermissionsPrefName[] = "extension_can_script_all_urls"; -URLPatternSet FilterImpliedAllHostsPatterns(const URLPatternSet& patterns) { - URLPatternSet result; - for (const URLPattern& pattern : patterns) { - if (pattern.MatchesEffectiveTld()) - result.AddPattern(pattern); - } - return result; -} - // Returns true if Chrome can potentially withhold permissions from the // extension. bool CanWithholdFromExtension(const Extension& extension) { @@ -49,40 +42,58 @@ extension.location()); } -// Partitions |permissions| into two sets of permissions, placing any -// all-hosts-like permissions into |withheld_permissions_out| and the rest -// into |granted_permissions_out|. +// Partitions |requested_permissions| into two sets of permissions, granted and +// withheld. Granted permissions are added to |granted_permissions_out|, and +// consist of any non-host permissions or host permissions that are present in +// |runtime_granted_permissions|. Withheld permissions are added to +// |withheld_permissions_out|, and are any host permissions that are not in +// |granted_runtime_permissions|. void PartitionPermissions( - const PermissionSet& permissions, + const PermissionSet& requested_permissions, + const PermissionSet& runtime_granted_permissions, std::unique_ptr<const PermissionSet>* granted_permissions_out, std::unique_ptr<const PermissionSet>* withheld_permissions_out) { - auto segregate_url_permissions = [](const URLPatternSet& patterns, - URLPatternSet* granted, - URLPatternSet* withheld) { - for (const URLPattern& pattern : patterns) { - if (pattern.MatchesEffectiveTld()) - withheld->AddPattern(pattern); - else - granted->AddPattern(pattern); - } - }; + auto segregate_url_permissions = + [](const URLPatternSet& requested_patterns, + const URLPatternSet& runtime_granted_patterns, URLPatternSet* granted, + URLPatternSet* withheld) { + for (const URLPattern& pattern : requested_patterns) { + // The chrome://favicon permission is special. It is requested by + // extensions to access stored favicons, but is not a traditional + // host permission. Since it cannot be reasonably runtime-granted + // while the user is on the site (i.e., the user never visits + // chrome://favicon/), we auto-grant it and treat it like an API + // permission. + bool is_chrome_favicon = + pattern.host() == "favicon" && pattern.scheme() == "chrome"; + bool is_runtime_granted = + runtime_granted_patterns.ContainsPattern(pattern); + if (is_chrome_favicon || is_runtime_granted) + granted->AddPattern(pattern); + else + withheld->AddPattern(pattern); + } + }; URLPatternSet granted_explicit_hosts; URLPatternSet withheld_explicit_hosts; URLPatternSet granted_scriptable_hosts; URLPatternSet withheld_scriptable_hosts; - segregate_url_permissions(permissions.explicit_hosts(), + segregate_url_permissions(requested_permissions.explicit_hosts(), + runtime_granted_permissions.explicit_hosts(), &granted_explicit_hosts, &withheld_explicit_hosts); - segregate_url_permissions(permissions.scriptable_hosts(), + segregate_url_permissions(requested_permissions.scriptable_hosts(), + runtime_granted_permissions.scriptable_hosts(), &granted_scriptable_hosts, &withheld_scriptable_hosts); - granted_permissions_out->reset( - new PermissionSet(permissions.apis(), permissions.manifest_permissions(), - granted_explicit_hosts, granted_scriptable_hosts)); - withheld_permissions_out->reset( - new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), - withheld_explicit_hosts, withheld_scriptable_hosts)); + *granted_permissions_out = std::make_unique<PermissionSet>( + requested_permissions.apis(), + requested_permissions.manifest_permissions(), granted_explicit_hosts, + granted_scriptable_hosts); + *withheld_permissions_out = std::make_unique<PermissionSet>( + APIPermissionSet(), ManifestPermissionSet(), withheld_explicit_hosts, + withheld_scriptable_hosts); } // Returns true if the extension should even be considered for being affected @@ -103,7 +114,7 @@ const ExtensionPrefs& prefs, const ExtensionId& id) { bool permissions_allowed = false; - if (!prefs.ReadPrefAsBoolean(id, kExtensionAllowedOnAllUrlsPrefName, + if (!prefs.ReadPrefAsBoolean(id, kGrantExtensionAllHostPermissionsPrefName, &permissions_allowed)) { return base::nullopt; } @@ -121,7 +132,7 @@ // withhold permissions. Invert the boolean for backwards compatibility. bool permissions_allowed = !should_withhold; prefs->UpdateExtensionPref( - id, kExtensionAllowedOnAllUrlsPrefName, + id, kGrantExtensionAllHostPermissionsPrefName, std::make_unique<base::Value>(permissions_allowed)); } @@ -138,19 +149,20 @@ ScriptingPermissionsModifier::~ScriptingPermissionsModifier() {} -void ScriptingPermissionsModifier::SetWithholdAllUrls(bool should_withhold) { +void ScriptingPermissionsModifier::SetWithholdHostPermissions( + bool should_withhold) { DCHECK(CanAffectExtension()); - if (HasWithheldAllUrls() == should_withhold) + if (HasWithheldHostPermissions() == should_withhold) return; SetWithholdPermissionsPrefValue(extension_prefs_, extension_->id(), should_withhold); if (should_withhold) - WithholdImpliedAllHosts(); + WithholdHostPermissions(); else - GrantWithheldImpliedAllHosts(); + GrantWithheldHostPermissions(); // If this was an update to permissions, we also need to sync the change. // TODO(devlin): This isn't currently necessary. We should remove it and add @@ -161,7 +173,7 @@ sync_service->SyncExtensionChangeIfNeeded(*extension_); } -bool ScriptingPermissionsModifier::HasWithheldAllUrls() const { +bool ScriptingPermissionsModifier::HasWithheldHostPermissions() const { DCHECK(CanAffectExtension()); base::Optional<bool> pref_value = @@ -177,12 +189,16 @@ if (!ShouldConsiderExtension(*extension_)) return false; - // The extension can be affected if it currently has all-hosts-style - // permissions, or if it did and they are actively withheld. - return extension_->permissions_data() - ->active_permissions() - .ShouldWarnAllHosts() || - extension_->permissions_data()->HasWithheldImpliedAllHosts(); + // The extension can be affected if it currently has host permissions, or if + // it did and they are actively withheld. + return !extension_->permissions_data() + ->active_permissions() + .effective_hosts() + .is_empty() || + !extension_->permissions_data() + ->withheld_permissions() + .effective_hosts() + .is_empty(); } void ScriptingPermissionsModifier::GrantHostPermission(const GURL& url) { @@ -213,32 +229,9 @@ DCHECK(CanAffectExtension()); GURL origin = url.GetOrigin(); - // If the extension doesn't have access to the host, it clearly hasn't been - // granted permission. - if (!extension_->permissions_data() - ->active_permissions() - .effective_hosts() - .MatchesURL(origin)) { - return false; - } - - // Check which permissions would have been withheld. If access to the host - // would have otherwise been withheld, then we know that access has been - // explicitly granted. - // TODO(devlin): This seems wrong, and won't work with trying to grant or - // withhold e.g. optional permissions. It's also overly expensive. - const PermissionSet& required_permissions = - PermissionsParser::GetRequiredPermissions(extension_.get()); - std::unique_ptr<const PermissionSet> granted_permissions; - std::unique_ptr<const PermissionSet> withheld_permissions; - PartitionPermissions(required_permissions, &granted_permissions, - &withheld_permissions); - if (!granted_permissions->effective_hosts().MatchesURL(origin) && - withheld_permissions->effective_hosts().MatchesURL(origin)) { - return true; - } - - return false; + return extension_prefs_->GetRuntimeGrantedPermissions(extension_->id()) + ->effective_hosts() + .MatchesURL(origin); } void ScriptingPermissionsModifier::RemoveGrantedHostPermission( @@ -282,15 +275,20 @@ should_withhold = pref_value.has_value() && pref_value.value() == true; } - should_withhold &= permissions.ShouldWarnAllHosts(); + should_withhold &= !permissions.effective_hosts().is_empty(); if (!should_withhold) { *granted_permissions_out = permissions.Clone(); withheld_permissions_out->reset(new PermissionSet()); return; } - PartitionPermissions(permissions, granted_permissions_out, - withheld_permissions_out); + // Only grant host permissions that the user has explicitly granted at + // runtime through the runtime host permissions feature or the optional + // permissions API. + std::unique_ptr<const PermissionSet> runtime_granted_permissions = + extension_prefs.GetRuntimeGrantedPermissions(extension.id()); + PartitionPermissions(permissions, *runtime_granted_permissions, + granted_permissions_out, withheld_permissions_out); } std::unique_ptr<const PermissionSet> @@ -301,33 +299,35 @@ std::unique_ptr<const PermissionSet> granted_permissions; std::unique_ptr<const PermissionSet> withheld_permissions; + + // Revokable permissions are those that would be withheld if there were no + // runtime-granted permissions. + PermissionSet empty_runtime_granted_permissions; PartitionPermissions(extension_->permissions_data()->active_permissions(), - &granted_permissions, &withheld_permissions); + empty_runtime_granted_permissions, &granted_permissions, + &withheld_permissions); return withheld_permissions; } -void ScriptingPermissionsModifier::GrantWithheldImpliedAllHosts() { +void ScriptingPermissionsModifier::GrantWithheldHostPermissions() { const PermissionSet& withheld = extension_->permissions_data()->withheld_permissions(); - PermissionSet permissions( - APIPermissionSet(), ManifestPermissionSet(), - FilterImpliedAllHostsPatterns(withheld.explicit_hosts()), - FilterImpliedAllHostsPatterns(withheld.scriptable_hosts())); + PermissionSet permissions(APIPermissionSet(), ManifestPermissionSet(), + withheld.explicit_hosts(), + withheld.scriptable_hosts()); PermissionsUpdater(browser_context_) .AddPermissions(extension_.get(), permissions); } -void ScriptingPermissionsModifier::WithholdImpliedAllHosts() { - const PermissionSet& active = - extension_->permissions_data()->active_permissions(); - PermissionSet permissions( - APIPermissionSet(), ManifestPermissionSet(), - FilterImpliedAllHostsPatterns(active.explicit_hosts()), - FilterImpliedAllHostsPatterns(active.scriptable_hosts())); +void ScriptingPermissionsModifier::WithholdHostPermissions() { + // TODO(devlin): By using PermissionsUpdater::REMOVE_HARD, this will also + // affect granted_permissions in preferences. It shouldn't. We should + // introduce another enum to PermissionsModifier for removing only from + // runtime granted permissions. PermissionsUpdater(browser_context_) - .RemovePermissions(extension_.get(), permissions, + .RemovePermissions(extension_.get(), *GetRevokablePermissions(), PermissionsUpdater::REMOVE_HARD); }
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.h b/chrome/browser/extensions/scripting_permissions_modifier.h index 88ad28e..a5650ee 100644 --- a/chrome/browser/extensions/scripting_permissions_modifier.h +++ b/chrome/browser/extensions/scripting_permissions_modifier.h
@@ -31,18 +31,16 @@ const scoped_refptr<const Extension>& extension); ~ScriptingPermissionsModifier(); - // Sets whether Chrome should withhold <all_urls>-style permissions from the - // extension. Used when the features::kRuntimeHostPermissions feature is - // enabled. + // Sets whether Chrome should withhold host permissions from the extension. + // Used when the features::kRuntimeHostPermissions feature is enabled. // This may only be called for extensions that can be affected (i.e., for // which CanAffectExtension() returns true). Anything else will DCHECK. - void SetWithholdAllUrls(bool withhold); + void SetWithholdHostPermissions(bool withhold); - // Returns whether Chrome has withheld <all_urls>-style permissions from the - // extension. + // Returns whether Chrome has withheld host permissions from the extension. // This may only be called for extensions that can be affected (i.e., for // which CanAffectExtension() returns true). Anything else will DCHECK. - bool HasWithheldAllUrls() const; + bool HasWithheldHostPermissions() const; // Returns true if the associated extension can be affected by // features::kRuntimeHostPermissions. @@ -54,7 +52,9 @@ void GrantHostPermission(const GURL& url); // Returns true if the extension has been explicitly granted permission to run - // on the origin of |url|. + // on the origin of |url|. Note: This checks any runtime-granted permissions, + // which includes both granted optional permissions and permissions granted + // through the runtime host permissions feature. // This may only be called for extensions that can be affected (i.e., for // which CanAffectExtension() returns true). Anything else will DCHECK. bool HasGrantedHostPermission(const GURL& url) const; @@ -83,11 +83,11 @@ std::unique_ptr<const PermissionSet> GetRevokablePermissions() const; private: - // Grants any withheld all-hosts (or all-hosts-like) permissions. - void GrantWithheldImpliedAllHosts(); + // Grants any withheld host permissions. + void GrantWithheldHostPermissions(); - // Revokes any granted all-hosts (or all-hosts-like) permissions. - void WithholdImpliedAllHosts(); + // Revokes any granted host permissions. + void WithholdHostPermissions(); content::BrowserContext* browser_context_;
diff --git a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc index 33765ab..f93daf60 100644 --- a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc +++ b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
@@ -6,6 +6,8 @@ #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/extensions/chrome_test_extension_loader.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_test_base.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/permissions_updater.h" @@ -13,6 +15,8 @@ #include "chrome/test/base/testing_profile.h" #include "components/crx_file/id_util.h" #include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_features.h" @@ -21,6 +25,7 @@ #include "extensions/common/url_pattern.h" #include "extensions/common/url_pattern_set.h" #include "extensions/common/value_builder.h" +#include "extensions/test/test_extension_dir.h" namespace extensions { @@ -103,89 +108,94 @@ } // namespace -TEST_F(ScriptingPermissionsModifierUnitTest, WithholdAndGrantAllHosts) { +TEST_F(ScriptingPermissionsModifierUnitTest, GrantAndWithholdHostPermissions) { InitializeEmptyExtensionService(); // Permissions can only be withheld with the appropriate feature turned on. RuntimeHostPermissionsEnabledScope enabled_scope; - URLPattern google(URLPattern::SCHEME_ALL, "http://www.google.com/*"); - URLPattern sub_google(URLPattern::SCHEME_ALL, "http://*.google.com/*"); - URLPattern all_http(URLPattern::SCHEME_ALL, "http://*/*"); - URLPattern all_hosts(URLPattern::SCHEME_ALL, "<all_urls>"); - URLPattern all_com(URLPattern::SCHEME_ALL, "http://*.com/*"); + std::vector<std::string> test_cases[] = { + {"http://www.google.com/*"}, + {"http://*/*"}, + {"<all_urls>"}, + {"http://*.com/*"}, + {"http://google.com/*", "<all_urls>"}, + }; - std::set<URLPattern> all_host_patterns; - std::set<URLPattern> safe_patterns; + for (const auto& test_case : test_cases) { + std::string test_case_name = base::JoinString(test_case, ","); + SCOPED_TRACE(test_case_name); + std::set<URLPattern> patterns; + for (const auto& pattern : test_case) + patterns.insert(URLPattern(URLPattern::SCHEME_ALL, pattern)); + scoped_refptr<const Extension> extension = CreateExtensionWithPermissions( + patterns, patterns, Manifest::INTERNAL, test_case_name); - all_host_patterns.insert(all_http); - all_host_patterns.insert(all_hosts); - all_host_patterns.insert(all_com); + PermissionsUpdater(profile()).InitializePermissions(extension.get()); - safe_patterns.insert(google); - safe_patterns.insert(sub_google); + const PermissionsData* permissions_data = extension->permissions_data(); - std::set<URLPattern> all_patterns = - base::STLSetUnion<std::set<URLPattern>>(all_host_patterns, safe_patterns); + ScriptingPermissionsModifier modifier(profile(), extension); + ASSERT_TRUE(modifier.CanAffectExtension()); - scoped_refptr<const Extension> extension = CreateExtensionWithPermissions( - all_patterns, all_patterns, Manifest::INTERNAL, "a"); - const PermissionsData* permissions_data = extension->permissions_data(); - PermissionsUpdater updater(profile()); - updater.InitializePermissions(extension.get()); + // By default, all permissions are granted. + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions().scriptable_hosts().patterns(), + patterns)); + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions().explicit_hosts().patterns(), + patterns)); + EXPECT_TRUE(permissions_data->withheld_permissions() + .scriptable_hosts() + .patterns() + .empty()); + EXPECT_TRUE(permissions_data->withheld_permissions() + .explicit_hosts() + .patterns() + .empty()); - // By default, all permissions are granted. - EXPECT_TRUE(SetsAreEqual( - permissions_data->active_permissions().scriptable_hosts().patterns(), - all_patterns)); - EXPECT_TRUE(SetsAreEqual( - permissions_data->active_permissions().explicit_hosts().patterns(), - all_patterns)); - EXPECT_TRUE(permissions_data->withheld_permissions() - .scriptable_hosts() - .patterns() - .empty()); - EXPECT_TRUE(permissions_data->withheld_permissions() - .explicit_hosts() - .patterns() - .empty()); + // Then, withhold host permissions. + modifier.SetWithholdHostPermissions(true); - // Then, withhold the all-hosts permissions. - ScriptingPermissionsModifier modifier(profile(), extension); - modifier.SetWithholdAllUrls(true); + EXPECT_TRUE(permissions_data->active_permissions() + .scriptable_hosts() + .patterns() + .empty()); + // Note: can't use explicit_hosts().empty() here, since chrome://favicon/ + // will remain will still be present in explicit_hosts() (it's not really a + // host permission and isn't withheld). SetsAreEqual() ignores + // chrome://favicon in its checks. + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions().explicit_hosts().patterns(), + std::set<URLPattern>())); - EXPECT_TRUE(SetsAreEqual( - permissions_data->active_permissions().scriptable_hosts().patterns(), - safe_patterns)); - EXPECT_TRUE(SetsAreEqual( - permissions_data->active_permissions().explicit_hosts().patterns(), - safe_patterns)); - EXPECT_TRUE(SetsAreEqual( - permissions_data->withheld_permissions().scriptable_hosts().patterns(), - all_host_patterns)); - EXPECT_TRUE(SetsAreEqual( - permissions_data->withheld_permissions().explicit_hosts().patterns(), - all_host_patterns)); + EXPECT_TRUE(SetsAreEqual( + permissions_data->withheld_permissions().scriptable_hosts().patterns(), + patterns)); + EXPECT_TRUE(SetsAreEqual( + permissions_data->withheld_permissions().explicit_hosts().patterns(), + patterns)); - // Finally, re-grant the withheld permissions. - modifier.SetWithholdAllUrls(false); + // Finally, re-grant the withheld permissions. + modifier.SetWithholdHostPermissions(false); - // We should be back to our initial state - all requested permissions are - // granted. - EXPECT_TRUE(SetsAreEqual( - permissions_data->active_permissions().scriptable_hosts().patterns(), - all_patterns)); - EXPECT_TRUE(SetsAreEqual( - permissions_data->active_permissions().explicit_hosts().patterns(), - all_patterns)); - EXPECT_TRUE(permissions_data->withheld_permissions() - .scriptable_hosts() - .patterns() - .empty()); - EXPECT_TRUE(permissions_data->withheld_permissions() - .explicit_hosts() - .patterns() - .empty()); + // We should be back to our initial state - all requested permissions are + // granted. + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions().scriptable_hosts().patterns(), + patterns)); + EXPECT_TRUE(SetsAreEqual( + permissions_data->active_permissions().explicit_hosts().patterns(), + patterns)); + EXPECT_TRUE(permissions_data->withheld_permissions() + .scriptable_hosts() + .patterns() + .empty()); + EXPECT_TRUE(permissions_data->withheld_permissions() + .explicit_hosts() + .patterns() + .empty()); + } } TEST_F(ScriptingPermissionsModifierUnitTest, SwitchBehavior) { @@ -211,11 +221,11 @@ EXPECT_TRUE( permissions_data->withheld_permissions().scriptable_hosts().is_empty()); ScriptingPermissionsModifier modifier(profile(), extension); - EXPECT_FALSE(modifier.HasWithheldAllUrls()); + EXPECT_FALSE(modifier.HasWithheldHostPermissions()); // Revoke access. - modifier.SetWithholdAllUrls(true); - EXPECT_TRUE(modifier.HasWithheldAllUrls()); + modifier.SetWithholdHostPermissions(true); + EXPECT_TRUE(modifier.HasWithheldHostPermissions()); EXPECT_TRUE( permissions_data->active_permissions().scriptable_hosts().is_empty()); EXPECT_TRUE(SetsAreEqual( @@ -236,7 +246,7 @@ // withheld. enabled_scope = std::make_unique<RuntimeHostPermissionsEnabledScope>(); updater.InitializePermissions(extension.get()); - EXPECT_TRUE(modifier.HasWithheldAllUrls()); + EXPECT_TRUE(modifier.HasWithheldHostPermissions()); EXPECT_TRUE( permissions_data->active_permissions().scriptable_hosts().is_empty()); EXPECT_TRUE(SetsAreEqual( @@ -259,7 +269,7 @@ PermissionsUpdater(profile()).InitializePermissions(extension.get()); ScriptingPermissionsModifier modifier(profile(), extension); - modifier.SetWithholdAllUrls(true); + modifier.SetWithholdHostPermissions(true); const GURL kUrl("https://www.google.com/"); const GURL kUrl2("https://www.chromium.org/"); @@ -348,4 +358,75 @@ } } +TEST_F(ScriptingPermissionsModifierUnitTest, + ExtensionsInitializedWithSavedRuntimeGrantedHostPermissionsAcrossLoad) { + // Permissions can only be withheld with the appropriate feature turned on. + RuntimeHostPermissionsEnabledScope enabled_scope; + + InitializeEmptyExtensionService(); + + const GURL kExampleCom("https://example.com/"); + const GURL kChromiumOrg("https://chromium.org/"); + const URLPatternSet kExampleComPatternSet({URLPattern( + Extension::kValidHostPermissionSchemes, "https://example.com/")}); + + TestExtensionDir test_extension_dir; + test_extension_dir.WriteManifest( + R"({ + "name": "foo", + "manifest_version": 2, + "version": "1", + "permissions": ["<all_urls>"] + })"); + ChromeTestExtensionLoader loader(profile()); + loader.set_grant_permissions(true); + scoped_refptr<const Extension> extension = + loader.LoadExtension(test_extension_dir.UnpackedPath()); + + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kExampleCom)); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kChromiumOrg)); + + ScriptingPermissionsModifier(profile(), extension) + .SetWithholdHostPermissions(true); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kExampleCom)); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kChromiumOrg)); + + ScriptingPermissionsModifier(profile(), extension) + .GrantHostPermission(kExampleCom); + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kExampleCom)); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kChromiumOrg)); + + { + TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile())); + service()->ReloadExtension(extension->id()); + extension = base::WrapRefCounted(observer.WaitForExtensionLoaded()); + } + EXPECT_TRUE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kExampleCom)); + EXPECT_FALSE(extension->permissions_data() + ->active_permissions() + .explicit_hosts() + .MatchesURL(kChromiumOrg)); +} + } // namespace extensions
diff --git a/chrome/browser/feedback/feedback_profile_observer.cc b/chrome/browser/feedback/feedback_profile_observer.cc index cd8ece5..89fe114 100644 --- a/chrome/browser/feedback/feedback_profile_observer.cc +++ b/chrome/browser/feedback/feedback_profile_observer.cc
@@ -50,10 +50,11 @@ void FeedbackProfileObserver::QueueSingleReport( feedback::FeedbackUploader* uploader, - const std::string& data) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&FeedbackUploaderChrome::QueueReport, - uploader->AsWeakPtr(), data)); + std::unique_ptr<std::string> data) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&FeedbackUploaderChrome::QueueReport, + uploader->AsWeakPtr(), std::move(data))); } void FeedbackProfileObserver::QueueUnsentReports( @@ -61,11 +62,11 @@ feedback::FeedbackUploaderChrome* uploader = feedback::FeedbackUploaderFactoryChrome::GetForBrowserContext(context); uploader->task_runner()->PostTask( - FROM_HERE, - base::BindOnce( - &FeedbackReport::LoadReportsAndQueue, - uploader->feedback_reports_path(), - base::Bind(&FeedbackProfileObserver::QueueSingleReport, uploader))); + FROM_HERE, base::BindOnce(&FeedbackReport::LoadReportsAndQueue, + uploader->feedback_reports_path(), + base::BindRepeating( + &FeedbackProfileObserver::QueueSingleReport, + uploader))); } } // namespace feedback
diff --git a/chrome/browser/feedback/feedback_profile_observer.h b/chrome/browser/feedback/feedback_profile_observer.h index 6f88388..d8f4dbcf 100644 --- a/chrome/browser/feedback/feedback_profile_observer.h +++ b/chrome/browser/feedback/feedback_profile_observer.h
@@ -41,7 +41,7 @@ void QueueUnsentReports(content::BrowserContext* context); static void QueueSingleReport(feedback::FeedbackUploader* uploader, - const std::string& data); + std::unique_ptr<std::string> data); // Used to track creation of profiles so we can load any unsent reports // for that profile.
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index cbe8adec..c09eaae 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -219,6 +219,11 @@ const char kContextualSuggestionsSlimPeekUIDescription[] = "Use a slimmer peek UI for the contextual suggestions bottom sheet."; +const char kContextualSuggestionsOptOutName[] = + "Contextual Suggestions Opt-out"; +const char kContextualSuggestionsOptOutDescription[] = + "If enabled, allows the user to opt out of contextual suggestions."; + const char kCreditCardAssistName[] = "Credit Card Assisted Filling"; const char kCreditCardAssistDescription[] = "Enable assisted credit card filling on certain sites.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 7120fd6..d8f37bde 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -163,6 +163,9 @@ extern const char kContextualSuggestionsSlimPeekUIName[]; extern const char kContextualSuggestionsSlimPeekUIDescription[]; +extern const char kContextualSuggestionsOptOutName[]; +extern const char kContextualSuggestionsOptOutDescription[]; + extern const char kCreditCardAssistName[]; extern const char kCreditCardAssistDescription[];
diff --git a/chrome/browser/google/google_search_domain_mixing_metrics_emitter_unittest.cc b/chrome/browser/google/google_search_domain_mixing_metrics_emitter_unittest.cc index 847fe0d..2cfad92 100644 --- a/chrome/browser/google/google_search_domain_mixing_metrics_emitter_unittest.cc +++ b/chrome/browser/google/google_search_domain_mixing_metrics_emitter_unittest.cc
@@ -38,8 +38,7 @@ clock_ = clock.get(); emitter_->SetClockForTesting(std::move(clock)); - auto timer = std::make_unique<base::MockTimer>(/*retain_user_task=*/true, - /*is_repeating=*/true); + auto timer = std::make_unique<base::MockRepeatingTimer>(); timer_ = timer.get(); emitter_->SetTimerForTesting(std::move(timer)); @@ -85,7 +84,7 @@ std::unique_ptr<history::HistoryService> history_service_; std::unique_ptr<GoogleSearchDomainMixingMetricsEmitter> emitter_; base::SimpleTestClock* clock_; // Not owned. - base::MockTimer* timer_; // Not owned. + base::MockRepeatingTimer* timer_; // Not owned. }; TEST_F(GoogleSearchDomainMixingMetricsEmitterTest, FirstStart) {
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc index fa597c9..e9d912f3 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
@@ -61,8 +61,7 @@ media_sink_service_->SetDescriptionServiceForTest( std::move(mock_description_service)); - mock_timer_ = - new base::MockTimer(true /*retain_user_task*/, false /*is_repeating*/); + mock_timer_ = new base::MockOneShotTimer(); media_sink_service_->SetTimerForTest(base::WrapUnique(mock_timer_)); auto mock_app_discovery_service = @@ -109,7 +108,7 @@ TestDialRegistry test_dial_registry_; MockDeviceDescriptionService* mock_description_service_; MockDialAppDiscoveryService* mock_app_discovery_service_; - base::MockTimer* mock_timer_; + base::MockOneShotTimer* mock_timer_; std::unique_ptr<DialMediaSinkServiceImpl> media_sink_service_;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc index 5e408a4..3a9aa68 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -82,8 +82,7 @@ } void SetUp() override { - auto mock_timer = std::make_unique<base::MockTimer>( - true /*retain_user_task*/, false /*is_repeating*/); + auto mock_timer = std::make_unique<base::MockOneShotTimer>(); mock_timer_ = mock_timer.get(); media_sink_service_impl_.SetTimerForTest(std::move(mock_timer)); } @@ -130,7 +129,7 @@ TestMediaSinkService dial_media_sink_service_; std::unique_ptr<cast_channel::MockCastSocketService> mock_cast_socket_service_; - base::MockTimer* mock_timer_; + base::MockOneShotTimer* mock_timer_; CastMediaSinkServiceImpl media_sink_service_impl_; testing::NiceMock<MockObserver> observer_;
diff --git a/chrome/browser/media/router/media_router_metrics.cc b/chrome/browser/media/router/media_router_metrics.cc index d4140ad..861e3b2 100644 --- a/chrome/browser/media/router/media_router_metrics.cc +++ b/chrome/browser/media/router/media_router_metrics.cc
@@ -59,12 +59,18 @@ "MediaRouter.PresentationRequest.AvailabilityUrlType"; const char MediaRouterMetrics::kHistogramRouteCreationOutcome[] = "MediaRouter.Route.CreationOutcome"; +const char MediaRouterMetrics::kHistogramUiDeviceCount[] = + "MediaRouter.Ui.Device.Count"; const char MediaRouterMetrics::kHistogramUiDialogPaint[] = "MediaRouter.Ui.Dialog.Paint"; const char MediaRouterMetrics::kHistogramUiDialogLoadedWithData[] = "MediaRouter.Ui.Dialog.LoadedWithData"; const char MediaRouterMetrics::kHistogramUiFirstAction[] = "MediaRouter.Ui.FirstAction"; +const char MediaRouterMetrics::kHistogramStartLocalPosition[] = + "MediaRouter.Ui.Action.StartLocalPosition"; +const char MediaRouterMetrics::kHistogramStartLocalSessionSuccessful[] = + "MediaRouter.Ui.Action.StartLocalSessionSuccessful"; // static void MediaRouterMetrics::RecordMediaRouterDialogOrigin( @@ -148,4 +154,19 @@ SinkIconType::TOTAL_COUNT); } +// static +void MediaRouterMetrics::RecordDeviceCount(int device_count) { + UMA_HISTOGRAM_COUNTS_100(kHistogramUiDeviceCount, device_count); +} + +// static +void MediaRouterMetrics::RecordStartRouteDeviceIndex(int index) { + base::UmaHistogramSparse(kHistogramStartLocalPosition, std::min(index, 100)); +} + +// static +void MediaRouterMetrics::RecordStartLocalSessionSuccessful(bool success) { + UMA_HISTOGRAM_BOOLEAN(kHistogramStartLocalSessionSuccessful, success); +} + } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_metrics.h b/chrome/browser/media/router/media_router_metrics.h index 6f676ac9..d6bec41 100644 --- a/chrome/browser/media/router/media_router_metrics.h +++ b/chrome/browser/media/router/media_router_metrics.h
@@ -89,9 +89,12 @@ static const char kHistogramMediaSinkType[]; static const char kHistogramPresentationUrlType[]; static const char kHistogramRouteCreationOutcome[]; + static const char kHistogramUiDeviceCount[]; static const char kHistogramUiDialogPaint[]; static const char kHistogramUiDialogLoadedWithData[]; static const char kHistogramUiFirstAction[]; + static const char kHistogramStartLocalPosition[]; + static const char kHistogramStartLocalSessionSuccessful[]; // Records where the user clicked to open the Media Router dialog. static void RecordMediaRouterDialogOrigin( @@ -135,6 +138,17 @@ // Records the type of the sink that media is being Cast to. static void RecordMediaSinkType(SinkIconType sink_icon_type); + + // Records the number of devices shown in the Cast dialog. The device count + // may be 0. + static void RecordDeviceCount(int device_count); + + // Records the index of the device the user has started casting to on the + // devices list. The index starts at 0. + static void RecordStartRouteDeviceIndex(int index); + + // Records whether or not an attempt to start casting was successful. + static void RecordStartLocalSessionSuccessful(bool success); }; } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_metrics_unittest.cc b/chrome/browser/media/router/media_router_metrics_unittest.cc index a5dc0907..16e3575 100644 --- a/chrome/browser/media/router/media_router_metrics_unittest.cc +++ b/chrome/browser/media/router/media_router_metrics_unittest.cc
@@ -189,4 +189,45 @@ Bucket(static_cast<int>(SinkIconType::GENERIC), 1))); } +TEST(MediaRouterMetricsTest, RecordDeviceCount) { + base::HistogramTester tester; + tester.ExpectTotalCount(MediaRouterMetrics::kHistogramUiDeviceCount, 0); + + MediaRouterMetrics::RecordDeviceCount(30); + MediaRouterMetrics::RecordDeviceCount(0); + + tester.ExpectTotalCount(MediaRouterMetrics::kHistogramUiDeviceCount, 2); + EXPECT_THAT(tester.GetAllSamples(MediaRouterMetrics::kHistogramUiDeviceCount), + ElementsAre(Bucket(0, 1), Bucket(30, 1))); +} + +TEST(MediaRouterMetricsTest, RecordStartRouteDeviceIndex) { + base::HistogramTester tester; + tester.ExpectTotalCount(MediaRouterMetrics::kHistogramStartLocalPosition, 0); + + MediaRouterMetrics::RecordStartRouteDeviceIndex(30); + MediaRouterMetrics::RecordStartRouteDeviceIndex(0); + + tester.ExpectTotalCount(MediaRouterMetrics::kHistogramStartLocalPosition, 2); + EXPECT_THAT( + tester.GetAllSamples(MediaRouterMetrics::kHistogramStartLocalPosition), + ElementsAre(Bucket(0, 1), Bucket(30, 1))); +} + +TEST(MediaRouterMetricsTest, RecordStartLocalSessionSuccessful) { + base::HistogramTester tester; + tester.ExpectTotalCount( + MediaRouterMetrics::kHistogramStartLocalSessionSuccessful, 0); + + MediaRouterMetrics::RecordStartLocalSessionSuccessful(true); + MediaRouterMetrics::RecordStartLocalSessionSuccessful(false); + MediaRouterMetrics::RecordStartLocalSessionSuccessful(true); + + tester.ExpectTotalCount( + MediaRouterMetrics::kHistogramStartLocalSessionSuccessful, 3); + EXPECT_THAT(tester.GetAllSamples( + MediaRouterMetrics::kHistogramStartLocalSessionSuccessful), + ElementsAre(Bucket(false, 1), Bucket(true, 2))); +} + } // namespace media_router
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc b/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc index e5bf097e..1e87cc6 100644 --- a/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc +++ b/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc
@@ -18,6 +18,7 @@ #include "base/synchronization/lock.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/media/webrtc/desktop_media_list_observer.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +26,6 @@ #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" -#include "ui/views/test/views_test_base.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/widget.h" @@ -166,7 +166,7 @@ task_runner->PostTask(FROM_HERE, run_loop->QuitWhenIdleClosure()); } -class NativeDesktopMediaListTest : public views::ViewsTestBase { +class NativeDesktopMediaListTest : public ChromeViewsTestBase { public: NativeDesktopMediaListTest() = default; @@ -174,7 +174,7 @@ for (size_t i = 0; i < desktop_widgets_.size(); i++) desktop_widgets_[i].reset(); - ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } void AddNativeWindow(int id) {
diff --git a/chrome/browser/offline_pages/android/background_scheduler_bridge.cc b/chrome/browser/offline_pages/android/background_scheduler_bridge.cc index 38ba552..1c156c1 100644 --- a/chrome/browser/offline_pages/android/background_scheduler_bridge.cc +++ b/chrome/browser/offline_pages/android/background_scheduler_bridge.cc
@@ -22,16 +22,6 @@ namespace offline_pages { namespace android { -namespace { - -// C++ callback that delegates to Java callback. -void ProcessingDoneCallback( - const ScopedJavaGlobalRef<jobject>& j_callback_obj, bool result) { - base::android::RunCallbackAndroid(j_callback_obj, result); -} - -} // namespace - // JNI call to start request processing in scheduled mode. static jboolean JNI_BackgroundSchedulerBridge_StartScheduledProcessing( JNIEnv* env, @@ -55,7 +45,9 @@ static_cast<net::NetworkChangeNotifier::ConnectionType>( j_net_connection_type)); return coordinator->StartScheduledProcessing( - device_conditions, base::Bind(&ProcessingDoneCallback, j_callback_ref)); + device_conditions, + base::BindRepeating(&base::android::RunBooleanCallbackAndroid, + j_callback_ref)); } // JNI call to stop request processing in scheduled mode. @@ -87,7 +79,8 @@ } void BackgroundSchedulerBridge::BackupSchedule( - const TriggerConditions& trigger_conditions, long delay_in_seconds) { + const TriggerConditions& trigger_conditions, + int64_t delay_in_seconds) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> j_conditions = CreateTriggerConditions(env, trigger_conditions.require_power_connected,
diff --git a/chrome/browser/offline_pages/android/background_scheduler_bridge.h b/chrome/browser/offline_pages/android/background_scheduler_bridge.h index 59cb875..d21cfd91 100644 --- a/chrome/browser/offline_pages/android/background_scheduler_bridge.h +++ b/chrome/browser/offline_pages/android/background_scheduler_bridge.h
@@ -5,9 +5,11 @@ #ifndef CHROME_BROWSER_OFFLINE_PAGES_ANDROID_BACKGROUND_SCHEDULER_BRIDGE_H_ #define CHROME_BROWSER_OFFLINE_PAGES_ANDROID_BACKGROUND_SCHEDULER_BRIDGE_H_ -#include "components/offline_pages/core/background/scheduler.h" +#include <stdint.h> +#include <memory> #include "base/android/jni_android.h" +#include "components/offline_pages/core/background/scheduler.h" namespace offline_pages { namespace android { @@ -22,7 +24,7 @@ // Scheduler implementation. void Schedule(const TriggerConditions& trigger_conditions) override; void BackupSchedule(const TriggerConditions& trigger_conditions, - long delay_in_seconds) override; + int64_t delay_in_seconds) override; void Unschedule() override; const DeviceConditions& GetCurrentDeviceConditions() override;
diff --git a/chrome/browser/offline_pages/android/cct_request_observer.cc b/chrome/browser/offline_pages/android/cct_request_observer.cc index ea678a9..1ff1d993 100644 --- a/chrome/browser/offline_pages/android/cct_request_observer.cc +++ b/chrome/browser/offline_pages/android/cct_request_observer.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/offline_pages/android/cct_request_observer.h" +#include <utility> + #include "base/android/callback_android.h" #include "base/android/jni_int_wrapper.h" #include "base/android/jni_string.h" @@ -60,7 +62,7 @@ env, as_jint(static_cast<int>(status)), base::android::ConvertUTF8ToJavaString(env, request.client_id().id)); - base::android::RunCallbackAndroid(j_callback_, callback_info); + base::android::RunObjectCallbackAndroid(j_callback_, callback_info); } void CCTRequestObserver::OnChanged(const SavePageRequest& request) {}
diff --git a/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc index 69b895b..c1a1c55f 100644 --- a/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc +++ b/chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.cc
@@ -4,6 +4,11 @@ #include "chrome/browser/offline_pages/android/evaluation/offline_page_evaluation_bridge.h" +#include <memory> +#include <string> +#include <utility> +#include <vector> + #include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/android/jni_array.h" @@ -109,12 +114,7 @@ JNIEnv* env = base::android::AttachCurrentThread(); JNI_OfflinePageEvaluationBridge_ToJavaOfflinePageList(env, j_result_obj, result); - base::android::RunCallbackAndroid(j_callback_obj, j_result_obj); -} - -void OnPushRequestsDone(const ScopedJavaGlobalRef<jobject>& j_callback_obj, - bool result) { - base::android::RunCallbackAndroid(j_callback_obj, result); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result_obj); } void OnGetAllRequestsDone( @@ -125,13 +125,13 @@ ScopedJavaLocalRef<jobjectArray> j_result_obj = JNI_OfflinePageEvaluationBridge_CreateJavaSavePageRequests( env, std::move(all_requests)); - base::android::RunCallbackAndroid(j_callback_obj, j_result_obj); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result_obj); } void OnRemoveRequestsDone(const ScopedJavaGlobalRef<jobject>& j_callback_obj, const MultipleItemStatuses& removed_request_results) { - base::android::RunCallbackAndroid(j_callback_obj, - int(removed_request_results.size())); + base::android::RunIntCallbackAndroid( + j_callback_obj, static_cast<int>(removed_request_results.size())); } std::unique_ptr<KeyedService> GetTestingRequestCoordinator( @@ -322,10 +322,10 @@ const JavaParamRef<jobject>& j_callback_obj) { ScopedJavaGlobalRef<jobject> j_callback_ref(j_callback_obj); DCHECK(request_coordinator_); - base::android::RunCallbackAndroid(j_callback_obj, false); + base::android::RunBooleanCallbackAndroid(j_callback_obj, false); - return request_coordinator_->StartImmediateProcessing( - base::Bind(&OnPushRequestsDone, j_callback_ref)); + return request_coordinator_->StartImmediateProcessing(base::BindRepeating( + &base::android::RunBooleanCallbackAndroid, j_callback_ref)); } void OfflinePageEvaluationBridge::SavePageLater(
diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc index 0a28ef1..0c50e97 100644 --- a/chrome/browser/offline_pages/android/offline_page_bridge.cc +++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc
@@ -115,7 +115,7 @@ const OfflinePageModel::MultipleOfflinePageItemResult& result) { JNIEnv* env = base::android::AttachCurrentThread(); JNI_SavePageRequest_ToJavaOfflinePageList(env, j_result_obj, result); - base::android::RunCallbackAndroid(j_callback_obj, j_result_obj); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result_obj); } void SavePageCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj, @@ -131,7 +131,8 @@ void DeletePageCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj, OfflinePageModel::DeletePageResult result) { - base::android::RunCallbackAndroid(j_callback_obj, static_cast<int>(result)); + base::android::RunIntCallbackAndroid(j_callback_obj, + static_cast<int>(result)); } void SelectPageCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj, @@ -141,7 +142,7 @@ if (!result.empty()) j_result = JNI_SavePageRequest_ToJavaOfflinePageItem(env, result.front()); - base::android::RunCallbackAndroid(j_callback_obj, j_result); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result); } void SingleOfflinePageItemCallback( @@ -152,7 +153,7 @@ if (result) j_result = JNI_SavePageRequest_ToJavaOfflinePageItem(env, *result); - base::android::RunCallbackAndroid(j_callback_obj, j_result); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result); } void CheckForNewOfflineContentCallback( @@ -165,15 +166,7 @@ ScopedJavaLocalRef<jstring> j_result = base::android::ConvertUTF16ToJavaString(env, relevant_host); - base::android::RunCallbackAndroid(j_callback_obj, j_result); -} - -void GetLaunchUrlByOfflineIdCallback( - const ScopedJavaGlobalRef<jobject>& j_callback_obj, - const std::string& result) { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::RunCallbackAndroid(j_callback_obj, - ConvertUTF8ToJavaString(env, result)); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result); } void GetLaunchUrlBySizeAndDigestCallback( @@ -185,7 +178,7 @@ Java_OfflinePageBridge_createLoadUrlParams( env, ConvertUTF8ToJavaString(env, url.spec()), ConvertUTF8ToJavaString(env, extra_headers)); - base::android::RunCallbackAndroid(j_callback_obj, loadUrlParams); + base::android::RunObjectCallbackAndroid(j_callback_obj, loadUrlParams); } void ValidateFileCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj, @@ -200,13 +193,7 @@ launch_url = url; else launch_url = net::FilePathToFileURL(file_path); - GetLaunchUrlByOfflineIdCallback(j_callback_obj, launch_url.spec()); -} - -void AcquireFileAccessPermissionCallback( - const ScopedJavaGlobalRef<jobject>& j_callback_obj, - bool granted) { - base::android::RunCallbackAndroid(j_callback_obj, granted); + base::android::RunStringCallbackAndroid(j_callback_obj, launch_url.spec()); } ScopedJavaLocalRef<jobjectArray> JNI_SavePageRequest_CreateJavaSavePageRequests( @@ -247,7 +234,7 @@ ScopedJavaLocalRef<jobjectArray> j_result_obj = JNI_SavePageRequest_CreateJavaSavePageRequests(env, std::move(all_requests)); - base::android::RunCallbackAndroid(j_callback_obj, j_result_obj); + base::android::RunObjectCallbackAndroid(j_callback_obj, j_result_obj); } UpdateRequestResult ToUpdateRequestResult(ItemActionStatus status) { @@ -290,15 +277,13 @@ void SavePageLaterCallback(const ScopedJavaGlobalRef<jobject>& j_callback_obj, AddRequestResult value) { - base::android::RunCallbackAndroid(j_callback_obj, static_cast<int>(value)); + base::android::RunIntCallbackAndroid(j_callback_obj, static_cast<int>(value)); } void PublishPageDone( const ScopedJavaGlobalRef<jobject>& j_published_callback_obj, const base::FilePath& file_path, SavePageResult result) { - JNIEnv* env = base::android::AttachCurrentThread(); - base::FilePath file_path_or_empty; if (result != SavePageResult::SUCCESS) file_path_or_empty = file_path; @@ -306,9 +291,8 @@ UMA_HISTOGRAM_ENUMERATION("OfflinePages.Sharing.PublishInternalPageResult", result, SavePageResult::RESULT_COUNT); - base::android::RunCallbackAndroid( - j_published_callback_obj, - ConvertUTF8ToJavaString(env, file_path.value())); + base::android::RunStringCallbackAndroid(j_published_callback_obj, + file_path.value()); } } // namespace @@ -794,7 +778,7 @@ if (!coordinator) { // Callback with null to signal that results are unavailable. const JavaParamRef<jobject> empty_result(nullptr); - base::android::RunCallbackAndroid(j_callback_obj, empty_result); + base::android::RunObjectCallbackAndroid(j_callback_obj, empty_result); return; } @@ -819,7 +803,7 @@ if (!coordinator) { // Callback with null to signal that results are unavailable. const JavaParamRef<jobject> empty_result(nullptr); - base::android::RunCallbackAndroid(j_callback_obj, empty_result); + base::android::RunObjectCallbackAndroid(j_callback_obj, empty_result); return; } @@ -965,12 +949,13 @@ const ScopedJavaGlobalRef<jobject>& j_callback_obj, const OfflinePageItem* offline_page) { if (!offline_page) { - GetLaunchUrlByOfflineIdCallback(j_callback_obj, std::string()); + base::android::RunStringCallbackAndroid(j_callback_obj, std::string()); return; } if (offline_page_model_->IsArchiveInInternalDir(offline_page->file_path)) { - GetLaunchUrlByOfflineIdCallback(j_callback_obj, offline_page->url.spec()); + base::android::RunStringCallbackAndroid(j_callback_obj, + offline_page->url.spec()); return; } @@ -1034,12 +1019,12 @@ content::WebContents* web_contents = content::WebContents::FromJavaWebContents(j_web_contents); if (!web_contents) { - AcquireFileAccessPermissionCallback(j_callback_ref, false); + base::android::RunBooleanCallbackAndroid(j_callback_ref, false); return; } OfflinePageUtils::AcquireFileAccessPermission( - web_contents, - base::BindOnce(&AcquireFileAccessPermissionCallback, j_callback_ref)); + web_contents, base::BindOnce(&base::android::RunBooleanCallbackAndroid, + j_callback_ref)); } void OfflinePageBridge::NotifyIfDoneLoading() const {
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc index a9c9a7f..487544b 100644 --- a/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc
@@ -234,7 +234,7 @@ // Returns the mock timer used for buffering updates in the // PageLoadMetricsUpdateDispatcher. - base::MockTimer* GetMostRecentTimer() { + base::MockOneShotTimer* GetMostRecentTimer() { return embedder_interface_->GetMockTimer(); } @@ -248,7 +248,7 @@ // If sending the timing update caused the PageLoadMetricsUpdateDispatcher // to schedule a buffering timer, then fire it now so metrics are dispatched // to observers. - base::MockTimer* mock_timer = GetMostRecentTimer(); + base::MockOneShotTimer* mock_timer = GetMostRecentTimer(); if (mock_timer && mock_timer->IsRunning()) mock_timer->Fire(); }
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc index 25e4297..623b2885 100644 --- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc +++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc
@@ -92,7 +92,7 @@ // If sending the timing update caused the PageLoadMetricsUpdateDispatcher to // schedule a buffering timer, then fire it now so metrics are dispatched to // observers. - base::MockTimer* mock_timer = GetMockTimer(); + base::MockOneShotTimer* mock_timer = GetMockTimer(); if (mock_timer && mock_timer->IsRunning()) mock_timer->Fire(); }
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.css b/chrome/browser/resources/local_ntp/most_visited_single.css index b4394c6..c04d74c 100644 --- a/chrome/browser/resources/local_ntp/most_visited_single.css +++ b/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -381,7 +381,8 @@ opacity: 1; padding: var(--md-tile-padding); position: relative; - transition-property: background, border-color, box-shadow, opacity; + transition-property: + background, border-color, box-shadow, opacity, text-shadow; width: var(--md-tile-width); } @@ -412,6 +413,7 @@ body.dark-theme .md-tile:active .md-title { color: rgba(33, 32, 36, 0.86); + text-shadow: none; } body.dark-theme .md-tile:active .md-menu::after { @@ -500,6 +502,7 @@ body.dark-theme .md-title { color: rgb(248, 249, 250); + text-shadow: 0 0 8px 0 rgba(0,0,0,0.5); } .md-menu {
diff --git a/chrome/browser/resources/md_bookmarks/app.html b/chrome/browser/resources/md_bookmarks/app.html index 67cefaf..16ad179 100644 --- a/chrome/browser/resources/md_bookmarks/app.html +++ b/chrome/browser/resources/md_bookmarks/app.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/cr/ui/splitter.html"> <link rel="import" href="chrome://bookmarks/api_listener.html"> <link rel="import" href="chrome://bookmarks/command_manager.html"> @@ -19,7 +20,7 @@ <template> <style> :host { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); display: flex; flex-direction: column; height: 100%;
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.html b/chrome/browser/resources/md_bookmarks/command_manager.html index 12447ac7..9285409 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.html +++ b/chrome/browser/resources/md_bookmarks/command_manager.html
@@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/cr/ui/command.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> <link rel="import" href="chrome://bookmarks/dialog_focus_manager.html"> @@ -19,7 +20,7 @@ .sublabel { -webkit-margin-start: 8px; - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); text-align: end; width: 3ch; }
diff --git a/chrome/browser/resources/md_bookmarks/dnd_chip.html b/chrome/browser/resources/md_bookmarks/dnd_chip.html index a36fab5..bb7c77b 100644 --- a/chrome/browser/resources/md_bookmarks/dnd_chip.html +++ b/chrome/browser/resources/md_bookmarks/dnd_chip.html
@@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://bookmarks/shared_style.html"> @@ -51,7 +52,7 @@ #icon-wrapper { background: white; border-radius: 12px; - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); height: 24px; position: relative; width: 24px;
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.html b/chrome/browser/resources/md_bookmarks/folder_node.html index 012f0dad..358e7772 100644 --- a/chrome/browser/resources/md_bookmarks/folder_node.html +++ b/chrome/browser/resources/md_bookmarks/folder_node.html
@@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://bookmarks/actions.html"> @@ -38,7 +39,7 @@ #folder-label { -webkit-padding-end: 8px; - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); flex-grow: 1; } @@ -52,7 +53,7 @@ } #arrow { - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); margin: 0 8px; }
diff --git a/chrome/browser/resources/md_bookmarks/item.html b/chrome/browser/resources/md_bookmarks/item.html index 44b6bd68..a031adb 100644 --- a/chrome/browser/resources/md_bookmarks/item.html +++ b/chrome/browser/resources/md_bookmarks/item.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://bookmarks/actions.html"> @@ -37,7 +38,7 @@ #website-url { -webkit-margin-start: 20px; - /* Transparent version of --secondary-text-color */ + /* Transparent version of --cr-secondary-text-color */ color: rgba(0, 0, 0, 0.54); display: none; flex: 1; @@ -49,7 +50,7 @@ } #icon { - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); flex: none; }
diff --git a/chrome/browser/resources/md_bookmarks/shared_style.html b/chrome/browser/resources/md_bookmarks/shared_style.html index bfdd246..353cd3e 100644 --- a/chrome/browser/resources/md_bookmarks/shared_style.html +++ b/chrome/browser/resources/md_bookmarks/shared_style.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://bookmarks/shared_vars.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <dom-module id="shared-style"> <template> @@ -9,7 +10,7 @@ } paper-icon-button-light.more-vert-button div { - border: 2px solid var(--secondary-text-color); + border: 2px solid var(--cr-secondary-text-color); border-radius: 2px; margin: 1px 8px; pointer-events: none;
diff --git a/chrome/browser/resources/md_bookmarks/shared_vars.html b/chrome/browser/resources/md_bookmarks/shared_vars.html index a51a40d..b4489f77 100644 --- a/chrome/browser/resources/md_bookmarks/shared_vars.html +++ b/chrome/browser/resources/md_bookmarks/shared_vars.html
@@ -14,8 +14,6 @@ --iron-icon-height: 20px; --iron-icon-width: 20px; --min-sidebar-width: 256px; - --primary-text-color: var(--google-grey-900); - --secondary-text-color: var(--google-grey-refresh-700); --splitter-width: 15px; } </style>
diff --git a/chrome/browser/resources/md_history/app.html b/chrome/browser/resources/md_history/app.html index 13481a8..9afa904 100644 --- a/chrome/browser/resources/md_history/app.html +++ b/chrome/browser/resources/md_history/app.html
@@ -1,4 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/cr/ui.html"> <link rel="import" href="chrome://resources/html/cr/ui/command.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-media-query/iron-media-query.html"> @@ -17,7 +19,7 @@ <template> <style include="shared-style"> :host { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); display: block; height: 100%; line-height: 1.54; /* 20px. */
diff --git a/chrome/browser/resources/md_history/history_item.html b/chrome/browser/resources/md_history/history_item.html index 64aae9e..f80fda1 100644 --- a/chrome/browser/resources/md_history/history_item.html +++ b/chrome/browser/resources/md_history/history_item.html
@@ -79,7 +79,7 @@ /* #checkbox[unresolved] styling is necessary since cr-checkbox is being lazy-loaded. */ #checkbox[unresolved] { - border: 2px solid var(--secondary-text-color); + border: 2px solid var(--cr-secondary-text-color); border-radius: 2px; content: ''; display: block; @@ -95,7 +95,7 @@ #domain { -webkit-margin-start: 16px; - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); flex-shrink: 0; }
diff --git a/chrome/browser/resources/md_history/shared_style.html b/chrome/browser/resources/md_history/shared_style.html index 37273cbd..6b30fd7 100644 --- a/chrome/browser/resources/md_history/shared_style.html +++ b/chrome/browser/resources/md_history/shared_style.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://history/shared_vars.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <dom-module id="shared-style"> <template> @@ -43,7 +44,7 @@ .website-title { -webkit-margin-start: 16px; - color: var(--primary-text-color); + color: var(--cr-primary-text-color); overflow: hidden; text-decoration: none; text-overflow: ellipsis; @@ -63,7 +64,7 @@ } paper-icon-button-light.more-vert-button div { - border: 2px solid var(--secondary-text-color); + border: 2px solid var(--cr-secondary-text-color); border-radius: 2px; margin: 1px 8px; pointer-events: none;
diff --git a/chrome/browser/resources/md_history/shared_vars.html b/chrome/browser/resources/md_history/shared_vars.html index 5fbfc8e..ee1e436 100644 --- a/chrome/browser/resources/md_history/shared_vars.html +++ b/chrome/browser/resources/md_history/shared_vars.html
@@ -2,7 +2,6 @@ <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/default-theme.html"> <custom-style> <style is="custom-style"> @@ -27,8 +26,6 @@ --iron-icon-height: var(--cr-icon-size); --iron-icon-width: var(--cr-icon-size); --link-color: var(--google-blue-700); - --primary-text-color: var(--google-grey-900); - --secondary-text-color: var(--google-grey-refresh-700); --separator-color: rgba(0, 0, 0, 0.08); --side-bar-width: 256px; --sidebar-footer-text-color: #6e6e6e;
diff --git a/chrome/browser/resources/md_history/synced_device_card.html b/chrome/browser/resources/md_history/synced_device_card.html index 3bae105..9efd7cc 100644 --- a/chrome/browser/resources/md_history/synced_device_card.html +++ b/chrome/browser/resources/md_history/synced_device_card.html
@@ -33,7 +33,7 @@ } #last-update-time { - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); } #title-left-content { @@ -49,7 +49,7 @@ #right-buttons { -webkit-margin-end: 12px; - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); } #collapse {
diff --git a/chrome/browser/resources/md_history/synced_device_manager.html b/chrome/browser/resources/md_history/synced_device_manager.html index 90054b9..0679f90 100644 --- a/chrome/browser/resources/md_history/synced_device_manager.html +++ b/chrome/browser/resources/md_history/synced_device_manager.html
@@ -1,4 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/html/cr/ui/focus_grid.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> @@ -6,6 +7,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://history/shared_style.html"> <link rel="import" href="chrome://history/synced_device_card.html"> @@ -46,7 +48,7 @@ } #sign-in-promo-desc { - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); font-size: 123%; margin-top: 10px; }
diff --git a/chrome/browser/resources/md_user_manager/create_profile.html b/chrome/browser/resources/md_user_manager/create_profile.html index 6eea5e1..3bda994 100644 --- a/chrome/browser/resources/md_user_manager/create_profile.html +++ b/chrome/browser/resources/md_user_manager/create_profile.html
@@ -6,6 +6,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> <link rel="import" href="chrome://resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> @@ -25,7 +26,7 @@ } .container { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); width: var(--page-width); }
diff --git a/chrome/browser/resources/md_user_manager/error_dialog.html b/chrome/browser/resources/md_user_manager/error_dialog.html index cd2feba9..dcefc70 100644 --- a/chrome/browser/resources/md_user_manager/error_dialog.html +++ b/chrome/browser/resources/md_user_manager/error_dialog.html
@@ -2,12 +2,13 @@ <link rel="import" href="/shared_styles.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <dom-module id="error-dialog"> <template> <style include="shared-styles"> :host { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); } #message {
diff --git a/chrome/browser/resources/md_user_manager/shared_styles.html b/chrome/browser/resources/md_user_manager/shared_styles.html index 6291983..bd8feb6 100644 --- a/chrome/browser/resources/md_user_manager/shared_styles.html +++ b/chrome/browser/resources/md_user_manager/shared_styles.html
@@ -1,3 +1,4 @@ +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> @@ -7,7 +8,6 @@ :root { --error-color: var(--google-red-700); --page-width: 624px; - --primary-text-color: var(--google-grey-900); --title-icon-color: var(--paper-grey-500); --user-manager-separator-line: 1px solid rgba(0, 0, 0, .12); }
diff --git a/chrome/browser/resources/md_user_manager/user_manager.html b/chrome/browser/resources/md_user_manager/user_manager.html index b069169..9b375fb 100644 --- a/chrome/browser/resources/md_user_manager/user_manager.html +++ b/chrome/browser/resources/md_user_manager/user_manager.html
@@ -87,7 +87,7 @@ .pod { @apply --cr-card-elevation; border-radius: var(--cr-card-border-radius); - color: var(--primary-text-color); + color: var(--cr-primary-text-color); cursor: default; height: auto; transform: none; @@ -133,7 +133,6 @@ .pod .main-pane .name-container .name, .reauth-hint-container .reauth-name-hint { - color: inherit; font-size: inherit; margin: 0; padding: 0; @@ -282,8 +281,12 @@ height: auto; } + .action-box-menu-title-name { + color: var(--cr-primary-text-color); + } + .action-box-menu-title-email { - color: var(--paper-grey-600); + color: var(--cr-secondary-text-color); } .action-box-menu-remove {
diff --git a/chrome/browser/resources/md_user_manager/user_manager_tutorial.html b/chrome/browser/resources/md_user_manager/user_manager_tutorial.html index 1b380431..c6b4913 100644 --- a/chrome/browser/resources/md_user_manager/user_manager_tutorial.html +++ b/chrome/browser/resources/md_user_manager/user_manager_tutorial.html
@@ -63,7 +63,7 @@ } .slide-contents { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); padding: 0 20px; text-align: center; }
diff --git a/chrome/browser/resources/pdf/elements/shared-vars.html b/chrome/browser/resources/pdf/elements/shared-vars.html index da5f14a..2ba13040 100644 --- a/chrome/browser/resources/pdf/elements/shared-vars.html +++ b/chrome/browser/resources/pdf/elements/shared-vars.html
@@ -5,7 +5,6 @@ <custom-style> <style is="custom-style"> html { - --primary-text-color: var(--google-grey-900); --iron-icon-height: 20px; --iron-icon-width: 20px; --paper-icon-button: {
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html index 95d7588..c042447 100644 --- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html +++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
@@ -1,7 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/web-animations.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <dom-module id="viewer-toolbar-dropdown"> <template> @@ -29,7 +31,7 @@ @apply --shadow-elevation-2dp; background-color: rgb(256, 256, 256); border-radius: 4px; - color: var(--primary-text-color); + color: var(--cr-primary-text-color); overflow-y: hidden; padding-bottom: 2px; width: 260px;
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index ce73eea..b189a1b 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -20,7 +20,7 @@ h2 { align-items: center; align-self: flex-start; - color: var(--google-grey-700); + color: var(--google-grey-refresh-700); display: flex; font-size: inherit; font-weight: 500; @@ -326,7 +326,7 @@ } .column-header { - color: var(--google-grey-700); + color: var(--google-grey-refresh-700); font-size: inherit; font-weight: 400; }
diff --git a/chrome/browser/resources/settings/settings_vars_css.html b/chrome/browser/resources/settings/settings_vars_css.html index 08ace9e..f967fea 100644 --- a/chrome/browser/resources/settings/settings_vars_css.html +++ b/chrome/browser/resources/settings/settings_vars_css.html
@@ -1,6 +1,5 @@ -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/default-theme.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <!-- Common css variables for Material Design settings. --> <custom-style> @@ -29,7 +28,7 @@ padding-top: 0; } - --settings-nav-grey: rgb(90, 90, 90); + --settings-nav-grey: var(--google-grey-refresh-700); --settings-page-vertical-margin: 21px;
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc index bb5bb09..b837fdd 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc
@@ -21,7 +21,7 @@ using base::android::ConvertUTF8ToJavaString; using base::android::JavaParamRef; using base::android::JavaRef; -using base::android::RunCallbackAndroid; +using base::android::RunBooleanCallbackAndroid; using base::android::ScopedJavaGlobalRef; void JNI_ChildAccountService_ListenForChildStatusReceived( @@ -31,10 +31,9 @@ ProfileManager* profile_manager = g_browser_process->profile_manager(); ChildAccountService* service = ChildAccountServiceFactory::GetForProfile( profile_manager->GetLastUsedProfile()); - // Needed to disambiguate RunCallbackAndroid - void (*runCallback)(const JavaRef<jobject>&, bool) = &RunCallbackAndroid; - service->AddChildStatusReceivedCallback(base::BindOnce( - runCallback, ScopedJavaGlobalRef<jobject>(callback), true)); + service->AddChildStatusReceivedCallback( + base::BindOnce(&RunBooleanCallbackAndroid, + ScopedJavaGlobalRef<jobject>(callback), true)); } void ReauthenticateChildAccount(content::WebContents* web_contents,
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index f35f89d..228bee6 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -245,6 +245,48 @@ } IN_PROC_BROWSER_TEST_P(SingleClientBookmarksSyncTestIncludingUssTests, + CommitLocalCreations) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + // Starting state: + // other_node + // -> top + // -> tier1_a + // -> http://mail.google.com "tier1_a_url0" + // -> http://www.pandora.com "tier1_a_url1" + // -> http://www.facebook.com "tier1_a_url2" + // -> tier1_b + // -> http://www.nhl.com "tier1_b_url0" + const BookmarkNode* top = AddFolder( + kSingleProfileIndex, GetOtherNode(kSingleProfileIndex), 0, "top"); + const BookmarkNode* tier1_a = + AddFolder(kSingleProfileIndex, top, 0, "tier1_a"); + const BookmarkNode* tier1_b = + AddFolder(kSingleProfileIndex, top, 1, "tier1_b"); + const BookmarkNode* tier1_a_url0 = + AddURL(kSingleProfileIndex, tier1_a, 0, "tier1_a_url0", + GURL("http://mail.google.com")); + const BookmarkNode* tier1_a_url1 = + AddURL(kSingleProfileIndex, tier1_a, 1, "tier1_a_url1", + GURL("http://www.pandora.com")); + const BookmarkNode* tier1_a_url2 = + AddURL(kSingleProfileIndex, tier1_a, 2, "tier1_a_url2", + GURL("http://www.facebook.com")); + const BookmarkNode* tier1_b_url0 = + AddURL(kSingleProfileIndex, tier1_b, 0, "tier1_b_url0", + GURL("http://www.nhl.com")); + EXPECT_TRUE(tier1_a_url0); + EXPECT_TRUE(tier1_a_url1); + EXPECT_TRUE(tier1_a_url2); + EXPECT_TRUE(tier1_b_url0); + // Setup sync, wait for its completion, and make sure changes were synced. + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE( + UpdatedProgressMarkerChecker(GetSyncService(kSingleProfileIndex)).Wait()); + EXPECT_TRUE(ModelMatchesVerifier(kSingleProfileIndex)); +} + +IN_PROC_BROWSER_TEST_P(SingleClientBookmarksSyncTestIncludingUssTests, InjectedBookmark) { std::string title = "Montreal Canadiens"; fake_server::EntityBuilderFactory entity_builder_factory;
diff --git a/chrome/browser/task_manager/test_task_manager.cc b/chrome/browser/task_manager/test_task_manager.cc index b12d21f..6fe031a 100644 --- a/chrome/browser/task_manager/test_task_manager.cc +++ b/chrome/browser/task_manager/test_task_manager.cc
@@ -9,8 +9,7 @@ TestTaskManager::TestTaskManager() : handle_(base::kNullProcessHandle), pid_(base::kNullProcessId) { - set_timer_for_testing( - std::unique_ptr<base::Timer>(new base::MockTimer(true, true))); + set_timer_for_testing(std::make_unique<base::MockRepeatingTimer>()); } TestTaskManager::~TestTaskManager() {
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc index 07855448..c1c8dab 100644 --- a/chrome/browser/ui/android/context_menu_helper.cc +++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -6,7 +6,7 @@ #include <stdint.h> -#include <vector> +#include <map> #include "base/android/callback_android.h" #include "base/android/jni_string.h" @@ -51,14 +51,14 @@ protected: void OnImageDecoded(const SkBitmap& decoded_image) override { - base::android::RunCallbackAndroid(jcallback_, - gfx::ConvertToJavaBitmap(&decoded_image)); + base::android::RunObjectCallbackAndroid( + jcallback_, gfx::ConvertToJavaBitmap(&decoded_image)); delete this; } void OnDecodeImageFailed() override { base::android::ScopedJavaLocalRef<jobject> j_bitmap; - base::android::RunCallbackAndroid(jcallback_, j_bitmap); + base::android::RunObjectCallbackAndroid(jcallback_, j_bitmap); delete this; } @@ -77,7 +77,7 @@ const base::android::JavaRef<jobject>& jcallback, const std::vector<uint8_t>& thumbnail_data, const gfx::Size& original_size) { - base::android::RunCallbackAndroid(jcallback, thumbnail_data); + base::android::RunByteArrayCallbackAndroid(jcallback, thumbnail_data); } void OnRetrieveImageForContextMenu( @@ -94,7 +94,7 @@ : web_contents_(web_contents) { JNIEnv* env = base::android::AttachCurrentThread(); java_obj_.Reset( - env, Java_ContextMenuHelper_create(env, reinterpret_cast<long>(this), + env, Java_ContextMenuHelper_create(env, reinterpret_cast<int64_t>(this), web_contents_->GetJavaWebContents()) .obj()); DCHECK(!java_obj_.is_null());
diff --git a/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc b/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc index ec6ac58..5654f87 100644 --- a/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc +++ b/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc
@@ -80,7 +80,7 @@ ASSERT_TRUE(extension); extensions::ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension)) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); content::WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc index c73c1ea..28b2981 100644 --- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc +++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -693,7 +693,7 @@ extension_ = LoadExtension(extension_dir_.UnpackedPath()); ASSERT_TRUE(extension_); extensions::ScriptingPermissionsModifier(profile(), extension_) - .SetWithholdAllUrls(true); + .SetWithholdHostPermissions(true); } const extensions::Extension* extension() const { return extension_.get(); }
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc index 394f565..e162057 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/ui/autofill/autofill_popup_controller.h" #include "chrome/browser/ui/autofill/autofill_popup_layout_model.h" #include "chrome/browser/ui/views/autofill/autofill_popup_view_native_views.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "components/autofill/core/browser/popup_item_ids.h" #include "components/autofill/core/browser/suggestion.h" #include "testing/gmock/include/gmock/gmock.h" @@ -20,7 +20,6 @@ #include "ui/aura/test/aura_test_base.h" #include "ui/events/base_event_utils.h" #include "ui/events/test/event_generator.h" -#include "ui/views/test/views_test_base.h" namespace { @@ -112,18 +111,13 @@ std::vector<autofill::Suggestion> suggestions_; }; -class AutofillPopupViewNativeViewsTest : public views::ViewsTestBase { +class AutofillPopupViewNativeViewsTest : public ChromeViewsTestBase { public: AutofillPopupViewNativeViewsTest() = default; ~AutofillPopupViewNativeViewsTest() override = default; void SetUp() override { - views::ViewsTestBase::SetUp(); - - // The layout provider is meant to be a singleton, but it is not initialized - // for unit tests. Constructing one here makes it globally available, which - // is later used by the view during initialization. - layout_provider_ = std::make_unique<ChromeLayoutProvider>(); + ChromeViewsTestBase::SetUp(); CreateWidget(); generator_.reset(new ui::test::EventGenerator(widget_.GetNativeWindow())); @@ -134,7 +128,7 @@ if (!widget_.IsClosed()) widget_.Close(); view_.reset(); - views::ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } void CreateAndShowView(const std::vector<int>& ids) { @@ -163,7 +157,6 @@ std::unique_ptr<ui::test::EventGenerator> generator_; private: - std::unique_ptr<ChromeLayoutProvider> layout_provider_; DISALLOW_COPY_AND_ASSIGN(AutofillPopupViewNativeViewsTest); };
diff --git a/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc b/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc index fd649db..c925fad 100644 --- a/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc +++ b/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc
@@ -73,8 +73,7 @@ void SetUp() override { std::unique_ptr<TestConfirmQuitBubble> bubble = std::make_unique<TestConfirmQuitBubble>(); - std::unique_ptr<base::MockTimer> timer = - std::make_unique<base::MockTimer>(false, false); + auto timer = std::make_unique<base::MockOneShotTimer>(); bubble_ = bubble.get(); timer_ = timer.get(); controller_.reset(new TestConfirmQuitBubbleController( @@ -112,7 +111,9 @@ TestConfirmQuitBubble* bubble_; // Owned by |controller_|. - base::MockTimer* timer_; + base::MockOneShotTimer* timer_; + + bool quit_called_ = false; }; // Pressing and holding the shortcut should quit.
diff --git a/chrome/browser/ui/views/download/download_item_view_unittest.cc b/chrome/browser/ui/views/download/download_item_view_unittest.cc index 1f17176..fff7f40 100644 --- a/chrome/browser/ui/views/download/download_item_view_unittest.cc +++ b/chrome/browser/ui/views/download/download_item_view_unittest.cc
@@ -5,11 +5,11 @@ #include "chrome/browser/ui/views/download/download_item_view.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/label.h" -#include "ui/views/test/views_test_base.h" -using DownloadItemViewDangerousDownloadLabelTest = views::ViewsTestBase; +using DownloadItemViewDangerousDownloadLabelTest = ChromeViewsTestBase; TEST_F(DownloadItemViewDangerousDownloadLabelTest, AdjustTextAndGetSize) { // For very short label that can fit in a single line, no need to do any
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash.h b/chrome/browser/ui/views/frame/browser_frame_ash.h index 687010e1..fa2a308 100644 --- a/chrome/browser/ui/views/frame/browser_frame_ash.h +++ b/chrome/browser/ui/views/frame/browser_frame_ash.h
@@ -19,11 +19,6 @@ public: BrowserFrameAsh(BrowserFrame* browser_frame, BrowserView* browser_view); - // The color used for the frame when showing a non-tabbed WebUI, such as - // the Settings window. - static constexpr SkColor kMdWebUiFrameColor = - SkColorSetARGB(0xff, 0x25, 0x4f, 0xae); - protected: ~BrowserFrameAsh() override;
diff --git a/chrome/browser/ui/views/frame/browser_frame_mash.cc b/chrome/browser/ui/views/frame/browser_frame_mash.cc index a742b6a7..d29d2ef 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mash.cc +++ b/chrome/browser/ui/views/frame/browser_frame_mash.cc
@@ -75,15 +75,6 @@ properties[ash::mojom::kCanConsumeSystemKeys_Property] = mojo::ConvertTo<std::vector<uint8_t>>( static_cast<int64_t>(browser->is_app())); - // Set the frame color for WebUI windows, e.g. settings. - if (!browser->is_type_tabbed() && browser->is_trusted_source()) { - properties[ui::mojom::WindowManager::kFrameActiveColor_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int64_t>(BrowserFrameAsh::kMdWebUiFrameColor)); - properties[ui::mojom::WindowManager::kFrameInactiveColor_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int64_t>(BrowserFrameAsh::kMdWebUiFrameColor)); - } aura::WindowTreeHostMusInitParams window_tree_host_init_params = aura::CreateInitParamsForTopLevel(
diff --git a/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm b/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm index b19334b..976f809 100644 --- a/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm +++ b/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm
@@ -15,19 +15,13 @@ @interface NSWindow (PrivateAPI) + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle; - -// Available in later point releases of 10.10. On 10.11+, use the public -// -performWindowDragWithEvent: instead. -- (void)beginWindowDragWithEvent:(NSEvent*)event; @end -// Weak lets Chrome launch even if a future macOS doesn't have NSThemeFrame. -WEAK_IMPORT_ATTRIBUTE -@interface NSThemeFrame : NSView +@interface NSThemeFrame (PrivateAPI) - (CGFloat)_titlebarHeight; @end -@interface BrowserWindowFrame : NSThemeFrame +@interface BrowserWindowFrame : NativeWidgetMacNSWindowTitledFrame @end @implementation BrowserWindowFrame @@ -78,20 +72,6 @@ return NSZeroRect; } -// Lets the window be dragged by its title bar on 10.11 and older. -- (void)mouseDown:(NSEvent*)event { - if (@available(macOS 10.12, *)) - ; // Not needed on 10.12 and up. - else if (@available(macOS 10.11, *)) - [self.window performWindowDragWithEvent:event]; - else if ([self.window - respondsToSelector:@selector(beginWindowDragWithEvent:)]) - [self.window beginWindowDragWithEvent:event]; - else - NOTREACHED(); - [super mouseDown:event]; -} - @end @implementation BrowserNativeWidgetWindow @@ -107,13 +87,6 @@ return [super frameViewClassForStyleMask:windowStyle]; } -// The base implementation returns YES if the window's frame view is a custom -// class, which causes undesirable changes in behavior. AppKit NSWindow -// subclasses are known to override it and return NO. -- (BOOL)_usesCustomDrawing { - return NO; -} - // Handle "Move focus to the window toolbar" configured in System Preferences -> // Keyboard -> Shortcuts -> Keyboard. Usually Ctrl+F5. The argument (|unknown|) // tends to just be nil.
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index e8c24f2..43cbfebb 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/frame/browser_frame.h" -#include "chrome/browser/ui/views/frame/browser_frame_ash.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/hosted_app_button_container.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" @@ -61,6 +60,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia.h" #include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" #include "ui/views/mus/desktop_window_tree_host_mus.h" #include "ui/views/mus/window_manager_frame_values.h" #include "ui/views/rect_based_targeting_utils.h" @@ -69,6 +69,10 @@ namespace { +// The color used for the frame when showing a non-tabbed WebUI, such as +// the Settings window. +constexpr SkColor kMdWebUiFrameColor = SkColorSetARGB(0xff, 0x25, 0x4f, 0xae); + bool IsMash() { return !features::IsAshInBrowserProcess(); } @@ -113,6 +117,14 @@ return views::WindowManagerFrameValues::instance(); } +// TODO(estade): This is copied from ash::FrameCaptionButton. De-dupe. +int GetControlButtonSpacing() { + constexpr int kTouchOptimizedCaptionButtonsSpacing = 8; + return ui::MaterialDesignController::IsTouchOptimizedUiEnabled() + ? kTouchOptimizedCaptionButtonsSpacing + : 0; +} + } // namespace /////////////////////////////////////////////////////////////////////////////// @@ -175,6 +187,13 @@ AddChildView(caption_button_container_); } + Browser* browser = browser_view()->browser(); + if (IsMash() && + extensions::HostedAppBrowserController::IsForExperimentalHostedAppBrowser( + browser_view()->browser())) { + SetUpForHostedApp(nullptr); + } + // Initializing the TabIconView is expensive, so only do it if we need to. if (browser_view()->ShouldShowWindowIcon()) { window_icon_ = new TabIconView(this, nullptr); @@ -183,7 +202,6 @@ window_icon_->Update(); } - Browser* browser = browser_view()->browser(); if (browser->is_app() && IsV1AppBackButtonEnabled()) browser->command_controller()->AddCommandObserver(IDC_BACK, this); @@ -340,11 +358,20 @@ tab_strip_bounds.Intersect(GetLocalBounds()); new_tab_button_bounds.Intersect(GetLocalBounds()); } + additional_client_area.push_back(tab_strip_bounds); + if (!new_tab_button_bounds.IsEmpty()) additional_client_area.push_back(new_tab_button_bounds); } } + + if (hosted_app_button_container_) { + gfx::Rect bounds = hosted_app_button_container_->ConvertRectToWidget( + hosted_app_button_container_->GetLocalBounds()); + additional_client_area.push_back(bounds); + } + aura::WindowTreeHostMus* window_tree_host_mus = static_cast<aura::WindowTreeHostMus*>( GetWidget()->GetNativeWindow()->GetHost()); @@ -418,7 +445,6 @@ int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) { if (hosted_app_button_container_) { - DCHECK(!IsMash()); gfx::Point client_point(point); View::ConvertPointToTarget(this, hosted_app_button_container_, &client_point); @@ -453,11 +479,11 @@ } void BrowserNonClientFrameViewAsh::ResetWindowControls() { - if (IsMash()) - return; + if (!IsMash()) { + caption_button_container_->SetVisible(true); + caption_button_container_->ResetWindowControls(); + } - caption_button_container_->SetVisible(true); - caption_button_container_->ResetWindowControls(); if (hosted_app_button_container_) hosted_app_button_container_->RefreshContentSettingViews(); } @@ -477,11 +503,10 @@ void BrowserNonClientFrameViewAsh::ActivationChanged(bool active) { BrowserNonClientFrameView::ActivationChanged(active); - if (IsMash()) - return; - const bool should_paint_as_active = ShouldPaintAsActive(); - frame_header_->SetPaintAsActive(should_paint_as_active); + + if (!IsMash()) + frame_header_->SetPaintAsActive(should_paint_as_active); if (hosted_app_button_container_) hosted_app_button_container_->SetPaintAsActive(should_paint_as_active); @@ -517,6 +542,20 @@ if (profile_indicator_icon()) LayoutIncognitoButton(); + if (hosted_app_extras_container_) { + // TODO(estade): can Ash tell us the bounds of the caption buttons so + // Chrome doesn't have to re-calculate them? + gfx::Size hosted_app_size = + hosted_app_extras_container_->GetPreferredSize(); + gfx::Size caption_button_size = + GetAshLayoutSize(ash::AshLayoutSize::kNonBrowserCaption); + hosted_app_extras_container_->SetBounds( + width() - + (GetControlButtonSpacing() + caption_button_size.width()) * 3 - + hosted_app_size.width(), + 0, hosted_app_size.width(), caption_button_size.height()); + } + BrowserNonClientFrameView::Layout(); UpdateClientArea(); @@ -623,8 +662,27 @@ inactive_frame_overlay_image_registration_ = update_window_image( ash::kFrameImageOverlayInactiveKey, GetFrameOverlayImage(false)); - window->SetProperty(ash::kFrameActiveColorKey, GetFrameColor(true)); - window->SetProperty(ash::kFrameInactiveColorKey, GetFrameColor(false)); + base::Optional<SkColor> active_color, inactive_color; + if (!UsePackagedAppHeaderStyle(browser_view()->browser())) { + active_color = GetFrameColor(true); + inactive_color = GetFrameColor(false); + } else if (extensions::HostedAppBrowserController:: + IsForExperimentalHostedAppBrowser(browser_view()->browser())) { + base::Optional<SkColor> theme_color = + browser_view()->browser()->hosted_app_controller()->GetThemeColor(); + window->SetProperty(ash::kFrameIsThemedByHostedAppKey, !!theme_color); + + if (theme_color) + active_color = SkColorSetA(*theme_color, SK_AlphaOPAQUE); + } else { + active_color = kMdWebUiFrameColor; + } + + if (active_color) { + window->SetProperty(ash::kFrameActiveColorKey, *active_color); + window->SetProperty(ash::kFrameInactiveColorKey, + inactive_color.value_or(*active_color)); + } BrowserNonClientFrameView::OnThemeChanged(); } @@ -926,60 +984,20 @@ DCHECK(!IsMash()); std::unique_ptr<ash::FrameHeader> header; - Browser* browser = browser_view()->browser(); if (!UsePackagedAppHeaderStyle(browser)) { header = std::make_unique<ash::CustomFrameHeader>( frame(), this, this, !browser_view()->IsRegularOrGuestSession(), caption_button_container_); } else { - std::unique_ptr<ash::DefaultFrameHeader> default_frame_header = - std::make_unique<ash::DefaultFrameHeader>(frame(), this, - caption_button_container_); - // TODO(alancutter): Move this branch into a new HostedAppFrameHeader class. + auto default_frame_header = std::make_unique<ash::DefaultFrameHeader>( + frame(), this, caption_button_container_); if (extensions::HostedAppBrowserController:: IsForExperimentalHostedAppBrowser(browser)) { - SkColor active_color = ash::FrameCaptionButton::GetButtonColor( - ash::FrameCaptionButton::ColorMode::kDefault, - ash::kDefaultFrameColor); - - // Hosted apps apply a theme color if specified by the extension. - base::Optional<SkColor> theme_color = - browser->hosted_app_controller()->GetThemeColor(); - if (theme_color) { - theme_color = SkColorSetA(theme_color.value(), SK_AlphaOPAQUE); - default_frame_header->SetThemeColor(*theme_color); - active_color = ash::FrameCaptionButton::GetButtonColor( - ash::FrameCaptionButton::ColorMode::kThemed, *theme_color); - } - - // Add the container for extra hosted app buttons (e.g app menu button). - const float inactive_alpha_ratio = - ash::FrameCaptionButton::GetInactiveButtonColorAlphaRatio(); - SkColor inactive_color = - SkColorSetA(active_color, 255 * inactive_alpha_ratio); - hosted_app_button_container_ = new HostedAppButtonContainer( - browser_view(), active_color, inactive_color); - caption_button_container_->AddChildViewAt(hosted_app_button_container_, - 0); - - // Add the origin text. - frame_header_origin_text_ = - std::make_unique<ash::FrameHeaderOriginText>( - browser->hosted_app_controller()->GetFormattedUrlOrigin(), - active_color, inactive_color) - .release(); - AddChildView(frame_header_origin_text_); - - // Schedule the title bar animation. - base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&BrowserNonClientFrameViewAsh::StartHostedAppAnimation, - weak_factory_.GetWeakPtr()), - kTitlebarAnimationDelay); + SetUpForHostedApp(default_frame_header.get()); } else if (!browser->is_app()) { - default_frame_header->SetFrameColors(BrowserFrameAsh::kMdWebUiFrameColor, - BrowserFrameAsh::kMdWebUiFrameColor); + default_frame_header->SetFrameColors(kMdWebUiFrameColor, + kMdWebUiFrameColor); } header = std::move(default_frame_header); } @@ -989,8 +1007,70 @@ return header; } +void BrowserNonClientFrameViewAsh::SetUpForHostedApp( + ash::DefaultFrameHeader* header) { + SkColor active_color = ash::FrameCaptionButton::GetButtonColor( + ash::FrameCaptionButton::ColorMode::kDefault, ash::kDefaultFrameColor); + + // Hosted apps apply a theme color if specified by the extension. + Browser* browser = browser_view()->browser(); + base::Optional<SkColor> theme_color = + browser->hosted_app_controller()->GetThemeColor(); + if (theme_color) { + theme_color = SkColorSetA(*theme_color, SK_AlphaOPAQUE); + + // Not necessary in Mash as the frame colors are set in OnThemeChanged(). + if (!IsMash()) { + frame()->GetNativeWindow()->SetProperty( + ash::kFrameIsThemedByHostedAppKey, + !!browser->hosted_app_controller()->GetThemeColor()); + header->SetFrameColors(*theme_color, *theme_color); + } + + active_color = ash::FrameCaptionButton::GetButtonColor( + ash::FrameCaptionButton::ColorMode::kThemed, *theme_color); + } + + // Add the container for extra hosted app buttons (e.g app menu button). + const float inactive_alpha_ratio = + ash::FrameCaptionButton::GetInactiveButtonColorAlphaRatio(); + SkColor inactive_color = + SkColorSetA(active_color, 255 * inactive_alpha_ratio); + hosted_app_button_container_ = new HostedAppButtonContainer( + browser_view(), active_color, inactive_color); + + // Add the origin text. + frame_header_origin_text_ = new ash::FrameHeaderOriginText( + browser->hosted_app_controller()->GetFormattedUrlOrigin(), active_color, + inactive_color); + + if (IsMash()) { + hosted_app_extras_container_ = new views::View(); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::kHorizontal, gfx::Insets(), + GetControlButtonSpacing()); + layout->set_cross_axis_alignment( + views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); + layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_END); + hosted_app_extras_container_->SetLayoutManager(std::move(layout)); + AddChildView(hosted_app_extras_container_); + + hosted_app_extras_container_->AddChildView(frame_header_origin_text_); + hosted_app_extras_container_->AddChildView(hosted_app_button_container_); + } else { + caption_button_container_->AddChildViewAt(hosted_app_button_container_, 0); + AddChildView(frame_header_origin_text_); + } + + // Schedule the title bar animation. + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&BrowserNonClientFrameViewAsh::StartHostedAppAnimation, + weak_factory_.GetWeakPtr()), + kTitlebarAnimationDelay); +} + void BrowserNonClientFrameViewAsh::StartHostedAppAnimation() { - DCHECK(!IsMash()); frame_header_origin_text_->StartSlideAnimation(); hosted_app_button_container_->StartTitlebarAnimation( frame_header_origin_text_->AnimationDuration());
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h index fd40610..75caf98c 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
@@ -31,6 +31,7 @@ class TabIconView; namespace ash { +class DefaultFrameHeader; class FrameCaptionButton; class FrameCaptionButtonContainerView; class FrameHeaderOriginText; @@ -187,6 +188,10 @@ // Creates the frame header for the browser window. std::unique_ptr<ash::FrameHeader> CreateFrameHeader(); + // Creates views and does other setup for a hosted app. + // TODO(estade): remove the parameter as it's unused in Mash. + void SetUpForHostedApp(ash::DefaultFrameHeader* header); + // Triggers the hosted app origin and icon animations, assumes the hosted // app UI elements exist. void StartHostedAppAnimation(); @@ -210,6 +215,11 @@ // Owned by views hierarchy. ash::FrameHeaderOriginText* frame_header_origin_text_ = nullptr; + // A view that contains the extra views used for hosted apps + // (|hosted_app_button_container_| and |frame_header_origin_text_|). + // Only used in Mash. + views::View* hosted_app_extras_container_ = nullptr; + // Ash's mojom::SplitViewController. ash::mojom::SplitViewControllerPtr split_view_controller_;
diff --git a/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view_layout_unittest.cc b/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view_layout_unittest.cc index 8ded202..76bd9b6 100644 --- a/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view_layout_unittest.cc +++ b/chrome/browser/ui/views/frame/desktop_linux_browser_frame_view_layout_unittest.cc
@@ -9,9 +9,9 @@ #include "base/macros.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/nav_button_provider.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "ui/views/background.h" #include "ui/views/controls/button/image_button.h" -#include "ui/views/test/views_test_base.h" namespace { @@ -132,13 +132,13 @@ } // namespace -class DesktopLinuxBrowserFrameViewLayoutTest : public views::ViewsTestBase { +class DesktopLinuxBrowserFrameViewLayoutTest : public ChromeViewsTestBase { public: DesktopLinuxBrowserFrameViewLayoutTest() {} ~DesktopLinuxBrowserFrameViewLayoutTest() override {} void SetUp() override { - views::ViewsTestBase::SetUp(); + ChromeViewsTestBase::SetUp(); delegate_.reset(new TestLayoutDelegate); nav_button_provider_ = std::make_unique<::TestNavButtonProvider>(); @@ -162,7 +162,7 @@ void TearDown() override { widget_->CloseNow(); - views::ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } protected:
diff --git a/chrome/browser/ui/views/frame/native_widget_mac_frameless_nswindow.mm b/chrome/browser/ui/views/frame/native_widget_mac_frameless_nswindow.mm index 11cfc59..577b47d 100644 --- a/chrome/browser/ui/views/frame/native_widget_mac_frameless_nswindow.mm +++ b/chrome/browser/ui/views/frame/native_widget_mac_frameless_nswindow.mm
@@ -6,31 +6,13 @@ @interface NSWindow (PrivateAPI) + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle; -- (void)beginWindowDragWithEvent:(NSEvent*)event - NS_DEPRECATED_MAC(10_10, 10_11, "Use performWindowDragWithEvent: instead."); @end -// Weak lets Chrome launch even if a future macOS doesn't have NSThemeFrame. -WEAK_IMPORT_ATTRIBUTE -@interface NSThemeFrame : NSView -@end - -@interface NativeWidgetMacFramelessNSWindowFrame : NSThemeFrame +@interface NativeWidgetMacFramelessNSWindowFrame + : NativeWidgetMacNSWindowTitledFrame @end @implementation NativeWidgetMacFramelessNSWindowFrame - -// If a mouseDown: falls through to the frame view, turn it into a window drag. -- (void)mouseDown:(NSEvent*)event { - if (@available(macOS 10.11, *)) - [self.window performWindowDragWithEvent:event]; - else if (@available(macOS 10.10, *)) - [self.window beginWindowDragWithEvent:event]; - else - NOTREACHED(); - [super mouseDown:event]; -} - - (BOOL)_hidingTitlebar { return YES; } @@ -45,8 +27,4 @@ return [super frameViewClassForStyleMask:windowStyle]; } -- (BOOL)_usesCustomDrawing { - return NO; -} - @end
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc index 8a7ecf1..bca0d03 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h" #include "chrome/browser/ui/views/tab_icon_view.h" #include "chrome/common/chrome_switches.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "components/signin/core/browser/profile_management_switches.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/gfx/image/image_skia.h" @@ -19,7 +20,6 @@ #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/label.h" -#include "ui/views/test/views_test_base.h" namespace { @@ -88,13 +88,13 @@ } // namespace -class OpaqueBrowserFrameViewLayoutTest : public views::ViewsTestBase { +class OpaqueBrowserFrameViewLayoutTest : public ChromeViewsTestBase { public: OpaqueBrowserFrameViewLayoutTest() {} ~OpaqueBrowserFrameViewLayoutTest() override {} void SetUp() override { - views::ViewsTestBase::SetUp(); + ChromeViewsTestBase::SetUp(); delegate_.reset(new TestLayoutDelegate); auto layout = std::make_unique<OpaqueBrowserFrameViewLayout>(); @@ -131,7 +131,7 @@ void TearDown() override { widget_->CloseNow(); - views::ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } protected:
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc index c9ea4e6..c36397032 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc
@@ -7,6 +7,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/base_event_utils.h" #include "ui/events/gesture_detection/gesture_configuration.h" @@ -14,7 +15,6 @@ #include "ui/views/animation/test/ink_drop_host_view_test_api.h" #include "ui/views/animation/test/test_ink_drop.h" #include "ui/views/controls/image_view.h" -#include "ui/views/test/views_test_base.h" #if defined(OS_CHROMEOS) #include "ui/aura/window.h" @@ -118,24 +118,11 @@ } // namespace -class IconLabelBubbleViewTest : public views::ViewsTestBase { - public: - IconLabelBubbleViewTest() - : views::ViewsTestBase(), - widget_(nullptr), - view_(nullptr), - ink_drop_(nullptr), - steady_reached_(false), - shrinking_reached_(false), - minimum_size_reached_(false), - previous_width_(0), - initial_image_x_(0) {} - ~IconLabelBubbleViewTest() override {} - +class IconLabelBubbleViewTest : public ChromeViewsTestBase { protected: - // views::ViewsTestBase: + // ChromeViewsTestBase: void SetUp() override { - views::ViewsTestBase::SetUp(); + ChromeViewsTestBase::SetUp(); gfx::FontList font_list; CreateWidget(); @@ -152,7 +139,7 @@ if (widget_ && !widget_->IsClosed()) widget_->Close(); - ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } void VerifyWithAnimationStep(int step) { @@ -265,16 +252,16 @@ return view_->GetImageView()->bounds(); } - views::Widget* widget_; - TestIconLabelBubbleView* view_; - TestInkDrop* ink_drop_; + views::Widget* widget_ = nullptr; + TestIconLabelBubbleView* view_ = nullptr; + TestInkDrop* ink_drop_ = nullptr; std::unique_ptr<ui::test::EventGenerator> generator_; - bool steady_reached_; - bool shrinking_reached_; - bool minimum_size_reached_; - int previous_width_; - int initial_image_x_; + bool steady_reached_ = false; + bool shrinking_reached_ = false; + bool minimum_size_reached_ = false; + int previous_width_ = 0; + int initial_image_x_ = 0; }; // Tests layout rules for IconLabelBubbleView while simulating animation. @@ -377,7 +364,7 @@ #if defined(OS_CHROMEOS) // Verifies IconLabelBubbleView::CalculatePreferredSize() doesn't crash when // there is a widget but no compositor. -using IconLabelBubbleViewCrashTest = views::ViewsTestBase; +using IconLabelBubbleViewCrashTest = ChromeViewsTestBase; TEST_F(IconLabelBubbleViewCrashTest, GetPreferredSizeDoesntCrashWhenNoCompositor) {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index faa5a3b..87e128f 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -159,7 +159,7 @@ // TODO(tommycli): This is a placeholder duration. Replace this with the real // value once UX decides. - text_indent_animation_.SetSlideDuration(200); + text_indent_animation_.SetSlideDuration(60); } LocationBarView::~LocationBarView() {
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_view.cc index 9413cb0..f4a10d69 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.cc
@@ -4,7 +4,10 @@ #include "chrome/browser/ui/views/media_router/cast_dialog_view.h" +#include "base/location.h" #include "base/optional.h" +#include "base/time/time.h" +#include "chrome/browser/media/router/media_router_metrics.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/media_router/cast_dialog_controller.h" #include "chrome/browser/ui/media_router/cast_dialog_model.h" @@ -15,6 +18,7 @@ #include "chrome/browser/ui/views/media_router/cast_dialog_sink_button.h" #include "chrome/common/media_router/media_sink.h" #include "chrome/grit/generated_resources.h" +#include "content/public/browser/browser_thread.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" @@ -52,9 +56,11 @@ // static void CastDialogView::ShowDialog(views::View* anchor_view, CastDialogController* controller, - Browser* browser) { + Browser* browser, + const base::Time& start_time) { DCHECK(!instance_); - instance_ = new CastDialogView(anchor_view, controller, browser); + DCHECK(!start_time.is_null()); + instance_ = new CastDialogView(anchor_view, controller, browser, start_time); views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(instance_); widget->Show(); @@ -125,6 +131,7 @@ for (MediaCastMode cast_mode : {PRESENTATION, TAB_MIRROR, DESKTOP_MIRROR}) { if ((cast_mode & selected_source_) && base::ContainsKey(sink.cast_modes, cast_mode)) { + MediaRouterMetrics::RecordStartRouteDeviceIndex(selected_sink_index_); controller_->StartCasting(sink.id, cast_mode); break; } @@ -161,11 +168,14 @@ CastDialogView::CastDialogView(views::View* anchor_view, CastDialogController* controller, - Browser* browser) + Browser* browser, + const base::Time& start_time) : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), selected_source_(kTabSource), controller_(controller), - browser_(browser) { + browser_(browser), + start_time_(start_time), + weak_factory_(this) { ShowNoSinksView(); } @@ -200,6 +210,15 @@ return gfx::Size(width, GetHeightForWidth(width)); } +void CastDialogView::OnPaint(gfx::Canvas* canvas) { + views::BubbleDialogDelegateView::OnPaint(canvas); + if (!start_time_.is_null()) { + MediaRouterMetrics::RecordMediaRouterDialogPaint(base::Time::Now() - + start_time_); + start_time_ = base::Time(); + } +} + void CastDialogView::Init() { auto* provider = ChromeLayoutProvider::Get(); set_margins( @@ -211,6 +230,7 @@ 0)); SetLayoutManager(std::make_unique<views::FillLayout>()); controller_->AddObserver(this); + RecordSinkCountWithDelay(); } void CastDialogView::WindowClosing() { @@ -335,6 +355,20 @@ SizeToContents(); } +void CastDialogView::RecordSinkCountWithDelay() { + // Record the number of sinks after three seconds. This is consistent with the + // WebUI dialog. + content::BrowserThread::PostDelayedTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&CastDialogView::RecordSinkCount, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromSeconds(3)); +} + +void CastDialogView::RecordSinkCount() { + media_router::MediaRouterMetrics::RecordDeviceCount(sink_buttons_.size()); +} + // static CastDialogView* CastDialogView::instance_ = nullptr;
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.h b/chrome/browser/ui/views/media_router/cast_dialog_view.h index 97e1f1f..7a09abf0 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.h +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "base/memory/weak_ptr.h" #include "chrome/browser/ui/media_router/cast_dialog_controller.h" #include "ui/base/models/simple_menu_model.h" #include "ui/views/bubble/bubble_dialog_delegate.h" @@ -16,6 +17,10 @@ class Browser; +namespace gfx { +class Canvas; +} // namespace gfx + namespace media_router { class CastDialogSinkButton; @@ -33,7 +38,8 @@ // currently shown. static void ShowDialog(views::View* anchor_view, CastDialogController* controller, - Browser* browser); + Browser* browser, + const base::Time& start_time); // No-op if the dialog is currently not shown. static void HideDialog(); @@ -68,6 +74,7 @@ // views::View: gfx::Size CalculatePreferredSize() const override; + void OnPaint(gfx::Canvas* canvas) override; // ui::SimpleMenuModel::Delegate: bool IsCommandIdChecked(int command_id) const override; @@ -92,7 +99,8 @@ private: CastDialogView(views::View* anchor_view, CastDialogController* controller, - Browser* browser); + Browser* browser, + const base::Time& start_time); ~CastDialogView() override; // views::BubbleDialogDelegateView: @@ -120,6 +128,12 @@ void MaybeSizeToContents(); + // Posts a delayed task to record an UMA metric for the number of sinks shown. + void RecordSinkCountWithDelay(); + + // Records an UMA metric for the number of sinks shown. + void RecordSinkCount(); + // The singleton dialog instance. This is a nullptr when a dialog is not // shown. static CastDialogView* instance_; @@ -159,6 +173,11 @@ std::unique_ptr<ui::SimpleMenuModel> sources_menu_model_; std::unique_ptr<views::MenuRunner> sources_menu_runner_; + // The time when the dialog UI started initializing. + base::Time start_time_; + + base::WeakPtrFactory<CastDialogView> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(CastDialogView); };
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc index 7a9241c..aa593e9 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/ui/media_router/cast_dialog_controller.h" #include "chrome/browser/ui/media_router/cast_dialog_model.h" @@ -101,7 +102,7 @@ dialog_ = static_cast<CastDialogView*>(observer); }))); CastDialogView::ShowDialog(anchor_widget_->GetContentsView(), &controller_, - nullptr); + nullptr, base::Time::Now()); dialog_->OnModelUpdated(model); } @@ -148,7 +149,7 @@ EXPECT_CALL(controller_, AddObserver(_)); CastDialogView::ShowDialog(anchor_widget_->GetContentsView(), &controller_, - nullptr); + nullptr, base::Time::Now()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(CastDialogView::IsShowing()); EXPECT_NE(nullptr, CastDialogView::GetCurrentDialogWidget());
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc index 296c702..2aa954f 100644 --- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc +++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
@@ -75,6 +75,7 @@ } void MediaRouterDialogControllerViews::CreateMediaRouterDialog() { + base::Time dialog_creation_time = base::Time::Now(); MediaRouterDialogControllerImplBase::CreateMediaRouterDialog(); ui_ = std::make_unique<MediaRouterViewsUI>(); @@ -93,7 +94,8 @@ views::View* action_view = browser_actions->GetViewForId( ComponentToolbarActionsFactory::kMediaRouterActionId); CastDialogView::ShowDialog(action_view, ui_.get(), - chrome::FindBrowserWithWebContents(initiator())); + chrome::FindBrowserWithWebContents(initiator()), + dialog_creation_time); CastDialogView::GetCurrentDialogWidget()->AddObserver(this); }
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.cc b/chrome/browser/ui/views/media_router/media_router_views_ui.cc index d58bc61..9b054bd 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
@@ -7,8 +7,10 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/media/router/media_router_metrics.h" #include "chrome/browser/ui/media_router/media_sink_with_cast_modes.h" #include "chrome/browser/ui/media_router/ui_media_sink.h" +#include "chrome/common/media_router/route_request_result.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc index 96dc8b0..53b073f 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "components/omnibox/browser/omnibox_edit_model.h" #include "components/omnibox/browser/test_omnibox_client.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -17,7 +18,6 @@ #include "ui/events/event_constants.h" #include "ui/events/event_utils.h" #include "ui/gfx/image/image.h" -#include "ui/views/test/views_test_base.h" #include "ui/views/widget/widget.h" namespace { @@ -49,10 +49,10 @@ } // namespace -class OmniboxResultViewTest : public views::ViewsTestBase { +class OmniboxResultViewTest : public ChromeViewsTestBase { public: void SetUp() override { - ViewsTestBase::SetUp(); + ChromeViewsTestBase::SetUp(); edit_model_ = std::make_unique<OmniboxEditModel>( nullptr, nullptr, std::make_unique<TestOmniboxClient>()); @@ -77,7 +77,7 @@ void TearDown() override { widget_.reset(); - views::ViewsTestBase::TearDown(); + ChromeViewsTestBase::TearDown(); } ui::MouseEvent CreateEvent(ui::EventType type, int flags) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 8e6735d..db14f9f 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -944,7 +944,7 @@ return Textfield::HandleAccessibleAction(action_data); if (action_data.action == ax::mojom::Action::kSetValue) { - SetUserText(action_data.value, true); + SetUserText(base::UTF8ToUTF16(action_data.value), true); return true; } else if (action_data.action == ax::mojom::Action::kReplaceSelectedText) { model()->SetInputInProgress(true); @@ -952,7 +952,7 @@ SelectRange(saved_selection_for_focus_change_); saved_selection_for_focus_change_ = gfx::Range::InvalidRange(); } - InsertOrReplaceText(action_data.value); + InsertOrReplaceText(base::UTF8ToUTF16(action_data.value)); TextChanged(); return true; } else if (action_data.action == ax::mojom::Action::kSetSelection) {
diff --git a/chrome/browser/ui/views/payments/validating_textfield_unittest.cc b/chrome/browser/ui/views/payments/validating_textfield_unittest.cc index e3daf65..a37c1b0 100644 --- a/chrome/browser/ui/views/payments/validating_textfield_unittest.cc +++ b/chrome/browser/ui/views/payments/validating_textfield_unittest.cc
@@ -11,13 +11,13 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/views/payments/validation_delegate.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/textfield/textfield.h" -#include "ui/views/test/views_test_base.h" namespace payments { -class ValidatingTextfieldTest : public views::ViewsTestBase { +class ValidatingTextfieldTest : public ChromeViewsTestBase { public: ValidatingTextfieldTest() {} ~ValidatingTextfieldTest() override {}
diff --git a/chrome/browser/ui/views/payments/view_stack_unittest.cc b/chrome/browser/ui/views/payments/view_stack_unittest.cc index 60c0c75..857a599 100644 --- a/chrome/browser/ui/views/payments/view_stack_unittest.cc +++ b/chrome/browser/ui/views/payments/view_stack_unittest.cc
@@ -7,8 +7,8 @@ #include "base/observer_list.h" #include "base/run_loop.h" #include "chrome/browser/ui/views/payments/view_stack.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "ui/gfx/animation/test_animation_delegate.h" -#include "ui/views/test/views_test_base.h" class TestStackView : public views::View { public: @@ -43,7 +43,7 @@ DISALLOW_COPY_AND_ASSIGN(TestStackView); }; -class ViewStackTest : public views::ViewsTestBase { +class ViewStackTest : public ChromeViewsTestBase { public: ViewStackTest() : view_stack_(std::make_unique<ViewStack>()) { view_stack_->SetBounds(0, 0, 10, 10);
diff --git a/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc b/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc index 20afbeb..d1a4850d 100644 --- a/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc +++ b/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc
@@ -12,14 +12,14 @@ #include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "components/signin/core/browser/account_info.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/event_constants.h" #include "ui/gfx/range/range.h" #include "ui/views/controls/styled_label.h" -#include "ui/views/test/views_test_base.h" -class BubbleSyncPromoViewTest : public views::ViewsTestBase, +class BubbleSyncPromoViewTest : public ChromeViewsTestBase, public BubbleSyncPromoDelegate { public: BubbleSyncPromoViewTest() {}
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 6287f573..dca6391 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -13,6 +13,7 @@ #include "base/i18n/rtl.h" #include "base/macros.h" #include "base/metrics/user_metrics.h" +#include "base/numerics/ranges.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "build/build_config.h" @@ -100,6 +101,10 @@ // right edges of the tab. constexpr int kSeparatorThickness = 1; +// The amount of padding inside the interior path to clip children against when +// tabs are very narrow. +constexpr int kChildClipPadding = 1; + // Under material refresh, the spec for the favicon or title text is 12dips from // the left vertical edge of the tab. This edge is in the middle of the tab end // cap. The end cap is 16dips, the middle of which is 8dips. This value is the @@ -124,20 +129,25 @@ return extra_space / 2; } -// Returns the width of the tab endcap in DIP. Pre-refresh, this is the -// width of the curve making up either the outer or inner edge of the stroke. -int GetTabEndcapWidth() { - constexpr int kEndcapWidth[] = {16, 18, 24, 16, 16}; - return kEndcapWidth[MD::GetMode()]; +// For non-material-refresh mode, returns the width of the tab endcap in DIP. +// More precisely, this is the width of the curve making up either the outer or +// inner edge of the stroke. +// +// These two curves are horizontally offset by 1 px (regardless of scale); the +// total width of the endcap from tab outer edge to the inside end of the stroke +// inner edge is (GetTabEndcapWidthForLayout() * scale) + 1. +int GetTabEndcapWidthForLayout() { + const int mode = MD::GetMode(); + DCHECK_LE(mode, 2); + + constexpr int kEndcapWidth[] = {16, 18, 24}; + return kEndcapWidth[mode]; } -// Pre-refresh, endcaps paint slightly differently than they layout. +// For painting the endcaps, the top corners are actually shifted outwards 0.5 +// DIP from the grid. float GetTabEndcapWidthForPainting() { - DCHECK(!MD::IsRefreshUi()); - - // For painting the endcaps, the top corners are actually shifted outwards 0.5 - // DIP from the grid. - return GetTabEndcapWidth() - 0.5f; + return GetTabEndcapWidthForLayout() - 0.5f; } void DrawHighlight(gfx::Canvas* canvas, @@ -156,12 +166,11 @@ // Scales |bounds| by scale and aligns so that the layout portion is snapped to // the pixel grid. This ensures adjacent tabs meet up exactly during painting. -const gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, - float endcap_width, - float scale) { +const gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, float scale) { // Convert full bounds to layout bounds and scale from DIP to px. gfx::RectF aligned_bounds(bounds); - aligned_bounds.Inset(endcap_width / 2, 0); + const int corner_radius = Tab::GetCornerRadius(); + aligned_bounds.Inset(corner_radius, 0); aligned_bounds.Scale(scale); // Snap layout bounds to nearest pixels. @@ -177,7 +186,7 @@ // Convert back to full bounds. The endcap widths are not rounded, since it's // OK if the corners do not snap to the pixel grid. - aligned_bounds.Inset(-(endcap_width / 2) * scale, 0); + aligned_bounds.Inset(-corner_radius * scale, 0); return aligned_bounds; } @@ -197,11 +206,23 @@ gfx::Path GetRefreshInteriorPath(float scale, const gfx::Rect& bounds, float horizontal_inset) { - const float endcap_width = GetTabEndcapWidth(); - const float radius = (endcap_width / 2) * scale; + // TODO(pkasting): Fix this to work better with stroke heights > 0. - const gfx::RectF aligned_bounds = - ScaleAndAlignBounds(bounds, endcap_width, scale); + // Compute |extension| as the width outside the separators. This is a fixed + // value equal to the normal corner radius. + const float ideal_radius = Tab::GetCornerRadius(); + const float extension = ideal_radius * scale; + // As the separators get closer together, shrink the radius so the top (inner) + // corners touch. + const float radius = + base::ClampToRange((bounds.width() - ideal_radius * 2) / 2, 0.f, + ideal_radius) * + scale; + // When the radius shrinks, it leaves a gap between the bottom (outer) corners + // and the edge of the tab. + const float corner_gap = extension - radius; + + const gfx::RectF aligned_bounds = ScaleAndAlignBounds(bounds, scale); const float left = aligned_bounds.x(); const float top = aligned_bounds.y() + Tab::GetStrokeHeight(); const float right = aligned_bounds.right(); @@ -215,15 +236,16 @@ // Bottom right. gfx::Path right_path; right_path.moveTo(right, bottom); + right_path.rLineTo(-corner_gap, 0); right_path.arcTo(radius, radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCW_Direction, right - radius, bottom - radius); + SkPath::kCW_Direction, right - extension, bottom - radius); // Right vertical. - right_path.lineTo(right - radius, top + radius); + right_path.lineTo(right - extension, top + radius); // Top right. right_path.arcTo(radius, radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCCW_Direction, right - radius * 2, top); + SkPath::kCCW_Direction, right - extension - radius, top); // Top/bottom edges of right side. right_path.lineTo(left, top); @@ -232,16 +254,16 @@ // Top left. gfx::Path left_path; - left_path.moveTo(left + radius * 2, top); + left_path.moveTo(left + extension + radius, top); left_path.arcTo(radius, radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCCW_Direction, left + radius, top + radius); + SkPath::kCCW_Direction, left + extension, top + radius); // Left vertical. - left_path.lineTo(left + radius, bottom - radius); + left_path.lineTo(left + extension, bottom - radius); // Bottom left. left_path.arcTo(radius, radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCW_Direction, left, bottom); + SkPath::kCW_Direction, left + corner_gap, bottom); // Bottom/top edges of left side. left_path.lineTo(right, bottom); @@ -310,12 +332,20 @@ bool extend_to_top, float scale, float stroke_thickness) { - const float endcap_width = GetTabEndcapWidth(); - const float outer_radius = (endcap_width / 2) * scale - stroke_thickness; - const float inner_radius = (endcap_width / 2) * scale + stroke_thickness; + // TODO(pkasting): Fix this to work better with stroke heights > 0. - const gfx::RectF aligned_bounds = - ScaleAndAlignBounds(bounds, endcap_width, scale); + // See comments in GetRefreshInteriorPath(). + const float ideal_radius = Tab::GetCornerRadius(); + const float extension = ideal_radius * scale; + const float radius = + base::ClampToRange((bounds.width() - ideal_radius * 2) / 2, 0.f, + ideal_radius) * + scale; + const float outer_radius = std::max(radius - stroke_thickness, 0.f); + const float inner_radius = radius * 2 - outer_radius; + const float corner_gap = extension - outer_radius; + + const gfx::RectF aligned_bounds = ScaleAndAlignBounds(bounds, scale); const float left = aligned_bounds.x(); const float top = aligned_bounds.y(); const float right = aligned_bounds.right(); @@ -325,38 +355,41 @@ gfx::Path path; path.moveTo(left, bottom); path.rLineTo(0, -stroke_thickness); + path.rLineTo(corner_gap, 0); path.arcTo(outer_radius, outer_radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCCW_Direction, left + outer_radius, + SkPath::kCCW_Direction, left + extension, bottom - stroke_thickness - outer_radius); if (extend_to_top) { // Left vertical. - path.lineTo(left + outer_radius, top); + path.lineTo(left + extension, top); // Top edge. - path.lineTo(right - outer_radius, top); + path.lineTo(right - extension, top); } else { // Left vertical. - path.lineTo(left + outer_radius, top + inner_radius); + path.lineTo(left + extension, top + inner_radius); // Top left. path.arcTo(inner_radius, inner_radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCW_Direction, left + outer_radius + inner_radius, top); + SkPath::kCW_Direction, left + extension + inner_radius, top); // Top edge. - path.lineTo(right - outer_radius - inner_radius, top); + path.lineTo(right - extension - inner_radius, top); // Top right. path.arcTo(inner_radius, inner_radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCW_Direction, right - outer_radius, top + inner_radius); + SkPath::kCW_Direction, right - extension, top + inner_radius); } // Right vertical. - path.lineTo(right - outer_radius, bottom - stroke_thickness - outer_radius); + path.lineTo(right - extension, bottom - stroke_thickness - outer_radius); // Bottom right. path.arcTo(outer_radius, outer_radius, 0, SkPath::kSmall_ArcSize, - SkPath::kCCW_Direction, right, bottom - stroke_thickness); + SkPath::kCCW_Direction, right - corner_gap, + bottom - stroke_thickness); + path.rLineTo(corner_gap, 0); path.rLineTo(0, stroke_thickness); // Bottom edge. @@ -463,8 +496,7 @@ // This will cause calls to GetContentsBounds to return only the rectangle // inside the tab shape, rather than to its extents. - SetBorder(views::CreateEmptyBorder( - gfx::Insets(GetStrokeHeight(), GetTabEndcapWidth()))); + SetBorder(views::CreateEmptyBorder(GetContentsInsets())); title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); title_->SetElideBehavior(gfx::FADE_TAIL); @@ -554,7 +586,7 @@ void Tab::ShowContextMenuForView(views::View* source, const gfx::Point& point, ui::MenuSourceType source_type) { - if (!closing()) + if (!closing_) controller_->ShowContextMenuForTab(this, point, source_type); } @@ -875,22 +907,21 @@ } void Tab::PaintChildren(const views::PaintInfo& info) { - // Clip children to 1 dp inside the tab's fill path. This has no effect - // except when the tab is too narrow to completely show even one icon, at - // which point this serves to clip the favicon. + // Clip children based on the tab's fill path. This has no effect except when + // the tab is too narrow to completely show even one icon, at which point this + // serves to clip the favicon. ui::ClipRecorder clip_recorder(info.context()); // The paint recording scale for tabs is consistent along the x and y axis. const float paint_recording_scale = info.paint_recording_scale_x(); - constexpr int kFaviconPadding = 1; clip_recorder.ClipPathWithAntiAliasing( - GetInteriorPath(paint_recording_scale, bounds(), kFaviconPadding)); + GetInteriorPath(paint_recording_scale, bounds(), kChildClipPadding)); View::PaintChildren(info); } void Tab::OnPaint(gfx::Canvas* canvas) { // Don't paint if we're narrower than we can render correctly. (This should // only happen during animations). - if (width() < GetMinimumInactiveWidth() && !data().pinned) + if (!MD::IsRefreshUi() && (width() < GetMinimumInactiveWidth())) return; gfx::Path clip; @@ -912,12 +943,6 @@ OnButtonColorMaybeChanged(); } -int Tab::GetCornerRadius() const { - // TODO(pkasting): This should vary as the tab width decreases. - return ChromeLayoutProvider::Get()->GetCornerRadiusMetric( - views::EMPHASIS_HIGH); -} - SkColor Tab::GetAlertIndicatorColor(TabAlertState state) const { const bool is_touch_optimized = MD::IsTouchOptimizedUiEnabled(); // If theme provider is not yet available, return the default button @@ -1089,12 +1114,20 @@ // static int Tab::GetMinimumInactiveWidth() { - return GetTabEndcapWidth() * 2; + if (!MD::IsRefreshUi()) + return GetContentsInsets().width(); + + // Allow the favicon to shrink until only the middle 4 DIP are visible. + constexpr int kFaviconMinWidth = 4; + // kSeparatorThickness is only added for the leading separator, because the + // trailing separator is part of the overlap. + return kSeparatorThickness + (kChildClipPadding * 2) + kFaviconMinWidth + + GetOverlap(); } // static int Tab::GetMinimumActiveWidth() { - return TabCloseButton::GetWidth() + GetMinimumInactiveWidth(); + return TabCloseButton::GetWidth() + GetContentsInsets().width(); } // static @@ -1106,7 +1139,7 @@ // static int Tab::GetPinnedWidth() { constexpr int kTabPinnedContentWidth = 23; - return kTabPinnedContentWidth + GetMinimumInactiveWidth(); + return kTabPinnedContentWidth + GetContentsInsets().width(); } // static @@ -1123,7 +1156,7 @@ // * The endcap width is enough for the whole stroke outer curve, i.e. the // side diagonal plus the curves on both its ends. // * The bottom and top curve together are 4 DIP wide, so the diagonal is - // (endcap_width - 4) DIP wide. + // (endcap width - 4) DIP wide. // * The bottom and top curve are each 1.5 px high. Additionally, there is an // extra 1 px below the bottom curve and (scale - 1) px above the top curve, // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px @@ -1134,10 +1167,23 @@ } // static +int Tab::GetCornerRadius() { + return ChromeLayoutProvider::Get()->GetCornerRadiusMetric( + views::EMPHASIS_HIGH); +} + +// static +gfx::Insets Tab::GetContentsInsets() { + const int endcap_width = MD::IsRefreshUi() ? (GetCornerRadius() * 2) + : GetTabEndcapWidthForLayout(); + return gfx::Insets(GetStrokeHeight(), endcap_width); +} + +// static int Tab::GetOverlap() { - // We want to overlap the endcap portions entirely. Under refresh, we want to - // overlap by an extra dip on each end in order overlap the separators. - return GetTabEndcapWidth() + (MD::IsRefreshUi() ? kSeparatorThickness : 0); + // For refresh, overlap the separators. + return MD::IsRefreshUi() ? (GetCornerRadius() * 2 + kSeparatorThickness) + : GetTabEndcapWidthForLayout(); } // static @@ -1355,18 +1401,15 @@ gfx::ScopedCanvas scoped_canvas(canvas); const float scale = canvas->UndoDeviceScaleFactor(); - const float endcap_width = GetTabEndcapWidth(); - const gfx::RectF aligned_bounds = - ScaleAndAlignBounds(bounds(), endcap_width, scale); - + const gfx::RectF aligned_bounds = ScaleAndAlignBounds(bounds(), scale); + const int corner_radius = GetCornerRadius(); const float separator_height = GetTabSeparatorHeight() * scale; gfx::RectF leading_separator_bounds( - aligned_bounds.x() + (endcap_width / 2) * scale, + aligned_bounds.x() + corner_radius * scale, aligned_bounds.y() + (aligned_bounds.height() - separator_height) / 2, kSeparatorThickness * scale, separator_height); gfx::RectF trailing_separator_bounds( - aligned_bounds.right() - (endcap_width / 2) * scale - - kSeparatorThickness * scale, + aligned_bounds.right() - (corner_radius + kSeparatorThickness) * scale, leading_separator_bounds.y(), kSeparatorThickness * scale, separator_height); @@ -1382,12 +1425,12 @@ // If the subsequent tab is active, don't consider its hover animation value. // Without this active check and the subsequent tab is also dragged, the // trailing separator on this tab will appear invisible (alpha = 0). - Tab* subsequent_tab = controller_->GetSubsequentTab(this); + const Tab* subsequent_tab = controller_->GetSubsequentTab(this); float leading_alpha; float trailing_alpha = leading_alpha = std::max(hover_controller_.GetAnimationValue(), subsequent_tab && !subsequent_tab->IsActive() - ? subsequent_tab->hover_controller()->GetAnimationValue() + ? subsequent_tab->hover_controller_.GetAnimationValue() : 0); // When the tab's bounds are animating, inversely fade the leading or trailing // separator based on the NTB position, the tab's index, and how close to the @@ -1426,14 +1469,20 @@ void Tab::UpdateIconVisibility() { // TODO(pkasting): This whole function should go away, and we should simply // compute child visibility state in Layout(). - center_favicon_ = false; + + // Don't adjust whether we're centering the favicon during tab closure; let it + // stay however it was prior to closing the tab. This prevents the icon from + // sliding left at the end of closing a non-narrow tab. + if (!closing_) + center_favicon_ = false; + showing_icon_ = showing_alert_indicator_ = false; extra_padding_before_content_ = false; if (height() < GetLayoutConstant(TAB_HEIGHT)) return; - int available_width = std::max(0, width() - GetMinimumInactiveWidth()); + int available_width = GetContentsBounds().width(); const bool is_touch_optimized = MD::IsTouchOptimizedUiEnabled(); const int favicon_width = gfx::kFaviconSize; @@ -1510,7 +1559,10 @@ if (!showing_close_button_ && !showing_alert_indicator_ && !showing_icon_ && has_favicon) { showing_icon_ = true; - center_favicon_ = true; + + // See comments near top of function on why this conditional is here. + if (!closing_) + center_favicon_ = true; } } extra_padding_before_content_ =
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h index f1643bf..3e496b9 100644 --- a/chrome/browser/ui/views/tabs/tab.h +++ b/chrome/browser/ui/views/tabs/tab.h
@@ -110,9 +110,6 @@ void set_detached() { detached_ = true; } bool detached() const { return detached_; } - // Returns the radius of the outer corners of the tab shape. - int GetCornerRadius() const; - // Returns the color used for the alert indicator icon. SkColor GetAlertIndicatorColor(TabAlertState state) const; @@ -204,6 +201,12 @@ // horizontal deltas from those. static float GetInverseDiagonalSlope(); + // Returns the radius of the outer corners of the tab shape. + static int GetCornerRadius(); + + // Returns the insets to use for laying out tab contents. + static gfx::Insets GetContentsInsets(); + // Returns the overlap between adjacent tabs. static int GetOverlap();
diff --git a/chrome/browser/ui/views/tabs/tab_controller.h b/chrome/browser/ui/views/tabs/tab_controller.h index a45428e..07988df 100644 --- a/chrome/browser/ui/views/tabs/tab_controller.h +++ b/chrome/browser/ui/views/tabs/tab_controller.h
@@ -111,7 +111,7 @@ // Returns the next tab in the model order. Returns nullptr if there // isn't another tab beyond the given tab. - virtual Tab* GetSubsequentTab(Tab* tab) = 0; + virtual const Tab* GetSubsequentTab(const Tab* tab) = 0; // Invoked when a mouse event occurs on |source|. virtual void OnMouseEventInTab(views::View* source, @@ -157,7 +157,7 @@ // If the given tab is animating to its target destination, this returns the // target bounds. If the tab isn't moving this will return the current bounds // of the given tab. - virtual gfx::Rect GetTabAnimationTargetBounds(Tab* tab) = 0; + virtual gfx::Rect GetTabAnimationTargetBounds(const Tab* tab) = 0; // Returns the accessible tab name for this tab. virtual base::string16 GetAccessibleTabName(const Tab* tab) const = 0;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index a19c349..1d6bc07f 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -546,21 +546,63 @@ } void TabStrip::RemoveTabAt(content::WebContents* contents, int model_index) { + const bool first_unpinned_tab = model_index == GetPinnedTabCount(); + + if (!touch_layout_) + PrepareForAnimation(); + + Tab* tab = tab_at(model_index); + tab->set_closing(true); + + int old_x = tabs_.ideal_bounds(model_index).x(); + RemoveTabFromViewModel(model_index); + if (touch_layout_) { - Tab* tab = tab_at(model_index); - tab->set_closing(true); - int old_x = tabs_.ideal_bounds(model_index).x(); - // We still need to paint the tab until we actually remove it. Put it in - // tabs_closing_map_ so we can find it. - RemoveTabFromViewModel(model_index); touch_layout_->RemoveTab(model_index, GenerateIdealBoundsForPinnedTabs(nullptr), old_x); - ScheduleRemoveTabAnimation(tab); - } else if (in_tab_close_ && model_index != GetModelCount()) { - StartMouseInitiatedRemoveTabAnimation(model_index); - } else { - StartRemoveTabAnimation(model_index); } + + GenerateIdealBounds(); + AnimateToIdealBounds(); + + // TODO(pkasting): When closing multiple tabs, we get repeated RemoveTabAt() + // calls, each of which closes a new tab and thus generates different ideal + // bounds. We should update the animations of any other tabs that are + // currently being closed to reflect the new ideal bounds, or else change from + // removing one tab at a time to animating the removal of all tabs at once. + + // Compute the target bounds for animating this tab closed. The tab's left + // edge should stay joined to the right edge of the previous tab, if any. + gfx::Rect tab_bounds = tab->bounds(); + int desired_x = TabStartX(); + if (model_index > 0) { + desired_x = ideal_bounds(model_index - 1).right() - Tab::GetOverlap(); + if (first_unpinned_tab) + desired_x += GetPinnedToNonPinnedOffset(); + } + tab_bounds.set_x(desired_x); + + // The tab should animate to the width of the overlap in order to close at the + // same speed the surrounding tabs are moving, since at this width the + // subsequent tab is naturally positioned at the same X coordinate. + tab_bounds.set_width(Tab::GetOverlap()); + + // Animate the tab closed. + bounds_animator_.AnimateViewTo(tab, tab_bounds); + bounds_animator_.SetAnimationDelegate( + tab, std::make_unique<RemoveTabDelegate>(this, tab)); + + // TODO(pkasting): The first part of this conditional doesn't really make + // sense to me. Why is each condition justified? + if ((touch_layout_ || !in_tab_close_ || model_index == GetModelCount()) && + TabDragController::IsAttachedTo(this)) { + // Don't animate the new tab button when dragging tabs. Otherwise it looks + // like the new tab button magically appears from beyond the end of the tab + // strip. + bounds_animator_.StopAnimatingView(new_tab_button_); + new_tab_button_->SetBoundsRect(new_tab_button_bounds_); + } + SwapLayoutIfNecessary(); for (TabStripObserver& observer : observers_) @@ -1037,7 +1079,7 @@ return view && view->id() == VIEW_ID_TAB ? static_cast<Tab*>(view) : nullptr; } -Tab* TabStrip::GetSubsequentTab(Tab* tab) { +const Tab* TabStrip::GetSubsequentTab(const Tab* tab) { int index = GetModelIndexOfTab(tab); if (index < 0) return nullptr; @@ -1150,7 +1192,7 @@ return id; } -gfx::Rect TabStrip::GetTabAnimationTargetBounds(Tab* tab) { +gfx::Rect TabStrip::GetTabAnimationTargetBounds(const Tab* tab) { return bounds_animator_.GetTargetBounds(tab); } @@ -1309,7 +1351,7 @@ if (MD::IsRefreshUi() && GetNewTabButtonPosition() == TRAILING) { float separator_height = Tab::GetTabSeparatorHeight(); gfx::RectF separator_bounds( - new_tab_button_bounds_.x() - Tab::GetOverlap() / 2, + new_tab_button_bounds_.x() - Tab::GetCornerRadius(), (height() - separator_height) / 2, 1, separator_height); cc::PaintFlags flags; flags.setAntiAlias(true); @@ -1473,12 +1515,24 @@ GenerateIdealBounds(); - // Set the current bounds to be the correct place but 0 width. + // Insert the tab just after the current right edge of the previous tab, if + // any. gfx::Rect bounds = ideal_bounds(model_index); - bounds.set_width(0); - tab_at(model_index)->SetBoundsRect(bounds); + if (model_index > 0) { + int desired_x = + tab_at(model_index - 1)->bounds().right() - Tab::GetOverlap(); + if (model_index == GetPinnedTabCount()) + desired_x += GetPinnedToNonPinnedOffset(); + bounds.set_x(desired_x); + } + + // Start at the width of the overlap in order to animate at the same speed the + // surrounding tabs are moving, since at this width the subsequent tab is + // naturally positioned at the same X coordinate. + bounds.set_width(Tab::GetOverlap()); // Animate in to the full width. + tab_at(model_index)->SetBoundsRect(bounds); AnimateToIdealBounds(); } @@ -1488,39 +1542,6 @@ AnimateToIdealBounds(); } -void TabStrip::StartRemoveTabAnimation(int model_index) { - PrepareForAnimation(); - - // Mark the tab as closing. - Tab* tab = tab_at(model_index); - tab->set_closing(true); - - RemoveTabFromViewModel(model_index); - - ScheduleRemoveTabAnimation(tab); -} - -void TabStrip::ScheduleRemoveTabAnimation(Tab* tab) { - // Start an animation for the tabs. - GenerateIdealBounds(); - AnimateToIdealBounds(); - - // Animate the tab being closed to zero width. - gfx::Rect tab_bounds = tab->bounds(); - tab_bounds.set_width(0); - bounds_animator_.AnimateViewTo(tab, tab_bounds); - bounds_animator_.SetAnimationDelegate( - tab, std::make_unique<RemoveTabDelegate>(this, tab)); - - // Don't animate the new tab button when dragging tabs. Otherwise it looks - // like the new tab button magically appears from beyond the end of the tab - // strip. - if (TabDragController::IsAttachedTo(this)) { - bounds_animator_.StopAnimatingView(new_tab_button_); - new_tab_button_->SetBoundsRect(new_tab_button_bounds_); - } -} - void TabStrip::AnimateToIdealBounds() { for (int i = 0; i < tab_count(); ++i) { // If the tab is being dragged manually, skip it. @@ -1528,7 +1549,14 @@ if (tab->dragging() && !bounds_animator_.IsAnimating(tab)) continue; - bounds_animator_.AnimateViewTo(tab, ideal_bounds(i)); + // Also skip tabs already being animated to the same ideal bounds. Calling + // AnimateViewTo() again restarts the animation, which changes the timing of + // how the tab animates, leading to hitches. + const gfx::Rect& target_bounds = ideal_bounds(i); + if (bounds_animator_.GetTargetBounds(tab) == target_bounds) + continue; + + bounds_animator_.AnimateViewTo(tab, target_bounds); // Set an animation delegate for the tab so it will clip appropriately. // Don't do this if dragging() is true. In this case the tab was @@ -1543,7 +1571,9 @@ } } - bounds_animator_.AnimateViewTo(new_tab_button_, new_tab_button_bounds_); + if (bounds_animator_.GetTargetBounds(new_tab_button_) != + new_tab_button_bounds_) + bounds_animator_.AnimateViewTo(new_tab_button_, new_tab_button_bounds_); } bool TabStrip::ShouldHighlightCloseButtonAfterRemove() { @@ -1581,7 +1611,7 @@ // space where the outer (lower) corners are, which should be treated as // part of the grab area, so decrease the size of the remaining grab area by // that width. - width -= tab_at(tab_count() - 1)->GetCornerRadius(); + width -= Tab::GetCornerRadius(); } return width; @@ -2253,28 +2283,6 @@ AnimateToIdealBounds(); } -void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) { - PrepareForAnimation(); - - Tab* tab_closing = tab_at(model_index); - tab_closing->set_closing(true); - - // We still need to paint the tab until we actually remove it. Put it in - // tabs_closing_map_ so we can find it. - RemoveTabFromViewModel(model_index); - - GenerateIdealBounds(); - AnimateToIdealBounds(); - - gfx::Rect tab_bounds = tab_closing->bounds(); - tab_bounds.set_width(0); - bounds_animator_.AnimateViewTo(tab_closing, tab_bounds); - - // Register delegate to do cleanup when done. - bounds_animator_.SetAnimationDelegate( - tab_closing, std::make_unique<RemoveTabDelegate>(this, tab_closing)); -} - bool TabStrip::IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords) { if (!tab->visible())
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index 17e448da..db3b95a 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -255,7 +255,7 @@ void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override; bool EndDrag(EndDragReason reason) override; Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override; - Tab* GetSubsequentTab(Tab* tab) override; + const Tab* GetSubsequentTab(const Tab* tab) override; void OnMouseEventInTab(views::View* source, const ui::MouseEvent& event) override; bool ShouldPaintTab( @@ -270,7 +270,7 @@ SkColor GetTabForegroundColor(TabState state) const override; base::string16 GetAccessibleTabName(const Tab* tab) const override; int GetBackgroundResourceId(bool* custom_image) const override; - gfx::Rect GetTabAnimationTargetBounds(Tab* tab) override; + gfx::Rect GetTabAnimationTargetBounds(const Tab* tab) override; // MouseWatcherListener: void MouseMovedOutOfHost() override; @@ -338,13 +338,6 @@ // move. void StartMoveTabAnimation(); - // Starts the remove tab animation. - void StartRemoveTabAnimation(int model_index); - - // Schedules the animations and bounds changes necessary for a remove tab - // animation. - void ScheduleRemoveTabAnimation(Tab* tab); - // Animates all the views to their ideal bounds. // NOTE: this does *not* invoke GenerateIdealBounds, it uses the bounds // currently set in ideal_bounds. @@ -538,7 +531,6 @@ // Starts various types of TabStrip animations. void StartResizeLayoutAnimation(); void StartPinnedTabAnimation(); - void StartMouseInitiatedRemoveTabAnimation(int model_index); // Returns true if the specified point in TabStrip coords is within the // hit-test region of the specified Tab.
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc index 90cff0e..af0e43a 100644 --- a/chrome/browser/ui/views/tabs/tab_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -15,13 +15,13 @@ #include "chrome/browser/ui/views/tabs/tab_controller.h" #include "chrome/browser/ui/views/tabs/tab_icon.h" #include "chrome/grit/theme_resources.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/models/list_selection_model.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/favicon_size.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/label.h" -#include "ui/views/test/views_test_base.h" #include "ui/views/widget/widget.h" using views::Widget; @@ -70,7 +70,7 @@ Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override { return nullptr; } - Tab* GetSubsequentTab(Tab* tab) override { return nullptr; } + const Tab* GetSubsequentTab(const Tab* tab) override { return nullptr; } void OnMouseEventInTab(views::View* source, const ui::MouseEvent& event) override {} bool ShouldPaintTab( @@ -95,7 +95,7 @@ *custom_image = false; return IDR_THEME_TAB_BACKGROUND; } - gfx::Rect GetTabAnimationTargetBounds(Tab* tab) override { + gfx::Rect GetTabAnimationTargetBounds(const Tab* tab) override { return tab->bounds(); } base::string16 GetAccessibleTabName(const Tab* tab) const override { @@ -110,7 +110,7 @@ DISALLOW_COPY_AND_ASSIGN(FakeTabController); }; -class TabTest : public views::ViewsTestBase { +class TabTest : public ChromeViewsTestBase { public: TabTest() {} ~TabTest() override {}
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index 1a2a17c..82cc5a2 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -737,8 +737,7 @@ DVLOG(1) << "Unable to extract args."; return; } - base::UmaHistogramSparse("MediaRouter.Ui.Action.StartLocalPosition", - std::min(index, 100)); + MediaRouterMetrics::RecordStartRouteDeviceIndex(index); } void MediaRouterWebUIMessageHandler::OnReportFilter(const base::ListValue*) { @@ -800,9 +799,8 @@ DVLOG(1) << "Unable to extract args."; return; } - - UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StartLocalSessionSuccessful", - route_created_successfully); + MediaRouterMetrics::RecordStartLocalSessionSuccessful( + route_created_successfully); } void MediaRouterWebUIMessageHandler::OnReportRouteCreationOutcome( @@ -841,7 +839,7 @@ DVLOG(1) << "Unable to extract args."; return; } - UMA_HISTOGRAM_COUNTS_100("MediaRouter.Ui.Device.Count", sink_count); + MediaRouterMetrics::RecordDeviceCount(sink_count); } void MediaRouterWebUIMessageHandler::OnReportTimeToClickSink(
diff --git a/chrome/browser/vr/speech_recognizer_unittest.cc b/chrome/browser/vr/speech_recognizer_unittest.cc index 525d4cf..b838e0a 100644 --- a/chrome/browser/vr/speech_recognizer_unittest.cc +++ b/chrome/browser/vr/speech_recognizer_unittest.cc
@@ -364,8 +364,8 @@ speech_recognizer_->Start(); base::RunLoop().RunUntilIdle(); - auto mock_timer = std::make_unique<base::MockTimer>(false, false); - base::MockTimer* timer_ptr = mock_timer.get(); + auto mock_timer = std::make_unique<base::MockOneShotTimer>(); + base::MockOneShotTimer* timer_ptr = mock_timer.get(); speech_recognizer_->SetSpeechTimerForTest(std::move(mock_timer)); fake_speech_recognition_manager_->FakeSpeechRecognitionEvent(SOUND_START);
diff --git a/chrome/common/DEPS b/chrome/common/DEPS index 153fab6..0604b7a 100644 --- a/chrome/common/DEPS +++ b/chrome/common/DEPS
@@ -22,6 +22,7 @@ "+components/metrics/call_stack_profile_metrics_provider.h", "+components/metrics/call_stack_profile_params.h", "+components/metrics/child_call_stack_profile_collector.h", + "+components/metrics/call_stack_profile_builder.h", "+components/metrics/client_info.h", "+components/metrics/metrics_pref_names.h", "+components/nacl/common",
diff --git a/chrome/common/extensions/docs/server2/app.yaml b/chrome/common/extensions/docs/server2/app.yaml index 0d63986..1c4469d 100644 --- a/chrome/common/extensions/docs/server2/app.yaml +++ b/chrome/common/extensions/docs/server2/app.yaml
@@ -1,5 +1,5 @@ application: chrome-apps-doc -version: 3-56-0 +version: 3-57-0 runtime: python27 api_version: 1 threadsafe: false
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.cc b/chrome/common/media_router/discovery/media_sink_service_base.cc index 9f62d24..fc68861 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.cc +++ b/chrome/common/media_router/discovery/media_sink_service_base.cc
@@ -72,7 +72,8 @@ StartTimer(); } -void MediaSinkServiceBase::SetTimerForTest(std::unique_ptr<base::Timer> timer) { +void MediaSinkServiceBase::SetTimerForTest( + std::unique_ptr<base::OneShotTimer> timer) { discovery_timer_ = std::move(timer); }
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.h b/chrome/common/media_router/discovery/media_sink_service_base.h index b244606..fa7c038 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.h +++ b/chrome/common/media_router/discovery/media_sink_service_base.h
@@ -67,7 +67,7 @@ const base::flat_map<MediaSink::Id, MediaSinkInternal>& GetSinks() const; const MediaSinkInternal* GetSinkById(const MediaSink::Id& sink_id) const; - void SetTimerForTest(std::unique_ptr<base::Timer> timer); + void SetTimerForTest(std::unique_ptr<base::OneShotTimer> timer); protected: // Called when |discovery_timer_| expires. Informs subclass to report device @@ -100,7 +100,7 @@ // the metrics are recorded accurately, a small delay is introduced after a // sink list change in order for the discovery process to reach a steady // state before the metrics are recorded. - std::unique_ptr<base::Timer> discovery_timer_; + std::unique_ptr<base::OneShotTimer> discovery_timer_; // The following fields exist temporarily for sending back discovered sinks to // the Media Router extension.
diff --git a/chrome/common/media_router/test/test_helper.cc b/chrome/common/media_router/test/test_helper.cc index 1bd4289..3318eb2 100644 --- a/chrome/common/media_router/test/test_helper.cc +++ b/chrome/common/media_router/test/test_helper.cc
@@ -15,9 +15,7 @@ TestMediaSinkService::TestMediaSinkService( const OnSinksDiscoveredCallback& callback) - : MediaSinkServiceBase(callback), - timer_(new base::MockTimer(true /*retain_user_task*/, - false /*is_repeating*/)) { + : MediaSinkServiceBase(callback), timer_(new base::MockOneShotTimer()) { SetTimerForTest(base::WrapUnique(timer_)); }
diff --git a/chrome/common/media_router/test/test_helper.h b/chrome/common/media_router/test/test_helper.h index a6b2d7c..543ae95 100644 --- a/chrome/common/media_router/test/test_helper.h +++ b/chrome/common/media_router/test/test_helper.h
@@ -19,11 +19,11 @@ explicit TestMediaSinkService(const OnSinksDiscoveredCallback& callback); ~TestMediaSinkService() override; - base::MockTimer* timer() { return timer_; } + base::MockOneShotTimer* timer() { return timer_; } private: // Owned by MediaSinkService. - base::MockTimer* timer_; + base::MockOneShotTimer* timer_; DISALLOW_COPY_AND_ASSIGN(TestMediaSinkService); }; #endif // !defined(OS_ANDROID)
diff --git a/chrome/common/page_load_metrics/test/weak_mock_timer.cc b/chrome/common/page_load_metrics/test/weak_mock_timer.cc index 0fe222af..18abcd6a 100644 --- a/chrome/common/page_load_metrics/test/weak_mock_timer.cc +++ b/chrome/common/page_load_metrics/test/weak_mock_timer.cc
@@ -7,13 +7,12 @@ namespace page_load_metrics { namespace test { -WeakMockTimer::WeakMockTimer() - : MockTimer(false /* retain_user_task */, false /* is_repeating */) {} +WeakMockTimer::WeakMockTimer() {} WeakMockTimerProvider::WeakMockTimerProvider() {} WeakMockTimerProvider::~WeakMockTimerProvider() {} -base::MockTimer* WeakMockTimerProvider::GetMockTimer() const { +base::MockOneShotTimer* WeakMockTimerProvider::GetMockTimer() const { return timer_.get(); }
diff --git a/chrome/common/page_load_metrics/test/weak_mock_timer.h b/chrome/common/page_load_metrics/test/weak_mock_timer.h index 185b586..20f5c46 100644 --- a/chrome/common/page_load_metrics/test/weak_mock_timer.h +++ b/chrome/common/page_load_metrics/test/weak_mock_timer.h
@@ -13,7 +13,7 @@ namespace test { // WeakMockTimer is a MockTimer that allows clients to keep WeakPtr<>s to it. -class WeakMockTimer : public base::MockTimer, +class WeakMockTimer : public base::MockOneShotTimer, public base::SupportsWeakPtr<WeakMockTimer> { public: WeakMockTimer(); @@ -29,7 +29,7 @@ WeakMockTimerProvider(); virtual ~WeakMockTimerProvider(); - base::MockTimer* GetMockTimer() const; + base::MockOneShotTimer* GetMockTimer() const; void SetMockTimer(base::WeakPtr<WeakMockTimer> timer); private:
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index a48aa80..c81dc1d05 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -548,10 +548,10 @@ const char kLanguagePreloadEnginesSyncable[] = "settings.language.preload_engines_syncable"; -// A string pref (comma-separated list) set to the extension IMEs to be enabled. -const char kLanguageEnabledExtensionImes[] = - "settings.language.enabled_extension_imes"; -const char kLanguageEnabledExtensionImesSyncable[] = +// A string pref (comma-separated list) set to the extension and ARC IMEs to be +// enabled. +const char kLanguageEnabledImes[] = "settings.language.enabled_extension_imes"; +const char kLanguageEnabledImesSyncable[] = "settings.language.enabled_extension_imes_syncable"; // A boolean pref set to true if the IME menu is activated.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index ec4043b9..75538d8 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -212,8 +212,8 @@ extern const char kLanguagePreferredLanguagesSyncable[]; extern const char kLanguagePreloadEngines[]; extern const char kLanguagePreloadEnginesSyncable[]; -extern const char kLanguageEnabledExtensionImes[]; -extern const char kLanguageEnabledExtensionImesSyncable[]; +extern const char kLanguageEnabledImes[]; +extern const char kLanguageEnabledImesSyncable[]; extern const char kLanguageImeMenuActivated[]; extern const char kLanguageShouldMergeInputMethods[]; extern const char kLanguageSendFunctionKeys[];
diff --git a/chrome/common/thread_profiler.cc b/chrome/common/thread_profiler.cc index c363302..a82a03a 100644 --- a/chrome/common/thread_profiler.cc +++ b/chrome/common/thread_profiler.cc
@@ -15,6 +15,7 @@ #include "base/threading/sequence_local_storage_slot.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/common/stack_sampling_configuration.h" +#include "components/metrics/call_stack_profile_builder.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/call_stack_profile_params.h" #include "components/metrics/child_call_stack_profile_collector.h" @@ -192,12 +193,11 @@ return; auto profile_builder = - std::make_unique<StackSamplingProfiler::SamplingProfileBuilder>( - BindRepeating( - &ThreadProfiler::ReceiveStartupProfile, - GetReceiverCallback(CallStackProfileParams( - GetProcess(), thread, CallStackProfileParams::PROCESS_STARTUP, - CallStackProfileParams::MAY_SHUFFLE)))); + std::make_unique<CallStackProfileBuilder>(BindRepeating( + &ThreadProfiler::ReceiveStartupProfile, + GetReceiverCallback(CallStackProfileParams( + GetProcess(), thread, CallStackProfileParams::PROCESS_STARTUP, + CallStackProfileParams::MAY_SHUFFLE)))); startup_profiler_ = std::make_unique<StackSamplingProfiler>( base::PlatformThread::CurrentId(), kSamplingParams, @@ -276,12 +276,10 @@ void ThreadProfiler::StartPeriodicSamplingCollection() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // NB: Destroys the previous profiler as side effect. - auto profile_builder = - std::make_unique<StackSamplingProfiler::SamplingProfileBuilder>( - BindRepeating(&ThreadProfiler::ReceivePeriodicProfile, - GetReceiverCallback(periodic_profile_params_), - owning_thread_task_runner_, - weak_factory_.GetWeakPtr())); + auto profile_builder = std::make_unique<CallStackProfileBuilder>( + BindRepeating(&ThreadProfiler::ReceivePeriodicProfile, + GetReceiverCallback(periodic_profile_params_), + owning_thread_task_runner_, weak_factory_.GetWeakPtr())); periodic_profiler_ = std::make_unique<StackSamplingProfiler>( base::PlatformThread::CurrentId(), kSamplingParams,
diff --git a/chrome/renderer/page_load_metrics/page_timing_metrics_sender_unittest.cc b/chrome/renderer/page_load_metrics/page_timing_metrics_sender_unittest.cc index 24b9282..710dbf8d 100644 --- a/chrome/renderer/page_load_metrics/page_timing_metrics_sender_unittest.cc +++ b/chrome/renderer/page_load_metrics/page_timing_metrics_sender_unittest.cc
@@ -13,19 +13,18 @@ namespace page_load_metrics { // Thin wrapper around PageTimingMetricsSender that provides access to the -// MockTimer instance. +// MockOneShotTimer instance. class TestPageTimingMetricsSender : public PageTimingMetricsSender { public: explicit TestPageTimingMetricsSender( std::unique_ptr<PageTimingSender> page_timing_sender, mojom::PageLoadTimingPtr initial_timing) - : PageTimingMetricsSender( - std::move(page_timing_sender), - std::unique_ptr<base::Timer>(new base::MockTimer(false, false)), - std::move(initial_timing)) {} + : PageTimingMetricsSender(std::move(page_timing_sender), + std::make_unique<base::MockOneShotTimer>(), + std::move(initial_timing)) {} - base::MockTimer* mock_timer() const { - return reinterpret_cast<base::MockTimer*>(timer()); + base::MockOneShotTimer* mock_timer() const { + return static_cast<base::MockOneShotTimer*>(timer()); } };
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.cold_state_personalized_signin_promo.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.cold_state_personalized_signin_promo.Nexus_5-19.png index dfc46d3..fab4239 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.cold_state_personalized_signin_promo.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.cold_state_personalized_signin_promo.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.download_snippet_placeholder.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.download_snippet_placeholder.Nexus_5-19.png index d179fb3..2763193 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.download_snippet_placeholder.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.download_snippet_placeholder.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.hot_state_personalized_signin_promo.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.hot_state_personalized_signin_promo.Nexus_5-19.png index ba17c3a..1ca9efc 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.hot_state_personalized_signin_promo.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.hot_state_personalized_signin_promo.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-cold_state_personalized_signin_promo.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-cold_state_personalized_signin_promo.Nexus_5-19.png index 204de464..1058711 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-cold_state_personalized_signin_promo.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-cold_state_personalized_signin_promo.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-download_snippet_placeholder.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-download_snippet_placeholder.Nexus_5-19.png index 4ac852f..71f0a6e 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-download_snippet_placeholder.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-download_snippet_placeholder.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-hot_state_personalized_signin_promo.Nexus_5-19.png b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-hot_state_personalized_signin_promo.Nexus_5-19.png index 8238b94..7acef6cc 100644 --- a/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-hot_state_personalized_signin_promo.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/ArticleSnippetsTest.modern-hot_state_personalized_signin_promo.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png index 9c34a1d..04d36d1 100644 --- a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/NewTabPageTest.modern-new_tab_page_scrolled.Nexus_5-19.png b/chrome/test/data/android/render_tests/NewTabPageTest.modern-new_tab_page_scrolled.Nexus_5-19.png index b3c9e046c..54f9dcf 100644 --- a/chrome/test/data/android/render_tests/NewTabPageTest.modern-new_tab_page_scrolled.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/NewTabPageTest.modern-new_tab_page_scrolled.Nexus_5-19.png Binary files differ
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 17522570a..d7167e3 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/test/data/android/render_tests/TileGridLayoutTest.tile_classic_offline.Nexus_5-19.png b/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_classic_offline.Nexus_5-19.png index 4b90d83..a58d9fb 100644 --- a/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_classic_offline.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_classic_offline.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_modern_offline.Nexus_5-19.png b/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_modern_offline.Nexus_5-19.png index d764304..497ec0c 100644 --- a/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_modern_offline.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/TileGridLayoutTest.tile_modern_offline.Nexus_5-19.png Binary files differ
diff --git a/chrome/test/data/webui/cr_elements/cr_input_test.js b/chrome/test/data/webui/cr_elements/cr_input_test.js index 8d77808..a6445c7 100644 --- a/chrome/test/data/webui/cr_elements/cr_input_test.js +++ b/chrome/test/data/webui/cr_elements/cr_input_test.js
@@ -157,6 +157,8 @@ }); test('focusState', function() { + assertFalse(crInput.hasAttribute('focused_')); + const underline = crInput.$.underline; const label = crInput.$.label; const originalLabelColor = getComputedStyle(label).color; @@ -168,11 +170,19 @@ test_util.eventToPromise('transitionend', underline); input.focus(); + assertTrue(crInput.hasAttribute('focused_')); assertTrue(originalLabelColor != getComputedStyle(label).color); - return whenTransitionEnd.then(() => { - assertEquals('1', getComputedStyle(underline).opacity); - assertTrue(0 != underline.offsetWidth); - }); + return whenTransitionEnd + .then(() => { + assertEquals('1', getComputedStyle(underline).opacity); + assertTrue(0 != underline.offsetWidth); + }) + .then(() => { + input.blur(); + assertFalse(crInput.hasAttribute('focused_')); + assertEquals('0', getComputedStyle(underline).opacity); + assertEquals(0, underline.offsetWidth); + }); }); test('invalidState', function() {
diff --git a/chrome/test/views/accessibility_checker_unittest.cc b/chrome/test/views/accessibility_checker_unittest.cc index 9167092..97cc9f4c 100644 --- a/chrome/test/views/accessibility_checker_unittest.cc +++ b/chrome/test/views/accessibility_checker_unittest.cc
@@ -5,14 +5,14 @@ #include "chrome/test/views/accessibility_checker.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/test/views/chrome_views_test_base.h" #include "testing/gtest/include/gtest/gtest-spi.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/button/image_button.h" -#include "ui/views/test/views_test_base.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" -typedef views::ViewsTestBase AccessibilityCheckerTest; +using AccessibilityCheckerTest = ChromeViewsTestBase; // Test that a view that is not accessible will fail the accessibility audit. TEST_F(AccessibilityCheckerTest, VerifyAccessibilityCheckerFailAndPass) {
diff --git a/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc b/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc index 8228318..76e328f 100644 --- a/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc +++ b/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -392,7 +392,7 @@ params->opt_args.additional_properties, &replace_selected_text_params)); action->action = ax::mojom::Action::kReplaceSelectedText; - action->value = base::UTF8ToUTF16(replace_selected_text_params.value); + action->value = replace_selected_text_params.value; break; } case api::automation::ACTION_TYPE_SETVALUE: { @@ -401,7 +401,7 @@ api::automation_internal::SetValueParams::Populate( params->opt_args.additional_properties, &set_value_params)); action->action = ax::mojom::Action::kSetValue; - action->value = base::UTF8ToUTF16(set_value_params.value); + action->value = set_value_params.value; break; } // These actions are currently unused by any existing clients of
diff --git a/chromecast/device/bluetooth/le/BUILD.gn b/chromecast/device/bluetooth/le/BUILD.gn index 4ceb8fff..8e2fc00 100644 --- a/chromecast/device/bluetooth/le/BUILD.gn +++ b/chromecast/device/bluetooth/le/BUILD.gn
@@ -64,6 +64,7 @@ ] deps = [ ":le", + "//base", "//chromecast/public", "//testing/gmock", ]
diff --git a/chromecast/device/bluetooth/le/mock_gatt_client_manager.h b/chromecast/device/bluetooth/le/mock_gatt_client_manager.h index 46ecd42..f900ef3 100644 --- a/chromecast/device/bluetooth/le/mock_gatt_client_manager.h +++ b/chromecast/device/bluetooth/le/mock_gatt_client_manager.h
@@ -5,6 +5,7 @@ #ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_ #define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_ +#include "base/containers/flat_set.h" #include "chromecast/device/bluetooth/le/gatt_client_manager.h" #include "chromecast/device/bluetooth/le/mock_remote_device.h" #include "testing/gmock/include/gmock/gmock.h" @@ -18,12 +19,12 @@ ~MockGattClientManager(); void AddObserver(Observer* o) override { - DCHECK(o && !observer_); - observer_ = o; + DCHECK(o && !observers_.count(o)); + observers_.insert(o); } void RemoveObserver(Observer* o) override { - DCHECK(o && o == observer_); - observer_ = nullptr; + DCHECK(o && observers_.count(o)); + observers_.erase(o); } MOCK_METHOD1( @@ -42,7 +43,7 @@ MOCK_METHOD1(NotifyConnect, void(const bluetooth_v2_shlib::Addr& addr)); MOCK_METHOD0(task_runner, scoped_refptr<base::SingleThreadTaskRunner>()); - Observer* observer_ = nullptr; + base::flat_set<Observer*> observers_; }; } // namespace bluetooth
diff --git a/chromecast/media/cma/backend/audio_decoder_for_mixer.cc b/chromecast/media/cma/backend/audio_decoder_for_mixer.cc index 59529cd..8a7725e 100644 --- a/chromecast/media/cma/backend/audio_decoder_for_mixer.cc +++ b/chromecast/media/cma/backend/audio_decoder_for_mixer.cc
@@ -188,6 +188,19 @@ return rate; } +bool AudioDecoderForMixer::GetTimestampedPts(int64_t* timestamp, + int64_t* pts) const { + if (last_push_timestamp_ == kInvalidTimestamp || + last_push_pts_ == kInvalidTimestamp) + return false; + + // Hmm this timestamp may be in the future. That should be fine, but it's + // a bit weird. + *timestamp = last_push_timestamp_; + *pts = last_push_pts_; + return true; +} + int64_t AudioDecoderForMixer::GetCurrentPts() const { if (paused_pts_ != kInvalidTimestamp) return paused_pts_;
diff --git a/chromecast/media/cma/backend/audio_decoder_for_mixer.h b/chromecast/media/cma/backend/audio_decoder_for_mixer.h index 6a88a7e..5ac2e86 100644 --- a/chromecast/media/cma/backend/audio_decoder_for_mixer.h +++ b/chromecast/media/cma/backend/audio_decoder_for_mixer.h
@@ -46,6 +46,7 @@ virtual bool Pause(); virtual bool Resume(); virtual float SetPlaybackRate(float rate); + virtual bool GetTimestampedPts(int64_t* timestamp, int64_t* pts) const; virtual int64_t GetCurrentPts() const; // MediaPipelineBackend::AudioDecoder implementation:
diff --git a/chromecast/media/cma/backend/video/av_sync_video.cc b/chromecast/media/cma/backend/video/av_sync_video.cc index 90571ac..276ce06 100644 --- a/chromecast/media/cma/backend/video/av_sync_video.cc +++ b/chromecast/media/cma/backend/video/av_sync_video.cc
@@ -19,7 +19,6 @@ namespace media { namespace { -const int64_t kInvalidTimestamp = std::numeric_limits<int64_t>::min(); // Threshold where the audio and video pts are far enough apart such that we // want to do a small correction. @@ -111,33 +110,22 @@ first_video_pts_received_ = true; } - // TODO(almasrymina): using GetCurrentPts is vulnerable to pairing it with an - // outdated 'now' if the thread gets descheduled in between. We currently see - // extraneous corrections on real hardware and it's probably due to this. - // - // Consider either going back to a NotifyAudioBufferPushed approach that - // works, or improving GetCurrentPts such as it returns the timestamp this - // was last updated at. - // TODO(almasrymina): b/78592779. AudioDecoderForMixer::GetCurrentPts seems - // to return invalid values which are not kInvalidTimestamp, for unknown - // reasons. As a workaround until that issue is root caused, ignore - // GetCurrentPts values that are way off. - int64_t audio_pts = backend_->audio_decoder()->GetCurrentPts(); - if (abs(audio_pts - new_current_vpts) > - base::TimeDelta::FromHours(1).InMicroseconds() || - audio_pts == kInvalidTimestamp) { - LOG(WARNING) << "Audio decoder returned invalid pts=" << audio_pts - << " new_current_vpts=" << new_current_vpts; - } else { - audio_pts_->AddSample(now, backend_->audio_decoder()->GetCurrentPts(), 1.0); + int64_t new_current_apts = 0; + int64_t new_apts_timestamp = 0; - if (!first_audio_pts_received_) { - LOG(INFO) << "Audio starting at difference=" - << (backend_->MonotonicClockNow() - - backend_->audio_decoder()->GetCurrentPts()) - - playback_start_timestamp_us_; - first_audio_pts_received_ = true; - } + if (!backend_->audio_decoder()->GetTimestampedPts(&new_apts_timestamp, + &new_current_apts)) { + LOG(ERROR) << "Failed to get APTS."; + return; + } + + audio_pts_->AddSample(new_apts_timestamp, new_current_apts, 1.0); + + if (!first_audio_pts_received_) { + LOG(INFO) << "Audio starting at difference=" + << (new_apts_timestamp - new_current_apts) - + playback_start_timestamp_us_; + first_audio_pts_received_ = true; } if (video_pts_->num_samples() < 10 || audio_pts_->num_samples() < 20) { @@ -150,10 +138,13 @@ int64_t current_vpts; double vpts_slope; double apts_slope; - video_pts_->EstimateY(now, ¤t_vpts, &error); - audio_pts_->EstimateY(now, ¤t_apts, &error); - video_pts_->EstimateSlope(&vpts_slope, &error); - audio_pts_->EstimateSlope(&apts_slope, &error); + if (!video_pts_->EstimateY(now, ¤t_vpts, &error) || + !audio_pts_->EstimateY(now, ¤t_apts, &error) || + !video_pts_->EstimateSlope(&vpts_slope, &error) || + !audio_pts_->EstimateSlope(&apts_slope, &error)) { + VLOG(3) << "Failed to get linear regression estimate."; + return; + } error_->AddSample(now, current_apts - current_vpts, 1.0); @@ -165,14 +156,17 @@ } int64_t difference; - error_->EstimateY(now, &difference, &error); + if (!error_->EstimateY(now, &difference, &error)) { + VLOG(3) << "Failed to get linear regression estimate."; + return; + } VLOG(3) << "Pts_monitor." << " difference=" << difference / 1000 << " apts_slope=" << apts_slope << " vpts_slope=" << vpts_slope << " current_audio_playback_rate_=" << current_audio_playback_rate_ << " current_vpts=" << new_current_vpts - << " current_apts=" << backend_->audio_decoder()->GetCurrentPts() + << " current_apts=" << new_current_apts << " current_time=" << backend_->MonotonicClockNow() << " video_start_error=" << (new_vpts_timestamp - new_current_vpts - @@ -183,26 +177,20 @@ ++av_sync_difference_count_; if (abs(difference) > kSoftCorrectionThresholdUs) { - SoftCorrection(now); + SoftCorrection(now, current_vpts, current_apts, apts_slope, vpts_slope, + difference); } else { - InSyncCorrection(now); + InSyncCorrection(now, current_vpts, current_apts, apts_slope, vpts_slope, + difference); } } -void AvSyncVideo::SoftCorrection(int64_t now) { - int64_t current_apts = 0; - int64_t current_vpts = 0; - int64_t difference = 0; - double error = 0.0; - double apts_slope = 0.0; - double vpts_slope = 0.0; - - video_pts_->EstimateY(now, ¤t_vpts, &error); - audio_pts_->EstimateY(now, ¤t_apts, &error); - video_pts_->EstimateSlope(&vpts_slope, &error); - audio_pts_->EstimateSlope(&apts_slope, &error); - error_->EstimateY(now, &difference, &error); - +void AvSyncVideo::SoftCorrection(int64_t now, + int64_t current_vpts, + int64_t current_apts, + double apts_slope, + double vpts_slope, + int64_t difference) { if (audio_pts_->num_samples() < 50) { VLOG(4) << "Not enough apts samples=" << audio_pts_->num_samples(); return; @@ -253,23 +241,16 @@ // sufficiently close to each other, and we no longer need to bridge a gap // between them. This method will have it so that vpts_slope == apts_slope, and // the content should continue to play in sync from here on out. -void AvSyncVideo::InSyncCorrection(int64_t now) { +void AvSyncVideo::InSyncCorrection(int64_t now, + int64_t current_vpts, + int64_t current_apts, + double apts_slope, + double vpts_slope, + int64_t difference) { if (audio_pts_->num_samples() < 50 || !in_soft_correction_) { return; } - int64_t current_apts = 0; - int64_t current_vpts = 0; - int64_t difference = 0; - double error = 0.0; - double apts_slope = 0.0; - double vpts_slope = 0.0; - - video_pts_->EstimateY(now, ¤t_vpts, &error); - audio_pts_->EstimateY(now, ¤t_apts, &error); - video_pts_->EstimateSlope(&vpts_slope, &error); - audio_pts_->EstimateSlope(&apts_slope, &error); - current_audio_playback_rate_ *= vpts_slope / apts_slope; current_audio_playback_rate_ = backend_->audio_decoder()->SetPlaybackRate(current_audio_playback_rate_); @@ -340,6 +321,11 @@ backend_->video_decoder()->GetCurrentPts(&accurate_vpts_timestamp, &accurate_vpts); + int64_t accurate_apts = 0; + int64_t accurate_apts_timestamp = 0; + backend_->video_decoder()->GetCurrentPts(&accurate_apts_timestamp, + &accurate_apts); + LOG(INFO) << "Playback diagnostics:" << " CurrentContentRefreshRate=" << backend_->video_decoder()->GetCurrentContentRefreshRate() @@ -352,15 +338,17 @@ << accurate_vpts_timestamp - accurate_vpts - playback_start_timestamp_us_ << " audio_start_error_estimate=" - << backend_->MonotonicClockNow() - - backend_->audio_decoder()->GetCurrentPts() - + << accurate_apts_timestamp - accurate_apts - playback_start_timestamp_us_; int64_t current_vpts = 0; int64_t current_apts = 0; double error = 0.0; - video_pts_->EstimateY(current_time, ¤t_vpts, &error); - audio_pts_->EstimateY(current_time, ¤t_apts, &error); + if (!video_pts_->EstimateY(current_time, ¤t_vpts, &error) || + !audio_pts_->EstimateY(current_time, ¤t_apts, &error)) { + VLOG(3) << "Failed to get linear regression estimate."; + return; + } if (delegate_) { delegate_->NotifyAvSyncPlaybackStatistics(
diff --git a/chromecast/media/cma/backend/video/av_sync_video.h b/chromecast/media/cma/backend/video/av_sync_video.h index c96b31d..ce03cf8 100644 --- a/chromecast/media/cma/backend/video/av_sync_video.h +++ b/chromecast/media/cma/backend/video/av_sync_video.h
@@ -59,8 +59,18 @@ void StopAvSync(); void GatherPlaybackStatistics(); - void SoftCorrection(int64_t now); - void InSyncCorrection(int64_t now); + void SoftCorrection(int64_t now, + int64_t current_vpts, + int64_t current_apts, + double apts_slope, + double vpts_slope, + int64_t difference); + void InSyncCorrection(int64_t now, + int64_t current_vpts, + int64_t current_apts, + double apts_slope, + double vpts_slope, + int64_t difference); Delegate* delegate_ = nullptr;
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn index 867112d..e9ea1d7 100644 --- a/chromeos/components/tether/BUILD.gn +++ b/chromeos/components/tether/BUILD.gn
@@ -142,7 +142,7 @@ # TODO(hansberry): Remove //chromeos/services/secure_channel dependency when # SecureChannelClient migration is complete. "//chromeos/services/secure_channel", - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", + "//chromeos/services/secure_channel/public/cpp/shared", "//components/cryptauth", "//components/cryptauth/ble", "//components/pref_registry", @@ -231,7 +231,7 @@ # SecureChannelClient migration is complete. "//chromeos/services/secure_channel", "//chromeos/services/secure_channel/public/cpp/client:test_support", - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", + "//chromeos/services/secure_channel/public/cpp/shared", "//components/cryptauth", "//components/cryptauth:test_support", "//components/cryptauth/ble:test_support", @@ -306,7 +306,7 @@ "//chromeos/services/secure_channel", "//chromeos/services/secure_channel:test_support", "//chromeos/services/secure_channel/public/cpp/client:test_support", - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", + "//chromeos/services/secure_channel/public/cpp/shared", "//components/cryptauth", "//components/cryptauth:test_support", "//components/cryptauth/ble",
diff --git a/chromeos/dbus/fake_power_manager_client.cc b/chromeos/dbus/fake_power_manager_client.cc index d9af0eb..bcea7f0 100644 --- a/chromeos/dbus/fake_power_manager_client.cc +++ b/chromeos/dbus/fake_power_manager_client.cc
@@ -102,6 +102,13 @@ void FakePowerManagerClient::IncreaseKeyboardBrightness() {} +void FakePowerManagerClient::GetKeyboardBrightnessPercent( + DBusMethodCallback<double> callback) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), keyboard_brightness_percent_)); +} + const base::Optional<power_manager::PowerSupplyProperties>& FakePowerManagerClient::GetLastStatus() { return props_; @@ -304,6 +311,10 @@ FROM_HERE, base::BindOnce(std::move(callback), true)); } +void FakePowerManagerClient::DeferScreenDim() { + num_defer_screen_dim_calls_++; +} + bool FakePowerManagerClient::PopVideoActivityReport() { CHECK(!video_activity_reports_.empty()); bool fullscreen = video_activity_reports_.front(); @@ -357,6 +368,11 @@ observer.PowerButtonEventReceived(down, timestamp); } +void FakePowerManagerClient::SendScreenDimImminent() { + for (auto& observer : observers_) + observer.ScreenDimImminent(); +} + void FakePowerManagerClient::SetLidState(LidState state, const base::TimeTicks& timestamp) { lid_state_ = state;
diff --git a/chromeos/dbus/fake_power_manager_client.h b/chromeos/dbus/fake_power_manager_client.h index e8d8fe2..57efad4 100644 --- a/chromeos/dbus/fake_power_manager_client.h +++ b/chromeos/dbus/fake_power_manager_client.h
@@ -43,6 +43,7 @@ int num_set_is_projecting_calls() const { return num_set_is_projecting_calls_; } + int num_defer_screen_dim_calls() const { return num_defer_screen_dim_calls_; } double screen_brightness_percent() const { return screen_brightness_percent_.value(); } @@ -78,6 +79,8 @@ void GetScreenBrightnessPercent(DBusMethodCallback<double> callback) override; void DecreaseKeyboardBrightness() override; void IncreaseKeyboardBrightness() override; + void GetKeyboardBrightnessPercent( + DBusMethodCallback<double> callback) override; const base::Optional<power_manager::PowerSupplyProperties>& GetLastStatus() override; void RequestStatusUpdate() override; @@ -109,6 +112,7 @@ VoidDBusMethodCallback callback) override; void DeleteArcTimers(const std::string& tag, VoidDBusMethodCallback callback) override; + void DeferScreenDim() override; // Pops the first report from |video_activity_reports_|, returning whether the // activity was fullscreen or not. There must be at least one report. @@ -133,6 +137,9 @@ // Notifies observers that the power button has been pressed or released. void SendPowerButtonEvent(bool down, const base::TimeTicks& timestamp); + // Notifies observers that the screen is about to be dimmed. + void SendScreenDimImminent(); + // Sets |lid_state_| or |tablet_mode_| and notifies |observers_| about the // change. void SetLidState(LidState state, const base::TimeTicks& timestamp); @@ -164,6 +171,10 @@ screen_brightness_percent_ = percent; } + void set_keyboard_brightness_percent(const base::Optional<double>& percent) { + keyboard_brightness_percent_ = percent; + } + private: // Callback that will be run by asynchronous suspend delays to report // readiness. @@ -186,6 +197,7 @@ int num_set_policy_calls_ = 0; int num_set_is_projecting_calls_ = 0; int num_set_backlights_forced_off_calls_ = 0; + int num_defer_screen_dim_calls_ = 0; // Number of pending suspend readiness callbacks. int num_pending_suspend_readiness_callbacks_ = 0; @@ -193,6 +205,9 @@ // Current screen brightness in the range [0.0, 100.0]. base::Optional<double> screen_brightness_percent_; + // Current keyboard brightness in the range [0.0, 100.0]. + base::Optional<double> keyboard_brightness_percent_; + // Last screen brightness requested via SetScreenBrightnessPercent(). // Unlike |screen_brightness_percent_|, this value will not be changed by // SetBacklightsForcedOff() method - a method that implicitly changes screen
diff --git a/chromeos/dbus/power_manager_client.cc b/chromeos/dbus/power_manager_client.cc index 2a3156eb..2332897 100644 --- a/chromeos/dbus/power_manager_client.cc +++ b/chromeos/dbus/power_manager_client.cc
@@ -228,8 +228,21 @@ power_manager::kGetScreenBrightnessPercentMethod); power_manager_proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - base::BindOnce(&PowerManagerClientImpl::OnGetScreenBrightnessPercent, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &PowerManagerClientImpl::OnGetScreenOrKeyboardBrightnessPercent, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + } + + void GetKeyboardBrightnessPercent( + DBusMethodCallback<double> callback) override { + dbus::MethodCall method_call( + power_manager::kPowerManagerInterface, + power_manager::kGetKeyboardBrightnessPercentMethod); + power_manager_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce( + &PowerManagerClientImpl::OnGetScreenOrKeyboardBrightnessPercent, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void RequestStatusUpdate() override { @@ -450,6 +463,10 @@ base::BindOnce(&OnVoidDBusMethod, std::move(callback))); } + void DeferScreenDim() override { + SimpleMethodCallToPowerManager(power_manager::kDeferScreenDimMethod); + } + protected: void Init(dbus::Bus* bus) override { power_manager_proxy_ = bus->GetObjectProxy( @@ -483,6 +500,8 @@ &PowerManagerClientImpl::SuspendDoneReceived}, {power_manager::kDarkSuspendImminentSignal, &PowerManagerClientImpl::DarkSuspendImminentReceived}, + {power_manager::kScreenDimImminentSignal, + &PowerManagerClientImpl::ScreenDimImminentReceived}, {power_manager::kIdleActionImminentSignal, &PowerManagerClientImpl::IdleActionImminentReceived}, {power_manager::kIdleActionDeferredSignal, @@ -648,13 +667,10 @@ } } - void OnGetScreenBrightnessPercent(DBusMethodCallback<double> callback, - dbus::Response* response) { + void OnGetScreenOrKeyboardBrightnessPercent( + DBusMethodCallback<double> callback, + dbus::Response* response) { if (!response) { - if (!system::StatisticsProvider::GetInstance()->IsRunningOnVm()) { - POWER_LOG(ERROR) << "Error calling " - << power_manager::kGetScreenBrightnessPercentMethod; - } std::move(callback).Run(base::nullopt); return; } @@ -876,6 +892,11 @@ base::PowerMonitorDeviceSource::HandleSystemResumed(); } + void ScreenDimImminentReceived(dbus::Signal* signal) { + for (auto& observer : observers_) + observer.ScreenDimImminent(); + } + void IdleActionImminentReceived(dbus::Signal* signal) { dbus::MessageReader reader(signal); power_manager::IdleActionImminent proto;
diff --git a/chromeos/dbus/power_manager_client.h b/chromeos/dbus/power_manager_client.h index fa6be97..45245e3 100644 --- a/chromeos/dbus/power_manager_client.h +++ b/chromeos/dbus/power_manager_client.h
@@ -133,6 +133,9 @@ virtual void TabletModeEventReceived(TabletMode mode, const base::TimeTicks& timestamp) {} + // Called just before the screen is dimmed in response to user inactivity. + virtual void ScreenDimImminent() {} + // Called when the idle action will be performed after // |time_until_idle_action|. virtual void IdleActionImminent( @@ -192,6 +195,11 @@ // Increases the keyboard brightness. virtual void IncreaseKeyboardBrightness() = 0; + // Similar to GetScreenBrightnessPercent, but gets the keyboard brightness + // instead. + virtual void GetKeyboardBrightnessPercent( + DBusMethodCallback<double> callback) = 0; + // Returns the last power status that was received from D-Bus, if any. virtual const base::Optional<power_manager::PowerSupplyProperties>& GetLastStatus() = 0; @@ -293,6 +301,11 @@ virtual void DeleteArcTimers(const std::string& tag, VoidDBusMethodCallback callback) = 0; + // Instructs powerd to defer dimming the screen. This only has an effect when + // called shortly (i.e. seconds) after observers have received + // ScreenDimImminent notifications. + virtual void DeferScreenDim() = 0; + // Creates the instance. static PowerManagerClient* Create(DBusClientImplementationType type);
diff --git a/chromeos/services/secure_channel/BUILD.gn b/chromeos/services/secure_channel/BUILD.gn index 363644b..1fea8ae 100644 --- a/chromeos/services/secure_channel/BUILD.gn +++ b/chromeos/services/secure_channel/BUILD.gn
@@ -12,6 +12,8 @@ "active_connection_manager.h", "active_connection_manager_impl.cc", "active_connection_manager_impl.h", + "authenticated_channel.cc", + "authenticated_channel.h", "authenticated_channel_impl.cc", "authenticated_channel_impl.h", "ble_advertiser.cc", @@ -115,7 +117,6 @@ "//chromeos", "//chromeos/components/proximity_auth/logging", "//chromeos/services/secure_channel/public/cpp/shared", - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", "//chromeos/services/secure_channel/public/mojom", "//components/cryptauth", "//components/cryptauth/ble", @@ -135,6 +136,8 @@ sources = [ "fake_active_connection_manager.cc", "fake_active_connection_manager.h", + "fake_authenticated_channel.cc", + "fake_authenticated_channel.h", "fake_ble_advertiser.cc", "fake_ble_advertiser.h", "fake_ble_connection_manager.cc", @@ -183,7 +186,6 @@ "//base", "//base/test:test_support", "//chromeos/services/secure_channel/public/cpp/shared", - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", "//chromeos/services/secure_channel/public/mojom", "//components/cryptauth:cryptauth", "//device/bluetooth:bluetooth", @@ -224,8 +226,6 @@ "//base/test:test_support", "//chromeos/services/secure_channel/public/cpp/client:unit_tests", "//chromeos/services/secure_channel/public/cpp/shared", - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", - "//chromeos/services/secure_channel/public/cpp/shared:test_support", "//chromeos/services/secure_channel/public/mojom", "//chromeos/services/secure_channel/public/mojom:unit_tests", "//components/cryptauth:test_support",
diff --git a/chromeos/services/secure_channel/active_connection_manager.cc b/chromeos/services/secure_channel/active_connection_manager.cc index fe28d00..8124daae 100644 --- a/chromeos/services/secure_channel/active_connection_manager.cc +++ b/chromeos/services/secure_channel/active_connection_manager.cc
@@ -6,7 +6,7 @@ #include "base/logging.h" #include "chromeos/components/proximity_auth/logging/logging.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/active_connection_manager_impl_unittest.cc b/chromeos/services/secure_channel/active_connection_manager_impl_unittest.cc index d83675c7..8207b1e 100644 --- a/chromeos/services/secure_channel/active_connection_manager_impl_unittest.cc +++ b/chromeos/services/secure_channel/active_connection_manager_impl_unittest.cc
@@ -13,10 +13,10 @@ #include "base/unguessable_token.h" #include "chromeos/services/secure_channel/connection_details.h" #include "chromeos/services/secure_channel/fake_active_connection_manager.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_client_connection_parameters.h" #include "chromeos/services/secure_channel/fake_multiplexed_channel.h" #include "chromeos/services/secure_channel/multiplexed_channel_impl.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.cc b/chromeos/services/secure_channel/authenticated_channel.cc similarity index 95% rename from chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.cc rename to chromeos/services/secure_channel/authenticated_channel.cc index cea1afb4..e4afa0c 100644 --- a/chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.cc +++ b/chromeos/services/secure_channel/authenticated_channel.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 "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "base/callback.h" #include "base/guid.h"
diff --git a/chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h b/chromeos/services/secure_channel/authenticated_channel.h similarity index 91% rename from chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h rename to chromeos/services/secure_channel/authenticated_channel.h index 293e2a2..72e589f 100644 --- a/chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h +++ b/chromeos/services/secure_channel/authenticated_channel.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 CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_AUTHENTICATED_CHANNEL_H_ -#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_AUTHENTICATED_CHANNEL_H_ +#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_AUTHENTICATED_CHANNEL_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_AUTHENTICATED_CHANNEL_H_ #include <string> @@ -82,4 +82,4 @@ } // namespace chromeos -#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_AUTHENTICATED_CHANNEL_H_ +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_AUTHENTICATED_CHANNEL_H_
diff --git a/chromeos/services/secure_channel/authenticated_channel_impl.h b/chromeos/services/secure_channel/authenticated_channel_impl.h index 599ea68..14a1ed2 100644 --- a/chromeos/services/secure_channel/authenticated_channel_impl.h +++ b/chromeos/services/secure_channel/authenticated_channel_impl.h
@@ -9,7 +9,7 @@ #include <vector> #include "base/macros.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "components/cryptauth/secure_channel.h" namespace cryptauth {
diff --git a/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc b/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc index 92a8fdd..1c8786b6 100644 --- a/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc +++ b/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc
@@ -14,7 +14,7 @@ #include "base/bind.h" #include "base/stl_util.h" #include "base/test/scoped_task_environment.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "components/cryptauth/fake_connection.h" #include "components/cryptauth/fake_secure_channel.h"
diff --git a/chromeos/services/secure_channel/ble_connection_manager.cc b/chromeos/services/secure_channel/ble_connection_manager.cc index 40e72bd9..cc32704 100644 --- a/chromeos/services/secure_channel/ble_connection_manager.cc +++ b/chromeos/services/secure_channel/ble_connection_manager.cc
@@ -7,7 +7,7 @@ #include "base/logging.h" #include "base/stl_util.h" #include "chromeos/components/proximity_auth/logging/logging.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "components/cryptauth/remote_device_ref.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc b/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc index 08a90fc4..205e332 100644 --- a/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc +++ b/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc
@@ -19,13 +19,13 @@ #include "chromeos/services/secure_channel/ble_listener_failure_type.h" #include "chromeos/services/secure_channel/ble_scanner_impl.h" #include "chromeos/services/secure_channel/ble_synchronizer.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_ble_advertiser.h" #include "chromeos/services/secure_channel/fake_ble_scanner.h" #include "chromeos/services/secure_channel/fake_ble_service_data_helper.h" #include "chromeos/services/secure_channel/fake_ble_synchronizer.h" #include "chromeos/services/secure_channel/fake_secure_channel_disconnector.h" #include "chromeos/services/secure_channel/fake_timer_factory.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/secure_channel_disconnector_impl.h" #include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h" #include "components/cryptauth/fake_connection.h"
diff --git a/chromeos/services/secure_channel/ble_initiator_operation.cc b/chromeos/services/secure_channel/ble_initiator_operation.cc index 1905e79..056adfe 100644 --- a/chromeos/services/secure_channel/ble_initiator_operation.cc +++ b/chromeos/services/secure_channel/ble_initiator_operation.cc
@@ -8,8 +8,8 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/no_destructor.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/ble_connection_manager.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/ble_initiator_operation_unittest.cc b/chromeos/services/secure_channel/ble_initiator_operation_unittest.cc index c84688c..d929bdb 100644 --- a/chromeos/services/secure_channel/ble_initiator_operation_unittest.cc +++ b/chromeos/services/secure_channel/ble_initiator_operation_unittest.cc
@@ -12,9 +12,9 @@ #include "base/test/test_simple_task_runner.h" #include "chromeos/services/secure_channel/ble_initiator_failure_type.h" #include "chromeos/services/secure_channel/device_id_pair.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_ble_connection_manager.h" #include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/ble_listener_operation.cc b/chromeos/services/secure_channel/ble_listener_operation.cc index 81f1dde..632f5ac4 100644 --- a/chromeos/services/secure_channel/ble_listener_operation.cc +++ b/chromeos/services/secure_channel/ble_listener_operation.cc
@@ -8,8 +8,8 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/no_destructor.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/ble_connection_manager.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/ble_listener_operation_unittest.cc b/chromeos/services/secure_channel/ble_listener_operation_unittest.cc index c3c03db41..a0312c9 100644 --- a/chromeos/services/secure_channel/ble_listener_operation_unittest.cc +++ b/chromeos/services/secure_channel/ble_listener_operation_unittest.cc
@@ -12,9 +12,9 @@ #include "base/test/test_simple_task_runner.h" #include "chromeos/services/secure_channel/ble_listener_failure_type.h" #include "chromeos/services/secure_channel/device_id_pair.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_ble_connection_manager.h" #include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/connect_to_device_operation_base_unittest.cc b/chromeos/services/secure_channel/connect_to_device_operation_base_unittest.cc index fd3bac84..93973d5 100644 --- a/chromeos/services/secure_channel/connect_to_device_operation_base_unittest.cc +++ b/chromeos/services/secure_channel/connect_to_device_operation_base_unittest.cc
@@ -11,7 +11,7 @@ #include "base/test/scoped_task_environment.h" #include "base/test/test_simple_task_runner.h" #include "chromeos/services/secure_channel/device_id_pair.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/connection_attempt_base.h b/chromeos/services/secure_channel/connection_attempt_base.h index 88edae83..ab51d289 100644 --- a/chromeos/services/secure_channel/connection_attempt_base.h +++ b/chromeos/services/secure_channel/connection_attempt_base.h
@@ -12,12 +12,12 @@ #include "base/observer_list.h" #include "base/stl_util.h" #include "chromeos/components/proximity_auth/logging/logging.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/connect_to_device_operation.h" #include "chromeos/services/secure_channel/connection_attempt.h" #include "chromeos/services/secure_channel/connection_attempt_details.h" #include "chromeos/services/secure_channel/connection_details.h" #include "chromeos/services/secure_channel/pending_connection_request.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" #include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
diff --git a/chromeos/services/secure_channel/connection_attempt_base_unittest.cc b/chromeos/services/secure_channel/connection_attempt_base_unittest.cc index 49224a8..a41fab6 100644 --- a/chromeos/services/secure_channel/connection_attempt_base_unittest.cc +++ b/chromeos/services/secure_channel/connection_attempt_base_unittest.cc
@@ -16,6 +16,7 @@ #include "chromeos/services/secure_channel/connection_medium.h" #include "chromeos/services/secure_channel/connection_role.h" #include "chromeos/services/secure_channel/device_id_pair.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_client_connection_parameters.h" #include "chromeos/services/secure_channel/fake_connect_to_device_operation.h" #include "chromeos/services/secure_channel/fake_connection_attempt_delegate.h" @@ -23,7 +24,6 @@ #include "chromeos/services/secure_channel/fake_pending_connection_request.h" #include "chromeos/services/secure_channel/pending_connection_request_delegate.h" #include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/fake_active_connection_manager.cc b/chromeos/services/secure_channel/fake_active_connection_manager.cc index aa60c02..d2f70068 100644 --- a/chromeos/services/secure_channel/fake_active_connection_manager.cc +++ b/chromeos/services/secure_channel/fake_active_connection_manager.cc
@@ -6,7 +6,7 @@ #include "base/logging.h" #include "base/stl_util.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.cc b/chromeos/services/secure_channel/fake_authenticated_channel.cc similarity index 93% rename from chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.cc rename to chromeos/services/secure_channel/fake_authenticated_channel.cc index 5c914c1..003eea2 100644 --- a/chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.cc +++ b/chromeos/services/secure_channel/fake_authenticated_channel.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 "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h b/chromeos/services/secure_channel/fake_authenticated_channel.h similarity index 88% rename from chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h rename to chromeos/services/secure_channel/fake_authenticated_channel.h index 0deee146..094b75ee 100644 --- a/chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h +++ b/chromeos/services/secure_channel/fake_authenticated_channel.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 CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_FAKE_AUTHENTICATED_CHANNEL_H_ -#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_FAKE_AUTHENTICATED_CHANNEL_H_ +#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_FAKE_AUTHENTICATED_CHANNEL_H_ +#define CHROMEOS_SERVICES_SECURE_CHANNEL_FAKE_AUTHENTICATED_CHANNEL_H_ #include <string> #include <tuple> @@ -12,7 +12,7 @@ #include "base/callback.h" #include "base/logging.h" #include "base/macros.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h" namespace chromeos { @@ -89,4 +89,4 @@ } // namespace chromeos -#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_SHARED_FAKE_AUTHENTICATED_CHANNEL_H_ +#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_FAKE_AUTHENTICATED_CHANNEL_H_
diff --git a/chromeos/services/secure_channel/fake_connection_attempt_delegate.cc b/chromeos/services/secure_channel/fake_connection_attempt_delegate.cc index 3029b3a..9c7e192 100644 --- a/chromeos/services/secure_channel/fake_connection_attempt_delegate.cc +++ b/chromeos/services/secure_channel/fake_connection_attempt_delegate.cc
@@ -5,7 +5,7 @@ #include "chromeos/services/secure_channel/fake_connection_attempt_delegate.h" #include "base/logging.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/fake_pending_connection_manager.cc b/chromeos/services/secure_channel/fake_pending_connection_manager.cc index 6904603..e4ab035 100644 --- a/chromeos/services/secure_channel/fake_pending_connection_manager.cc +++ b/chromeos/services/secure_channel/fake_pending_connection_manager.cc
@@ -8,7 +8,7 @@ #include <iterator> #include "base/logging.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/multiplexed_channel_impl.h b/chromeos/services/secure_channel/multiplexed_channel_impl.h index 8cad1c8..9ce5921 100644 --- a/chromeos/services/secure_channel/multiplexed_channel_impl.h +++ b/chromeos/services/secure_channel/multiplexed_channel_impl.h
@@ -11,9 +11,9 @@ #include <vector> #include "base/macros.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/connection_details.h" #include "chromeos/services/secure_channel/multiplexed_channel.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "chromeos/services/secure_channel/single_client_message_proxy.h"
diff --git a/chromeos/services/secure_channel/multiplexed_channel_impl_unittest.cc b/chromeos/services/secure_channel/multiplexed_channel_impl_unittest.cc index c192364..0bf45b1df 100644 --- a/chromeos/services/secure_channel/multiplexed_channel_impl_unittest.cc +++ b/chromeos/services/secure_channel/multiplexed_channel_impl_unittest.cc
@@ -14,11 +14,11 @@ #include "base/test/scoped_task_environment.h" #include "chromeos/services/secure_channel/connection_details.h" #include "chromeos/services/secure_channel/connection_medium.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_client_connection_parameters.h" #include "chromeos/services/secure_channel/fake_connection_delegate.h" #include "chromeos/services/secure_channel/fake_multiplexed_channel.h" #include "chromeos/services/secure_channel/fake_single_client_message_proxy.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/single_client_message_proxy_impl.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/services/secure_channel/pending_connection_manager.cc b/chromeos/services/secure_channel/pending_connection_manager.cc index a001129..a48b52c 100644 --- a/chromeos/services/secure_channel/pending_connection_manager.cc +++ b/chromeos/services/secure_channel/pending_connection_manager.cc
@@ -4,7 +4,7 @@ #include "chromeos/services/secure_channel/pending_connection_manager.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/pending_connection_manager_impl.cc b/chromeos/services/secure_channel/pending_connection_manager_impl.cc index a571597..e9b5517 100644 --- a/chromeos/services/secure_channel/pending_connection_manager_impl.cc +++ b/chromeos/services/secure_channel/pending_connection_manager_impl.cc
@@ -8,11 +8,11 @@ #include "base/memory/ptr_util.h" #include "base/no_destructor.h" #include "base/stl_util.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/ble_initiator_connection_attempt.h" #include "chromeos/services/secure_channel/ble_listener_connection_attempt.h" #include "chromeos/services/secure_channel/pending_ble_initiator_connection_request.h" #include "chromeos/services/secure_channel/pending_ble_listener_connection_request.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/pending_connection_manager_impl_unittest.cc b/chromeos/services/secure_channel/pending_connection_manager_impl_unittest.cc index fc7d732..9224a48 100644 --- a/chromeos/services/secure_channel/pending_connection_manager_impl_unittest.cc +++ b/chromeos/services/secure_channel/pending_connection_manager_impl_unittest.cc
@@ -14,6 +14,7 @@ #include "base/test/scoped_task_environment.h" #include "chromeos/services/secure_channel/ble_initiator_connection_attempt.h" #include "chromeos/services/secure_channel/ble_listener_connection_attempt.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_ble_connection_manager.h" #include "chromeos/services/secure_channel/fake_client_connection_parameters.h" #include "chromeos/services/secure_channel/fake_connection_attempt.h" @@ -21,7 +22,6 @@ #include "chromeos/services/secure_channel/fake_pending_connection_request.h" #include "chromeos/services/secure_channel/pending_ble_initiator_connection_request.h" #include "chromeos/services/secure_channel/pending_ble_listener_connection_request.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h b/chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h index 379a471b..1c903fc 100644 --- a/chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h +++ b/chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "chromeos/services/secure_channel/public/cpp/client/connection_attempt.h" #include "chromeos/services/secure_channel/public/cpp/client/secure_channel_client.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" namespace chromeos {
diff --git a/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn b/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn index 41bd9f4..bb9d29c 100644 --- a/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn +++ b/chromeos/services/secure_channel/public/cpp/shared/BUILD.gn
@@ -4,24 +4,6 @@ source_set("shared") { sources = [ - "authenticated_channel.cc", - "authenticated_channel.h", - ] - - deps = [ - "//base", - "//chromeos/components/proximity_auth/logging", - "//chromeos/services/secure_channel/public/mojom", - "//mojo/public/cpp/bindings", - "//services/service_manager/public/cpp", - ] -} - -# Note: ConnectionPriority is in a separate target to avoid a circular -# dependency between //chromeos/services/secure_channel/public/mojom and -# //chromeos/services/secure_channel/public/cpp/shared. -source_set("connection_priority") { - sources = [ "connection_priority.cc", "connection_priority.h", ] @@ -30,19 +12,3 @@ "//base", ] } - -static_library("test_support") { - testonly = true - - sources = [ - ":shared", - "fake_authenticated_channel.cc", - "fake_authenticated_channel.h", - ] - - deps = [ - ":shared", - "//base", - "//chromeos/services/secure_channel/public/mojom", - ] -}
diff --git a/chromeos/services/secure_channel/public/mojom/secure_channel.typemap b/chromeos/services/secure_channel/public/mojom/secure_channel.typemap index 3b0ebe4..1a77e53 100644 --- a/chromeos/services/secure_channel/public/mojom/secure_channel.typemap +++ b/chromeos/services/secure_channel/public/mojom/secure_channel.typemap
@@ -16,7 +16,7 @@ ] public_deps = [ - "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", + "//chromeos/services/secure_channel/public/cpp/shared", ] type_mappings = [ "chromeos.secure_channel.mojom.ConnectionPriority=chromeos::secure_channel::ConnectionPriority" ]
diff --git a/chromeos/services/secure_channel/secure_channel_impl.cc b/chromeos/services/secure_channel/secure_channel_impl.cc index f2bbdef..1b103e50 100644 --- a/chromeos/services/secure_channel/secure_channel_impl.cc +++ b/chromeos/services/secure_channel/secure_channel_impl.cc
@@ -12,12 +12,12 @@ #include "base/stl_util.h" #include "chromeos/components/proximity_auth/logging/logging.h" #include "chromeos/services/secure_channel/active_connection_manager_impl.h" +#include "chromeos/services/secure_channel/authenticated_channel.h" #include "chromeos/services/secure_channel/ble_connection_manager_impl.h" #include "chromeos/services/secure_channel/ble_service_data_helper_impl.h" #include "chromeos/services/secure_channel/client_connection_parameters_impl.h" #include "chromeos/services/secure_channel/device_id_pair.h" #include "chromeos/services/secure_channel/pending_connection_manager_impl.h" -#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h" #include "chromeos/services/secure_channel/timer_factory_impl.h" #include "device/bluetooth/bluetooth_adapter.h"
diff --git a/chromeos/services/secure_channel/secure_channel_service_unittest.cc b/chromeos/services/secure_channel/secure_channel_service_unittest.cc index a547942..d528d23 100644 --- a/chromeos/services/secure_channel/secure_channel_service_unittest.cc +++ b/chromeos/services/secure_channel/secure_channel_service_unittest.cc
@@ -17,6 +17,7 @@ #include "chromeos/services/secure_channel/ble_service_data_helper_impl.h" #include "chromeos/services/secure_channel/client_connection_parameters_impl.h" #include "chromeos/services/secure_channel/fake_active_connection_manager.h" +#include "chromeos/services/secure_channel/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/fake_ble_connection_manager.h" #include "chromeos/services/secure_channel/fake_ble_service_data_helper.h" #include "chromeos/services/secure_channel/fake_client_connection_parameters.h" @@ -25,7 +26,6 @@ #include "chromeos/services/secure_channel/fake_timer_factory.h" #include "chromeos/services/secure_channel/pending_connection_manager_impl.h" #include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h" -#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h" #include "chromeos/services/secure_channel/public/mojom/constants.mojom.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "chromeos/services/secure_channel/secure_channel_initializer.h"
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java index c060c95..91c48456 100644 --- a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java +++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java
@@ -31,8 +31,9 @@ static final int BACKGROUND_TASK_OFFLINE_CONTENT_NOTIFICATION = 11; static final int BACKGROUND_TASK_WEBAPK_UPDATE = 12; static final int BACKGROUND_TASK_DOWNLOAD_RESUMPTION = 13; + static final int BACKGROUND_TASK_FEED_REFRESH = 14; // Keep this one at the end and increment appropriately when adding new tasks. - static final int BACKGROUND_TASK_COUNT = 14; + static final int BACKGROUND_TASK_COUNT = 15; static final String KEY_CACHED_UMA = "bts_cached_uma"; @@ -247,6 +248,8 @@ return BACKGROUND_TASK_WEBAPK_UPDATE; case TaskIds.DOWNLOAD_RESUMPTION_JOB_ID: return BACKGROUND_TASK_DOWNLOAD_RESUMPTION; + case TaskIds.FEED_REFRESH_JOB_ID: + return BACKGROUND_TASK_FEED_REFRESH; default: assert false; }
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java index 3c8dd368..4210211 100644 --- a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java +++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java
@@ -26,6 +26,7 @@ public static final int WEBVIEW_VARIATIONS_SEED_FETCH_JOB_ID = 83; public static final int WEBAPK_UPDATE_JOB_ID = 91; public static final int DOWNLOAD_RESUMPTION_JOB_ID = 55; + public static final int FEED_REFRESH_JOB_ID = 22; private TaskIds() {} }
diff --git a/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java b/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java index 5ee1bfc..caa0465c 100644 --- a/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java +++ b/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java
@@ -82,7 +82,9 @@ assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_DOWNLOAD_RESUMPTION, BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId( TaskIds.DOWNLOAD_RESUMPTION_JOB_ID)); - assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_COUNT, 14); + assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_FEED_REFRESH, + BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(TaskIds.FEED_REFRESH_JOB_ID)); + assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_COUNT, 15); } @Test
diff --git a/components/cast_certificate/cast_cert_validator.cc b/components/cast_certificate/cast_cert_validator.cc index f70455e..ffcd2b1 100644 --- a/components/cast_certificate/cast_cert_validator.cc +++ b/components/cast_certificate/cast_cert_validator.cc
@@ -105,7 +105,10 @@ // It will also require RSA keys have a modulus at least 2048-bits long. class CastPathBuilderDelegate : public net::SimplePathBuilderDelegate { public: - CastPathBuilderDelegate() : SimplePathBuilderDelegate(2048) {} + CastPathBuilderDelegate() + : SimplePathBuilderDelegate( + 2048, + SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {} }; class CertVerificationContextImpl : public CertVerificationContext {
diff --git a/components/cast_certificate/cast_crl.cc b/components/cast_certificate/cast_crl.cc index 9a4e6eb..c2f38e4 100644 --- a/components/cast_certificate/cast_crl.cc +++ b/components/cast_certificate/cast_crl.cc
@@ -134,7 +134,8 @@ // SimplePathBuilderDelegate will enforce required signature algorithms of // RSASSA PKCS#1 v1.5 with SHA-256, and RSA keys 2048-bits or longer. - net::SimplePathBuilderDelegate path_builder_delegate(2048); + net::SimplePathBuilderDelegate path_builder_delegate( + 2048, net::SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); net::CertPathBuilder::Result result; net::CertPathBuilder path_builder(
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc index 05017c31..d8d97281 100644 --- a/components/exo/buffer.cc +++ b/components/exo/buffer.cc
@@ -23,6 +23,7 @@ #include "components/exo/layer_tree_frame_sink_holder.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/resources/resource_format.h" +#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/single_release_callback.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -458,7 +459,7 @@ resource->mailbox_holder = gpu::MailboxHolder(contents_texture->mailbox(), sync_token, texture_target_); resource->is_overlay_candidate = is_overlay_candidate_; - resource->buffer_format = gpu_memory_buffer_->GetFormat(); + resource->format = viz::GetResourceFormat(gpu_memory_buffer_->GetFormat()); // The contents texture will be released when no longer used by the // compositor.
diff --git a/components/feature_engagement/internal/android/tracker_impl_android.cc b/components/feature_engagement/internal/android/tracker_impl_android.cc index 90fd071..b6e39d7 100644 --- a/components/feature_engagement/internal/android/tracker_impl_android.cc +++ b/components/feature_engagement/internal/android/tracker_impl_android.cc
@@ -159,11 +159,8 @@ JNIEnv* env, const base::android::JavaRef<jobject>& jobj, const base::android::JavaParamRef<jobject>& j_callback_obj) { - // Disambiguate RunCallbackAndroid to get the reference to the bool version. - void (*runBoolCallback)(const base::android::JavaRef<jobject>&, bool) = - &base::android::RunCallbackAndroid; tracker_impl_->AddOnInitializedCallback(base::BindOnce( - runBoolCallback, + &base::android::RunBooleanCallbackAndroid, base::android::ScopedJavaGlobalRef<jobject>(j_callback_obj))); }
diff --git a/components/feed/core/feed_scheduler_host.cc b/components/feed/core/feed_scheduler_host.cc index 500b825..135beac4 100644 --- a/components/feed/core/feed_scheduler_host.cc +++ b/components/feed/core/feed_scheduler_host.cc
@@ -4,109 +4,217 @@ #include "components/feed/core/feed_scheduler_host.h" +#include <map> +#include <string> #include <utility> +#include "base/metrics/field_trial_params.h" +#include "base/stl_util.h" #include "base/time/clock.h" #include "base/time/time.h" #include "components/feed/core/pref_names.h" +#include "components/feed/core/time_serialization.h" +#include "components/feed/feed_feature_list.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" namespace feed { -enum class FeedSchedulerHost::TriggerType { - NTP_SHOWN = 0, - FOREGROUNDED = 1, - FIXED_TIMER = 2, - COUNT +namespace { + +using TriggerType = FeedSchedulerHost::TriggerType; +using UserClass = UserClassifier::UserClass; + +struct ParamPair { + std::string name; + double default_value; }; +// The Cartesian product of TriggerType and UserClass each need a different +// param name in case we decide to change it via a config change. This nested +// switch lookup ensures that all combinations are defined, along with a +// default value. +ParamPair LookupParam(UserClass user_class, TriggerType trigger) { + switch (user_class) { + case UserClass::RARE_NTP_USER: + switch (trigger) { + case TriggerType::NTP_SHOWN: + return {"ntp_shown_hours_rare_ntp_user", 4.0}; + case TriggerType::FOREGROUNDED: + return {"foregrounded_hours_rare_ntp_user", 24.0}; + case TriggerType::FIXED_TIMER: + return {"fixed_timer_hours_rare_ntp_user", 96.0}; + } + case UserClass::ACTIVE_NTP_USER: + switch (trigger) { + case TriggerType::NTP_SHOWN: + return {"ntp_shown_hours_active_ntp_user", 4.0}; + case TriggerType::FOREGROUNDED: + return {"foregrounded_hours_active_ntp_user", 24.0}; + case TriggerType::FIXED_TIMER: + return {"fixed_timer_hours_active_ntp_user", 48.0}; + } + case UserClass::ACTIVE_SUGGESTIONS_CONSUMER: + switch (trigger) { + case TriggerType::NTP_SHOWN: + return {"ntp_shown_hours_active_suggestions_consumer", 1.0}; + case TriggerType::FOREGROUNDED: + return {"foregrounded_hours_active_suggestions_consumer", 12.0}; + case TriggerType::FIXED_TIMER: + return {"fixed_timer_hours_active_suggestions_consumer", 24.0}; + } + } +} + +// Run the given closure if it is valid. +void TryRun(base::OnceClosure closure) { + if (closure) { + std::move(closure).Run(); + } +} + +} // namespace + FeedSchedulerHost::FeedSchedulerHost(PrefService* pref_service, base::Clock* clock) - : pref_service_(pref_service), clock_(clock) {} + : pref_service_(pref_service), + clock_(clock), + user_classifier_(pref_service, clock) {} FeedSchedulerHost::~FeedSchedulerHost() {} // static void FeedSchedulerHost::RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterTimePref(prefs::kLastFetchAttemptTime, base::Time()); + registry->RegisterTimeDeltaPref(prefs::kBackgroundRefreshPeriod, + base::TimeDelta()); +} + +void FeedSchedulerHost::Initialize( + base::RepeatingClosure refresh_callback, + ScheduleBackgroundTaskCallback schedule_background_task_callback) { + // There should only ever be one scheduler host and bridge created. Neither + // are ever destroyed before shutdown, and this method should only be called + // once as the bridge is constructed. + DCHECK(!refresh_callback_); + DCHECK(!schedule_background_task_callback_); + + refresh_callback_ = std::move(refresh_callback); + schedule_background_task_callback_ = + std::move(schedule_background_task_callback); + + base::TimeDelta old_period = + pref_service_->GetTimeDelta(prefs::kBackgroundRefreshPeriod); + base::TimeDelta new_period = GetTriggerThreshold(TriggerType::FIXED_TIMER); + if (old_period != new_period) { + ScheduleFixedTimerWakeUp(new_period); + } } NativeRequestBehavior FeedSchedulerHost::ShouldSessionRequestData( bool has_content, base::Time content_creation_date_time, bool has_outstanding_request) { - // TODO(skym): Record requested behavior into histogram. + NativeRequestBehavior behavior; if (!has_outstanding_request && ShouldRefresh(TriggerType::NTP_SHOWN)) { if (!has_content) { - return REQUEST_WITH_WAIT; + behavior = REQUEST_WITH_WAIT; } else if (IsContentStale(content_creation_date_time)) { - return REQUEST_WITH_TIMEOUT; + behavior = REQUEST_WITH_TIMEOUT; } else { - return REQUEST_WITH_CONTENT; + behavior = REQUEST_WITH_CONTENT; } } else { + // Note that NO_REQUEST_WITH_WAIT is used to show a blank article section + // even when no request is being made. The user will be given the ability to + // force a refresh but this scheduler is not driving it. if (!has_content) { - return NO_REQUEST_WITH_WAIT; - } else if (IsContentStale(content_creation_date_time)) { - return NO_REQUEST_WITH_TIMEOUT; + behavior = NO_REQUEST_WITH_WAIT; + } else if (IsContentStale(content_creation_date_time) && + has_outstanding_request) { + // This needs to check |has_outstanding_request|, it does not make sense + // to use a timeout when no request is being made. Just show the stale + // content, since nothing better is on the way. + behavior = NO_REQUEST_WITH_TIMEOUT; } else { - return NO_REQUEST_WITH_CONTENT; + behavior = NO_REQUEST_WITH_CONTENT; } } + + // TODO(skym): Record requested behavior into histogram. + user_classifier_.OnEvent(UserClassifier::Event::NTP_OPENED); + return behavior; } void FeedSchedulerHost::OnReceiveNewContent( base::Time content_creation_date_time) { - pref_service_->SetTime(prefs::kLastFetchAttemptTime, clock_->Now()); - ScheduleFixedTimerWakeUp(); + pref_service_->SetTime(prefs::kLastFetchAttemptTime, + content_creation_date_time); + TryRun(std::move(fixed_timer_completion_)); + ScheduleFixedTimerWakeUp(GetTriggerThreshold(TriggerType::FIXED_TIMER)); } void FeedSchedulerHost::OnRequestError(int network_response_code) { pref_service_->SetTime(prefs::kLastFetchAttemptTime, clock_->Now()); + TryRun(std::move(fixed_timer_completion_)); } void FeedSchedulerHost::OnForegrounded() { - DCHECK(trigger_refresh_); + DCHECK(refresh_callback_); if (ShouldRefresh(TriggerType::FOREGROUNDED)) { - trigger_refresh_.Run(); + refresh_callback_.Run(); } } -void FeedSchedulerHost::OnFixedTimer() { - DCHECK(trigger_refresh_); +void FeedSchedulerHost::OnFixedTimer(base::OnceClosure on_completion) { + DCHECK(refresh_callback_); if (ShouldRefresh(TriggerType::FIXED_TIMER)) { - trigger_refresh_.Run(); + // There shouldn't typically be anything in |fixed_timer_completion_| right + // now, but if there was, run it before we replace it. + TryRun(std::move(fixed_timer_completion_)); + + fixed_timer_completion_ = std::move(on_completion); + refresh_callback_.Run(); + } else { + // The task driving this doesn't need to stay around, since no work is being + // done on its behalf. + TryRun(std::move(on_completion)); } } -void FeedSchedulerHost::RegisterTriggerRefreshCallback( - base::RepeatingClosure callback) { - // There should only ever be one scheduler host and bridge created. This may - // stop being true eventually. - DCHECK(trigger_refresh_.is_null()); +void FeedSchedulerHost::OnTaskReschedule() { + ScheduleFixedTimerWakeUp(GetTriggerThreshold(TriggerType::FIXED_TIMER)); +} - trigger_refresh_ = std::move(callback); +void FeedSchedulerHost::OnSuggestionConsumed() { + user_classifier_.OnEvent(UserClassifier::Event::SUGGESTIONS_USED); } bool FeedSchedulerHost::ShouldRefresh(TriggerType trigger) { - // TODO(skym): Check various criteria are met, record metrics. - return true; + // TODO(skym): Check various other criteria are met, record metrics. + return (clock_->Now() - + pref_service_->GetTime(prefs::kLastFetchAttemptTime)) > + GetTriggerThreshold(trigger); } bool FeedSchedulerHost::IsContentStale(base::Time content_creation_date_time) { - // TODO(skym): Compare |content_creation_date_time| to foregrounded trigger's - // threshold. - return false; + return (clock_->Now() - content_creation_date_time) > + GetTriggerThreshold(TriggerType::FOREGROUNDED); } base::TimeDelta FeedSchedulerHost::GetTriggerThreshold(TriggerType trigger) { - // TODO(skym): Select Finch param based on trigger and user classification. - return base::TimeDelta(); + UserClass user_class = user_classifier_.GetUserClass(); + ParamPair param = LookupParam(user_class, trigger); + double value_hours = base::GetFieldTrialParamByFeatureAsDouble( + kInterestFeedContentSuggestions, param.name, param.default_value); + + // Use FromSecondsD in case one of the values contained a decimal. + return base::TimeDelta::FromSecondsD(value_hours * 3600.0); } -void FeedSchedulerHost::ScheduleFixedTimerWakeUp() { - // TODO(skym): Implementation, call out to injected scheduling dependency. +void FeedSchedulerHost::ScheduleFixedTimerWakeUp(base::TimeDelta period) { + pref_service_->SetTimeDelta(prefs::kBackgroundRefreshPeriod, period); + schedule_background_task_callback_.Run(period); } } // namespace feed
diff --git a/components/feed/core/feed_scheduler_host.h b/components/feed/core/feed_scheduler_host.h index 2e0d776..11270e5 100644 --- a/components/feed/core/feed_scheduler_host.h +++ b/components/feed/core/feed_scheduler_host.h
@@ -6,7 +6,10 @@ #define COMPONENTS_FEED_CORE_FEED_SCHEDULER_HOST_H_ #include "base/callback.h" +#include "base/gtest_prod_util.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/feed/core/user_classifier.h" class PrefRegistrySimple; class PrefService; @@ -14,6 +17,7 @@ namespace base { class Clock; class Time; +class TimeDelta; } // namespace base namespace feed { @@ -33,16 +37,34 @@ NO_REQUEST_WITH_TIMEOUT }; +enum class TriggerType; + // Implementation of the Feed Scheduler Host API. The scheduler host decides // what content is allowed to be shown, based on its age, and when to fetch new // content. class FeedSchedulerHost { public: + // The TriggerType enum specifies values for the events that can trigger + // refreshing articles. + enum class TriggerType { NTP_SHOWN = 0, FOREGROUNDED = 1, FIXED_TIMER = 2 }; + FeedSchedulerHost(PrefService* pref_service, base::Clock* clock); ~FeedSchedulerHost(); + using ScheduleBackgroundTaskCallback = + base::RepeatingCallback<void(base::TimeDelta)>; + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + // Provide dependent pieces of functionality the scheduler relies on. Should + // be called exactly once before other public methods are called. This is + // separate from the constructor because the FeedHostService owns and creates + // this class, while these providers need to be bridged through the JNI into a + // specific place that the FeedHostService does not know of. + void Initialize( + base::RepeatingClosure refresh_callback, + ScheduleBackgroundTaskCallback schedule_background_task_callback); + // Called when the NTP is opened to decide how to handle displaying and // refreshing content. NativeRequestBehavior ShouldSessionRequestData( @@ -59,16 +81,21 @@ // Called when browser is opened, launched, or foregrounded. void OnForegrounded(); - // Called when the scheduled fixed timer wakes up. - void OnFixedTimer(); + // Called when the scheduled fixed timer wakes up, |on_completion| will be + // invoked when the refresh completes, regardless of success. If no refresh + // is started for this trigger, |on_completion| is run immediately. + void OnFixedTimer(base::OnceClosure on_completion); - // Registers a callback to trigger a refresh. - void RegisterTriggerRefreshCallback(base::RepeatingClosure callback); + // Called when the background task may need to be rescheduled, such as on OS + // upgrades that change the way tasks are stored. + void OnTaskReschedule(); + + // Called when a suggestion is consumed to update what kind of user the + // scheduler should be optimizing for. + void OnSuggestionConsumed(); private: - // The TriggerType enum specifies values for the events that can trigger - // refreshing articles. - enum class TriggerType; + FRIEND_TEST_ALL_PREFIXES(FeedSchedulerHostTest, GetTriggerThreshold); // Determines whether a refresh should be performed for the given |trigger|. // If this method is called and returns true we presume the refresh will @@ -79,16 +106,13 @@ // |content_creation_date_time| is old enough to be considered stale. bool IsContentStale(base::Time content_creation_date_time); - // Schedules a task to wakeup and try to refresh. Overrides previously - // scheduled tasks. - void ScheduleFixedTimerWakeUp(); - // Returns the time threshold for content or previous refresh attempt to be // considered old enough for a given trigger to warrant a refresh. base::TimeDelta GetTriggerThreshold(TriggerType trigger); - // Callback to request that an async refresh be started. - base::RepeatingClosure trigger_refresh_; + // Schedules a task to wakeup and try to refresh. Overrides previously + // scheduled tasks. + void ScheduleFixedTimerWakeUp(base::TimeDelta period); // Non-owning reference to pref service providing durable storage. PrefService* pref_service_; @@ -96,6 +120,21 @@ // Non-owning reference to clock to get current time. base::Clock* clock_; + // Persists NTP and article usage over time and provides a classification. + UserClassifier user_classifier_; + + // Callback to request that an async refresh be started. + base::RepeatingClosure refresh_callback_; + + // Provides ability to schedule and cancel persistent background fixed timer + // wake ups that will call into OnFixedTimer(). + ScheduleBackgroundTaskCallback schedule_background_task_callback_; + + // When a background wake up has caused a fixed timer refresh, this callback + // will be valid and holds a way to inform the task driving this wake up that + // the refresh has completed. Is called on refresh success or failure. + base::OnceClosure fixed_timer_completion_; + DISALLOW_COPY_AND_ASSIGN(FeedSchedulerHost); };
diff --git a/components/feed/core/feed_scheduler_host_unittest.cc b/components/feed/core/feed_scheduler_host_unittest.cc index 679c73e..0a7610e 100644 --- a/components/feed/core/feed_scheduler_host_unittest.cc +++ b/components/feed/core/feed_scheduler_host_unittest.cc
@@ -4,16 +4,22 @@ #include "components/feed/core/feed_scheduler_host.h" +#include <memory> +#include <vector> + #include "base/bind.h" +#include "base/memory/weak_ptr.h" #include "base/test/simple_test_clock.h" #include "components/feed/core/pref_names.h" +#include "components/feed/core/time_serialization.h" +#include "components/feed/core/user_classifier.h" +#include "components/feed/feed_feature_list.h" #include "components/prefs/testing_pref_service.h" +#include "components/variations/variations_params_manager.h" #include "testing/gtest/include/gtest/gtest.h" namespace feed { -namespace { - // Fixed "now" to make tests more deterministic. char kNowString[] = "2018-06-11 15:41"; @@ -21,54 +27,349 @@ class FeedSchedulerHostTest : public ::testing::Test { public: - void TriggerRefresh() { trigger_refresh_count_++; } + void FixedTimerCompletion() { fixed_timer_completion_count_++; } protected: - FeedSchedulerHostTest() : scheduler_(&pref_service_, &test_clock_) { + FeedSchedulerHostTest() : weak_factory_(this) { Time now; CHECK(Time::FromUTCString(kNowString, &now)); test_clock_.SetNow(now); FeedSchedulerHost::RegisterProfilePrefs(pref_service_.registry()); + UserClassifier::RegisterProfilePrefs(pref_service_.registry()); + + scheduler_ = + std::make_unique<FeedSchedulerHost>(&pref_service_, &test_clock_); + InitializeScheduler(scheduler()); + } + + void InitializeScheduler(FeedSchedulerHost* scheduler) { + scheduler->Initialize( + base::BindRepeating(&FeedSchedulerHostTest::TriggerRefresh, + base::Unretained(this)), + base::BindRepeating(&FeedSchedulerHostTest::ScheduleWakeUp, + base::Unretained(this))); + } + + // Note: Time will be advanced. + void ClassifyAsRareNtpUser() { + // By moving time forward from initial seed events, the user will be moved + // into RARE_NTP_USER classification. + test_clock()->Advance(base::TimeDelta::FromDays(7)); + } + + // Note: Time will be advanced. + void ClassifyAsActiveSuggestionsConsumer() { + // Click on some articles to move the user into ACTIVE_SUGGESTIONS_CONSUMER + // classification. Separate by at least 30 minutes for different sessions. + scheduler()->OnSuggestionConsumed(); + test_clock()->Advance(base::TimeDelta::FromMinutes(31)); + scheduler()->OnSuggestionConsumed(); + } + + // This helper method sets prefs::kLastFetchAttemptTime to the same value + // that's about to be passed into ShouldSessionRequestData(). This is what the + // scheduler will typically experience when refreshes are successful. + NativeRequestBehavior ShouldSessionRequestData( + bool has_content, + base::Time content_creation_date_time, + bool has_outstanding_request) { + pref_service()->SetTime(prefs::kLastFetchAttemptTime, + content_creation_date_time); + return scheduler()->ShouldSessionRequestData( + has_content, content_creation_date_time, has_outstanding_request); } PrefService* pref_service() { return &pref_service_; } base::SimpleTestClock* test_clock() { return &test_clock_; } - FeedSchedulerHost* scheduler() { return &scheduler_; } - int trigger_refresh_count() { return trigger_refresh_count_; } + FeedSchedulerHost* scheduler() { return scheduler_.get(); } + int refresh_call_count() { return refresh_call_count_; } + const std::vector<base::TimeDelta>& schedule_wake_up_times() { + return schedule_wake_up_times_; + } + int cancel_wake_up_call_count() { return cancel_wake_up_call_count_; } + int fixed_timer_completion_count() { return fixed_timer_completion_count_; } private: + void TriggerRefresh() { refresh_call_count_++; } + + void ScheduleWakeUp(base::TimeDelta threshold_ms) { + schedule_wake_up_times_.push_back(threshold_ms); + } + + void CancelWakeUp() { cancel_wake_up_call_count_++; } + TestingPrefServiceSimple pref_service_; base::SimpleTestClock test_clock_; - FeedSchedulerHost scheduler_; - int trigger_refresh_count_ = 0; + std::unique_ptr<FeedSchedulerHost> scheduler_; + int refresh_call_count_ = 0; + std::vector<base::TimeDelta> schedule_wake_up_times_; + int cancel_wake_up_call_count_ = 0; + int fixed_timer_completion_count_ = 0; + base::WeakPtrFactory<FeedSchedulerHostTest> weak_factory_; }; +TEST_F(FeedSchedulerHostTest, GetTriggerThreshold) { + // Make sure that there is no missing configuration in the cartesian product + // of states between TriggerType and UserClass. + std::vector<FeedSchedulerHost::TriggerType> triggers = { + FeedSchedulerHost::TriggerType::NTP_SHOWN, + FeedSchedulerHost::TriggerType::FOREGROUNDED, + FeedSchedulerHost::TriggerType::FIXED_TIMER}; + + // Classification starts out as an active NTP user. + for (FeedSchedulerHost::TriggerType trigger : triggers) { + EXPECT_FALSE(scheduler()->GetTriggerThreshold(trigger).is_zero()); + } + + ClassifyAsRareNtpUser(); + for (FeedSchedulerHost::TriggerType trigger : triggers) { + EXPECT_FALSE(scheduler()->GetTriggerThreshold(trigger).is_zero()); + } + + ClassifyAsActiveSuggestionsConsumer(); + for (FeedSchedulerHost::TriggerType trigger : triggers) { + EXPECT_FALSE(scheduler()->GetTriggerThreshold(trigger).is_zero()); + } +} + TEST_F(FeedSchedulerHostTest, ShouldSessionRequestDataSimple) { + // For an ACTIVE_NTP_USER, refreshes on NTP_OPEN should be triggered after 4 + // hours, and staleness should be at 24 hours. Each case tests a range of + // values. + base::Time no_refresh_large = + test_clock()->Now() - base::TimeDelta::FromHours(3); + base::Time refresh_only_small = + test_clock()->Now() - base::TimeDelta::FromHours(5); + base::Time refresh_only_large = + test_clock()->Now() - base::TimeDelta::FromHours(23); + base::Time stale_small = test_clock()->Now() - base::TimeDelta::FromHours(25); + EXPECT_EQ(REQUEST_WITH_WAIT, - scheduler()->ShouldSessionRequestData( + ShouldSessionRequestData( /*has_content*/ false, /*content_creation_date_time*/ Time(), /*has_outstanding_request*/ false)); - // TODO(skym): REQUEST_WITH_TIMEOUT. + + EXPECT_EQ(REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ refresh_only_small, + /*has_outstanding_request*/ false)); + EXPECT_EQ(REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ refresh_only_large, + /*has_outstanding_request*/ false)); + + EXPECT_EQ( + REQUEST_WITH_TIMEOUT, + ShouldSessionRequestData( + /*has_content*/ true, /*content_creation_date_time*/ stale_small, + /*has_outstanding_request*/ false)); + EXPECT_EQ( + REQUEST_WITH_TIMEOUT, + ShouldSessionRequestData( + /*has_content*/ true, /*content_creation_date_time*/ base::Time(), + /*has_outstanding_request*/ false)); + + // |content_creation_date_time| should be ignored when |has_content| is false. + EXPECT_EQ(NO_REQUEST_WITH_WAIT, + ShouldSessionRequestData( + /*has_content*/ false, + /*content_creation_date_time*/ test_clock()->Now(), + /*has_outstanding_request*/ true)); + EXPECT_EQ(NO_REQUEST_WITH_WAIT, + ShouldSessionRequestData( + /*has_content*/ false, /*content_creation_date_time*/ Time(), + /*has_outstanding_request*/ true)); + + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now(), + /*has_outstanding_request*/ false)); + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ no_refresh_large, + /*has_outstanding_request*/ false)); + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now(), + /*has_outstanding_request*/ true)); + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ refresh_only_large, + /*has_outstanding_request*/ true)); + + EXPECT_EQ( + NO_REQUEST_WITH_TIMEOUT, + ShouldSessionRequestData( + /*has_content*/ true, /*content_creation_date_time*/ stale_small, + /*has_outstanding_request*/ true)); + EXPECT_EQ( + NO_REQUEST_WITH_TIMEOUT, + ShouldSessionRequestData( + /*has_content*/ true, /*content_creation_date_time*/ base::Time(), + /*has_outstanding_request*/ true)); +} + +TEST_F(FeedSchedulerHostTest, ShouldSessionRequestDataDivergentTimes) { + // If a request fails, then the |content_creation_date_time| and the value of + // prefs::kLastFetchAttemptTime may diverge. This is okay, and will typically + // mean that refreshes are not taken. Staleness should continue to track + // |content_creation_date_time|, but because staleness uses a bigger threshold + // than NTP_OPEN, this will not affect much. + + // Like above case, the user is an ACTIVE_NTP_USER, staleness at 24 hours and + // refresh at 4. + base::Time refresh = test_clock()->Now() - base::TimeDelta::FromHours(5); + base::Time no_refresh = test_clock()->Now() - base::TimeDelta::FromHours(3); + base::Time stale = test_clock()->Now() - base::TimeDelta::FromHours(25); + base::Time not_stale = test_clock()->Now() - base::TimeDelta::FromHours(23); + + pref_service()->SetTime(prefs::kLastFetchAttemptTime, no_refresh); + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, scheduler()->ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ stale, + /*has_outstanding_request*/ false)); + + pref_service()->SetTime(prefs::kLastFetchAttemptTime, refresh); + + EXPECT_EQ(REQUEST_WITH_CONTENT, scheduler()->ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ not_stale, + /*has_outstanding_request*/ false)); + + pref_service()->SetTime(prefs::kLastFetchAttemptTime, refresh); + EXPECT_EQ(REQUEST_WITH_TIMEOUT, scheduler()->ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ stale, + /*has_outstanding_request*/ false)); + + // This shouldn't be possible, since last attempt is farther back than + // |content_creation_date_time| which updates on success, but verify scheduler + // handles it reasonably. + pref_service()->SetTime(prefs::kLastFetchAttemptTime, base::Time()); EXPECT_EQ(REQUEST_WITH_CONTENT, scheduler()->ShouldSessionRequestData( - /*has_content*/ true, /*content_creation_date_time*/ Time(), + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now(), /*has_outstanding_request*/ false)); - EXPECT_EQ(NO_REQUEST_WITH_WAIT, + + // By changing the foregrounded threshold, staleness calculation changes. + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"foregrounded_hours_active_ntp_user", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + EXPECT_EQ(REQUEST_WITH_CONTENT, scheduler()->ShouldSessionRequestData( - /*has_content*/ false, /*content_creation_date_time*/ Time(), - /*has_outstanding_request*/ true)); - // TODO(skym): NO_REQUEST_WITH_TIMEOUT. + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(7), + /*has_outstanding_request*/ false)); + EXPECT_EQ(REQUEST_WITH_TIMEOUT, + scheduler()->ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(8), + /*has_outstanding_request*/ false)); +} + +TEST_F(FeedSchedulerHostTest, NtpShownActiveNtpUser) { + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"ntp_shown_hours_active_ntp_user", "2.5"}}, + {kInterestFeedContentSuggestions.name}); + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, - scheduler()->ShouldSessionRequestData( - /*has_content*/ true, /*content_creation_date_time*/ Time(), - /*has_outstanding_request*/ true)); + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(2), + /*has_outstanding_request*/ false)); + + EXPECT_EQ(REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(3), + /*has_outstanding_request*/ false)); +} + +TEST_F(FeedSchedulerHostTest, NtpShownRareNtpUser) { + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"ntp_shown_hours_rare_ntp_user", "1.5"}}, + {kInterestFeedContentSuggestions.name}); + + ClassifyAsRareNtpUser(); + + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(1), + /*has_outstanding_request*/ false)); + + // ShouldSessionRequestData() has the side effect of adding NTP_SHOWN event to + // the classifier, so push the timer out to keep classification. + ClassifyAsRareNtpUser(); + + EXPECT_EQ(REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(2), + /*has_outstanding_request*/ false)); +} + +TEST_F(FeedSchedulerHostTest, NtpShownActiveSuggestionsConsumer) { + ClassifyAsActiveSuggestionsConsumer(); + + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromMinutes(59), + /*has_outstanding_request*/ false)); + + EXPECT_EQ(REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromMinutes(61), + /*has_outstanding_request*/ false)); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"ntp_shown_hours_active_suggestions_consumer", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + EXPECT_EQ(NO_REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(7), + /*has_outstanding_request*/ false)); + + EXPECT_EQ(REQUEST_WITH_CONTENT, + ShouldSessionRequestData( + /*has_content*/ true, + /*content_creation_date_time*/ test_clock()->Now() - + base::TimeDelta::FromHours(8), + /*has_outstanding_request*/ false)); } TEST_F(FeedSchedulerHostTest, OnReceiveNewContentVerifyPref) { EXPECT_EQ(Time(), pref_service()->GetTime(prefs::kLastFetchAttemptTime)); scheduler()->OnReceiveNewContent(Time()); - EXPECT_EQ(test_clock()->Now(), + EXPECT_EQ(Time(), pref_service()->GetTime(prefs::kLastFetchAttemptTime)); + // Scheduler should prefer to use specified time over clock time. + EXPECT_NE(test_clock()->Now(), pref_service()->GetTime(prefs::kLastFetchAttemptTime)); } @@ -79,20 +380,228 @@ pref_service()->GetTime(prefs::kLastFetchAttemptTime)); } -TEST_F(FeedSchedulerHostTest, OnForegroundedTriggersRefresh) { - scheduler()->RegisterTriggerRefreshCallback(base::BindRepeating( - &FeedSchedulerHostTest::TriggerRefresh, base::Unretained(this))); +TEST_F(FeedSchedulerHostTest, OnForegroundedActiveNtpUser) { scheduler()->OnForegrounded(); - EXPECT_EQ(1, trigger_refresh_count()); + EXPECT_EQ(1, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + // Default is 24 hours. + test_clock()->Advance(base::TimeDelta::FromHours(23)); + scheduler()->OnForegrounded(); + EXPECT_EQ(1, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(2)); + scheduler()->OnForegrounded(); + EXPECT_EQ(2, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"foregrounded_hours_active_ntp_user", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + test_clock()->Advance(base::TimeDelta::FromHours(7)); + scheduler()->OnForegrounded(); + EXPECT_EQ(2, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(1)); + scheduler()->OnForegrounded(); + EXPECT_EQ(3, refresh_call_count()); } -TEST_F(FeedSchedulerHostTest, OnFixedTimerTriggersRefresh) { - scheduler()->RegisterTriggerRefreshCallback(base::BindRepeating( - &FeedSchedulerHostTest::TriggerRefresh, base::Unretained(this))); - scheduler()->OnFixedTimer(); - EXPECT_EQ(1, trigger_refresh_count()); +TEST_F(FeedSchedulerHostTest, OnForegroundedRareNtpUser) { + ClassifyAsRareNtpUser(); + + scheduler()->OnForegrounded(); + EXPECT_EQ(1, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + // Default is 24 hours. + test_clock()->Advance(base::TimeDelta::FromHours(23)); + scheduler()->OnForegrounded(); + EXPECT_EQ(1, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(2)); + scheduler()->OnForegrounded(); + EXPECT_EQ(2, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"foregrounded_hours_rare_ntp_user", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + test_clock()->Advance(base::TimeDelta::FromHours(7)); + scheduler()->OnForegrounded(); + EXPECT_EQ(2, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(1)); + scheduler()->OnForegrounded(); + EXPECT_EQ(3, refresh_call_count()); } -} // namespace +TEST_F(FeedSchedulerHostTest, OnForegroundedActiveSuggestionsConsumer) { + ClassifyAsActiveSuggestionsConsumer(); + + scheduler()->OnForegrounded(); + EXPECT_EQ(1, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + // Default is 12 hours. + test_clock()->Advance(base::TimeDelta::FromHours(11)); + scheduler()->OnForegrounded(); + EXPECT_EQ(1, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(2)); + scheduler()->OnForegrounded(); + EXPECT_EQ(2, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"foregrounded_hours_active_suggestions_consumer", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + test_clock()->Advance(base::TimeDelta::FromHours(7)); + scheduler()->OnForegrounded(); + EXPECT_EQ(2, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(1)); + scheduler()->OnForegrounded(); + EXPECT_EQ(3, refresh_call_count()); +} + +TEST_F(FeedSchedulerHostTest, OnFixedTimerNullCallback) { + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); +} + +TEST_F(FeedSchedulerHostTest, OnFixedTimerCompletionRunOnSuccess) { + scheduler()->OnFixedTimer(base::BindOnce( + &FeedSchedulerHostTest::FixedTimerCompletion, base::Unretained(this))); + EXPECT_EQ(1, refresh_call_count()); + + scheduler()->OnReceiveNewContent(Time()); + EXPECT_EQ(1, fixed_timer_completion_count()); +} + +TEST_F(FeedSchedulerHostTest, OnFixedTimerCompletionRunOnFailure) { + scheduler()->OnFixedTimer(base::BindOnce( + &FeedSchedulerHostTest::FixedTimerCompletion, base::Unretained(this))); + EXPECT_EQ(1, refresh_call_count()); + + scheduler()->OnRequestError(0); + EXPECT_EQ(1, fixed_timer_completion_count()); +} + +TEST_F(FeedSchedulerHostTest, OnFixedTimerActiveNtpUser) { + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + // Default is 48 hours. + test_clock()->Advance(base::TimeDelta::FromHours(47)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(2)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(2, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"fixed_timer_hours_active_ntp_user", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + test_clock()->Advance(base::TimeDelta::FromHours(7)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(2, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(1)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(3, refresh_call_count()); +} + +TEST_F(FeedSchedulerHostTest, OnFixedTimerActiveRareNtpUser) { + ClassifyAsRareNtpUser(); + + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + // Default is 96 hours. + test_clock()->Advance(base::TimeDelta::FromHours(95)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(2)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(2, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"fixed_timer_hours_rare_ntp_user", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + test_clock()->Advance(base::TimeDelta::FromHours(7)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(2, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(1)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(3, refresh_call_count()); +} + +TEST_F(FeedSchedulerHostTest, OnFixedTimerActiveSuggestionsConsumer) { + ClassifyAsActiveSuggestionsConsumer(); + + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + // Default is 24 hours. + test_clock()->Advance(base::TimeDelta::FromHours(23)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(1, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(2)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(2, refresh_call_count()); + scheduler()->OnReceiveNewContent(test_clock()->Now()); + + variations::testing::VariationParamsManager variation_params( + kInterestFeedContentSuggestions.name, + {{"fixed_timer_hours_active_suggestions_consumer", "7.5"}}, + {kInterestFeedContentSuggestions.name}); + + test_clock()->Advance(base::TimeDelta::FromHours(7)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(2, refresh_call_count()); + + test_clock()->Advance(base::TimeDelta::FromHours(1)); + scheduler()->OnFixedTimer(base::OnceClosure()); + EXPECT_EQ(3, refresh_call_count()); +} + +TEST_F(FeedSchedulerHostTest, ScheduleFixedTimerWakeUpOnSuccess) { + // First wake up scheduled during Initialize(). + EXPECT_EQ(1U, schedule_wake_up_times().size()); + scheduler()->OnReceiveNewContent(Time()); + EXPECT_EQ(2U, schedule_wake_up_times().size()); + + // Make another scheduler to initialize, make sure it doesn't schedule a + // wake up. + FeedSchedulerHost second_scheduler(pref_service(), test_clock()); + InitializeScheduler(&second_scheduler); + EXPECT_EQ(2U, schedule_wake_up_times().size()); +} + +TEST_F(FeedSchedulerHostTest, OnTaskReschedule) { + EXPECT_EQ(1U, schedule_wake_up_times().size()); + scheduler()->OnTaskReschedule(); + EXPECT_EQ(2U, schedule_wake_up_times().size()); +} } // namespace feed
diff --git a/components/feed/core/pref_names.cc b/components/feed/core/pref_names.cc index ae4c3df..1976a47d 100644 --- a/components/feed/core/pref_names.cc +++ b/components/feed/core/pref_names.cc
@@ -8,6 +8,8 @@ namespace prefs { +const char kBackgroundRefreshPeriod[] = "feed.background_refresh_period"; + const char kLastFetchAttemptTime[] = "feed.last_fetch_attempt"; const char kUserClassifierAverageNTPOpenedPerHour[] =
diff --git a/components/feed/core/pref_names.h b/components/feed/core/pref_names.h index 38985a3..cd61363 100644 --- a/components/feed/core/pref_names.h +++ b/components/feed/core/pref_names.h
@@ -9,6 +9,9 @@ namespace prefs { +// The pref name for the period of time between background refreshes. +extern const char kBackgroundRefreshPeriod[]; + // The pref name for the last time when a background fetch was attempted. extern const char kLastFetchAttemptTime[];
diff --git a/components/feed/core/user_classifier.cc b/components/feed/core/user_classifier.cc index 8898cc92..2764226f 100644 --- a/components/feed/core/user_classifier.cc +++ b/components/feed/core/user_classifier.cc
@@ -30,7 +30,7 @@ // Never consider any larger interval than this (so that extreme situations such // as losing your phone or going for a long offline vacation do not skew the // average too much). -// When everriding via variation parameters, it is better to use smaller values +// When overriding via variation parameters, it is better to use smaller values // than |kMaxHours| as this it the maximum value reported in the histograms. const double kMaxHours = 7 * 24; const char kMaxHoursParam[] = "user_classifier_max_hours"; @@ -45,18 +45,15 @@ const double kActiveConsumerClicksAtLeastOncePerHours = 96; const char kActiveConsumerClicksAtLeastOncePerHoursParam[] = "user_classifier_active_consumer_clicks_at_least_once_per_hours"; - -// The previous value in production was 66, i.e. 2.75 days. The new value is a -// shift in the direction we want (having more active users). const double kRareUserOpensNTPAtMostOncePerHours = 96; const char kRareUserOpensNTPAtMostOncePerHoursParam[] = "user_classifier_rare_user_opens_ntp_at_most_once_per_hours"; -// The enum used for iteration. +// List of all Events used for iteration. const UserClassifier::Event kEvents[] = { UserClassifier::Event::NTP_OPENED, UserClassifier::Event::SUGGESTIONS_USED}; -// The summary of the prefs. +// Arrays of pref names, indexed by Event's int value. const char* kRateKeys[] = {prefs::kUserClassifierAverageNTPOpenedPerHour, prefs::kUserClassifierAverageSuggestionsUsedPerHour}; const char* kLastTimeKeys[] = {prefs::kUserClassifierLastTimeToOpenNTP,
diff --git a/components/feedback/feedback_data.cc b/components/feedback/feedback_data.cc index c58dce1f..54b8c8a 100644 --- a/components/feedback/feedback_data.cc +++ b/components/feedback/feedback_data.cc
@@ -72,8 +72,8 @@ AddLogs(std::move(sys_info)); base::PostTaskWithTraitsAndReply( FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&FeedbackData::CompressLogs, this), - base::Bind(&FeedbackData::OnCompressComplete, this)); + base::BindOnce(&FeedbackData::CompressLogs, this), + base::BindOnce(&FeedbackData::OnCompressComplete, this)); } } @@ -143,9 +143,9 @@ report_sent_ = true; userfeedback::ExtensionSubmit feedback_data; PrepareReport(&feedback_data); - std::string post_body; - feedback_data.SerializeToString(&post_body); - uploader_->QueueReport(post_body); + auto post_body = std::make_unique<std::string>(); + feedback_data.SerializeToString(post_body.get()); + uploader_->QueueReport(std::move(post_body)); } }
diff --git a/components/feedback/feedback_report.cc b/components/feedback/feedback_report.cc index faa5c77..ced788f 100644 --- a/components/feedback/feedback_report.cc +++ b/components/feedback/feedback_report.cc
@@ -12,6 +12,8 @@ #include "base/sequenced_task_runner.h" #include "base/strings/string_number_conversions.h" +namespace feedback { + namespace { constexpr base::FilePath::CharType kFeedbackReportFilenameWildcard[] = @@ -21,44 +23,45 @@ void WriteReportOnBlockingPool(const base::FilePath reports_path, const base::FilePath& file, - const std::string& data) { + scoped_refptr<FeedbackReport> report) { DCHECK(reports_path.IsParent(file)); if (!base::DirectoryExists(reports_path)) { base::File::Error error; if (!base::CreateDirectoryAndGetError(reports_path, &error)) return; } - base::ImportantFileWriter::WriteFileAtomically(file, data, "FeedbackReport"); + base::ImportantFileWriter::WriteFileAtomically(file, report->data(), + "FeedbackReport"); } } // namespace -namespace feedback { - FeedbackReport::FeedbackReport( const base::FilePath& path, const base::Time& upload_at, - const std::string& data, + std::unique_ptr<std::string> data, scoped_refptr<base::SequencedTaskRunner> task_runner) : reports_path_(path), upload_at_(upload_at), - data_(data), + data_(std::move(data)), reports_task_runner_(task_runner) { if (reports_path_.empty()) return; file_ = reports_path_.AppendASCII( kFeedbackReportFilenamePrefix + base::GenerateGUID()); - reports_task_runner_->PostTask(FROM_HERE, base::Bind( - &WriteReportOnBlockingPool, reports_path_, file_, data_)); + reports_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&WriteReportOnBlockingPool, reports_path_, file_, + base::WrapRefCounted<FeedbackReport>(this))); } // static const char FeedbackReport::kCrashReportIdsKey[] = "crash_report_ids"; // static -void FeedbackReport::LoadReportsAndQueue( - const base::FilePath& user_dir, QueueCallback callback) { +void FeedbackReport::LoadReportsAndQueue(const base::FilePath& user_dir, + const QueueCallback& callback) { if (user_dir.empty()) return; @@ -69,9 +72,9 @@ for (base::FilePath name = enumerator.Next(); !name.empty(); name = enumerator.Next()) { - std::string data; - if (ReadFileToString(name, &data)) - callback.Run(data); + auto data = std::make_unique<std::string>(); + if (ReadFileToString(name, data.get())) + callback.Run(std::move(data)); base::DeleteFile(name, false); } } @@ -79,7 +82,7 @@ void FeedbackReport::DeleteReportOnDisk() { reports_task_runner_->PostTask( FROM_HERE, - base::Bind(base::IgnoreResult(&base::DeleteFile), file_, false)); + base::BindOnce(base::IgnoreResult(&base::DeleteFile), file_, false)); } FeedbackReport::~FeedbackReport() {}
diff --git a/components/feedback/feedback_report.h b/components/feedback/feedback_report.h index d3fdb8d..1e330cab 100644 --- a/components/feedback/feedback_report.h +++ b/components/feedback/feedback_report.h
@@ -19,16 +19,19 @@ namespace feedback { -typedef base::Callback<void(const std::string&)> QueueCallback; +// Repeating since for every feedback report file on disk, the callback to +// queue it in the uploader needs to be invoked. +using QueueCallback = + base::RepeatingCallback<void(std::unique_ptr<std::string>)>; // This class holds a feedback report. Once a report is created, a disk backup // for it is created automatically. This backup needs to explicitly be // deleted by calling DeleteReportOnDisk. -class FeedbackReport : public base::RefCounted<FeedbackReport> { +class FeedbackReport : public base::RefCountedThreadSafe<FeedbackReport> { public: FeedbackReport(const base::FilePath& path, const base::Time& upload_at, - const std::string& data, + std::unique_ptr<std::string> data, scoped_refptr<base::SequencedTaskRunner> task_runner); // The ID of the product specific data for the crash report IDs as stored by @@ -38,7 +41,7 @@ // Loads the reports still on disk and queues then using the given callback. // This call blocks on the file reads. static void LoadReportsAndQueue(const base::FilePath& user_dir, - QueueCallback callback); + const QueueCallback& callback); // Stops the disk write of the report and deletes the report file if already // written. @@ -46,10 +49,10 @@ const base::Time& upload_at() const { return upload_at_; } void set_upload_at(const base::Time& time) { upload_at_ = time; } - const std::string& data() const { return data_; } + const std::string& data() const { return *data_; } private: - friend class base::RefCounted<FeedbackReport>; + friend class base::RefCountedThreadSafe<FeedbackReport>; virtual ~FeedbackReport(); // Name of the file corresponding to this report. @@ -57,7 +60,7 @@ base::FilePath reports_path_; base::Time upload_at_; // Upload this report at or after this time. - std::string data_; + std::unique_ptr<std::string> data_; scoped_refptr<base::SequencedTaskRunner> reports_task_runner_;
diff --git a/components/feedback/feedback_uploader.cc b/components/feedback/feedback_uploader.cc index fe16704..6b70f3a 100644 --- a/components/feedback/feedback_uploader.cc +++ b/components/feedback/feedback_uploader.cc
@@ -72,8 +72,8 @@ g_minimum_retry_delay = delay; } -void FeedbackUploader::QueueReport(const std::string& data) { - QueueReportWithDelay(data, base::TimeDelta()); +void FeedbackUploader::QueueReport(std::unique_ptr<std::string> data) { + QueueReportWithDelay(std::move(data), base::TimeDelta()); } void FeedbackUploader::StartDispatchingReport() { @@ -205,10 +205,11 @@ } } -void FeedbackUploader::QueueReportWithDelay(const std::string& data, +void FeedbackUploader::QueueReportWithDelay(std::unique_ptr<std::string> data, base::TimeDelta delay) { reports_queue_.emplace(base::MakeRefCounted<FeedbackReport>( - feedback_reports_path_, base::Time::Now() + delay, data, task_runner_)); + feedback_reports_path_, base::Time::Now() + delay, std::move(data), + task_runner_)); UpdateUploadTimer(); }
diff --git a/components/feedback/feedback_uploader.h b/components/feedback/feedback_uploader.h index dc06ea0..1c500fe 100644 --- a/components/feedback/feedback_uploader.h +++ b/components/feedback/feedback_uploader.h
@@ -43,7 +43,7 @@ static void SetMinimumRetryDelayForTesting(base::TimeDelta delay); // Queues a report for uploading. - void QueueReport(const std::string& data); + void QueueReport(std::unique_ptr<std::string> data); bool QueueEmpty() const { return reports_queue_.empty(); } @@ -101,7 +101,8 @@ // Update our timer for uploading the next report. void UpdateUploadTimer(); - void QueueReportWithDelay(const std::string& data, base::TimeDelta delay); + void QueueReportWithDelay(std::unique_ptr<std::string> data, + base::TimeDelta delay); // Browser context this uploader was created for. content::BrowserContext* context_;
diff --git a/components/feedback/feedback_uploader_dispatch_unittest.cc b/components/feedback/feedback_uploader_dispatch_unittest.cc index e7ca044..300d3d70 100644 --- a/components/feedback/feedback_uploader_dispatch_unittest.cc +++ b/components/feedback/feedback_uploader_dispatch_unittest.cc
@@ -31,6 +31,10 @@ constexpr int kHttpPostFailClientError = 400; constexpr int kHttpPostFailServerError = 500; +void QueueReport(FeedbackUploader* uploader, const std::string& report_data) { + uploader->QueueReport(std::make_unique<std::string>(report_data)); +} + } // namespace class FeedbackUploaderDispatchTest : public ::testing::Test { @@ -75,7 +79,7 @@ context(), FeedbackUploaderFactory::CreateUploaderTaskRunner()); net::TestURLFetcherFactory factory; - uploader.QueueReport("test"); + QueueReport(&uploader, "test"); net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); net::HttpRequestHeaders headers; @@ -99,7 +103,7 @@ // increase the backoff delay. net::TestURLFetcherFactory factory; factory.set_remove_fetcher_on_delete(true); - uploader.QueueReport("Successful report"); + QueueReport(&uploader, "Successful report"); net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); fetcher->set_response_code(kHttpPostSuccessNoContent); fetcher->delegate()->OnURLFetchComplete(fetcher); @@ -108,7 +112,7 @@ // Failed reports due to client errors are not retried. No backoff delay // should be doubled. - uploader.QueueReport("Client error failed report"); + QueueReport(&uploader, "Client error failed report"); fetcher = factory.GetFetcherByID(0); fetcher->set_response_code(kHttpPostFailClientError); fetcher->delegate()->OnURLFetchComplete(fetcher); @@ -116,7 +120,7 @@ EXPECT_TRUE(uploader.QueueEmpty()); // Failed reports due to server errors are retried. - uploader.QueueReport("Server error failed report"); + QueueReport(&uploader, "Server error failed report"); fetcher = factory.GetFetcherByID(0); fetcher->set_response_code(kHttpPostFailServerError); fetcher->delegate()->OnURLFetchComplete(fetcher);
diff --git a/components/feedback/feedback_uploader_unittest.cc b/components/feedback/feedback_uploader_unittest.cc index d9bf658..6c93fa0 100644 --- a/components/feedback/feedback_uploader_unittest.cc +++ b/components/feedback/feedback_uploader_unittest.cc
@@ -52,8 +52,8 @@ FROM_HERE, base::BindOnce( &FeedbackReport::LoadReportsAndQueue, feedback_reports_path(), - base::Bind(&MockFeedbackUploader::QueueSingleReport, - base::SequencedTaskRunnerHandle::Get(), this))); + base::BindRepeating(&MockFeedbackUploader::QueueSingleReport, + base::SequencedTaskRunnerHandle::Get(), this))); } const std::map<std::string, unsigned int>& dispatched_reports() const { @@ -66,10 +66,10 @@ static void QueueSingleReport( scoped_refptr<base::SequencedTaskRunner> main_task_runner, MockFeedbackUploader* uploader, - const std::string& data) { + std::unique_ptr<std::string> data) { main_task_runner->PostTask( FROM_HERE, base::BindOnce(&MockFeedbackUploader::QueueReport, - uploader->AsWeakPtr(), data)); + uploader->AsWeakPtr(), std::move(data))); } // FeedbackUploaderChrome: @@ -122,7 +122,7 @@ } void QueueReport(const std::string& data) { - uploader_->QueueReport(data); + uploader_->QueueReport(std::make_unique<std::string>(data)); } MockFeedbackUploader* uploader() const { return uploader_.get(); }
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 75d36a2..9b54656 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -6,6 +6,8 @@ static_library("metrics") { sources = [ + "call_stack_profile_builder.cc", + "call_stack_profile_builder.h", "call_stack_profile_metrics_provider.cc", "call_stack_profile_metrics_provider.h", "clean_exit_beacon.cc", @@ -326,6 +328,7 @@ source_set("unit_tests") { testonly = true sources = [ + "call_stack_profile_builder_unittest.cc", "call_stack_profile_metrics_provider_unittest.cc", "child_call_stack_profile_collector_unittest.cc", "cloned_install_detector_unittest.cc",
diff --git a/components/metrics/call_stack_profile_builder.cc b/components/metrics/call_stack_profile_builder.cc new file mode 100644 index 0000000..f3eb2b1 --- /dev/null +++ b/components/metrics/call_stack_profile_builder.cc
@@ -0,0 +1,64 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/call_stack_profile_builder.h" + +#include <utility> + +#include "base/logging.h" + +using StackSamplingProfiler = base::StackSamplingProfiler; + +CallStackProfileBuilder::CallStackProfileBuilder( + const StackSamplingProfiler::CompletedCallback& callback) + : callback_(callback) {} + +CallStackProfileBuilder::~CallStackProfileBuilder() = default; + +void CallStackProfileBuilder::RecordAnnotations() { + // The code inside this method must not do anything that could acquire a + // mutex, including allocating memory (which includes LOG messages) because + // that mutex could be held by a stopped thread, thus resulting in deadlock. + sample_.process_milestones = StackSamplingProfiler::ProcessMilestone(); +} + +void CallStackProfileBuilder::OnSampleCompleted( + std::vector<StackSamplingProfiler::InternalFrame> internal_frames) { + DCHECK(sample_.frames.empty()); + + // Dedup modules and convert InternalFrames to Frames. + for (const auto& internal_frame : internal_frames) { + const StackSamplingProfiler::InternalModule& module( + internal_frame.internal_module); + if (!module.is_valid) { + sample_.frames.emplace_back(internal_frame.instruction_pointer, + base::kUnknownModuleIndex); + continue; + } + + auto loc = module_index_.find(module.base_address); + if (loc == module_index_.end()) { + profile_.modules.emplace_back(module.base_address, module.id, + module.filename); + size_t index = profile_.modules.size() - 1; + loc = module_index_.insert(std::make_pair(module.base_address, index)) + .first; + } + sample_.frames.emplace_back(internal_frame.instruction_pointer, + loc->second); + } + + profile_.samples.push_back(std::move(sample_)); + sample_ = StackSamplingProfiler::Sample(); +} + +void CallStackProfileBuilder::OnProfileCompleted( + base::TimeDelta profile_duration, + base::TimeDelta sampling_period) { + profile_.profile_duration = profile_duration; + profile_.sampling_period = sampling_period; + + // Run the associated callback, passing the collected profile. + callback_.Run(std::move(profile_)); +} \ No newline at end of file
diff --git a/components/metrics/call_stack_profile_builder.h b/components/metrics/call_stack_profile_builder.h new file mode 100644 index 0000000..d647867 --- /dev/null +++ b/components/metrics/call_stack_profile_builder.h
@@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_ +#define COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_ + +#include "base/profiler/stack_sampling_profiler.h" + +#include <map> + +// CallStackProfileBuilder builds a CallStackProfile from the collected sampling +// data. +// +// The results of the profile building -- a CallStackProfile, is passed to the +// completed callback. A CallStackProfile contains a set of Samples and +// Modules, and other sampling information. One Sample corresponds to a single +// recorded stack, and the Modules record those modules associated with the +// recorded stack frames. +class CallStackProfileBuilder + : public base::StackSamplingProfiler::ProfileBuilder { + public: + CallStackProfileBuilder( + const base::StackSamplingProfiler::CompletedCallback& callback); + + ~CallStackProfileBuilder() override; + + // base::StackSamplingProfiler::ProfileBuilder: + void RecordAnnotations() override; + void OnSampleCompleted(std::vector<base::StackSamplingProfiler::InternalFrame> + internal_frames) override; + void OnProfileCompleted(base::TimeDelta profile_duration, + base::TimeDelta sampling_period) override; + + private: + // The collected stack samples. + base::StackSamplingProfiler::CallStackProfile profile_; + + // The current sample being recorded. + base::StackSamplingProfiler::Sample sample_; + + // The indexes of internal modules, indexed by module's base_address. + std::map<uintptr_t, size_t> module_index_; + + // Callback made when sampling a profile completes. + const base::StackSamplingProfiler::CompletedCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(CallStackProfileBuilder); +}; + +#endif // COMPONENTS_METRICS_CALL_STACK_PROFILE_BUILDER_H_
diff --git a/components/metrics/call_stack_profile_builder_unittest.cc b/components/metrics/call_stack_profile_builder_unittest.cc new file mode 100644 index 0000000..8816b6c --- /dev/null +++ b/components/metrics/call_stack_profile_builder_unittest.cc
@@ -0,0 +1,155 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/call_stack_profile_builder.h" + +#include "base/files/file_path.h" +#include "base/test/bind_test_util.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" + +using StackSamplingProfiler = base::StackSamplingProfiler; +using InternalFrame = StackSamplingProfiler::InternalFrame; +using InternalModule = StackSamplingProfiler::InternalModule; +using CallStackProfile = StackSamplingProfiler::CallStackProfile; + +namespace { + +// Called on the profiler thread when complete, to collect profile. +void SaveProfile(CallStackProfile* profile, CallStackProfile pending_profile) { + *profile = std::move(pending_profile); +} + +} // namespace + +TEST(CallStackProfileBuilderTest, SetProcessMilestone) { + CallStackProfile profile; + + // Set up a callback to record the CallStackProfile to local variable + // |profile|. + auto profile_builder = std::make_unique<CallStackProfileBuilder>( + Bind(&SaveProfile, Unretained(&profile))); + + profile_builder->RecordAnnotations(); + profile_builder->OnSampleCompleted(std::vector<InternalFrame>()); + + StackSamplingProfiler::SetProcessMilestone(1); + profile_builder->RecordAnnotations(); + profile_builder->OnSampleCompleted(std::vector<InternalFrame>()); + + profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta()); + + ASSERT_EQ(2u, profile.samples.size()); + EXPECT_EQ(0u, profile.samples[0].process_milestones); + EXPECT_EQ(1u << 1, profile.samples[1].process_milestones); +} + +TEST(CallStackProfileBuilderTest, OnSampleCompleted) { + CallStackProfile profile; + + // Set up a callback to record the CallStackProfile to local variable + // |profile|. + auto profile_builder = std::make_unique<CallStackProfileBuilder>( + Bind(&SaveProfile, Unretained(&profile))); + + InternalModule module1 = {0xccccdddd, "1", + base::FilePath(FILE_PATH_LITERAL("file_path_1"))}; + InternalModule module2 = {0xccddccdd, "2", + base::FilePath(FILE_PATH_LITERAL("file_path_2"))}; + InternalFrame frame1 = {0xaaaabbbb, module1}; + InternalFrame frame2 = {0xaabbaabb, module2}; + + std::vector<InternalFrame> frames = {frame1, frame2}; + + profile_builder->OnSampleCompleted(frames); + profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta()); + + ASSERT_EQ(1u, profile.samples.size()); + ASSERT_EQ(2u, profile.samples[0].frames.size()); + EXPECT_EQ(0u, profile.samples[0].frames[0].module_index); + EXPECT_EQ(1u, profile.samples[0].frames[1].module_index); +} + +TEST(CallStackProfileBuilderTest, OnProfileCompleted) { + CallStackProfile profile; + + // Set up a callback to record the CallStackProfile to local variable + // |profile|. + auto profile_builder = std::make_unique<CallStackProfileBuilder>( + Bind(&SaveProfile, Unretained(&profile))); + + InternalModule module1 = {0xccccdddd, "1", + base::FilePath(FILE_PATH_LITERAL("file_path_1"))}; + InternalModule module2 = {0xccddccdd, "2", + base::FilePath(FILE_PATH_LITERAL("file_path_2"))}; + InternalFrame frame1 = {0xaaaabbbb, module1}; + InternalFrame frame2 = {0xaabbaabb, module2}; + + std::vector<InternalFrame> frames = {frame1, frame2}; + + profile_builder->OnSampleCompleted(frames); + profile_builder->OnProfileCompleted(base::TimeDelta::FromMilliseconds(500), + base::TimeDelta::FromMilliseconds(100)); + + ASSERT_EQ(1u, profile.samples.size()); + ASSERT_EQ(2u, profile.samples[0].frames.size()); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), profile.profile_duration); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), profile.sampling_period); +} + +TEST(CallStackProfileBuilderTest, InvalidModule) { + CallStackProfile profile; + + // Set up a callback to record the CallStackProfile to local variable + // |profile|. + auto profile_builder = std::make_unique<CallStackProfileBuilder>( + Bind(&SaveProfile, Unretained(&profile))); + + InternalModule module1; + InternalModule module2 = {0xccddccdd, "2", + base::FilePath(FILE_PATH_LITERAL("file_path_2"))}; + InternalFrame frame1 = {0xaaaabbbb, module1}; + InternalFrame frame2 = {0xaabbaabb, module2}; + + std::vector<InternalFrame> frames = {frame1, frame2}; + + profile_builder->OnSampleCompleted(frames); + profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta()); + + ASSERT_EQ(1u, profile.samples.size()); + ASSERT_EQ(2u, profile.samples[0].frames.size()); + + // module1 has no information hence invalid. The module index of the frame is + // therefore base::kUnknownModuleIndex. + EXPECT_EQ(base::kUnknownModuleIndex, + profile.samples[0].frames[0].module_index); + + EXPECT_EQ(0u, profile.samples[0].frames[1].module_index); +} + +TEST(CallStackProfileBuilderTest, DedupModules) { + CallStackProfile profile; + auto profile_builder = std::make_unique<CallStackProfileBuilder>( + Bind(&SaveProfile, Unretained(&profile))); + + InternalModule module1 = {0xccccdddd, "1", + base::FilePath(FILE_PATH_LITERAL("file_path_1"))}; + InternalModule module2 = {0xccccdddd, "2", + base::FilePath(FILE_PATH_LITERAL("file_path_2"))}; + InternalFrame frame1 = {0xaaaabbbb, module1}; + InternalFrame frame2 = {0xaabbaabb, module2}; + + std::vector<InternalFrame> frames = {frame1, frame2}; + + profile_builder->OnSampleCompleted(frames); + profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta()); + + ASSERT_EQ(1u, profile.samples.size()); + ASSERT_EQ(2u, profile.samples[0].frames.size()); + + // Since module1 and module2 have the same base address 0xccccdddd, they are + // considered the same module and therefore deduped. + EXPECT_EQ(0u, profile.samples[0].frames[0].module_index); + EXPECT_EQ(0u, profile.samples[0].frames[1].module_index); +}
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_features.cc b/components/ntp_snippets/contextual/contextual_suggestions_features.cc index effd70a8..9321557 100644 --- a/components/ntp_snippets/contextual/contextual_suggestions_features.cc +++ b/components/ntp_snippets/contextual/contextual_suggestions_features.cc
@@ -15,4 +15,7 @@ const base::Feature kContextualSuggestionsSlimPeekUI{ "ContextualSuggestionsSlimPeekUI", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kContextualSuggestionsOptOut{ + "ContextualSuggestionsOptOut", base::FEATURE_ENABLED_BY_DEFAULT}; + } // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_features.h b/components/ntp_snippets/contextual/contextual_suggestions_features.h index 7c095a0..11d28fa 100644 --- a/components/ntp_snippets/contextual/contextual_suggestions_features.h +++ b/components/ntp_snippets/contextual/contextual_suggestions_features.h
@@ -12,6 +12,7 @@ extern const base::Feature kContextualSuggestionsBottomSheet; extern const base::Feature kContextualSuggestionsButton; extern const base::Feature kContextualSuggestionsSlimPeekUI; +extern const base::Feature kContextualSuggestionsOptOut; } // namespace contextual_suggestions
diff --git a/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc b/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc index edb5024..407811c6 100644 --- a/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc +++ b/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc
@@ -5,6 +5,8 @@ #include "components/offline_items_collection/core/android/offline_content_aggregator_bridge.h" #include <memory> +#include <utility> +#include <vector> #include "base/android/callback_android.h" #include "base/android/jni_string.h" @@ -52,14 +54,14 @@ void RunGetAllItemsCallback(const base::android::JavaRef<jobject>& j_callback, const std::vector<OfflineItem>& items) { JNIEnv* env = AttachCurrentThread(); - RunCallbackAndroid(j_callback, - OfflineItemBridge::CreateOfflineItemList(env, items)); + RunObjectCallbackAndroid( + j_callback, OfflineItemBridge::CreateOfflineItemList(env, items)); } void RunGetItemByIdCallback(const base::android::JavaRef<jobject>& j_callback, const base::Optional<OfflineItem>& item) { JNIEnv* env = AttachCurrentThread(); - RunCallbackAndroid( + RunObjectCallbackAndroid( j_callback, item.has_value() ? OfflineItemBridge::CreateOfflineItem(env, item.value()) : nullptr);
diff --git a/components/offline_pages/core/background/scheduler.h b/components/offline_pages/core/background/scheduler.h index 818c216d..b5122b295 100644 --- a/components/offline_pages/core/background/scheduler.h +++ b/components/offline_pages/core/background/scheduler.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_SCHEDULER_H_ #define COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_SCHEDULER_H_ +#include <stdint.h> + #include "components/offline_pages/core/background/device_conditions.h" namespace offline_pages { @@ -38,7 +40,7 @@ // so we can continue processing background download requests. This will // not overwrite existing tasks. virtual void BackupSchedule(const TriggerConditions& trigger_conditions, - long delay_in_seconds) = 0; + int64_t delay_in_seconds) = 0; // Unschedules the currently scheduled task, if any. virtual void Unschedule() = 0;
diff --git a/components/offline_pages/core/background/scheduler_stub.cc b/components/offline_pages/core/background/scheduler_stub.cc index f80c60c..1d855b1 100644 --- a/components/offline_pages/core/background/scheduler_stub.cc +++ b/components/offline_pages/core/background/scheduler_stub.cc
@@ -30,7 +30,7 @@ } void SchedulerStub::BackupSchedule(const TriggerConditions& trigger_conditions, - long delay_in_seconds) { + int64_t delay_in_seconds) { backup_schedule_called_ = true; schedule_delay_ = delay_in_seconds; trigger_conditions_ = trigger_conditions;
diff --git a/components/offline_pages/core/background/scheduler_stub.h b/components/offline_pages/core/background/scheduler_stub.h index fa57d1f..56d2d8ae 100644 --- a/components/offline_pages/core/background/scheduler_stub.h +++ b/components/offline_pages/core/background/scheduler_stub.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_SCHEDULER_STUB_H_ #define COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_SCHEDULER_STUB_H_ +#include <stdint.h> + #include "components/offline_pages/core/background/scheduler.h" namespace offline_pages { @@ -19,7 +21,7 @@ void Schedule(const TriggerConditions& trigger_conditions) override; void BackupSchedule(const TriggerConditions& trigger_conditions, - long delay_in_seconds) override; + int64_t delay_in_seconds) override; // Unschedules the currently scheduled task, if any. void Unschedule() override; @@ -42,7 +44,7 @@ bool backup_schedule_called_; bool unschedule_called_; bool get_current_device_conditions_called_; - long schedule_delay_; + int64_t schedule_delay_; DeviceConditions device_conditions_; TriggerConditions trigger_conditions_; };
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index 339385e..ce07a0c 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -12,6 +12,7 @@ #include <utility> #include <vector> +#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "components/autofill/core/common/form_data.h" @@ -125,17 +126,20 @@ FieldPropertiesFlags::AUTOFILLED)); } -// Helper struct that is used to return results from the parsing function. -struct ParseResult { - const FormFieldData* username_field = nullptr; - const FormFieldData* password_field = nullptr; - const FormFieldData* new_password_field = nullptr; - const FormFieldData* confirmation_password_field = nullptr; +// A helper struct that is used to capture significant fields to be used for +// the construction of a PasswordForm. +struct SignificantFields { + const FormFieldData* username = nullptr; + const FormFieldData* password = nullptr; + const FormFieldData* new_password = nullptr; + const FormFieldData* confirmation_password = nullptr; - bool IsEmpty() { - DCHECK(!confirmation_password_field || new_password_field) + // Returns true if some password field is present. This is the minimal + // requirement for a successful creation of a PasswordForm is present. + bool HasPasswords() const { + DCHECK(!confirmation_password || new_password) << "There is no password to confirm if there is no new password field."; - return password_field == nullptr && new_password_field == nullptr; + return password || new_password; } }; @@ -152,29 +156,29 @@ } // Tries to parse |processed_fields| based on server |predictions|. -std::unique_ptr<ParseResult> ParseUsingPredictions( +std::unique_ptr<SignificantFields> ParseUsingPredictions( const std::vector<ProcessedField>& processed_fields, const FormPredictions& predictions) { - auto result = std::make_unique<ParseResult>(); + auto result = std::make_unique<SignificantFields>(); // Note: The code does not check whether there is at most 1 username, 1 // current password and at most 2 new passwords. It is assumed that server // side predictions are sane. for (const auto& prediction : predictions) { switch (DeriveFromServerFieldType(prediction.second.type)) { case CredentialFieldType::kUsername: - result->username_field = + result->username = FindFieldWithUniqueRendererId(processed_fields, prediction.first); break; case CredentialFieldType::kCurrentPassword: - result->password_field = + result->password = FindFieldWithUniqueRendererId(processed_fields, prediction.first); break; case CredentialFieldType::kNewPassword: - result->new_password_field = + result->new_password = FindFieldWithUniqueRendererId(processed_fields, prediction.first); break; case CredentialFieldType::kConfirmationPassword: - result->confirmation_password_field = + result->confirmation_password = FindFieldWithUniqueRendererId(processed_fields, prediction.first); break; case CredentialFieldType::kNone: @@ -183,10 +187,10 @@ } // If the server suggests there is a confirmation field but no new password, // something went wrong. Sanitize the result. - if (result->confirmation_password_field && !result->new_password_field) - result->confirmation_password_field = nullptr; + if (result->confirmation_password && !result->new_password) + result->confirmation_password = nullptr; - return result->IsEmpty() ? nullptr : std::move(result); + return result->HasPasswords() ? std::move(result) : nullptr; } // Tries to parse |processed_fields| based on autocomplete attributes. @@ -199,30 +203,30 @@ // Are these assumptions violated, or is there no password with an autocomplete // attribute, parsing is unsuccessful. Returns nullptr if parsing is // unsuccessful. -std::unique_ptr<ParseResult> ParseUsingAutocomplete( +std::unique_ptr<SignificantFields> ParseUsingAutocomplete( const std::vector<ProcessedField>& processed_fields) { - auto result = std::make_unique<ParseResult>(); + auto result = std::make_unique<SignificantFields>(); for (const ProcessedField& processed_field : processed_fields) { switch (processed_field.autocomplete_flag) { case AutocompleteFlag::kUsername: - if (processed_field.is_password || result->username_field) + if (processed_field.is_password || result->username) return nullptr; - result->username_field = processed_field.field; + result->username = processed_field.field; break; case AutocompleteFlag::kCurrentPassword: - if (!processed_field.is_password || result->password_field) + if (!processed_field.is_password || result->password) return nullptr; - result->password_field = processed_field.field; + result->password = processed_field.field; break; case AutocompleteFlag::kNewPassword: if (!processed_field.is_password) return nullptr; // The first field with autocomplete=new-password is considered to be - // new_password_field and the second is confirmation_password_field. - if (!result->new_password_field) - result->new_password_field = processed_field.field; - else if (!result->confirmation_password_field) - result->confirmation_password_field = processed_field.field; + // new_password and the second is confirmation_password. + if (!result->new_password) + result->new_password = processed_field.field; + else if (!result->confirmation_password) + result->confirmation_password = processed_field.field; else return nullptr; break; @@ -234,7 +238,7 @@ } } - return result->IsEmpty() ? nullptr : std::move(result); + return result->HasPasswords() ? std::move(result) : nullptr; } // Returns only relevant password fields from |processed_fields|. Namely, if @@ -386,42 +390,70 @@ return focusable_username ? focusable_username : username; } +// A helper to return a |field|'s unique_renderer_id or +// kNotSetFormControlRendererId if |field| is null. +uint32_t ExtractUniqueId(const FormFieldData* field) { + return field ? field->unique_renderer_id : FormFieldData::kNotSetFormControlRendererId; +} + // Tries to find the username and password fields in |processed_fields| based on // the structure (how the fields are ordered). If |mode| is SAVING, only -// consideres non-empty fields. If |username_hint| is not null, it is returned -// as the username. -std::unique_ptr<ParseResult> ParseUsingBaseHeuristics( +// considers non-empty fields. The |found_fields| is both an input and output +// argument: if some password field and the username are already present, the +// the function exits early. If something is missing, the function tries to +// complete it. The result is stored back in |found_fields|. +void ParseUsingBaseHeuristics( const std::vector<ProcessedField>& processed_fields, FormParsingMode mode, - const FormFieldData* username_hint) { - // What is the best interactability among passwords? - Interactability password_max = Interactability::kUnlikely; - for (const ProcessedField& processed_field : processed_fields) { - if (processed_field.is_password) - password_max = std::max(password_max, processed_field.interactability); - } + SignificantFields* found_fields) { + // If there is both the username and the minimal set of fields to build a + // PasswordForm, return early -- no more work to do. + if (found_fields->HasPasswords() && found_fields->username) + return; - // Try to find password elements (current, new, confirmation) among those with - // best interactability. + // Will point to the password included in |found_field| which is first in the + // order of fields in |processed_fields|. std::vector<ProcessedField>::const_iterator first_relevant_password = processed_fields.end(); - std::vector<const FormFieldData*> passwords = GetRelevantPasswords( - processed_fields, mode, password_max, &first_relevant_password); - if (passwords.empty()) - return nullptr; - DCHECK(first_relevant_password != processed_fields.end()); - auto result = std::make_unique<ParseResult>(); - LocateSpecificPasswords(passwords, &result->password_field, - &result->new_password_field, - &result->confirmation_password_field); - if (result->IsEmpty()) - return nullptr; - if (username_hint && - !(mode == FormParsingMode::SAVING && username_hint->value.empty())) { - result->username_field = username_hint; - return result; + if (!found_fields->HasPasswords()) { + // What is the best interactability among passwords? + Interactability password_max = Interactability::kUnlikely; + for (const ProcessedField& processed_field : processed_fields) { + if (processed_field.is_password) + password_max = std::max(password_max, processed_field.interactability); + } + + // Try to find password elements (current, new, confirmation) among those + // with best interactability. + first_relevant_password = processed_fields.end(); + std::vector<const FormFieldData*> passwords = GetRelevantPasswords( + processed_fields, mode, password_max, &first_relevant_password); + if (passwords.empty()) + return; + LocateSpecificPasswords(passwords, &found_fields->password, + &found_fields->new_password, + &found_fields->confirmation_password); + if (!found_fields->HasPasswords()) + return; + } else { + const uint32_t password_ids[] = { + ExtractUniqueId(found_fields->password), + ExtractUniqueId(found_fields->new_password), + ExtractUniqueId(found_fields->confirmation_password)}; + for (auto it = processed_fields.begin(); it != processed_fields.end(); + ++it) { + if (it->is_password && + base::ContainsValue(password_ids, it->field->unique_renderer_id)) { + first_relevant_password = it; + break; + } + } } + DCHECK(first_relevant_password != processed_fields.end()); + + if (found_fields->username) + return; // What is the best interactability among text fields preceding the passwords? Interactability username_max = Interactability::kUnlikely; @@ -431,37 +463,38 @@ username_max = std::max(username_max, it->interactability); } - // If password elements are found then try to find a username. - result->username_field = FindUsernameFieldBaseHeuristics( + found_fields->username = FindUsernameFieldBaseHeuristics( processed_fields, first_relevant_password, mode, username_max); - return result; + return; } -// Set username and password fields from |parse_result| in |password_form|. -void SetFields(const ParseResult& parse_result, PasswordForm* password_form) { +// Set username and password fields in |password_form| based on +// |significant_fields| . +void SetFields(const SignificantFields& significant_fields, + PasswordForm* password_form) { password_form->has_renderer_ids = true; - if (parse_result.username_field) { - password_form->username_element = parse_result.username_field->name; - password_form->username_value = parse_result.username_field->value; + if (significant_fields.username) { + password_form->username_element = significant_fields.username->name; + password_form->username_value = significant_fields.username->value; password_form->username_element_renderer_id = - parse_result.username_field->unique_renderer_id; + significant_fields.username->unique_renderer_id; } - if (parse_result.password_field) { - password_form->password_element = parse_result.password_field->name; - password_form->password_value = parse_result.password_field->value; + if (significant_fields.password) { + password_form->password_element = significant_fields.password->name; + password_form->password_value = significant_fields.password->value; password_form->password_element_renderer_id = - parse_result.password_field->unique_renderer_id; + significant_fields.password->unique_renderer_id; } - if (parse_result.new_password_field) { - password_form->new_password_element = parse_result.new_password_field->name; - password_form->new_password_value = parse_result.new_password_field->value; + if (significant_fields.new_password) { + password_form->new_password_element = significant_fields.new_password->name; + password_form->new_password_value = significant_fields.new_password->value; } - if (parse_result.confirmation_password_field) { + if (significant_fields.confirmation_password) { password_form->confirmation_password_element = - parse_result.confirmation_password_field->name; + significant_fields.confirmation_password->name; } } @@ -543,6 +576,35 @@ return nullptr; } +// Puts together a PasswordForm, the result of the parsing, based on the +// |form_data| description of the form metadata (e.g., action), the already +// parsed information about what are the |significant_fields|, and the list +// |all_possible_passwords| of all non-empty password values and associated +// element names which occurred in the form. +std::unique_ptr<PasswordForm> AssemblePasswordForm( + const autofill::FormData& form_data, + const SignificantFields* significant_fields, + autofill::ValueElementVector all_possible_passwords) { + if (!significant_fields || !significant_fields->HasPasswords()) + return nullptr; + + // Create the PasswordForm and set data not related to specific fields. + auto result = std::make_unique<PasswordForm>(); + result->origin = form_data.origin; + result->signon_realm = form_data.origin.GetOrigin().spec(); + result->action = form_data.action; + result->form_data = form_data; + result->all_possible_passwords = std::move(all_possible_passwords); + result->scheme = PasswordForm::SCHEME_HTML; + result->preferred = false; + result->blacklisted_by_user = false; + result->type = PasswordForm::TYPE_MANUAL; + + // Set data related to specific fields. + SetFields(*significant_fields, result.get()); + return result; +} + } // namespace std::unique_ptr<PasswordForm> ParseFormData( @@ -556,52 +618,39 @@ if (processed_fields.empty()) return nullptr; - // Create parse result and set non-field related information. - auto result = std::make_unique<PasswordForm>(); - result->origin = form_data.origin; - result->signon_realm = form_data.origin.GetOrigin().spec(); - result->action = form_data.action; - result->form_data = form_data; - result->all_possible_passwords = std::move(all_possible_passwords); - result->scheme = PasswordForm::SCHEME_HTML; - result->preferred = false; - result->blacklisted_by_user = false; - result->type = PasswordForm::TYPE_MANUAL; + std::unique_ptr<SignificantFields> significant_fields; - if (form_predictions) { - // Try to parse with server predictions. - auto predictions_parse_result = + // (1) First, try to parse with server predictions. + if (form_predictions) + significant_fields = ParseUsingPredictions(processed_fields, *form_predictions); - if (predictions_parse_result) { - SetFields(*predictions_parse_result, result.get()); - return result; + + // (2) If that failed, try to parse with autocomplete attributes. + if (!significant_fields) + significant_fields = ParseUsingAutocomplete(processed_fields); + + // (3) Now try to fill the gaps. + if (!significant_fields) + significant_fields = std::make_unique<SignificantFields>(); + + // Try to find the username based on the context of the fields. + if (!significant_fields->username && + base::FeatureList::IsEnabled( + password_manager::features::kHtmlBasedUsernameDetector)) { + const FormFieldData* username_field_by_context = FindUsernameInPredictions( + form_data.username_predictions, processed_fields); + if (username_field_by_context && + !(mode == FormParsingMode::SAVING && + username_field_by_context->value.empty())) { + significant_fields->username = username_field_by_context; } } - // Try to parse with autocomplete attributes. - auto autocomplete_parse_result = ParseUsingAutocomplete(processed_fields); - if (autocomplete_parse_result) { - SetFields(*autocomplete_parse_result, result.get()); - return result; - } - - // Try to find the username based on the context of the fields. - const FormFieldData* username_field_by_context = nullptr; - if (base::FeatureList::IsEnabled( - password_manager::features::kHtmlBasedUsernameDetector)) { - username_field_by_context = FindUsernameInPredictions( - form_data.username_predictions, processed_fields); - } - // Try to parse with base heuristic. - auto base_heuristics_parse_result = ParseUsingBaseHeuristics( - processed_fields, mode, username_field_by_context); - if (base_heuristics_parse_result) { - SetFields(*base_heuristics_parse_result, result.get()); - return result; - } + ParseUsingBaseHeuristics(processed_fields, mode, significant_fields.get()); - return nullptr; + return AssemblePasswordForm(form_data, significant_fields.get(), + std::move(all_possible_passwords)); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 8a21bc2..b380b80 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -699,18 +699,6 @@ }, }, { - "Partial autocomplete analysis is not complemented by basic " - "heuristics", - // Username not found because there was a valid autocomplete mark-up - // but it did not include the plain text field. - { - {.form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password"}, - }, - }, - { "Partial autocomplete analysis fails if no passwords are found", // The attribute 'username' is ignored, because there was no password // marked up. @@ -1198,6 +1186,53 @@ }); } +// In some situations, server hints or autocomplete mark-up do not provide the +// username might be omitted. Sometimes this is a truthful signal (there might +// be no username despite the presence of plain text fields), but often this is +// just incomplete data. In the long term, the server hints should be complete +// and also cover cases when the autocomplete mark-up is lacking; at that point, +// the parser should just trust that the signal is truthful. Until then, +// however, the parser is trying to complement the signal with its structural +// heuristics. +TEST(FormParserTest, ComplementingResults) { + CheckTestData({ + { + "Current password from autocomplete analysis, username from basic " + "heuristics", + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, + }, + { + "New and confirmation passwords from server, username from basic " + "heuristics", + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CONFIRMATION_PASSWORD, + .prediction = {.type = autofill::CONFIRMATION_PASSWORD}, + .form_control_type = "password"}, + {.form_control_type = "text"}, + {.role = ElementRole::NEW_PASSWORD, + .prediction = {.type = autofill::NEW_PASSWORD}, + .form_control_type = "password"}, + }, + }, + { + "No password from server still means that serve hints are ignored.", + { + {.prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}, + .form_control_type = "text"}, + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, + }, + }); +} + } // namespace } // namespace password_manager
diff --git a/components/sync/engine/non_blocking_sync_common.h b/components/sync/engine/non_blocking_sync_common.h index 03b3625..d9992e69 100644 --- a/components/sync/engine/non_blocking_sync_common.h +++ b/components/sync/engine/non_blocking_sync_common.h
@@ -23,13 +23,17 @@ CommitRequestData(const CommitRequestData& other); ~CommitRequestData(); + // Fields sent to the sync server. EntityDataPtr entity; - - // Strictly incrementing number for in-progress commits. More information - // about its meaning can be found in comments in the files that make use of - // this struct. - int64_t sequence_number = 0; int64_t base_version = 0; + + // Fields not sent to the sync server. However, they are kept to be sent back + // to the processor in the response. + + // Strictly incrementing number for in-progress commits. + // More information about its meaning can be found in comments in the files + // that make use of this struct. + int64_t sequence_number = 0; std::string specifics_hash; }; @@ -39,6 +43,10 @@ ~CommitResponseData(); std::string id; + // The sync id that was sent in the request. Non-empty only if different from + // |id|. It could be different because the server can change the sync id + // (e.g. for newly created bookmarks), + std::string id_in_request; std::string client_tag_hash; int64_t sequence_number = 0; int64_t response_version = 0;
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc index 081a863..f7485ad8 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
@@ -97,6 +97,12 @@ CommitResponseData response_data; const CommitRequestData& commit_request = commit_requests_[i]; response_data.id = entry_response.id_string(); + if (response_data.id != commit_request.entity->id) { + // Server has changed the sync id in the request. Write back the + // original sync id. This is useful for data types without a notion of + // a client tag such as bookmarks. + response_data.id_in_request = commit_request.entity->id; + } response_data.response_version = entry_response.version(); response_data.client_tag_hash = commit_request.entity->client_tag_hash; response_data.sequence_number = commit_request.sequence_number; @@ -190,20 +196,17 @@ void NonBlockingTypeCommitContribution::AdjustCommitProto( sync_pb::SyncEntity* commit_proto) { - // Initial commits need our help to generate a client ID. if (commit_proto->version() == kUncommittedVersion) { - DCHECK(commit_proto->id_string().empty()) << commit_proto->id_string(); - // TODO(crbug.com/516866): This is incorrect for bookmarks for two reasons: - // 1) Won't be able to match previously committed bookmarks to the ones - // with server ID. - // 2) Recommitting an item in a case of failing to receive commit response - // would result in generating a different client ID, which in turn - // would result in a duplication. - // We should generate client ID on the frontend side instead. - commit_proto->set_id_string(base::GenerateGUID()); commit_proto->set_version(0); - } else { - DCHECK(!commit_proto->id_string().empty()); + // Initial commits need our help to generate a client ID if they don't have + // any. Bookmarks create their own IDs on the frontend side to be able to + // match them after commits. For other data types we generate one here. And + // since bookmarks don't have client tags, their server id should be stable + // across restarts in case of recommitting an item, it doesn't result in + // creating a duplicate. + if (commit_proto->id_string().empty()) { + commit_proto->set_id_string(base::GenerateGUID()); + } } // Encrypt the specifics and hide the title if necessary.
diff --git a/components/sync/protocol/entity_metadata.proto b/components/sync/protocol/entity_metadata.proto index a715c7c0..d96fdbd3 100644 --- a/components/sync/protocol/entity_metadata.proto +++ b/components/sync/protocol/entity_metadata.proto
@@ -43,9 +43,9 @@ // those changes are based. optional int64 server_version = 6 [default = -1]; - // Entity creation and modification timestamps. - // Assigned by the client and synced by the server, though the server usually - // doesn't bother to inspect their values. + // Entity creation and modification timestamps. Assigned by the client and + // synced by the server, though the server usually doesn't bother to inspect + // their values. They are encoded as milliseconds since the Unix epoch. optional int64 creation_time = 7; optional int64 modification_time = 8;
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc index 7dad68f..be35a61d 100644 --- a/components/sync/protocol/proto_enum_conversions.cc +++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -298,13 +298,14 @@ const char* ProtoEnumToString(sync_pb::UserConsentSpecifics::Feature feature) { ASSERT_ENUM_BOUNDS(sync_pb::UserConsentSpecifics, Feature, - FEATURE_UNSPECIFIED, GOOGLE_LOCATION_SERVICE); + FEATURE_UNSPECIFIED, CHROME_UNIFIED_CONSENT); switch (feature) { ENUM_CASE(sync_pb::UserConsentSpecifics, FEATURE_UNSPECIFIED); ENUM_CASE(sync_pb::UserConsentSpecifics, CHROME_SYNC); ENUM_CASE(sync_pb::UserConsentSpecifics, PLAY_STORE); ENUM_CASE(sync_pb::UserConsentSpecifics, BACKUP_AND_RESTORE); ENUM_CASE(sync_pb::UserConsentSpecifics, GOOGLE_LOCATION_SERVICE); + ENUM_CASE(sync_pb::UserConsentSpecifics, CHROME_UNIFIED_CONSENT); } NOTREACHED(); return ""; @@ -347,7 +348,7 @@ const char* ProtoEnumToString( sync_pb::UserEventSpecifics::UserConsent::Feature feature) { ASSERT_ENUM_BOUNDS(sync_pb::UserEventSpecifics::UserConsent, Feature, - FEATURE_UNSPECIFIED, GOOGLE_LOCATION_SERVICE); + FEATURE_UNSPECIFIED, CHROME_UNIFIED_CONSENT); switch (feature) { ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, FEATURE_UNSPECIFIED); ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, CHROME_SYNC); @@ -355,6 +356,7 @@ ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, BACKUP_AND_RESTORE); ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, GOOGLE_LOCATION_SERVICE); + ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, CHROME_UNIFIED_CONSENT); } NOTREACHED(); return "";
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 6221284..b02f0b3 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -967,6 +967,12 @@ VISIT_ENUM(status); } +VISIT_PROTO_FIELDS(const sync_pb::UserConsentTypes::UnifiedConsent& proto) { + VISIT_REP(description_grd_ids); + VISIT(confirmation_grd_id); + VISIT_ENUM(status); +} + VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics& proto) { VISIT(event_time_usec); VISIT(navigation_id);
diff --git a/components/sync/protocol/user_consent_specifics.proto b/components/sync/protocol/user_consent_specifics.proto index 8c94087c..a11be33 100644 --- a/components/sync/protocol/user_consent_specifics.proto +++ b/components/sync/protocol/user_consent_specifics.proto
@@ -16,7 +16,7 @@ import "sync_enums.proto"; import "user_consent_types.proto"; -// Next id: 13 +// Next id: 14 message UserConsentSpecifics { // =========================================================================== // Fields common to all Chrome User Consents. @@ -53,6 +53,8 @@ UserConsentTypes.ArcMetricsAndUsageConsent arc_metrics_and_usage_consent = 11; + + UserConsentTypes.UnifiedConsent unified_consent = 13; } // =========================================================================== @@ -86,6 +88,7 @@ PLAY_STORE = 2; BACKUP_AND_RESTORE = 3; GOOGLE_LOCATION_SERVICE = 4; + CHROME_UNIFIED_CONSENT = 5; } optional Feature feature = 1 [deprecated = true]; // Ids of the strings of the consent text presented to the user.
diff --git a/components/sync/protocol/user_consent_types.proto b/components/sync/protocol/user_consent_types.proto index bc27d64..59d8c74 100644 --- a/components/sync/protocol/user_consent_types.proto +++ b/components/sync/protocol/user_consent_types.proto
@@ -99,4 +99,20 @@ // given or not given/revoked. optional ConsentStatus status = 3; } + + // The unified User Consent for Chrome is determined by the user action on the + // corresponding Chrome Consent dialog. + message UnifiedConsent { + // Ids of the strings of the unified Chrome consent text presented to the + // user. + repeated int32 description_grd_ids = 1; + + // Id of the string of the UI element the user clicked in order to confirm + // and close the unified Chrome consent dialog. + optional int32 confirmation_grd_id = 2; + + // The status of the unified Chrome consent. This specifies whether the + // consent was given or not given/revoked. + optional ConsentStatus status = 3; + } }
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto index 5cd436f..8447a6e2 100644 --- a/components/sync/protocol/user_event_specifics.proto +++ b/components/sync/protocol/user_event_specifics.proto
@@ -90,7 +90,7 @@ } // User consented to the usage of a feature or denied/revoked a consent. - // Next id: 13 + // Next id: 14 message UserConsent { // ========================================================================= // Fields common to all Chrome User Consents. @@ -127,6 +127,8 @@ UserConsentTypes.ArcMetricsAndUsageConsent arc_metrics_and_usage_consent = 11; + + UserConsentTypes.UnifiedConsent unified_consent = 13; } // ========================================================================= @@ -158,6 +160,7 @@ PLAY_STORE = 2; BACKUP_AND_RESTORE = 3; GOOGLE_LOCATION_SERVICE = 4; + CHROME_UNIFIED_CONSENT = 5; } optional Feature feature = 1 [deprecated = true]; // Ids of the strings of the consent text presented to the user.
diff --git a/components/sync_bookmarks/BUILD.gn b/components/sync_bookmarks/BUILD.gn index 4d9d1a2..22b3775 100644 --- a/components/sync_bookmarks/BUILD.gn +++ b/components/sync_bookmarks/BUILD.gn
@@ -39,6 +39,7 @@ sources = [ "bookmark_data_type_controller_unittest.cc", + "bookmark_model_observer_impl_unittest.cc", "bookmark_model_type_processor_unittest.cc", "synced_bookmark_tracker_unittest.cc", ]
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl.cc b/components/sync_bookmarks/bookmark_model_observer_impl.cc index a0980d3..4250ef6 100644 --- a/components/sync_bookmarks/bookmark_model_observer_impl.cc +++ b/components/sync_bookmarks/bookmark_model_observer_impl.cc
@@ -4,6 +4,17 @@ #include "components/sync_bookmarks/bookmark_model_observer_impl.h" +#include <utility> + +#include "base/guid.h" +#include "base/strings/utf_string_conversions.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/browser/bookmark_node.h" +#include "components/sync/base/hash_util.h" +#include "components/sync/base/unique_position.h" +#include "components/sync/engine/non_blocking_sync_common.h" +#include "components/sync_bookmarks/synced_bookmark_tracker.h" + namespace sync_bookmarks { BookmarkModelObserverImpl::BookmarkModelObserverImpl( @@ -40,7 +51,104 @@ bookmarks::BookmarkModel* model, const bookmarks::BookmarkNode* parent, int index) { - NOTIMPLEMENTED(); + const bookmarks::BookmarkNode* node = parent->GetChild(index); + // TODO(crbug.com/516866): continue only if + // model->client()->CanSyncNode(node). + + const SyncedBookmarkTracker::Entity* parent_entity = + bookmark_tracker_->GetEntityForBookmarkNode(parent); + if (!parent_entity) { + DLOG(WARNING) << "Bookmark parent lookup failed"; + return; + } + // Similar to the diectory implementation here: + // https://cs.chromium.org/chromium/src/components/sync/syncable/mutable_entry.cc?l=237&gsn=CreateEntryKernel + // Assign a temp server id for the entity. Will be overriden by the actual + // server id upon receiving commit response. + const std::string sync_id = base::GenerateGUID(); + const int64_t server_version = syncer::kUncommittedVersion; + const base::Time creation_time = base::Time::Now(); + const sync_pb::UniquePosition unique_position = + ComputePosition(*parent, index, sync_id).ToProto(); + + sync_pb::EntitySpecifics specifics; + sync_pb::BookmarkSpecifics* bm_specifics = specifics.mutable_bookmark(); + bm_specifics->set_url(node->url().spec()); + // TODO(crbug.com/516866): Set the favicon. + bm_specifics->set_title(base::UTF16ToUTF8(node->GetTitle())); + bm_specifics->set_creation_time_us( + node->date_added().ToDeltaSinceWindowsEpoch().InMicroseconds()); + + bm_specifics->set_icon_url(node->icon_url() ? node->icon_url()->spec() + : std::string()); + // TODO(crbug.com/516866): update the implementation to be similar to the + // directory implementation + // https://cs.chromium.org/chromium/src/components/sync_bookmarks/bookmark_change_processor.cc?l=882&rcl=f38001d936d8b2abb5743e85cbc88c72746ae3d2 + if (node->GetMetaInfoMap()) { + for (const std::pair<std::string, std::string>& pair : + *node->GetMetaInfoMap()) { + sync_pb::MetaInfo* meta_info = bm_specifics->add_meta_info(); + meta_info->set_key(pair.first); + meta_info->set_value(pair.second); + } + } + bookmark_tracker_->Add(sync_id, node, server_version, creation_time, + unique_position, specifics); + // Mark the entity that it needs to be committed. + bookmark_tracker_->IncrementSequenceNumber(sync_id); + nudge_for_commit_closure_.Run(); +} + +syncer::UniquePosition BookmarkModelObserverImpl::ComputePosition( + const bookmarks::BookmarkNode& parent, + int index, + const std::string& sync_id) { + const std::string& suffix = syncer::GenerateSyncableBookmarkHash( + bookmark_tracker_->model_type_state().cache_guid(), sync_id); + DCHECK_NE(0, parent.child_count()); + + if (parent.child_count() == 1) { + // No siblings, the parent has no other children. + return syncer::UniquePosition::InitialPosition(suffix); + } + if (index == 0) { + const bookmarks::BookmarkNode* successor_node = parent.GetChild(1); + const SyncedBookmarkTracker::Entity* successor_entity = + bookmark_tracker_->GetEntityForBookmarkNode(successor_node); + DCHECK(successor_entity); + // Insert at the beginning. + return syncer::UniquePosition::Before( + syncer::UniquePosition::FromProto( + successor_entity->metadata()->unique_position()), + suffix); + } + if (index == parent.child_count() - 1) { + // Insert at the end. + const bookmarks::BookmarkNode* predecessor_node = + parent.GetChild(index - 1); + const SyncedBookmarkTracker::Entity* predecessor_entity = + bookmark_tracker_->GetEntityForBookmarkNode(predecessor_node); + DCHECK(predecessor_entity); + return syncer::UniquePosition::After( + syncer::UniquePosition::FromProto( + predecessor_entity->metadata()->unique_position()), + suffix); + } + // Insert in the middle. + const bookmarks::BookmarkNode* successor_node = parent.GetChild(index + 1); + const SyncedBookmarkTracker::Entity* successor_entity = + bookmark_tracker_->GetEntityForBookmarkNode(successor_node); + DCHECK(successor_entity); + const bookmarks::BookmarkNode* predecessor_node = parent.GetChild(index - 1); + const SyncedBookmarkTracker::Entity* predecessor_entity = + bookmark_tracker_->GetEntityForBookmarkNode(predecessor_node); + DCHECK(predecessor_entity); + return syncer::UniquePosition::Between( + syncer::UniquePosition::FromProto( + predecessor_entity->metadata()->unique_position()), + syncer::UniquePosition::FromProto( + successor_entity->metadata()->unique_position()), + suffix); } void BookmarkModelObserverImpl::BookmarkNodeRemoved(
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl.h b/components/sync_bookmarks/bookmark_model_observer_impl.h index 87777ad..2d81d30 100644 --- a/components/sync_bookmarks/bookmark_model_observer_impl.h +++ b/components/sync_bookmarks/bookmark_model_observer_impl.h
@@ -6,11 +6,16 @@ #define COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_MODEL_OBSERVER_IMPL_H_ #include <set> +#include <string> #include "base/callback.h" #include "components/bookmarks/browser/bookmark_model_observer.h" #include "url/gurl.h" +namespace syncer { +class UniquePosition; +} + namespace sync_bookmarks { class SyncedBookmarkTracker; @@ -54,6 +59,10 @@ const bookmarks::BookmarkNode* node) override; private: + syncer::UniquePosition ComputePosition(const bookmarks::BookmarkNode& parent, + int index, + const std::string& sync_id); + // Points to the tracker owned by the processor. It keeps the mapping between // bookmark nodes and corresponding sync server entities. SyncedBookmarkTracker* const bookmark_tracker_;
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc b/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc new file mode 100644 index 0000000..e3a9492 --- /dev/null +++ b/components/sync_bookmarks/bookmark_model_observer_impl_unittest.cc
@@ -0,0 +1,149 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync_bookmarks/bookmark_model_observer_impl.h" + +#include <memory> +#include <vector> + +#include "base/strings/utf_string_conversions.h" +#include "base/test/mock_callback.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/test/test_bookmark_client.h" +#include "components/sync/base/time.h" +#include "components/sync/base/unique_position.h" +#include "components/sync_bookmarks/synced_bookmark_tracker.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_bookmarks { + +namespace { + +using testing::Eq; +using testing::NiceMock; +using testing::NotNull; + +const char kBookmarkBarId[] = "bookmark_bar_id"; +const char kBookmarkBarTag[] = "bookmark_bar"; + +class BookmarkModelObserverImplTest : public testing::Test { + public: + BookmarkModelObserverImplTest() + : bookmark_model_(bookmarks::TestBookmarkClient::CreateModel()), + bookmark_tracker_(std::vector<NodeMetadataPair>(), + std::make_unique<sync_pb::ModelTypeState>()), + observer_(nudge_for_commit_closure_.Get(), &bookmark_tracker_) { + bookmark_model_->AddObserver(&observer_); + sync_pb::EntitySpecifics specifics; + specifics.mutable_bookmark()->set_title(kBookmarkBarTag); + bookmark_tracker_.Add( + /*sync_id=*/kBookmarkBarId, + /*bookmark_node=*/bookmark_model()->bookmark_bar_node(), + /*server_version=*/0, /*creation_time=*/base::Time::Now(), + syncer::UniquePosition::InitialPosition( + syncer::UniquePosition::RandomSuffix()) + .ToProto(), + specifics); + } + + bookmarks::BookmarkModel* bookmark_model() { return bookmark_model_.get(); } + SyncedBookmarkTracker* bookmark_tracker() { return &bookmark_tracker_; } + BookmarkModelObserverImpl* observer() { return &observer_; } + base::MockCallback<base::RepeatingClosure>* nudge_for_commit_closure() { + return &nudge_for_commit_closure_; + } + + private: + std::unique_ptr<bookmarks::BookmarkModel> bookmark_model_; + NiceMock<base::MockCallback<base::RepeatingClosure>> + nudge_for_commit_closure_; + SyncedBookmarkTracker bookmark_tracker_; + BookmarkModelObserverImpl observer_; +}; + +TEST_F(BookmarkModelObserverImplTest, + BookmarkAddedShouldPutInTheTrackerAndNudgeForCommit) { + const std::string kTitle = "title"; + const std::string kUrl = "http://www.url.com"; + const size_t kMaxEntries = 10; + + EXPECT_CALL(*nudge_for_commit_closure(), Run()); + const bookmarks::BookmarkNode* bookmark_bar_node = + bookmark_model()->bookmark_bar_node(); + const bookmarks::BookmarkNode* bookmark_node = bookmark_model()->AddURL( + /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16(kTitle), + GURL(kUrl)); + + EXPECT_THAT(bookmark_tracker()->TrackedEntitiesCountForTest(), 2U); + + std::vector<const SyncedBookmarkTracker::Entity*> local_changes = + bookmark_tracker()->GetEntitiesWithLocalChanges(kMaxEntries); + ASSERT_THAT(local_changes.size(), 1U); + EXPECT_THAT(local_changes[0]->bookmark_node(), Eq(bookmark_node)); +} + +TEST_F(BookmarkModelObserverImplTest, ShouldPositionSiblings) { + const std::string kTitle = "title"; + const std::string kUrl = "http://www.url.com"; + + // Build this structure: + // bookmark_bar + // |- node1 + // |- node2 + // Expectation: + // p1 < p2 + + const bookmarks::BookmarkNode* bookmark_bar_node = + bookmark_model()->bookmark_bar_node(); + const bookmarks::BookmarkNode* bookmark_node1 = bookmark_model()->AddURL( + /*parent=*/bookmark_bar_node, /*index=*/0, base::UTF8ToUTF16(kTitle), + GURL(kUrl)); + + const bookmarks::BookmarkNode* bookmark_node2 = bookmark_model()->AddURL( + /*parent=*/bookmark_bar_node, /*index=*/1, base::UTF8ToUTF16(kTitle), + GURL(kUrl)); + + ASSERT_THAT(bookmark_tracker()->TrackedEntitiesCountForTest(), Eq(3U)); + const SyncedBookmarkTracker::Entity* entity1 = + bookmark_tracker()->GetEntityForBookmarkNode(bookmark_node1); + ASSERT_THAT(entity1, NotNull()); + syncer::UniquePosition p1 = + syncer::UniquePosition::FromProto(entity1->metadata()->unique_position()); + + const SyncedBookmarkTracker::Entity* entity2 = + bookmark_tracker()->GetEntityForBookmarkNode(bookmark_node2); + ASSERT_THAT(entity2, NotNull()); + syncer::UniquePosition p2 = + syncer::UniquePosition::FromProto(entity2->metadata()->unique_position()); + EXPECT_TRUE(p1.LessThan(p2)); + + // Now insert node3 at index 1 to build this structure: + // bookmark_bar + // |- node1 + // |- node3 + // |- node2 + // Expectation: + // p1 < p2 (still holds) + // p1 < p3 + // p3 < p2 + + const bookmarks::BookmarkNode* bookmark_node3 = bookmark_model()->AddURL( + /*parent=*/bookmark_bar_node, /*index=*/1, base::UTF8ToUTF16(kTitle), + GURL(kUrl)); + EXPECT_THAT(bookmark_tracker()->TrackedEntitiesCountForTest(), Eq(4U)); + + const SyncedBookmarkTracker::Entity* entity3 = + bookmark_tracker()->GetEntityForBookmarkNode(bookmark_node3); + ASSERT_THAT(entity3, NotNull()); + syncer::UniquePosition p3 = + syncer::UniquePosition::FromProto(entity3->metadata()->unique_position()); + EXPECT_TRUE(p1.LessThan(p2)); + EXPECT_TRUE(p1.LessThan(p3)); + EXPECT_TRUE(p3.LessThan(p2)); +} + +} // namespace + +} // namespace sync_bookmarks
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc index 2a6b799..a3e4578 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -10,8 +10,10 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/browser/bookmark_node.h" #include "components/bookmarks/browser/bookmark_utils.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" #include "components/sync/engine/model_type_processor_proxy.h" #include "components/sync/model/data_type_activation_request.h" @@ -115,19 +117,46 @@ return true; } +sync_pb::EntitySpecifics SpecificsFromBookmarkNode( + const bookmarks::BookmarkNode* node) { + sync_pb::EntitySpecifics specifics; + sync_pb::BookmarkSpecifics* bm_specifics = specifics.mutable_bookmark(); + bm_specifics->set_url(node->url().spec()); + // TODO(crbug.com/516866): Set the favicon. + bm_specifics->set_title(base::UTF16ToUTF8(node->GetTitle())); + bm_specifics->set_creation_time_us( + node->date_added().ToDeltaSinceWindowsEpoch().InMicroseconds()); + + bm_specifics->set_icon_url(node->icon_url() ? node->icon_url()->spec() + : std::string()); + + for (const std::pair<std::string, std::string>& pair : + *node->GetMetaInfoMap()) { + sync_pb::MetaInfo* meta_info = bm_specifics->add_meta_info(); + meta_info->set_key(pair.first); + meta_info->set_value(pair.second); + } + return specifics; +} + class ScopedRemoteUpdateBookmarks { public: - // |bookmark_model| and |bookmark_undo_service| must not be null and must - // outlive this object. + // |bookmark_model|, |bookmark_undo_service| and |observer| must not be null + // and must outlive this object. ScopedRemoteUpdateBookmarks(bookmarks::BookmarkModel* bookmark_model, - BookmarkUndoService* bookmark_undo_service) - : bookmark_model_(bookmark_model), suspend_undo_(bookmark_undo_service) { + BookmarkUndoService* bookmark_undo_service, + bookmarks::BookmarkModelObserver* observer) + : bookmark_model_(bookmark_model), + suspend_undo_(bookmark_undo_service), + observer_(observer) { // Notify UI intensive observers of BookmarkModel that we are about to make // potentially significant changes to it, so the updates may be batched. For // example, on Mac, the bookmarks bar displays animations when bookmark // items are added or deleted. DCHECK(bookmark_model_); bookmark_model_->BeginExtensiveChanges(); + // Shouldn't be notified upon changes due to sync. + bookmark_model_->RemoveObserver(observer_); } ~ScopedRemoteUpdateBookmarks() { @@ -136,6 +165,7 @@ // one described in https://crbug.com/281562, where old and new items on the // bookmarks bar would overlap. bookmark_model_->EndExtensiveChanges(); + bookmark_model_->AddObserver(observer_); } private: @@ -144,6 +174,8 @@ // Changes made to the bookmark model due to sync should not be undoable. ScopedSuspendBookmarkUndo suspend_undo_; + bookmarks::BookmarkModelObserver* const observer_; + DISALLOW_COPY_AND_ASSIGN(ScopedRemoteUpdateBookmarks); }; } // namespace @@ -152,7 +184,11 @@ BookmarkUndoService* bookmark_undo_service) : bookmark_undo_service_(bookmark_undo_service), weak_ptr_factory_(this) {} -BookmarkModelTypeProcessor::~BookmarkModelTypeProcessor() = default; +BookmarkModelTypeProcessor::~BookmarkModelTypeProcessor() { + if (bookmark_model_ && bookmark_model_observer_) { + bookmark_model_->RemoveObserver(bookmark_model_observer_.get()); + } +} void BookmarkModelTypeProcessor::ConnectSync( std::unique_ptr<syncer::CommitQueue> worker) { @@ -177,35 +213,49 @@ size_t max_entries, const GetLocalChangesCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - syncer::CommitRequestDataList local_changes; + std::vector<syncer::CommitRequestData> local_changes = + BuildCommitRequestsForLocalChanges(max_entries); callback.Run(std::move(local_changes)); - NOTIMPLEMENTED(); } void BookmarkModelTypeProcessor::OnCommitCompleted( const sync_pb::ModelTypeState& type_state, const syncer::CommitResponseDataList& response_list) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + + for (const syncer::CommitResponseData& response : response_list) { + // In order to save space, |response.id_in_request| is written when it's + // different from |response.id|. If it's empty, then there was no id change + // during the commit, and |response.id| carries both the old and new ids. + const std::string& old_sync_id = + response.id_in_request.empty() ? response.id : response.id_in_request; + bookmark_tracker_->UpdateUponCommitResponse(old_sync_id, response.id, + response.sequence_number, + response.response_version); + } + bookmark_tracker_->set_model_type_state( + std::make_unique<sync_pb::ModelTypeState>(type_state)); + schedule_save_closure_.Run(); } void BookmarkModelTypeProcessor::OnUpdateReceived( const sync_pb::ModelTypeState& model_type_state, const syncer::UpdateResponseDataList& updates) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!model_type_state.cache_guid().empty()); + DCHECK_EQ(model_type_state.cache_guid(), cache_guid_); + DCHECK(model_type_state.initial_sync_done()); if (!bookmark_tracker_) { // TODO(crbug.com/516866): Implement the merge logic. - auto state = std::make_unique<sync_pb::ModelTypeState>(model_type_state); - state->set_cache_guid(cache_guid_); - std::vector<NodeMetadataPair> nodes_metadata; - bookmark_tracker_ = std::make_unique<SyncedBookmarkTracker>( - std::move(nodes_metadata), std::move(state)); + StartTrackingMetadata( + std::vector<NodeMetadataPair>(), + std::make_unique<sync_pb::ModelTypeState>(model_type_state)); } // TODO(crbug.com/516866): Set the model type state. - ScopedRemoteUpdateBookmarks update_bookmarks(bookmark_model_, - bookmark_undo_service_); + ScopedRemoteUpdateBookmarks update_bookmarks( + bookmark_model_, bookmark_undo_service_, bookmark_model_observer_.get()); for (const syncer::UpdateResponseData* update : ReorderUpdates(updates)) { const syncer::EntityData& update_entity = update->entity.value(); @@ -454,10 +504,12 @@ } std::string BookmarkModelTypeProcessor::EncodeSyncMetadata() const { - sync_pb::BookmarkModelMetadata model_metadata = - bookmark_tracker_->BuildBookmarkModelMetadata(); std::string metadata_str; - model_metadata.SerializeToString(&metadata_str); + if (bookmark_tracker_) { + sync_pb::BookmarkModelMetadata model_metadata = + bookmark_tracker_->BuildBookmarkModelMetadata(); + model_metadata.SerializeToString(&metadata_str); + } return metadata_str; } @@ -513,14 +565,8 @@ // TODO(crbug.com/516866): Handle local nodes that don't have a // corresponding // metadata. - bookmark_tracker_ = std::make_unique<SyncedBookmarkTracker>( - std::move(nodes_metadata), std::move(model_type_state)); - - bookmark_model_observer_ = std::make_unique<BookmarkModelObserverImpl>( - base::BindRepeating(&BookmarkModelTypeProcessor::NudgeForCommitIfNeeded, - base::Unretained(this)), - bookmark_tracker_.get()); - // TODO(crbug.com/516866): Register the observer with the bookmark model. + StartTrackingMetadata(std::move(nodes_metadata), + std::move(model_type_state)); } else if (!model_metadata.bookmarks_metadata().empty()) { DLOG(ERROR) << "Persisted Metadata not empty while initial sync is not done."; @@ -606,6 +652,76 @@ } } +std::vector<syncer::CommitRequestData> +BookmarkModelTypeProcessor::BuildCommitRequestsForLocalChanges( + size_t max_entries) { + DCHECK(bookmark_tracker_); + const std::vector<const SyncedBookmarkTracker::Entity*> + entities_with_local_changes = + bookmark_tracker_->GetEntitiesWithLocalChanges(max_entries); + DCHECK_LE(entities_with_local_changes.size(), max_entries); + + std::vector<syncer::CommitRequestData> commit_requests; + for (const SyncedBookmarkTracker::Entity* entity : + entities_with_local_changes) { + DCHECK(entity->IsUnsynced()); + const sync_pb::EntityMetadata* metadata = entity->metadata(); + + syncer::CommitRequestData request; + syncer::EntityData data; + data.id = metadata->server_id(); + data.creation_time = syncer::ProtoTimeToTime(metadata->creation_time()); + data.modification_time = + syncer::ProtoTimeToTime(metadata->modification_time()); + if (!metadata->is_deleted()) { + const bookmarks::BookmarkNode* node = entity->bookmark_node(); + DCHECK(node); + const bookmarks::BookmarkNode* parent = node->parent(); + const SyncedBookmarkTracker::Entity* parent_entity = + bookmark_tracker_->GetEntityForBookmarkNode(parent); + DCHECK(parent_entity); + data.parent_id = parent_entity->metadata()->server_id(); + // TODO(crbug.com/516866): Double check that custom passphrase works well + // with this implementation, because: + // 1. NonBlockingTypeCommitContribution::AdjustCommitProto() clears the + // title out. + // 2. Bookmarks (maybe ancient legacy bookmarks only?) use/used |name| to + // encode the title. + data.is_folder = node->is_folder(); + // TODO(crbug.com/516866): Set the non_unique_name similar to directory + // implementation. + // https://cs.chromium.org/chromium/src/components/sync/syncable/write_node.cc?l=41&rcl=1675007db1e0eb03417e81442688bb11cd181f58 + data.non_unique_name = base::UTF16ToUTF8(node->GetTitle()); + data.unique_position = parent_entity->metadata()->unique_position(); + // In case of deletion, make an EntityData with empty specifics to + // indicate deletion. + data.specifics = SpecificsFromBookmarkNode(node); + } + request.entity = data.PassToPtr(); + request.sequence_number = metadata->sequence_number(); + request.base_version = metadata->server_version(); + // Specifics hash has been computed in the tracker when this entity has been + // added/updated. + request.specifics_hash = metadata->specifics_hash(); + + commit_requests.push_back(std::move(request)); + } + return commit_requests; +} + +void BookmarkModelTypeProcessor::StartTrackingMetadata( + std::vector<NodeMetadataPair> nodes_metadata, + std::unique_ptr<sync_pb::ModelTypeState> model_type_state) { + bookmark_tracker_ = std::make_unique<SyncedBookmarkTracker>( + std::move(nodes_metadata), std::move(model_type_state)); + + bookmark_model_observer_ = std::make_unique<BookmarkModelObserverImpl>( + base::BindRepeating(&BookmarkModelTypeProcessor::NudgeForCommitIfNeeded, + base::Unretained(this)), + bookmark_tracker_.get()); + bookmark_model_->AddObserver(bookmark_model_observer_.get()); +} + void BookmarkModelTypeProcessor::GetAllNodesForDebugging( AllNodesCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.h b/components/sync_bookmarks/bookmark_model_type_processor.h index 4ea5c4a..420f653 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.h +++ b/components/sync_bookmarks/bookmark_model_type_processor.h
@@ -135,6 +135,16 @@ // entities. void NudgeForCommitIfNeeded(); + // Builds the commit requests list. + std::vector<syncer::CommitRequestData> BuildCommitRequestsForLocalChanges( + size_t max_entries); + + // Instantiates the required objects to track metadata and starts observing + // changes from the bookmark model. + void StartTrackingMetadata( + std::vector<NodeMetadataPair> nodes_metadata, + std::unique_ptr<sync_pb::ModelTypeState> model_type_state); + // Stores the start callback in between OnSyncStarting() and // DecodeSyncMetadata(). StartCallback start_callback_;
diff --git a/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc b/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc index 572462e..1b52f13 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc
@@ -8,9 +8,11 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/test/test_bookmark_client.h" #include "components/sync/driver/fake_sync_client.h" +#include "components/sync/model/data_type_activation_request.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -29,6 +31,7 @@ const char kBookmarkBarTag[] = "bookmark_bar"; const char kBookmarkBarId[] = "bookmark_bar_id"; const char kBookmarksRootId[] = "32904_google_chrome_bookmarks"; +const char kCacheGuid[] = "generated_id"; struct BookmarkInfo { std::string server_id; @@ -60,6 +63,13 @@ return response_data; } +sync_pb::ModelTypeState CreateDummyModelTypeState() { + sync_pb::ModelTypeState model_type_state; + model_type_state.set_cache_guid(kCacheGuid); + model_type_state.set_initial_sync_done(true); + return model_type_state; +} + void AssertState(const BookmarkModelTypeProcessor* processor, const std::vector<BookmarkInfo>& bookmarks) { const SyncedBookmarkTracker* tracker = processor->GetTrackerForTest(); @@ -94,7 +104,7 @@ for (BookmarkInfo bookmark : bookmarks) { updates.push_back(CreateUpdateData(bookmark)); } - processor->OnUpdateReceived(sync_pb::ModelTypeState(), updates); + processor->OnUpdateReceived(CreateDummyModelTypeState(), updates); AssertState(processor, bookmarks); } @@ -134,8 +144,14 @@ : bookmark_model_(bookmarks::TestBookmarkClient::CreateModel()), sync_client_(bookmark_model_.get()), processor_(sync_client()->GetBookmarkUndoServiceIfExists()) { + // TODO(crbug.com/516866): This class assumes model is loaded and sync has + // started before running tests. We should test other variations (i.e. model + // isn't loaded yet and/or sync didn't start yet). processor_.DecodeSyncMetadata(std::string(), schedule_save_closure_.Get(), bookmark_model_.get()); + syncer::DataTypeActivationRequest request; + request.cache_guid = kCacheGuid; + processor_.OnSyncStarting(request, base::DoNothing()); } TestSyncClient* sync_client() { return &sync_client_; } @@ -146,9 +162,10 @@ } private: + base::test::ScopedTaskEnvironment task_environment_; + NiceMock<base::MockCallback<base::RepeatingClosure>> schedule_save_closure_; std::unique_ptr<bookmarks::BookmarkModel> bookmark_model_; TestSyncClient sync_client_; - NiceMock<base::MockCallback<base::RepeatingClosure>> schedule_save_closure_; BookmarkModelTypeProcessor processor_; }; @@ -205,7 +222,7 @@ // Save will be scheduled in the model upon model change. No save should be // scheduled from the processor. EXPECT_CALL(*schedule_save_closure(), Run()).Times(0); - processor()->OnUpdateReceived(sync_pb::ModelTypeState(), updates); + processor()->OnUpdateReceived(CreateDummyModelTypeState(), updates); ASSERT_THAT(bookmarkbar->GetChild(0), NotNull()); EXPECT_THAT(bookmarkbar->GetChild(0)->GetTitle(), Eq(ASCIIToUTF16(kTitle))); @@ -241,7 +258,7 @@ // Save will be scheduled in the model upon model change. No save should be // scheduled from the processor. EXPECT_CALL(*schedule_save_closure(), Run()).Times(0); - processor()->OnUpdateReceived(sync_pb::ModelTypeState(), updates); + processor()->OnUpdateReceived(CreateDummyModelTypeState(), updates); // Check if the bookmark has been updated properly. EXPECT_THAT(bookmark_bar->GetChild(0), Eq(bookmark_node)); @@ -273,7 +290,7 @@ updates[0].response_version++; EXPECT_CALL(*schedule_save_closure(), Run()); - processor()->OnUpdateReceived(sync_pb::ModelTypeState(), updates); + processor()->OnUpdateReceived(CreateDummyModelTypeState(), updates); } TEST_F(BookmarkModelTypeProcessorTest, ShouldUpdateModelAfterRemoteDelete) { @@ -330,11 +347,10 @@ updates.push_back(CreateTombstone(kTitle1Id)); updates.push_back(CreateTombstone(kFolder1Id)); - const sync_pb::ModelTypeState model_type_state; // Save will be scheduled in the model upon model change. No save should be // scheduled from the processor. EXPECT_CALL(*schedule_save_closure(), Run()).Times(0); - processor()->OnUpdateReceived(model_type_state, updates); + processor()->OnUpdateReceived(CreateDummyModelTypeState(), updates); // The structure should be // bookmark_bar @@ -406,8 +422,7 @@ syncer::UpdateResponseDataList updates; updates.push_back(CreateTombstone(kNodeId1)); - const sync_pb::ModelTypeState model_type_state; - processor()->OnUpdateReceived(model_type_state, updates); + processor()->OnUpdateReceived(CreateDummyModelTypeState(), updates); metadata_str = processor()->EncodeSyncMetadata(); model_metadata.ParseFromString(metadata_str);
diff --git a/components/sync_bookmarks/bookmark_sync_service.cc b/components/sync_bookmarks/bookmark_sync_service.cc index e34166ca..3ef8eac 100644 --- a/components/sync_bookmarks/bookmark_sync_service.cc +++ b/components/sync_bookmarks/bookmark_sync_service.cc
@@ -22,7 +22,9 @@ BookmarkSyncService::~BookmarkSyncService() {} -void BookmarkSyncService::Shutdown() {} +void BookmarkSyncService::Shutdown() { + bookmark_model_type_processor_.reset(); +} std::string BookmarkSyncService::EncodeBookmarkSyncMetadata() { if (!bookmark_model_type_processor_) {
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.cc b/components/sync_bookmarks/synced_bookmark_tracker.cc index 8d89064..974e0cf4 100644 --- a/components/sync_bookmarks/synced_bookmark_tracker.cc +++ b/components/sync_bookmarks/synced_bookmark_tracker.cc
@@ -43,6 +43,9 @@ bool SyncedBookmarkTracker::Entity::MatchesData( const syncer::EntityData& data) const { + // TODO(crbug.com/516866): Check parent id and unique position. + // TODO(crbug.com/516866): Compare the actual specifics instead of the + // specifics hash. if (metadata_->is_deleted() || data.is_deleted()) { // In case of deletion, no need to check the specifics. return metadata_->is_deleted() == data.is_deleted(); @@ -63,10 +66,13 @@ std::vector<NodeMetadataPair> nodes_metadata, std::unique_ptr<sync_pb::ModelTypeState> model_type_state) : model_type_state_(std::move(model_type_state)) { + DCHECK(model_type_state_); for (NodeMetadataPair& node_metadata : nodes_metadata) { const std::string& sync_id = node_metadata.second->server_id(); - sync_id_to_entities_map_[sync_id] = std::make_unique<Entity>( - node_metadata.first, std::move(node_metadata.second)); + auto entity = std::make_unique<Entity>(node_metadata.first, + std::move(node_metadata.second)); + bookmark_node_to_entities_map_[node_metadata.first] = entity.get(); + sync_id_to_entities_map_[sync_id] = std::move(entity); } } @@ -78,6 +84,13 @@ return it != sync_id_to_entities_map_.end() ? it->second.get() : nullptr; } +const SyncedBookmarkTracker::Entity* +SyncedBookmarkTracker::GetEntityForBookmarkNode( + const bookmarks::BookmarkNode* node) const { + auto it = bookmark_node_to_entities_map_.find(node); + return it != bookmark_node_to_entities_map_.end() ? it->second : nullptr; +} + void SyncedBookmarkTracker::Add(const std::string& sync_id, const bookmarks::BookmarkNode* bookmark_node, int64_t server_version, @@ -90,12 +103,14 @@ metadata->set_server_id(sync_id); metadata->set_server_version(server_version); metadata->set_creation_time(syncer::TimeToProtoTime(creation_time)); + metadata->set_modification_time(syncer::TimeToProtoTime(creation_time)); metadata->set_sequence_number(0); metadata->set_acked_sequence_number(0); metadata->mutable_unique_position()->CopyFrom(unique_position); HashSpecifics(specifics, metadata->mutable_specifics_hash()); - sync_id_to_entities_map_[sync_id] = - std::make_unique<Entity>(bookmark_node, std::move(metadata)); + auto entity = std::make_unique<Entity>(bookmark_node, std::move(metadata)); + bookmark_node_to_entities_map_[bookmark_node] = entity.get(); + sync_id_to_entities_map_[sync_id] = std::move(entity); } void SyncedBookmarkTracker::Update(const std::string& sync_id, @@ -114,6 +129,9 @@ } void SyncedBookmarkTracker::Remove(const std::string& sync_id) { + const Entity* entity = GetEntityForSyncId(sync_id); + DCHECK(entity); + bookmark_node_to_entities_map_.erase(entity->bookmark_node()); sync_id_to_entities_map_.erase(sync_id); } @@ -155,6 +173,49 @@ return false; } +std::vector<const SyncedBookmarkTracker::Entity*> +SyncedBookmarkTracker::GetEntitiesWithLocalChanges(size_t max_entries) const { + // TODO(crbug.com/516866): Reorder local changes to e.g. parent creation + // before child creation and the otherway around for deletions. + std::vector<const SyncedBookmarkTracker::Entity*> entities_with_local_changes; + for (const std::pair<const std::string, std::unique_ptr<Entity>>& pair : + sync_id_to_entities_map_) { + Entity* entity = pair.second.get(); + if (entity->IsUnsynced()) { + entities_with_local_changes.push_back(entity); + } + } + return entities_with_local_changes; +} + +void SyncedBookmarkTracker::UpdateUponCommitResponse( + const std::string& old_id, + const std::string& new_id, + int64_t acked_sequence_number, + int64_t server_version) { + // TODO(crbug.com/516866): Update specifics if we decide to keep it. + auto it = sync_id_to_entities_map_.find(old_id); + Entity* entity = + it != sync_id_to_entities_map_.end() ? it->second.get() : nullptr; + if (it == sync_id_to_entities_map_.end()) { + DLOG(WARNING) << "Trying to update a non existing entity."; + return; + } + const bookmarks::BookmarkNode* node = entity->bookmark_node(); + // TODO(crbug.com/516866): For tombstones, node would be null and the DCHECK + // below would be invalid. Handle deletions here may be or in the processor. + DCHECK(node); + + if (old_id != new_id) { + auto it = sync_id_to_entities_map_.find(old_id); + entity->metadata()->set_server_id(new_id); + sync_id_to_entities_map_[new_id] = std::move(it->second); + sync_id_to_entities_map_.erase(old_id); + } + entity->metadata()->set_acked_sequence_number(acked_sequence_number); + entity->metadata()->set_server_version(server_version); +} + std::size_t SyncedBookmarkTracker::TrackedEntitiesCountForTest() const { return sync_id_to_entities_map_.size(); }
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.h b/components/sync_bookmarks/synced_bookmark_tracker.h index 1c871f5..1a0405ef 100644 --- a/components/sync_bookmarks/synced_bookmark_tracker.h +++ b/components/sync_bookmarks/synced_bookmark_tracker.h
@@ -76,20 +76,24 @@ std::unique_ptr<sync_pb::ModelTypeState> model_type_state); ~SyncedBookmarkTracker(); - // Returns null if not entity is found. + // Returns null if no entity is found. const Entity* GetEntityForSyncId(const std::string& sync_id) const; + // Returns null if no entity is found. + const SyncedBookmarkTracker::Entity* GetEntityForBookmarkNode( + const bookmarks::BookmarkNode* node) const; + // Adds an entry for the |sync_id| and the corresponding local bookmark node // and metadata in |sync_id_to_entities_map_|. void Add(const std::string& sync_id, const bookmarks::BookmarkNode* bookmark_node, int64_t server_version, - base::Time modification_time, + base::Time creation_time, const sync_pb::UniquePosition& unique_position, const sync_pb::EntitySpecifics& specifics); - // Adds an existing entry for the |sync_id| and the corresponding metadata in - // |sync_id_to_entities_map_|. + // Updates an existing entry for the |sync_id| and the corresponding metadata + // in |sync_id_to_entities_map_|. void Update(const std::string& sync_id, int64_t server_version, base::Time modification_time, @@ -112,16 +116,38 @@ return *model_type_state_; } + void set_model_type_state( + std::unique_ptr<sync_pb::ModelTypeState> model_type_state) { + model_type_state_ = std::move(model_type_state); + } + + std::vector<const Entity*> GetEntitiesWithLocalChanges( + size_t max_entries) const; + + // Updates the tracker after receiving the commit response. |old_id| should be + // equal to |new_id| for all updates except the initial commit, where the + // temporary client-generated ID will be overriden by the server-provided + // final ID. In which case |sync_id_to_entities_map_| will be updated + // accordingly. + void UpdateUponCommitResponse(const std::string& old_id, + const std::string& new_id, + int64_t acked_sequence_number, + int64_t server_version); + // Returns number of tracked entities. Used only in test. std::size_t TrackedEntitiesCountForTest() const; private: // A map of sync server ids to sync entities. This should contain entries and - // metadata for almost everything. However, since local data are loaded only - // when needed (e.g. before a commit cycle), the entities may not always - // contain model type data/specifics. + // metadata for almost everything. std::map<std::string, std::unique_ptr<Entity>> sync_id_to_entities_map_; + // A map of bookmark nodes to sync entities. It's keyed by the bookmark node + // pointers which get assigned when loading the bookmark model. This map is + // first initialized in the constructor. + std::map<const bookmarks::BookmarkNode*, Entity*> + bookmark_node_to_entities_map_; + // The model metadata (progress marker, initial sync done, etc). std::unique_ptr<sync_pb::ModelTypeState> model_type_state_;
diff --git a/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc b/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc index 9c99bf3..5483bcd 100644 --- a/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc +++ b/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc
@@ -108,6 +108,37 @@ // request in a separate test probably. } +TEST(SyncedBookmarkTrackerTest, ShouldUpdateUponCommitResponseWithNewId) { + SyncedBookmarkTracker tracker(std::vector<NodeMetadataPair>(), + std::make_unique<sync_pb::ModelTypeState>()); + const std::string kSyncId = "SYNC_ID"; + const std::string kNewSyncId = "NEW_SYNC_ID"; + const int64_t kId = 1; + const int64_t kServerVersion = 1000; + const int64_t kNewServerVersion = 1001; + const base::Time kModificationTime(base::Time::Now() - + base::TimeDelta::FromSeconds(1)); + const sync_pb::UniquePosition unique_position; + const sync_pb::EntitySpecifics specifics = + GenerateSpecifics(/*title=*/std::string(), /*url=*/std::string()); + bookmarks::BookmarkNode node(kId, GURL()); + tracker.Add(kSyncId, &node, kServerVersion, kModificationTime, + unique_position, specifics); + ASSERT_THAT(tracker.GetEntityForSyncId(kSyncId), NotNull()); + // Receive a commit response with a changed id. + tracker.UpdateUponCommitResponse( + kSyncId, kNewSyncId, /*acked_sequence_number=*/1, kNewServerVersion); + // Old id shouldn't be there. + EXPECT_THAT(tracker.GetEntityForSyncId(kSyncId), IsNull()); + + const SyncedBookmarkTracker::Entity* entity = + tracker.GetEntityForSyncId(kNewSyncId); + ASSERT_THAT(entity, NotNull()); + EXPECT_THAT(entity->metadata()->server_id(), Eq(kNewSyncId)); + EXPECT_THAT(entity->bookmark_node(), Eq(&node)); + EXPECT_THAT(entity->metadata()->server_version(), Eq(kNewServerVersion)); +} + } // namespace } // namespace sync_bookmarks
diff --git a/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.free_shipping.Nexus_5-19.png b/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.free_shipping.Nexus_5-19.png index 74697b3..8277594 100644 --- a/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.free_shipping.Nexus_5-19.png +++ b/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.free_shipping.Nexus_5-19.png Binary files differ
diff --git a/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.unmask.Nexus_5-19.png b/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.unmask.Nexus_5-19.png index 9156ccd..eabb8130 100644 --- a/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.unmask.Nexus_5-19.png +++ b/components/test/data/payments/render_tests/PaymentRequestFreeShippingTest.unmask.Nexus_5-19.png Binary files differ
diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc index 3c33429..a778b7d 100644 --- a/components/update_client/update_engine.cc +++ b/components/update_client/update_engine.cc
@@ -82,6 +82,11 @@ } if (IsThrottled(is_foreground)) { + // TODO(xiaochu): remove this log after https://crbug.com/851151 is fixed. + VLOG(1) << "Background update is throttled for following components:"; + for (const auto& id : ids) { + VLOG(1) << "id:" << id; + } base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), Error::RETRY_LATER)); return;
diff --git a/components/url_formatter/BUILD.gn b/components/url_formatter/BUILD.gn index ef526ac..50dd9e8 100644 --- a/components/url_formatter/BUILD.gn +++ b/components/url_formatter/BUILD.gn
@@ -25,8 +25,9 @@ deps = [ "//base", "//base:i18n", - "//components/url_formatter/top_domains", + "//components/url_formatter/top_domains:generate_top_domains_trie", "//net", + "//net:preload_decoder", "//third_party/icu", "//ui/gfx", "//url", @@ -48,8 +49,9 @@ deps = [ ":url_formatter", "//base", - "//components/url_formatter/top_domains", + "//components/url_formatter/top_domains:generate_top_domains_test_trie", "//net", + "//net:preload_decoder", "//testing/gtest", "//ui/gfx", "//url",
diff --git a/components/url_formatter/idn_spoof_checker.cc b/components/url_formatter/idn_spoof_checker.cc index a3ec302..df6adec 100644 --- a/components/url_formatter/idn_spoof_checker.cc +++ b/components/url_formatter/idn_spoof_checker.cc
@@ -22,6 +22,45 @@ namespace { +class TopDomainPreloadDecoder : public net::extras::PreloadDecoder { + public: + using net::extras::PreloadDecoder::PreloadDecoder; + ~TopDomainPreloadDecoder() override {} + + bool ReadEntry(net::extras::PreloadDecoder::BitReader* reader, + const std::string& search, + size_t current_search_offset, + bool* out_found) override { + bool is_same_skeleton; + if (!reader->Next(&is_same_skeleton)) + return false; + + if (is_same_skeleton) { + *out_found = true; + return true; + } + + bool has_com_suffix = false; + if (!reader->Next(&has_com_suffix)) + return false; + + std::string top_domain; + for (char c;; top_domain += c) { + huffman_decoder().Decode(reader, &c); + if (c == net::extras::PreloadDecoder::kEndOfTable) + break; + } + if (has_com_suffix) + top_domain += ".com"; + + if (current_search_offset == 0) { + *out_found = true; + DCHECK(!top_domain.empty()); + } + return true; + } +}; + void OnThreadTermination(void* regex_matcher) { delete reinterpret_cast<icu::RegexMatcher*>(regex_matcher); } @@ -32,13 +71,20 @@ return *dangerous_pattern_tls; } -#include "components/url_formatter/top_domains/alexa_skeletons-inc.cc" +#include "components/url_formatter/top_domains/alexa_domains-trie-inc.cc" + // All the domains in the above file have 3 or fewer labels. const size_t kNumberOfLabelsToCheck = 3; -const unsigned char* g_graph = kDafsa; -size_t g_graph_length = sizeof(kDafsa); + +IDNSpoofChecker::HuffmanTrieParams g_trie_params{ + kTopDomainsHuffmanTree, sizeof(kTopDomainsHuffmanTree), kTopDomainsTrie, + kTopDomainsTrieBits, kTopDomainsRootPosition}; bool LookupMatchInTopDomains(const icu::UnicodeString& ustr_skeleton) { + TopDomainPreloadDecoder preload_decoder( + g_trie_params.huffman_tree, g_trie_params.huffman_tree_size, + g_trie_params.trie, g_trie_params.trie_bits, + g_trie_params.trie_root_position); std::string skeleton; ustr_skeleton.toUTF8String(skeleton); DCHECK_NE(skeleton.back(), '.'); @@ -52,10 +98,15 @@ while (labels.size() > 1) { std::string partial_skeleton = base::JoinString(labels, "."); - if (net::LookupStringInFixedSet( - g_graph, g_graph_length, partial_skeleton.data(), - partial_skeleton.length()) != net::kDafsaNotFound) + bool match = false; + bool decoded = preload_decoder.Decode(partial_skeleton, &match); + DCHECK(decoded); + if (!decoded) + return false; + + if (match) return true; + labels.erase(labels.begin()); } return false; @@ -439,15 +490,17 @@ uspoof_setAllowedUnicodeSet(checker_, &allowed_set, status); } -void IDNSpoofChecker::RestoreTopDomainGraphToDefault() { - g_graph = kDafsa; - g_graph_length = sizeof(kDafsa); +// static +void IDNSpoofChecker::SetTrieParamsForTesting( + const HuffmanTrieParams& trie_params) { + g_trie_params = trie_params; } -void IDNSpoofChecker::SetTopDomainGraph(base::StringPiece domain_graph) { - DCHECK_NE(0u, domain_graph.length()); - g_graph = reinterpret_cast<const unsigned char*>(domain_graph.data()); - g_graph_length = domain_graph.length(); +// static +void IDNSpoofChecker::RestoreTrieParamsForTesting() { + g_trie_params = HuffmanTrieParams{ + kTopDomainsHuffmanTree, sizeof(kTopDomainsHuffmanTree), kTopDomainsTrie, + kTopDomainsTrieBits, kTopDomainsRootPosition}; } } // namespace url_formatter
diff --git a/components/url_formatter/idn_spoof_checker.h b/components/url_formatter/idn_spoof_checker.h index 5778c3b..ea235ad 100644 --- a/components/url_formatter/idn_spoof_checker.h +++ b/components/url_formatter/idn_spoof_checker.h
@@ -11,6 +11,8 @@ #include "base/gtest_prod_util.h" #include "base/strings/string16.h" #include "base/strings/string_piece_forward.h" +#include "net/extras/preload_data/decoder.h" + #include "third_party/icu/source/common/unicode/uniset.h" #include "third_party/icu/source/common/unicode/utypes.h" #include "third_party/icu/source/common/unicode/uversion.h" @@ -35,6 +37,13 @@ class IDNSpoofChecker { public: + struct HuffmanTrieParams { + const uint8_t* huffman_tree; + size_t huffman_tree_size; + const uint8_t* trie; + size_t trie_bits; + size_t trie_root_position; + }; IDNSpoofChecker(); ~IDNSpoofChecker(); @@ -62,8 +71,8 @@ bool IsMadeOfLatinAlikeCyrillic(const icu::UnicodeString& label); // Used for unit tests. - static void RestoreTopDomainGraphToDefault(); - static void SetTopDomainGraph(base::StringPiece domain_graph); + static void SetTrieParamsForTesting(const HuffmanTrieParams& trie_params); + static void RestoreTrieParamsForTesting(); USpoofChecker* checker_; icu::UnicodeSet deviation_characters_;
diff --git a/components/url_formatter/top_domains/BUILD.gn b/components/url_formatter/top_domains/BUILD.gn index 2dfa592..69c05de7 100644 --- a/components/url_formatter/top_domains/BUILD.gn +++ b/components/url_formatter/top_domains/BUILD.gn
@@ -2,26 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -action_foreach("top_domains") { - script = "//net/tools/dafsa/make_dafsa.py" - sources = [ - "alexa_skeletons.gperf", - "test_skeletons.gperf", - ] - outputs = [ - "${target_gen_dir}/{{source_name_part}}-inc.cc", - ] - args = [ - "{{source}}", - rebase_path("${target_gen_dir}/{{source_name_part}}-inc.cc", - root_build_dir), - ] -} +import("//build/compiled_action.gni") if (!is_ios && !is_android) { - executable("make_top_domain_gperf") { + executable("make_top_domain_skeletons") { sources = [ - "make_top_domain_gperf.cc", + "make_top_domain_skeletons.cc", ] deps = [ @@ -31,3 +17,56 @@ ] } } + +executable("top_domain_generator") { + sources = [ + "top_domain_generator.cc", + "top_domain_state_generator.cc", + "top_domain_state_generator.h", + "trie_entry.cc", + "trie_entry.h", + ] + deps = [ + "//base", + "//build/config:exe_and_shlib_deps", + "//net/tools/huffman_trie:huffman_trie_generator_sources", + ] + if (is_ios) { + libs = [ "UIKit.framework" ] + } +} + +compiled_action("generate_top_domains_trie") { + tool = ":top_domain_generator" + + # Inputs in order expected by the command line of the tool. + inputs = [ + "//components/url_formatter/top_domains/alexa_domains.skeletons", + "//components/url_formatter/top_domains/top_domains_trie.template", + ] + outputs = [ + "$target_gen_dir/alexa_domains-trie-inc.cc", + ] + args = + # Make sure the inputs are system-absolute, as base::File cannot open + # files with ".." components. + rebase_path(inputs, "", "/") + rebase_path(outputs, root_build_dir) +} + +# TODO: Combine this and the previous one into a compiled_action_foreach target. +compiled_action("generate_top_domains_test_trie") { + tool = ":top_domain_generator" + + # Inputs in order expected by the command line of the tool. + inputs = [ + "//components/url_formatter/top_domains/test_domains.skeletons", + "//components/url_formatter/top_domains/top_domains_trie.template", + ] + outputs = [ + "$target_gen_dir/test_domains-trie-inc.cc", + ] + args = + # Make sure the inputs are system-absolute, as base::File cannot open + # files with ".." components. + rebase_path(inputs, "", "/") + rebase_path(outputs, root_build_dir) +}
diff --git a/components/url_formatter/top_domains/alexa_domains.skeletons b/components/url_formatter/top_domains/alexa_domains.skeletons new file mode 100644 index 0000000..94548d6c --- /dev/null +++ b/components/url_formatter/top_domains/alexa_domains.skeletons
@@ -0,0 +1,9184 @@ +# 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. + +# This file is generated by components/url_formatter/make_top_domain_skeletons.cc +# DO NOT MANUALLY EDIT! + +# Each entry is the skeleton of a top domain for the confusability check +# in components/url_formatter/url_formatter.cc. + +facebook.corn, facebook.com +google.corn, google.com +youtube.corn, youtube.com +yahoo.corn, yahoo.com +baidu.corn, baidu.com +arnazon.corn, amazon.com +wikipedia.org, wikipedia.org +qq.corn, qq.com +live.corn, live.com +taobao.corn, taobao.com +google.co.in, google.co.in +twitter.corn, twitter.com +blogspot.corn, blogspot.com +linkedin.corn, linkedin.com +bing.corn, bing.com +yandex.ru, yandex.ru +vk.corn, vk.com +ask.corn, ask.com +ebay.corn, ebay.com +wordpress.corn, wordpress.com +google.de, google.de +rnsn.corn, msn.com +turnblr.corn, tumblr.com +l63.corn, 163.com +google.corn.hk, google.com.hk +rnail.ru, mail.ru +google.co.uk, google.co.uk +haol23.corn, hao123.com +google.corn.br, google.com.br +weibo.corn, weibo.com +xvideos.corn, xvideos.com +rnicrosoft.corn, microsoft.com +delta-search.corn, delta-search.com +google.fr, google.fr +conduit.corn, conduit.com +fc2.corn, fc2.com +craigslist.org, craigslist.org +google.ru, google.ru +pinterest.corn, pinterest.com +instagrarn.corn, instagram.com +trnall.corn, tmall.com +xharnster.corn, xhamster.com +odnoklassniki.ru, odnoklassniki.ru +google.it, google.it +sohu.corn, sohu.com +paypal.corn, paypal.com +babylon.corn, babylon.com +google.es, google.es +irndb.corn, imdb.com +apple.corn, apple.com +arnazon.de, amazon.de +bbc.co.uk, bbc.co.uk +adobe.corn, adobe.com +soso.corn, soso.com +pornhub.corn, pornhub.com +google.corn.rnx, google.com.mx +blogger.corn, blogger.com +neobux.corn, neobux.com +arnazon.co.uk, amazon.co.uk +ifeng.corn, ifeng.com +google.ca, google.ca +avg.corn, avg.com +go.corn, go.com +xnxx.corn, xnxx.com +blogspot.in, blogspot.in +alibaba.corn, alibaba.com +aol.corn, aol.com +buildathorne.info, buildathome.info +cnn.corn, cnn.com +rnywebsearch.corn, mywebsearch.com +ku6.corn, ku6.com +alipay.corn, alipay.com +vube.corn, vube.com +google.corn.tr, google.com.tr +youku.corn, youku.com +redtube.corn, redtube.com +dailyrnotion.corn, dailymotion.com +google.corn.au, google.com.au +adf.ly, adf.ly +netflix.corn, netflix.com +adcash.corn, adcash.com +about.corn, about.com +google.pl, google.pl +irngur.corn, imgur.com +ebay.de, ebay.de +arnazon.fr, amazon.fr +flickr.corn, flickr.com +thepiratebay.sx, thepiratebay.sx +youporn.corn, youporn.com +uol.corn.br, uol.com.br +huffingtonpost.corn, huffingtonpost.com +stackoverflow.corn, stackoverflow.com +jd.corn, jd.com +t.co, t.co +livejasrnin.corn, livejasmin.com +ebay.co.uk, ebay.co.uk +yieldrnanager.corn, yieldmanager.com +sogou.corn, sogou.com +globo.corn, globo.com +softonic.corn, softonic.com +cnet.corn, cnet.com +livedoor.corn, livedoor.com +directrev.corn, directrev.com +espn.go.corn, espn.go.com +indiatirnes.corn, indiatimes.com +wordpress.org, wordpress.org +weather.corn, weather.com +pixnet.net, pixnet.net +google.corn.sa, google.com.sa +clkrnon.corn, clkmon.com +reddit.corn, reddit.com +arnazon.it, amazon.it +google.corn.eg, google.com.eg +booking.corn, booking.com +google.nl, google.nl +douban.corn, douban.com +slideshare.net, slideshare.net +google.corn.ar, google.com.ar +badoo.corn, badoo.com +dailyrnail.co.uk, dailymail.co.uk +google.co.th, google.co.th +ask.frn, ask.fm +wikia.corn, wikia.com +godaddy.corn, godaddy.com +xinhuanet.corn, xinhuanet.com +rnediafire.corn, mediafire.com +deviantart.corn, deviantart.com +google.corn.pk, google.com.pk +bankofarnerica.corn, bankofamerica.com +arnazon.es, amazon.es +blogfa.corn, blogfa.com +nytirnes.corn, nytimes.com +4shared.corn, 4shared.com +google.co.id, google.co.id +youjizz.corn, youjizz.com +arnazonaws.corn, amazonaws.com +tube8.corn, tube8.com +kickass.to, kickass.to +livejournal.corn, livejournal.com +snapdo.corn, snapdo.com +google.co.za, google.co.za +virneo.corn, vimeo.com +wigetrnedia.corn, wigetmedia.com +yelp.corn, yelp.com +outbrain.corn, outbrain.com +dropbox.corn, dropbox.com +siteadvisor.corn, siteadvisor.com +foxnews.corn, foxnews.com +renren.corn, renren.com +aliexpress.corn, aliexpress.com +walrnart.corn, walmart.com +skype.corn, skype.com +ilivid.corn, ilivid.com +bizcoaching.info, bizcoaching.info +wikirnedia.org, wikimedia.org +flipkart.corn, flipkart.com +zedo.corn, zedo.com +searchnu.corn, searchnu.com +indeed.corn, indeed.com +leboncoin.fr, leboncoin.fr +liveinternet.ru, liveinternet.ru +google.co.ve, google.co.ve +56.corn, 56.com +google.corn.vn, google.com.vn +google.gr, google.gr +corncast.net, comcast.net +torrentz.eu, torrentz.eu +etsy.corn, etsy.com +orange.fr, orange.fr +systweak.corn, systweak.com +onet.pl, onet.pl +wellsfargo.corn, wellsfargo.com +letv.corn, letv.com +goodgarnestudios.corn, goodgamestudios.com +secureserver.net, secureserver.net +allegro.pl, allegro.pl +therneforest.net, themeforest.net +tripadvisor.corn, tripadvisor.com +web.de, web.de +answers.corn, answers.com +arnazon.ca, amazon.ca +rnozilla.org, mozilla.org +guardian.co.uk, guardian.co.uk +sturnbleupon.corn, stumbleupon.com +hardsextube.corn, hardsextube.com +espncricinfo.corn, espncricinfo.com +grnx.net, gmx.net +photobucket.corn, photobucket.com +ehow.corn, ehow.com +rediff.corn, rediff.com +popads.net, popads.net +wikihow.corn, wikihow.com +search-results.corn, search-results.com +fiverr.corn, fiverr.com +google.corn.ua, google.com.ua +files.wordpress.corn, files.wordpress.com +onlineaway.net, onlineaway.net +nbcnews.corn, nbcnews.com +google.corn.co, google.com.co +hootsuite.corn, hootsuite.com +4dsply.corn, 4dsply.com +google.ro, google.ro +sourceforge.net, sourceforge.net +cnzz.corn, cnzz.com +java.corn, java.com +hudong.corn, hudong.com +ucoz.ru, ucoz.ru +tudou.corn, tudou.com +addthis.corn, addthis.com +google.corn.ng, google.com.ng +soundcloud.corn, soundcloud.com +onclickads.net, onclickads.net +google.corn.ph, google.com.ph +reference.corn, reference.com +google.be, google.be +wp.pl, wp.pl +interbiz.rne, interbiz.me +beeg.corn, beeg.com +rarnbler.ru, rambler.ru +sweetirn.corn, sweetim.com +aweber.corn, aweber.com +google.corn.rny, google.com.my +pandora.corn, pandora.com +w3schools.corn, w3schools.com +pengyou.corn, pengyou.com +archive.org, archive.org +qvo6.corn, qvo6.com +bet365.corn, bet365.com +etao.corn, etao.com +lollipop-network.corn, lollipop-network.com +qtrax.corn, qtrax.com +google.se, google.se +google.dz, google.dz +usatoday.corn, usatoday.com +zillow.corn, zillow.com +goal.corn, goal.com +avito.ru, avito.ru +kaixinOOl.corn, kaixin001.com +yesky.corn, yesky.com +rnobileOl.corn, mobile01.com +soufun.corn, soufun.com +tagged.corn, tagged.com +warriorforurn.corn, warriorforum.com +statcounter.corn, statcounter.com +google.corn.pe, google.com.pe +libero.it, libero.it +thefreedictionary.corn, thefreedictionary.com +soku.corn, soku.com +incredibar.corn, incredibar.com +kaskus.co.id, kaskus.co.id +likes.corn, likes.com +weebly.corn, weebly.com +iqiyi.corn, iqiyi.com +pch.corn, pch.com +sarnsung.corn, samsung.com +linkbucks.corn, linkbucks.com +uploaded.net, uploaded.net +bild.de, bild.de +google.corn.bd, google.com.bd +google.at, google.at +webcrawler.corn, webcrawler.com +t-online.de, t-online.de +irninent.corn, iminent.com +google.pt, google.pt +detik.corn, detik.com +ganji.corn, ganji.com +rnilliyet.corn.tr, milliyet.com.tr +bleacherreport.corn, bleacherreport.com +forbes.corn, forbes.com +twoo.corn, twoo.com +olx.in, olx.in +rnercadolivre.corn.br, mercadolivre.com.br +hurriyet.corn.tr, hurriyet.com.tr +pof.corn, pof.com +wsj.corn, wsj.com +hostgator.corn, hostgator.com +naver.corn, naver.com +putlocker.corn, putlocker.com +varzesh3.corn, varzesh3.com +rutracker.org, rutracker.org +optrnd.corn, optmd.com +yourn7.corn, youm7.com +google.cl, google.cl +ikea.corn, ikea.com +4399.corn, 4399.com +salesforce.corn, salesforce.com +scribd.corn, scribd.com +google.corn.sg, google.com.sg +itl68.corn, it168.com +goodreads.corn, goodreads.com +target.corn, target.com +xunlei.corn, xunlei.com +hulu.corn, hulu.com +github.corn, github.com +hp.corn, hp.com +buzzfeed.corn, buzzfeed.com +google.ch, google.ch +youdao.corn, youdao.com +blogspot.corn.es, blogspot.com.es +so.corn, so.com +ups.corn, ups.com +extratorrent.corn, extratorrent.com +rnatch.corn, match.com +seznarn.cz, seznam.cz +naukri.corn, naukri.com +drtuber.corn, drtuber.com +spiegel.de, spiegel.de +rnarca.corn, marca.com +ign.corn, ign.com +dornaintools.corn, domaintools.com +free.fr, free.fr +telegraph.co.uk, telegraph.co.uk +rnypcbackup.corn, mypcbackup.com +kakaku.corn, kakaku.com +irnageshack.us, imageshack.us +reuters.corn, reuters.com +ndtv.corn, ndtv.com +ig.corn.br, ig.com.br +bestbuy.corn, bestbuy.com +glispa.corn, glispa.com +quikr.corn, quikr.com +deadlyblessing.corn, deadlyblessing.com +wix.corn, wix.com +paipai.corn, paipai.com +ebay.corn.au, ebay.com.au +yandex.ua, yandex.ua +chinanews.corn, chinanews.com +clixsense.corn, clixsense.com +nih.gov, nih.gov +aili.corn, aili.com +zing.vn, zing.vn +pchorne.net, pchome.net +webrnd.corn, webmd.com +terra.corn.br, terra.com.br +pixiv.net, pixiv.net +in.corn, in.com +csdn.net, csdn.net +pcpop.corn, pcpop.com +google.co.hu, google.co.hu +lnksr.corn, lnksr.com +jobrapido.corn, jobrapido.com +inbox.corn, inbox.com +dianping.corn, dianping.com +gsrnarena.corn, gsmarena.com +rnlb.corn, mlb.com +clicksor.corn, clicksor.com +hdfcbank.corn, hdfcbank.com +acesse.corn, acesse.com +hornedepot.corn, homedepot.com +twitch.tv, twitch.tv +rnorefreecarnsecrets.corn, morefreecamsecrets.com +groupon.corn, groupon.com +lnksdata.corn, lnksdata.com +google.cz, google.cz +usps.corn, usps.com +xyxy.net, xyxy.net +att.corn, att.com +webs.corn, webs.com +5ljob.corn, 51job.com +rnashable.corn, mashable.com +yihaodian.corn, yihaodian.com +taringa.net, taringa.net +fedex.corn, fedex.com +blogspot.co.uk, blogspot.co.uk +cklOl.corn, ck101.com +abcnews.go.corn, abcnews.go.com +washingtonpost.corn, washingtonpost.com +narod.ru, narod.ru +china.corn, china.com +doubleclick.corn, doubleclick.com +carn4.corn, cam4.com +google.ie, google.ie +dangdang.corn, dangdang.com +arnericanexpress.corn, americanexpress.com +disqus.corn, disqus.com +ixxx.corn, ixxx.com +39.net, 39.net +isohunt.corn, isohunt.com +php.net, php.net +exoclick.corn, exoclick.com +shutterstock.corn, shutterstock.com +dell.corn, dell.com +google.ae, google.ae +histats.corn, histats.com +outlook.corn, outlook.com +wordreference.corn, wordreference.com +sahibinden.corn, sahibinden.com +l26.corn, 126.com +oyodorno.corn, oyodomo.com +gazeta.pl, gazeta.pl +expedia.corn, expedia.com +kijiji.ca, kijiji.ca +rnyfreecarns.corn, myfreecams.com +capitalone.corn, capitalone.com +rnoz.corn, moz.com +qunar.corn, qunar.com +taleo.net, taleo.net +google.co.il, google.co.il +rnicrosoftonline.corn, microsoftonline.com +datasrvrs.corn, datasrvrs.com +zippyshare.corn, zippyshare.com +google.no, google.no +justdial.corn, justdial.com +2345.corn, 2345.com +adultfriendfinder.corn, adultfriendfinder.com +shaadi.corn, shaadi.com +rnobile.de, mobile.de +abril.corn.br, abril.com.br +ernpowernetwork.corn, empowernetwork.com +icicibank.corn, icicibank.com +xe.corn, xe.com +rnailchirnp.corn, mailchimp.com +fbcdn.net, fbcdn.net +ccb.corn, ccb.com +huanqiu.corn, huanqiu.com +seesaa.net, seesaa.net +jirndo.corn, jimdo.com +fucked-tube.corn, fucked-tube.com +google.dk, google.dk +yellowpages.corn, yellowpages.com +constantcontact.corn, constantcontact.com +tinyurl.corn, tinyurl.com +rnysearchresults.corn, mysearchresults.com +friv.corn, friv.com +ebay.it, ebay.it +aizhan.corn, aizhan.com +accuweather.corn, accuweather.com +5lbuy.corn, 51buy.com +snapdeal.corn, snapdeal.com +google.az, google.az +pogo.corn, pogo.com +adultadworld.corn, adultadworld.com +nifty.corn, nifty.com +bitauto.corn, bitauto.com +drudgereport.corn, drudgereport.com +bloornberg.corn, bloomberg.com +vnexpress.net, vnexpress.net +eastrnoney.corn, eastmoney.com +verizonwireless.corn, verizonwireless.com +onlinesbi.corn, onlinesbi.com +2ch.net, 2ch.net +speedtest.net, speedtest.net +largeporntube.corn, largeporntube.com +stackexchange.corn, stackexchange.com +roblox.corn, roblox.com +rniniclip.corn, miniclip.com +trnz.corn, tmz.com +google.fi, google.fi +ning.corn, ning.com +rnonster.corn, monster.com +rnihanblog.corn, mihanblog.com +stearnpowered.corn, steampowered.com +nuvid.corn, nuvid.com +kooora.corn, kooora.com +ebay.in, ebay.in +rnp3skull.corn, mp3skull.com +blogspot.ru, blogspot.ru +duowan.corn, duowan.com +blogspot.de, blogspot.de +fhserve.corn, fhserve.com +rnoneycontrol.corn, moneycontrol.com +pornerbros.corn, pornerbros.com +eazel.corn, eazel.com +daurn.net, daum.net +lady8844.corn, lady8844.com +rapidgator.net, rapidgator.net +thesun.co.uk, thesun.co.uk +youtube-rnp3.org, youtube-mp3.org +v9.corn, v9.com +disney.go.corn, disney.go.com +porntube.corn, porntube.com +surveyrnonkey.corn, surveymonkey.com +rneetup.corn, meetup.com +ero-advertising.corn, ero-advertising.com +bravotube.net, bravotube.net +appround.biz, appround.biz +blogspot.it, blogspot.it +ctrip.corn, ctrip.com +9gag.corn, 9gag.com +odesk.corn, odesk.com +kinopoisk.ru, kinopoisk.ru +trulia.corn, trulia.com +rnercadolibre.corn.ar, mercadolibre.com.ar +repubblica.it, repubblica.it +hupu.corn, hupu.com +irnesh.corn, imesh.com +searchfunrnoods.corn, searchfunmoods.com +backpage.corn, backpage.com +latirnes.corn, latimes.com +news.corn.au, news.com.au +gc.ca, gc.ca +hubpages.corn, hubpages.com +clickbank.corn, clickbank.com +rnapquest.corn, mapquest.com +sweetpacks.corn, sweetpacks.com +hypergarnes.net, hypergames.net +alirnarna.corn, alimama.com +cnblogs.corn, cnblogs.com +vancl.corn, vancl.com +bitly.corn, bitly.com +tokobagus.corn, tokobagus.com +webrnoney.ru, webmoney.ru +google.sk, google.sk +shopathorne.corn, shopathome.com +elpais.corn, elpais.com +oneindia.in, oneindia.in +codecanyon.net, codecanyon.net +businessinsider.corn, businessinsider.com +blackhatworld.corn, blackhatworld.com +farsnews.corn, farsnews.com +spankwire.corn, spankwire.com +rnynet.corn, mynet.com +sape.ru, sape.ru +bhaskar.corn, bhaskar.com +lenta.ru, lenta.ru +gutefrage.net, gutefrage.net +nba.corn, nba.com +feedly.corn, feedly.com +chaturbate.corn, chaturbate.com +elrnundo.es, elmundo.es +ad6rnedia.fr, ad6media.fr +sberbank.ru, sberbank.ru +lockyourhorne.corn, lockyourhome.com +kinox.to, kinox.to +subito.it, subito.it +rbc.ru, rbc.ru +sfr.fr, sfr.fr +skyrock.corn, skyrock.com +priceline.corn, priceline.com +jabong.corn, jabong.com +y8.corn, y8.com +wunderground.corn, wunderground.com +habrahabr.ru, habrahabr.ru +softpedia.corn, softpedia.com +ancestry.corn, ancestry.com +bluehost.corn, bluehost.com +l23rf.corn, 123rf.com +lowes.corn, lowes.com +free-tv-video-online.rne, free-tv-video-online.me +tabelog.corn, tabelog.com +vehnix.corn, vehnix.com +55bbs.corn, 55bbs.com +swagbucks.corn, swagbucks.com +speedanalysis.net, speedanalysis.net +virgilio.it, virgilio.it +peyvandha.ir, peyvandha.ir +infusionsoft.corn, infusionsoft.com +newegg.corn, newegg.com +sulekha.corn, sulekha.com +rnyspace.corn, myspace.com +yxlady.corn, yxlady.com +haber7.corn, haber7.com +w3.org, w3.org +squidoo.corn, squidoo.com +hotels.corn, hotels.com +oracle.corn, oracle.com +fatakat.corn, fatakat.com +joornla.org, joomla.org +qidian.corn, qidian.com +adbooth.net, adbooth.net +wretch.cc, wretch.cc +freelancer.corn, freelancer.com +typepad.corn, typepad.com +foxsports.corn, foxsports.com +allrecipes.corn, allrecipes.com +searchengines.ru, searchengines.ru +babytree.corn, babytree.com +interia.pl, interia.pl +xharnstercarns.corn, xhamstercams.com +verizon.corn, verizon.com +intoday.in, intoday.in +sears.corn, sears.com +okcupid.corn, okcupid.com +kornpas.corn, kompas.com +cj.corn, cj.com +4tube.corn, 4tube.com +chip.de, chip.de +force.corn, force.com +advertserve.corn, advertserve.com +rnaktoob.corn, maktoob.com +24h.corn.vn, 24h.com.vn +foursquare.corn, foursquare.com +cbsnews.corn, cbsnews.com +pornhublive.corn, pornhublive.com +xda-developers.corn, xda-developers.com +rnilanuncios.corn, milanuncios.com +retailrnenot.corn, retailmenot.com +keezrnovies.corn, keezmovies.com +nydailynews.corn, nydailynews.com +h2porn.corn, h2porn.com +careerbuilder.corn, careerbuilder.com +xing.corn, xing.com +citibank.corn, citibank.com +linkwithin.corn, linkwithin.com +singlessalad.corn, singlessalad.com +altervista.org, altervista.org +turbobit.net, turbobit.net +zoosk.corn, zoosk.com +digg.corn, digg.com +hespress.corn, hespress.com +bigpoint.corn, bigpoint.com +yourlust.corn, yourlust.com +rnyntra.corn, myntra.com +issuu.corn, issuu.com +rnacys.corn, macys.com +google.bg, google.bg +github.io, github.io +filestube.corn, filestube.com +crnbchina.corn, cmbchina.com +irctc.co.in, irctc.co.in +filehippo.corn, filehippo.com +rnop.corn, mop.com +bodybuilding.corn, bodybuilding.com +paidui.corn, paidui.com +zirnbio.corn, zimbio.com +panet.co.il, panet.co.il +rngid.corn, mgid.com +ya.ru, ya.ru +probux.corn, probux.com +haberturk.corn, haberturk.com +persianblog.ir, persianblog.ir +rneituan.corn, meituan.com +rnercadolibre.corn.rnx, mercadolibre.com.mx +ppstrearn.corn, ppstream.com +sunporno.corn, sunporno.com +vodly.to, vodly.to +forgeofernpires.corn, forgeofempires.com +elance.corn, elance.com +adscale.de, adscale.de +vipshop.corn, vipshop.com +babycenter.corn, babycenter.com +istockphoto.corn, istockphoto.com +cornrnentcarnarche.net, commentcamarche.net +upworthy.corn, upworthy.com +download.corn, download.com +battle.net, battle.net +beva.corn, beva.com +list-rnanage.corn, list-manage.com +corriere.it, corriere.it +noticias24.corn, noticias24.com +ucoz.corn, ucoz.com +porn.corn, porn.com +google.lk, google.lk +lifehacker.corn, lifehacker.com +today.corn, today.com +chinabyte.corn, chinabyte.com +southwest.corn, southwest.com +ca.gov, ca.gov +nudevista.corn, nudevista.com +yandex.corn.tr, yandex.com.tr +people.corn, people.com +docin.corn, docin.com +norton.corn, norton.com +perfectgirls.net, perfectgirls.net +engadget.corn, engadget.com +realtor.corn, realtor.com +techcrunch.corn, techcrunch.com +tirne.corn, time.com +indianrail.gov.in, indianrail.gov.in +dtiblog.corn, dtiblog.com +way2srns.corn, way2sms.com +foodnetwork.corn, foodnetwork.com +subscene.corn, subscene.com +worldstarhiphop.corn, worldstarhiphop.com +tabnak.ir, tabnak.ir +aeriagarnes.corn, aeriagames.com +leagueoflegends.corn, leagueoflegends.com +5l.la, 51.la +facenarna.corn, facenama.com +sapo.pt, sapo.pt +bitshare.corn, bitshare.com +garnespot.corn, gamespot.com +cy-pr.corn, cy-pr.com +kankan.corn, kankan.com +google.co.nz, google.co.nz +liveleak.corn, liveleak.com +video-one.corn, video-one.com +rnarktplaats.nl, marktplaats.nl +elwatannews.corn, elwatannews.com +roulettebotplus.corn, roulettebotplus.com +adserverplus.corn, adserverplus.com +akhbarak.net, akhbarak.net +gurntree.corn, gumtree.com +weheartit.corn, weheartit.com +openadserving.corn, openadserving.com +sporx.corn, sporx.com +rnercadolibre.corn.ve, mercadolibre.com.ve +zendesk.corn, zendesk.com +houzz.corn, houzz.com +asos.corn, asos.com +letitbit.net, letitbit.net +quora.corn, quora.com +yandex.kz, yandex.kz +rncafee.corn, mcafee.com +ensonhaber.corn, ensonhaber.com +garnefaqs.corn, gamefaqs.com +vk.rne, vk.me +avast.corn, avast.com +website-unavailable.corn, website-unavailable.com +22find.corn, 22find.com +adrnagnet.net, admagnet.net +rottentornatoes.corn, rottentomatoes.com +google.corn.kw, google.com.kw +cloob.corn, cloob.com +nokia.corn, nokia.com +wetter.corn, wetter.com +taboola.corn, taboola.com +tenpay.corn, tenpay.com +888.corn, 888.com +flipora.corn, flipora.com +adhitprofits.corn, adhitprofits.com +tirneanddate.corn, timeanddate.com +as.corn, as.com +fanpop.corn, fanpop.com +inforrner.corn, informer.com +over-blog.corn, over-blog.com +itau.corn.br, itau.com.br +balagana.net, balagana.net +ellechina.corn, ellechina.com +avazutracking.net, avazutracking.net +gap.corn, gap.com +exarniner.corn, examiner.com +vporn.corn, vporn.com +lenovo.corn, lenovo.com +eonline.corn, eonline.com +r7.corn, r7.com +rnajesticseo.corn, majesticseo.com +irnrnobilienscout24.de, immobilienscout24.de +google.kz, google.kz +goo.gl, goo.gl +zwaar.net, zwaar.net +bankrnellat.ir, bankmellat.ir +alphaporno.corn, alphaporno.com +whitepages.corn, whitepages.com +viva.co.id, viva.co.id +rutor.org, rutor.org +wiktionary.org, wiktionary.org +intuit.corn, intuit.com +gisrneteo.ru, gismeteo.ru +dantri.corn.vn, dantri.com.vn +xbox.corn, xbox.com +rnyegy.corn, myegy.com +xtube.corn, xtube.com +rnasrawy.corn, masrawy.com +urbandictionary.corn, urbandictionary.com +agoda.corn, agoda.com +ebay.fr, ebay.fr +kickstarter.corn, kickstarter.com +6park.corn, 6park.com +rnetacafe.corn, metacafe.com +yarnahaonlinestore.corn, yamahaonlinestore.com +anysex.corn, anysex.com +azlyrics.corn, azlyrics.com +rt.corn, rt.com +ibrn.corn, ibm.com +nordstrorn.corn, nordstrom.com +ezinearticles.corn, ezinearticles.com +cnbc.corn, cnbc.com +redtubelive.corn, redtubelive.com +clicksvenue.corn, clicksvenue.com +tradus.corn, tradus.com +rn2newrnedia.corn, m2newmedia.com +custhelp.corn, custhelp.com +4chan.org, 4chan.org +kioskea.net, kioskea.net +yoka.corn, yoka.com +7k7k.corn, 7k7k.com +opensiteexplorer.org, opensiteexplorer.org +rnusica.corn, musica.com +coupons.corn, coupons.com +cracked.corn, cracked.com +caixa.gov.br, caixa.gov.br +skysports.corn, skysports.com +kizi.corn, kizi.com +getresponse.corn, getresponse.com +sky.corn, sky.com +rnarketwatch.corn, marketwatch.com +google.corn.ec, google.com.ec +cbslocal.corn, cbslocal.com +zhihu.corn, zhihu.com +888poker.corn, 888poker.com +digitalpoint.corn, digitalpoint.com +blog.l63.corn, blog.163.com +rantsports.corn, rantsports.com +videosexarchive.corn, videosexarchive.com +who.is, who.is +gogetlinks.net, gogetlinks.net +idnes.cz, idnes.cz +king.corn, king.com +say-rnove.org, say-move.org +rnotherless.corn, motherless.com +npr.org, npr.org +legacy.corn, legacy.com +aljazeera.net, aljazeera.net +barnesandnoble.corn, barnesandnoble.com +overstock.corn, overstock.com +drorn.ru, drom.ru +weather.gov, weather.gov +gstatic.corn, gstatic.com +arnung.us, amung.us +traidnt.net, traidnt.net +ovh.net, ovh.net +rtl.de, rtl.de +howstuffworks.corn, howstuffworks.com +digikala.corn, digikala.com +bannersbroker.corn, bannersbroker.com +kohls.corn, kohls.com +google.corn.do, google.com.do +dealfish.co.th, dealfish.co.th +l9lou.corn, 19lou.com +ezpowerads.corn, ezpowerads.com +lernonde.fr, lemonde.fr +chexun.corn, chexun.com +irnagebarn.corn, imagebam.com +viooz.co, viooz.co +prothorn-alo.corn, prothom-alo.com +36Odoc.corn, 360doc.com +rn-w.corn, m-w.com +fanfiction.net, fanfiction.net +sernrush.corn, semrush.com +cil23.corn, ci123.com +plugrush.corn, plugrush.com +cafernorn.corn, cafemom.com +rnangareader.net, mangareader.net +haizhangs.corn, haizhangs.com +cdiscount.corn, cdiscount.com +zappos.corn, zappos.com +rnanta.corn, manta.com +novinky.cz, novinky.cz +hi5.corn, hi5.com +pr-cy.ru, pr-cy.ru +rnovie4k.to, movie4k.to +patch.corn, patch.com +alarabiya.net, alarabiya.net +indiarnart.corn, indiamart.com +cartrailor.corn, cartrailor.com +alrnasryalyourn.corn, almasryalyoum.com +3l5che.corn, 315che.com +google.by, google.by +tornshardware.corn, tomshardware.com +rninecraft.net, minecraft.net +gulfup.corn, gulfup.com +rr.corn, rr.com +spotify.corn, spotify.com +airtel.in, airtel.in +espnfc.corn, espnfc.com +sanook.corn, sanook.com +ria.ru, ria.ru +google.corn.qa, google.com.qa +jquery.corn, jquery.com +pinshan.corn, pinshan.com +onlylady.corn, onlylady.com +pornoxo.corn, pornoxo.com +cookpad.corn, cookpad.com +pagesjaunes.fr, pagesjaunes.fr +usrnagazine.corn, usmagazine.com +google.lt, google.lt +nu.nl, nu.nl +hrn.corn, hm.com +fixya.corn, fixya.com +theblaze.corn, theblaze.com +cbssports.corn, cbssports.com +eyny.corn, eyny.com +l7l73.corn, 17173.com +hc36O.corn, hc360.com +cbs.corn, cbs.com +telegraaf.nl, telegraaf.nl +netlog.corn, netlog.com +slickdeals.net, slickdeals.net +yobt.corn, yobt.com +certified-toolbar.corn, certified-toolbar.com +rniercn.corn, miercn.com +aparat.corn, aparat.com +billdesk.corn, billdesk.com +yandex.by, yandex.by +888casino.corn, 888casino.com +twitpic.corn, twitpic.com +google.hr, google.hr +tubegalore.corn, tubegalore.com +dhgate.corn, dhgate.com +rnakernytrip.corn, makemytrip.com +shop.corn, shop.com +nike.corn, nike.com +kayak.corn, kayak.com +fandango.corn, fandango.com +tutsplus.corn, tutsplus.com +gotorneeting.corn, gotomeeting.com +shareasale.corn, shareasale.com +rnpnrs.corn, mpnrs.com +keepvid.corn, keepvid.com +lequipe.fr, lequipe.fr +narnecheap.corn, namecheap.com +doublepirnp.corn, doublepimp.com +softigloo.corn, softigloo.com +givernesport.corn, givemesport.com +rntirne.corn, mtime.com +letras.rnus.br, letras.mus.br +pole-ernploi.fr, pole-emploi.fr +biblegateway.corn, biblegateway.com +independent.co.uk, independent.co.uk +e-hentai.org, e-hentai.org +gurntree.corn.au, gumtree.com.au +livestrong.corn, livestrong.com +garne32l.corn, game321.com +corncast.corn, comcast.com +clubpenguin.corn, clubpenguin.com +rightrnove.co.uk, rightmove.co.uk +stearncornrnunity.corn, steamcommunity.com +sockshare.corn, sockshare.com +globalconsurnersurvey.corn, globalconsumersurvey.com +rapidshare.corn, rapidshare.com +auto.ru, auto.ru +staples.corn, staples.com +anitube.se, anitube.se +rozblog.corn, rozblog.com +reliancenetconnect.co.in, reliancenetconnect.co.in +credit-agricole.fr, credit-agricole.fr +exposedwebcarns.corn, exposedwebcams.com +webalta.ru, webalta.ru +usbank.corn, usbank.com +google.corn.ly, google.com.ly +pantip.corn, pantip.com +aftonbladet.se, aftonbladet.se +scoop.it, scoop.it +rnayoclinic.corn, mayoclinic.com +evernote.corn, evernote.com +nyaa.eu, nyaa.eu +livingsocial.corn, livingsocial.com +noaa.gov, noaa.gov +irnagefap.corn, imagefap.com +abchina.corn, abchina.com +google.rs, google.rs +arnazon.in, amazon.in +tnaflix.corn, tnaflix.com +xici.net, xici.net +united.corn, united.com +ternplaternonster.corn, templatemonster.com +deezer.corn, deezer.com +pixlr.corn, pixlr.com +tradedoubler.corn, tradedoubler.com +gurntree.co.za, gumtree.co.za +rlO.net, r10.net +kongregate.corn, kongregate.com +jeuxvideo.corn, jeuxvideo.com +gawker.corn, gawker.com +chewen.corn, chewen.com +r2garnes.corn, r2games.com +rnayajo.corn, mayajo.com +topix.corn, topix.com +easyhits4u.corn, easyhits4u.com +netteller.corn, netteller.com +ing.nl, ing.nl +tripadvisor.co.uk, tripadvisor.co.uk +udn.corn, udn.com +cheezburger.corn, cheezburger.com +fotostrana.ru, fotostrana.ru +bbc.corn, bbc.com +behance.net, behance.net +lefigaro.fr, lefigaro.fr +nikkei.corn, nikkei.com +fidelity.corn, fidelity.com +baornihua.corn, baomihua.com +fool.corn, fool.com +nairaland.corn, nairaland.com +sendspace.corn, sendspace.com +woot.corn, woot.com +travelocity.corn, travelocity.com +shopclues.corn, shopclues.com +sureonlinefind.corn, sureonlinefind.com +gizrnodo.corn, gizmodo.com +hidernyass.corn, hidemyass.com +o2.pl, o2.pl +clickbank.net, clickbank.net +fotolia.corn, fotolia.com +opera.corn, opera.com +sabah.corn.tr, sabah.com.tr +n-rnobile.net, n-mobile.net +chacha.corn, chacha.com +autotrader.corn, autotrader.com +anonyrn.to, anonym.to +walrnart.corn.br, walmart.com.br +yjc.ir, yjc.ir +autoscout24.de, autoscout24.de +gobookee.net, gobookee.net +yaolan.corn, yaolan.com +india.corn, india.com +tribalfusion.corn, tribalfusion.com +gittigidiyor.corn, gittigidiyor.com +otto.de, otto.de +adclickxpress.corn, adclickxpress.com +rnade-in-china.corn, made-in-china.com +ahrarn.org.eg, ahram.org.eg +asriran.corn, asriran.com +blackberry.corn, blackberry.com +beytoote.corn, beytoote.com +piriforrn.corn, piriform.com +ilrneteo.it, ilmeteo.it +att.net, att.net +brainyquote.corn, brainyquote.com +last.frn, last.fm +directadvert.ru, directadvert.ru +slate.corn, slate.com +rnangahere.corn, mangahere.com +jalan.net, jalan.net +blog.corn, blog.com +tuvaro.corn, tuvaro.com +doc88.corn, doc88.com +rnbc.net, mbc.net +europa.eu, europa.eu +onlinedown.net, onlinedown.net +jcpenney.corn, jcpenney.com +rnyplaycity.corn, myplaycity.com +bahn.de, bahn.de +laredoute.fr, laredoute.fr +alexa.corn, alexa.com +flashx.tv, flashx.tv +5l.corn, 51.com +rnail.corn, mail.com +costco.corn, costco.com +rnirror.co.uk, mirror.co.uk +hubspot.corn, hubspot.com +tfl.fr, tf1.fr +rnerdeka.corn, merdeka.com +nypost.corn, nypost.com +lrnall.corn, 1mall.com +wrntransfer.corn, wmtransfer.com +pcrnag.corn, pcmag.com +univision.corn, univision.com +nationalgeographic.corn, nationalgeographic.com +sourtirnes.org, sourtimes.org +iciba.corn, iciba.com +petardas.corn, petardas.com +wrnrnail.ru, wmmail.ru +light-dark.net, light-dark.net +ultirnate-guitar.corn, ultimate-guitar.com +korarngarne.corn, koramgame.com +rnegavod.fr, megavod.fr +srnh.corn.au, smh.com.au +ticketrnaster.corn, ticketmaster.com +adrnin5.corn, admin5.com +get-a-fuck-tonight.corn, get-a-fuck-tonight.com +eenadu.net, eenadu.net +argos.co.uk, argos.co.uk +nipic.corn, nipic.com +google.iq, google.iq +alhea.corn, alhea.com +citrixonline.corn, citrixonline.com +girlsgogarnes.corn, girlsgogames.com +fanatik.corn.tr, fanatik.com.tr +google.tn, google.tn +usaa.corn, usaa.com +earthlink.net, earthlink.net +ryanair.corn, ryanair.com +city-data.corn, city-data.com +lloydstsb.co.uk, lloydstsb.co.uk +pornsharia.corn, pornsharia.com +baixing.corn, baixing.com +all-free-download.corn, all-free-download.com +qianyanOOl.corn, qianyan001.com +hellporno.corn, hellporno.com +pornrnd.corn, pornmd.com +conferenceplus.corn, conferenceplus.com +docstoc.corn, docstoc.com +christian-dogrna.corn, christian-dogma.com +drnoz.org, dmoz.org +perezhilton.corn, perezhilton.com +rnega.co.nz, mega.co.nz +zazzle.corn, zazzle.com +echoroukonline.corn, echoroukonline.com +ea.corn, ea.com +yiqifa.corn, yiqifa.com +rnysearchdial.corn, mysearchdial.com +hotwire.corn, hotwire.com +ninernsn.corn.au, ninemsn.com.au +tablica.pl, tablica.pl +brazzers.corn, brazzers.com +arnericanas.corn.br, americanas.com.br +extrernetube.corn, extremetube.com +zynga.corn, zynga.com +buscape.corn.br, buscape.com.br +t-rnobile.corn, t-mobile.com +portaldosites.corn, portaldosites.com +businessweek.corn, businessweek.com +feedburner.corn, feedburner.com +contenko.corn, contenko.com +horneshopl8.corn, homeshop18.com +brni.ir, bmi.ir +wwe.corn, wwe.com +adult-ernpire.corn, adult-empire.com +nfl.corn, nfl.com +globososo.corn, globososo.com +sfgate.corn, sfgate.com +rnrnotraffic.corn, mmotraffic.com +zalando.de, zalando.de +warthunder.corn, warthunder.com +icloud.corn, icloud.com +xiarni.corn, xiami.com +newsrnax.corn, newsmax.com +solarrnovie.so, solarmovie.so +junglee.corn, junglee.com +discovercard.corn, discovercard.com +hh.ru, hh.ru +searchengineland.corn, searchengineland.com +labanquepostale.fr, labanquepostale.fr +5lcto.corn, 51cto.com +fling.corn, fling.com +liveperson.net, liveperson.net +sulit.corn.ph, sulit.com.ph +tinypic.corn, tinypic.com +rneilishuo.corn, meilishuo.com +googleadservices.corn, googleadservices.com +boston.corn, boston.com +chron.corn, chron.com +breitbart.corn, breitbart.com +youjizzlive.corn, youjizzlive.com +cornrnbank.corn.au, commbank.com.au +axisbank.corn, axisbank.com +wired.corn, wired.com +trialpay.corn, trialpay.com +berniaga.corn, berniaga.com +cnrno.corn, cnmo.com +tunein.corn, tunein.com +hotfile.corn, hotfile.com +dubizzle.corn, dubizzle.com +olx.corn.br, olx.com.br +haxiu.corn, haxiu.com +zulily.corn, zulily.com +infolinks.corn, infolinks.com +yourgirlfriends.corn, yourgirlfriends.com +logrnein.corn, logmein.com +irs.gov, irs.gov +noticiadeldia.corn, noticiadeldia.com +nbcsports.corn, nbcsports.com +holasearch.corn, holasearch.com +indianexpress.corn, indianexpress.com +depositfiles.corn, depositfiles.com +elfagr.org, elfagr.org +hirnado.in, himado.in +lurnosity.corn, lumosity.com +rnbank.corn.pl, mbank.com.pl +prirnewire.ag, primewire.ag +drearnstirne.corn, dreamstime.com +sootoo.corn, sootoo.com +souq.corn, souq.com +craigslist.ca, craigslist.ca +zara.corn, zara.com +groupon.it, groupon.it +rnangafox.rne, mangafox.me +casino.corn, casino.com +arrnorgarnes.corn, armorgames.com +zanox.corn, zanox.com +finn.no, finn.no +qihoo.corn, qihoo.com +toysrus.corn, toysrus.com +airasia.corn, airasia.com +dafont.corn, dafont.com +tvrnuse.eu, tvmuse.eu +pnc.corn, pnc.com +donanirnhaber.corn, donanimhaber.com +cnbeta.corn, cnbeta.com +prntscr.corn, prntscr.com +cox.net, cox.net +bloglovin.corn, bloglovin.com +picrnonkey.corn, picmonkey.com +zoho.corn, zoho.com +glassdoor.corn, glassdoor.com +rnyfitnesspal.corn, myfitnesspal.com +change.org, change.org +aa.corn, aa.com +playstation.corn, playstation.com +bl.org, b1.org +correios.corn.br, correios.com.br +hindustantirnes.corn, hindustantimes.com +softlayer.corn, softlayer.com +irnagevenue.corn, imagevenue.com +windowsphone.corn, windowsphone.com +wikirnapia.org, wikimapia.org +transferrnarkt.de, transfermarkt.de +dict.cc, dict.cc +blocket.se, blocket.se +lacaixa.es, lacaixa.es +hilton.corn, hilton.com +rntv.corn, mtv.com +cbc.ca, cbc.ca +rnsn.ca, msn.ca +box.corn, box.com +szn.cz, szn.cz +haodf.corn, haodf.com +rnonsterindia.corn, monsterindia.com +okezone.corn, okezone.com +entertainrnent-factory.corn, entertainment-factory.com +linternaute.corn, linternaute.com +break.corn, break.com +ustrearn.tv, ustream.tv +songspk.narne, songspk.name +bilibili.tv, bilibili.tv +avira.corn, avira.com +thehindu.corn, thehindu.com +watchrnygf.corn, watchmygf.com +google.co.rna, google.co.ma +nick.corn, nick.com +sp.gov.br, sp.gov.br +zeobit.corn, zeobit.com +sprint.corn, sprint.com +khabaronline.ir, khabaronline.ir +rnagentocornrnerce.corn, magentocommerce.com +hsbc.co.uk, hsbc.co.uk +trafficholder.corn, trafficholder.com +garnestop.corn, gamestop.com +cartoonnetwork.corn, cartoonnetwork.com +fifa.corn, fifa.com +ebay.ca, ebay.ca +vatanirn.corn.tr, vatanim.com.tr +qvc.corn, qvc.com +rnarriott.corn, marriott.com +eventbrite.corn, eventbrite.com +gi-akadernie.corn, gi-akademie.com +intel.corn, intel.com +oschina.net, oschina.net +dojki.corn, dojki.com +thechive.corn, thechive.com +viadeo.corn, viadeo.com +walgreens.corn, walgreens.com +leo.org, leo.org +statscrop.corn, statscrop.com +brothersoft.corn, brothersoft.com +allocine.fr, allocine.fr +slutload.corn, slutload.com +google.corn.gt, google.com.gt +santabanta.corn, santabanta.com +stardoll.corn, stardoll.com +polyvore.corn, polyvore.com +focus.de, focus.de +duckduckgo.corn, duckduckgo.com +funshion.corn, funshion.com +rnarieclairechina.corn, marieclairechina.com +internethaber.corn, internethaber.com +worldoftanks.ru, worldoftanks.ru +lundl.de, 1und1.de +anyporn.corn, anyporn.com +cars.corn, cars.com +asg.to, asg.to +alice.it, alice.it +hongkiat.corn, hongkiat.com +bhphotovideo.corn, bhphotovideo.com +bdnews24.corn, bdnews24.com +sdo.corn, sdo.com +cerdas.corn, cerdas.com +clarin.corn, clarin.com +victoriassecret.corn, victoriassecret.com +instructables.corn, instructables.com +state.gov, state.gov +agarne.corn, agame.com +xiaorni.corn, xiaomi.com +adfoc.us, adfoc.us +telekorn.corn, telekom.com +skycn.corn, skycn.com +orbitz.corn, orbitz.com +nhl.corn, nhl.com +vistaprint.corn, vistaprint.com +trklnks.corn, trklnks.com +basecarnp.corn, basecamp.com +hot-sex-tube.corn, hot-sex-tube.com +incredibar-search.corn, incredibar-search.com +qingdaonews.corn, qingdaonews.com +sabq.org, sabq.org +nasa.gov, nasa.gov +dx.corn, dx.com +addrnefast.corn, addmefast.com +yepi.corn, yepi.com +xxx-ok.corn, xxx-ok.com +sex.corn, sex.com +food.corn, food.com +freeones.corn, freeones.com +tesco.corn, tesco.com +alO.corn, a10.com +abc.net.au, abc.net.au +internetdownloadrnanager.corn, internetdownloadmanager.com +seowhy.corn, seowhy.com +otornoto.pl, otomoto.pl +idealo.de, idealo.de +laposte.net, laposte.net +eroprofile.corn, eroprofile.com +bbb.org, bbb.org +tiu.ru, tiu.ru +blogsky.corn, blogsky.com +bigfishgarnes.corn, bigfishgames.com +weiphone.corn, weiphone.com +livescore.corn, livescore.com +tubepleasure.corn, tubepleasure.com +jagran.corn, jagran.com +livestrearn.corn, livestream.com +stagrarn.corn, stagram.com +vine.co, vine.co +olx.corn.pk, olx.com.pk +edrnunds.corn, edmunds.com +banglanews24.corn, banglanews24.com +reverso.net, reverso.net +stargarnes.at, stargames.at +postirng.org, postimg.org +overthurnbs.corn, overthumbs.com +iteye.corn, iteye.com +yify-torrents.corn, yify-torrents.com +forexfactory.corn, forexfactory.com +hefei.cc, hefei.cc +thefreecarnsecret.corn, thefreecamsecret.com +lanacion.corn.ar, lanacion.com.ar +jeu-a-telecharger.corn, jeu-a-telecharger.com +spartoo.corn, spartoo.com +adv-adserver.corn, adv-adserver.com +asus.corn, asus.com +9l.corn, 91.com +wirnbledon.corn, wimbledon.com +yarn.corn, yam.com +grooveshark.corn, grooveshark.com +tdcanadatrust.corn, tdcanadatrust.com +lovetirne.corn, lovetime.com +iltalehti.fi, iltalehti.fi +alnaddy.corn, alnaddy.com +bb.corn.br, bb.com.br +tebyan.net, tebyan.net +redbox.corn, redbox.com +filecrop.corn, filecrop.com +aliyun.corn, aliyun.com +2lcn.corn, 21cn.com +news24.corn, news24.com +infowars.corn, infowars.com +thetaoofbadass.corn, thetaoofbadass.com +juegos.corn, juegos.com +p5w.net, p5w.net +vg.no, vg.no +discovery.corn, discovery.com +gazzetta.it, gazzetta.it +tvguide.corn, tvguide.com +khabarfarsi.corn, khabarfarsi.com +bradesco.corn.br, bradesco.com.br +autotrader.co.uk, autotrader.co.uk +wetransfer.corn, wetransfer.com +jinti.corn, jinti.com +xharnsterhq.corn, xhamsterhq.com +appround.net, appround.net +lotour.corn, lotour.com +reverbnation.corn, reverbnation.com +thedailybeast.corn, thedailybeast.com +vente-privee.corn, vente-privee.com +subscribe.ru, subscribe.ru +rnarketgid.corn, marketgid.com +super.cz, super.cz +jvzoo.corn, jvzoo.com +shine.corn, shine.com +screencast.corn, screencast.com +picofile.corn, picofile.com +rnanorarnaonline.corn, manoramaonline.com +kbb.corn, kbb.com +seasonvar.ru, seasonvar.ru +android.corn, android.com +egrana.corn.br, egrana.com.br +ettoday.net, ettoday.net +webstatsdornain.net, webstatsdomain.net +haberler.corn, haberler.com +vesti.ru, vesti.ru +fastpic.ru, fastpic.ru +dpreview.corn, dpreview.com +google.si, google.si +ouedkniss.corn, ouedkniss.com +crackle.corn, crackle.com +chefkoch.de, chefkoch.de +rnogujie.corn, mogujie.com +brassring.corn, brassring.com +govorne.corn, govome.com +copyscape.corn, copyscape.com +rninecraftforurn.net, minecraftforum.net +rnit.edu, mit.edu +cvs.corn, cvs.com +tirnesjobs.corn, timesjobs.com +ksl.corn, ksl.com +verizon.net, verizon.net +direct.gov.uk, direct.gov.uk +rniralinks.ru, miralinks.ru +elheddaf.corn, elheddaf.com +stockphoto9.corn, stockphoto9.com +ashernaletube.corn, ashemaletube.com +drnrn.corn, dmm.com +abckjl23.corn, abckj123.com +srnzdrn.corn, smzdm.com +cox.corn, cox.com +welt.de, welt.de +guyspy.corn, guyspy.com +rnakeuseof.corn, makeuseof.com +tiscali.it, tiscali.it +l78.corn, 178.com +rnetrolyrics.corn, metrolyrics.com +vsuch.corn, vsuch.com +seosprint.net, seosprint.net +sarnanyoluhaber.corn, samanyoluhaber.com +garanti.corn.tr, garanti.com.tr +chicagotribune.corn, chicagotribune.com +hinet.net, hinet.net +kp.ru, kp.ru +chornikuj.pl, chomikuj.pl +nk.pl, nk.pl +webhostingtalk.corn, webhostingtalk.com +dnaindia.corn, dnaindia.com +prograrnrne-tv.net, programme-tv.net +ievbz.corn, ievbz.com +rnysql.corn, mysql.com +perfectrnoney.is, perfectmoney.is +liveundnackt.corn, liveundnackt.com +flippa.corn, flippa.com +vevo.corn, vevo.com +jappy.de, jappy.de +bidvertiser.corn, bidvertiser.com +bankrnandiri.co.id, bankmandiri.co.id +letour.fr, letour.fr +yr.no, yr.no +suning.corn, suning.com +nosub.tv, nosub.tv +delicious.corn, delicious.com +pornpoly.corn, pornpoly.com +echo.rnsk.ru, echo.msk.ru +coingeneration.corn, coingeneration.com +shutterfly.corn, shutterfly.com +royalbank.corn, royalbank.com +techradar.corn, techradar.com +ll4la.corn, 114la.com +bizrate.corn, bizrate.com +srvey.net, srvey.net +heavy-r.corn, heavy-r.com +telexfree.corn, telexfree.com +lego.corn, lego.com +battlefield.corn, battlefield.com +shahrekhabar.corn, shahrekhabar.com +tuenti.corn, tuenti.com +bookrnyshow.corn, bookmyshow.com +ft.corn, ft.com +prweb.corn, prweb.com +l337x.org, 1337x.org +networkedblogs.corn, networkedblogs.com +pbskids.org, pbskids.org +aipai.corn, aipai.com +jang.corn.pk, jang.com.pk +dribbble.corn, dribbble.com +ezdownloadpro.info, ezdownloadpro.info +gonzoxxxrnovies.corn, gonzoxxxmovies.com +auferninin.corn, aufeminin.com +6prn.corn, 6pm.com +azet.sk, azet.sk +trustedoffer.corn, trustedoffer.com +sirnplyhired.corn, simplyhired.com +adserverpub.corn, adserverpub.com +privalia.corn, privalia.com +bedbathandbeyond.corn, bedbathandbeyond.com +yyets.corn, yyets.com +verycd.corn, verycd.com +sbnation.corn, sbnation.com +blogspot.nl, blogspot.nl +ikariarn.corn, ikariam.com +sitepoint.corn, sitepoint.com +gazeta.ru, gazeta.ru +tataindicorn.corn, tataindicom.com +chekb.corn, chekb.com +literotica.corn, literotica.com +ah-rne.corn, ah-me.com +eztv.it, eztv.it +onliner.by, onliner.by +pptv.corn, pptv.com +rnacrurnors.corn, macrumors.com +xvideo-jp.corn, xvideo-jp.com +state.tx.us, state.tx.us +jarnnews.ir, jamnews.ir +etoro.corn, etoro.com +ny.gov, ny.gov +searchenginewatch.corn, searchenginewatch.com +google.co.cr, google.co.cr +td.corn, td.com +ahrefs.corn, ahrefs.com +337.corn, 337.com +klout.corn, klout.com +ebay.es, ebay.es +theverge.corn, theverge.com +kapook.corn, kapook.com +barclays.co.uk, barclays.co.uk +nuorni.corn, nuomi.com +index-of-rnp3s.corn, index-of-mp3s.com +ohfreesex.corn, ohfreesex.com +rnts.ru, mts.ru +instantcheckrnate.corn, instantcheckmate.com +sport.es, sport.es +sitescout.corn, sitescout.com +irr.ru, irr.ru +tuniu.corn, tuniu.com +startirnes.corn, startimes.com +tvn24.pl, tvn24.pl +kenhl4.vn, kenh14.vn +rnyvideo.de, myvideo.de +speedbit.corn, speedbit.com +aljazeera.corn, aljazeera.com +pudelek.pl, pudelek.pl +rnrngp.ru, mmgp.ru +ernpflix.corn, empflix.com +tigerdirect.corn, tigerdirect.com +elegantthernes.corn, elegantthemes.com +ted.corn, ted.com +downloads.corn, down1oads.com +bancobrasil.corn.br, bancobrasil.com.br +qip.ru, qip.ru +fapdu.corn, fapdu.com +softango.corn, softango.com +ap.org, ap.org +rneteofrance.corn, meteofrance.com +gentenocturna.corn, gentenocturna.com +2ch-c.net, 2ch-c.net +orf.at, orf.at +rnaybank2u.corn.rny, maybank2u.com.my +rninecraftwiki.net, minecraftwiki.net +tv.corn, tv.com +orkut.corn, orkut.com +adp.corn, adp.com +woorank.corn, woorank.com +irnagetwist.corn, imagetwist.com +pastebin.corn, pastebin.com +airtel.corn, airtel.com +ew.corn, ew.com +forever2l.corn, forever21.com +adarn4adarn.corn, adam4adam.com +voyages-sncf.corn, voyages-sncf.com +nextag.corn, nextag.com +usnews.corn, usnews.com +dinarnalar.corn, dinamalar.com +virginrnedia.corn, virginmedia.com +investopedia.corn, investopedia.com +seekingalpha.corn, seekingalpha.com +jurnponhottie.corn, jumponhottie.com +national-lottery.co.uk, national-lottery.co.uk +rnobifiesta.corn, mobifiesta.com +kapanlagi.corn, kapanlagi.com +segundarnano.es, segundamano.es +gfan.corn, gfan.com +xdating.corn, xdating.com +ynet.corn, ynet.com +rnedu.ir, medu.ir +hsn.corn, hsn.com +newsru.corn, newsru.com +rninus.corn, minus.com +sitetalk.corn, sitetalk.com +aarp.org, aarp.org +clickpaid.corn, clickpaid.com +panorarnio.corn, panoramio.com +webcarno.corn, webcamo.com +yobt.tv, yobt.tv +slutfinder.corn, slutfinder.com +freelotto.corn, freelotto.com +rnudah.rny, mudah.my +toptenreviews.corn, toptenreviews.com +caisse-epargne.fr, caisse-epargne.fr +wirnp.corn, wimp.com +woothernes.corn, woothemes.com +css-tricks.corn, css-tricks.com +coolrnath-garnes.corn, coolmath-games.com +tagu.corn.ar, tagu.com.ar +sheknows.corn, sheknows.com +advancedfileoptirnizer.corn, advancedfileoptimizer.com +drupal.org, drupal.org +centrurn.cz, centrum.cz +charter.net, charter.net +adxhosting.net, adxhosting.net +squarespace.corn, squarespace.com +traderne.co.nz, trademe.co.nz +sitesell.corn, sitesell.com +birthrecods.corn, birthrecods.com +rnegashare.info, megashare.info +freepornvs.corn, freepornvs.com +isna.ir, isna.ir +ziddu.corn, ziddu.com +airtelforurn.corn, airtelforum.com +justin.tv, justin.tv +Olnet.corn, 01net.com +ed.gov, ed.gov +no-ip.corn, no-ip.com +nikkansports.corn, nikkansports.com +srnashingrnagazine.corn, smashingmagazine.com +salon.corn, salon.com +nrnisr.corn, nmisr.com +wanggou.corn, wanggou.com +bayt.corn, bayt.com +codeproject.corn, codeproject.com +downloadha.corn, downloadha.com +local.corn, local.com +abola.pt, abola.pt +delta-hornes.corn, delta-homes.com +filrnweb.pl, filmweb.pl +gov.uk, gov.uk +worldoftanks.eu, worldoftanks.eu +ads-id.corn, ads-id.com +sergey-rnavrodi.corn, sergey-mavrodi.com +pornoid.corn, pornoid.com +freakshare.corn, freakshare.com +5lfanli.corn, 51fanli.com +bankrate.corn, bankrate.com +grindtv.corn, grindtv.com +webrnasterworld.corn, webmasterworld.com +torrentz.in, torrentz.in +bwin.corn, bwin.com +watchtower.corn, watchtower.com +payza.corn, payza.com +anz.corn, anz.com +vagalurne.corn.br, vagalume.com.br +ozon.ru, ozon.ru +tonicrnovies.corn, tonicmovies.com +arbeitsagentur.de, arbeitsagentur.de +graphicriver.net, graphicriver.net +theweathernetwork.corn, theweathernetwork.com +sarnsclub.corn, samsclub.com +tribunnews.corn, tribunnews.com +soldonsrnart.corn, soldonsmart.com +tut.by, tut.by +voila.fr, voila.fr +doctissirno.fr, doctissimo.fr +sueddeutsche.de, sueddeutsche.de +rnarnba.ru, mamba.ru +krnart.corn, kmart.com +abc.es, abc.es +rnanager.co.th, manager.co.th +spokeo.corn, spokeo.com +apache.org, apache.org +tdbank.corn, tdbank.com +asklaila.corn, asklaila.com +adrnin5.net, admin5.net +rtve.es, rtve.es +ynet.co.il, ynet.co.il +infospace.corn, infospace.com +yirng.corn, yimg.com +torcache.net, torcache.net +zap2it.corn, zap2it.com +srnallseotools.corn, smallseotools.com +privatbank.ua, privatbank.ua +nnrn-club.ru, nnm-club.ru +payoneer.corn, payoneer.com +bidorbuy.co.za, bidorbuy.co.za +islarnweb.net, islamweb.net +juicyads.corn, juicyads.com +vid2c.corn, vid2c.com +dnsrsearch.corn, dnsrsearch.com +the-bux.net, the-bux.net +yaplakal.corn, yaplakal.com +ex.ua, ex.ua +rntsindia.in, mtsindia.in +reclarneaqui.corn.br, reclameaqui.com.br +postbank.de, postbank.de +gogvo.corn, gogvo.com +bearshare.net, bearshare.net +socialsex.corn, socialsex.com +yebhi.corn, yebhi.com +rnktrnobi.corn, mktmobi.com +dfiles.eu, dfiles.eu +citibank.co.in, citibank.co.in +garnersky.corn, gamersky.com +kotaku.corn, kotaku.com +tearnviewer.corn, teamviewer.com +kwejk.pl, kwejk.pl +harnariweb.corn, hamariweb.com +torn.corn, tom.com +gayrorneo.corn, gayromeo.com +sony.corn, sony.com +westpac.corn.au, westpac.com.au +gtrnetrix.corn, gtmetrix.com +shorouknews.corn, shorouknews.com +xl.pt, xl.pt +networksolutions.corn, networksolutions.com +5OOpx.corn, 500px.com +yprnate.corn, ypmate.com +indowebster.corn, indowebster.com +sports.ru, sports.ru +netshoes.corn.br, netshoes.com.br +dfiles.ru, dfiles.ru +cpasbien.rne, cpasbien.me +webgarne.web.id, webgame.web.id +tuto4pc.corn, tuto4pc.com +poponclick.corn, poponclick.com +cornplex.corn, complex.com +sakshi.corn, sakshi.com +infobae.corn, infobae.com +sify.corn, sify.com +4pda.ru, 4pda.ru +starsue.net, starsue.net +newgrounds.corn, newgrounds.com +rnehrnews.corn, mehrnews.com +depositphotos.corn, depositphotos.com +keek.corn, keek.com +indeed.co.in, indeed.co.in +stanford.edu, stanford.edu +hepsiburada.corn, hepsiburada.com +2Orninutos.es, 20minutos.es +paper.li, paper.li +prizee.corn, prizee.com +xlovecarn.corn, xlovecam.com +criteo.corn, criteo.com +endlessrnatches.corn, endlessmatches.com +dyndns.org, dyndns.org +lightinthebox.corn, lightinthebox.com +easyjet.corn, easyjet.com +vice.corn, vice.com +tiexue.net, tiexue.net +rnonsterrnarketplace.corn, monstermarketplace.com +rnojang.corn, mojang.com +carns.corn, cams.com +pingdorn.corn, pingdom.com +askrnen.corn, askmen.com +list-rnanagel.corn, list-manage1.com +express.corn.pk, express.com.pk +pricerninister.corn, priceminister.com +duba.corn, duba.com +rneinestadt.de, meinestadt.de +rnediatakeout.corn, mediatakeout.com +terere.info, terere.info +strearnate.corn, streamate.com +garrnin.corn, garmin.com +a-telecharger.corn, a-telecharger.com +vipzona.info, vipzona.info +coffetube.corn, coffetube.com +discuz.net, discuz.net +directv.corn, directv.com +foreningssparbanken.se, foreningssparbanken.se +fatwallet.corn, fatwallet.com +rnackolik.corn, mackolik.com +rnegacinerna.fr, megacinema.fr +chess.corn, chess.com +suntrust.corn, suntrust.com +investing.corn, investing.com +whois.corn, whois.com +durnrnies.corn, dummies.com +yinyuetai.corn, yinyuetai.com +rnihandownload.corn, mihandownload.com +freapp.corn, freapp.com +theage.corn.au, theage.com.au +audible.corn, audible.com +hotelurbano.corn.br, hotelurbano.com.br +vatgia.corn, vatgia.com +wizardlOl.corn, wizard101.com +ceneo.pl, ceneo.pl +lting.corn, 1ting.com +rneetic.fr, meetic.fr +cardekho.corn, cardekho.com +tripadvisor.it, tripadvisor.it +dhl.corn, dhl.com +aibang.corn, aibang.com +asp.net, asp.net +toing.corn.br, toing.com.br +zhubajie.corn, zhubajie.com +telecornitalia.it, telecomitalia.it +claro-search.corn, claro-search.com +nickjr.corn, nickjr.com +iconfinder.corn, iconfinder.com +rnobile9.corn, mobile9.com +cisco.corn, cisco.com +cpanel.net, cpanel.net +indiegogo.corn, indiegogo.com +egotastic.corn, egotastic.com +hforcare.corn, hforcare.com +pbs.org, pbs.org +realestate.corn.au, realestate.com.au +abv.bg, abv.bg +drugs.corn, drugs.com +bt.corn, bt.com +wildberries.ru, wildberries.ru +edrearns.it, edreams.it +statigr.arn, statigr.am +prestashop.corn, prestashop.com +adxite.corn, adxite.com +birthdaypeorns.corn, birthdaypeoms.com +exbii.corn, exbii.com +blogrnura.corn, blogmura.com +sciencedirect.corn, sciencedirect.com +sanspo.corn, sanspo.com +nextrnedia.corn, nextmedia.com +tvoyauda4a.ru, tvoyauda4a.ru +tangdou.corn, tangdou.com +blackboard.corn, blackboard.com +qiyou.corn, qiyou.com +prezentacya.ru, prezentacya.ru +clicrbs.corn.br, clicrbs.com.br +wayfair.corn, wayfair.com +xvideos-field.corn, xvideos-field.com +national.corn.au, national.com.au +friendfeed.corn, friendfeed.com +plurk.corn, plurk.com +lolrnake.corn, lolmake.com +b9drn.corn, b9dm.com +afkarnews.ir, afkarnews.ir +dhl.de, dhl.de +charnpionat.corn, championat.com +rnoviefone.corn, moviefone.com +popcash.net, popcash.net +cliphunter.corn, cliphunter.com +sharebeast.corn, sharebeast.com +wowhead.corn, wowhead.com +firstpost.corn, firstpost.com +lloydstsb.corn, lloydstsb.com +fazenda.gov.br, fazenda.gov.br +lonelyplanet.corn, lonelyplanet.com +freenet.de, freenet.de +justanswer.corn, justanswer.com +qiwi.corn, qiwi.com +shufuni.corn, shufuni.com +drive2.ru, drive2.ru +slando.ua, slando.ua +caribbeancorn.corn, caribbeancom.com +uniblue.corn, uniblue.com +real.corn, real.com +addictinggarnes.corn, addictinggames.com +wnd.corn, wnd.com +col3negoriginal.org, col3negoriginal.org +loltrk.corn, loltrk.com +videodownloadconverter.corn, videodownloadconverter.com +google.lv, google.lv +seriesyonkis.corn, seriesyonkis.com +ryushare.corn, ryushare.com +sl979.corn, s1979.com +cheapoair.corn, cheapoair.com +subrnarino.corn.br, submarino.com.br +topface.corn, topface.com +hotelscornbined.corn, hotelscombined.com +whatisrnyipaddress.corn, whatismyipaddress.com +z6.corn, z6.com +sozcu.corn.tr, sozcu.com.tr +sonyrnobile.corn, sonymobile.com +planetrninecraft.corn, planetminecraft.com +optirnurn.net, optimum.net +google.corn.pr, google.com.pr +rnthai.corn, mthai.com +onlinecreditcenter6.corn, onlinecreditcenter6.com +tharunaya.co.uk, tharunaya.co.uk +sfirng.corn, sfimg.com +natwest.corn, natwest.com +zergnet.corn, zergnet.com +alotporn.corn, alotporn.com +urbanspoon.corn, urbanspoon.com +punishtube.corn, punishtube.com +proboards.corn, proboards.com +betfair.corn, betfair.com +iltasanornat.fi, iltasanomat.fi +ssisurveys.corn, ssisurveys.com +harvard.edu, harvard.edu +blic.rs, blic.rs +clicksia.corn, clicksia.com +skillpages.corn, skillpages.com +rnobilewap.corn, mobilewap.com +fiducia.de, fiducia.de +torntvz.org, torntvz.org +leparisien.fr, leparisien.fr +anjuke.corn, anjuke.com +rabobank.nl, rabobank.nl +sport.pl, sport.pl +schwab.corn, schwab.com +buenastareas.corn, buenastareas.com +befuck.corn, befuck.com +srnart-search.corn, smart-search.com +ivi.ru, ivi.ru +dvdvideosoft.corn, dvdvideosoft.com +ubi.corn, ubi.com +rnakepolo.corn, makepolo.com +landl.corn, 1and1.com +pcworld.corn, pcworld.com +caf.fr, caf.fr +fnb.co.za, fnb.co.za +vanguardngr.corn, vanguardngr.com +floozycity.corn, floozycity.com +ubuntu.corn, ubuntu.com +rny-link.pro, my-link.pro +centurylink.corn, centurylink.com +slashdot.org, slashdot.org +rnirrorcreator.corn, mirrorcreator.com +rutube.ru, rutube.ru +tubeplus.rne, tubeplus.me +kicker.de, kicker.de +unibet.corn, unibet.com +pornyaz.corn, pornyaz.com +learntotradethernarket.corn, learntotradethemarket.com +tokyo-porn-tube.corn, tokyo-porn-tube.com +luvcow.corn, luvcow.com +i.ua, i.ua +ole.corn.ar, ole.com.ar +redfin.corn, redfin.com +cnki.net, cnki.net +2shared.corn, 2shared.com +infibearn.corn, infibeam.com +zdnet.corn, zdnet.com +fishki.net, fishki.net +ukr.net, ukr.net +jiarneng.corn, jiameng.com +utorrent.corn, utorrent.com +elkhabar.corn, elkhabar.com +anirne44.corn, anime44.com +societegenerale.fr, societegenerale.fr +livernerne.corn, livememe.com +startertv.fr, startertv.fr +pingornatic.corn, pingomatic.com +indeed.co.uk, indeed.co.uk +dpstrearn.net, dpstream.net +rnundodeportivo.corn, mundodeportivo.com +gravatar.corn, gravatar.com +ipl38.corn, ip138.com +yandex.net, yandex.net +barbie.corn, barbie.com +wattpad.corn, wattpad.com +dzwww.corn, dzwww.com +technorati.corn, technorati.com +rneishichina.corn, meishichina.com +russianpost.ru, russianpost.ru +kboing.corn.br, kboing.com.br +lzjl.corn, lzjl.com +newsnow.co.uk, newsnow.co.uk +dw.de, dw.de +inetglobal.corn, inetglobal.com +tripadvisor.in, tripadvisor.in +ashleyrnadison.corn, ashleyrnadison.com +rapgenius.corn, rapgenius.com +xuite.net, xuite.net +nowvideo.eu, nowvideo.eu +search.us.corn, search.us.com +usagc.org, usagc.org +santander.co.uk, santander.co.uk +99acres.corn, 99acres.com +bigcartel.corn, bigcartel.com +haivl.corn, haivl.com +jsfiddle.net, jsfiddle.net +io9.corn, io9.com +lg.corn, lg.com +veoh.corn, veoh.com +dafiti.corn.br, dafiti.com.br +heise.de, heise.de +wikispaces.corn, wikispaces.com +google.corn.bo, google.com.bo +skyscrapercity.corn, skyscrapercity.com +zaobao.corn, zaobao.com +pirateproxy.net, pirateproxy.net +rnuyzorras.corn, muyzorras.com +entrepreneur.corn, entrepreneur.com +sxc.hu, sxc.hu +superuser.corn, superuser.com +jb5l.net, jb51.net +bitsnoop.corn, bitsnoop.com +index.hu, index.hu +tubexclips.corn, tubexclips.com +syrnantec.corn, symantec.com +sedo.corn, sedo.com +gongchang.corn, gongchang.com +newsrnth.net, newsmth.net +srclick.ru, srclick.ru +bornnegocio.corn, bomnegocio.com +ornegle.corn, omegle.com +sweetpacks-search.corn, sweetpacks-search.com +OOOwebhost.corn, 000webhost.com +rencontreshard.corn, rencontreshard.com +jurnei.corn, jumei.com +acfun.tv, acfun.tv +celebuzz.corn, celebuzz.com +el-balad.corn, el-balad.com +wajarn.corn, wajam.com +zoopla.co.uk, zoopla.co.uk +sc4888.corn, sc4888.com +rnobileaziende.it, mobileaziende.it +officialsurvey.org, officialsurvey.org +googleapis.corn, googleapis.com +jobsdb.corn, jobsdb.com +google.corn.sv, google.com.sv +freejobalert.corn, freejobalert.com +walla.co.il, walla.co.il +hollywoodreporter.corn, hollywoodreporter.com +inc.corn, inc.com +bbandt.corn, bbandt.com +williarnhill.corn, williamhill.com +jeu.info, jeu.info +vrbo.corn, vrbo.com +arabseed.corn, arabseed.com +spielaffe.de, spielaffe.de +wykop.pl, wykop.pl +narne.corn, name.com +web-opinions.corn, web-opinions.com +ehowenespanol.corn, ehowenespanol.com +uuzu.corn, uuzu.com +cafepress.corn, cafepress.com +beeline.ru, beeline.ru +searchenginejournal.corn, searchenginejournal.com +webex.corn, webex.com +zerohedge.corn, zerohedge.com +cityads.ru, cityads.ru +colurnbia.edu, columbia.edu +jia.corn, jia.com +tistory.corn, tistory.com +lOObestbuy.corn, 100bestbuy.com +realitykings.corn, realitykings.com +shopify.corn, shopify.com +garnetop.corn, gametop.com +eharrnony.corn, eharmony.com +ngoisao.net, ngoisao.net +angieslist.corn, angieslist.com +grotal.corn, grotal.com +rnanhunt.net, manhunt.net +adslgate.corn, adslgate.com +dernotywatory.pl, demotywatory.pl +enfernenino.corn, enfemenino.com +yallakora.corn, yallakora.com +careesrna.in, careesma.in +draugiern.lv, draugiem.lv +greatandhra.corn, greatandhra.com +lifescript.corn, lifescript.com +androidcentral.corn, androidcentral.com +wiley.corn, wiley.com +alot.corn, alot.com +lOOlO.corn, 10010.com +next.co.uk, next.co.uk +ll5.corn, 115.com +orngprn.corn, omgpm.com +rnycalendarbook.corn, mycalendarbook.com +playxn.corn, playxn.com +niksalehi.corn, niksalehi.com +serviporno.corn, serviporno.com +poste.it, poste.it +kirniss.corn, kimiss.com +bearshare.corn, bearshare.com +clickpoint.corn, clickpoint.com +seek.corn.au, seek.com.au +bab.la, bab.la +ads8.corn, ads8.com +viewster.corn, viewster.com +ideacellular.corn, ideacellular.com +tyrnpanus.net, tympanus.net +wwwblogto.corn, wwwblogto.com +tblop.corn, tblop.com +elong.corn, elong.com +funnyordie.corn, funnyordie.com +radikal.ru, radikal.ru +rk.corn, rk.com +alarab.net, alarab.net +willhaben.at, willhaben.at +beyond.corn, beyond.com +punchng.corn, punchng.com +viglink.corn, viglink.com +rnicrosoftstore.corn, microsoftstore.com +tripleclicks.corn, tripleclicks.com +rnl9O5.corn, m1905.com +ofreegarnes.corn, ofreegames.com +s2d6.corn, s2d6.com +36Obuy.corn, 360buy.com +rakuten.corn, rakuten.com +evite.corn, evite.com +kornpasiana.corn, kompasiana.com +dailycaller.corn, dailycaller.com +holidaycheck.de, holidaycheck.de +irnvu.corn, imvu.com +nate.corn, nate.com +fnac.corn, fnac.com +htc.corn, htc.com +savenkeep.corn, savenkeep.com +alfabank.ru, alfabank.ru +zaycev.net, zaycev.net +vidtornp3.corn, vidtomp3.com +eluniversal.corn.rnx, eluniversal.com.mx +theatlantic.corn, theatlantic.com +garnigo.de, gamigo.de +lolking.net, lolking.net +wer-kennt-wen.de, wer-kennt-wen.de +stern.de, stern.de +sportl.de, sport1.de +goalunited.org, goalunited.org +discogs.corn, discogs.com +whirlpool.net.au, whirlpool.net.au +savefrorn.net, savefrom.net +eurosport.fr, eurosport.fr +juegosjuegos.corn, juegosjuegos.com +open24news.tv, open24news.tv +sinaapp.corn, sinaapp.com +fuq.corn, fuq.com +index.hr, index.hr +realpopbid.corn, realpopbid.com +rollingstone.corn, rollingstone.com +globaltestrnarket.corn, globaltestmarket.com +seopult.ru, seopult.ru +wurnii.corn, wumii.com +ford.corn, ford.com +cabelas.corn, cabelas.com +securepaynet.net, securepaynet.net +zhibo8.cc, zhibo8.cc +jiji.corn, jiji.com +gezinti.corn, gezinti.com +rneb.gov.tr, meb.gov.tr +classifiedads.corn, classifiedads.com +kitco.corn, kitco.com +incredirnail.corn, incredimail.com +esrnas.corn, esmas.com +soccerway.corn, soccerway.com +rivals.corn, rivals.com +prezi.corn, prezi.com +shopping.corn, shopping.com +superjob.ru, superjob.ru +chinaacc.corn, chinaacc.com +arnoureux.corn, amoureux.com +rnysrnartprice.corn, mysmartprice.com +eleconornista.es, eleconomista.es +rnercola.corn, mercola.com +irnlive.corn, imlive.com +teacup.corn, teacup.com +rnodelrnayhern.corn, modelmayhem.com +nic.ru, nic.ru +brazzersnetwork.corn, brazzersnetwork.com +everything.org.uk, everything.org.uk +bhg.corn, bhg.com +longhoo.net, longhoo.net +superpages.corn, superpages.com +tny.cz, tny.cz +yourfilezone.corn, yourfilezone.com +tuan8OO.corn, tuan800.com +streev.corn, streev.com +sedty.corn, sedty.com +boxofficernojo.corn, boxofficemojo.com +hollyscoop.corn, hollyscoop.com +safecart.corn, safecart.com +alrnogaz.corn, almogaz.com +cashnhits.corn, cashnhits.com +wetplace.corn, wetplace.com +freepik.corn, freepik.com +rarbg.corn, rarbg.com +xxxbunker.corn, xxxbunker.com +prchecker.info, prchecker.info +halifax-online.co.uk, halifax-online.co.uk +trafficfactory.biz, trafficfactory.biz +telecinco.es, telecinco.es +searchterrnresults.corn, searchtermresults.com +unarn.rnx, unam.mx +akhbar-elwatan.corn, akhbar-elwatan.com +lynda.corn, lynda.com +yougetlaid.corn, yougetlaid.com +srnart.corn.au, smart.com.au +advfn.corn, advfn.com +unicredit.it, unicredit.it +zornato.corn, zomato.com +flirt.corn, flirt.com +netease.corn, netease.com +bnpparibas.net, bnpparibas.net +elcornercio.pe, elcomercio.pe +rnathrubhurni.corn, mathrubhumi.com +koyotesoft.corn, koyotesoft.com +filrnix.net, filmix.net +xnxxhdtube.corn, xnxxhdtube.com +ennaharonline.corn, ennaharonline.com +junbi-tracker.corn, junbi-tracker.com +buzzdock.corn, buzzdock.com +ernirates.corn, emirates.com +vivanuncios.corn.rnx, vivanuncios.com.mx +infojobs.net, infojobs.net +srni2.ru, smi2.ru +lotterypost.corn, lotterypost.com +bandcarnp.corn, bandcamp.com +ekstrabladet.dk, ekstrabladet.dk +nownews.corn, nownews.com +bc.vc, bc.vc +google.corn.af, google.com.af +ulrnart.ru, ulmart.ru +estadao.corn.br, estadao.com.br +politico.corn, politico.com +kl688.corn, kl688.com +resellerclub.corn, resellerclub.com +whois.net, whois.net +seobuilding.ru, seobuilding.ru +t4ll.rne, t411.me +googlesyndication.corn, googlesyndication.com +delfi.lt, delfi.lt +eqla3.corn, eqla3.com +ali2l3.net, ali213.net +fanpage.it, fanpage.it +uptobox.corn, uptobox.com +google.jo, google.jo +cncn.corn, cncn.com +srne.sk, sme.sk +kinozal.tv, kinozal.tv +ceconline.corn, ceconline.com +billboard.corn, billboard.com +citi.corn, citi.com +naughtyarnerica.corn, naughtyamerica.com +classrnates.corn, classmates.com +coursera.org, coursera.org +pingan.corn, pingan.com +voanews.corn, voanews.com +tankionline.corn, tankionline.com +jetblue.corn, jetblue.com +spainshtranslation.corn, spainshtranslation.com +ebookbrowse.corn, ebookbrowse.com +rnet-art.corn, met-art.com +rnegafon.ru, megafon.ru +quibids.corn, quibids.com +srnartfren.corn, smartfren.com +cleartrip.corn, cleartrip.com +pixrnania.corn, pixmania.com +vivastreet.corn, vivastreet.com +thegfnetwork.corn, thegfnetwork.com +paytrn.corn, paytm.com +rneinsextagebuch.net, meinsextagebuch.net +rnernecenter.corn, memecenter.com +ixbt.corn, ixbt.com +dagbladet.no, dagbladet.no +basecarnphq.corn, basecamphq.com +chinatirnes.corn, chinatimes.com +bubblews.corn, bubblews.com +xtool.ru, xtool.ru +opodo.co.uk, opodo.co.uk +hattrick.org, hattrick.org +zopirn.corn, zopim.com +aol.co.uk, aol.co.uk +gazzetta.gr, gazzetta.gr +l8andabused.corn, 18andabused.com +rncssl.corn, mcssl.com +econornist.corn, economist.com +zeit.de, zeit.de +google.corn.uy, google.com.uy +pinoy-ako.info, pinoy-ako.info +lazada.co.id, lazada.co.id +filgoal.corn, filgoal.com +rozetka.corn.ua, rozetka.com.ua +alrnesryoon.corn, almesryoon.com +csrnonitor.corn, csmonitor.com +bizjournals.corn, bizjournals.com +rackspace.corn, rackspace.com +webgozar.corn, webgozar.com +opencart.corn, opencart.com +rnediaplex.corn, mediaplex.com +deutsche-bank.de, deutsche-bank.de +sirnilarsites.corn, similarsites.com +sotrnarket.ru, sotmarket.ru +chatzurn.corn, chatzum.com +huffingtonpost.co.uk, huffingtonpost.co.uk +carwale.corn, carwale.com +rnernez.corn, memez.com +hostrnonster.corn, hostmonster.com +rnuzofon.corn, muzofon.com +elephanttube.corn, elephanttube.com +crunchbase.corn, crunchbase.com +irnhonet.ru, imhonet.ru +lusongsong.corn, lusongsong.com +filrnesonlinegratis.net, filmesonlinegratis.net +giaoduc.net.vn, giaoduc.net.vn +rnanhub.corn, manhub.com +tatadocorno.corn, tatadocomo.com +realitatea.net, realitatea.net +freernp3x.corn, freemp3x.com +freernail.hu, freemail.hu +ganool.corn, ganool.com +feedreader.corn, feedreader.com +sportsdirect.corn, sportsdirect.com +videolan.org, videolan.org +watchseries.lt, watchseries.lt +rotapost.ru, rotapost.ru +nwolb.corn, nwolb.com +searchquotes.corn, searchquotes.com +kaspersky.corn, kaspersky.com +go2cloud.org, go2cloud.org +grepolis.corn, grepolis.com +profit-partner.ru, profit-partner.ru +articlesbase.corn, articlesbase.com +dns-shop.ru, dns-shop.ru +radikal.corn.tr, radikal.com.tr +justjared.corn, justjared.com +lancenet.corn.br, lancenet.com.br +rnangapanda.corn, mangapanda.com +theglobeandrnail.corn, theglobeandmail.com +ecollege.corn, ecollege.com +rnyanirnelist.net, myanimelist.net +fotornac.corn.tr, fotomac.com.tr +irnanhua.corn, imanhua.com +travelzoo.corn, travelzoo.com +jjwxc.net, jjwxc.net +q.gs, q.gs +naaptol.corn, naaptol.com +sarnbaporno.corn, sambaporno.com +rnacrojuegos.corn, macrojuegos.com +ooo-sex.corn, ooo-sex.com +fab.corn, fab.com +roflzone.corn, roflzone.com +searchcornpletion.corn, searchcompletion.com +jezebel.corn, jezebel.com +bizdec.ru, bizdec.ru +torrentino.corn, torrentino.com +rnultitran.ru, multitran.ru +tune-up.corn, tune-up.com +sparkpeople.corn, sparkpeople.com +desi-tashan.corn, desi-tashan.com +rnashreghnews.ir, mashreghnews.ir +talktalk.co.uk, talktalk.co.uk +hinkhoj.corn, hinkhoj.com +2Orninutes.fr, 20minutes.fr +sulia.corn, sulia.com +icirns.corn, icims.com +dizi-rnag.corn, dizi-mag.com +webaslan.corn, webaslan.com +en.wordpress.corn, en.wordpress.com +funrnoods.corn, funmoods.com +softgozar.corn, softgozar.com +starwoodhotels.corn, starwoodhotels.com +studiopress.corn, studiopress.com +click.in, click.in +rneetcheap.corn, meetcheap.com +angel-live.corn, angel-live.com +beforeitsnews.corn, beforeitsnews.com +trello.corn, trello.com +icontact.corn, icontact.com +prlog.org, prlog.org +incentria.corn, incentria.com +bouyguestelecorn.fr, bouyguestelecom.fr +dstv.corn, dstv.com +arstechnica.corn, arstechnica.com +diigo.corn, diigo.com +consurners-research.corn, consumers-research.com +rnetaffiliation.corn, metaffiliation.com +telekorn.de, telekom.de +izlesene.corn, izlesene.com +newsit.gr, newsit.gr +fuckingawesorne.corn, fuckingawesome.com +osyrn.gov.tr, osym.gov.tr +svyaznoy.ru, svyaznoy.ru +watchfreernovies.ch, watchfreemovies.ch +gurntree.pl, gumtree.pl +sportbox.ru, sportbox.ru +reserverunessai.corn, reserverunessai.com +hsbc.corn.hk, hsbc.com.hk +cricbuzz.corn, cricbuzz.com +djelfa.info, djelfa.info +nouvelobs.corn, nouvelobs.com +aruba.it, aruba.it +hornes.corn, homes.com +allezleslions.corn, allezleslions.com +orkut.corn.br, orkut.com.br +aionfreetoplay.corn, aionfreetoplay.com +acadernia.edu, academia.edu +consurnerreports.org, consumerreports.org +ilsole24ore.corn, ilsole24ore.com +sephora.corn, sephora.com +lds.org, lds.org +vrnall.corn, vmall.com +ultirnasnoticias.corn.ve, ultimasnoticias.com.ve +healthgrades.corn, healthgrades.com +irngbox.corn, imgbox.com +dlsite.corn, dlsite.com +whitesrnoke.corn, whitesmoke.com +thenextweb.corn, thenextweb.com +qirel23.corn, qire123.com +peeplo.corn, peeplo.com +chitika.corn, chitika.com +alwafd.org, alwafd.org +phonearena.corn, phonearena.com +ovh.corn, ovh.com +tusfiles.net, tusfiles.net +l8schoolgirlz.corn, 18schoolgirlz.com +bongacarns.corn, bongacams.com +horne.pl, home.pl +footrnercato.net, footmercato.net +sprashivai.ru, sprashivai.ru +rnegafilrneshd.net, megafilmeshd.net +prerniurn-display.corn, premium-display.com +clickey.corn, clickey.com +tokyo-tube.corn, tokyo-tube.com +watch32.corn, watch32.com +pornolab.net, pornolab.net +tirnewarnercable.corn, timewarnercable.com +naturalnews.corn, naturalnews.com +afirnet.corn, afimet.com +telderi.ru, telderi.ru +ioffer.corn, ioffer.com +lapatilla.corn, lapatilla.com +livetv.ru, livetv.ru +cloudflare.corn, cloudflare.com +lupoporno.corn, lupoporno.com +nhaccuatui.corn, nhaccuatui.com +thepostgarne.corn, thepostgame.com +ipage.corn, ipage.com +banesconline.corn, banesconline.com +cdc.gov, cdc.gov +adonweb.ru, adonweb.ru +zone-telechargernent.corn, zone-telechargement.com +intellicast.corn, intellicast.com +uloz.to, uloz.to +pikabu.ru, pikabu.ru +rnegogo.net, megogo.net +wenxuecity.corn, wenxuecity.com +xrnl-siternaps.corn, xml-sitemaps.com +webdunia.corn, webdunia.com +justhost.corn, justhost.com +starbucks.corn, starbucks.com +wargarning.net, wargaming.net +hugedornains.corn, hugedomains.com +rnagicbricks.corn, magicbricks.com +gigporno.corn, gigporno.com +rikunabi.corn, rikunabi.com +5lauto.corn, 51auto.com +warriorplus.corn, warriorplus.com +gudvin.tv, gudvin.tv +bigrnir.net, bigmir.net +ansa.it, ansa.it +standardbank.co.za, standardbank.co.za +toshiba.corn, toshiba.com +xinnet.corn, xinnet.com +geico.corn, geico.com +funnyjunk.corn, funnyjunk.com +affaritaliani.it, affaritaliani.it +cityheaven.net, cityheaven.net +tubewolf.corn, tubewolf.com +google.org, google.org +ad.nl, ad.nl +tutorialspoint.corn, tutorialspoint.com +uidai.gov.in, uidai.gov.in +everydayhealth.corn, everydayhealth.com +jzip.corn, jzip.com +lolspotsarticles.corn, lolspotsarticles.com +rueducornrnerce.fr, rueducommerce.fr +lvrnarna.corn, lvmama.com +roboforrn.corn, roboform.com +zoznarn.sk, zoznam.sk +livesrni.corn, livesmi.com +die-boersenforrnel.corn, die-boersenformel.com +watchcartoononline.corn, watchcartoononline.com +abclocal.go.corn, abclocal.go.com +techrepublic.corn, techrepublic.com +just-fuck.corn, just-fuck.com +carnster.corn, camster.com +akairan.corn, akairan.com +yeslibertin.corn, yeslibertin.com +abc.go.corn, abc.go.com +searchtherightwords.corn, searchtherightwords.com +scotiabank.corn, scotiabank.com +justclick.ru, justclick.ru +douguo.corn, douguo.com +discover.corn, discover.com +britishairways.corn, britishairways.com +rnobafire.corn, mobafire.com +gi-akadernie.ning.corn, gi-akademie.ning.com +desirulez.net, desirulez.net +qiushibaike.corn, qiushibaike.com +rnoonbasa.corn, moonbasa.com +all.biz, all.biz +springer.corn, springer.com +ernai.corn, emai.com +deadspin.corn, deadspin.com +hulkshare.corn, hulkshare.com +fast-torrent.ru, fast-torrent.ru +oriflarne.corn, oriflame.com +irngchili.net, imgchili.net +rnega-juegos.rnx, mega-juegos.mx +gyazo.corn, gyazo.com +persianv.corn, persianv.com +adk2.corn, adk2.com +ingbank.pl, ingbank.pl +nationalconsurnercenter.corn, nationalconsumercenter.com +xxxkinky.corn, xxxkinky.com +rnywot.corn, mywot.com +gayrnaletube.corn, gaymaletube.com +ltv.ru, 1tv.ru +rnanutd.corn, manutd.com +rnerchantcircle.corn, merchantcircle.com +canalblog.corn, canalblog.com +capitalone36O.corn, capitalone360.com +tlbb8.corn, tlbb8.com +softonic.fr, softonic.fr +ccavenue.corn, ccavenue.com +tyroodr.corn, tyroodr.com +exarn8.corn, exam8.com +allrnusic.corn, allmusic.com +stubhub.corn, stubhub.com +arcor.de, arcor.de +yolasite.corn, yolasite.com +haraj.corn.sa, haraj.com.sa +rnypopup.ir, mypopup.ir +rnernurlar.net, memurlar.net +srnugrnug.corn, smugmug.com +filefactory.corn, filefactory.com +fantasti.cc, fantasti.cc +bokra.net, bokra.net +goarticles.corn, goarticles.com +rnoneysavingexpert.corn, moneysavingexpert.com +donga.corn, donga.com +lastrninute.corn, lastminute.com +xkcd.corn, xkcd.com +sou3OO.corn, sou300.com +rnagnovideo.corn, magnovideo.com +inquirer.net, inquirer.net +phoenix.edu, phoenix.edu +videogenesis.corn, videogenesis.com +thestar.corn, thestar.com +tripadvisor.es, tripadvisor.es +blankrefer.corn, blankrefer.com +yle.fi, yle.fi +bearntele.corn, beamtele.com +oanda.corn, oanda.com +iheart.corn, iheart.com +google.co.tz, google.co.tz +stargazete.corn, stargazete.com +bossip.corn, bossip.com +defaultsear.ch, defaultsear.ch +thaiseoboard.corn, thaiseoboard.com +qinbei.corn, qinbei.com +ninisite.corn, ninisite.com +j.gs, j.gs +nos.nl, nos.nl +qualtrics.corn, qualtrics.com +kornrnersant.ru, kommersant.ru +urban-rivals.corn, urban-rivals.com +cornputerbild.de, computerbild.de +fararu.corn, fararu.com +rnenshealth.corn, menshealth.com +jobstreet.corn, jobstreet.com +rbcroyalbank.corn, rbcroyalbank.com +inrnotionhosting.corn, inmotionhosting.com +surveyrouter.corn, surveyrouter.com +kankanews.corn, kankanews.com +aol.de, aol.de +bol.corn, bol.com +datpiff.corn, datpiff.com +rnplife.corn, mplife.com +sale-fire.corn, sale-fire.com +inbox.lv, inbox.lv +offeraturn.corn, offeratum.com +pandora.tv, pandora.tv +eltiernpo.corn, eltiempo.com +indiarailinfo.corn, indiarailinfo.com +solidtrustpay.corn, solidtrustpay.com +warthunder.ru, warthunder.ru +novarnov.corn, novamov.com +folkd.corn, folkd.com +envato.corn, envato.com +wetpaint.corn, wetpaint.com +ternpo.co, tempo.co +howtogeek.corn, howtogeek.com +foundationapi.corn, foundationapi.com +care2.corn, care2.com +bendibao.corn, bendibao.com +rnazika2day.corn, mazika2day.com +asda.corn, asda.com +nowvideo.ch, nowvideo.ch +hiapk.corn, hiapk.com +l7u.corn, 17u.com +tutu.ru, tutu.ru +ncdownloader.corn, ncdownloader.com +warez-bb.org, warez-bb.org +jsoftj.corn, jsoftj.com +xrnarks.corn, xmarks.com +36kr.corn, 36kr.com +runetki.corn, runetki.com +quoka.de, quoka.de +heureka.cz, heureka.cz +rnonografias.corn, monografias.com +zhenai.corn, zhenai.com +4porn.corn, 4porn.com +antena3.corn, antena3.com +lintas.rne, lintas.me +seroundtable.corn, seroundtable.com +el.ru, e1.ru +berkeley.edu, berkeley.edu +officedepot.corn, officedepot.com +rnyflorida.corn, myflorida.com +parispornrnovies.corn, parispornmovies.com +uniqlo.corn, uniqlo.com +topky.sk, topky.sk +lurnovies.corn, lumovies.com +buysellads.corn, buysellads.com +stirileprotv.ro, stirileprotv.ro +scottrade.corn, scottrade.com +rnrntrends.net, mmtrends.net +wholesale-dress.net, wholesale-dress.net +rnetacritic.corn, metacritic.com +pichunter.corn, pichunter.com +rnoneybookers.corn, moneybookers.com +idealista.corn, idealista.com +buzzle.corn, buzzle.com +rcorn.co.in, rcom.co.in +weightwatchers.corn, weightwatchers.com +itv.corn, itv.com +inilah.corn, inilah.com +vic.gov.au, vic.gov.au +prorn.ua, prom.ua +with2.net, with2.net +doodle.corn, doodle.com +trafficbroker.corn, trafficbroker.com +h33t.corn, h33t.com +avaaz.org, avaaz.org +rnaultalk.corn, maultalk.com +brno.corn, bmo.com +nerdbux.corn, nerdbux.com +abnarnro.nl, abnamro.nl +didigarnes.corn, didigames.com +pornorarna.corn, pornorama.com +forurnotion.corn, forumotion.com +wornan.ru, woman.ru +thaivisa.corn, thaivisa.com +lexpress.fr, lexpress.fr +forurncornrnunity.net, forumcommunity.net +regions.corn, regions.com +sf-express.corn, sf-express.com +donkeyrnails.corn, donkeymails.com +clubic.corn, clubic.com +aucfan.corn, aucfan.com +enterfactory.corn, enterfactory.com +yandex.corn, yandex.com +iherb.corn, iherb.com +in.gr, in.gr +olx.pt, olx.pt +fbdownloader.corn, fbdownloader.com +autoscout24.it, autoscout24.it +siteground.corn, siteground.com +psicofxp.corn, psicofxp.com +persiangig.corn, persiangig.com +rnetroer.corn, metroer.com +tokopedia.corn, tokopedia.com +seccarn.info, seccam.info +sport-express.ru, sport-express.ru +vodafone.it, vodafone.it +blekko.corn, blekko.com +entekhab.ir, entekhab.ir +expressen.se, expressen.se +zalando.fr, zalando.fr +hawaaworld.corn, hawaaworld.com +freeonlinegarnes.corn, freeonlinegames.com +google.corn.lb, google.com.lb +ab-in-den-urlaub.de, ab-in-den-urlaub.de +android4tw.corn, android4tw.com +alriyadh.corn, alriyadh.com +drugstore.corn, drugstore.com +iobit.corn, iobit.com +rei.corn, rei.com +racing-garnes.corn, racing-games.com +rnornrnyfucktube.corn, mommyfucktube.com +pideo.net, pideo.net +gogoanirne.corn, gogoanime.com +avaxho.rne, avaxho.me +christianrningle.corn, christianmingle.com +activesearchresults.corn, activesearchresults.com +trendsonline.biz, trendsonline.biz +planetsuzy.org, planetsuzy.org +rubiasl9.corn, rubias19.com +cleverbridge.corn, cleverbridge.com +jeevansathi.corn, jeevansathi.com +washingtontirnes.corn, washingtontimes.com +lcl.fr, lcl.fr +98ia.corn, 98ia.com +rnercadolibre.corn.co, mercadolibre.com.co +n-tv.de, n-tv.de +divyabhaskar.co.in, divyabhaskar.co.in +airbnb.corn, airbnb.com +rnybrowserbar.corn, mybrowserbar.com +travian.corn, travian.com +autoblog.corn, autoblog.com +blesk.cz, blesk.cz +playboy.corn, playboy.com +p3Odownload.corn, p30download.com +pazienti.net, pazienti.net +uast.ac.ir, uast.ac.ir +logsoku.corn, logsoku.com +zedge.net, zedge.net +creditrnutuel.fr, creditmutuel.fr +absa.co.za, absa.co.za +rnilliyet.tv, milliyet.tv +jiathis.corn, jiathis.com +liverpoolfc.tv, liverpoolfc.tv +dospy.corn, dospy.com +calarneo.corn, calameo.com +netsuite.corn, netsuite.com +angelfire.corn, angelfire.com +snagajob.corn, snagajob.com +hollywoodlife.corn, hollywoodlife.com +techtudo.corn.br, techtudo.com.br +payserve.corn, payserve.com +portalnet.cl, portalnet.cl +worldadult-videos.info, worldadult-videos.info +indianpornvideos.corn, indianpornvideos.com +france24.corn, france24.com +discuss.corn.hk, discuss.com.hk +theplanet.corn, theplanet.com +advego.ru, advego.ru +eltiernpo.es, eltiempo.es +55tuan.corn, 55tuan.com +snopes.corn, snopes.com +startnow.corn, startnow.com +tucarro.corn, tucarro.com +skyscanner.net, skyscanner.net +wchonline.corn, wchonline.com +gaadi.corn, gaadi.com +lindaikeji.blogspot.corn, lindaikeji.blogspot.com +keywordblocks.corn, keywordblocks.com +apsense.corn, apsense.com +avangate.corn, avangate.com +gandul.info, gandul.info +google.corn.gh, google.com.gh +rnybigcornrnerce.corn, mybigcommerce.com +horneaway.corn, homeaway.com +wikitravel.org, wikitravel.org +etxt.ru, etxt.ru +zerx.ru, zerx.ru +sidereel.corn, sidereel.com +edrearns.es, edreams.es +india-forurns.corn, india-forums.com +infonews.corn, infonews.com +zoorninfo.corn, zoominfo.com +stylebistro.corn, stylebistro.com +dorninos.corn, dominos.com +59lhx.corn, 591hx.com +authorize.net, authorize.net +6lbaobao.corn, 61baobao.com +digitalspy.co.uk, digitalspy.co.uk +godvine.corn, godvine.com +rednowtube.corn, rednowtube.com +appbank.net, appbank.net +woozgo.fr, woozgo.fr +expireddornains.net, expireddomains.net +rny-uq.corn, my-uq.com +peliculasyonkis.corn, peliculasyonkis.com +forurnfree.it, forumfree.it +shangdu.corn, shangdu.com +startrnyripple.corn, startmyripple.com +hottube.rne, hottube.me +rnernbers.webs.corn, members.webs.com +blick.ch, blick.ch +google.crn, google.cm +torntorn.corn, tomtom.com +rzd.ru, rzd.ru +opensooq.corn, opensooq.com +pizzahut.corn, pizzahut.com +rnarksandspencer.corn, marksandspencer.com +filenuke.corn, filenuke.com +filelist.ro, filelist.ro +akharinnews.corn, akharinnews.com +etrade.corn, etrade.com +planetrorneo.corn, planetromeo.com +wpbeginner.corn, wpbeginner.com +bancornercantil.corn, bancomercantil.com +pastdate.corn, pastdate.com +webutation.net, webutation.net +rnywebgrocer.corn, mywebgrocer.com +rnobile.ir, mobile.ir +seernorgh.corn, seemorgh.com +nhs.uk, nhs.uk +google.ba, google.ba +ileehoo.corn, ileehoo.com +seobook.corn, seobook.com +wetteronline.de, wetteronline.de +happy-porn.corn, happy-porn.com +theonion.corn, theonion.com +webnode.corn, webnode.com +svaiza.corn, svaiza.com +newsbornb.gr, newsbomb.gr +t88u.corn, t88u.com +tsn.ca, tsn.ca +unity3d.corn, unity3d.com +nseindia.corn, nseindia.com +juegosdiarios.corn, juegosdiarios.com +genieo.corn, genieo.com +kelkoo.corn, kelkoo.com +shabdkosh.corn, shabdkosh.com +tecrnundo.corn.br, tecmundo.com.br +chinaunix.net, chinaunix.net +goo-net.corn, goo-net.com +asana.corn, asana.com +hdporn.in, hdporn.in +virtapay.corn, virtapay.com +jobdiagnosis.corn, jobdiagnosis.com +guokr.corn, guokr.com +clickpoint.it, clickpoint.it +3drngarne.corn, 3dmgame.com +ashleyrnadison.corn, ashleymadison.com +utsprofitads.corn, utsprofitads.com +google.ee, google.ee +oyunskor.corn, oyunskor.com +rnetro.co.uk, metro.co.uk +ebaurnsworld.corn, ebaumsworld.com +realsirnple.corn, realsimple.com +3file.info, 3file.info +xcarns.corn, xcams.com +cyberforurn.ru, cyberforum.ru +babble.corn, babble.com +lidl.de, lidl.de +pixer.rnobi, pixer.mobi +yell.corn, yell.com +alnilin.corn, alnilin.com +lurkrnore.to, lurkmore.to +olx.co.za, olx.co.za +eorezo.corn, eorezo.com +baby.ru, baby.ru +redporntube.corn, redporntube.com +extabit.corn, extabit.com +wayn.corn, wayn.com +gaana.corn, gaana.com +islarnicfinder.org, islamicfinder.org +venturebeat.corn, venturebeat.com +played.to, played.to +alrakoba.net, alrakoba.net +rnouthshut.corn, mouthshut.com +banquepopulaire.fr, banquepopulaire.fr +dasoertliche.de, dasoertliche.de +lstwebdesigner.corn, 1stwebdesigner.com +tarn.corn.br, tam.com.br +nature.corn, nature.com +carnfrog.corn, camfrog.com +philly.corn, philly.com +zerntv.corn, zemtv.com +oprah.corn, oprah.com +wrnaraci.corn, wmaraci.com +ruvr.ru, ruvr.ru +gsn.corn, gsn.com +acrobat.corn, acrobat.com +depositfiles.org, depositfiles.org +srnartresponder.ru, smartresponder.ru +huxiu.corn, huxiu.com +porn-wanted.corn, porn-wanted.com +tripadvisor.fr, tripadvisor.fr +3366.corn, 3366.com +ranker.corn, ranker.com +cibc.corn, cibc.com +trend.az, trend.az +whatsapp.corn, whatsapp.com +O7O73.corn, 07073.com +netload.in, netload.in +channel4.corn, channel4.com +yatra.corn, yatra.com +elconfidencial.corn, elconfidencial.com +labnol.org, labnol.org +google.co.ke, google.co.ke +disneylatino.corn, disneylatino.com +pconverter.corn, pconverter.com +cqnews.net, cqnews.net +blog.co.uk, blog.co.uk +irnrnowelt.de, immowelt.de +crunchyroll.corn, crunchyroll.com +garnesgarnes.corn, gamesgames.com +prototherna.gr, protothema.gr +vrnoptions.corn, vmoptions.com +go2jurnp.org, go2jump.org +psu.edu, psu.edu +sanjesh.org, sanjesh.org +sportingnews.corn, sportingnews.com +televisionfanatic.corn, televisionfanatic.com +fansshare.corn, fansshare.com +xcarns4u.corn, xcams4u.com +rnadthurnbs.corn, madthumbs.com +ebates.corn, ebates.com +erornon.net, eromon.net +copyblogger.corn, copyblogger.com +flirt4free.corn, flirt4free.com +gaytube.corn, gaytube.com +notdoppler.corn, notdoppler.com +allrnyvideos.net, allmyvideos.net +carn4.de.corn, cam4.de.com +chosun.corn, chosun.com +adrne.ru, adme.ru +codeplex.corn, codeplex.com +jurnia.corn.ng, jumia.com.ng +digitaltrends.corn, digitaltrends.com +b92.net, b92.net +rniniinthebox.corn, miniinthebox.com +radaronline.corn, radaronline.com +hujiang.corn, hujiang.com +gardenweb.corn, gardenweb.com +pizap.corn, pizap.com +iptorrents.corn, iptorrents.com +yuku.corn, yuku.com +rnega-giochi.it, mega-giochi.it +nrk.no, nrk.no +99designs.corn, 99designs.com +uscis.gov, uscis.gov +lostfilrn.tv, lostfilm.tv +rnileroticos.corn, mileroticos.com +republika.co.id, republika.co.id +sharethis.corn, sharethis.com +sarnplicio.us, samplicio.us +lsaleaday.corn, 1saleaday.com +vonelo.corn, vonelo.com +oyunrnoyun.corn, oyunmoyun.com +flightradar24.corn, flightradar24.com +geo.tv, geo.tv +nexusrnods.corn, nexusmods.com +blogspot.fi, blogspot.fi +directtrack.corn, directtrack.com +rnedia.net, media.net +bigresource.corn, bigresource.com +free-lance.ru, free-lance.ru +loveplanet.ru, loveplanet.ru +ilfattoquotidiano.it, ilfattoquotidiano.it +coolrnovs.corn, coolmovs.com +rnango.corn, mango.com +nj.corn, nj.com +rnagazineluiza.corn.br, magazineluiza.com.br +datehookup.corn, datehookup.com +registro.br, registro.br +debenharns.corn, debenhams.com +jqueryui.corn, jqueryui.com +palcornp3.corn, palcomp3.com +opensubtitles.org, opensubtitles.org +socialrnediatoday.corn, socialmediatoday.com +allgarneshorne.corn, allgameshome.com +pricegrabber.corn, pricegrabber.com +lufthansa.corn, lufthansa.com +ip-adress.corn, ip-adress.com +business-standard.corn, business-standard.com +garnes.corn, games.com +zarnan.corn.tr, zaman.com.tr +jagranjosh.corn, jagranjosh.com +rnint.corn, mint.com +gorillavid.in, gorillavid.in +google.corn.orn, google.com.om +blogbigtirne.corn, blogbigtime.com +korrespondent.net, korrespondent.net +nyrnag.corn, nymag.com +proporn.corn, proporn.com +ycasrnd.info, ycasmd.info +persiantools.corn, persiantools.com +torrenthound.corn, torrenthound.com +bestsexo.corn, bestsexo.com +alwatanvoice.corn, alwatanvoice.com +jahannews.corn, jahannews.com +bluewin.ch, bluewin.ch +sap.corn, sap.com +rzb.ir, rzb.ir +rnyorderbox.corn, myorderbox.com +dealsandsavings.net, dealsandsavings.net +goldenline.pl, goldenline.pl +stuff.co.nz, stuff.co.nz +opentable.corn, opentable.com +4738.corn, 4738.com +freshersworld.corn, freshersworld.com +state.pa.us, state.pa.us +lavanguardia.corn, lavanguardia.com +rnob.org, mob.org +vodafone.in, vodafone.in +blogdetik.corn, blogdetik.com +888.it, 888.it +passportindia.gov.in, passportindia.gov.in +ssa.gov, ssa.gov +desitvforurn.net, desitvforum.net +rajasthan.gov.in, rajasthan.gov.in +zonealarrn.corn, zonealarm.com +locaweb.corn.br, locaweb.com.br +logrne.in, logme.in +fetlife.corn, fetlife.com +lyricsfreak.corn, lyricsfreak.com +te3p.corn, te3p.com +hrnrc.gov.uk, hmrc.gov.uk +bravoerotica.corn, bravoerotica.com +kolesa.kz, kolesa.kz +vinescope.corn, vinescope.com +shoplocal.corn, shoplocal.com +rnydrivers.corn, mydrivers.com +bigidearnasterrnind.corn, bigideamastermind.com +uncoverthenet.corn, uncoverthenet.com +ragecornic.corn, ragecomic.com +yodobashi.corn, yodobashi.com +titan24.corn, titan24.com +nocoty.pl, nocoty.pl +turkishairlines.corn, turkishairlines.com +liputan6.corn, liputan6.com +3suisses.fr, 3suisses.fr +cancan.ro, cancan.ro +apetube.corn, apetube.com +kurir-info.rs, kurir-info.rs +wow.corn, wow.com +rnyblogguest.corn, myblogguest.com +wp.corn, wp.com +tre.it, tre.it +livrariasaraiva.corn.br, livrariasaraiva.com.br +ubuntuforurns.org, ubuntuforums.org +serverfault.corn, serverfault.com +princeton.edu, princeton.edu +experienceproject.corn, experienceproject.com +ero-video.net, ero-video.net +west263.corn, west263.com +nguoiduatin.vn, nguoiduatin.vn +findthebest.corn, findthebest.com +iol.pt, iol.pt +hotukdeals.corn, hotukdeals.com +filrnifullizle.corn, filmifullizle.com +blog.hu, blog.hu +dailyfinance.corn, dailyfinance.com +bigxvideos.corn, bigxvideos.com +adreactor.corn, adreactor.com +frnworld.net, fmworld.net +furnu.corn, fumu.com +ntv.ru, ntv.ru +poringa.net, poringa.net +syosetu.corn, syosetu.com +giantsextube.corn, giantsextube.com +uuu9.corn, uuu9.com +babosas.corn, babosas.com +square-enix.corn, square-enix.com +bankia.es, bankia.es +freedownloadrnanager.org, freedownloadmanager.org +add-anirne.net, add-anime.net +tuttornercatoweb.corn, tuttomercatoweb.com +l92.corn, 192.com +freekaarnaal.corn, freekaamaal.com +youngpornvideos.corn, youngpornvideos.com +nbc.corn, nbc.com +jne.co.id, jne.co.id +fobshanghai.corn, fobshanghai.com +johnlewis.corn, johnlewis.com +rnvideo.ru, mvideo.ru +bhinneka.corn, bhinneka.com +gooddrarna.net, gooddrama.net +lobstertube.corn, lobstertube.com +ovguide.corn, ovguide.com +joernonster.org, joemonster.org +editor.wix.corn, editor.wix.com +wechat.corn, wechat.com +locanto.in, locanto.in +video2rnp3.net, video2mp3.net +couchsurfing.org, couchsurfing.org +tchibo.de, tchibo.de +rol.ro, rol.ro +toroporno.corn, toroporno.com +backlinkwatch.corn, backlinkwatch.com +greatergood.corn, greatergood.com +srnartaddressbar.corn, smartaddressbar.com +getgoodlinks.ru, getgoodlinks.ru +fitbit.corn, fitbit.com +elcorteingles.es, elcorteingles.es +up2c.corn, up2c.com +rg.ru, rg.ru +ftalk.corn, ftalk.com +apartrnenttherapy.corn, apartmenttherapy.com +blogspot.hu, blogspot.hu +e-rewards.corn, e-rewards.com +weloveshopping.corn, weloveshopping.com +swtor.corn, swtor.com +abs-cbnnews.corn, abs-cbnnews.com +webpagetest.org, webpagetest.org +ricardo.ch, ricardo.ch +ghatreh.corn, ghatreh.com +ibps.in, ibps.in +rnoneyrnakergroup.corn, moneymakergroup.com +exist.ru, exist.ru +kakprosto.ru, kakprosto.ru +gradeuptube.corn, gradeuptube.com +lastarnpa.it, lastampa.it +rnedicinenet.corn, medicinenet.com +theknot.corn, theknot.com +yale.edu, yale.edu +okazii.ro, okazii.ro +wa.gov, wa.gov +grnhuowan.corn, gmhuowan.com +cnhubei.corn, cnhubei.com +dickssportinggoods.corn, dickssportinggoods.com +instaforex.corn, instaforex.com +zdf.de, zdf.de +getpocket.corn, getpocket.com +takungpao.corn, takungpao.com +junkrnail.co.za, junkmail.co.za +tripwirernagazine.corn, tripwiremagazine.com +popcap.corn, popcap.com +bangbros.corn, bangbros.com +shtyle.frn, shtyle.fm +jungle.gr, jungle.gr +apserver.net, apserver.net +rnzarnin.corn, mzamin.com +google.lu, google.lu +squarebux.corn, squarebux.com +bollywoodhungarna.corn, bollywoodhungama.com +rnilfrnovs.corn, milfmovs.com +softonic.it, softonic.it +cyberciti.biz, cyberciti.biz +scout.corn, scout.com +teensnow.corn, teensnow.com +pornper.corn, pornper.com +torrentreactor.net, torrentreactor.net +srnotri.corn, smotri.com +startpage.corn, startpage.com +clirnaternpo.corn.br, climatempo.com.br +bigrock.in, bigrock.in +kajabi.corn, kajabi.com +irngchili.corn, imgchili.com +dogpile.corn, dogpile.com +thestreet.corn, thestreet.com +sport24.gr, sport24.gr +tophotels.ru, tophotels.ru +bbva.es, bbva.es +perfectrnoney.corn, perfectmoney.com +cashrnachines2.corn, cashmachines2.com +skroutz.gr, skroutz.gr +logitech.corn, logitech.com +seriescoco.corn, seriescoco.com +fastclick.corn, fastclick.com +carnbridge.org, cambridge.org +fark.corn, fark.com +krypt.corn, krypt.com +indiangilrna.corn, indiangilma.com +safe-swaps.corn, safe-swaps.com +trenitalia.corn, trenitalia.com +flycell.corn.rnx, flycell.com.mx +livefreefun.corn, livefreefun.com +ourtoolbar.corn, ourtoolbar.com +anandtech.corn, anandtech.com +neirnanrnarcus.corn, neimanmarcus.com +lelong.corn.rny, lelong.com.my +pulscen.ru, pulscen.ru +paginegialle.it, paginegialle.it +intelius.corn, intelius.com +orange.pl, orange.pl +aktuality.sk, aktuality.sk +webgarne.in.th, webgame.in.th +runescape.corn, runescape.com +rocketnews24.corn, rocketnews24.com +lineadirecta.corn, lineadirecta.com +origin.corn, origin.com +newsbeast.gr, newsbeast.gr +justhookup.corn, justhookup.com +lifenews.ru, lifenews.ru +siterneter.corn, sitemeter.com +isbank.corn.tr, isbank.com.tr +cornrnerzbanking.de, commerzbanking.de +rnarthastewart.corn, marthastewart.com +ntvrnsnbc.corn, ntvmsnbc.com +seloger.corn, seloger.com +vend-o.corn, vend-o.com +alrnanar.corn.lb, almanar.com.lb +sifyitest.corn, sifyitest.com +taojindi.corn, taojindi.com +rnylife.corn, mylife.com +talkfusion.corn, talkfusion.com +hichina.corn, hichina.com +paruvendu.fr, paruvendu.fr +adrncsport.corn, admcsport.com +faz.net, faz.net +narutoget.corn, narutoget.com +wufoo.corn, wufoo.com +feedads-srv.corn, feedads-srv.com +gophoto.it, gophoto.it +tgju.org, tgju.org +dynarnicdrive.corn, dynamicdrive.com +centurylink.net, centurylink.net +ngs.ru, ngs.ru +anyap.info, anyap.info +dailykos.corn, dailykos.com +rnalaysiakini.corn, malaysiakini.com +uefa.corn, uefa.com +socialrnediaexarniner.corn, socialmediaexaminer.com +peperonity.de, peperonity.de +support.wordpress.corn, support.wordpress.com +hola.corn, hola.com +readrnanga.eu, readmanga.eu +jstv.corn, jstv.com +irib.ir, irib.ir +bookingbuddy.corn, bookingbuddy.com +cornputerhope.corn, computerhope.com +ilovernobi.corn, ilovemobi.com +pinkrod.corn, pinkrod.com +videobash.corn, videobash.com +alfernrninile.corn, alfemminile.com +tu.tv, tu.tv +utro.ru, utro.ru +urbanoutfitters.corn, urbanoutfitters.com +autozone.corn, autozone.com +gilt.corn, gilt.com +atpworldtour.corn, atpworldtour.com +goibibo.corn, goibibo.com +propellerpops.corn, propellerpops.com +cornell.edu, cornell.edu +flashscore.corn, flashscore.com +babyblog.ru, babyblog.ru +sport-frn.gr, sport-fm.gr +viarnichelin.fr, viamichelin.fr +newyorker.corn, newyorker.com +tagesschau.de, tagesschau.de +guiarnais.corn.br, guiamais.com.br +jeux.fr, jeux.fr +pontofrio.corn.br, pontofrio.com.br +drn5.corn, dm5.com +ss.lv, ss.lv +rnirtesen.ru, mirtesen.ru +rnoney.pl, money.pl +tlbsearch.corn, tlbsearch.com +usernbassy.gov, usembassy.gov +cineblogOl.net, cineblog01.net +nur.kz, nur.kz +hotnewhiphop.corn, hotnewhiphop.com +rnp3sheriff.corn, mp3sheriff.com +garnes.co.id, games.co.id +deviantclip.corn, deviantclip.com +list.ru, list.ru +xitek.corn, xitek.com +netvibes.corn, netvibes.com +24sata.hr, 24sata.hr +usda.gov, usda.gov +zerofreeporn.corn, zerofreeporn.com +tvb.corn, tvb.com +decolar.corn, decolar.com +worldfree4u.corn, worldfree4u.com +dzone.corn, dzone.com +wikiquote.org, wikiquote.org +techtunes.corn.bd, techtunes.com.bd +pornup.rne, pornup.me +blogutils.net, blogutils.net +yupoo.corn, yupoo.com +peoplesrnart.corn, peoplesmart.com +kijiji.it, kijiji.it +usairways.corn, usairways.com +betfred.corn, betfred.com +ow.ly, ow.ly +nsw.gov.au, nsw.gov.au +rnci.ir, mci.ir +iranecar.corn, iranecar.com +wisegeek.corn, wisegeek.com +gocornics.corn, gocomics.com +brarnjnet.corn, bramjnet.com +bit.ly, bit.ly +tirnesofindia.corn, timesofindia.com +xingcloud.corn, xingcloud.com +tfl.gov.uk, tfl.gov.uk +derstandard.at, derstandard.at +icq.corn, icq.com +orange.co.uk, orange.co.uk +pornokopilka.info, pornokopilka.info +88db.corn, 88db.com +house365.corn, house365.com +collegehurnor.corn, collegehumor.com +gfxtra.corn, gfxtra.com +borsapernegati.corn, borsapernegati.com +surveygifters.corn, surveygifters.com +ec2l.corn, ec21.com +seoprofiler.corn, seoprofiler.com +goldporntube.corn, goldporntube.com +tvtropes.org, tvtropes.org +techtarget.corn, techtarget.com +juno.corn, juno.com +visual.ly, visual.ly +dardarkorn.corn, dardarkom.com +showup.tv, showup.tv +three.co.uk, three.co.uk +shopstyle.corn, shopstyle.com +penguinvids.corn, penguinvids.com +trainenquiry.corn, trainenquiry.com +soha.vn, soha.vn +fengniao.corn, fengniao.com +carschina.corn, carschina.com +5OOwan.corn, 500wan.com +perfectinter.net, perfectinter.net +elog-ch.corn, elog-ch.com +thetoptens.corn, thetoptens.com +l6l6.net, 1616.net +nationwide.co.uk, nationwide.co.uk +rnyhabit.corn, myhabit.com +kinornaniak.tv, kinomaniak.tv +googlecode.corn, googlecode.com +kddi.corn, kddi.com +wyborcza.biz, wyborcza.biz +gtbank.corn, gtbank.com +zigwheels.corn, zigwheels.com +lepoint.fr, lepoint.fr +forrnulal.corn, formula1.com +baornoi.corn, baomoi.com +apa.az, apa.az +rnovie2k.to, movie2k.to +irpopup.ir, irpopup.ir +nps.gov, nps.gov +lachainerneteo.corn, lachainemeteo.com +x-art.corn, x-art.com +bakecaincontrii.corn, bakecaincontrii.com +longtailvideo.corn, longtailvideo.com +yengo.corn, yengo.com +listentoyoutube.corn, listentoyoutube.com +drearnhost.corn, dreamhost.com +cari.corn.rny, cari.com.my +sergeyrnavrodi.corn, sergeymavrodi.com +boursorarna.corn, boursorama.com +extra.corn.br, extra.com.br +rnsnbc.corn, msnbc.com +uwants.corn, uwants.com +utexas.edu, utexas.edu +rninijuegos.corn, minijuegos.com +rnurnayi.corn, mumayi.com +skorer.tv, skorer.tv +ddrnap.corn, ddmap.com +ebog.corn, ebog.com +artlebedev.ru, artlebedev.ru +venere.corn, venere.com +acadernic.ru, academic.ru +rnako.co.il, mako.co.il +nabble.corn, nabble.com +autodesk.corn, autodesk.com +vertitechnologygroup.corn, vertitechnologygroup.com +leaseweb.corn, leaseweb.com +yoox.corn, yoox.com +papajohns.corn, papajohns.com +unrnillondeutilidades.corn, unmillondeutilidades.com +webrnasters.ru, webmasters.ru +seoclerks.corn, seoclerks.com +yootherne.corn, yootheme.com +google.corn.py, google.com.py +beernp3.corn, beemp3.com +yeprne.corn, yepme.com +alef.ir, alef.ir +gotowebinar.corn, gotowebinar.com +onec.dz, onec.dz +bonprix.de, bonprix.de +landsend.corn, landsend.com +libertatea.ro, libertatea.ro +tirneout.corn, timeout.com +appnexus.corn, appnexus.com +uproxx.corn, uproxx.com +alohatube.corn, alohatube.com +citilink.ru, citilink.ru +askubuntu.corn, askubuntu.com +freernake.corn, freemake.com +rockettherne.corn, rockettheme.com +tupaki.corn, tupaki.com +53.corn, 53.com +tune.pk, tune.pk +standardchartered.corn, standardchartered.com +video-i365.corn, video-i365.com +knowyourrnerne.corn, knowyourmeme.com +goferninin.de, gofeminin.de +vrnware.corn, vmware.com +vbox7.corn, vbox7.com +webfail.corn, webfail.com +onewebsearch.corn, onewebsearch.com +xnxxrnovies.corn, xnxxmovies.com +blogspot.hk, blogspot.hk +hgtv.corn, hgtv.com +findagrave.corn, findagrave.com +yoast.corn, yoast.com +audiopoisk.corn, audiopoisk.com +sexytube.rne, sexytube.me +centerblog.net, centerblog.net +webpronews.corn, webpronews.com +prnewswire.corn, prnewswire.com +vietnarnnet.vn, vietnamnet.vn +groupon.co.in, groupon.co.in +born.gov.au, bom.gov.au +loxblog.corn, loxblog.com +llnw.corn, llnw.com +jcrew.corn, jcrew.com +carsensor.net, carsensor.net +aukro.cz, aukro.cz +zoornby.ru, zoomby.ru +wallstcheatsheet.corn, wallstcheatsheet.com +l7k.corn, 17k.com +secondlife.corn, secondlife.com +rnarrniton.org, marmiton.org +zorpia.corn, zorpia.com +searchya.corn, searchya.com +rtl2.de, rtl2.de +wiocha.pl, wiocha.pl +28tui.corn, 28tui.com +shopzilla.corn, shopzilla.com +google.corn.ni, google.com.ni +lycos.corn, lycos.com +gucheng.corn, gucheng.com +rajanews.corn, rajanews.com +blackhattearn.corn, blackhatteam.com +rnp3.es, mp3.es +forurns.wordpress.corn, forums.wordpress.com +rnicrornaxinfo.corn, micromaxinfo.com +duden.de, duden.de +nyc.gov, nyc.gov +rnonova.org, monova.org +al-wlid.corn, al-wlid.com +dastelefonbuch.de, dastelefonbuch.de +carn4ultirnate.corn, cam4ultimate.com +inps.it, inps.it +nazwa.pl, nazwa.pl +beatport.corn, beatport.com +wizzair.corn, wizzair.com +thornann.de, thomann.de +juntadeandalucia.es, juntadeandalucia.es +oficialsurveyscenter.co, oficialsurveyscenter.co +zaluu.corn, zaluu.com +videarn.corn, videarn.com +azcentral.corn, azcentral.com +xvideosrnovie.corn, xvideosmovie.com +eforosh.corn, eforosh.com +rnovie25.corn, movie25.com +creditkarrna.corn, creditkarma.com +upi.corn, upi.com +rnozook.corn, mozook.com +heavy.corn, heavy.com +worldoftanks.corn, worldoftanks.com +vkrugudruzei.ru, vkrugudruzei.ru +hourlyrevshare.net, hourlyrevshare.net +walkerplus.corn, walkerplus.com +btyou.corn, btyou.com +adzibiz.corn, adzibiz.com +tryflirting.corn, tryflirting.com +rnoi.gov.sa, moi.gov.sa +cooltext.corn, cooltext.com +dawanda.corn, dawanda.com +travian.corn.sa, travian.com.sa +va.gov, va.gov +sunrnaker.corn, sunmaker.com +aaa.corn, aaa.com +dinodirect.corn, dinodirect.com +cirna4u.corn, cima4u.com +huaban.corn, huaban.com +nzherald.co.nz, nzherald.co.nz +plotek.pl, plotek.pl +chow.corn, chow.com +rincondelvago.corn, rincondelvago.com +uzai.corn, uzai.com +stayfriends.de, stayfriends.de +reed.co.uk, reed.co.uk +rainpow.corn, rainpow.com +dallasnews.corn, dallasnews.com +ntvspor.net, ntvspor.net +fonearena.corn, fonearena.com +forocoches.corn, forocoches.com +rnyfonts.corn, myfonts.com +fenopy.se, fenopy.se +anirnefreak.tv, animefreak.tv +websitewelcorne.corn, websitewelcome.com +indonetwork.co.id, indonetwork.co.id +rnapsofindia.corn, mapsofindia.com +newlook.corn, newlook.com +holiday-weather.corn, holiday-weather.com +zhe8OO.corn, zhe800.com +recipesfinder.corn, recipesfinder.com +bborn.corn.br, bbom.com.br +jalopnik.corn, jalopnik.com +canon.corn, canon.com +freshbooks.corn, freshbooks.com +clickcornpare.info, clickcompare.info +aprod.hu, aprod.hu +thisav.corn, thisav.com +boerse.bz, boerse.bz +orange.es, orange.es +forobeta.corn, forobeta.com +surfactif.fr, surfactif.fr +listverse.corn, listverse.com +feedjit.corn, feedjit.com +bni.co.id, bni.co.id +garnernazing.corn, gamemazing.com +rnbalib.corn, mbalib.com +topsy.corn, topsy.com +torchbrowser.corn, torchbrowser.com +ieee.org, ieee.org +tinydeal.corn, tinydeal.com +playdorn.corn, playdom.com +redorbit.corn, redorbit.com +inboxdollars.corn, inboxdollars.com +google.corn.bh, google.com.bh +pcanalysis.net, pcanalysis.net +acer.corn, acer.com +jizzbell.corn, jizzbell.com +google.corn.kh, google.com.kh +rnappy.corn, mappy.com +day.az, day.az +euronews.corn, euronews.com +wikidot.corn, wikidot.com +creativecornrnons.org, creativecommons.org +quantcast.corn, quantcast.com +iconarchive.corn, iconarchive.com +iyaya.corn, iyaya.com +jetstar.corn, jetstar.com +diandian.corn, diandian.com +winzip.corn, winzip.com +clixzor.corn, clixzor.com +teebik.corn, teebik.com +rneilele.corn, meilele.com +gsrn.ir, gsm.ir +dek-d.corn, dek-d.com +giantbornb.corn, giantbomb.com +tala.ir, tala.ir +extrernetracking.corn, extremetracking.com +hornevv.corn, homevv.com +truthaboutabs.corn, truthaboutabs.com +psychologytoday.corn, psychologytoday.com +vod.pl, vod.pl +rnacrornill.corn, macromill.com +arnd.corn, amd.com +livescience.corn, livescience.com +dedecrns.corn, dedecms.com +jinll5.corn, jin115.com +arnpxchange.corn, ampxchange.com +profitcentr.corn, profitcentr.com +webrnotors.corn.br, webmotors.com.br +lan.corn, lan.com +fileice.net, fileice.net +ingdirect.es, ingdirect.es +arntrak.corn, amtrak.com +ernag.ro, emag.ro +progressive.corn, progressive.com +balatarin.corn, balatarin.com +irnrnonet.de, immonet.de +e-travel.corn, e-travel.com +studyrnode.corn, studymode.com +go2OOO.corn, go2000.com +shopbop.corn, shopbop.com +filesfetcher.corn, filesfetcher.com +euroresidentes.corn, euroresidentes.com +rnovistar.es, movistar.es +lefeng.corn, lefeng.com +google.hn, google.hn +hornestead.corn, homestead.com +filesonar.corn, filesonar.com +hsbccreditcard.corn, hsbccreditcard.com +google.corn.np, google.com.np +parperfeito.corn.br, parperfeito.com.br +sciencedaily.corn, sciencedaily.com +realgfporn.corn, realgfporn.com +wonderhowto.corn, wonderhowto.com +coolrorn.corn, coolrom.com +wikibooks.org, wikibooks.org +archdaily.corn, archdaily.com +gigazine.net, gigazine.net +totaljerkface.corn, totaljerkface.com +bezaat.corn, bezaat.com +eurosport.corn, eurosport.com +fontspace.corn, fontspace.com +tirage24.corn, tirage24.com +bancorner.corn.rnx, bancomer.com.mx +nasdaq.corn, nasdaq.com +bravoteens.corn, bravoteens.com +bdjobs.corn, bdjobs.com +zirnbra.free.fr, zimbra.free.fr +arsenal.corn, arsenal.com +rabota.ru, rabota.ru +lovefilrn.corn, lovefilm.com +tsetrnc.corn, tsetmc.com +rnovshare.net, movshare.net +debonairblog.corn, debonairblog.com +zrnovie.co, zmovie.co +peoplefinders.corn, peoplefinders.com +rnercadolibre.corn, mercadolibre.com +connectlondoner.corn, connectlondoner.com +forbes.ru, forbes.ru +gagnezauxoptions.corn, gagnezauxoptions.com +taikang.corn, taikang.com +rnywapblog.corn, mywapblog.com +citysearch.corn, citysearch.com +novafinanza.corn, novafinanza.com +gruposantander.es, gruposantander.es +relianceada.corn, relianceada.com +rankingsandreviews.corn, rankingsandreviews.com +hjenglish.corn, hjenglish.com +state.nj.us, state.nj.us +corndirect.de, comdirect.de +claro.corn.br, claro.com.br +alluc.to, alluc.to +godlikeproductions.corn, godlikeproductions.com +lowyat.net, lowyat.net +dawn.corn, dawn.com +l8xgirls.corn, 18xgirls.com +origo.hu, origo.hu +loopnet.corn, loopnet.com +payu.in, payu.in +digitalrnedia-cornunicacion.corn, digitalmedia-comunicacion.com +newsvine.corn, newsvine.com +petfinder.corn, petfinder.com +kuaibo.corn, kuaibo.com +soft32.corn, soft32.com +yellowpages.ca, yellowpages.ca +lfichier.corn, 1fichier.com +egyup.corn, egyup.com +iskullgarnes.corn, iskullgames.com +androidforurns.corn, androidforums.com +blogspot.cz, blogspot.cz +urnich.edu, umich.edu +rnadsextube.corn, madsextube.com +bigcinerna.tv, bigcinema.tv +donedeal.ie, donedeal.ie +winporn.corn, winporn.com +cosrnopolitan.corn, cosmopolitan.com +reg.ru, reg.ru +localrnoxie.corn, localmoxie.com +kootation.corn, kootation.com +gidonline.ru, gidonline.ru +clipconverter.cc, clipconverter.cc +gioco.it, gioco.it +ravelry.corn, ravelry.com +gettyirnages.corn, gettyimages.com +rnedicalnewsreporter.corn, medicalnewsreporter.com +shop4ll.corn, shop411.com +aif.ru, aif.ru +journaldesfernrnes.corn, journaldesfemmes.com +blogcu.corn, blogcu.com +vanguard.corn, vanguard.com +freernp3go.corn, freemp3go.com +google.ci, google.ci +findicons.corn, findicons.com +tineye.corn, tineye.com +webdesignerdepot.corn, webdesignerdepot.com +nornorerack.corn, nomorerack.com +iqoo.rne, iqoo.me +arnarujala.corn, amarujala.com +pengfu.corn, pengfu.com +leadpages.net, leadpages.net +zalukaj.tv, zalukaj.tv +avon.corn, avon.com +casasbahia.corn.br, casasbahia.com.br +juegosdechicas.corn, juegosdechicas.com +tvrain.ru, tvrain.ru +askrnefast.corn, askmefast.com +stockcharts.corn, stockcharts.com +footlocker.corn, footlocker.com +allanalpass.corn, allanalpass.com +theoatrneal.corn, theoatmeal.com +storify.corn, storify.com +santander.corn.br, santander.com.br +laughnfiddle.corn, laughnfiddle.com +lornadee.corn, lomadee.com +aftenposten.no, aftenposten.no +larnoda.ru, lamoda.ru +tasteofhorne.corn, tasteofhome.com +news247.gr, news247.gr +sherdog.corn, sherdog.com +rnilb.corn, milb.com +3djuegos.corn, 3djuegos.com +drearnrnovies.corn, dreammovies.com +cornrnonfloor.corn, commonfloor.com +tharunee.lk, tharunee.lk +chatrandorn.corn, chatrandom.com +rechargeitnow.corn, rechargeitnow.com +arnl5.net, am15.net +sexad.net, sexad.net +herokuapp.corn, herokuapp.com +apontador.corn.br, apontador.com.br +rfi.fr, rfi.fr +woozworld.corn, woozworld.com +hitta.se, hitta.se +cornedycentral.corn, comedycentral.com +fbsbx.corn, fbsbx.com +aftabnews.ir, aftabnews.ir +stepstone.de, stepstone.de +filrnon.corn, filmon.com +arneritrade.corn, ameritrade.com +ecitic.corn, ecitic.com +bola.net, bola.net +hq-sex-tube.corn, hq-sex-tube.com +gsp.ro, gsp.ro +groupon.co.uk, groupon.co.uk +2Ornin.ch, 20min.ch +barclaycardus.corn, barclaycardus.com +dice.corn, dice.com +hirnasoku.corn, himasoku.com +nwsource.corn, nwsource.com +gougou.corn, gougou.com +iol.co.za, iol.co.za +thinkgeek.corn, thinkgeek.com +governrnentjobs.corn, governmentjobs.com +5OO.corn, 500.com +caixin.corn, caixin.com +elsevier.corn, elsevier.com +rafflecopter.corn, rafflecopter.com +auctiva.corn, auctiva.com +pracuj.pl, pracuj.pl +strato.de, strato.de +ricardoeletro.corn.br, ricardoeletro.com.br +vodafone.de, vodafone.de +jike.corn, jike.com +srnosh.corn, smosh.com +downlite.net, downlite.net +to8to.corn, to8to.com +tikona.in, tikona.in +royalrnail.corn, royalmail.com +tripadvisor.de, tripadvisor.de +realclearpolitics.corn, realclearpolitics.com +pubdirecte.corn, pubdirecte.com +rassd.corn, rassd.com +ptt.cc, ptt.cc +townhall.corn, townhall.com +theoldreader.corn, theoldreader.com +viki.corn, viki.com +one.corn, one.com +peopleperhour.corn, peopleperhour.com +desidirne.corn, desidime.com +l7track.net, 17track.net +duote.corn, duote.com +ernuch.net, emuch.net +rnlgarne.co.uk, mlgame.co.uk +rockstargarnes.corn, rockstargames.com +slaati.corn, slaati.com +ibibo.corn, ibibo.com +journaldunet.corn, journaldunet.com +ria.ua, ria.ua +odatv.corn, odatv.com +cornodo.corn, comodo.com +clickfair.corn, clickfair.com +systern5OO.corn, system500.com +wordstrearn.corn, wordstream.com +alexaboostup.corn, alexaboostup.com +yjbys.corn, yjbys.com +hsbc.corn, hsbc.com +online-convert.corn, online-convert.com +rniui.corn, miui.com +totaljobs.corn, totaljobs.com +travian.fr, travian.fr +funda.nl, funda.nl +bazos.sk, bazos.sk +efukt.corn, efukt.com +startlap.corn, startlap.com +hir24.hu, hir24.hu +rnrskin.corn, mrskin.com +dbs.corn, dbs.com +sevenforurns.corn, sevenforums.com +adrnitad.corn, admitad.com +graaarn.corn, graaam.com +exactrne.corn, exactme.com +roadrunner.corn, roadrunner.com +liberation.fr, liberation.fr +cas.sk, cas.sk +redbubble.corn, redbubble.com +ezilon.corn, ezilon.com +hihi2.corn, hihi2.com +net.hr, net.hr +rnediaite.corn, mediaite.com +clip2net.corn, clip2net.com +wapka.rnobi, wapka.mobi +dailybasis.corn, dailybasis.com +o2online.de, o2online.de +tweetdeck.corn, tweetdeck.com +fakt.pl, fakt.pl +service-public.fr, service-public.fr +bodisparking.corn, bodisparking.com +corporationwiki.corn, corporationwiki.com +jandan.net, jandan.net +alisoft.corn, alisoft.com +gosuslugi.ru, gosuslugi.ru +grxf.corn, grxf.com +daserste.de, daserste.de +freedigitalphotos.net, freedigitalphotos.net +flirchi.ru, flirchi.ru +htrnlbook.ru, htmlbook.ru +independent.ie, independent.ie +bufferapp.corn, bufferapp.com +panzar.corn, panzar.com +sport.cz, sport.cz +rnatorneantena.corn, matomeantena.com +thenewporn.corn, thenewporn.com +iran-tejarat.corn, iran-tejarat.com +rotoworld.corn, rotoworld.com +rnaalairnalar.corn, maalaimalar.com +poppen.de, poppen.de +csfd.cz, csfd.cz +2ip.ru, 2ip.ru +hawarner.corn, hawamer.com +telkornsel.corn, telkomsel.com +un.org, un.org +autobinaryea.corn, autobinaryea.com +erngoldex.corn, emgoldex.com +saksfifthavenue.corn, saksfifthavenue.com +realtor.ca, realtor.ca +hdwallpapers.in, hdwallpapers.in +chinahr.corn, chinahr.com +niazerooz.corn, niazerooz.com +sina.corn, sina.com +kinopod.ru, kinopod.ru +funweek.it, funweek.it +pornsake.corn, pornsake.com +vitacost.corn, vitacost.com +llO.corn, 110.com +jobornas.corn, jobomas.com +joyreactor.cc, joyreactor.cc +3dnews.ru, 3dnews.ru +vedornosti.ru, vedomosti.ru +stansberryresearch.corn, stansberryresearch.com +perforrnersoft.corn, performersoft.com +codecaderny.corn, codecademy.com +petsrnart.corn, petsmart.com +kissrnetrics.corn, kissmetrics.com +infojobs.it, infojobs.it +wealink.corn, wealink.com +rapidtrk.corn, rapidtrk.com +enterprise.corn, enterprise.com +iran-forurn.ir, iran-forum.ir +express-files.corn, express-files.com +cyberpresse.ca, cyberpresse.ca +dobreprograrny.pl, dobreprogramy.pl +uploading.corn, uploading.com +profitclicking.corn, profitclicking.com +playwartune.corn, playwartune.com +toluna.corn, toluna.com +shoptirne.corn.br, shoptime.com.br +totaladperforrnance.corn, totaladperformance.com +handelsblatt.corn, handelsblatt.com +harnshahrionline.ir, hamshahrionline.ir +l5rnin.lt, 15min.lt +wyborcza.pl, wyborcza.pl +flvto.corn, flvto.com +rnicrosofttranslator.corn, microsofttranslator.com +trovaprezzi.it, trovaprezzi.it +eversave.corn, eversave.com +wrnzona.corn, wmzona.com +hardwarezone.corn.sg, hardwarezone.com.sg +thestar.corn.rny, thestar.com.my +siliconindia.corn, siliconindia.com +jfranews.corn, jfranews.com +ernol.corn, emol.com +nordea.fi, nordea.fi +heroturko.rne, heroturko.me +xat.corn, xat.com +3asq.corn, 3asq.com +hlntv.corn, hlntv.com +incruit.corn, incruit.com +list-rnanage2.corn, list-manage2.com +bulbagarden.net, bulbagarden.net +blogdohotelurbano.corn, blogdohotelurbano.com +suorni24.fi, suomi24.fi +nicozon.net, nicozon.net +tuporno.tv, tuporno.tv +perfectworld.corn, perfectworld.com +ayosdito.ph, ayosdito.ph +grnx.at, gmx.at +l23greetings.corn, 123greetings.com +rnetafilter.corn, metafilter.com +g9g.corn, g9g.com +searchnfind.org, searchnfind.org +pcgarner.corn, pcgamer.com +on.cc, on.cc +rentalcars.corn, rentalcars.com +rnail2web.corn, mail2web.com +zalando.it, zalando.it +freevideo.cz, freevideo.cz +source-wave.corn, source-wave.com +iranjib.ir, iranjib.ir +societe.corn, societe.com +l6Oby2.corn, 160by2.com +berooztarinha.corn, berooztarinha.com +poprnog.corn, popmog.com +fantasy8.corn, fantasy8.com +rnotortrend.corn, motortrend.com +huffingtonpost.ca, huffingtonpost.ca +5ltest.net, 51test.net +ringtonernatcher.corn, ringtonematcher.com +ourtirne.corn, ourtime.com +standardchartered.co.in, standardchartered.co.in +rdio.corn, rdio.com +parsiblog.corn, parsiblog.com +btvguide.corn, btvguide.com +sport.ro, sport.ro +freep.corn, freep.com +gisrneteo.ua, gismeteo.ua +rojadirecta.rne, rojadirecta.me +babol.pl, babol.pl +lun.corn, lun.com +epicurious.corn, epicurious.com +fetishok.corn, fetishok.com +rnystart.corn, mystart.com +wn.corn, wn.com +nationalrail.co.uk, nationalrail.co.uk +feedsportal.corn, feedsportal.com +rai.it, rai.it +sportlernon.tv, sportlemon.tv +groupon.corn.br, groupon.com.br +ebay.at, ebay.at +yourdictionary.corn, yourdictionary.com +36Osafe.corn, 360safe.com +statefarrn.corn, statefarm.com +desjardins.corn, desjardins.com +biblehub.corn, biblehub.com +rnercadolibre.cl, mercadolibre.cl +eluniversal.corn, eluniversal.com +lrytas.lt, lrytas.lt +youboy.corn, youboy.com +gratka.pl, gratka.pl +etype.corn, etype.com +reallifecarn.corn, reallifecam.com +irnp.free.fr, imp.free.fr +jobstreet.co.id, jobstreet.co.id +geenstijl.nl, geenstijl.nl +aebn.net, aebn.net +openoffice.org, openoffice.org +diythernes.corn, diythemes.com +2gis.ru, 2gis.ru +wprnu.org, wpmu.org +scrubtheweb.corn, scrubtheweb.com +dornain.corn.au, domain.com.au +buyrna.corn, buyma.com +ccbill.corn, ccbill.com +tuil8.corn, tui18.com +goforfiles.corn, goforfiles.com +billionuploads.corn, billionuploads.com +blogtalkradio.corn, blogtalkradio.com +pipl.corn, pipl.com +wallpaperswide.corn, wallpaperswide.com +tuttosport.corn, tuttosport.com +astucecherry.corn, astucecherry.com +tradingfornewbies.corn, tradingfornewbies.com +urnn.edu, umn.edu +rj.gov.br, rj.gov.br +rnlive.corn, mlive.com +justfab.corn, justfab.com +ijreview.corn, ijreview.com +daniweb.corn, daniweb.com +quickrnerne.corn, quickmeme.com +safeway.corn, safeway.com +virtualedge.corn, virtualedge.com +saudiairlines.corn, saudiairlines.com +elbotola.corn, elbotola.com +holtgarnes.corn, holtgames.com +boots.corn, boots.com +potterybarn.corn, potterybarn.com +rnediarnarkt.de, mediamarkt.de +rnangastrearn.corn, mangastream.com +rnypoints.corn, mypoints.com +torrentdownloads.rne, torrentdownloads.me +subtitleseeker.corn, subtitleseeker.com +idlebrain.corn, idlebrain.com +ekantipur.corn, ekantipur.com +nowgarnez.corn, nowgamez.com +neoseeker.corn, neoseeker.com +christianpost.corn, christianpost.com +joystiq.corn, joystiq.com +iphone-winners.info, iphone-winners.info +quizlet.corn, quizlet.com +prosport.ro, prosport.ro +quanjing.corn, quanjing.com +garnechit.corn, gamechit.com +teleshow.pl, teleshow.pl +corrieredellosport.it, corrieredellosport.it +yoo7.corn, yoo7.com +fotocasa.es, fotocasa.es +attracta.corn, attracta.com +hyatt.corn, hyatt.com +confirrnit.corn, confirmit.com +xyu.tv, xyu.tv +yoolplay.corn, yoolplay.com +active.corn, active.com +gizrnag.corn, gizmag.com +hostelworld.corn, hostelworld.com +pc6.corn, pc6.com +lacentrale.fr, lacentrale.fr +rnegasesso.corn, megasesso.com +thairath.co.th, thairath.co.th +thinkprogress.org, thinkprogress.org +4OOgb.corn, 400gb.com +rnanageflitter.corn, manageflitter.com +pronto.corn, pronto.com +erotube.org, erotube.org +luxtarget.corn, luxtarget.com +vui.vn, vui.vn +screenrant.corn, screenrant.com +nationalreview.corn, nationalreview.com +ikrnan.lk, ikman.lk +aboutus.org, aboutus.org +booloo.corn, booloo.com +klrn.corn, klm.com +aukro.ua, aukro.ua +skladchik.corn, skladchik.com +alfalfalfa.corn, alfalfalfa.com +ghanaweb.corn, ghanaweb.com +cheetahrnail.corn, cheetahmail.com +celebritynetworth.corn, celebritynetworth.com +honda.corn, honda.com +regnurn.ru, regnum.ru +rnediabistro.corn, mediabistro.com +ternplate-help.corn, template-help.com +elektroda.pl, elektroda.pl +howlifeworks.corn, howlifeworks.com +avjavjav.corn, avjavjav.com +justunfollow.corn, justunfollow.com +kindgirls.corn, kindgirls.com +xrea.corn, xrea.com +songspk.cc, songspk.cc +irnpiego24.it, impiego24.it +health.corn, health.com +whitehouse.gov, whitehouse.gov +ulozto.cz, ulozto.cz +clickindia.corn, clickindia.com +zoosnet.net, zoosnet.net +yingjiesheng.corn, yingjiesheng.com +copacet.corn, copacet.com +fluege.de, fluege.de +uiuc.edu, uiuc.edu +funnyrnarna.corn, funnymama.com +popsugar.corn, popsugar.com +siyahgazete.corn, siyahgazete.com +ligatus.corn, ligatus.com +seornastering.corn, seomastering.com +nintendo.corn, nintendo.com +kuaidilOO.corn, kuaidi100.com +rnotor-talk.de, motor-talk.de +p.ht, p.ht +care.corn, care.com +ttnet.corn.tr, ttnet.com.tr +cifraclub.corn.br, cifraclub.com.br +yunfile.corn, yunfile.com +telechargernent-de-ouf.fr, telechargement-de-ouf.fr +hotpornshow.corn, hotpornshow.com +upenn.edu, upenn.edu +brg8.corn, brg8.com +techspot.corn, techspot.com +rnilli.az, milli.az +segundarnano.rnx, segundamano.mx +n4g.corn, n4g.com +blogspot.no, blogspot.no +frys.corn, frys.com +pixhost.org, pixhost.org +washington.edu, washington.edu +rte.ie, rte.ie +lockerdorne.corn, lockerdome.com +qassirny.corn, qassimy.com +signup.wordpress.corn, signup.wordpress.com +sochiset.corn, sochiset.com +rnycokerewards.corn, mycokerewards.com +collegeboard.org, collegeboard.org +fengyunzhibo.corn, fengyunzhibo.com +twickerz.corn, twickerz.com +bikroy.corn, bikroy.com +apkrnania.co, apkmania.co +webrankstats.corn, webrankstats.com +dl-protect.corn, dl-protect.com +dr.dk, dr.dk +ernoneyspace.corn, emoneyspace.com +rae.es, rae.es +theexgirlfriends.corn, theexgirlfriends.com +gigaorn.corn, gigaom.com +burrneseclassic.corn, burmeseclassic.com +wisc.edu, wisc.edu +ocnk.net, ocnk.net +arcot.corn, arcot.com +paginasarnarillas.es, paginasamarillas.es +tunisia-sat.corn, tunisia-sat.com +rnedscape.corn, medscape.com +garneninja.corn, gameninja.com +irnperiaonline.org, imperiaonline.org +2ernernain.be, 2ememain.be +rnyshopping.corn.au, myshopping.com.au +nvidia.corn, nvidia.com +fanhuan.corn, fanhuan.com +vista.ir, vista.ir +dish.corn, dish.com +cartrade.corn, cartrade.com +egopay.corn, egopay.com +sonyentertainrnentnetwork.corn, sonyentertainmentnetwork.com +rnyway.corn, myway.com +kariyer.net, kariyer.net +thanhnien.corn.vn, thanhnien.com.vn +gulfnews.corn, gulfnews.com +flagcounter.corn, flagcounter.com +yfrog.corn, yfrog.com +bigstockphoto.corn, bigstockphoto.com +occ.corn.rnx, occ.com.mx +39ll.net, 3911.net +naszerniasto.pl, naszemiasto.pl +pgatour.corn, pgatour.com +zgjrw.corn, zgjrw.com +fdj.fr, fdj.fr +rnotogp.corn, motogp.com +organogold.corn, organogold.com +tarnindir.corn, tamindir.com +ykb.corn, ykb.com +biglion.ru, biglion.ru +yourfiledownloader.corn, yourfiledownloader.com +publika.az, publika.az +dealnews.corn, dealnews.com +warnerbros.corn, warnerbros.com +wprnudev.org, wpmudev.org +pu-results.info, pu-results.info +usajobs.gov, usajobs.gov +adsprofitwiz.es, adsprofitwiz.es +parallels.corn, parallels.com +thqafawe3lorn.corn, thqafawe3lom.com +xiazaiba.corn, xiazaiba.com +enikos.gr, enikos.gr +rn5zn.corn, m5zn.com +dir.bg, dir.bg +ripoffreport.corn, ripoffreport.com +jusbrasil.corn.br, jusbrasil.com.br +rnaxifoot.fr, maxifoot.fr +eva.vn, eva.vn +dfnhk8.net, dfnhk8.net +api.ning.corn, api.ning.com +ligtv.corn.tr, ligtv.com.tr +openrice.corn, openrice.com +999l2O.net, 999120.net +pho.to, pho.to +indiblogger.in, indiblogger.in +tfile.rne, tfile.me +kotak.corn, kotak.com +katproxy.corn, katproxy.com +calottery.corn, calottery.com +klrnty.net, klmty.net +endornondo.corn, endomondo.com +uploadboy.corn, uploadboy.com +8tracks.corn, 8tracks.com +blox.pl, blox.pl +conrad.de, conrad.de +sonico.corn, sonico.com +windguru.cz, windguru.cz +tinhte.vn, tinhte.vn +grantland.corn, grantland.com +seratnews.ir, seratnews.ir +solornono.ru, solomono.ru +foreca.corn, foreca.com +ziprecruiter.corn, ziprecruiter.com +chirne.in, chime.in +intesasanpaolo.corn, intesasanpaolo.com +softonic.de, softonic.de +adtech.info, adtech.info +appgarne.corn, appgame.com +opendns.corn, opendns.com +tubekitty.corn, tubekitty.com +linguee.de, linguee.de +pepperfry.corn, pepperfry.com +egou.corn, egou.com +tweakers.net, tweakers.net +alfavita.gr, alfavita.gr +plusnetwork.corn, plusnetwork.com +tirneweb.ru, timeweb.ru +rnaybeporn.corn, maybeporn.com +gharreh.corn, gharreh.com +canoe.ca, canoe.ca +parsine.corn, parsine.com +ucla.edu, ucla.edu +freeridegarnes.corn, freeridegames.com +doctoroz.corn, doctoroz.com +tradeindia.corn, tradeindia.com +socialrnediabar.corn, socialmediabar.com +yaske.net, yaske.net +rniniih.corn, miniih.com +blog.rne, blog.me +dn.se, dn.se +alrnos3a.corn, almos3a.com +bbvanet.corn.rnx, bbvanet.com.mx +fcbarcelona.corn, fcbarcelona.com +web.corn, web.com +raaga.corn, raaga.com +yad2.co.il, yad2.co.il +2cto.corn, 2cto.com +nx8.corn, nx8.com +rnodcloth.corn, modcloth.com +carsales.corn.au, carsales.com.au +cooks.corn, cooks.com +fileswap.corn, fileswap.com +egyptiansnews.corn, egyptiansnews.com +azyya.corn, azyya.com +rnasreat.corn, masreat.com +airliners.net, airliners.net +corn-lb.info, com-1b.info +virginrnobileusa.corn, virginmobileusa.com +pleasantharborrv.corn, pleasantharborrv.com +gsrnhosting.corn, gsmhosting.com +foxbusiness.corn, foxbusiness.com +delfi.lv, delfi.lv +flightaware.corn, flightaware.com +arneli.fr, ameli.fr +fbxtk.corn, fbxtk.com +purdue.edu, purdue.edu +sbi.co.in, sbi.co.in +fotka.pl, fotka.pl +quicksprout.corn, quicksprout.com +arjwana.corn, arjwana.com +affili.net, affili.net +5sing.corn, 5sing.com +rnozilla.corn, mozilla.com +taaza.corn, taaza.com +onetad.corn, onetad.com +vivastreet.it, vivastreet.it +leguide.corn, leguide.com +casualclub.corn, casualclub.com +wanelo.corn, wanelo.com +ipsosinteractive.corn, ipsosinteractive.com +videohive.net, videohive.net +fenzhi.corn, fenzhi.com +lefrecce.it, lefrecce.it +bugun.corn.tr, bugun.com.tr +p3Oworld.corn, p30world.com +cuevana.tv, cuevana.tv +joins.corn, joins.com +tvnet.lv, tvnet.lv +aliirng.corn, aliimg.com +bellanaija.corn, bellanaija.com +startpagina.nl, startpagina.nl +incornetaxindiaefiling.gov.in, incometaxindiaefiling.gov.in +rnichigan.gov, michigan.gov +harborfreight.corn, harborfreight.com +fineartarnerica.corn, fineartamerica.com +rnysurvey.corn, mysurvey.com +kapaza.be, kapaza.be +adxpansion.corn, adxpansion.com +thefind.corn, thefind.com +priyo.corn, priyo.com +burrp.corn, burrp.com +sky.it, sky.it +ipad-winners.info, ipad-winners.info +usgs.gov, usgs.gov +gavick.corn, gavick.com +ellislab.corn, ellislab.com +voegol.corn.br, voegol.com.br +paginebianche.it, paginebianche.it +getwebcake.corn, getwebcake.com +zeroredirectl.corn, zeroredirect1.com +gaiaonline.corn, gaiaonline.com +iqilu.corn, iqilu.com +bright.corn, bright.com +cornunidades.net, comunidades.net +webgains.corn, webgains.com +overdrive.corn, overdrive.com +bigcornrnerce.corn, bigcommerce.com +paperpkads.corn, paperpkads.com +irnageporter.corn, imageporter.com +listal.corn, listal.com +rbcdaily.ru, rbcdaily.ru +redbus.in, redbus.in +3brneteo.corn, 3bmeteo.com +earn-on.corn, earn-on.com +ae.corn, ae.com +shoutrneloud.corn, shoutmeloud.com +oeeee.corn, oeeee.com +usenet.nl, usenet.nl +rnediotiernpo.corn, mediotiempo.com +prostoporno.net, prostoporno.net +bangyoulater.corn, bangyoulater.com +cornunio.de, comunio.de +pureleads.corn, pureleads.com +bakeca.it, bakeca.it +trovit.it, trovit.it +fakku.net, fakku.net +indeed.fr, indeed.fr +inquisitr.corn, inquisitr.com +wizards.corn, wizards.com +straightdope.corn, straightdope.com +pornpros.corn, pornpros.com +s-ornan.net, s-oman.net +facilisirno.corn, facilisimo.com +dostor.org, dostor.org +tabloidpulsa.co.id, tabloidpulsa.co.id +shafaf.ir, shafaf.ir +bt.dk, bt.dk +lent.az, lent.az +filrnaffinity.corn, filmaffinity.com +wjunction.corn, wjunction.com +garnefront.corn, gamefront.com +photoshelter.corn, photoshelter.com +cheaptickets.corn, cheaptickets.com +rneetic.it, meetic.it +seochat.corn, seochat.com +livernixtapes.corn, livemixtapes.com +deadline.corn, deadline.com +boingboing.net, boingboing.net +lecai.corn, lecai.com +onetravel.corn, onetravel.com +erotictube.rne, erotictube.me +svd.se, svd.se +pcadvisor.co.uk, pcadvisor.co.uk +pravda.corn.ua, pravda.com.ua +afisha.ru, afisha.ru +dressupgarnesite.corn, dressupgamesite.com +rnercadopago.corn, mercadopago.com +bangkokpost.corn, bangkokpost.com +durnpert.nl, dumpert.nl +rnonotaro.corn, monotaro.com +bloorningdales.corn, bloomingdales.com +ebayclassifieds.corn, ebayclassifieds.com +t-online.hu, t-online.hu +2dbook.corn, 2dbook.com +thekitchn.corn, thekitchn.com +halifax.co.uk, halifax.co.uk +tanx.corn, tanx.com +jutarnji.hr, jutarnji.hr +petardashd.corn, petardashd.com +rookee.ru, rookee.ru +showroornprive.corn, showroomprive.com +sharepoint.corn, sharepoint.com +liebiao.corn, liebiao.com +purnbaporn.corn, pumbaporn.com +dwnews.corn, dwnews.com +sanguosha.corn, sanguosha.com +pp.cc, pp.cc +rnyfc.ir, myfc.ir +alicdn.corn, alicdn.com +carrnax.corn, carmax.com +defencenet.gr, defencenet.gr +cuantarazon.corn, cuantarazon.com +westernunion.corn, westernunion.com +natunbarta.corn, natunbarta.com +sekindo.corn, sekindo.com +edublogs.org, edublogs.org +hotrnail.corn, hotmail.com +problogger.net, problogger.net +arnardeshonline.corn, amardeshonline.com +gernius.corn, gemius.com +egynews.net, egynews.net +indiabix.corn, indiabix.com +provincial.corn, provincial.com +play.corn, play.com +beslist.nl, beslist.nl +shape.corn, shape.com +alhilal.corn, alhilal.com +irecornrnend.ru, irecommend.ru +crnrnnts.corn, cmmnts.com +lnews.az, 1news.az +kinobanda.net, kinobanda.net +banarnex.corn.rnx, banamex.com.mx +cleanfiles.net, cleanfiles.net +algeriaforurn.net, algeriaforum.net +zurni.pl, zumi.pl +giallozafferano.it, giallozafferano.it +news-postseven.corn, news-postseven.com +firstcry.corn, firstcry.com +lookforporn.corn, lookforporn.com +xxsy.net, xxsy.net +scriptrnafia.org, scriptmafia.org +intodns.corn, intodns.com +farnitsu.corn, famitsu.com +eclipse.org, eclipse.org +net-a-porter.corn, net-a-porter.com +bternplates.corn, btemplates.com +topshop.corn, topshop.com +rnyvidster.corn, myvidster.com +calciornercato.corn, calciomercato.com +arabyonline.corn, arabyonline.com +lesechos.fr, lesechos.fr +ernpireavenue.corn, empireavenue.com +darnnlol.corn, damnlol.com +nukistrearn.corn, nukistream.com +wayport.net, wayport.net +buienradar.nl, buienradar.nl +vivastreet.co.in, vivastreet.co.in +kroger.corn, kroger.com +geocaching.corn, geocaching.com +hunantv.corn, hunantv.com +fotolog.net, fotolog.net +gunbroker.corn, gunbroker.com +flalottery.corn, flalottery.com +priples.corn, priples.com +nlayer.net, nlayer.net +trafficshop.corn, trafficshop.com +standardrnedia.co.ke, standardmedia.co.ke +finanzen.net, finanzen.net +rneta.ua, meta.ua +gfy.corn, gfy.com +playground.ru, playground.ru +rp5.ru, rp5.ru +otnnetwork.net, otnnetwork.net +tvrnao.corn, tvmao.com +hir.rna, hir.ma +twilightsex.corn, twilightsex.com +haodou.corn, haodou.com +virgin-atlantic.corn, virgin-atlantic.com +ankieta-online.pl, ankieta-online.pl +kinkytube.rne, kinkytube.me +l23rnplayer.corn, 123mplayer.com +elifting.corn, elifting.com +akiba-online.corn, akiba-online.com +tcsbank.ru, tcsbank.ru +garnetrailers.corn, gametrailers.com +dihitt.corn, dihitt.com +fancy.corn, fancy.com +adrnairnai.corn, admaimai.com +6l.corn, 61.com +hotchatdirect.corn, hotchatdirect.com +penesalud.corn, penesalud.com +adsupplyads.corn, adsupplyads.com +robokassa.ru, robokassa.ru +brooonzyah.net, brooonzyah.net +rnoviesrnobile.net, moviesmobile.net +fuck-rnates.corn, fuck-mates.com +ch-news.corn, ch-news.com +cwan.corn, cwan.com +rnec.gov.br, mec.gov.br +rnusiciansfriend.corn, musiciansfriend.com +angrybirds.corn, angrybirds.com +ebrun.corn, ebrun.com +kienthuc.net.vn, kienthuc.net.vn +rnorningstar.corn, morningstar.com +rasekhoon.net, rasekhoon.net +techsrnith.corn, techsmith.com +diy.corn, diy.com +awwwards.corn, awwwards.com +ajc.corn, ajc.com +akisrnet.corn, akismet.com +itar-tass.corn, itar-tass.com +6Osecprofit.corn, 60secprofit.com +videoweed.es, videoweed.es +guitarcenter.corn, guitarcenter.com +tv2.dk, tv2.dk +narutorn.corn, narutom.com +bittorrent.corn, bittorrent.com +unionpaysecure.corn, unionpaysecure.com +9ljrn.corn, 91jm.com +licindia.in, licindia.in +barna.ir, bama.ir +hertz.corn, hertz.com +propertyguru.corn.sg, propertyguru.com.sg +city8.corn, city8.com +blu-ray.corn, blu-ray.com +abebooks.corn, abebooks.com +adidas.corn, adidas.com +sing365.corn, sing365.com +qql63.corn, qq163.com +fashionandyou.corn, fashionandyou.com +lietou.corn, lietou.com +eniro.se, eniro.se +pengpeng.corn, pengpeng.com +haibao.corn, haibao.com +jxedt.corn, jxedt.com +crsky.corn, crsky.com +nyu.edu, nyu.edu +rninecraftskins.corn, minecraftskins.com +yangtse.corn, yangtse.com +alrnstba.co, almstba.co +parsnews.corn, parsnews.com +twiends.corn, twiends.com +dkb.de, dkb.de +friendscout24.de, friendscout24.de +aviny.corn, aviny.com +dig.do, dig.do +garnestorrents.corn, gamestorrents.com +guru.corn, guru.com +bostonglobe.corn, bostonglobe.com +brandalley.fr, brandalley.fr +tn.corn.ar, tn.com.ar +yourwebsite.corn, yourwebsite.com +istgah.corn, istgah.com +e-farnilynet.corn, e-familynet.com +hotsharne.corn, hotshame.com +volkskrant.nl, volkskrant.nl +karnaval.corn, karnaval.com +tearn-bhp.corn, team-bhp.com +sinernalar.corn, sinemalar.com +ipko.pl, ipko.pl +fastcornpany.corn, fastcompany.com +ernbedupload.corn, embedupload.com +gzrnarna.corn, gzmama.com +icicidirect.corn, icicidirect.com +whatisrnyip.corn, whatismyip.com +siasat.pk, siasat.pk +rbi.org.in, rbi.org.in +arnarillasinternet.corn, amarillasinternet.com +netvasco.corn.br, netvasco.com.br +ctvnews.ca, ctvnews.ca +gad.de, gad.de +dailyfx.corn, dailyfx.com +srnartklicks.corn, smartklicks.com +qoolO.sg, qoo10.sg +loc.gov, loc.gov +playerflv.corn, playerflv.com +uta-net.corn, uta-net.com +afl.corn.au, afl.com.au +rnainlink.ru, mainlink.ru +pricedekho.corn, pricedekho.com +wickedfire.corn, wickedfire.com +rlslog.net, rlslog.net +raiffeisen.at, raiffeisen.at +easports.corn, easports.com +groupon.fr, groupon.fr +o2.co.uk, o2.co.uk +irangrand.ir, irangrand.ir +vuku.tv, vuku.tv +play.pl, play.pl +rnxtoolbox.corn, mxtoolbox.com +prorniflash.de, promiflash.de +linode.corn, linode.com +farnilysearch.org, familysearch.org +publico.pt, publico.pt +freepornvideo.rne, freepornvideo.me +uploadbaz.corn, uploadbaz.com +tocrnai.ro, tocmai.ro +cirnbclicks.corn.rny, cimbclicks.com.my +bestporntube.rne, bestporntube.me +lainforrnacion.corn, lainformacion.com +herschina.corn, herschina.com +fontsquirrel.corn, fontsquirrel.com +blip.tv, blip.tv +caranddriver.corn, caranddriver.com +qld.gov.au, qld.gov.au +pons.eu, pons.eu +nascar.corn, nascar.com +hrsrnart.corn, hrsmart.com +tripadvisor.corn.au, tripadvisor.com.au +hs.fi, hs.fi +auspost.corn.au, auspost.com.au +sponsoredreviews.corn, sponsoredreviews.com +webopedia.corn, webopedia.com +sovsport.ru, sovsport.ru +bancsabadell.corn, bancsabadell.com +prettyporntube.corn, prettyporntube.com +sodahead.corn, sodahead.com +ovi.corn, ovi.com +aleseriale.pl, aleseriale.pl +rnnwan.corn, mnwan.com +callofduty.corn, callofduty.com +sportskeeda.corn, sportskeeda.com +cp.cx, cp.cx +researchgate.net, researchgate.net +rnichaels.corn, michaels.com +createspace.corn, createspace.com +sprintrade.corn, sprintrade.com +anonyrnouse.org, anonymouse.org +hautelook.corn, hautelook.com +4garner.net, 4gamer.net +accorhotels.corn, accorhotels.com +roornkey.corn, roomkey.com +guildwars2.corn, guildwars2.com +cargurus.corn, cargurus.com +wpengine.corn, wpengine.com +iis.net, iis.net +vendaria.corn, vendaria.com +argentinawarez.corn, argentinawarez.com +webdesigntunes.corn, webdesigntunes.com +allvoices.corn, allvoices.com +eprize.corn, eprize.com +prnu.fr, pmu.fr +carrefour.fr, carrefour.fr +tax.gov.ir, tax.gov.ir +ruelala.corn, ruelala.com +rnainspy.ru, mainspy.ru +phpwind.net, phpwind.net +loteriasyapuestas.es, loteriasyapuestas.es +rnusavat.corn, musavat.com +lenskart.corn, lenskart.com +refinery29.corn, refinery29.com +888poker.es, 888poker.es +denverpost.corn, denverpost.com +who.int, who.int +thesirns3.corn, thesims3.com +jerkhour.corn, jerkhour.com +lyricsrnode.corn, lyricsmode.com +ivillage.corn, ivillage.com +qyer.corn, qyer.com +hktdc.corn, hktdc.com +pornoload.corn, pornoload.com +bluedart.corn, bluedart.com +here.corn, here.com +philips.corn, philips.com +dsebd.org, dsebd.org +tubidy.rnobi, tubidy.mobi +strearn.cz, stream.cz +infojobs.corn.br, infojobs.com.br +soft98.ir, soft98.ir +bolsaparanovatos.corn, bolsaparanovatos.com +rnercador.ro, mercador.ro +neogaf.corn, neogaf.com +yardbarker.corn, yardbarker.com +rapidlibrary.corn, rapidlibrary.com +xxeronetxx.info, xxeronetxx.info +kaiserperrnanente.org, kaiserpermanente.org +telstra.corn.au, telstra.com.au +contra.gr, contra.gr +laredoute.it, laredoute.it +lipsurn.corn, lipsum.com +twitlonger.corn, twitlonger.com +hln.be, hln.be +53kf.corn, 53kf.com +gofundrne.corn, gofundme.com +carigold.corn, carigold.com +clips4sale.corn, clips4sale.com +focalprice.corn, focalprice.com +garneaholic.corn, gameaholic.com +presstv.ir, presstv.ir +puu.sh, puu.sh +filrnlinks4u.net, filmlinks4u.net +traffic-delivery.corn, traffic-delivery.com +bebo.corn, bebo.com +enter.ru, enter.ru +shufoo.net, shufoo.net +vivo.corn.br, vivo.com.br +jizzhut.corn, jizzhut.com +ljux.net, 1jux.net +serebii.net, serebii.net +translate.ru, translate.ru +rntv3.fi, mtv3.fi +njuskalo.hr, njuskalo.hr +bell.ca, bell.ca +rnyheritage.corn, myheritage.com +cic.fr, cic.fr +rnercurynews.corn, mercurynews.com +alaan.tv, alaan.tv +econsultancy.corn, econsultancy.com +pornhost.corn, pornhost.com +a8.net, a8.net +netzero.net, netzero.net +tracklablOl.corn, tracklab101.com +spanishdict.corn, spanishdict.com +arnctv.corn, amctv.com +erepublik.corn, erepublik.com +rnk.ru, mk.ru +publico.es, publico.es +fux.corn, fux.com +webcarntoy.corn, webcamtoy.com +rahnarna.corn, rahnama.com +wanyh.corn, wanyh.com +ecplaza.net, ecplaza.net +rnol.gov.sa, mol.gov.sa +torrentday.corn, torrentday.com +hsbc.corn.br, hsbc.com.br +interoperabilitybridges.corn, interoperabilitybridges.com +billrnelater.corn, billmelater.com +speedanalysis.corn, speedanalysis.com +volusion.corn, volusion.com +rnixcloud.corn, mixcloud.com +weeronline.nl, weeronline.nl +tiancity.corn, tiancity.com +thehun.corn, thehun.com +cornparisons.org, comparisons.org +eurosport.ru, eurosport.ru +trendyol.corn, trendyol.com +7l2O.corn, 7120.com +eldiariodearnerica.corn, eldiariodeamerica.com +fap8.corn, fap8.com +joyrne.corn, joyme.com +ufl.edu, ufl.edu +cuantocabron.corn, cuantocabron.com +hotrnart.corn.br, hotmart.com.br +wolfrarnalpha.corn, wolframalpha.com +cpasbien.corn, cpasbien.com +sanalpazar.corn, sanalpazar.com +publipt.corn, publipt.com +9ku.corn, 9ku.com +officernax.corn, officemax.com +cuny.edu, cuny.edu +gern.pl, gem.pl +waelelebrashy.corn, waelelebrashy.com +coinrnill.corn, coinmill.com +bet.corn, bet.com +rnoskva.frn, moskva.fm +groupalia.corn, groupalia.com +l3l.corn, 131.com +pichak.net, pichak.net +theatlanticwire.corn, theatlanticwire.com +laptoprnag.corn, laptopmag.com +worldpay.corn, worldpay.com +groupon.pl, groupon.pl +irneirnarna.corn, imeimama.com +torrents.net, torrents.net +britishcouncil.org, britishcouncil.org +letsbonus.corn, letsbonus.com +e-rnonsite.corn, e-monsite.com +url.org, url.org +discuz.corn, discuz.com +freepornsite.rne, freepornsite.me +cheatcc.corn, cheatcc.com +rnagicrnovies.corn, magicmovies.com +lateroorns.corn, laterooms.com +du.ac.in, du.ac.in +uservoice.corn, uservoice.com +discas.net, discas.net +dlg.corn, d1g.com +explicittube.corn, explicittube.com +e-autopay.corn, e-autopay.com +3lian.corn, 3lian.com +oopsrnovs.corn, oopsmovs.com +agenziaentrate.gov.it, agenziaentrate.gov.it +ufc.corn, ufc.com +rnooshare.biz, mooshare.biz +ankangO6.org, ankang06.org +betradar.corn, betradar.com +explosrn.net, explosm.net +silkroad.corn, silkroad.com +crackberry.corn, crackberry.com +toyota.corn, toyota.com +bongda.corn.vn, bongda.com.vn +europapress.es, europapress.es +rnlxchange.corn, mlxchange.com +plius.lt, plius.lt +pitchfork.corn, pitchfork.com +groupon.de, groupon.de +hollisterco.corn, hollisterco.com +hasoffers.corn, hasoffers.com +rniarni.corn, miami.com +dslreports.corn, dslreports.com +blinkweb.corn, blinkweb.com +alarnaula.corn, alamaula.com +leonardo.it, leonardo.it +very.co.uk, very.co.uk +globalsources.corn, globalsources.com +viator.corn, viator.com +greenwichrneantirne.corn, greenwichmeantime.com +appannie.corn, appannie.com +eldorado.ru, eldorado.ru +canadiantire.ca, canadiantire.ca +enjin.corn, enjin.com +szhorne.corn, szhome.com +phirn3s.net, phim3s.net +bash.irn, bash.im +irnrni.gov.au, immi.gov.au +enjoydressup.corn, enjoydressup.com +thesuperficial.corn, thesuperficial.com +9lrnobiles.corn, 91mobiles.com +libertaddigital.corn, libertaddigital.com +po-kaki-to.corn, po-kaki-to.com +truelocal.corn.au, truelocal.com.au +centrurn24.pl, centrum24.pl +zylorn.corn, zylom.com +rnypornrnotion.corn, mypornmotion.com +skybet.corn, skybet.com +soccerrnanager.corn, soccermanager.com +poriborton.corn, poriborton.com +rnozzi.corn, mozzi.com +eset.corn, eset.com +chelseafc.corn, chelseafc.com +arnulyarn.in, amulyam.in +argaarn.corn, argaam.com +rnnn.corn, mnn.com +papystrearning.corn, papystreaming.com +hostelbookers.corn, hostelbookers.com +vatera.hu, vatera.hu +pciconcursos.corn.br, pciconcursos.com.br +rnilenio.corn, milenio.com +yellowbook.corn, yellowbook.com +rnobilepriceindia.co.in, mobilepriceindia.co.in +naked.corn, naked.com +lazada.vn, lazada.vn +7Oe.corn, 70e.com +rnapy.cz, mapy.cz +vodafone.es, vodafone.es +zbiornik.corn, zbiornik.com +fc2web.corn, fc2web.com +rghost.ru, rghost.ru +avvo.corn, avvo.com +fardanews.corn, fardanews.com +pcbeta.corn, pcbeta.com +hibapress.corn, hibapress.com +garnehouse.corn, gamehouse.com +rnacworld.corn, macworld.com +qantas.corn.au, qantas.com.au +dba.dk, dba.dk +inttrax.corn, inttrax.com +conejox.corn, conejox.com +irnrnobiliare.it, immobiliare.it +sparkasse.at, sparkasse.at +uderny.corn, udemy.com +accenture.corn, accenture.com +pokerstrategy.corn, pokerstrategy.com +leroyrnerlin.fr, leroymerlin.fr +sweetkiss.rne, sweetkiss.me +siriusxrn.corn, siriusxm.com +nieuwsblad.be, nieuwsblad.be +blogun.ru, blogun.ru +ojogos.corn.br, ojogos.com.br +lexilogos.corn, lexilogos.com +c-and-a.corn, c-and-a.com +authorstrearn.corn, authorstream.com +newser.corn, newser.com +rninube.corn, minube.com +yellowpages.corn.au, yellowpages.com.au +torrentfreak.corn, torrentfreak.com +expatriates.corn, expatriates.com +5lcredit.corn, 51credit.com +rawstory.corn, rawstory.com +crictirne.corn, crictime.com +ladolcevitae.corn, ladolcevitae.com +astro.corn, astro.com +riverisland.corn, riverisland.com +rnyzarnana.corn, myzamana.com +xpg.corn.br, xpg.com.br +svt.se, svt.se +yrnlp.corn, ymlp.com +coupondunia.in, coupondunia.in +rnyrnovies.it, mymovies.it +portaleducacao.corn.br, portaleducacao.com.br +watchabc.go.corn, watchabc.go.com +scrabblefinder.corn, scrabblefinder.com +2hua.corn, 2hua.com +guiaconsurnidor.corn, guiaconsumidor.com +jzpt.corn, jzpt.com +jino.ru, jino.ru +google.tt, google.tt +addwallet.corn, addwallet.com +enorn.corn, enom.com +searchfreernp3.corn, searchfreemp3.com +spox.corn, spox.com +enarne.net, ename.net +researchnow.corn, researchnow.com +decathlon.fr, decathlon.fr +j-cast.corn, j-cast.com +updatetube.corn, updatetube.com +polo.corn, polo.com +asiaone.corn, asiaone.com +kkiste.to, kkiste.to +frrntr.corn, frmtr.com +skai.gr, skai.gr +zovi.corn, zovi.com +qiwi.ru, qiwi.ru +stfucollege.corn, stfucollege.com +carros.corn.br, carros.com.br +privatejobshub.blogspot.in, privatejobshub.blogspot.in +englishtown.corn, englishtown.com +info.corn, info.com +rnulticlickbrasil.corn.br, multiclickbrasil.com.br +gazeteoku.corn, gazeteoku.com +kinghost.corn, kinghost.com +izisrnile.corn, izismile.com +gopro.corn, gopro.com +uspto.gov, uspto.gov +testberichte.de, testberichte.de +fs.to, fs.to +sketchtoy.corn, sketchtoy.com +sinarharian.corn.rny, sinarharian.com.my +stylernode.corn, stylemode.com +v7n.corn, v7n.com +livenation.corn, livenation.com +firstrowl.eu, firstrow1.eu +joornlaforurn.ru, joomlaforum.ru +sharecare.corn, sharecare.com +vetogate.corn, vetogate.com +series.ly, series.ly +property24.corn, property24.com +payarnsara.corn, payamsara.com +webstarts.corn, webstarts.com +renfe.es, renfe.es +fatcow.corn, fatcow.com +24ur.corn, 24ur.com +lide.cz, lide.cz +sabayacafe.corn, sabayacafe.com +prodavalnik.corn, prodavalnik.com +hyves.nl, hyves.nl +alrnaany.corn, almaany.com +xero.corn, xero.com +celluway.corn, celluway.com +rnapbar.corn, mapbar.com +vecernji.hr, vecernji.hr +konga.corn, konga.com +fresherslive.corn, fresherslive.com +nova.cz, nova.cz +onlinefwd.corn, onlinefwd.com +petco.corn, petco.com +benisonapparel.corn, benisonapparel.com +jango.corn, jango.com +rnangocity.corn, mangocity.com +garnefly.corn, gamefly.com +igrna.tv, igma.tv +2lcineplex.corn, 21cineplex.com +fblife.corn, fblife.com +rnoe.gov.eg, moe.gov.eg +heydouga.corn, heydouga.com +buildhr.corn, buildhr.com +rnrno-charnpion.corn, mmo-champion.com +ithorne.corn, ithome.com +krakow.pl, krakow.pl +history.corn, history.com +privatehorneclips.corn, privatehomeclips.com +bazos.cz, bazos.cz +appchina.corn, appchina.com +helpster.de, helpster.de +5lhejia.corn, 51hejia.com +fuckbadbitches.corn, fuckbadbitches.com +toyota-autocenter.corn, toyota-autocenter.com +alnaharegypt.corn, alnaharegypt.com +eastbay.corn, eastbay.com +softonic.corn.br, softonic.com.br +translit.ru, translit.ru +justcloud.corn, justcloud.com +validclick.net, validclick.net +seneweb.corn, seneweb.com +fsiblog.corn, fsiblog.com +williarnhill.it, williamhill.it +twitchy.corn, twitchy.com +y4yy.corn, y4yy.com +gouv.qc.ca, gouv.qc.ca +nubiles.net, nubiles.net +rnarvel.corn, marvel.com +helprnefindyour.info, helpmefindyour.info +tripadvisor.ca, tripadvisor.ca +joornlart.corn, joomlart.com +rnl8.corn, m18.com +orgasrnatrix.corn, orgasmatrix.com +bidoo.corn, bidoo.com +rogers.corn, rogers.com +inforrnationng.corn, informationng.com +voyage-prive.corn, voyage-prive.com +corningsoon.net, comingsoon.net +searchrnetrics.corn, searchmetrics.com +jetztspielen.de, jetztspielen.de +rnathxl.corn, mathxl.com +telrnex.corn, telmex.com +purpleporno.corn, purpleporno.com +coches.net, coches.net +harnusoku.corn, hamusoku.com +link-assistant.corn, link-assistant.com +gosur.corn, gosur.com +torrentcrazy.corn, torrentcrazy.com +funny-garnes.biz, funny-games.biz +bseindia.corn, bseindia.com +prornosite.ru, promosite.ru +google.rnn, google.mn +cartoonnetworkarabic.corn, cartoonnetworkarabic.com +icrn.edu.pl, icm.edu.pl +ttt4.corn, ttt4.com +pepperjarnnetwork.corn, pepperjamnetwork.com +lolzbook.corn, lolzbook.com +nationalpost.corn, nationalpost.com +tukif.corn, tukif.com +club-asteria.corn, club-asteria.com +7search.corn, 7search.com +kasikornbank.corn, kasikornbank.com +ebay.ie, ebay.ie +sexlunch.corn, sexlunch.com +qype.corn, qype.com +sankakucornplex.corn, sankakucomplex.com +flashback.org, flashback.org +strearnhunter.eu, streamhunter.eu +rsb.ru, rsb.ru +royalporntube.corn, royalporntube.com +diretta.it, diretta.it +yurnrnly.corn, yummly.com +dorn2.ru, dom2.ru +rnetoffice.gov.uk, metoffice.gov.uk +goodbaby.corn, goodbaby.com +pornbb.org, pornbb.org +forrnspring.rne, formspring.me +google.corn.cy, google.com.cy +purepeople.corn, purepeople.com +epnet.corn, epnet.com +penny-arcade.corn, penny-arcade.com +onlinekhabar.corn, onlinekhabar.com +vcornrnission.corn, vcommission.com +zirnabdk.corn, zimabdk.com +car.gr, car.gr +wat.tv, wat.tv +nnn.ru, nnn.ru +arvixe.corn, arvixe.com +buxp.org, buxp.org +shaw.ca, shaw.ca +cnyes.corn, cnyes.com +casa.it, casa.it +233.corn, 233.com +text.ru, text.ru +8OOnotes.corn, 800notes.com +banki.ru, banki.ru +rnarinetraffic.corn, marinetraffic.com +rneteo.gr, meteo.gr +thetrainline.corn, thetrainline.com +blogspot.ch, blogspot.ch +netaffiliation.corn, netaffiliation.com +olx.co.id, olx.co.id +slando.kz, slando.kz +nordea.se, nordea.se +xbabe.corn, xbabe.com +bibsonorny.org, bibsonomy.org +rnoneynews.corn, moneynews.com +265g.corn, 265g.com +horoscope.corn, horoscope.com +yarnrner.corn, yammer.com +sextgern.corn, sextgem.com +tribune.corn.pk, tribune.com.pk +topeuro.biz, topeuro.biz +perfectgirls.xxx, perfectgirls.xxx +ssc.nic.in, ssc.nic.in +8264.corn, 8264.com +flvrunner.corn, flvrunner.com +gry.pl, gry.pl +pravda.ru, pravda.ru +fulltiltpoker.corn, fulltiltpoker.com +kure.tv, kure.tv +turbo.az, turbo.az +ujian.cc, ujian.cc +rnustseeindia.corn, mustseeindia.com +thithtoolwin.corn, thithtoolwin.com +chiphell.corn, chiphell.com +spieletipps.de, spieletipps.de +portail.free.fr, portail.free.fr +hbr.org, hbr.org +sex-hq.corn, sex-hq.com +webdeveloper.corn, webdeveloper.com +cloudzer.net, cloudzer.net +vagas.corn.br, vagas.com.br +anspress.corn, anspress.com +beitaichufang.corn, beitaichufang.com +songkick.corn, songkick.com +oyunlari.net, oyunlari.net +unfollowers.rne, unfollowers.me +cornputrabajo.corn.rnx, computrabajo.com.mx +usp.br, usp.br +parseek.corn, parseek.com +salary.corn, salary.com +navyfcu.org, navyfcu.org +bigpond.corn, bigpond.com +joann.corn, joann.com +ajansspor.corn, ajansspor.com +burnews.corn, burnews.com +rnyrecipes.corn, myrecipes.com +rnt5.corn, mt5.com +webconfs.corn, webconfs.com +offcn.corn, offcn.com +travian.corn.tr, travian.com.tr +anirnenewsnetwork.corn, animenewsnetwork.com +srnartshopping.corn, smartshopping.com +twojapogoda.pl, twojapogoda.pl +tigerairways.corn, tigerairways.com +archiveofourown.org, archiveofourown.org +qq937.corn, qq937.com +rnenearne.net, meneame.net +joyclub.de, joyclub.de +yy.corn, yy.com +weddingwire.corn, weddingwire.com +rnoddb.corn, moddb.com +acervoarnador.corn, acervoamador.com +stgeorge.corn.au, stgeorge.com.au +forurnhouse.ru, forumhouse.ru +rnp3xd.corn, mp3xd.com +lionair.co.id, lionair.co.id +needtoporn.corn, needtoporn.com +playcast.ru, playcast.ru +paheal.net, paheal.net +finishline.corn, finishline.com +sep.gob.rnx, sep.gob.mx +cornenity.net, comenity.net +tqn.corn, tqn.com +eroticads.corn, eroticads.com +svpressa.ru, svpressa.ru +dtvideo.corn, dtvideo.com +rnobile.free.fr, mobile.free.fr +privat24.ua, privat24.ua +rnp3sk.net, mp3sk.net +atlas.sk, atlas.sk +aib.ie, aib.ie +shockwave.corn, shockwave.com +qatarairways.corn, qatarairways.com +theladders.corn, theladders.com +dsnetwb.corn, dsnetwb.com +expansiondirecto.corn, expansiondirecto.com +povarenok.ru, povarenok.ru +rnoneysuperrnarket.corn, moneysupermarket.com +getchu.corn, getchu.com +gay.corn, gay.com +hsbc.corn.rnx, hsbc.com.mx +textsale.ru, textsale.ru +kadinlarkulubu.corn, kadinlarkulubu.com +scientificarnerican.corn, scientificamerican.com +hillnews.corn, hillnews.com +tori.fi, tori.fi +6tie.corn, 6tie.com +charnpionselect.net, championselect.net +gtobal.corn, gtobal.com +bangkokbank.corn, bangkokbank.com +akakce.corn, akakce.com +srnarter.corn, smarter.com +totalvideoplugin.corn, totalvideoplugin.com +drnir.ru, dmir.ru +rpp.corn.pe, rpp.com.pe +uhaul.corn, uhaul.com +kayako.corn, kayako.com +buyvip.corn, buyvip.com +sixrevisions.corn, sixrevisions.com +arrny.rnil, army.mil +rediffrnail.corn, rediffmail.com +gsis.gr, gsis.gr +destinia.corn, destinia.com +behindwoods.corn, behindwoods.com +wearehairy.corn, wearehairy.com +coqnu.corn, coqnu.com +soundclick.corn, soundclick.com +drive.ru, drive.ru +carn4.fr, cam4.fr +bakusai.corn, bakusai.com +thailandtorrent.corn, thailandtorrent.com +videosz.corn, videosz.com +eporner.corn, eporner.com +stltoday.corn, stltoday.com +ilrnessaggero.it, ilmessaggero.it +theregister.co.uk, theregister.co.uk +bloggang.corn, bloggang.com +nastyvideotube.corn, nastyvideotube.com +doityourself.corn, doityourself.com +rp-online.de, rp-online.de +wow-irnpulse.ru, wow-impulse.ru +kar.nic.in, kar.nic.in +bershka.corn, bershka.com +neteller.corn, neteller.com +adevarul.ro, adevarul.ro +divxtotal.corn, divxtotal.com +bolshoyvopros.ru, bolshoyvopros.ru +letudiant.fr, letudiant.fr +xinshipu.corn, xinshipu.com +vhl.corn, vh1.com +excite.corn, excite.com +sornewhereinblog.net, somewhereinblog.net +rncgraw-hill.corn, mcgraw-hill.com +patheos.corn, patheos.com +webdesignledger.corn, webdesignledger.com +plus28.corn, plus28.com +adultwork.corn, adultwork.com +dajuegos.corn, dajuegos.com +blogs.corn, blogs.com +glopart.ru, glopart.ru +donews.corn, donews.com +nation.co.ke, nation.co.ke +delfi.ee, delfi.ee +lacuerda.net, lacuerda.net +jjshouse.corn, jjshouse.com +rnegaindex.ru, megaindex.ru +darty.corn, darty.com +rnaturetube.corn, maturetube.com +jokeroo.corn, jokeroo.com +estekhtarn.corn, estekhtam.com +fnac.es, fnac.es +ninjakiwi.corn, ninjakiwi.com +tovirna.gr, tovima.gr +tirninternet.it, timinternet.it +citizensbankonline.corn, citizensbankonline.com +builtwith.corn, builtwith.com +ko499.corn, ko499.com +tastyblacks.corn, tastyblacks.com +currys.co.uk, currys.co.uk +jobui.corn, jobui.com +notebookreview.corn, notebookreview.com +rneishij.net, meishij.net +filerio.in, filerio.in +cheapflights.co.uk, cheapflights.co.uk +puls24.rnk, puls24.mk +rurnbo.es, rumbo.es +newsbusters.org, newsbusters.org +irngdino.corn, imgdino.com +oxforddictionaries.corn, oxforddictionaries.com +ftdownloads.corn, ftdownloads.com +ciudad.corn.ar, ciudad.com.ar +latercera.cl, latercera.cl +lankadeepa.lk, lankadeepa.lk +bankier.pl, bankier.pl +hawahorne.corn, hawahome.com +cornicvine.corn, comicvine.com +carn4.it, cam4.it +fok.nl, fok.nl +iknowthatgirl.corn, iknowthatgirl.com +hizliresirn.corn, hizliresim.com +ebizrnba.corn, ebizmba.com +twistys.corn, twistys.com +rninkchan.corn, minkchan.com +dnevnik.hr, dnevnik.hr +peliculascoco.corn, peliculascoco.com +new-xharnster.corn, new-xhamster.com +freelancer.in, freelancer.in +globalgrind.corn, globalgrind.com +talkgold.corn, talkgold.com +kanui.corn.br, kanui.com.br +woxikon.de, woxikon.de +jobstreet.corn.rny, jobstreet.com.my +job.ru, job.ru +wowbiz.ro, wowbiz.ro +yiyi.cc, yiyi.cc +sinoptik.ua, sinoptik.ua +parents.corn, parents.com +forblabla.corn, forblabla.com +trojrniasto.pl, trojmiasto.pl +anyoption.corn, anyoption.com +wplocker.corn, wplocker.com +paytrn.in, paytm.in +elespectador.corn, elespectador.com +rnysitecost.ru, mysitecost.ru +startribune.corn, startribune.com +carn4.co.uk, cam4.co.uk +bestcoolrnobile.corn, bestcoolmobile.com +soup.io, soup.io +starfall.corn, starfall.com +ixl.corn, ixl.com +oreilly.corn, oreilly.com +dansrnovies.corn, dansmovies.com +facernoods.corn, facemoods.com +google.ge, google.ge +sat.gob.rnx, sat.gob.mx +weatherbug.corn, weatherbug.com +rnajorgeeks.corn, majorgeeks.com +llbean.corn, llbean.com +catho.corn.br, catho.com.br +googlegroups.corn, googlegroups.com +anirnoto.corn, animoto.com +alquds.co.uk, alquds.co.uk +newsday.corn, newsday.com +garnes2girls.corn, games2girls.com +youporngay.corn, youporngay.com +spaces.ru, spaces.ru +seriespepito.corn, seriespepito.com +gelbeseiten.de, gelbeseiten.de +thethirdrnedia.corn, thethirdmedia.com +watchfornny.corn, watchfomny.com +freecarnsexposed.corn, freecamsexposed.com +dinakaran.corn, dinakaran.com +xxxhost.rne, xxxhost.me +srnartprix.corn, smartprix.com +thoughtcatalog.corn, thoughtcatalog.com +soccersuck.corn, soccersuck.com +vivanuncios.corn, vivanuncios.com +liba.corn, liba.com +gog.corn, gog.com +philstar.corn, philstar.com +cian.ru, cian.ru +avclub.corn, avclub.com +slon.ru, slon.ru +stc.corn.sa, stc.com.sa +jstor.org, jstor.org +wehkarnp.nl, wehkamp.nl +vodafone.co.uk, vodafone.co.uk +deser.pl, deser.pl +adscendrnedia.corn, adscendmedia.com +getcashforsurveys.corn, getcashforsurveys.com +glarnsharn.corn, glamsham.com +dressupgarnes.corn, dressupgames.com +lifo.gr, lifo.gr +37signals.corn, 37signals.com +pdfonline.corn, pdfonline.com +flipkey.corn, flipkey.com +epochtirnes.corn, epochtimes.com +futhead.corn, futhead.com +inlinkz.corn, inlinkz.com +fx-trend.corn, fx-trend.com +yasdl.corn, yasdl.com +techbang.corn, techbang.com +narenji.ir, narenji.ir +szonline.net, szonline.net +perfil.corn.ar, perfil.com.ar +rnywebface.corn, mywebface.com +taknaz.ir, taknaz.ir +tradera.corn, tradera.com +golern.de, golem.de +its-rno.corn, its-mo.com +arabnet5.corn, arabnet5.com +freerepublic.corn, freerepublic.com +britannica.corn, britannica.com +deccanchronicle.corn, deccanchronicle.com +ohio.gov, ohio.gov +busuu.corn, busuu.com +pricecheck.co.za, pricecheck.co.za +paltalk.corn, paltalk.com +sportinglife.corn, sportinglife.com +google.sn, google.sn +rneteornedia.corn, meteomedia.com +push2check.net, push2check.net +ing-diba.de, ing-diba.de +irnrnoweb.be, immoweb.be +oregonlive.corn, oregonlive.com +ge.tt, ge.tt +bbspink.corn, bbspink.com +business2cornrnunity.corn, business2community.com +viidii.corn, viidii.com +hrloo.corn, hrloo.com +rnglradio.corn, mglradio.com +cosrne.net, cosme.net +xilu.corn, xilu.com +scbeasy.corn, scbeasy.com +biglots.corn, biglots.com +dhakatirnes24.corn, dhakatimes24.com +spankbang.corn, spankbang.com +hitleap.corn, hitleap.com +proz.corn, proz.com +phplOO.corn, php100.com +tvtoday.de, tvtoday.de +funnie.st, funnie.st +velvet.hu, velvet.hu +dhnet.be, dhnet.be +capital.gr, capital.gr +inosrni.ru, inosmi.ru +healthkart.corn, healthkart.com +arnway.corn, amway.com +rnadrnirni.corn, madmimi.com +drarnafever.corn, dramafever.com +oodle.corn, oodle.com +spreadshirt.corn, spreadshirt.com +google.rng, google.mg +utarget.ru, utarget.ru +rnatorny.corn, matomy.com +rnedhelp.org, medhelp.org +curnlouder.corn, cumlouder.com +aliorbank.pl, aliorbank.pl +takepart.corn, takepart.com +rnyfreshnet.corn, myfreshnet.com +adorarna.corn, adorama.com +dhs.gov, dhs.gov +rnivo.tv, mivo.tv +nchsoftware.corn, nchsoftware.com +gnc.corn, gnc.com +spiceworks.corn, spiceworks.com +jeu.fr, jeu.fr +terra.corn, terra.com +irishtirnes.corn, irishtimes.com +kleiderkreisel.de, kleiderkreisel.de +ebay.be, ebay.be +rt.ru, rt.ru +radiofarda.corn, radiofarda.com +atrapalo.corn, atrapalo.com +southcn.corn, southcn.com +turkcell.corn.tr, turkcell.com.tr +thernetapicture.corn, themetapicture.com +aujourdhui.corn, aujourdhui.com +ato.gov.au, ato.gov.au +pelis24.corn, pelis24.com +saaid.net, saaid.net +bradsdeals.corn, bradsdeals.com +piratelOl.corn, pirate101.com +saturn.de, saturn.de +thisissouthwales.co.uk, thisissouthwales.co.uk +cyberlink.corn, cyberlink.com +internationalredirects.corn, internationalredirects.com +radardedescontos.corn.br, radardedescontos.com.br +rapidcontentwizard.corn, rapidcontentwizard.com +kaburn.corn.br, kabum.com.br +webrankinfo.corn, webrankinfo.com +kiabi.corn, kiabi.com +farecornpare.corn, farecompare.com +xinjunshi.corn, xinjunshi.com +vidxden.corn, vidxden.com +pvrcinernas.corn, pvrcinemas.com +chachaba.corn, chachaba.com +wanrnei.corn, wanmei.com +alternet.org, alternet.org +rozklad-pkp.pl, rozklad-pkp.pl +ornniture.corn, omniture.com +childrensplace.corn, childrensplace.com +rnenards.corn, menards.com +zhcw.corn, zhcw.com +ouest-france.fr, ouest-france.fr +vitorrent.org, vitorrent.org +xanga.corn, xanga.com +zbozi.cz, zbozi.cz +radioshack.corn, radioshack.com +startv.in, startv.in +affiliatewindow.corn, affiliatewindow.com +gov.on.ca, gov.on.ca +grainger.corn, grainger.com +3rat.corn, 3rat.com +indeed.co.za, indeed.co.za +rtbf.be, rtbf.be +strava.corn, strava.com +disneystore.corn, disneystore.com +travelagency.travel, travelagency.travel +ekitan.corn, ekitan.com +volagratis.corn, volagratis.com +yiifrarnework.corn, yiiframework.com +drarnacrazy.net, dramacrazy.net +addtoany.corn, addtoany.com +uzrnantv.corn, uzmantv.com +uline.corn, uline.com +fitnessrnagazine.corn, fitnessmagazine.com +khrnerload.corn, khmerload.com +italiafilrn.tv, italiafilm.tv +baseball-reference.corn, baseball-reference.com +neopets.corn, neopets.com +rnultiupload.nl, multiupload.nl +lakii.corn, lakii.com +downloadrnaster.ru, downloadmaster.ru +babbel.corn, babbel.com +gossip-tv.gr, gossip-tv.gr +laban.vn, laban.vn +cornputerbase.de, computerbase.de +juyouqu.corn, juyouqu.com +rnarkt.de, markt.de +linuxquestions.org, linuxquestions.org +giveawayoftheday.corn, giveawayoftheday.com +l76.corn, 176.com +hornernadernoviez.corn, homemademoviez.com +huffingtonpost.fr, huffingtonpost.fr +rnovieweb.corn, movieweb.com +pornzeus.corn, pornzeus.com +posta.corn.tr, posta.com.tr +biography.corn, biography.com +bukkit.org, bukkit.org +spirit.corn, spirit.com +vernale.corn, vemale.com +elnuevodia.corn, elnuevodia.com +pof.corn.br, pof.com.br +iranproud.corn, iranproud.com +rnolodost.bz, molodost.bz +netcarshow.corn, netcarshow.com +ardrnediathek.de, ardmediathek.de +fabfurnish.corn, fabfurnish.com +rnyfreeblack.corn, myfreeblack.com +antichat.ru, antichat.ru +crocko.corn, crocko.com +b5rn.corn, b5m.com +entrance-exarn.net, entrance-exam.net +benaughty.corn, benaughty.com +sierratradingpost.corn, sierratradingpost.com +apartrnentguide.corn, apartmentguide.com +slirnspots.corn, slimspots.com +sondakika.corn, sondakika.com +glarnour.corn, glamour.com +ilyke.net, ilyke.net +rnybroadband.co.za, mybroadband.co.za +alaskaair.corn, alaskaair.com +virtualtourist.corn, virtualtourist.com +rexxx.corn, rexxx.com +fullhdfilrnizle.org, fullhdfilmizle.org +starpulse.corn, starpulse.com +winkal.corn, winkal.com +ad-feeds.net, ad-feeds.net +irannaz.corn, irannaz.com +elahrnad.corn, elahmad.com +dealspl.us, dealspl.us +rnoikrug.ru, moikrug.ru +olx.corn.rnx, olx.com.mx +rd.corn, rd.com +newone.org, newone.org +naijapals.corn, naijapals.com +forgifs.corn, forgifs.com +fsjgw.corn, fsjgw.com +nicoviewer.net, nicoviewer.net +topeleven.corn, topeleven.com +peerfly.corn, peerfly.com +softportal.corn, softportal.com +clker.corn, clker.com +tehran98.corn, tehran98.com +weather2urnbrella.corn, weather2umbrella.com +lookbook.nu, lookbook.nu +futureshop.ca, futureshop.ca +blackpeoplerneet.corn, blackpeoplemeet.com +adworkrnedia.corn, adworkmedia.com +entire.xxx, entire.xxx +bitbucket.org, bitbucket.org +transferrnarkt.co.uk, transfermarkt.co.uk +rnoshirnonsters.corn, moshimonsters.com +bairnao.corn, baimao.com +khanacaderny.org, khanacademy.org +2chan.net, 2chan.net +adopteunrnec.corn, adopteunmec.com +rnochirnedia.corn, mochimedia.com +strawberrynet.corn, strawberrynet.com +gdeivse.corn, gdeivse.com +speckyboy.corn, speckyboy.com +radical-foto.ru, radical-foto.ru +softcoin.corn, softcoin.com +cnews.ru, cnews.ru +ubs.corn, ubs.com +lankasri.corn, lankasri.com +cylex.de, cylex.de +irntranslator.net, imtranslator.net +horneoffice.gov.uk, homeoffice.gov.uk +answerbag.corn, answerbag.com +chainreactioncycles.corn, chainreactioncycles.com +sportal.bg, sportal.bg +livernaster.ru, livemaster.ru +rnercadolibre.corn.pe, mercadolibre.com.pe +rnentalfloss.corn, mentalfloss.com +google.arn, google.am +rnawaly.corn, mawaly.com +douban.frn, douban.fm +abidjan.net, abidjan.net +pricegong.corn, pricegong.com +brother.corn, brother.com +basspro.corn, basspro.com +popsci.corn, popsci.com +olx.corn.ar, olx.com.ar +python.org, python.org +voetbalzone.nl, voetbalzone.nl +aztecaporno.corn, aztecaporno.com +d-h.st, d-h.st +voyeurweb.corn, voyeurweb.com +storenvy.corn, storenvy.com +aftabir.corn, aftabir.com +irngsrc.ru, imgsrc.ru +peru.corn, peru.com +rnindbodygreen.corn, mindbodygreen.com +stereotude.corn, stereotude.com +arl5.corn, ar15.com +gogecapital.corn, gogecapital.com +xipin.rne, xipin.me +gvt.corn.br, gvt.com.br +today.it, today.it +rnastercard.corn.au, mastercard.com.au +hobbyking.corn, hobbyking.com +hawkhost.corn, hawkhost.com +theburnp.corn, thebump.com +alpari.ru, alpari.ru +garnrna-ic.corn, gamma-ic.com +rnundorne.corn, mundome.com +quotev.corn, quotev.com +anirnaljarn.corn, animaljam.com +ohozaa.corn, ohozaa.com +sayyac.corn, sayyac.com +kobobooks.corn, kobobooks.com +rnuslirna.corn, muslima.com +digsitesvalue.net, digsitesvalue.net +colourlovers.corn, colourlovers.com +uludagsozluk.corn, uludagsozluk.com +rnercadolibre.corn.uy, mercadolibre.com.uy +oern.corn.rnx, oem.com.mx +self.corn, self.com +kyohk.net, kyohk.net +dillards.corn, dillards.com +eduu.corn, eduu.com +replays.net, replays.net +bnpparibasfortis.be, bnpparibasfortis.be +express.co.uk, express.co.uk +guaixun.corn, guaixun.com +75Og.corn, 750g.com +craveonline.corn, craveonline.com +rnarkafoni.corn, markafoni.com +enarne.corn, ename.com +abercrornbie.corn, abercrombie.com +noticiaaldia.corn, noticiaaldia.com +seniorpeoplerneet.corn, seniorpeoplemeet.com +dhingana.corn, dhingana.com +prokerala.corn, prokerala.com +iefirnerida.gr, iefimerida.gr +wprazzi.corn, wprazzi.com +pantiprnarket.corn, pantipmarket.com +vueling.corn, vueling.com +newsonlineweekly.corn, newsonlineweekly.com +crl73.corn, cr173.com +ecp888.corn, ecp888.com +diary.ru, diary.ru +pervclips.corn, pervclips.com +sudaneseonline.corn, sudaneseonline.com +personal.corn.ar, personal.com.ar +articlesnatch.corn, articlesnatch.com +rnitbbs.corn, mitbbs.com +techsupportalert.corn, techsupportalert.com +filepost.corn, filepost.com +unblockyoutube.co.uk, unblockyoutube.co.uk +hasznaltauto.hu, hasznaltauto.hu +drnv.org, dmv.org +port.hu, port.hu +anastasiadate.corn, anastasiadate.com +adtgs.corn, adtgs.com +narnejet.corn, namejet.com +ally.corn, ally.com +djrnaza.corn, djmaza.com +asstr.org, asstr.org +corel.corn, corel.com +interfax.ru, interfax.ru +rozee.pk, rozee.pk +akinator.corn, akinator.com +dorninos.co.in, dominos.co.in +boardgarnegeek.corn, boardgamegeek.com +tearnliquid.net, teamliquid.net +sbrf.ru, sbrf.ru +l99.corn, l99.com +eatingwell.corn, eatingwell.com +rnid-day.corn, mid-day.com +blinkogold.it, blinkogold.it +rosbalt.ru, rosbalt.ru +islarnrnerno.cc, islammemo.cc +bettycrocker.corn, bettycrocker.com +wornenshealthrnag.corn, womenshealthmag.com +asandownload.corn, asandownload.com +twitcasting.tv, twitcasting.tv +lOand9.corn, 10and9.com +youngleafs.corn, youngleafs.com +saharareporters.corn, saharareporters.com +overclock.net, overclock.net +rnapsgalaxy.corn, mapsgalaxy.com +internetslang.corn, internetslang.com +sokrnil.corn, sokmil.com +yousendit.corn, yousendit.com +forex-rnrncis.corn, forex-mmcis.com +vador.corn, vador.com +pagewash.corn, pagewash.com +pringotrack.corn, pringotrack.com +cprnstar.corn, cpmstar.com +yxdown.corn, yxdown.com +surfingbird.ru, surfingbird.ru +identi.li, identi.li +n4hr.corn, n4hr.com +elitetorrent.net, elitetorrent.net +livechatinc.corn, livechatinc.com +anzhi.corn, anzhi.com +2checkout.corn, 2checkout.com +bancoestado.cl, bancoestado.cl +epson.corn, epson.com +twodollarclick.corn, twodollarclick.com +okaz.corn.sa, okaz.com.sa +china-sss.corn, china-sss.com +xforex.corn, xforex.com +salliernae.corn, salliemae.com +acunn.corn, acunn.com +navyfederal.org, navyfederal.org +forurnactif.corn, forumactif.com +affaire.corn, affaire.com +rnediaternple.net, mediatemple.net +qdrnrn.corn, qdmm.com +urlrn.co, urlm.co +toofab.corn, toofab.com +yola.corn, yola.com +sheldonsfans.corn, sheldonsfans.com +piratestrearning.corn, piratestreaming.com +frontier.corn, frontier.com +businesswire.corn, businesswire.com +rue89.corn, rue89.com +yenisafak.corn.tr, yenisafak.com.tr +wikirnart.ru, wikimart.ru +xpressvids.info, xpressvids.info +rnedicalnewstoday.corn, medicalnewstoday.com +express.de, express.de +grid.rnk, grid.mk +rnass.gov, mass.gov +onlinefinder.net, onlinefinder.net +yllix.corn, yllix.com +aksarn.corn.tr, aksam.com.tr +telegraf.rs, telegraf.rs +ternplatic.corn, templatic.com +kandao.corn, kandao.com +policyrnic.corn, policymic.com +farfesh.corn, farfesh.com +alza.cz, alza.cz +judgeporn.corn, judgeporn.com +townwork.net, townwork.net +3dcartstores.corn, 3dcartstores.com +rnarketingland.corn, marketingland.com +okooo.corn, okooo.com +siteduzero.corn, siteduzero.com +cellbazaar.corn, cellbazaar.com +ornblOO.corn, omb100.com +danarirnedia.corn, danarimedia.com +nlcafe.hu, nlcafe.hu +qz.corn, qz.com +indiapost.gov.in, indiapost.gov.in +kinogo.net, kinogo.net +neverblue.corn, neverblue.com +spyfu.corn, spyfu.com +shindanrnaker.corn, shindanmaker.com +bankpasargad.corn, bankpasargad.com +internetautoguide.corn, internetautoguide.com +allover3O.corn, allover30.com +rnetric-conversions.org, metric-conversions.org +carid.corn, carid.com +rnofos.corn, mofos.com +kanald.corn.tr, kanald.com.tr +rnobikwik.corn, mobikwik.com +checkpagerank.net, checkpagerank.net +hotscripts.corn, hotscripts.com +hornywife.corn, hornywife.com +prixrnoinscher.corn, prixmoinscher.com +worldbank.org, worldbank.org +wsodownloads.info, wsodownloads.info +his-j.corn, his-j.com +powned.tv, powned.tv +redrnondpie.corn, redmondpie.com +rnolotok.ru, molotok.ru +whatrnobile.corn.pk, whatmobile.com.pk +wiziq.corn, wiziq.com +excelsior.corn.rnx, excelsior.com.mx +tradetang.corn, tradetang.com +terra.es, terra.es +sdchina.corn, sdchina.com +rai.tv, rai.tv +indiansexstories.net, indiansexstories.net +upbulk.corn, upbulk.com +surveygizrno.corn, surveygizmo.com +ulta.corn, ulta.com +tera-europe.corn, tera-europe.com +tuoitre.vn, tuoitre.vn +onedio.corn, onedio.com +favirn.corn, favim.com +seo-fast.ru, seo-fast.ru +twitterfeed.corn, twitterfeed.com +trustedreviews.corn, trustedreviews.com +ztgarne.corn, ztgame.com +radiojavan.corn, radiojavan.com +fun698.corn, fun698.com +l26.net, 126.net +indiaglitz.corn, indiaglitz.com +jdouga.corn, jdouga.com +lofter.corn, lofter.com +rnysavings.corn, mysavings.com +snapfish.corn, snapfish.com +i-sux.corn, i-sux.com +cebbank.corn, cebbank.com +ethnos.gr, ethnos.gr +desktop2ch.tv, desktop2ch.tv +expedia.ca, expedia.ca +kinja.corn, kinja.com +rusfolder.corn, rusfolder.com +expat-blog.corn, expat-blog.com +8teenxxx.corn, 8teenxxx.com +variety.corn, variety.com +naternat.pl, natemat.pl +niazpardaz.corn, niazpardaz.com +gezginler.net, gezginler.net +baur.de, baur.de +tv2.no, tv2.no +realgrn.corn, realgm.com +zarnzar.corn, zamzar.com +freecharge.in, freecharge.in +ahlarnontada.corn, ahlamontada.com +salespider.corn, salespider.com +beanfun.corn, beanfun.com +cleveland.corn, cleveland.com +truecaller.corn, truecaller.com +walrnart.ca, walmart.ca +fanbox.corn, fanbox.com +designrnodo.corn, designmodo.com +frip.corn, frip.com +sarnrnobile.corn, sammobile.com +rninnano-av.corn, minnano-av.com +bri.co.id, bri.co.id +creativebloq.corn, creativebloq.com +anthropologie.corn, anthropologie.com +afpbb.corn, afpbb.com +kingsera.ir, kingsera.ir +songspk.co, songspk.co +sexsearch.corn, sexsearch.com +dailydot.corn, dailydot.com +hayah.cc, hayah.cc +angolotesti.it, angolotesti.it +si.kz, si.kz +allthingsd.corn, allthingsd.com +paddypower.corn, paddypower.com +canadapost.ca, canadapost.ca +qq.cc, qq.cc +arnctheatres.corn, amctheatres.com +alltop.corn, alltop.com +allkpop.corn, allkpop.com +nalog.ru, nalog.ru +dynadot.corn, dynadot.com +copart.corn, copart.com +rnexat.corn, mexat.com +skelbiu.lt, skelbiu.lt +kerala.gov.in, kerala.gov.in +cathaypacific.corn, cathaypacific.com +clip2ni.corn, clip2ni.com +tribune.corn, tribune.com +acidcow.corn, acidcow.com +arnkspor.corn, amkspor.com +shiksha.corn, shiksha.com +l8Oupload.corn, 180upload.com +vietgiaitri.corn, vietgiaitri.com +sportsauthority.corn, sportsauthority.com +banki.ir, banki.ir +vancouversun.corn, vancouversun.com +hackforurns.net, hackforums.net +t-rnobile.de, t-mobile.de +sirnplyrecipes.corn, simplyrecipes.com +crazyhornesex.corn, crazyhomesex.com +thehindubusinessline.corn, thehindubusinessline.com +kriesi.at, kriesi.at +deyi.corn, deyi.com +plirnus.corn, plimus.com +websyndic.corn, websyndic.com +express.corn, express.com +dougasouko.corn, dougasouko.com +rnrnstat.corn, mmstat.com +wornai.corn, womai.com +alrajhibank.corn.sa, alrajhibank.com.sa +ice-porn.corn, ice-porn.com +benchrnarkernail.corn, benchmarkemail.com +ringcentral.corn, ringcentral.com +erail.in, erail.in +poptropica.corn, poptropica.com +search.ch, search.ch +rneteo.it, meteo.it +adriver.ru, adriver.ru +ratp.fr, ratp.fr +orgasrn.corn, orgasm.com +pornrne.corn, pornme.com +garneinforrner.corn, gameinformer.com +woobox.corn, woobox.com +advertising.corn, advertising.com +flyflv.corn, flyflv.com +chinaren.corn, chinaren.com +tube2Ol2.corn, tube2012.com +ikhwanonline.corn, ikhwanonline.com +iwebtool.corn, iwebtool.com +ucdavis.edu, ucdavis.edu +boyfriendtv.corn, boyfriendtv.com +rurubu.travel, rurubu.travel +kabarn.corn, kabam.com +talkingpointsrnerno.corn, talkingpointsmemo.com +detnews.corn, detnews.com +sibnet.ru, sibnet.ru +carnztube.net, camztube.net +rnadarnenoire.corn, madamenoire.com +evz.ro, evz.ro +staseraintv.corn, staseraintv.com +chel68.corn, che168.com +kidshealth.org, kidshealth.org +rn24.ru, m24.ru +zenfolio.corn, zenfolio.com +webtretho.corn, webtretho.com +postjung.corn, postjung.com +supersport.corn, supersport.com +cshtracker.corn, cshtracker.com +jeuxjeuxjeux.fr, jeuxjeuxjeux.fr +foxtv.es, foxtv.es +postjoint.corn, postjoint.com +podnapisi.net, podnapisi.net +prav.tv, prav.tv +realrnadrid.corn, realmadrid.com +rnbs-potsdarn.de, mbs-potsdam.de +tirn.it, tim.it +uplus.rnetroer.corn, uplus.metroer.com +esquire.corn, esquire.com +ooopic.corn, ooopic.com +castorarna.fr, castorama.fr +afarnily.vn, afamily.vn +findlaw.corn, findlaw.com +srnartpassiveincorne.corn, smartpassiveincome.com +sa.ae, sa.ae +hernnet.se, hemnet.se +diytrade.corn, diytrade.com +weblancer.net, weblancer.net +zaprneta.de, zapmeta.de +bizsugar.corn, bizsugar.com +banesco.corn, banesco.com +ideeli.corn, ideeli.com +lnx.lu, lnx.lu +divxplanet.corn, divxplanet.com +aircanada.corn, aircanada.com +uzise.corn, uzise.com +sabay.corn.kh, sabay.com.kh +football365.corn, football365.com +crazydornains.corn.au, crazydomains.com.au +qxox.org, qxox.org +thesrnokinggun.corn, thesmokinggun.com +w8n3.info, w8n3.info +po.st, po.st +debian.org, debian.org +flypgs.corn, flypgs.com +craigslist.co.in, craigslist.co.in +islarnway.net, islamway.net +debate.corn.rnx, debate.com.mx +bitdefender.corn, bitdefender.com +listindiario.corn, listindiario.com +l23telugu.corn, 123telugu.com +ilbe.corn, ilbe.com +wordlinx.corn, wordlinx.com +ebc.corn.br, ebc.com.br +pr.gov.br, pr.gov.br +videoyourn7.corn, videoyoum7.com +ets.org, ets.org +exteen.corn, exteen.com +cornicbookresources.corn, comicbookresources.com +grarnrnarly.corn, grammarly.com +pdapi.corn, pdapi.com +adultflashOl.corn, adultflash01.com +orlandosentinel.corn, orlandosentinel.com +24option.corn, 24option.com +rnoviepilot.de, moviepilot.de +rfa.org, rfa.org +crateandbarrel.corn, crateandbarrel.com +srv2trking.corn, srv2trking.com +rnercusuar.info, mercusuar.info +dofus.corn, dofus.com +rnyfxbook.corn, myfxbook.com +rnadrnovs.corn, madmovs.com +rnyffi.biz, myffi.biz +peru2l.pe, peru21.pe +bollywoodlife.corn, bollywoodlife.com +garnetracker.corn, gametracker.com +terra.corn.rnx, terra.com.mx +antenarn.info, antenam.info +ihotelier.corn, ihotelier.com +hypebeast.corn, hypebeast.com +drarnasonline.corn, dramasonline.com +wordtracker.corn, wordtracker.com +thefrisky.corn, thefrisky.com +rneritnation.corn, meritnation.com +irna.ir, irna.ir +trovit.corn, trovit.com +cngold.org, cngold.org +optyrnalizacja.corn, optymalizacja.com +flexrnls.corn, flexmls.com +softarchive.net, softarchive.net +divxonline.info, divxonline.info +rnalaysian-inc.corn, malaysian-inc.com +dsw.corn, dsw.com +fantastigarnes.corn, fantastigames.com +rnattcutts.corn, mattcutts.com +ziprealty.corn, ziprealty.com +saavn.corn, saavn.com +ruporn.tv, ruporn.tv +e-estekhdarn.corn, e-estekhdam.com +novafile.corn, novafile.com +tornsguide.fr, tomsguide.fr +tornshardware.co.uk, tomshardware.co.uk +crosswalk.corn, crosswalk.com +businessdictionary.corn, businessdictionary.com +sharesix.corn, sharesix.com +travian.cl, travian.cl +indiastudychannel.corn, indiastudychannel.com +rn7shsh.corn, m7shsh.com +hbogo.corn, hbogo.com +888casino.it, 888casino.it +keywordspy.corn, keywordspy.com +pureleverage.corn, pureleverage.com +photodune.net, photodune.net +foreignpolicy.corn, foreignpolicy.com +shiftdelete.net, shiftdelete.net +living36O.net, living360.net +paixie.net, paixie.net +barstoolsports.corn, barstoolsports.com +aernet.es, aemet.es +local.ch, local.ch +sperrnyporn.corn, spermyporn.com +tasnirnnews.corn, tasnimnews.com +irngserve.net, imgserve.net +huawei.corn, huawei.com +pik.ba, pik.ba +info-dvd.ru, info-dvd.ru +2dornains.ru, 2domains.ru +sextube.frn, sextube.fm +searchrocket.info, searchrocket.info +dicio.corn.br, dicio.com.br +ittefaq.corn.bd, ittefaq.com.bd +fileserve.corn, fileserve.com +genteflow.corn, genteflow.com +5giay.vn, 5giay.vn +elbadil.corn, elbadil.com +wizaz.pl, wizaz.pl +cyclingnews.corn, cyclingnews.com +southparkstudios.corn, southparkstudios.com +hangseng.corn, hangseng.com +rnapsofworld.corn, mapsofworld.com +gaokao.corn, gaokao.com +antarvasna.corn, antarvasna.com +televisa.corn, televisa.com +dressupwho.corn, dressupwho.com +goldprice.org, goldprice.org +directlyrics.corn, directlyrics.com +v2cigar.net, v2cigar.net +peopleclick.corn, peopleclick.com +rnoudarnepo.corn, moudamepo.com +baijob.corn, baijob.com +geni.corn, geni.com +huangye88.corn, huangye88.com +phun.org, phun.org +kasikornbankgroup.corn, kasikornbankgroup.com +angryrnovs.corn, angrymovs.com +bibliocornrnons.corn, bibliocommons.com +rnelateiran.corn, melateiran.com +gigya.corn, gigya.com +l7ok.corn, 17ok.com +xdowns.corn, xdowns.com +tportal.hr, tportal.hr +drearntearnrnoney.corn, dreamteammoney.com +prevention.corn, prevention.com +terra.cl, terra.cl +blinklist.corn, blinklist.com +5lseer.corn, 51seer.com +ruelsoft.corn, ruelsoft.com +kulichki.net, kulichki.net +tatatele.in, tatatele.in +rnybloggertricks.corn, mybloggertricks.com +rna-birnbo.corn, ma-bimbo.com +ftchinese.corn, ftchinese.com +sergey-rnavrodi-rnrnrn.net, sergey-mavrodi-mmm.net +wp.tv, wp.tv +chevrolet.corn, chevrolet.com +razerzone.corn, razerzone.com +subrnanga.corn, submanga.com +thornson.co.uk, thomson.co.uk +syosetu.org, syosetu.org +olx.corn, olx.com +vplay.ro, vplay.ro +rtnn.net, rtnn.net +55.la, 55.la +instructure.corn, instructure.com +lvse.corn, lvse.com +hvg.hu, hvg.hu +androidpolice.corn, androidpolice.com +cookinglight.corn, cookinglight.com +rnadadsrnedia.corn, madadsmedia.com +inews.gr, inews.gr +ktxp.corn, ktxp.com +socialsecurity.gov, socialsecurity.gov +equifax.corn, equifax.com +ceskatelevize.cz, ceskatelevize.cz +gaaks.corn, gaaks.com +chillingeffects.org, chillingeffects.org +kornando.corn, komando.com +nowpublic.corn, nowpublic.com +khanwars.ae, khanwars.ae +berlin.de, berlin.de +bleepingcornputer.corn, bleepingcomputer.com +rnilitary.corn, military.com +zerolO.net, zero10.net +onekingslane.corn, onekingslane.com +beget.ru, beget.ru +get-tune.net, get-tune.net +freewebs.corn, freewebs.com +pcfinancial.ca, pcfinancial.ca +sparknotes.corn, sparknotes.com +tinychat.corn, tinychat.com +luxup.ru, luxup.ru +geforce.corn, geforce.com +tatts.corn.au, tatts.com.au +alweearn.corn.sa, alweeam.com.sa +l23-reg.co.uk, 123-reg.co.uk +sexyswingertube.corn, sexyswingertube.com +groupon.es, groupon.es +guardianlv.corn, guardianlv.com +hypovereinsbank.de, hypovereinsbank.de +usc.edu, usc.edu +ard.de, ard.de +hoovers.corn, hoovers.com +tdarneritrade.corn, tdameritrade.com +userscripts.org, userscripts.org +applll.corn, app111.com +al.corn, al.com +op.fi, op.fi +adbkrn.corn, adbkm.com +pivithurutv.info, pivithurutv.info +haber3.corn, haber3.com +shatel.ir, shatel.ir +carnonster.corn, camonster.com +weltbild.de, weltbild.de +advanceautoparts.corn, advanceautoparts.com +rnplssaturn.corn, mplssaturn.com +weeklystandard.corn, weeklystandard.com +popscreen.corn, popscreen.com +freelifetirnefuckbook.corn, freelifetimefuckbook.com +peixeurbano.corn.br, peixeurbano.com.br +2258.corn, 2258.com +proxfree.corn, proxfree.com +zend.corn, zend.com +citehr.corn, citehr.com +gadyd.corn, gadyd.com +tvspielfilrn.de, tvspielfilm.de +skapiec.pl, skapiec.pl +9see.corn, 9see.com +cndns.corn, cndns.com +hurriyeternlak.corn, hurriyetemlak.com +census.gov, census.gov +collider.corn, collider.com +cinaplay.corn, cinaplay.com +aq.corn, aq.com +aolsearch.corn, aolsearch.com +ce4arab.corn, ce4arab.com +cbi.ir, cbi.ir +cjol.corn, cjol.com +brandporno.corn, brandporno.com +yicheshi.corn, yicheshi.com +rnydealz.de, mydealz.de +xiachufang.corn, xiachufang.com +sun-sentinel.corn, sun-sentinel.com +flashkhor.corn, flashkhor.com +join.rne, join.me +hankyung.corn, hankyung.com +oneandone.co.uk, oneandone.co.uk +derwesten.de, derwesten.de +garnrnae.corn, gammae.com +webadultdating.biz, webadultdating.biz +pokerstars.corn, pokerstars.com +fucked-sex.corn, fucked-sex.com +antaranews.corn, antaranews.com +banorte.corn, banorte.com +travian.it, travian.it +rnsu.edu, msu.edu +ozbargain.corn.au, ozbargain.com.au +77vcd.corn, 77vcd.com +bestooxx.corn, bestooxx.com +siernens.corn, siemens.com +en-japan.corn, en-japan.com +akbank.corn, akbank.com +srf.ch, srf.ch +rneijer.corn, meijer.com +htrnldrive.net, htmldrive.net +peoplestylewatch.corn, peoplestylewatch.com +boards.ie, boards.ie +zhulong.corn, zhulong.com +svyaznoybank.ru, svyaznoybank.ru +rnyfilestore.corn, myfilestore.com +sucuri.net, sucuri.net +redflagdeals.corn, redflagdeals.com +javascriptkit.corn, javascriptkit.com +edrearns.fr, edreams.fr +wral.corn, wral.com +togetter.corn, togetter.com +drni.dk, dmi.dk +thinkdigit.corn, thinkdigit.com +barclaycard.co.uk, barclaycard.co.uk +cornrnlOO.corn, comm100.com +christianbook.corn, christianbook.com +popularrnechanics.corn, popularmechanics.com +taste.corn.au, taste.com.au +tripadvisor.ru, tripadvisor.ru +colissirno.fr, colissimo.fr +gdposir.info, gdposir.info +rarlab.corn, rarlab.com +dcnepalevent.corn, dcnepalevent.com +sagepub.corn, sagepub.com +rnarkosweb.corn, markosweb.com +france3.fr, france3.fr +rnindbodyonline.corn, mindbodyonline.com +yapo.cl, yapo.cl +O-6.corn, 0-6.com +dilbert.corn, dilbert.com +searchqu.corn, searchqu.com +usa.gov, usa.gov +vatandownload.corn, vatandownload.com +nastyrnovs.corn, nastymovs.com +santanderrio.corn.ar, santanderrio.com.ar +notebookcheck.net, notebookcheck.net +canalplus.fr, canalplus.fr +epa.gov, epa.gov +disp.cc, disp.cc +hotsales.net, hotsales.net +interpals.net, interpals.net +vz.ru, vz.ru +flyertalk.corn, flyertalk.com +pjrnedia.corn, pjmedia.com +solornid.net, solomid.net +rnegaplan.ru, megaplan.ru +hatenablog.corn, hatenablog.com +getsatisfaction.corn, getsatisfaction.com +hotline.ua, hotline.ua +alternativeto.net, alternativeto.net +hipfile.corn, hipfile.com +247sports.corn, 247sports.com +phpnuke.org, phpnuke.org +indiaresults.corn, indiaresults.com +prisjakt.nu, prisjakt.nu +ltvlive.in, 1tvlive.in +e-rnai.net, e-mai.net +trafficg.corn, trafficg.com +ojogo.pt, ojogo.pt +totaldornination.corn, totaldomination.com +eroino.net, eroino.net +network-tools.corn, network-tools.com +unibytes.corn, unibytes.com +seriouseats.corn, seriouseats.com +twicsy.corn, twicsy.com +srnbc-card.corn, smbc-card.com +toocle.corn, toocle.com +unbounce.corn, unbounce.com +2tu.cc, 2tu.cc +cornputerworld.corn, computerworld.com +clicktrackprofit.corn, clicktrackprofit.com +serialu.net, serialu.net +realfarrnacy.corn, realfarmacy.com +rnetrodeal.corn, metrodeal.com +binzhi.corn, binzhi.com +srnilebox.corn, smilebox.com +coderanch.corn, coderanch.com +uptodown.corn, uptodown.com +vbulletin.corn, vbulletin.com +teasernet.corn, teasernet.com +adrnob.corn, admob.com +fingerhut.corn, fingerhut.com +urlopener.corn, urlopener.com +vi.nl, vi.nl +expedia.de, expedia.de +thekrazycouponlady.corn, thekrazycouponlady.com +linezing.corn, linezing.com +rnetropcs.corn, metropcs.com +draugas.lt, draugas.lt +rninecraftdl.corn, minecraftdl.com +airberlin.corn, airberlin.com +eelly.corn, eelly.com +siarnsport.co.th, siamsport.co.th +e-junkie.corn, e-junkie.com +gulte.corn, gulte.com +lazada.corn.ph, lazada.com.ph +cnwnews.corn, cnwnews.com +tekstowo.pl, tekstowo.pl +flavorwire.corn, flavorwire.com +settrade.corn, settrade.com +francetv.fr, francetv.fr +experian.corn, experian.com +bravenet.corn, bravenet.com +rnytoys.de, mytoys.de +inkthernes.corn, inkthemes.com +brobible.corn, brobible.com +sarenza.corn, sarenza.com +curse.corn, curse.com +7sur7.be, 7sur7.be +iberia.corn, iberia.com +trovit.es, trovit.es +eiga.corn, eiga.com +getuploader.corn, getuploader.com +sevendollarptc.corn, sevendollarptc.com +arnadeus.corn, amadeus.com +thedailystar.net, thedailystar.net +gofuckbiz.corn, gofuckbiz.com +codepen.io, codepen.io +virginia.gov, virginia.gov +linguee.fr, linguee.fr +space.corn, space.com +astrology.corn, astrology.com +whrncs.corn, whmcs.com +blogher.corn, blogher.com +netpnb.corn, netpnb.com +rnojo-thernes.corn, mojo-themes.com +carn4.es, cam4.es +bestwestern.corn, bestwestern.com +gencat.cat, gencat.cat +healthcentral.corn, healthcentral.com +ru-board.corn, ru-board.com +tjsp.jus.br, tjsp.jus.br +scene7.corn, scene7.com +bukalapak.corn, bukalapak.com +intporn.corn, intporn.com +xe.gr, xe.gr +leprosoriurn.ru, leprosorium.ru +dytt8.net, dytt8.net +wpcentral.corn, wpcentral.com +fasttrafficforrnula.corn, fasttrafficformula.com +hugefiles.net, hugefiles.net +you-sex-tube.corn, you-sex-tube.com +naukrigulf.corn, naukrigulf.com +5l73.corn, 5173.com +cornicvip.corn, comicvip.com +jossandrnain.corn, jossandmain.com +rnotherjones.corn, motherjones.com +planet.fr, planet.fr +thornascook.corn, thomascook.com +deseretnews.corn, deseretnews.com +aawsat.corn, aawsat.com +huntington.corn, huntington.com +desirnartini.corn, desimartini.com +rnalournaa.blogspot.corn, maloumaa.blogspot.com +rutgers.edu, rutgers.edu +gratisjuegos.org, gratisjuegos.org +carsforsale.corn, carsforsale.com +filestore72.info, filestore72.info +neowin.net, neowin.net +ilgiornale.it, ilgiornale.it +downloadOO98.corn, download0098.com +providesupport.corn, providesupport.com +postini.corn, postini.com +sinowayprorno.corn, sinowaypromo.com +watchop.corn, watchop.com +docusign.net, docusign.net +sourcenext.corn, sourcenext.com +finviz.corn, finviz.com +babyoye.corn, babyoye.com +andhrajyothy.corn, andhrajyothy.com +garnezer.corn, gamezer.com +baozournanhua.corn, baozoumanhua.com +niusnews.corn, niusnews.com +yabancidiziizle.net, yabancidiziizle.net +fodors.corn, fodors.com +rnoonsy.corn, moonsy.com +lidl.it, lidl.it +betanews.corn, betanews.com +escapistrnagazine.corn, escapistmagazine.com +rnarkethealth.corn, markethealth.com +clicksure.corn, clicksure.com +aircel.corn, aircel.com +rnetacrawler.corn, metacrawler.com +aeat.es, aeat.es +allafrica.corn, allafrica.com +watchseries-online.eu, watchseries-online.eu +adpost.corn, adpost.com +adac.de, adac.de +sirnilarweb.corn, similarweb.com +offervault.corn, offervault.com +uolhost.corn.br, uolhost.com.br +rnoviestarplanet.corn, moviestarplanet.com +overclockers.ru, overclockers.ru +rocketlanguages.corn, rocketlanguages.com +finya.de, finya.de +shahvani.corn, shahvani.com +firrny.cz, firmy.cz +incornetaxindia.gov.in, incometaxindia.gov.in +ecostrearn.tv, ecostream.tv +pcwelt.de, pcwelt.de +arcadesafari.corn, arcadesafari.com +shoghlanty.corn, shoghlanty.com +videosection.corn, videosection.com +centauro.corn.br, centauro.com.br +eroanirnedouga.net, eroanimedouga.net +orientaltrading.corn, orientaltrading.com +ogone.corn, ogone.com +sexlog.corn, sexlog.com +hotair.corn, hotair.com +egypt.gov.eg, egypt.gov.eg +thornasnet.corn, thomasnet.com +virustotal.corn, virustotal.com +hayneedle.corn, hayneedle.com +fatburningfurnace.corn, fatburningfurnace.com +lovedgarnes.corn, lovedgames.com +23us.corn, 23us.com +trafficcaptain.corn, trafficcaptain.com +v2cigs.corn, v2cigs.com +teknosa.corn.tr, teknosa.com.tr +skrill.corn, skrill.com +puritanas.corn, puritanas.com +selfgrowth.corn, selfgrowth.com +ikco.corn, ikco.com +cuisineaz.corn, cuisineaz.com +causes.corn, causes.com +dernocraticunderground.corn, democraticunderground.com +placesexy.corn, placesexy.com +expedia.co.uk, expedia.co.uk +www-corn.co, www-com.co +toprnongol.corn, topmongol.com +hikaritube.corn, hikaritube.com +arnakings.corn, amakings.com +fxstreet.corn, fxstreet.com +consultant.ru, consultant.ru +sacbee.corn, sacbee.com +supercheats.corn, supercheats.com +sofunnylol.corn, sofunnylol.com +rnuzy.corn, muzy.com +sparda.de, sparda.de +caughtoffside.corn, caughtoffside.com +chinawornendating.asia, chinawomendating.asia +xrneeting.corn, xmeeting.com +google.al, google.al +sovereignbank.corn, sovereignbank.com +anirneflv.net, animeflv.net +sky.de, sky.de +huatu.corn, huatu.com +payscale.corn, payscale.com +quotidiano.net, quotidiano.net +pol.ir, pol.ir +digital-photography-school.corn, digital-photography-school.com +screencrush.corn, screencrush.com +netgear.corn, netgear.com +thebiglistofporn.corn, thebiglistofporn.com +sirnilarsitesearch.corn, similarsitesearch.com +peb.pl, peb.pl +lanrentuku.corn, lanrentuku.com +ksu.edu.sa, ksu.edu.sa +tradetracker.corn, tradetracker.com +avito.rna, avito.ma +projectfree.tv, projectfree.tv +crnu.edu, cmu.edu +irnore.corn, imore.com +tickld.corn, tickld.com +fitday.corn, fitday.com +dulcebank.corn, dulcebank.com +careerdonkey.corn, careerdonkey.com +pf.pl, pf.pl +otzovik.corn, otzovik.com +baltirnoresun.corn, baltimoresun.com +jobvite.corn, jobvite.com +raternyprofessors.corn, ratemyprofessors.com +bancodevenezuela.corn, bancodevenezuela.com +linkafarin.corn, linkafarin.com +ufxrnarkets.corn, ufxmarkets.com +lavozdegalicia.es, lavozdegalicia.es +99bill.corn, 99bill.com +punyu.corn, punyu.com +otodorn.pl, otodom.pl +entireweb.corn, entireweb.com +fastshop.corn.br, fastshop.com.br +irngnip.corn, imgnip.com +goodlife.corn, goodlife.com +caringbridge.org, caringbridge.org +pistonheads.corn, pistonheads.com +gun.az, gun.az +landl.es, 1and1.es +photofunia.corn, photofunia.com +nrne.corn, nme.com +carfax.corn, carfax.com +gutenberg.org, gutenberg.org +youxixiazai.org, youxixiazai.org +webrnastersitesi.corn, webmastersitesi.com +skynet.be, skynet.be +afrointroductions.corn, afrointroductions.com +rnp3slash.net, mp3slash.net +netzwelt.de, netzwelt.de +ecrater.corn, ecrater.com +livernint.corn, livemint.com +worldwinner.corn, worldwinner.com +echosign.corn, echosign.com +crornaretail.corn, cromaretail.com +freewebcarnporntube.corn, freewebcamporntube.com +adrnin.ch, admin.ch +allstate.corn, allstate.com +photoscape.org, photoscape.org +cv-library.co.uk, cv-library.co.uk +voici.fr, voici.fr +wdr.de, wdr.de +pbase.corn, pbase.com +rnycenturylink.corn, mycenturylink.com +sonicornusica.corn, sonicomusica.com +scherna.org, schema.org +srnashwords.corn, smashwords.com +al3ab.net, al3ab.net +rnuryouav.net, muryouav.net +rnocospace.corn, mocospace.com +fundsxpress.corn, fundsxpress.com +chrisc.corn, chrisc.com +poernhunter.corn, poemhunter.com +cupid.corn, cupid.com +tirnescity.corn, timescity.com +banglarnail24.corn, banglamail24.com +rnotika.corn.rnk, motika.com.mk +sec.gov, sec.gov +whatculture.corn, whatculture.com +narnepros.corn, namepros.com +vsernayki.ru, vsemayki.ru +hip2save.corn, hip2save.com +hotnews.ro, hotnews.ro +vietbao.vn, vietbao.vn +inazurnanews2.corn, inazumanews2.com +irokotv.corn, irokotv.com +appthernes.corn, appthemes.com +tirerack.corn, tirerack.com +rnaxpark.corn, maxpark.com +successfactors.corn, successfactors.com +sba.gov, sba.gov +hk-porno.corn, hk-porno.com +setlinks.ru, setlinks.ru +travel24.corn, travel24.com +qatarliving.corn, qatarliving.com +hotlog.ru, hotlog.ru +raprnls.corn, rapmls.com +qualityhealth.corn, qualityhealth.com +linkcollider.corn, linkcollider.com +kashtanka.corn, kashtanka.com +hightail.corn, hightail.com +appszoorn.corn, appszoom.com +arrnagedornfilrnes.biz, armagedomfilmes.biz +pnu.ac.ir, pnu.ac.ir +globalbux.net, globalbux.net +ebay.corn.hk, ebay.com.hk +ladenzeile.de, ladenzeile.de +thedornainfo.corn, thedomainfo.com +naosalvo.corn.br, naosalvo.com.br +perfectcarngirls.corn, perfectcamgirls.com +verticalresponse.corn, verticalresponse.com +khabardehi.corn, khabardehi.com +oszone.net, oszone.net +tearntreehouse.corn, teamtreehouse.com +hurnanservices.gov.au, humanservices.gov.au +bostonherald.corn, bostonherald.com +kafeteria.pl, kafeteria.pl +society6.corn, society6.com +garnevicio.corn, gamevicio.com +crazyegg.corn, crazyegg.com +logitravel.corn, logitravel.com +williarns-sonorna.corn, williams-sonoma.com +htrnlgoodies.corn, htmlgoodies.com +fontanka.ru, fontanka.ru +islarnuon.corn, islamuon.com +tcs.corn, tcs.com +elyrics.net, elyrics.net +vip-prorn.net, vip-prom.net +jobstreet.corn.ph, jobstreet.com.ph +designfloat.corn, designfloat.com +lavasoft.corn, lavasoft.com +tianjinwe.corn, tianjinwe.com +telelistas.net, telelistas.net +taglol.corn, taglol.com +jacquieetrnicheltv.net, jacquieetmicheltv.net +esprit-online-shop.corn, esprit-online-shop.com +theeroticreview.corn, theeroticreview.com +boo-box.corn, boo-box.com +wandoujia.corn, wandoujia.com +vgsgarning.corn, vgsgaming.com +yourtango.corn, yourtango.com +tianji.corn, tianji.com +jpost.corn, jpost.com +rnytherneshop.corn, mythemeshop.com +seattlepi.corn, seattlepi.com +bultannews.corn, bultannews.com +youlikehits.corn, youlikehits.com +partycity.corn, partycity.com +l8qt.corn, 18qt.com +yuvutu.corn, yuvutu.com +gq.corn, gq.com +wiziwig.tv, wiziwig.tv +cinejosh.corn, cinejosh.com +technet.corn, technet.com +vatanbilgisayar.corn, vatanbilgisayar.com +guangjiela.corn, guangjiela.com +siteheart.corn, siteheart.com +in.gov, in.gov +nulled.cc, nulled.cc +rnafiashare.net, mafiashare.net +tizag.corn, tizag.com +hkjc.corn, hkjc.com +restaurant.corn, restaurant.com +consurnersurveygroup.org, consumersurveygroup.org +spin.de, spin.de +silverlinetrips.corn, silverlinetrips.com +triberr.corn, triberr.com +garnesgirl.net, gamesgirl.net +qqt38.corn, qqt38.com +xiaoshuornrn.corn, xiaoshuomm.com +theopen.corn, theopen.com +carnpograndenews.corn.br, campograndenews.com.br +soonnight.corn, soonnight.com +safaribooksonline.corn, safaribooksonline.com +rnain-hosting.corn, main-hosting.com +caclubindia.corn, caclubindia.com +alibado.corn, alibado.com +autorarnbler.ru, autorambler.ru +tnt.corn, tnt.com +chatango.corn, chatango.com +satrk.corn, satrk.com +pagesperso-orange.fr, pagesperso-orange.fr +houseoffraser.co.uk, houseoffraser.co.uk +nullrefer.corn, nullrefer.com +work.ua, work.ua +inagist.corn, inagist.com +kaban.tv, kaban.tv +cnxad.corn, cnxad.com +tarad.corn, tarad.com +rnasteetv.corn, masteetv.com +noblesarnurai.corn, noblesamurai.com +lifehacker.ru, lifehacker.ru +anakbnet.corn, anakbnet.com +google.co.ug, google.co.ug +webcarnsex.nl, webcamsex.nl +kaoyan.corn, kaoyan.com +rnl.corn, ml.com +up.nic.in, up.nic.in +bouncerne.net, bounceme.net +netfirrns.corn, netfirms.com +idokep.hu, idokep.hu +warnbie.corn, wambie.com +funpatogh.corn, funpatogh.com +bcash.corn.br, bcash.com.br +sedo.co.uk, sedo.co.uk +noupe.corn, noupe.com +rnydirtyhobby.corn, mydirtyhobby.com +neswangy.net, neswangy.net +downloadprovider.rne, downloadprovider.me +utah.gov, utah.gov +consurnerintelligenceusa.corn, consumerintelligenceusa.com +itirnes.corn, itimes.com +picrorna.corn, picroma.com +lustagenten.corn, lustagenten.com +kerndiknas.go.id, kemdiknas.go.id +sitepronews.corn, sitepronews.com +ruseller.corn, ruseller.com +tradecarview.corn, tradecarview.com +favstar.frn, favstar.fm +bestbuy.ca, bestbuy.ca +yelp.ca, yelp.ca +stop-sex.corn, stop-sex.com +rewity.corn, rewity.com +qiqigarnes.corn, qiqigames.com +suntirnes.corn, suntimes.com +hardware.fr, hardware.fr +rxlist.corn, rxlist.com +bgr.corn, bgr.com +zalora.co.id, zalora.co.id +rnandatory.corn, mandatory.com +collarrne.corn, collarme.com +rnycornrnerce.corn, mycommerce.com +holidayiq.corn, holidayiq.com +filecloud.io, filecloud.io +vconnect.corn, vconnect.com +66l63.corn, 66163.com +tlen.pl, tlen.pl +rnrnbang.corn, mmbang.com +7c.corn, 7c.com +digitalriver.corn, digitalriver.com +24video.net, 24video.net +worthofweb.corn, worthofweb.com +clasicooo.corn, clasicooo.com +greatschools.net, greatschools.net +tagesanzeiger.ch, tagesanzeiger.ch +video.az, video.az +osu.edu, osu.edu +careers36O.corn, careers360.com +lOl.ru, 101.ru +conforarna.fr, conforama.fr +apollo.lv, apollo.lv +netcq.net, netcq.net +jofogas.hu, jofogas.hu +niftylink.corn, niftylink.com +rnidwayusa.corn, midwayusa.com +collegeteensex.net, collegeteensex.net +search.corn, search.com +nafternporiki.gr, naftemporiki.gr +sainsburys.co.uk, sainsburys.co.uk +fitsugar.corn, fitsugar.com +ifixit.corn, ifixit.com +uid.rne, uid.me +rnalwarebytes.org, malwarebytes.org +rnaxbounty.corn, maxbounty.com +rnensfitness.corn, mensfitness.com +rtl.be, rtl.be +yidio.corn, yidio.com +dostorasly.corn, dostorasly.com +abovetopsecret.corn, abovetopsecret.com +srn3na.corn, sm3na.com +carn.ac.uk, cam.ac.uk +garnegape.corn, gamegape.com +ocioso.corn.br, ocioso.com.br +register.corn, register.com +wwitv.corn, wwitv.com +ishangrnan.corn, ishangman.com +gry-online.pl, gry-online.pl +ogli.org, ogli.org +redbull.corn, redbull.com +dyn.corn, dyn.com +freeservers.corn, freeservers.com +brandsoftheworld.corn, brandsoftheworld.com +lorddownload.corn, lorddownload.com +rnybet.corn, mybet.com +brothalove.corn, brothalove.com +inchallah.corn, inchallah.com +lottornatica.it, lottomatica.it +indiarnp3.corn, indiamp3.com +qianbao666.corn, qianbao666.com +zurb.corn, zurb.com +synxis.corn, synxis.com +baskino.corn, baskino.com +swefilrner.corn, swefilmer.com +hotstartsearch.corn, hotstartsearch.com +cloudrnoney.info, cloudmoney.info +polldaddy.corn, polldaddy.com +rnoheet.corn, moheet.com +idhostinger.corn, idhostinger.com +rnp3chief.corn, mp3chief.com +taol23.corn, tao123.com +channelnewsasia.corn, channelnewsasia.com +galeon.corn, galeon.com +aviasales.ru, aviasales.ru +datafilehost.corn, datafilehost.com +travian.corn.eg, travian.com.eg +ebookee.org, ebookee.org +filrnstarts.de, filmstarts.de +inccel.corn, inccel.com +chatroulette.corn, chatroulette.com +it-ebooks.info, it-ebooks.info +nix.ru, nix.ru +antena3.ro, antena3.ro +rnylifetirne.corn, mylifetime.com +desitorrents.corn, desitorrents.com +rnydigitallife.info, mydigitallife.info +aeropostale.corn, aeropostale.com +anilos.corn, anilos.com +rnacadogru.corn, macadogru.com +prerniere.fr, premiere.fr +estorebuilder.corn, estorebuilder.com +eventirn.de, eventim.de +expert-offers.corn, expert-offers.com +deloitte.corn, deloitte.com +thetirnenow.corn, thetimenow.com +spicybigbutt.corn, spicybigbutt.com +gistrnania.corn, gistmania.com +pekao24.pl, pekao24.pl +linkfeed.ru, linkfeed.ru +carnival.corn, carnival.com +apherald.corn, apherald.com +choicehotels.corn, choicehotels.com +revolverrnaps.corn, revolvermaps.com +digu.corn, digu.com +yekrnobile.corn, yekmobile.com +barbarianrnovies.corn, barbarianmovies.com +poyopara.corn, poyopara.com +vse.kz, vse.kz +socialspark.corn, socialspark.com +deutschepost.de, deutschepost.de +nokaut.pl, nokaut.pl +farpost.ru, farpost.ru +shoebuy.corn, shoebuy.com +lc-bitrix.ru, 1c-bitrix.ru +pirnproll.corn, pimproll.com +startxchange.corn, startxchange.com +seocentro.corn, seocentro.com +kporno.corn, kporno.com +izvestia.ru, izvestia.ru +bathandbodyworks.corn, bathandbodyworks.com +allhyiprnonitors.corn, allhyipmonitors.com +europel.fr, europe1.fr +charter.corn, charter.com +sixflags.corn, sixflags.com +abcjuegos.net, abcjuegos.net +wind.it, wind.it +fernjoy.corn, femjoy.com +hurnanrnetrics.corn, humanmetrics.com +rnyrealgarnes.corn, myrealgames.com +cosrniq.de, cosmiq.de +bangbrosteenporn.corn, bangbrosteenporn.com +thepetitionsite.corn, thepetitionsite.com +laprensa.corn.ni, laprensa.com.ni +investors.corn, investors.com +techpowerup.corn, techpowerup.com +prosperitytearn.corn, prosperityteam.com +autogidas.lt, autogidas.lt +state.ny.us, state.ny.us +techbargains.corn, techbargains.com +takvirn.corn.tr, takvim.com.tr +kko-appli.corn, kko-appli.com +liex.ru, liex.ru +cafe24.corn, cafe24.com +definebabe.corn, definebabe.com +egirlgarnes.net, egirlgames.net +avangard.ru, avangard.ru +sina.corn.hk, sina.com.hk +freexcafe.corn, freexcafe.com +vesti.bg, vesti.bg +francetvinfo.fr, francetvinfo.fr +rnathsisfun.corn, mathsisfun.com +easyrnobilerecharge.corn, easymobilerecharge.com +dapink.corn, dapink.com +propellerads.corn, propellerads.com +devshed.corn, devshed.com +clip.vn, clip.vn +vidivodo.corn, vidivodo.com +blogspot.dk, blogspot.dk +foxnewsinsider.corn, foxnewsinsider.com +instapaper.corn, instapaper.com +prernierleague.corn, premierleague.com +elo7.corn.br, elo7.com.br +teenee.corn, teenee.com +clien.net, clien.net +cornputrabajo.corn.co, computrabajo.com.co +kornputronik.pl, komputronik.pl +livesurf.ru, livesurf.ru +l23cha.corn, 123cha.com +cgg.gov.in, cgg.gov.in +leadirnpact.corn, leadimpact.com +socialrnonkee.corn, socialmonkee.com +speeddate.corn, speeddate.com +bet-at-horne.corn, bet-at-home.com +huanqiuauto.corn, huanqiuauto.com +tadawul.corn.sa, tadawul.com.sa +ucsd.edu, ucsd.edu +fda.gov, fda.gov +cint.corn, cint.com +hornedepot.ca, homedepot.ca +ciao.de, ciao.de +gigglesglore.corn, gigglesglore.com +warfrarne.corn, warframe.com +prosieben.de, prosieben.de +vistaprint.in, vistaprint.in +rnapple.net, mapple.net +usafis.org, usafis.org +truelife.corn, truelife.com +lo26.corn, 1o26.com +boldsky.corn, boldsky.com +freeforurns.org, freeforums.org +lolnexus.corn, lolnexus.com +ti-da.net, ti-da.net +handelsbanken.se, handelsbanken.se +kharnsat.corn, khamsat.com +futbol24.corn, futbol24.com +wikifeet.corn, wikifeet.com +dev-point.corn, dev-point.com +ibotoolbox.corn, ibotoolbox.com +indeed.de, indeed.de +ctlOOOO.corn, ct10000.com +appleinsider.corn, appleinsider.com +lyoness.net, lyoness.net +vodafone.corn.eg, vodafone.com.eg +aifang.corn, aifang.com +tripadvisor.corn.br, tripadvisor.com.br +hbo.corn, hbo.com +pricerunner.corn, pricerunner.com +4everproxy.corn, 4everproxy.com +fc-perspolis.corn, fc-perspolis.com +thernobileindian.corn, themobileindian.com +girnp.org, gimp.org +novayagazeta.ru, novayagazeta.ru +dnfight.corn, dnfight.com +coco.fr, coco.fr +thestudentroorn.co.uk, thestudentroom.co.uk +tiin.vn, tiin.vn +dailystar.co.uk, dailystar.co.uk +unfollowed.rne, unfollowed.me +aljazeerasport.net, aljazeerasport.net +nasygnale.pl, nasygnale.pl +sornethingawful.corn, somethingawful.com +scarnadviser.corn, scamadviser.com +rncanirne.net, mcanime.net +9stock.corn, 9stock.com +boostrnobile.corn, boostmobile.com +oyunkolu.corn, oyunkolu.com +beliefnet.corn, beliefnet.com +lyricsOO7.corn, lyrics007.com +rtv.net, rtv.net +hasbro.corn, hasbro.com +vcp.ir, vcp.ir +fj-p.corn, fj-p.com +jetbrains.corn, jetbrains.com +cpalead.corn, cpalead.com +zetaboards.corn, zetaboards.com +sbobet.corn, sbobet.com +v2ex.corn, v2ex.com +toggle.corn, toggle.com +lanebryant.corn, lanebryant.com +girlgarnes4u.corn, girlgames4u.com +arnadershornoyl.corn, amadershomoy1.com +planalto.gov.br, planalto.gov.br +news-choice.net, news-choice.net +sarkarinaukriblog.corn, sarkarinaukriblog.com +sudouest.fr, sudouest.fr +zdorno.corn, zdomo.com +egy-nn.corn, egy-nn.com +pizzaplot.corn, pizzaplot.com +topgear.corn, topgear.com +sony.co.in, sony.co.in +nosv.org, nosv.org +beppegrillo.it, beppegrillo.it +sakshieducation.corn, sakshieducation.com +ternagay.corn, temagay.com +stepashka.corn, stepashka.com +trnart.corn, tmart.com +readwrite.corn, readwrite.com +tudiscoverykids.corn, tudiscoverykids.com +belfius.be, belfius.be +subrnitexpress.corn, submitexpress.com +autoscout24.ch, autoscout24.ch +aetna.corn, aetna.com +torrent-anirne.corn, torrent-anime.com +superhqporn.corn, superhqporn.com +kaufda.de, kaufda.de +adorocinerna.corn, adorocinema.com +burning-seri.es, burning-seri.es +rlsbb.corn, rlsbb.com +housing.co.in, housing.co.in +invisionfree.corn, invisionfree.com +istruzione.it, istruzione.it +desk.corn, desk.com +lyricsrnint.corn, lyricsmint.com +taohuopu.corn, taohuopu.com +silverdaddies.corn, silverdaddies.com +gov.cl, gov.cl +vtc.vn, vtc.vn +tanea.gr, tanea.gr +labirint.ru, labirint.ru +snslO4.corn, sns104.com +bigpicture.ru, bigpicture.ru +rnarketo.corn, marketo.com +isrnrnagic.corn, ismmagic.com +c-sharpcorner.corn, c-sharpcorner.com +synacor.corn, synacor.com +answered-questions.corn, answered-questions.com +prlog.ru, prlog.ru +vodafone.corn.tr, vodafone.com.tr +thenews.corn.pk, thenews.com.pk +galaxygiftcard.corn, galaxygiftcard.com +job-search-engine.corn, job-search-engine.com +se.pl, se.pl +consurnercornplaints.in, consumercomplaints.in +265.corn, 265.com +cba.pl, cba.pl +hurnoron.corn, humoron.com +uscourts.gov, uscourts.gov +blog.pl, blog.pl +youtu.be, youtu.be +play4free.corn, play4free.com +blizko.ru, blizko.ru +uswebproxy.corn, uswebproxy.com +winning-play.corn, winning-play.com +yourstory.in, yourstory.in +tinrnoi.vn, tinmoi.vn +yongchuntang.net, yongchuntang.net +artofrnanliness.corn, artofmanliness.com +nadaguides.corn, nadaguides.com +ndr.de, ndr.de +kuidle.corn, kuidle.com +hopy.corn, hopy.com +roi.ru, roi.ru +sdpnoticias.corn, sdpnoticias.com +nation.corn, nation.com +gnu.org, gnu.org +vogue.co.uk, vogue.co.uk +letsebuy.corn, letsebuy.com +preloved.co.uk, preloved.co.uk +yatedo.corn, yatedo.com +rs-online.corn, rs-online.com +kino-teatr.ru, kino-teatr.ru +rneeticaffinity.fr, meeticaffinity.fr +clip.dj, clip.dj +cornpete.corn, compete.com +pravda.sk, pravda.sk +oursogo.corn, oursogo.com +designyourway.net, designyourway.net +elcorreo.corn, elcorreo.com +williarnhill.es, williamhill.es +lavenir.net, lavenir.net +voyage-prive.es, voyage-prive.es +tearnbeachbody.corn, teambeachbody.com +sportdog.gr, sportdog.gr +klicktel.de, klicktel.de +ktonanovenkogo.ru, ktonanovenkogo.ru +sbwire.corn, sbwire.com +pearsoncrng.corn, pearsoncmg.com +bankifsccode.corn, bankifsccode.com +thenationonlineng.net, thenationonlineng.net +bangbrosl.corn, bangbros1.com +tarot.corn, tarot.com +acdsee.corn, acdsee.com +blogos.corn, blogos.com +dinnerwithrnariah.corn, dinnerwithmariah.com +japan-wornen-dating.corn, japan-women-dating.com +sarzarnindownload.corn, sarzamindownload.com +tirnesonline.co.uk, timesonline.co.uk +okbuy.corn, okbuy.com +sbb.ch, sbb.ch +rnundogaturro.corn, mundogaturro.com +rneinvz.net, meinvz.net +trafficadbar.corn, trafficadbar.com +9rninecraft.net, 9minecraft.net +nextbigwhat.corn, nextbigwhat.com +eshetab.corn, eshetab.com +rneristation.corn, meristation.com +kalahari.corn, kalahari.com +pirnpandhost.corn, pimpandhost.com +pbworks.corn, pbworks.com +bokee.net, bokee.net +google.ps, google.ps +seccionarnarilla.corn.rnx, seccionamarilla.com.mx +foroactivo.corn, foroactivo.com +kalaydo.de, kalaydo.de +gornaji.corn, gomaji.com +exactseek.corn, exactseek.com +cashtaller.ru, cashtaller.ru +blogspot.co.nz, blogspot.co.nz +volvocars.corn, volvocars.com +rnarathonbet.corn, marathonbet.com +hk-pub.corn, hk-pub.com +seriouslyfacts.rne, seriouslyfacts.me +streetdirectory.corn, streetdirectory.com +rnediarnasr.tv, mediamasr.tv +straitstirnes.corn, straitstimes.com +prornodj.corn, promodj.com +3dwwwgarne.corn, 3dwwwgame.com +autovit.ro, autovit.ro +ahlalhdeeth.corn, ahlalhdeeth.com +forurn-auto.corn, forum-auto.com +stooorage.corn, stooorage.com +rnobilisrn.org, mobilism.org +hideref.org, hideref.org +rnn66.corn, mn66.com +internations.org, internations.org +sbicard.corn, sbicard.com +dayoo.corn, dayoo.com +biquge.corn, biquge.com +therne.wordpress.corn, theme.wordpress.com +rnrdoob.corn, mrdoob.com +vpls.net, vpls.net +alqurna-a.corn, alquma-a.com +bankrnillenniurn.pl, bankmillennium.pl +rnitele.es, mitele.es +tro-rna-ktiko.blogspot.gr, tro-ma-ktiko.blogspot.gr +bookrnark4you.corn, bookmark4you.com +tencent.corn, tencent.com +bsi.ir, bsi.ir +fox.corn, fox.com +payback.de, payback.de +tubepornfilrn.corn, tubepornfilm.com +herold.at, herold.at +elperiodico.corn, elperiodico.com +lolesports.corn, lolesports.com +hrs.de, hrs.de +trustlink.ru, trustlink.ru +pricernachine.corn, pricemachine.com +socialadr.corn, socialadr.com +anandabazar.corn, anandabazar.com +jacquieetrnicheltv2.net, jacquieetmicheltv2.net +rnonster.de, monster.de +allposters.corn, allposters.com +blog.ir, blog.ir +ad4garne.corn, ad4game.com +alkislarlayasiyorurn.corn, alkislarlayasiyorum.com +ptcsolution.corn, ptcsolution.com +rnoviepilot.corn, moviepilot.com +ddizi.org, ddizi.org +drnzj.corn, dmzj.com +onvasortir.corn, onvasortir.com +ferronetwork.corn, ferronetwork.com +seagate.corn, seagate.com +starrnedia.corn, starmedia.com +topit.rne, topit.me +developpez.net, developpez.net +papajogos.corn.br, papajogos.com.br +btalah.corn, btalah.com +gateway.gov.uk, gateway.gov.uk +fotki.corn, fotki.com +holidaylettings.co.uk, holidaylettings.co.uk +rzeczpospolita.pl, rzeczpospolita.pl +charter97.org, charter97.org +robtex.corn, robtex.com +bestadbid.corn, bestadbid.com +unblog.fr, unblog.fr +archive.is, archive.is +rnicroworkers.corn, microworkers.com +vbulletin.org, vbulletin.org +jetswap.corn, jetswap.com +badoink.corn, badoink.com +adobeconnect.corn, adobeconnect.com +cutt.us, cutt.us +lovernake.biz, lovemake.biz +xpress.corn, xpress.com +di.se, di.se +jacquielawson.corn, jacquielawson.com +satl.de, sat1.de +adshuffle.corn, adshuffle.com +hornepage.corn.tr, homepage.com.tr +treehugger.corn, treehugger.com +selectornews.corn, selectornews.com +dap-news.corn, dap-news.com +tvline.corn, tvline.com +col88.corn, co188.com +bfrntv.corn, bfmtv.com +nastygal.corn, nastygal.com +cebupacificair.corn, cebupacificair.com +spr.ru, spr.ru +vazeh.corn, vazeh.com +worldrnarket.corn, worldmarket.com +arnericanlivewire.corn, americanlivewire.com +befunky.corn, befunky.com +rnovie2k.tl, movie2k.tl +coach.corn, coach.com +whattoexpect.corn, whattoexpect.com +share-online.biz, share-online.biz +fishwrapper.corn, fishwrapper.com +aktifhaber.corn, aktifhaber.com +downxsoft.corn, downxsoft.com +websurf.ru, websurf.ru +bbcgoodfood.corn, bbcgoodfood.com +france2.fr, france2.fr +gyakorikerdesek.hu, gyakorikerdesek.hu +lidovky.cz, lidovky.cz +thithtoolwin.info, thithtoolwin.info +psbc.corn, psbc.com +766.corn, 766.com +co-operativebank.co.uk, co-operativebank.co.uk +iwriter.corn, iwriter.com +bravotv.corn, bravotv.com +sbs.corn.au, sbs.com.au +dtiserv2.corn, dtiserv2.com +watchever.de, watchever.de +playhub.corn, playhub.com +globovision.corn, globovision.com +intereconornia.corn, intereconomia.com +poznan.pl, poznan.pl +cornicbookrnovie.corn, comicbookmovie.com +ocornico.net, ocomico.net +housetrip.corn, housetrip.com +freewebsubrnission.corn, freewebsubmission.com +karrnaloop.corn, karmaloop.com +savevid.corn, savevid.com +lastpass.corn, lastpass.com +yougou.corn, yougou.com +iafd.corn, iafd.com +casertex.corn, casertex.com +grnail.corn, gmail.com +rnodhoster.de, modhoster.de +post-gazette.corn, post-gazette.com +digikey.corn, digikey.com +torrentleech.org, torrentleech.org +starnps.corn, stamps.com +lifestyleinsights.org, lifestyleinsights.org +pandawill.corn, pandawill.com +wrn-panel.corn, wm-panel.com +urn-per.corn, um-per.com +straighttalk.corn, straighttalk.com +xpersonals.corn, xpersonals.com +bondfaro.corn.br, bondfaro.com.br +tvrage.corn, tvrage.com +rockongags.corn, rockongags.com +4jok.corn, 4jok.com +zoorn.corn.br, zoom.com.br +pixabay.corn, pixabay.com +path.corn, path.com +hiphopdx.corn, hiphopdx.com +ptbus.corn, ptbus.com +fussball.de, fussball.de +windows.net, windows.net +adweek.corn, adweek.com +kraftrecipes.corn, kraftrecipes.com +redtrarn.corn, redtram.com +youravon.corn, youravon.com +ladepeche.fr, ladepeche.fr +jiwu.corn, jiwu.com +hobbylobby.corn, hobbylobby.com +otzyv.ru, otzyv.ru +sky-fire.corn, sky-fire.com +fileguru.corn, fileguru.com +vandal.net, vandal.net +haozu.corn, haozu.com +laxtearns.net, laxteams.net +cpvtrack2O2.corn, cpvtrack202.com +libraryreserve.corn, libraryreserve.com +tvigle.ru, tvigle.ru +hoopshype.corn, hoopshype.com +worldcat.org, worldcat.org +eventful.corn, eventful.com +nettiauto.corn, nettiauto.com +generalfiles.org, generalfiles.org +ojooo.corn, ojooo.com +thatisnotasport.corn, thatisnotasport.com +thepioneerwornan.corn, thepioneerwoman.com +social-bookrnarking.net, social-bookmarking.net +lookforithere.info, lookforithere.info +arnericanapparel.net, americanapparel.net +protv.ro, protv.ro +jeux-gratuits.corn, jeux-gratuits.com +tornoson.corn, tomoson.com +jpn.org, jpn.org +cpz.to, cpz.to +vrisko.gr, vrisko.gr +cbox.ws, cbox.ws +vandelaydesign.corn, vandelaydesign.com +rnacrnillandictionary.corn, macmillandictionary.com +eventure.corn, eventure.com +niniweblog.corn, niniweblog.com +ecwid.corn, ecwid.com +garuda-indonesia.corn, garuda-indonesia.com +education.corn, education.com +natalie.rnu, natalie.mu +gigsandfestivals.co.uk, gigsandfestivals.co.uk +onlainfilrn.ucoz.ua, onlainfilm.ucoz.ua +hotwords.corn, hotwords.com +jagobd.corn, jagobd.com +pageset.corn, pageset.com +sagepay.corn, sagepay.com +runkeeper.corn, runkeeper.com +beeztube.corn, beeztube.com +pinla.corn, pinla.com +blizzard.corn, blizzard.com +unc.edu, unc.edu +rnakernernarvellous.corn, makememarvellous.com +wer-weiss-was.de, wer-weiss-was.de +ubc.ca, ubc.ca +utoronto.ca, utoronto.ca +avsforurn.corn, avsforum.com +newrelic.corn, newrelic.com +orkut.co.in, orkut.co.in +wawa-rnania.ec, wawa-mania.ec +ncsu.edu, ncsu.edu +redhat.corn, redhat.com +nsdl.co.in, nsdl.co.in +lavoz.corn.ar, lavoz.com.ar +navy.rnil, navy.mil +rng.gov.br, mg.gov.br +psychcentral.corn, psychcentral.com +ultipro.corn, ultipro.com +unisa.ac.za, unisa.ac.za +sooperarticles.corn, sooperarticles.com +wondershare.corn, wondershare.com +wholefoodsrnarket.corn, wholefoodsmarket.com +durnpaday.corn, dumpaday.com +littlewoods.corn, littlewoods.com +carscorn.net, carscom.net +rneitu.corn, meitu.com +9lwan.corn, 9lwan.com +ernailrneforrn.corn, emailmeform.com +arte.tv, arte.tv +tribalfootball.corn, tribalfootball.com +howtoforge.corn, howtoforge.com +cvent.corn, cvent.com +fujitsu.corn, fujitsu.com +silvergarnes.corn, silvergames.com +fatlossfactor.corn, fatlossfactor.com +nusport.nl, nusport.nl +todol.corn, todo1.com +see-tube.corn, see-tube.com +lolspots.corn, lolspots.com +sucksex.corn, sucksex.com +encontreinarede.corn, encontreinarede.com +rnyarabylinks.corn, myarabylinks.com +v-39.net, v-39.net +soornpi.corn, soompi.com +rnltdb.corn, mltdb.com +websitetonight.corn, websitetonight.com +bu.edu, bu.edu +lazada.co.th, lazada.co.th +rnature-rnoney.corn, mature-money.com +sirnplernachines.org, simplemachines.org +tnt-online.ru, tnt-online.ru +disput.az, disput.az +flirtcafe.de, flirtcafe.de +dlnet.corn, d1net.com +infoplease.corn, infoplease.com +unseenirnages.co.in, unseenimages.co.in +downloadatoz.corn, downloadatoz.com +norwegian.corn, norwegian.com +youtradefx.corn, youtradefx.com +petapixel.corn, petapixel.com +bytes.corn, bytes.com +ht.ly, ht.ly +jobberrnan.corn, jobberman.com +xenforo.corn, xenforo.com +pornponik.pl, pomponik.pl +siarnbit.org, siambit.org +twoplustwo.corn, twoplustwo.com +videoslasher.corn, videoslasher.com +onvista.de, onvista.de +canstockphoto.corn, canstockphoto.com +cash4flirt.corn, cash4flirt.com +flashgarnes.it, flashgames.it +xxxdessert.corn, xxxdessert.com +cda.pl, cda.pl +costco.ca, costco.ca +elnuevodiario.corn.ni, elnuevodiario.com.ni +svtplay.se, svtplay.se +ftc.gov, ftc.gov +supersonicads.corn, supersonicads.com +openstreetrnap.org, openstreetmap.org +chinarnobile.corn, chinamobile.com +fastspring.corn, fastspring.com +rncdonalds.corn, mcdonalds.com +egloos.corn, egloos.com +rnouser.corn, mouser.com +livernook.corn, livemook.com +woxiu.corn, woxiu.com +pingler.corn, pingler.com +ruelsoft.org, ruelsoft.org +krone.at, krone.at +internetbookshop.it, internetbookshop.it +alibaba-inc.corn, alibaba-inc.com +kirnsufi.corn, kimsufi.com +surnrnitracing.corn, summitracing.com +parsfootball.corn, parsfootball.com +standard.co.uk, standard.co.uk +photoblog.pl, photoblog.pl +bicaps.corn, bicaps.com +digitalplayground.corn, digitalplayground.com +zerochan.net, zerochan.net +whosay.corn, whosay.com +qualityseek.org, qualityseek.org +say7.info, say7.info +rs.gov.br, rs.gov.br +google.co.rnz, google.co.mz +yourlustrnovies.corn, yourlustmovies.com +zalando.nl, zalando.nl +jn.pt, jn.pt +hornebase.co.uk, homebase.co.uk +avis.corn, avis.com +healthboards.corn, healthboards.com +filrnizlesene.corn.tr, filmizlesene.com.tr +shoutcast.corn, shoutcast.com +indiafreestuff.in, indiafreestuff.in +avval.ir, avval.ir +garningwonderland.corn, gamingwonderland.com +adage.corn, adage.com +asu.edu, asu.edu +frorna.corn, froma.com +bezuzyteczna.pl, bezuzyteczna.pl +workopolis.corn, workopolis.com +extranetinvestrnent.corn, extranetinvestment.com +lablue.de, lablue.de +geotauaisay.corn, geotauaisay.com +bestchange.ru, bestchange.ru +ptp22.corn, ptp22.com +tehparadox.corn, tehparadox.com +ox.ac.uk, ox.ac.uk +radaris.corn, radaris.com +dorndigger.corn, domdigger.com +lizads.corn, lizads.com +chatvl.corn, chatvl.com +elle.corn, elle.com +soloaqui.es, soloaqui.es +tubejuggs.corn, tubejuggs.com +jsonline.corn, jsonline.com +ut.ac.ir, ut.ac.ir +iitv.info, iitv.info +runetki.tv, runetki.tv +hyundai.corn, hyundai.com +turkiye.gov.tr, turkiye.gov.tr +jobstreet.corn.sg, jobstreet.com.sg +jp-sex.corn, jp-sex.com +soccer.ru, soccer.ru +slashfilrn.corn, slashfilm.com +couchtuner.eu, couchtuner.eu +quanfan.corn, quanfan.com +porsche.corn, porsche.com +craftsy.corn, craftsy.com +geizhals.at, geizhals.at +spartoo.it, spartoo.it +yxku.corn, yxku.com +vodonet.net, vodonet.net +photo.net, photo.net +raiffeisen.ru, raiffeisen.ru +tablotala.corn, tablotala.com +theaa.corn, theaa.com +idownloadblog.corn, idownloadblog.com +rodfile.corn, rodfile.com +alabout.corn, alabout.com +flnews.ru, f1news.ru +divxstage.eu, divxstage.eu +itusozluk.corn, itusozluk.com +hicdrna.corn, hicdma.com +dota2lounge.corn, dota2lounge.com +greensrnut.corn, greensmut.com +bharatiyarnobile.corn, bharatiyamobile.com +handycafe.corn, handycafe.com +regarder-filrn-gratuit.corn, regarder-film-gratuit.com +adultgeek.net, adultgeek.net +yintai.corn, yintai.com +brasilescola.corn, brasilescola.com +verisign.corn, verisign.com +dnslink.corn, dnslink.com +standaard.be, standaard.be +cbengine.corn, cbengine.com +pchealthboost.corn, pchealthboost.com +dealdey.corn, dealdey.com +cnnturk.corn, cnnturk.com +trutv.corn, trutv.com +tahrirnews.corn, tahrirnews.com +getit.in, getit.in +jqueryrnobile.corn, jquerymobile.com +girlgarnes.corn, girlgames.com +alhayat.corn, alhayat.com +ilpvideo.corn, ilpvideo.com +stihi.ru, stihi.ru +skyscanner.ru, skyscanner.ru +jarnejarnonline.ir, jamejamonline.ir +t3n.de, t3n.de +rent.corn, rent.com +telerik.corn, telerik.com +tandfonline.corn, tandfonline.com +argonas.corn, argonas.com +ludokado.corn, ludokado.com +luvgag.corn, luvgag.com +rnyspongebob.ru, myspongebob.ru +z5x.net, z5x.net +allhyiprnon.ru, allhyipmon.ru +fanswong.corn, fanswong.com +oddee.corn, oddee.com +guoli.corn, guoli.com +wpzoorn.corn, wpzoom.com +2gheroon.corn, 2gheroon.com +artisteer.corn, artisteer.com +share-links.biz, share-links.biz +flightstats.corn, flightstats.com +wisegeek.org, wisegeek.org +shuangtv.net, shuangtv.net +rnylikes.corn, mylikes.com +OzzO.corn, 0zz0.com +xiu.corn, xiu.com +pornizle69.corn, pornizle69.com +sendgrid.corn, sendgrid.com +theweek.corn, theweek.com +veetle.corn, veetle.com +theanirnalrescuesite.corn, theanimalrescuesite.com +sears.ca, sears.ca +tianpin.corn, tianpin.com +thisdaylive.corn, thisdaylive.com +rnyfunlife.corn, myfunlife.com +furaffinity.net, furaffinity.net +politiken.dk, politiken.dk +youwatch.org, youwatch.org +lesoir.be, lesoir.be +toyokeizai.net, toyokeizai.net +centos.org, centos.org +sunnyplayer.corn, sunnyplayer.com +knuddels.de, knuddels.de +rnturk.corn, mturk.com +egyrnodern.corn, egymodern.com +sernprot.corn, semprot.com +rnonsterhigh.corn, monsterhigh.com +kornpass.corn, kompass.com +olx.corn.ve, olx.com.ve +hq-xnxx.corn, hq-xnxx.com +whorush.corn, whorush.com +bongdaso.corn, bongdaso.com +centrelink.gov.au, centrelink.gov.au +folha.corn.br, folha.com.br +getjetso.corn, getjetso.com +ycornbinator.corn, ycombinator.com +chouti.corn, chouti.com +33lc.corn, 33lc.com +hostgator.corn.br, hostgator.com.br +ernirates247.corn, emirates247.com +itpub.net, itpub.net +fsyrnbols.corn, fsymbols.com +bestproducttesters.corn, bestproducttesters.com +daodao.corn, daodao.com +virtuernart.net, virtuemart.net +hindilinks4u.net, hindilinks4u.net +nnrn.rne, nnm.me +xplocial.corn, xplocial.com +apartrnents.corn, apartments.com +ekolay.net, ekolay.net +doviz.corn, doviz.com +flixya.corn, flixya.com +3alrnthqafa.corn, 3almthqafa.com +zarnalekfans.corn, zamalekfans.com +irneigu.corn, imeigu.com +wikibit.net, wikibit.net +windstrearn.net, windstream.net +rnatichon.co.th, matichon.co.th +appshopper.corn, appshopper.com +socialbakers.corn, socialbakers.com +lpopov.ru, 1popov.ru +blikk.hu, blikk.hu +bdrl3O.net, bdr130.net +arizona.edu, arizona.edu +rnadhyarnarn.corn, madhyamam.com +rnweb.co.za, mweb.co.za +affiliates.de, affiliates.de +ebs.in, ebs.in +bestgfx.corn, bestgfx.com +share-garnes.corn, share-games.com +inforrnador.corn.rnx, informador.com.mx +jobsite.co.uk, jobsite.co.uk +carters.corn, carters.com +kinghost.net, kinghost.net +usl.corn, us1.com +archives.corn, archives.com +forosdelweb.corn, forosdelweb.com +siteslike.corn, siteslike.com +thedailyshow.corn, thedailyshow.com +68design.net, 68design.net +irntalk.org, imtalk.org +visualwebsiteoptirnizer.corn, visualwebsiteoptimizer.com +glarysoft.corn, glarysoft.com +xhby.net, xhby.net +ernail.cz, email.cz +arnateurs-gone-wild.corn, amateurs-gone-wild.com +davidwalsh.narne, davidwalsh.name +finalfantasyxiv.corn, finalfantasyxiv.com +aa.corn.tr, aa.com.tr +legalzoorn.corn, legalzoom.com +lifehack.org, lifehack.org +rnca.gov.in, mca.gov.in +hidrvids.corn, hidrvids.com +key.corn, key.com +thurnbtack.corn, thumbtack.com +nujij.nl, nujij.nl +cinetux.org, cinetux.org +hrnetro.corn.rny, hmetro.com.my +ignou.ac.in, ignou.ac.in +affilorarna.corn, affilorama.com +pokernon.corn, pokemon.com +sportsnewsinternational.corn, sportsnewsinternational.com +geek.corn, geek.com +larepublica.pe, larepublica.pe +europacasino.corn, europacasino.com +ok-porn.corn, ok-porn.com +tutorialzine.corn, tutorialzine.com +google.corn.bn, google.com.bn +site5.corn, site5.com +trafficjunky.net, trafficjunky.net +xueqiu.corn, xueqiu.com +yournewscorner.corn, yournewscorner.com +rnetrotvnews.corn, metrotvnews.com +nichegalz.corn, nichegalz.com +job.corn, job.com +koirnoi.corn, koimoi.com +questionablecontent.net, questionablecontent.net +volaris.rnx, volaris.mx +rakuten.de, rakuten.de +cyworld.corn, cyworld.com +yudu.corn, yudu.com +zakon.kz, zakon.kz +rnsi.corn, msi.com +darkxxxtube.corn, darkxxxtube.com +sarnakal.net, samakal.net +appstorrn.net, appstorm.net +vulture.corn, vulture.com +racingpost.corn, racingpost.com +classicrurnrny.corn, classicrummy.com +iegallery.corn, iegallery.com +cinernagia.ro, cinemagia.ro +nullpoantenna.corn, nullpoantenna.com +ihned.cz, ihned.cz +vdolady.corn, vdolady.com +babes.corn, babes.com +kornli.corn, komli.com +asianbeauties.corn, asianbeauties.com +onedate.corn, onedate.com +adhitz.corn, adhitz.com +jjgirls.corn, jjgirls.com +dot.tk, dot.tk +autobild.de, autobild.de +jobs-to-careers.corn, jobs-to-careers.com +rnovietickets.corn, movietickets.com +net4.in, net4.in +crutchfield.corn, crutchfield.com +subdivx.corn, subdivx.com +sirarcade.corn, sirarcade.com +sitescoutadserver.corn, sitescoutadserver.com +fantasy-rivals.corn, fantasy-rivals.com +chegg.corn, chegg.com +sportsrnansguide.corn, sportsmansguide.com +extrernetech.corn, extremetech.com +loft.corn, loft.com +dirtyarnateurtube.corn, dirtyamateurtube.com +socialsex.biz, socialsex.biz +opensubtitles.us, opensubtitles.us +infornoney.corn.br, infomoney.com.br +openstat.ru, openstat.ru +adlandpro.corn, adlandpro.com +trivago.de, trivago.de +feiren.corn, feiren.com +lespac.corn, lespac.com +iceporn.corn, iceporn.com +anirnehere.corn, animehere.com +klix.ba, klix.ba +elitepvpers.corn, elitepvpers.com +rnrconservative.corn, mrconservative.com +tarnu.edu, tamu.edu +startv.corn.tr, startv.com.tr +haberl9O3.corn, haber1903.com +apa.tv, apa.tv +idbi.corn, idbi.com +golfchannel.corn, golfchannel.com +pep.ph, pep.ph +toukoucity.to, toukoucity.to +ernpirernoney.corn, empiremoney.com +androidauthority.corn, androidauthority.com +ref4bux.corn, ref4bux.com +digitaljournal.corn, digitaljournal.com +sporcle.corn, sporcle.com +bzwbk.pl, bzwbk.pl +lalarnao.corn, lalamao.com +ziare.corn, ziare.com +cliti.corn, cliti.com +thatguywiththeglasses.corn, thatguywiththeglasses.com +vodu.ch, vodu.ch +ycwb.corn, ycwb.com +bls.gov, bls.gov +ltubenews.corn, 1tubenews.com +cl.ly, cl.ly +ing.be, ing.be +bitterstrawberry.corn, bitterstrawberry.com +fubar.corn, fubar.com +arabic-keyboard.org, arabic-keyboard.org +rnejortorrent.corn, mejortorrent.com +trendrnicro.corn, trendmicro.com +ap7arn.corn, ap7am.com +windowsazure.corn, windowsazure.com +q8yat.corn, q8yat.com +yyv.co, yyv.co +tvoy-start.corn, tvoy-start.com +creativetoolbars.corn, creativetoolbars.com +forrent.corn, forrent.com +rnlstatic.corn, mlstatic.com +like4like.org, like4like.org +alpha.gr, alpha.gr +arnkey.net, amkey.net +iwiw.hu, iwiw.hu +routard.corn, routard.com +teacherspayteachers.corn, teacherspayteachers.com +ahashare.corn, ahashare.com +ultoo.corn, ultoo.com +oakley.corn, oakley.com +upforit.corn, upforit.com +trafficbee.corn, trafficbee.com +rnonster.co.uk, monster.co.uk +boulanger.fr, boulanger.fr +bloglines.corn, bloglines.com +wdc.corn, wdc.com +el-nacional.corn, el-nacional.com +bloggertipstricks.corn, bloggertipstricks.com +oreillyauto.corn, oreillyauto.com +hotpads.corn, hotpads.com +tubexvideo.corn, tubexvideo.com +rnudainodocurnent.corn, mudainodocument.com +discoverpedia.info, discoverpedia.info +noobteens.corn, noobteens.com +shockrnansion.corn, shockmansion.com +qudsonline.ir, qudsonline.ir +rnec.es, mec.es +vt.edu, vt.edu +akelite.corn, akelite.com +travelandleisure.corn, travelandleisure.com +sunnewsonline.corn, sunnewsonline.com +tok2.corn, tok2.com +truste.org, truste.org +2dehands.be, 2dehands.be +hf365.corn, hf365.com +westelrn.corn, westelm.com +real.gr, real.gr +downloadrning.rne, downloadming.me +citrornail.hu, citromail.hu +fotocornrnunity.de, fotocommunity.de +zapjuegos.corn, zapjuegos.com +aastocks.corn, aastocks.com +unb.br, unb.br +adchakra.net, adchakra.net +check24.de, check24.de +vidto.rne, vidto.me +peekyou.corn, peekyou.com +urssaf.fr, urssaf.fr +alixixi.corn, alixixi.com +winarnp.corn, winamp.com +xianguo.corn, xianguo.com +indiasextube.net, indiasextube.net +fitnea.corn, fitnea.com +telernundo.corn, telemundo.com +webnode.cz, webnode.cz +kliksaya.corn, kliksaya.com +wikileaks.org, wikileaks.org +rnyblog.it, myblog.it +99wed.corn, 99wed.com +adorika.corn, adorika.com +siliconrus.corn, siliconrus.com +dealrnoon.corn, dealmoon.com +ricanadfunds.corn, ricanadfunds.com +vietcornbank.corn.vn, vietcombank.com.vn +chernistry.corn, chemistry.com +reisen.de, reisen.de +torlock.corn, torlock.com +wsop.corn, wsop.com +travian.co.id, travian.co.id +ipoll.corn, ipoll.com +bpiexpressonline.corn, bpiexpressonline.com +neeu.corn, neeu.com +beyondtherack.corn, beyondtherack.com +blueidea.corn, blueidea.com +tedata.net, tedata.net +garnesradar.corn, gamesradar.com +big.az, big.az +h-douga.net, h-douga.net +runnersworld.corn, runnersworld.com +lurnfile.corn, lumfile.com +ul7.corn, u17.com +badjojo.corn, badjojo.com +nginx.org, nginx.org +filrnfanatic.corn, filmfanatic.com +filrney.corn, filmey.com +rnousebreaker.corn, mousebreaker.com +rnihanstore.net, mihanstore.net +sharebuilder.corn, sharebuilder.com +cnhan.corn, cnhan.com +partnerwithtorn.corn, partnerwithtom.com +synonyrn.corn, synonym.com +areaconnect.corn, areaconnect.com +one.lt, one.lt +rnp3quran.net, mp3quran.net +anz.co.nz, anz.co.nz +buyincoins.corn, buyincoins.com +surfline.corn, surfline.com +packtpub.corn, packtpub.com +inforrne2l.corn, informe21.com +d4OOO.corn, d4000.com +blog.cz, blog.cz +rnyredbook.corn, myredbook.com +seslisozluk.net, seslisozluk.net +sirnple2advertise.corn, simple2advertise.com +bookit.corn, bookit.com +eranico.corn, eranico.com +pakwheels.corn, pakwheels.com +x-rates.corn, x-rates.com +ilrnatieteenlaitos.fi, ilmatieteenlaitos.fi +vozforurns.corn, vozforums.com +galerieslafayette.corn, galerieslafayette.com +trafficswirl.corn, trafficswirl.com +rnql4.corn, mql4.com +torontosun.corn, torontosun.com +lebuteur.corn, lebuteur.com +cruisecritic.corn, cruisecritic.com +rateyourrnusic.corn, rateyourmusic.com +binsearch.info, binsearch.info +nrj.fr, nrj.fr +rnegaflix.net, megaflix.net +dosug.cz, dosug.cz +stop55.corn, stop55.com +qqnz.corn, qqnz.com +ibuonline.corn, ibuonline.com +jobego.corn, jobego.com +euro.corn.pl, euro.com.pl +quran.corn, quran.com +adl.ru, ad1.ru +avaz.ba, avaz.ba +eloqua.corn, eloqua.com +educationconnection.corn, educationconnection.com +dbank.corn, dbank.com +whois.sc, whois.sc +yournob.corn, youmob.com +lOlgreatgoals.corn, 101greatgoals.com +livefyre.corn, livefyre.com +sextubebox.corn, sextubebox.com +shooshtirne.corn, shooshtime.com +tapuz.co.il, tapuz.co.il +auchan.fr, auchan.fr +pinkvilla.corn, pinkvilla.com +perspolisnews.corn, perspolisnews.com +scholastic.corn, scholastic.com +google.rnu, google.mu +forex4you.org, forex4you.org +rnandtbank.corn, mandtbank.com +gnezdo.ru, gnezdo.ru +lulu.corn, lulu.com +anniezhang.corn, anniezhang.com +bharian.corn.rny, bharian.com.my +cornprafacil.corn.br, comprafacil.com.br +rnrnafighting.corn, mmafighting.com +autotrader.ca, autotrader.ca +vectorstock.corn, vectorstock.com +convio.corn, convio.com +ktunnel.corn, ktunnel.com +hbs.edu, hbs.edu +rnindspark.corn, mindspark.com +trovit.corn.rnx, trovit.com.mx +thornsonreuters.corn, thomsonreuters.com +yupptv.corn, yupptv.com +fullsail.edu, fullsail.edu +perfectworld.eu, perfectworld.eu +ju5l.corn, ju51.com +newssnip.corn, newssnip.com +livernocha.corn, livemocha.com +nespresso.corn, nespresso.com +uinvest.corn.ua, uinvest.com.ua +yazete.corn, yazete.com +rnalaysiaairlines.corn, malaysiaairlines.com +clikseguro.corn, clikseguro.com +rnarksdailyapple.corn, marksdailyapple.com +topnewsquick.corn, topnewsquick.com +ikyu.corn, ikyu.com +rnydocorno.corn, mydocomo.com +tarnpabay.corn, tampabay.com +rno.gov, mo.gov +oxfordjournals.org, oxfordjournals.org +rnanageyourloans.corn, manageyourloans.com +couponcabin.corn, couponcabin.com +rnrrnlsrnatrix.corn, mrmlsmatrix.com +knowd.corn, knowd.com +ladbrokes.corn, ladbrokes.com +ikoo.corn, ikoo.com +devhub.corn, devhub.com +dropjack.corn, dropjack.com +sadistic.pl, sadistic.pl +8cornic.corn, 8comic.com +optirnizepress.corn, optimizepress.com +ofweek.corn, ofweek.com +donya-e-eqtesad.corn, donya-e-eqtesad.com +arabarn.corn, arabam.com +playtv.fr, playtv.fr +yourtv.corn.au, yourtv.com.au +tearntalk.corn, teamtalk.com +createsend.corn, createsend.com +bitcointalk.org, bitcointalk.org +rnicrocenter.corn, microcenter.com +arcadeprehacks.corn, arcadeprehacks.com +sublirnetext.corn, sublimetext.com +posindonesia.co.id, posindonesia.co.id +payrnaster.ru, paymaster.ru +ncore.cc, ncore.cc +wikisource.org, wikisource.org +notebooksbilliger.de, notebooksbilliger.de +nayakhabar.corn, nayakhabar.com +tirn.corn.br, tim.com.br +leggo.it, leggo.it +swoodoo.corn, swoodoo.com +perfectgirls.es, perfectgirls.es +beautystyleliving.corn, beautystyleliving.com +xrnaduras.corn, xmaduras.com +e-shop.gr, e-shop.gr +belastingdienst.nl, belastingdienst.nl +urbia.de, urbia.de +lovoo.net, lovoo.net +citizensbank.corn, citizensbank.com +gulesider.no, gulesider.no +zhongsou.net, zhongsou.net +cinernablend.corn, cinemablend.com +joydownload.corn, joydownload.com +telkorn.co.id, telkom.co.id +nangaspace.corn, nangaspace.com +panerabread.corn, panerabread.com +cinechest.corn, cinechest.com +flixjunky.corn, flixjunky.com +berlinl.de, berlin1.de +tabonito.pt, tabonito.pt +snob.ru, snob.ru +audiovkontakte.ru, audiovkontakte.ru +linuxrnint.corn, linuxmint.com +freshdesk.corn, freshdesk.com +professionali.ru, professionali.ru +prirnelocation.corn, primelocation.com +fernina.hu, femina.hu +jecontacte.corn, jecontacte.com +celebritytoob.corn, celebritytoob.com +strearniz-filrnze.corn, streamiz-filmze.com +l-tike.corn, l-tike.com +collegeconfidential.corn, collegeconfidential.com +hafiz.gov.sa, hafiz.gov.sa +rnega-porno.ru, mega-porno.ru +ivoox.corn, ivoox.com +lrngtfy.corn, lmgtfy.com +pclab.pl, pclab.pl +preisvergleich.de, preisvergleich.de +weeb.tv, weeb.tv +tnews.ir, tnews.ir +wwtdd.corn, wwtdd.com +totalfilrn.corn, totalfilm.com +girlfriendvideos.corn, girlfriendvideos.com +wgt.corn, wgt.com +iu.edu, iu.edu +topictorch.corn, topictorch.com +wenweipo.corn, wenweipo.com +duitang.corn, duitang.com +rnadrid.org, madrid.org +retrogarner.corn, retrogamer.com +pantheranetwork.corn, pantheranetwork.com +sorneecards.corn, someecards.com +visafone.corn.ng, visafone.com.ng +infopraca.pl, infopraca.pl +nrelate.corn, nrelate.com +sia.az, sia.az +wallbase.cc, wallbase.cc +shareflare.net, shareflare.net +sarnrnydress.corn, sammydress.com +goldesel.to, goldesel.to +thefiscaltirnes.corn, thefiscaltimes.com +freelogoservices.corn, freelogoservices.com +dealigg.corn, dealigg.com +babypips.corn, babypips.com +diynetwork.corn, diynetwork.com +porn99.net, porn99.net +skynewsarabia.corn, skynewsarabia.com +eweb4.corn, eweb4.com +fedoraproject.org, fedoraproject.org +nolo.corn, nolo.com +rnegabus.corn, megabus.com +fao.org, fao.org +arn.ru, am.ru +sportowefakty.pl, sportowefakty.pl +kidstaff.corn.ua, kidstaff.com.ua +jhu.edu, jhu.edu +which.co.uk, which.co.uk +sextubehd.xxx, sextubehd.xxx +swansonvitarnins.corn, swansonvitamins.com +iran-eng.corn, iran-eng.com +fakenarnegenerator.corn, fakenamegenerator.com +gosong.net, gosong.net +24open.ru, 24open.ru +l23sdfsdfsdfsd.ru, 123sdfsdfsdfsd.ru +gotgayporn.corn, gotgayporn.com +casadellibro.corn, casadellibro.com +ixwebhosting.corn, ixwebhosting.com +buyorbury.corn, buyorbury.com +getglue.corn, getglue.com +86432l.corn, 864321.com +alivv.corn, alivv.com +cornpetitor.corn, competitor.com +iheirna.corn, iheima.com +subrnarinoviagens.corn.br, submarinoviagens.com.br +ernailsrvr.corn, emailsrvr.com +udacity.corn, udacity.com +rncafeesecure.corn, mcafeesecure.com +laposte.fr, laposte.fr +ppy.sh, ppy.sh +rurnah.corn, rumah.com +pullbear.corn, pullbear.com +pkt.pl, pkt.pl +jayde.corn, jayde.com +rnyjoyonline.corn, myjoyonline.com +locopengu.corn, locopengu.com +vsnl.net.in, vsnl.net.in +hornbunny.corn, hornbunny.com +royalcaribbean.corn, royalcaribbean.com +football.ua, football.ua +thaifriendly.corn, thaifriendly.com +bankofthewest.corn, bankofthewest.com +indianprice.corn, indianprice.com +chodientu.vn, chodientu.vn +alison.corn, alison.com +eveonline.corn, eveonline.com +blogg.se, blogg.se +jetairways.corn, jetairways.com +larousse.fr, larousse.fr +noticierodigital.corn, noticierodigital.com +rnkfst.corn, mkfst.com +anyfiledownloader.corn, anyfiledownloader.com +tirarnillas.net, tiramillas.net +telus.corn, telus.com +paperblog.corn, paperblog.com +songsterr.corn, songsterr.com +entrernujeres.corn, entremujeres.com +startsiden.no, startsiden.no +hotspotshield.corn, hotspotshield.com +hosteurope.de, hosteurope.de +ebags.corn, ebags.com +eenadupratibha.net, eenadupratibha.net +uppit.corn, uppit.com +piaohua.corn, piaohua.com +xxxyrnovies.corn, xxxymovies.com +netbarg.corn, netbarg.com +chip.corn.tr, chip.com.tr +xl.co.id, xl.co.id +kowalskypage.corn, kowalskypage.com +afterdawn.corn, afterdawn.com +locanto.corn, locanto.com +liilas.corn, liilas.com +superboy.corn, superboy.com +indiavisiontv.corn, indiavisiontv.com +ixquick.corn, ixquick.com +hoteliurn.corn, hotelium.com +twsela.corn, twsela.com +newsrneback.corn, newsmeback.com +perfectliving.corn, perfectliving.com +laughingsquid.corn, laughingsquid.com +designboorn.corn, designboom.com +zigil.ir, zigil.ir +coachfactory.corn, coachfactory.com +kaboodle.corn, kaboodle.com +fastrnail.frn, fastmail.fm +threadless.corn, threadless.com +wiseconvert.corn, wiseconvert.com +br.de, br.de +prornovacances.corn, promovacances.com +wrzuta.pl, wrzuta.pl +frorndoctopdf.corn, fromdoctopdf.com +ono.es, ono.es +zinio.corn, zinio.com +netcoc.corn, netcoc.com +eanswers.corn, eanswers.com +wallst.corn, wallst.com +ipiccy.corn, ipiccy.com +fastweb.it, fastweb.it +kaufrnich.corn, kaufmich.com +groupon.co.za, groupon.co.za +cyzo.corn, cyzo.com +addic7ed.corn, addic7ed.com +alintibaha.net, alintibaha.net +indiewire.corn, indiewire.com +needforspeed.corn, needforspeed.com +e24.no, e24.no +hupso.corn, hupso.com +kathirnerini.gr, kathimerini.gr +worldoffiles.net, worldoffiles.net +express.pk, express.pk +wieszjak.pl, wieszjak.pl +rnobile.bg, mobile.bg +subway.corn, subway.com +akhbarelyorn.corn, akhbarelyom.com +thisoldhouse.corn, thisoldhouse.com +autoevolution.corn, autoevolution.com +public-api.wordpress.corn, public-api.wordpress.com +airarabia.corn, airarabia.com +powerball.corn, powerball.com +visa.corn, visa.com +gendai.net, gendai.net +gyrnboree.corn, gymboree.com +tvp.pl, tvp.pl +sinhayasocialreader.corn, sinhayasocialreader.com +a963.corn, a963.com +garngos.ae, gamgos.ae +fx678.corn, fx678.com +rnp3round.corn, mp3round.com +kornonews.corn, komonews.com +contactcars.corn, contactcars.com +pdftoword.corn, pdftoword.com +songtaste.corn, songtaste.com +squareup.corn, squareup.com +newsevent24.corn, newsevent24.com +livestation.corn, livestation.com +oldertube.corn, oldertube.com +rtl.fr, rtl.fr +gather.corn, gather.com +liderendeportes.corn, liderendeportes.com +thewrap.corn, thewrap.com +viber.corn, viber.com +reklarna5.rnk, reklama5.mk +fonts.corn, fonts.com +hrsaccount.corn, hrsaccount.com +bizcornrnunity.corn, bizcommunity.com +favicon.cc, favicon.cc +totalping.corn, totalping.com +live365.corn, live365.com +tlife.gr, tlife.gr +irnasters.corn.br, imasters.com.br +nll.corn, n11.com +iarn.rna, iam.ma +qq5.corn, qq5.com +tvboxnow.corn, tvboxnow.com +lirnetorrents.corn, limetorrents.com +bancopopular.es, bancopopular.es +ray-ban.corn, ray-ban.com +drweb.corn, drweb.com +hushrnail.corn, hushmail.com +resuelvetudeuda.corn, resuelvetudeuda.com +sharpnews.ru, sharpnews.ru +hellocoton.fr, hellocoton.fr +buysub.corn, buysub.com +hornernoviestube.corn, homemoviestube.com +utsandiego.corn, utsandiego.com +learn4good.corn, learn4good.com +girlsgogarnes.ru, girlsgogames.ru +talksport.co.uk, talksport.co.uk +fap.to, fap.to +teennick.corn, teennick.com +seitwert.de, seitwert.de +celebrityrnoviearchive.corn, celebritymoviearchive.com +sukar.corn, sukar.com +astrorneridian.ru, astromeridian.ru +zen-cart.corn, zen-cart.com +lphads.corn, 1phads.com +plaisio.gr, plaisio.gr +cplusplus.corn, cplusplus.com +ewebse.corn, ewebse.com +6eat.corn, 6eat.com +payless.corn, payless.com +subaonet.corn, subaonet.com +dlisted.corn, dlisted.com +kia.corn, kia.com +lankahotnews.net, lankahotnews.net +vg247.corn, vg247.com +forrnstack.corn, formstack.com +jobs.net, jobs.net +coolchaser.corn, coolchaser.com +blackplanet.corn, blackplanet.com +unionbank.corn, unionbank.com +record.corn.rnx, record.com.mx +l2lware.corn, 121ware.com +inkfrog.corn, inkfrog.com +cnstock.corn, cnstock.com +rnarineaquariurnfree.corn, marineaquariumfree.com +encuentra24.corn, encuentra24.com +rnixturecloud.corn, mixturecloud.com +yninfo.corn, yninfo.com +lesnurneriques.corn, lesnumeriques.com +autopartswarehouse.corn, autopartswarehouse.com +lijit.corn, lijit.com +ti.corn, ti.com +urnd.edu, umd.edu +zdnet.co.uk, zdnet.co.uk +begin-download.corn, begin-download.com +showsiteinfo.us, showsiteinfo.us +uchicago.edu, uchicago.edu +whatsrnyserp.corn, whatsmyserp.com +asos.fr, asos.fr +ibosocial.corn, ibosocial.com +arnorenlinea.corn, amorenlinea.com +videoprerniurn.tv, videopremium.tv +trkjrnp.corn, trkjmp.com +creativecow.net, creativecow.net +webartex.ru, webartex.ru +olx.corn.ng, olx.com.ng +overclockzone.corn, overclockzone.com +rongbay.corn, rongbay.com +rnaxirnustube.corn, maximustube.com +priberarn.pt, priberam.pt +cornsenz.corn, comsenz.com +prensaescrita.corn, prensaescrita.com +garneslist.corn, gameslist.com +lingualeo.corn, lingualeo.com +epfoservices.in, epfoservices.in +webbirga.net, webbirga.net +pb.corn, pb.com +fineco.it, fineco.it +highrisehq.corn, highrisehq.com +hotgoo.corn, hotgoo.com +netdoctor.co.uk, netdoctor.co.uk +dornain.corn, domain.com +ararnex.corn, aramex.com +google.co.uz, google.co.uz +savings.corn, savings.com +airtelbroadband.in, airtelbroadband.in +postirnees.ee, postimees.ee +wallsave.corn, wallsave.com +df.gob.rnx, df.gob.mx +flashgarnes247.corn, flashgames247.com +libsyn.corn, libsyn.com +goobike.corn, goobike.com +trivago.corn, trivago.com +android-hilfe.de, android-hilfe.de +anquan.org, anquan.org +dota2.corn, dota2.com +vladtv.corn, vladtv.com +oovoo.corn, oovoo.com +rnybrowsercash.corn, mybrowsercash.com +stafaband.info, stafaband.info +vsao.vn, vsao.vn +srnithsonianrnag.corn, smithsonianmag.com +feedblitz.corn, feedblitz.com +kibeloco.corn.br, kibeloco.com.br +burningcarnel.corn, burningcamel.com +northwestern.edu, northwestern.edu +tucows.corn, tucows.com +porn-granny-tube.corn, porn-granny-tube.com +linksys.corn, linksys.com +avea.corn.tr, avea.com.tr +arns.se, ams.se +canadanepalvid.corn, canadanepalvid.com +venrnobulo.corn, venmobulo.com +levi.corn, levi.com +freshorne.corn, freshome.com +loja2.corn.br, loja2.com.br +garneduell.de, gameduell.de +reservearnerica.corn, reserveamerica.com +fakings.corn, fakings.com +polygon.corn, polygon.com +news.rnn, news.mn +addictinginfo.org, addictinginfo.org +bonanza.corn, bonanza.com +adlock.in, adlock.in +apni.tv, apni.tv +3rn.corn, 3m.com +usingenglish.corn, usingenglish.com +sarnrnsoft.corn, sammsoft.com +thevault.bz, thevault.bz +groupon.rny, groupon.my +banarnex.corn, banamex.com +hualongxiang.corn, hualongxiang.com +bodis.corn, bodis.com +io.ua, io.ua +rninglebox.corn, minglebox.com +forurnspecialoffers.corn, forumspecialoffers.com +rernax.corn, remax.com +rnakaan.corn, makaan.com +voglioporno.corn, voglioporno.com +chinaluxus.corn, chinaluxus.com +parenting.corn, parenting.com +superdownloads.corn.br, superdownloads.com.br +nettavisen.no, nettavisen.no +2lcbh.corn, 21cbh.com +rnobilestan.net, mobilestan.net +cheathappens.corn, cheathappens.com +azxeber.corn, azxeber.com +foodgawker.corn, foodgawker.com +eb8O.corn, eb80.com +dudarnobile.corn, dudamobile.com +sahafah.net, sahafah.net +ait-thernes.corn, ait-themes.com +house.gov, house.gov +ffffound.corn, ffffound.com +khanwars.ir, khanwars.ir +wowslider.corn, wowslider.com +fashionara.corn, fashionara.com +pornxxxhub.corn, pornxxxhub.com +rninhavida.corn.br, minhavida.com.br +senzapudore.it, senzapudore.it +extra.cz, extra.cz +cinernark.corn, cinemark.com +career.ru, career.ru +realself.corn, realself.com +i4455.corn, i4455.com +ntlworld.corn, ntlworld.com +chinaw3.corn, chinaw3.com +berliner-sparkasse.de, berliner-sparkasse.de +autoscout24.be, autoscout24.be +heureka.sk, heureka.sk +tienphong.vn, tienphong.vn +lOOlfreefonts.corn, 1001freefonts.com +bluestacks.corn, bluestacks.com +livesports.pl, livesports.pl +bd-pratidin.corn, bd-pratidin.com +es.tl, es.tl +backcountry.corn, backcountry.com +fourhourworkweek.corn, fourhourworkweek.com +pointclicktrack.corn, pointclicktrack.com +joornlacode.org, joomlacode.org +fantage.corn, fantage.com +seowizard.ru, seowizard.ru +rnilitary38.corn, military38.com +swedbank.lt, swedbank.lt +govoyages.corn, govoyages.com +fgov.be, fgov.be +dengeki.corn, dengeki.com +ed4.net, ed4.net +rnql5.corn, mql5.com +gottabernobile.corn, gottabemobile.com +kdslife.corn, kdslife.com +5yi.corn, 5yi.com +bforex.corn, bforex.com +eurogarner.net, eurogamer.net +az.pl, az.pl +partypoker.corn, partypoker.com +cinapalace.corn, cinapalace.com +sbt.corn.br, sbt.com.br +weatherzone.corn.au, weatherzone.com.au +cutv.corn, cutv.com +sweetwater.corn, sweetwater.com +vodacorn.co.za, vodacom.co.za +hostgator.in, hostgator.in +rnojirn.corn, mojim.com +eklablog.corn, eklablog.com +divaina.corn, divaina.com +acces-charrne.corn, acces-charme.com +airfrance.fr, airfrance.fr +widgeo.net, widgeo.net +whosdatedwho.corn, whosdatedwho.com +funtrivia.corn, funtrivia.com +servis24.cz, servis24.cz +ernagister.corn, emagister.com +torrentkitty.corn, torrentkitty.com +abc.corn.py, abc.com.py +farfetch.corn, farfetch.com +garnestar.de, gamestar.de +careers24.corn, careers24.com +styleblazer.corn, styleblazer.com +ibtesarna.corn, ibtesama.com +ifunny.rnobi, ifunny.mobi +antpedia.corn, antpedia.com +fivb.org, fivb.org +littleone.ru, littleone.ru +rainbowdressup.corn, rainbowdressup.com +zerozero.pt, zerozero.pt +edrearns.corn, edreams.com +whoishostingthis.corn, whoishostingthis.com +gucci.corn, gucci.com +anirneplus.tv, animeplus.tv +five.tv, five.tv +vacationstogo.corn, vacationstogo.com +dikaiologitika.gr, dikaiologitika.gr +rnrnorpg.corn, mmorpg.com +jcwhitney.corn, jcwhitney.com +russiandatingbeauties.corn, russiandatingbeauties.com +xrstats.corn, xrstats.com +grn99.corn, gm99.com +rnegashares.corn, megashares.com +oscaro.corn, oscaro.com +yezizhu.corn, yezizhu.com +get2ch.net, get2ch.net +cheaperthandirt.corn, cheaperthandirt.com +telcel.corn, telcel.com +thernefuse.corn, themefuse.com +addictivetips.corn, addictivetips.com +designshack.net, designshack.net +eurobank.gr, eurobank.gr +nexon.net, nexon.net +fulltiltpoker.eu, fulltiltpoker.eu +pirnei.corn, pimei.com +photoshop.corn, photoshop.com +dornainnarnesales.corn, domainnamesales.com +sky.frn, sky.fm +yasni.de, yasni.de +travian.ru, travian.ru +stickpage.corn, stickpage.com +joornla-rnaster.org, joomla-master.org +sarkari-naukri.in, sarkari-naukri.in +iphones.ru, iphones.ru +foto.ru, foto.ru +srnude.edu.in, smude.edu.in +gotharnist.corn, gothamist.com +teslarnotors.corn, teslamotors.com +seobudget.ru, seobudget.ru +tiantian.corn, tiantian.com +videohelp.corn, videohelp.com +textbroker.corn, textbroker.com +garena.corn, garena.com +patient.co.uk, patient.co.uk +2Orninutepayday.corn, 20minutepayday.com +bgarnes.corn, bgames.com +superherohype.corn, superherohype.com +sephora.corn.br, sephora.com.br +interest.rne, interest.me +inhabitat.corn, inhabitat.com +downloads.nl, downloads.nl +rusnovosti.ru, rusnovosti.ru +rnr-guangdong.corn, mr-guangdong.com +greyhound.corn, greyhound.com +okpay.corn, okpay.com +arnateurcornrnunity.corn, amateurcommunity.com +jeunesseglobal.corn, jeunesseglobal.com +nigrna.ru, nigma.ru +brightcove.corn, brightcove.com +safesearch.net, safesearch.net +teluguone.corn, teluguone.com +custojusto.pt, custojusto.pt +telebank.ru, telebank.ru +kuwait.tt, kuwait.tt +acs.org, acs.org +sverigesradio.se, sverigesradio.se +rnps.it, mps.it +utanbaby.corn, utanbaby.com +junocloud.rne, junocloud.me +expedia.co.in, expedia.co.in +rosnet.ru, rosnet.ru +kanoon.ir, kanoon.ir +website.ws, website.ws +bagittoday.corn, bagittoday.com +gooya.corn, gooya.com +travelchannel.corn, travelchannel.com +flix247.corn, flix247.com +rnornsbangteens.corn, momsbangteens.com +photofacefun.corn, photofacefun.com +vistaprint.fr, vistaprint.fr +vidbux.corn, vidbux.com +edu.ro, edu.ro +hd-xvideos.corn, hd-xvideos.com +woodworking4horne.corn, woodworking4home.com +reforrnal.ru, reformal.ru +rnorodora.corn, morodora.com +gelbooru.corn, gelbooru.com +porntalk.corn, porntalk.com +assurland.corn, assurland.com +arnalgarna-lab.corn, amalgama-lab.com +9to5rnac.corn, 9to5mac.com +linux.org.ru, linux.org.ru +dolartoday.corn, dolartoday.com +therne-junkie.corn, theme-junkie.com +seolib.ru, seolib.ru +unesco.org, unesco.org +porncontrol.corn, porncontrol.com +topdocurnentaryfilrns.corn, topdocumentaryfilms.com +tvrnovie.de, tvmovie.de +adsl.free.fr, adsl.free.fr +sprinthost.ru, sprinthost.ru +reason.corn, reason.com +rnorazzia.corn, morazzia.com +yellowrnoxie.corn, yellowmoxie.com +banggood.corn, banggood.com +espn.corn.br, espn.com.br +rnernedad.corn, memedad.com +lovebuddyhookup.corn, lovebuddyhookup.com +scrnp.corn, scmp.com +kjendis.no, kjendis.no +rnetro-cc.ru, metro-cc.ru +disdus.corn, disdus.com +nola.corn, nola.com +tubesplash.corn, tubesplash.com +crx76Ol.corn, crx7601.com +iana.org, iana.org +howrse.corn, howrse.com +anirne-sharing.corn, anime-sharing.com +geny.corn, geny.com +carrefour.es, carrefour.es +kernalistgazete.net, kemalistgazete.net +freedirectory-list.corn, freedirectory-list.com +girlgarney.corn, girlgamey.com +blogbus.corn, blogbus.com +funlolx.corn, funlolx.com +zyue.corn, zyue.com +freepeople.corn, freepeople.com +tgareed.corn, tgareed.com +lifestreetrnedia.corn, lifestreetmedia.com +fybersearch.corn, fybersearch.com +livefreefun.org, livefreefun.org +cairodar.corn, cairodar.com +suitelOl.corn, suite101.com +elcinerna.corn, elcinema.com +leitingOOl.corn, leiting001.com +ifttt.corn, ifttt.com +google.corn.rnrn, google.com.mm +gizbot.corn, gizbot.com +garnes2win.corn, games2win.com +stiforp.corn, stiforp.com +nrc.nl, nrc.nl +slashgear.corn, slashgear.com +girlsgarnesl23.corn, girlsgames123.com +rnrnajunkie.corn, mmajunkie.com +cadenaser.corn, cadenaser.com +frornbar.corn, frombar.com +katrnirror.corn, katmirror.com +cnsnews.corn, cnsnews.com +duolingo.corn, duolingo.com +afterbuy.de, afterbuy.de +jpc.corn, jpc.com +publix.corn, publix.com +ehealthforurn.corn, ehealthforum.com +budget.corn, budget.com +iprna.pt, ipma.pt +rneetladies.rne, meetladies.me +adroll.corn, adroll.com +renxo.corn, renxo.com +ernpireonline.corn, empireonline.com +rnodareb.corn, modareb.com +toprnoviesdirect.corn, topmoviesdirect.com +rnforos.corn, mforos.com +pubarticles.corn, pubarticles.com +prirneshare.tv, primeshare.tv +flycell.corn.tr, flycell.com.tr +rapidvidz.corn, rapidvidz.com +kouclo.corn, kouclo.com +photography-on-the.net, photography-on-the.net +tsn.ua, tsn.ua +drearnarnateurs.corn, dreamamateurs.com +avenues.info, avenues.info +coolrnath.corn, coolmath.com +pegast.ru, pegast.ru +rnyplayyard.corn, myplayyard.com +rnyscore.ru, myscore.ru +theync.corn, theync.com +ducktoursoftarnpabay.corn, ducktoursoftampabay.com +rnarunadanrnalayali.corn, marunadanmalayali.com +tribune.corn.ng, tribune.com.ng +83suncity.corn, 83suncity.com +nissanusa.corn, nissanusa.com +radio.de, radio.de +diapers.corn, diapers.com +rnyherbalife.corn, myherbalife.com +flibusta.net, flibusta.net +daft.ie, daft.ie +buycheapr.corn, buycheapr.com +sportrnaster.ru, sportmaster.ru +wordhippo.corn, wordhippo.com +gva.es, gva.es +sport24.co.za, sport24.co.za +putariabrasileira.corn, putariabrasileira.com +suddenlink.net, suddenlink.net +bangbrosnetwork.corn, bangbrosnetwork.com +creaders.net, creaders.net +dailysteals.corn, dailysteals.com +karakartal.corn, karakartal.com +tv-series.rne, tv-series.me +bongdaplus.vn, bongdaplus.vn +one.co.il, one.co.il +giga.de, giga.de +contactrnusic.corn, contactmusic.com +inforrnationweek.corn, informationweek.com +iqbank.ru, iqbank.ru +duapp.corn, duapp.com +cgd.pt, cgd.pt +yepporn.corn, yepporn.com +sharekhan.corn, sharekhan.com +365online.corn, 365online.com +thedailyrneal.corn, thedailymeal.com +ag.ru, ag.ru +claro.corn.ar, claro.com.ar +rnediaworld.it, mediaworld.it +bestgore.corn, bestgore.com +rnohajerist.corn, mohajerist.com +passion-hd.corn, passion-hd.com +srnallbiztrends.corn, smallbiztrends.com +vitals.corn, vitals.com +rocketlawyer.corn, rocketlawyer.com +vr-zone.corn, vr-zone.com +doridro.corn, doridro.com +expedia.it, expedia.it +aflarn4you.tv, aflam4you.tv +wisconsin.gov, wisconsin.gov +chinavasion.corn, chinavasion.com +bigpara.corn, bigpara.com +hightrafficacaderny.corn, hightrafficacademy.com +novaposhta.ua, novaposhta.ua +pearl.de, pearl.de +boobpedia.corn, boobpedia.com +rnycrnapp.corn, mycmapp.com +89.corn, 89.com +foxsportsla.corn, foxsportsla.com +annauniv.edu, annauniv.edu +tri.co.id, tri.co.id +browsershots.org, browsershots.org +newindianexpress.corn, newindianexpress.com +washingtonexarniner.corn, washingtonexaminer.com +rnozillazine.org, mozillazine.org +rng.co.za, mg.co.za +newalburnreleases.net, newalbumreleases.net +trornbi.corn, trombi.com +pirnsleurapproach.corn, pimsleurapproach.com +decathlon.es, decathlon.es +shoprnania.ro, shopmania.ro +brokenlinkcheck.corn, brokenlinkcheck.com +forurneiros.corn, forumeiros.com +rnoreniche.corn, moreniche.com +falabella.corn, falabella.com +turner.corn, turner.com +reachlocal.net, reachlocal.net +upsc.gov.in, upsc.gov.in +allday2.corn, allday2.com +dtiserv.corn, dtiserv.com +singaporeair.corn, singaporeair.com +patoghu.corn, patoghu.com +intercarnbiosvirtuales.org, intercambiosvirtuales.org +bored.corn, bored.com +nn.ru, nn.ru +24srni.org, 24smi.org +rnobile-review.corn, mobile-review.com +rbs.co.uk, rbs.co.uk +westeros.org, westeros.org +dragonfable.corn, dragonfable.com +wg-gesucht.de, wg-gesucht.de +ebaypartnernetwork.corn, ebaypartnernetwork.com +srnartsheet.corn, smartsheet.com +filrnai.in, filmai.in +iranianuk.corn, iranianuk.com +zhulang.corn, zhulang.com +garne-garne.corn.ua, game-game.com.ua +jigzone.corn, jigzone.com +vidbull.corn, vidbull.com +trustpilot.corn, trustpilot.com +baodatviet.vn, baodatviet.vn +haaretz.corn, haaretz.com +careerbuilder.co.in, careerbuilder.co.in +veikkaus.fi, veikkaus.fi +potterybarnkids.corn, potterybarnkids.com +freegarnelot.corn, freegamelot.com +worldtirneserver.corn, worldtimeserver.com +jigsy.corn, jigsy.com +widgetbox.corn, widgetbox.com +lasexta.corn, lasexta.com +rnediav.corn, mediav.com +aintitcool.corn, aintitcool.com +youwillfind.info, youwillfind.info +bharatrnatrirnony.corn, bharatmatrimony.com +translated.net, translated.net +virginia.edu, virginia.edu +5566.net, 5566.net +questionrnarket.corn, questionmarket.com +587766.corn, 587766.com +newspickup.corn, newspickup.com +wornansday.corn, womansday.com +segodnya.ua, segodnya.ua +reagancoalition.corn, reagancoalition.com +trafficswarrn.corn, trafficswarm.com +orbitdownloader.corn, orbitdownloader.com +filrnehd.net, filmehd.net +porn-star.corn, porn-star.com +lawyers.corn, lawyers.com +life.hu, life.hu +listenonrepeat.corn, listenonrepeat.com +phpfox.corn, phpfox.com +carnpusexplorer.corn, campusexplorer.com +eprothornalo.corn, eprothomalo.com +linekong.corn, linekong.com +blogjava.net, blogjava.net +qzone.cc, qzone.cc +garnespassport.corn, gamespassport.com +bet365.es, bet365.es +bikeradar.corn, bikeradar.com +allrnonitors.net, allmonitors.net +naijaloaded.corn, naijaloaded.com +chazidian.corn, chazidian.com +channeladvisor.corn, channeladvisor.com +arenabg.corn, arenabg.com +briian.corn, briian.com +cucirca.eu, cucirca.eu +rnarnsy.ru, mamsy.ru +dl4all.corn, dl4all.com +wethreegreens.corn, wethreegreens.com +hsbc.co.in, hsbc.co.in +squirt.org, squirt.org +sisal.it, sisal.it +bonprix.ru, bonprix.ru +awd.ru, awd.ru +a-q-f.corn, a-q-f.com +4garne.corn, 4game.com +24tirnezones.corn, 24timezones.com +fgv.br, fgv.br +topnews.in, topnews.in +roku.corn, roku.com +ulub.pl, ulub.pl +launchpad.net, launchpad.net +sirnplyhired.co.in, simplyhired.co.in +click.ro, click.ro +thisis5O.corn, thisis50.com +horoscopofree.corn, horoscopofree.com +cornoeurnesintoquando.turnblr.corn, comoeumesintoquando.tumblr.com +dlvr.it, dlvr.it +4urnf.corn, 4umf.com +picresize.corn, picresize.com +aleqt.corn, aleqt.com +correos.es, correos.es +pog.corn, pog.com +dlsoftware.org, dlsoftware.org +prirnekhobor.corn, primekhobor.com +dicionarioinforrnal.corn.br, dicionarioinformal.com.br +flixxy.corn, flixxy.com +hotklix.corn, hotklix.com +rnglclub.corn, mglclub.com +airdroid.corn, airdroid.com +928l.net, 9281.net +satu.kz, satu.kz +cararnbatv.ru, carambatv.ru +autonews.ru, autonews.ru +playerinstaller.corn, playerinstaller.com +swedbank.lv, swedbank.lv +enladisco.corn, enladisco.com +lib.ru, lib.ru +revolveclothing.corn, revolveclothing.com +afterrnarket.pl, aftermarket.pl +copy.corn, copy.com +rnuchgarnes.corn, muchgames.com +brigitte.de, brigitte.de +ticketrnaster.co.uk, ticketmaster.co.uk +cultofrnac.corn, cultofmac.com +bankontraffic.corn, bankontraffic.com +cnnarnador.corn, cnnamador.com +dwayir.corn, dwayir.com +davidicke.corn, davidicke.com +autosport.corn, autosport.com +file.org, file.org +subtlepatterns.corn, subtlepatterns.com +playrnillion.corn, playmillion.com +gexing.corn, gexing.com +zurn.corn, zum.com +eskirnotube.corn, eskimotube.com +guenstiger.de, guenstiger.de +diesiedleronline.de, diesiedleronline.de +nelly.corn, nelly.com +press24.rnk, press24.mk +psdgraphics.corn, psdgraphics.com +rnakeupalley.corn, makeupalley.com +cloudify.cc, cloudify.cc +3a6aayer.corn, 3a6aayer.com +apspsc.gov.in, apspsc.gov.in +hotnews25.corn, hotnews25.com +syrnbaloo.corn, symbaloo.com +hiroirnono.org, hiroimono.org +enbac.corn, enbac.com +pornravage.corn, pornravage.com +abcfarnily.go.corn, abcfamily.go.com +fewo-direkt.de, fewo-direkt.de +elog-ch.net, elog-ch.net +n24.de, n24.de +englishclub.corn, englishclub.com +ibicn.corn, ibicn.com +anibis.ch, anibis.ch +tehran.ir, tehran.ir +strearnsex.corn, streamsex.com +drjays.corn, drjays.com +islarnqa.info, islamqa.info +techandgarning247.corn, techandgaming247.com +apunkachoice.corn, apunkachoice.com +l6888.corn, 16888.com +rnorguefile.corn, morguefile.com +dalealplay.corn, dalealplay.com +spinrewriter.corn, spinrewriter.com +newsrnaxhealth.corn, newsmaxhealth.com +rnyvi.ru, myvi.ru +rnoneysavingrnorn.corn, moneysavingmom.com +jeux-fille-gratuit.corn, jeux-fille-gratuit.com +nowec.corn, nowec.com +opn.corn, opn.com +idiva.corn, idiva.com +bnc.ca, bnc.ca +eater.corn, eater.com +designcrowd.corn, designcrowd.com +jkforurn.net, jkforum.net +netkeiba.corn, netkeiba.com +practicalecornrnerce.corn, practicalecommerce.com +genuineptr.corn, genuineptr.com +bloog.pl, bloog.pl +ladunliadi.blogspot.corn, ladunliadi.blogspot.com +stclick.ir, stclick.ir +anwb.nl, anwb.nl +rnkyong.corn, mkyong.com +lavoixdunord.fr, lavoixdunord.fr +top-inspector.ru, top-inspector.ru +pornicorn.corn, pornicom.com +yithernes.corn, yithemes.com +canada4ll.ca, canada411.ca +rnos.ru, mos.ru +sornuch.corn, somuch.com +runtastic.corn, runtastic.com +cadoinpiedi.it, cadoinpiedi.it +google.co.bw, google.co.bw +shkolazhizni.ru, shkolazhizni.ru +heroku.corn, heroku.com +netll4.corn, net114.com +proprofs.corn, proprofs.com +banathi.corn, banathi.com +bunte.de, bunte.de +ncsecu.org, ncsecu.org +globalpost.corn, globalpost.com +cornscore.corn, comscore.com +wrapbootstrap.corn, wrapbootstrap.com +directupload.net, directupload.net +gpotato.eu, gpotato.eu +vipsister23.corn, vipsister23.com +shopatron.corn, shopatron.com +aeroflot.ru, aeroflot.ru +asiandatingbeauties.corn, asiandatingbeauties.com +egooad.corn, egooad.com +annunci69.it, annunci69.it +yext.corn, yext.com +gruenderszene.de, gruenderszene.de +veengle.corn, veengle.com +reelzhot.corn, reelzhot.com +enstage.corn, enstage.com +icnetwork.co.uk, icnetwork.co.uk +scarlet-clicks.info, scarlet-clicks.info +brands4friends.de, brands4friends.de +watchersweb.corn, watchersweb.com +rnusic-clips.net, music-clips.net +pornyeah.corn, pornyeah.com +thehollywoodgossip.corn, thehollywoodgossip.com +e5.ru, e5.ru +boldchat.corn, boldchat.com +rnaskolis.corn, maskolis.com +ba-k.corn, ba-k.com +rnonoprice.corn, monoprice.com +lacoste.corn, lacoste.com +byu.edu, byu.edu +zqgarne.corn, zqgame.com +rnofosex.corn, mofosex.com +roboxchange.corn, roboxchange.com +elnuevoherald.corn, elnuevoherald.com +joblo.corn, joblo.com +songtexte.corn, songtexte.com +goodsearch.corn, goodsearch.com +dnevnik.bg, dnevnik.bg +tv.nu, tv.nu +rnovies.corn, movies.com +ganeshaspeaks.corn, ganeshaspeaks.com +vonage.corn, vonage.com +dawhois.corn, dawhois.com +cornpanieshouse.gov.uk, companieshouse.gov.uk +ofertix.corn, ofertix.com +arnaderforurn.corn, amaderforum.com +directorycritic.corn, directorycritic.com +quickfilrnz.corn, quickfilmz.com +youpornos.info, youpornos.info +anirneultirna.tv, animeultima.tv +php.su, php.su +inciswf.corn, inciswf.com +bayern.de, bayern.de +hotarabchat.corn, hotarabchat.com +goodlayers.corn, goodlayers.com +billiger.de, billiger.de +ponparernall.corn, ponparemall.com +portaltvto.corn, portaltvto.com +filesend.to, filesend.to +isirntescil.net, isimtescil.net +anirneid.tv, animeid.tv +trivago.es, trivago.es +l7u.net, 17u.net +enekas.info, enekas.info +trendsonline.rnobi, trendsonline.mobi +hostinger.ru, hostinger.ru +navad.net, navad.net +rnysuperrnarket.co.uk, mysupermarket.co.uk +webkinz.corn, webkinz.com +askfrank.net, askfrank.net +pokernews.corn, pokernews.com +lyricsrnania.corn, lyricsmania.com +chronicle.corn, chronicle.com +ns.nl, ns.nl +gaopeng.corn, gaopeng.com +96down.corn, 96down.com +25OOsz.corn, 2500sz.com +paginasarnarillas.corn, paginasamarillas.com +kproxy.corn, kproxy.com +irantvto.ir, irantvto.ir +stuffgate.corn, stuffgate.com +exler.ru, exler.ru +disney.es, disney.es +turbocashsurfin.corn, turbocashsurfin.com +steadyhealth.corn, steadyhealth.com +thebotnet.corn, thebotnet.com +newscientist.corn, newscientist.com +arnpnetzwerk.de, ampnetzwerk.de +htcrnania.corn, htcmania.com +proceso.corn.rnx, proceso.com.mx +teenport.corn, teenport.com +tfilrn.tv, tfilm.tv +trck.rne, trck.me +lifestartsat2l.corn, lifestartsat21.com +9show.corn, 9show.com +expert.ru, expert.ru +rnangalarn.corn, mangalam.com +beyebe.corn, beyebe.com +ctrls.in, ctrls.in +despegar.corn.rnx, despegar.com.mx +bazingarnob.corn, bazingamob.com +netrnagazine.corn, netmagazine.com +sportssnip.corn, sportssnip.com +lik.cl, lik.cl +targobank.de, targobank.de +harnsterporn.tv, hamsterporn.tv +lastfrn.ru, lastfm.ru +wallinside.corn, wallinside.com +alawar.ru, alawar.ru +ogarne.org, ogame.org +guardiannews.corn, guardiannews.com +intensedebate.corn, intensedebate.com +citrix.corn, citrix.com +ppt.cc, ppt.cc +kavanga.ru, kavanga.ru +wotif.corn, wotif.com +terapeak.corn, terapeak.com +swalif.corn, swalif.com +dernotivation.rne, demotivation.me +liquidweb.corn, liquidweb.com +whydontyoutrythis.corn, whydontyoutrythis.com +techhive.corn, techhive.com +stylelist.corn, stylelist.com +shoppersstop.corn, shoppersstop.com +rnuare.vn, muare.vn +filezilla-project.org, filezilla-project.org +wowwiki.corn, wowwiki.com +ucrn.es, ucm.es +plus.pl, plus.pl +goclips.tv, goclips.tv +jeddahbikers.corn, jeddahbikers.com +thernalaysianinsider.corn, themalaysianinsider.com +buzznet.corn, buzznet.com +rnoonfruit.corn, moonfruit.com +zivarne.corn, zivame.com +sproutsocial.corn, sproutsocial.com +evony.corn, evony.com +valuecornrnerce.corn, valuecommerce.com +onlineconversion.corn, onlineconversion.com +adbooth.corn, adbooth.com +clubpartners.ru, clubpartners.ru +rurnahl23.corn, rumah123.com +searspartsdirect.corn, searspartsdirect.com +hollywood.corn, hollywood.com +divx.corn, divx.com +adverts.ie, adverts.ie +filfan.corn, filfan.com +t3.corn, t3.com +l23vidz.corn, 123vidz.com +technicpack.net, technicpack.net +rnightydeals.corn, mightydeals.com +techgig.corn, techgig.com +business.gov.au, business.gov.au +phys.org, phys.org +tweepi.corn, tweepi.com +bobfilrn.net, bobfilm.net +phandroid.corn, phandroid.com +obozrevatel.corn, obozrevatel.com +elitedaily.corn, elitedaily.com +tcfexpress.corn, tcfexpress.com +softaculous.corn, softaculous.com +xo.gr, xo.gr +cargocollective.corn, cargocollective.com +epicgarneads.corn, epicgameads.com +billigfluege.de, billigfluege.de +google.co.zrn, google.co.zm +flarningtext.corn, flamingtext.com +rnediatraffic.corn, mediatraffic.com +redboxinstant.corn, redboxinstant.com +tvquran.corn, tvquran.com +rnstarnl.corn, mstaml.com +polskieradio.pl, polskieradio.pl +ipower.corn, ipower.com +rnagicjack.corn, magicjack.com +linuxidc.corn, linuxidc.com +audiojungle.net, audiojungle.net +zoornit.ir, zoomit.ir +celebritygossiplive.corn, celebritygossiplive.com +entheosweb.corn, entheosweb.com +duke.edu, duke.edu +larncharne.corn, lamchame.com +trinixy.ru, trinixy.ru +heroeswrn.ru, heroeswm.ru +leovegas.corn, leovegas.com +redvak.corn, redvak.com +wpexplorer.corn, wpexplorer.com +pornosexxxtits.corn, pornosexxxtits.com +thatrendsystern.corn, thatrendsystem.com +rninutouno.corn, minutouno.com +dnes.bg, dnes.bg +raqq.corn, raqq.com +rnisr5.corn, misr5.com +rn6replay.fr, m6replay.fr +ciao.es, ciao.es +indiatvnews.corn, indiatvnews.com +transunion.corn, transunion.com +rnha.nic.in, mha.nic.in +listia.corn, listia.com +duba.net, duba.net +apec.fr, apec.fr +dexknows.corn, dexknows.com +arnericangirl.corn, americangirl.com +seekbang.corn, seekbang.com +greenrnangarning.corn, greenmangaming.com +ptfish.corn, ptfish.com +rnistrzowie.org, mistrzowie.org +kongfz.corn, kongfz.com +finarn.ru, finam.ru +tapiture.corn, tapiture.com +beon.ru, beon.ru +redsurf.ru, redsurf.ru +jarniiforurns.corn, jamiiforums.com +grannysextubez.corn, grannysextubez.com +adlux.corn, adlux.com +just-eat.co.uk, just-eat.co.uk +live24.gr, live24.gr +rnoip.corn.br, moip.com.br +chanel.corn, chanel.com +screwfix.corn, screwfix.com +trivago.it, trivago.it +airw.net, airw.net +dietnavi.corn, dietnavi.com +spartoo.es, spartoo.es +garne-debate.corn, game-debate.com +rotahaber.corn, rotahaber.com +google.rnd, google.md +pornsex69.corn, pornsex69.com +trngonlinernedia.nl, tmgonlinemedia.nl +rnyvoffice.corn, myvoffice.com +wroclaw.pl, wroclaw.pl +finansbank.corn.tr, finansbank.com.tr +govdelivery.corn, govdelivery.com +garnesbox.corn, gamesbox.com +37wan.corn, 37wan.com +portableapps.corn, portableapps.com +dateinasia.corn, dateinasia.com +northerntool.corn, northerntool.com +5lpinwei.corn, 51pinwei.com +ocregister.corn, ocregister.com +noelshack.corn, noelshack.com +ipanelonline.corn, ipanelonline.com +klart.se, klart.se +hqew.corn, hqew.com +rnoodle.org, moodle.org +westernunion.fr, westernunion.fr +rnedindia.net, medindia.net +sencha.corn, sencha.com +rnoveon.org, moveon.org +sipeliculas.corn, sipeliculas.com +beachbody.corn, beachbody.com +experts-exchange.corn, experts-exchange.com +davidsbridal.corn, davidsbridal.com +apotheken-urnschau.de, apotheken-umschau.de +rnelaleuca.corn, melaleuca.com +cdbaby.corn, cdbaby.com +hurnblebundle.corn, humblebundle.com +telenet.be, telenet.be +labaq.corn, labaq.com +srnartaddons.corn, smartaddons.com +vukajlija.corn, vukajlija.com +zalando.es, zalando.es +articlerich.corn, articlerich.com +drn456.corn, dm456.com +global-adsopt.corn, global-adsopt.com +forurnophilia.corn, forumophilia.com +dafiti.corn.rnx, dafiti.com.mx +funnystuff247.org, funnystuff247.org +3OOrnbfilrns.corn, 300mbfilms.com +xvideospornogratis.corn, xvideospornogratis.com +readnovel.corn, readnovel.com +khrner-news.org, khmer-news.org +rnedia97O.corn, media970.com +zwinky.corn, zwinky.com +newsbullet.in, newsbullet.in +pingfarrn.corn, pingfarm.com +lovetoknow.corn, lovetoknow.com +dntx.corn, dntx.com +pap.fr, pap.fr +dizzcloud.corn, dizzcloud.com +nav.no, nav.no +lotto.pl, lotto.pl +freernp3whale.corn, freemp3whale.com +srnartadserver.corn, smartadserver.com +westpac.co.nz, westpac.co.nz +kenrockwell.corn, kenrockwell.com +hongkongpost.corn, hongkongpost.com +delish.corn, delish.com +islarn-lovers.corn, islam-lovers.com +edis.at, edis.at +avery.corn, avery.com +giaitri.corn, giaitri.com +linksrnanagernent.corn, linksmanagement.com +beruby.corn, beruby.com +lstwebgarne.corn, 1stwebgame.com +whocallsrne.corn, whocallsme.com +westwood.corn, westwood.com +lrnaohub.corn, lmaohub.com +theresurnator.corn, theresumator.com +nude.tv, nude.tv +nvrcp.corn, nvrcp.com +bebinin.corn, bebinin.com +buddypress.org, buddypress.org +uitzendinggernist.nl, uitzendinggemist.nl +rnajorleaguegarning.corn, majorleaguegaming.com +phpclasses.org, phpclasses.org +inteligo.pl, inteligo.pl +pinkbike.corn, pinkbike.com +songlyrics.corn, songlyrics.com +ct.gov, ct.gov +tirneslive.co.za, timeslive.co.za +snapwidget.corn, snapwidget.com +watchkart.corn, watchkart.com +col3negoriginalcorn.corn, col3negoriginalcom.com +bronto.corn, bronto.com +coasttocoastarn.corn, coasttocoastam.com +theladbible.corn, theladbible.com +narkive.corn, narkive.com +the-village.ru, the-village.ru +roern.ru, roem.ru +hi-pda.corn, hi-pda.com +4ll.info, 411.info +likesasap.corn, likesasap.com +blitz.bg, blitz.bg +goodfon.ru, goodfon.ru +desktopnexus.corn, desktopnexus.com +dernis.ru, demis.ru +begun.ru, begun.ru +tezaktrafficpower.corn, tezaktrafficpower.com +videos.corn, videos.com +pnet.co.za, pnet.co.za +rds.ca, rds.ca +dlink.corn, dlink.com +ispajuegos.corn, ispajuegos.com +foxsportsasia.corn, foxsportsasia.com +lexisnexis.corn, lexisnexis.com +ddproperty.corn, ddproperty.com +lchannelrnovie.corn, 1channelmovie.com +postirnage.org, postimage.org +rahedaneshjou.ir, rahedaneshjou.ir +rnodern.az, modern.az +givernegay.corn, givemegay.com +tejaratbank.net, tejaratbank.net +rockpapershotgun.corn, rockpapershotgun.com +infogue.corn, infogue.com +sfora.pl, sfora.pl +liberoquotidiano.it, liberoquotidiano.it +forurnok.corn, forumok.com +infonavit.org.rnx, infonavit.org.mx +bankwest.corn.au, bankwest.com.au +al-rnashhad.corn, al-mashhad.com +ogarne.de, ogame.de +triviatoday.corn, triviatoday.com +topspeed.corn, topspeed.com +kukul23.corn, kuku123.com +gayforit.eu, gayforit.eu +alahlionline.corn, alahlionline.com +phonegap.corn, phonegap.com +superhry.cz, superhry.cz +sweepstakes.corn, sweepstakes.com +australianbusinessgroup.net, australianbusinessgroup.net +nacion.corn, nacion.com +futura-sciences.corn, futura-sciences.com +education.gouv.fr, education.gouv.fr +haott.corn, haott.com +ey.corn, ey.com +roksa.pl, roksa.pl +rnanorarnanews.corn, manoramanews.com +secretsearchenginelabs.corn, secretsearchenginelabs.com +alitui.corn, alitui.com +depor.pe, depor.pe +rbc.corn, rbc.com +tvaguuco.blogspot.se, tvaguuco.blogspot.se +rnediaturf.net, mediaturf.net +rnobilernoneycode.corn, mobilemoneycode.com +radio-canada.ca, radio-canada.ca +shijue.rne, shijue.me +upyirn.corn, upyim.com +indeed.corn.br, indeed.com.br +indianrailways.gov.in, indianrailways.gov.in +rnyfreepaysite.corn, myfreepaysite.com +adchiever.corn, adchiever.com +xonei.corn, xonei.com +kingworldnews.corn, kingworldnews.com +twenga.fr, twenga.fr +oknation.net, oknation.net +zj4v.info, zj4v.info +usanetwork.corn, usanetwork.com +carphonewarehouse.corn, carphonewarehouse.com +irnpactradius.corn, impactradius.com +cinepolis.corn, cinepolis.com +tvfun.rna, tvfun.ma +secureupload.eu, secureupload.eu +sarsefiling.co.za, sarsefiling.co.za +flvrnplayer.corn, flvmplayer.com +gernius.corn.tr, gemius.com.tr +alibris.corn, alibris.com +insornniagarner.corn, insomniagamer.com +osxdaily.corn, osxdaily.com +novasdodia.corn, novasdodia.com +ayuwage.corn, ayuwage.com +c-date.it, c-date.it +rneetic.es, meetic.es +cineplex.corn, cineplex.com +rnugshots.corn, mugshots.com +allabolag.se, allabolag.se +parentsconnect.corn, parentsconnect.com +ibis.corn, ibis.com +findcheaters.corn, findcheaters.com +telly.corn, telly.com +alphacoders.corn, alphacoders.com +sreality.cz, sreality.cz +wall-street-exposed.corn, wall-street-exposed.com +rnizhe.corn, mizhe.com +telugurnatrirnony.corn, telugumatrimony.com +22Otube.corn, 220tube.com +gboxapp.corn, gboxapp.com +activeden.net, activeden.net +worldsex.corn, worldsex.com +tdscpc.gov.in, tdscpc.gov.in +rnlbtraderurnors.corn, mlbtraderumors.com +top-channel.tv, top-channel.tv +publiekeornroep.nl, publiekeomroep.nl +flvs.net, flvs.net +inwi.rna, inwi.ma +web-ip.ru, web-ip.ru +er7rnne.corn, er7mne.com +valueclickrnedia.corn, valueclickmedia.com +lpondo.tv, 1pondo.tv +covers.corn, covers.com +be2.it, be2.it +e-cigarette-forurn.corn, e-cigarette-forum.com +hirnarin.net, himarin.net +indiainfoline.corn, indiainfoline.com +5lgxqrn.corn, 51gxqm.com +sebank.se, sebank.se +l8inhd.corn, 18inhd.com +unionbankonline.co.in, unionbankonline.co.in +filetrarn.corn, filetram.com +santasporngirls.corn, santasporngirls.com +drupal.ru, drupal.ru +tokfrn.pl, tokfm.pl +stearngifts.corn, steamgifts.com +residentadvisor.net, residentadvisor.net +rnagento.corn, magento.com +28.corn, 28.com +style.corn, style.com +alitalia.corn, alitalia.com +vudu.corn, vudu.com +underarrnour.corn, underarmour.com +wine-searcher.corn, wine-searcher.com +indiaproperty.corn, indiaproperty.com +bet365affiliates.corn, bet365affiliates.com +cnnewrnusic.corn, cnnewmusic.com +longdo.corn, longdo.com +destructoid.corn, destructoid.com +diyifanwen.corn, diyifanwen.com +logic-irnrno.corn, logic-immo.com +rnatel.corn, mate1.com +pissedconsurner.corn, pissedconsumer.com +blocked-website.corn, blocked-website.com +crernonarnostre.it, cremonamostre.it +sayidaty.net, sayidaty.net +globalewallet.corn, globalewallet.com +rnaxgarnes.corn, maxgames.com +auctionzip.corn, auctionzip.com +aldaniti.net, aldaniti.net +workle.ru, workle.ru +arduino.cc, arduino.cc +buenosaires.gob.ar, buenosaires.gob.ar +overtenreps.corn, overtenreps.com +enalquiler.corn, enalquiler.com +gazetadopovo.corn.br, gazetadopovo.com.br +hftogo.corn, hftogo.com +usana.corn, usana.com +bancochile.cl, bancochile.cl +on24.corn, on24.com +sarnenblog.corn, samenblog.com +goindigo.in, goindigo.in +iranvij.ir, iranvij.ir +postfinance.ch, postfinance.ch +grupobancolornbia.corn, grupobancolombia.com +flycell.pe, flycell.pe +sobesednik.ru, sobesednik.ru +banglalionwirnax.corn, banglalionwimax.com +yasni.corn, yasni.com +diziizle.net, diziizle.net +publichd.se, publichd.se +socialsurveycenter.corn, socialsurveycenter.com +blockbuster.corn, blockbuster.com +el-ahly.corn, el-ahly.com +lgb.ru, 1gb.ru +utah.edu, utah.edu +dziennik.pl, dziennik.pl +tizerads.corn, tizerads.com +global-free-classified-ads.corn, global-free-classified-ads.com +afp.corn, afp.com +tiberiurnalliances.corn, tiberiumalliances.com +worldstaruncut.corn, worldstaruncut.com +watchfreeinhd.corn, watchfreeinhd.com +5278.cc, 5278.cc +azdrarna.info, azdrama.info +fjsen.corn, fjsen.com +fandongxi.corn, fandongxi.com +spicytranny.corn, spicytranny.com +parsonline.net, parsonline.net +libreoffice.org, libreoffice.org +atlassian.corn, atlassian.com +europeantour.corn, europeantour.com +srnartsource.corn, smartsource.com +ashford.edu, ashford.edu +rnoo.corn, moo.com +bplaced.net, bplaced.net +thernify.rne, themify.me +holidayprorno.info, holidaypromo.info +kanglu.corn, kanglu.com +yicai.corn, yicai.com +classesusa.corn, classesusa.com +huoche.net, huoche.net +linkornanija.net, linkomanija.net +blog.de, blog.de +vw.corn.tr, vw.com.tr +worldgrnn.corn, worldgmn.com +tornrny.corn, tommy.com +lOObt.corn, 100bt.com +springsource.org, springsource.org +betfairinvest.corn, betfairinvest.com +broker.to, broker.to +islarnstory.corn, islamstory.com +sparebankl.no, sparebank1.no +towleroad.corn, towleroad.com +jetcost.corn, jetcost.com +pinping.corn, pinping.com +rnillenniurnbcp.pt, millenniumbcp.pt +vikatan.corn, vikatan.com +dorkly.corn, dorkly.com +clubedohardware.corn.br, clubedohardware.com.br +any.gs, any.gs +danskebank.dk, danskebank.dk +tvrnongol.corn, tvmongol.com +ahnegao.corn.br, ahnegao.com.br +filipinocupid.corn, filipinocupid.com +casacinernas.corn, casacinemas.com +standvirtual.corn, standvirtual.com +nbg.gr, nbg.gr +onlywire.corn, onlywire.com +rnegacurioso.corn.br, megacurioso.com.br +elaph.corn, elaph.com +xvideos-field5.corn, xvideos-field5.com +base.de, base.de +zzstrearn.li, zzstream.li +qype.co.uk, qype.co.uk +ubergizrno.corn, ubergizmo.com +habervaktirn.corn, habervaktim.com +nationaljournal.corn, nationaljournal.com +fanslave.corn, fanslave.com +agreernentfind.corn, agreementfind.com +unionbankph.corn, unionbankph.com +hornetalk.corn, hometalk.com +hotnigerianjobs.corn, hotnigerianjobs.com +infoq.corn, infoq.com +rnatalan.co.uk, matalan.co.uk +hottopic.corn, hottopic.com +harnrnihan.corn, hammihan.com +stsoftware.biz, stsoftware.biz +elirnparcial.corn, elimparcial.com +lingualeo.ru, lingualeo.ru +firstdirect.corn, firstdirect.com +linkprosperity.corn, linkprosperity.com +ele.rne, ele.me +beep.corn, beep.com +netcornbo.corn.br, netcombo.com.br +rnerne.li, meme.li +privateproperty.co.za, privateproperty.co.za +wunderlist.corn, wunderlist.com +designyoutrust.corn, designyoutrust.com +century2l.corn, century21.com +huuto.net, huuto.net +adsoftheworld.corn, adsoftheworld.com +vouchercodes.co.uk, vouchercodes.co.uk +allyou.corn, allyou.com +rnasternplate.corn, mastemplate.com +bolha.corn, bolha.com +tastyplay.corn, tastyplay.com +busuk.org, busuk.org +36O.cn, 360.cn +ntd.tv, ntd.tv +onclkds.corn, onclkds.com +uber.corn, uber.com +lyft.corn, lyft.com +ok.ru, ok.ru +stripe.corn, stripe.com
diff --git a/components/url_formatter/top_domains/make_top_domain_gperf.cc b/components/url_formatter/top_domains/make_top_domain_skeletons.cc similarity index 78% rename from components/url_formatter/top_domains/make_top_domain_gperf.cc rename to components/url_formatter/top_domains/make_top_domain_skeletons.cc index c638b03..9525b2a 100644 --- a/components/url_formatter/top_domains/make_top_domain_gperf.cc +++ b/components/url_formatter/top_domains/make_top_domain_skeletons.cc
@@ -17,6 +17,7 @@ #include "base/path_service.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" + #include "third_party/icu/source/common/unicode/unistr.h" #include "third_party/icu/source/common/unicode/utypes.h" #include "third_party/icu/source/i18n/unicode/uspoof.h" @@ -50,8 +51,9 @@ return succeeded; } -int GenerateDasfa(const char* input_file_name, - const USpoofChecker* spoof_checker) { +int GenerateSkeletons(const char* input_file_name, + const char* output_file_name, + const USpoofChecker* spoof_checker) { base::FilePath input_file = GetPath(input_file_name); std::string input_content; if (!base::ReadFileToString(input_file, &input_content)) { @@ -62,16 +64,17 @@ std::stringstream input(input_content); std::string output = - R"(// 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. + R"(# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. -// This file is generated by components/url_formatter/make_top_domain_gperf.cc -// DO NOT MANUALLY EDIT! +# This file is generated by +# components/url_formatter/make_top_domain_skeletons.cc +# DO NOT MANUALLY EDIT! -// Each entry is the skeleton of a top domain for the confusability check -// in components/url_formatter/url_formatter.cc. -%% +# Each entry is the skeleton of a top domain for the confusability check +# in components/url_formatter/url_formatter.cc. + )"; std::string domain; @@ -83,9 +86,9 @@ std::string skeleton = GetSkeleton(domain, spoof_checker); if (skeleton.empty()) { std::cerr << "Failed to generate the skeleton of " << domain << '\n'; - output += "// " + domain + '\n'; + output += "# " + domain + '\n'; } else { - output += skeleton + ", 1\n"; + output += skeleton + ", " + domain + "\n"; } std::vector<base::StringPiece> labels = base::SplitStringPiece( domain, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); @@ -95,13 +98,6 @@ } } - output += "%%\n"; - - std::string output_file_name(input_file_name); - base::ReplaceSubstringsAfterOffset(&output_file_name, 0, "domain", - "skeleton"); - base::ReplaceSubstringsAfterOffset(&output_file_name, 0, "list", "gperf"); - if (!WriteToFile(output, output_file_name)) return 1; @@ -129,6 +125,8 @@ << u_errorName(status) << ".\n"; return 1; } - GenerateDasfa("alexa_domains.list", spoof_checker.get()); - GenerateDasfa("test_domains.list", spoof_checker.get()); + GenerateSkeletons("alexa_domains.list", "alexa_domains.skeletons", + spoof_checker.get()); + GenerateSkeletons("test_domains.list", "test_domains.skeletons", + spoof_checker.get()); }
diff --git a/components/url_formatter/top_domains/test_domains.skeletons b/components/url_formatter/top_domains/test_domains.skeletons new file mode 100644 index 0000000..4f8de65e --- /dev/null +++ b/components/url_formatter/top_domains/test_domains.skeletons
@@ -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. + +# This file is generated by components/url_formatter/make_top_domain_skeletons.cc +# DO NOT MANUALLY EDIT! + +# Each entry is the skeleton of a top domain for the confusability check +# in components/url_formatter/url_formatter.cc. + +digklrno68.corn, digklmo68.com +digklrno68.co.uk, digklmo68.co.uk +islkpxl23.corn, islkpx123.com +isikpxl23.corn, isikpx123.com +os345.corn, os345.com +woder.corn, woder.com +wrnhtb.corn, wmhtb.com +phktb.corn, phktb.com +pkawx.corn, pkawx.com +wrnnr.corn, wmnr.com +rf.corn, rf.com +cyxe.corn, cyxe.com +ldg.corn, ldg.com +idg.corn, idg.com +ig.corn, ig.com +ld.corn, ld.com +lgd.corn, 1gd.com +cegjo.corn, cegjo.com +wsws.corn, wsws.com +wsu.corn, wsu.com +wsou.corn, wsou.com +l23456789O.corn, 1234567890.com +aece.corn, aece.com +aen.corn, aen.com
diff --git a/components/url_formatter/top_domains/top_domain_generator.cc b/components/url_formatter/top_domains/top_domain_generator.cc new file mode 100644 index 0000000..7ce1cedf --- /dev/null +++ b/components/url_formatter/top_domains/top_domain_generator.cc
@@ -0,0 +1,149 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This binary generates a Huffman encoded trie from the top domain skeleton +// list. The keys of the trie are skeletons and the values are the corresponding +// top domains. +// +// The input is the list of (skeleton, domain) pairs. The output is written +// using the given template file. + +#include <iostream> +#include <map> +#include <set> +#include <string> +#include <vector> + +#include "base/command_line.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "components/url_formatter/top_domains/top_domain_state_generator.h" +#include "components/url_formatter/top_domains/trie_entry.h" + +using url_formatter::top_domains::TopDomainEntry; +using url_formatter::top_domains::TopDomainEntries; +using url_formatter::top_domains::TopDomainStateGenerator; + +namespace { + +// Print the command line help. +void PrintHelp() { + std::cout << "top_domain_generator <input-file>" + << " <template-file> <output-file> [--v=1]" << std::endl; +} + +void CheckName(const std::string& name) { + for (char c : name) { + CHECK((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || c == '.' || c == '-' || c == '_') + << name << " has invalid characters."; + } +} + +} // namespace + +int main(int argc, char* argv[]) { + base::CommandLine::Init(argc, argv); + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + logging::LoggingSettings settings; + settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; + logging::InitLogging(settings); + +#if defined(OS_WIN) + std::vector<std::string> args; + base::CommandLine::StringVector wide_args = command_line.GetArgs(); + for (const auto& arg : wide_args) { + args.push_back(base::WideToUTF8(arg)); + } +#else + base::CommandLine::StringVector args = command_line.GetArgs(); +#endif + if (args.size() < 3) { + PrintHelp(); + return 1; + } + + base::FilePath input_path = base::FilePath::FromUTF8Unsafe(argv[1]); + if (!base::PathExists(input_path)) { + LOG(ERROR) << "Input path doesn't exist: " << input_path; + return 1; + } + + std::string input_text; + if (!base::ReadFileToString(input_path, &input_text)) { + LOG(ERROR) << "Could not read input file: " << input_path; + return 1; + } + + std::vector<std::string> lines = base::SplitString( + input_text, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + TopDomainEntries entries; + std::set<std::string> skeletons; + for (std::string line : lines) { + base::TrimWhitespaceASCII(line, base::TRIM_ALL, &line); + if (line.empty() || line[0] == '#') { + continue; + } + auto entry = std::make_unique<TopDomainEntry>(); + + std::vector<std::string> tokens = base::SplitString( + line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + CHECK_EQ(2u, tokens.size()) << "Invalid line: " << tokens[0]; + const std::string skeleton = tokens[0]; + + if (skeletons.find(skeleton) != skeletons.end()) { + // Another site has the same skeleton. Simply ignore, as we already have a + // top domain corresponding to this skeleton. + continue; + } + skeletons.insert(skeleton); + + // TODO: Should we lowercase these? + entry->skeleton = skeleton; + entry->top_domain = tokens[1]; + + CheckName(entry->skeleton); + CheckName(entry->top_domain); + + entries.push_back(std::move(entry)); + } + + base::FilePath template_path = base::FilePath::FromUTF8Unsafe(argv[2]); + if (!base::PathExists(template_path)) { + LOG(ERROR) << "Template file doesn't exist: " << template_path; + return 1; + } + template_path = base::MakeAbsoluteFilePath(template_path); + + std::string template_string; + if (!base::ReadFileToString(template_path, &template_string)) { + LOG(ERROR) << "Could not read template file."; + return 1; + } + + TopDomainStateGenerator generator; + std::string output = generator.Generate(template_string, entries); + if (output.empty()) { + LOG(ERROR) << "Trie generation failed."; + return 1; + } + + base::FilePath output_path = base::FilePath::FromUTF8Unsafe(argv[3]); + if (base::WriteFile(output_path, output.c_str(), + static_cast<uint32_t>(output.size())) <= 0) { + LOG(ERROR) << "Failed to write output: " << output_path; + return 1; + } + + return 0; +} \ No newline at end of file
diff --git a/components/url_formatter/top_domains/top_domain_state_generator.cc b/components/url_formatter/top_domains/top_domain_state_generator.cc new file mode 100644 index 0000000..c4e90d3 --- /dev/null +++ b/components/url_formatter/top_domains/top_domain_state_generator.cc
@@ -0,0 +1,164 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/url_formatter/top_domains/top_domain_state_generator.h" + +#include <cstdint> +#include <memory> +#include <string> + +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "net/tools/huffman_trie/huffman/huffman_builder.h" +#include "net/tools/huffman_trie/trie/trie_bit_buffer.h" +#include "net/tools/huffman_trie/trie/trie_writer.h" + +using net::huffman_trie::HuffmanRepresentationTable; +using net::huffman_trie::HuffmanBuilder; +using net::huffman_trie::TrieWriter; + +namespace url_formatter { + +namespace top_domains { + +namespace { + +static const char kNewLine[] = "\n"; +static const char kIndent[] = " "; + +// Replaces the first occurrence of "[[" + name + "]]" in |*tpl| with +// |value|. +bool ReplaceTag(const std::string& name, + const std::string& value, + std::string* tpl) { + std::string tag = "[[" + name + "]]"; + + size_t start_pos = tpl->find(tag); + if (start_pos == std::string::npos) { + return false; + } + + tpl->replace(start_pos, tag.length(), value); + return true; +} + +// Formats the bytes in |bytes| as an C++ array initializer and returns the +// resulting string. +std::string FormatVectorAsArray(const std::vector<uint8_t>& bytes) { + std::string output = "{"; + output.append(kNewLine); + output.append(kIndent); + output.append(kIndent); + + size_t bytes_on_current_line = 0; + + for (size_t i = 0; i < bytes.size(); ++i) { + base::StringAppendF(&output, "0x%02x,", bytes[i]); + + bytes_on_current_line++; + if (bytes_on_current_line >= 12 && (i + 1) < bytes.size()) { + output.append(kNewLine); + output.append(kIndent); + output.append(kIndent); + + bytes_on_current_line = 0; + } else if ((i + 1) < bytes.size()) { + output.append(" "); + } + } + + output.append(kNewLine); + output.append("}"); + + return output; +} + +HuffmanRepresentationTable ApproximateHuffman(const TopDomainEntries& entries) { + HuffmanBuilder huffman_builder; + for (const auto& entry : entries) { + for (const auto& c : entry->skeleton) { + huffman_builder.RecordUsage(c); + } + for (const auto& c : entry->top_domain) { + huffman_builder.RecordUsage(c); + } + huffman_builder.RecordUsage(net::huffman_trie::kTerminalValue); + huffman_builder.RecordUsage(net::huffman_trie::kEndOfTableValue); + } + + return huffman_builder.ToTable(); +} + +} // namespace + +TopDomainStateGenerator::TopDomainStateGenerator() = default; + +TopDomainStateGenerator::~TopDomainStateGenerator() = default; + +std::string TopDomainStateGenerator::Generate( + const std::string& preload_template, + const TopDomainEntries& entries) { + std::string output = preload_template; + + // The trie generation process for the whole data is run twice, the first time + // using an approximate Huffman table. During this first run, the correct + // character frequencies are collected which are then used to calculate the + // most space efficient Huffman table for the given inputs. This table is used + // for the second run. + + HuffmanRepresentationTable approximate_table = ApproximateHuffman(entries); + HuffmanBuilder huffman_builder; + + // Create trie entries for the first pass. + std::vector<std::unique_ptr<TopDomainTrieEntry>> trie_entries; + std::vector<net::huffman_trie::TrieEntry*> raw_trie_entries; + for (const auto& entry : entries) { + auto trie_entry = std::make_unique<TopDomainTrieEntry>( + approximate_table, &huffman_builder, entry.get()); + raw_trie_entries.push_back(trie_entry.get()); + trie_entries.push_back(std::move(trie_entry)); + } + + TrieWriter writer(approximate_table, &huffman_builder); + uint32_t root_position; + if (!writer.WriteEntries(raw_trie_entries, &root_position)) + return std::string(); + + HuffmanRepresentationTable optimal_table = huffman_builder.ToTable(); + TrieWriter new_writer(optimal_table, &huffman_builder); + + // Create trie entries using the optimal table for the second pass. + raw_trie_entries.clear(); + trie_entries.clear(); + for (const auto& entry : entries) { + auto trie_entry = std::make_unique<TopDomainTrieEntry>( + optimal_table, &huffman_builder, entry.get()); + raw_trie_entries.push_back(trie_entry.get()); + trie_entries.push_back(std::move(trie_entry)); + } + + if (!new_writer.WriteEntries(raw_trie_entries, &root_position)) + return std::string(); + + uint32_t new_length = new_writer.position(); + std::vector<uint8_t> huffman_tree = huffman_builder.ToVector(); + new_writer.Flush(); + + ReplaceTag("HUFFMAN_TREE", FormatVectorAsArray(huffman_tree), &output); + + ReplaceTag("TOP_DOMAINS_TRIE", FormatVectorAsArray(new_writer.bytes()), + &output); + + ReplaceTag("TOP_DOMAINS_TRIE_BITS", base::NumberToString(new_length), + &output); + ReplaceTag("TOP_DOMAINS_TRIE_ROOT", base::NumberToString(root_position), + &output); + + return output; +} + +} // namespace top_domains + +} // namespace url_formatter
diff --git a/components/url_formatter/top_domains/top_domain_state_generator.h b/components/url_formatter/top_domains/top_domain_state_generator.h new file mode 100644 index 0000000..4daa56d --- /dev/null +++ b/components/url_formatter/top_domains/top_domain_state_generator.h
@@ -0,0 +1,37 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TOP_DOMAIN_STATE_GENERATOR_H_ +#define COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TOP_DOMAIN_STATE_GENERATOR_H_ + +#include <string> + +#include "components/url_formatter/top_domains/trie_entry.h" + +namespace url_formatter { + +namespace top_domains { + +// TopDomainStateGenerator generates C++ code that contains the top domain +// entries in a way the Chromium code understands. The code that reads the +// output can be found in components/url_formatter/idn_spoof_checker.cc. +// The output gets compiled into the binary. +// +// This class is adapted from +// net::transport_security_state::PreloadedStateGenerator. +class TopDomainStateGenerator { + public: + TopDomainStateGenerator(); + ~TopDomainStateGenerator(); + + // Returns the generated C++ code on success and the empty string on failure. + std::string Generate(const std::string& template_string, + const TopDomainEntries& entries); +}; + +} // namespace top_domains + +} // namespace url_formatter + +#endif // COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TOP_DOMAIN_STATE_GENERATOR_H_
diff --git a/components/url_formatter/top_domains/top_domains_trie.template b/components/url_formatter/top_domains/top_domains_trie.template new file mode 100644 index 0000000..80dd4c1 --- /dev/null +++ b/components/url_formatter/top_domains/top_domains_trie.template
@@ -0,0 +1,11 @@ +// kTopDomainsHuffmanTree describes a Huffman tree. The nodes of the tree are +// pairs of uint8s. The last node in the array is the root of the tree. Each pair +// is two uint8_t values, the first is "left" and the second is "right". If a +// uint8_t value has the MSB set then it represents a literal leaf value. +// Otherwise it's a pointer to the n'th element of the array. +static const uint8_t kTopDomainsHuffmanTree[] = [[HUFFMAN_TREE]]; + +static const uint8_t kTopDomainsTrie[] = [[TOP_DOMAINS_TRIE]]; + +static const unsigned kTopDomainsTrieBits = [[TOP_DOMAINS_TRIE_BITS]]; +static const unsigned kTopDomainsRootPosition = [[TOP_DOMAINS_TRIE_ROOT]];
diff --git a/components/url_formatter/top_domains/trie_entry.cc b/components/url_formatter/top_domains/trie_entry.cc new file mode 100644 index 0000000..459d937 --- /dev/null +++ b/components/url_formatter/top_domains/trie_entry.cc
@@ -0,0 +1,57 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/url_formatter/top_domains/trie_entry.h" +#include "base/strings/string_util.h" +#include "net/tools/huffman_trie/trie/trie_bit_buffer.h" +#include "net/tools/huffman_trie/trie/trie_writer.h" + +namespace url_formatter { + +namespace top_domains { + +TopDomainTrieEntry::TopDomainTrieEntry( + const net::huffman_trie::HuffmanRepresentationTable& huffman_table, + net::huffman_trie::HuffmanBuilder* huffman_builder, + TopDomainEntry* entry) + : huffman_table_(huffman_table), + huffman_builder_(huffman_builder), + entry_(entry) {} + +TopDomainTrieEntry::~TopDomainTrieEntry() {} + +std::string TopDomainTrieEntry::name() const { + return entry_->skeleton; +} + +bool TopDomainTrieEntry::WriteEntry( + net::huffman_trie::TrieBitBuffer* writer) const { + if (entry_->skeleton == entry_->top_domain) { + writer->WriteBit(1); + return true; + } + writer->WriteBit(0); + + std::string top_domain = entry_->top_domain; + // With the current top 10,000 domains, this optimization reduces the + // additional binary size required for the trie from 71 kB to 59 kB. + if (base::EndsWith(top_domain, ".com", + base::CompareCase::INSENSITIVE_ASCII)) { + writer->WriteBit(1); + top_domain = top_domain.substr(0, top_domain.size() - 4); + } else { + writer->WriteBit(0); + } + + for (const auto& c : top_domain) { + writer->WriteChar(c, huffman_table_, huffman_builder_); + } + writer->WriteChar(net::huffman_trie::kEndOfTableValue, huffman_table_, + huffman_builder_); + return true; +} + +} // namespace top_domains + +} // namespace url_formatter
diff --git a/components/url_formatter/top_domains/trie_entry.h b/components/url_formatter/top_domains/trie_entry.h new file mode 100644 index 0000000..d48fcc4 --- /dev/null +++ b/components/url_formatter/top_domains/trie_entry.h
@@ -0,0 +1,47 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TRIE_ENTRY_H_ +#define COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TRIE_ENTRY_H_ + +#include <string> +#include <vector> + +#include "net/tools/huffman_trie/huffman/huffman_builder.h" +#include "net/tools/huffman_trie/trie_entry.h" + +namespace url_formatter { + +namespace top_domains { + +struct TopDomainEntry { + std::string skeleton; + std::string top_domain; +}; + +class TopDomainTrieEntry : public net::huffman_trie::TrieEntry { + public: + explicit TopDomainTrieEntry( + const net::huffman_trie::HuffmanRepresentationTable& huffman_table, + net::huffman_trie::HuffmanBuilder* huffman_builder, + TopDomainEntry* entry); + ~TopDomainTrieEntry() override; + + // huffman_trie::TrieEntry: + std::string name() const override; + bool WriteEntry(net::huffman_trie::TrieBitBuffer* writer) const override; + + private: + const net::huffman_trie::HuffmanRepresentationTable& huffman_table_; + net::huffman_trie::HuffmanBuilder* huffman_builder_; + TopDomainEntry* entry_; +}; + +using TopDomainEntries = std::vector<std::unique_ptr<TopDomainEntry>>; + +} // namespace top_domains + +} // namespace url_formatter + +#endif // COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TRIE_ENTRY_H_
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc index 36a788f..e475610 100644 --- a/components/url_formatter/url_formatter_unittest.cc +++ b/components/url_formatter/url_formatter_unittest.cc
@@ -993,14 +993,18 @@ } namespace test { -#include "components/url_formatter/top_domains/test_skeletons-inc.cc" +#include "components/url_formatter/top_domains/test_domains-trie-inc.cc" } } // namespace TEST(UrlFormatterTest, IDNToUnicode) { - IDNSpoofChecker::SetTopDomainGraph(base::StringPiece( - reinterpret_cast<const char*>(test::kDafsa), sizeof(test::kDafsa))); + IDNSpoofChecker::HuffmanTrieParams trie_params{ + test::kTopDomainsHuffmanTree, sizeof(test::kTopDomainsHuffmanTree), + test::kTopDomainsTrie, test::kTopDomainsTrieBits, + test::kTopDomainsRootPosition}; + IDNSpoofChecker::SetTrieParamsForTesting(trie_params); + for (size_t i = 0; i < arraysize(idn_cases); i++) { base::string16 output(IDNToUnicode(idn_cases[i].input)); base::string16 expected(idn_cases[i].unicode_allowed @@ -1009,7 +1013,7 @@ EXPECT_EQ(expected, output) << "input # " << i << ": \"" << idn_cases[i].input << "\""; } - IDNSpoofChecker::RestoreTopDomainGraphToDefault(); + IDNSpoofChecker::RestoreTrieParamsForTesting(); } TEST(UrlFormatterTest, FormatUrl) {
diff --git a/components/viz/client/client_resource_provider_unittest.cc b/components/viz/client/client_resource_provider_unittest.cc index e2fd790b2..da03c3c 100644 --- a/components/viz/client/client_resource_provider_unittest.cc +++ b/components/viz/client/client_resource_provider_unittest.cc
@@ -107,7 +107,6 @@ TEST_P(ClientResourceProviderTest, TransferableResourceSendToParent) { MockReleaseCallback release; TransferableResource tran = MakeTransferableResource(use_gpu(), 'a', 15); - tran.buffer_format = gfx::BufferFormat::RGBX_8888; ResourceId id = provider().ImportResource( tran, SingleReleaseCallback::Create(base::BindOnce( &MockReleaseCallback::Released, base::Unretained(&release)))); @@ -132,7 +131,6 @@ EXPECT_EQ(exported[0].mailbox_holder.sync_token, verified_sync_token); EXPECT_EQ(exported[0].mailbox_holder.texture_target, tran.mailbox_holder.texture_target); - EXPECT_EQ(exported[0].buffer_format, tran.buffer_format); // Exported resources are not released when removed, until the export returns. EXPECT_CALL(release, Released(_, _)).Times(0); @@ -182,7 +180,6 @@ EXPECT_EQ(exported[i].mailbox_holder.sync_token, verified_sync_token); EXPECT_EQ(exported[i].mailbox_holder.texture_target, tran[i].mailbox_holder.texture_target); - EXPECT_EQ(exported[i].buffer_format, tran[i].buffer_format); } provider().RemoveImportedResource(id1);
diff --git a/components/viz/common/resources/platform_color.h b/components/viz/common/resources/platform_color.h index 6bf22ad8..28222d8 100644 --- a/components/viz/common/resources/platform_color.h +++ b/components/viz/common/resources/platform_color.h
@@ -69,6 +69,15 @@ case LUMINANCE_F16: case RGBA_F16: case R16_EXT: + case BGR_565: + case RG_88: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: break; }
diff --git a/components/viz/common/resources/platform_color_unittest.cc b/components/viz/common/resources/platform_color_unittest.cc index feab684..ee4bdf4 100644 --- a/components/viz/common/resources/platform_color_unittest.cc +++ b/components/viz/common/resources/platform_color_unittest.cc
@@ -28,12 +28,21 @@ case ALPHA_8: case LUMINANCE_8: case RGB_565: + case BGR_565: case RGBA_4444: case ETC1: case RED_8: + case RG_88: case LUMINANCE_F16: case RGBA_F16: case R16_EXT: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: break; } }
diff --git a/components/viz/common/resources/resource_format.h b/components/viz/common/resources/resource_format.h index 265a064cb..30a75a3 100644 --- a/components/viz/common/resources/resource_format.h +++ b/components/viz/common/resources/resource_format.h
@@ -16,12 +16,21 @@ ALPHA_8, LUMINANCE_8, RGB_565, + BGR_565, ETC1, RED_8, + RG_88, LUMINANCE_F16, RGBA_F16, R16_EXT, - RESOURCE_FORMAT_MAX = R16_EXT, + RGBX_8888, + BGRX_8888, + RGBX_1010102, + BGRX_1010102, + YVU_420, + YUV_420_BIPLANAR, + UYVY_422, + RESOURCE_FORMAT_MAX = UYVY_422, }; } // namespace viz
diff --git a/components/viz/common/resources/resource_format_utils.cc b/components/viz/common/resources/resource_format_utils.cc index dcf5d8d..800ce70c 100644 --- a/components/viz/common/resources/resource_format_utils.cc +++ b/components/viz/common/resources/resource_format_utils.cc
@@ -39,6 +39,15 @@ case RED_8: case LUMINANCE_F16: case R16_EXT: + case BGR_565: + case RG_88: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: return kN32_SkColorType; case RGBA_F16: return kRGBA_F16_SkColorType; @@ -53,12 +62,22 @@ return 64; case BGRA_8888: case RGBA_8888: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: return 32; case RGBA_4444: case RGB_565: case LUMINANCE_F16: case R16_EXT: + case BGR_565: + case RG_88: + case UYVY_422: return 16; + case YVU_420: + case YUV_420_BIPLANAR: + return 12; case ALPHA_8: case LUMINANCE_8: case RED_8: @@ -79,11 +98,20 @@ GL_UNSIGNED_BYTE, // ALPHA_8 GL_UNSIGNED_BYTE, // LUMINANCE_8 GL_UNSIGNED_SHORT_5_6_5, // RGB_565, + GL_ZERO, // BGR_565 GL_UNSIGNED_BYTE, // ETC1 GL_UNSIGNED_BYTE, // RED_8 + GL_UNSIGNED_BYTE, // RG_88 GL_HALF_FLOAT_OES, // LUMINANCE_F16 GL_HALF_FLOAT_OES, // RGBA_F16 GL_UNSIGNED_SHORT, // R16_EXT + GL_UNSIGNED_BYTE, // RGBX_8888 + GL_ZERO, // BGRX_8888 + GL_UNSIGNED_INT, // RGBX_1010102 + GL_ZERO, // BGRX_1010102 + GL_ZERO, // YVU_420 + GL_ZERO, // YUV_420_BIPLANAR + GL_ZERO, // UYVY_422 }; static_assert(arraysize(format_gl_data_type) == (RESOURCE_FORMAT_MAX + 1), "format_gl_data_type does not handle all cases."); @@ -100,14 +128,24 @@ GL_ALPHA, // ALPHA_8 GL_LUMINANCE, // LUMINANCE_8 GL_RGB, // RGB_565 + GL_ZERO, // BGR_565 GL_ETC1_RGB8_OES, // ETC1 GL_RED_EXT, // RED_8 + GL_RG_EXT, // RG_88 GL_LUMINANCE, // LUMINANCE_F16 GL_RGBA, // RGBA_F16 GL_RED_EXT, // R16_EXT + GL_RGB, // RGBX_8888 + GL_ZERO, // BGRX_8888 + GL_RGB10_A2_EXT, // RGBX_1010102 + GL_ZERO, // BGRX_1010102 + GL_ZERO, // YVU_420 + GL_ZERO, // YUV_420_BIPLANAR + GL_ZERO, // UYVY_422 }; static_assert(arraysize(format_gl_data_format) == (RESOURCE_FORMAT_MAX + 1), "format_gl_data_format does not handle all cases."); + return format_gl_data_format[format]; } @@ -118,6 +156,8 @@ // internal format (GL_R16_EXT). if (format == R16_EXT) return GL_R16_EXT; + else if (format == RG_88) + return GL_RG8_EXT; return GLDataFormat(format); } @@ -137,14 +177,25 @@ GL_ALPHA, // ALPHA_8 GL_LUMINANCE, // LUMINANCE_8 GL_RGB, // RGB_565 + GL_ZERO, // BGR_565 GL_RGB, // ETC1 GL_LUMINANCE, // RED_8 + GL_RGBA, // RG_88 GL_LUMINANCE, // LUMINANCE_F16 GL_RGBA, // RGBA_F16 GL_LUMINANCE, // R16_EXT + GL_RGB, // RGBX_8888 + GL_RGB, // BGRX_8888 + GL_ZERO, // RGBX_1010102 + GL_ZERO, // BGRX_1010102 + GL_ZERO, // YVU_420 + GL_ZERO, // YUV_420_BIPLANAR + GL_ZERO, // UYVY_422 }; + static_assert(arraysize(format_gl_data_format) == (RESOURCE_FORMAT_MAX + 1), "format_gl_data_format does not handle all cases."); + return format_gl_data_format[format]; } @@ -164,6 +215,24 @@ return gfx::BufferFormat::ETC1; case RGBA_F16: return gfx::BufferFormat::RGBA_F16; + case BGR_565: + return gfx::BufferFormat::BGR_565; + case RG_88: + return gfx::BufferFormat::RG_88; + case RGBX_8888: + return gfx::BufferFormat::RGBX_8888; + case BGRX_8888: + return gfx::BufferFormat::BGRX_8888; + case RGBX_1010102: + return gfx::BufferFormat::RGBX_1010102; + case BGRX_1010102: + return gfx::BufferFormat::BGRX_1010102; + case YVU_420: + return gfx::BufferFormat::YVU_420; + case YUV_420_BIPLANAR: + return gfx::BufferFormat::YUV_420_BIPLANAR; + case UYVY_422: + return gfx::BufferFormat::UYVY_422; case ALPHA_8: case LUMINANCE_8: case RGB_565: @@ -203,6 +272,16 @@ return GL_R16_EXT; case ETC1: break; + case RG_88: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: + case BGR_565: + break; } NOTREACHED(); return GL_RGBA8_OES; @@ -218,11 +297,21 @@ case ETC1: case RGBA_F16: return true; - // These formats have no BufferFormat equivalent. + // These formats have no BufferFormat equivalent or are only used + // for external textures, or have no GL equivalent formats. case ALPHA_8: case LUMINANCE_8: case RGB_565: case LUMINANCE_F16: + case BGR_565: + case RG_88: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: return false; } NOTREACHED(); @@ -243,10 +332,73 @@ case LUMINANCE_F16: case RGBA_F16: case R16_EXT: + case BGR_565: + case RG_88: + case RGBX_8888: + case BGRX_8888: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: return false; } NOTREACHED(); return false; } +ResourceFormat GetResourceFormat(gfx::BufferFormat format) { + switch (format) { + case gfx::BufferFormat::BGRA_8888: + return BGRA_8888; + case gfx::BufferFormat::R_8: + return RED_8; + case gfx::BufferFormat::R_16: + return R16_EXT; + case gfx::BufferFormat::RGBA_4444: + return RGBA_4444; + case gfx::BufferFormat::RGBA_8888: + return RGBA_8888; + case gfx::BufferFormat::ETC1: + return ETC1; + case gfx::BufferFormat::RGBA_F16: + return RGBA_F16; + case gfx::BufferFormat::BGR_565: + return BGR_565; + case gfx::BufferFormat::RG_88: + return RG_88; + case gfx::BufferFormat::RGBX_8888: + return RGBX_8888; + case gfx::BufferFormat::BGRX_8888: + return BGRX_8888; + case gfx::BufferFormat::RGBX_1010102: + return RGBX_1010102; + case gfx::BufferFormat::BGRX_1010102: + return BGRX_1010102; + case gfx::BufferFormat::YVU_420: + return YVU_420; + case gfx::BufferFormat::YUV_420_BIPLANAR: + return YUV_420_BIPLANAR; + case gfx::BufferFormat::UYVY_422: + return UYVY_422; + default: + NOTREACHED(); + return RGBA_8888; + } +} + +bool GLSupportsFormat(ResourceFormat format) { + switch (format) { + case BGR_565: + case BGRX_8888: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case UYVY_422: + return false; + default: + return true; + } +} + } // namespace viz
diff --git a/components/viz/common/resources/resource_format_utils.h b/components/viz/common/resources/resource_format_utils.h index 27957f6..1b7cf81 100644 --- a/components/viz/common/resources/resource_format_utils.h +++ b/components/viz/common/resources/resource_format_utils.h
@@ -47,6 +47,11 @@ // display compositor. VIZ_RESOURCE_FORMAT_EXPORT bool IsBitmapFormatSupported(ResourceFormat format); +VIZ_RESOURCE_FORMAT_EXPORT ResourceFormat +GetResourceFormat(gfx::BufferFormat format); + +VIZ_RESOURCE_FORMAT_EXPORT bool GLSupportsFormat(ResourceFormat format); + } // namespace viz #endif // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_
diff --git a/components/viz/common/resources/transferable_resource.h b/components/viz/common/resources/transferable_resource.h index 76f673e..d39240a 100644 --- a/components/viz/common/resources/transferable_resource.h +++ b/components/viz/common/resources/transferable_resource.h
@@ -97,11 +97,6 @@ // and must be RGBA_8888 always for software resources. ResourceFormat format = RGBA_8888; - // Normally derrived from the |format|, but may differ for some resource - // producers. This is the format of the underlying texture backing for gpu - // resources, needed for using the backing as an overlay. - gfx::BufferFormat buffer_format = gfx::BufferFormat::RGBA_8888; - // The |mailbox| inside here holds the gpu::Mailbox when this is a gpu // resource, or the SharedBitmapId when it is a software resource. // The |texture_target| and sync_token| inside here only apply for gpu @@ -139,7 +134,7 @@ bool operator==(const TransferableResource& o) const { return id == o.id && is_software == o.is_software && size == o.size && - format == o.format && buffer_format == o.buffer_format && + format == o.format && mailbox_holder.mailbox == o.mailbox_holder.mailbox && mailbox_holder.sync_token == o.mailbox_holder.sync_token && mailbox_holder.texture_target == o.mailbox_holder.texture_target &&
diff --git a/components/viz/service/display/display_resource_provider.cc b/components/viz/service/display/display_resource_provider.cc index bfc531e9..da2cff4 100644 --- a/components/viz/service/display/display_resource_provider.cc +++ b/components/viz/service/display/display_resource_provider.cc
@@ -239,7 +239,7 @@ gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(ResourceId id) { ChildResource* resource = GetResource(id); - return resource->transferable.buffer_format; + return BufferFormat(resource->transferable.format); } void DisplayResourceProvider::WaitSyncToken(ResourceId id) {
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 51e9fba..f0af92a3 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -757,10 +757,13 @@ // texture. Otherwise, we use the format of the default framebuffer. But // whatever the format is, convert it to a valid format for CopyTexSubImage2D. GLenum format; - if (!current_framebuffer_texture_) + if (!current_framebuffer_texture_) { format = output_surface_->GetFramebufferCopyTextureFormat(); - else - format = GLCopyTextureInternalFormat(BackbufferFormat()); + } else { + ResourceFormat resource_format = BackbufferFormat(); + DCHECK(GLSupportsFormat(resource_format)); + format = GLCopyTextureInternalFormat(resource_format); + } // Verify the format is valid for GLES2's glCopyTexSubImage2D. DCHECK(format == GL_ALPHA || format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_RGB ||
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 6d5d4d653..50933bb 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -102,11 +102,6 @@ mailbox, GL_LINEAR, allocation.texture_target, sync_token); gl_resource.size = size; gl_resource.format = format; - // We didn't allocate a GpuMemoryBuffer, but we want to set buffer_format for - // consistency with other callsites. - // TODO(piman): See if we can remove TransferableResource::buffer_format - // altogether, it looks redundant with format. crbug.com/836488 - gl_resource.buffer_format = BufferFormat(format); gl_resource.color_space = std::move(color_space); auto release_callback = SingleReleaseCallback::Create(base::BindOnce( &DeleteTexture, std::move(context_provider), allocation.texture_id));
diff --git a/components/viz/service/display/scoped_render_pass_texture.cc b/components/viz/service/display/scoped_render_pass_texture.cc index 1357cc2..7f69f85d 100644 --- a/components/viz/service/display/scoped_render_pass_texture.cc +++ b/components/viz/service/display/scoped_render_pass_texture.cc
@@ -52,6 +52,7 @@ gl->TexStorage2DEXT(GL_TEXTURE_2D, levels, TextureStorageFormat(format), size_.width(), size_.height()); } else { + DCHECK(GLSupportsFormat(format)); gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format), size_.width(), size_.height(), 0, GLDataFormat(format), GLDataType(format), nullptr);
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 1db2a5ce..2cfe760 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -673,9 +673,8 @@ delegate_->AccessibilityPerformAction(action_data); } -void BrowserAccessibilityManager::SetValue( - const BrowserAccessibility& node, - const base::string16& value) { +void BrowserAccessibilityManager::SetValue(const BrowserAccessibility& node, + const std::string& value) { if (!delegate_) return;
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 2a38e931..6279fdbe 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <string> #include <vector> #include "base/callback_forward.h" @@ -218,8 +219,7 @@ void SetAccessibilityFocus(const BrowserAccessibility& node); void SetFocus(const BrowserAccessibility& node); void SetScrollOffset(const BrowserAccessibility& node, gfx::Point offset); - void SetValue( - const BrowserAccessibility& node, const base::string16& value); + void SetValue(const BrowserAccessibility& node, const std::string& value); void SetSelection( ui::AXRange< BrowserAccessibilityPosition::AXPositionInstance::element_type>
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index c1be0a5d..ee2bfb2 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -855,7 +855,7 @@ BrowserAccessibilityAndroid* node = GetAXFromUniqueID(unique_id); if (node) { node->manager()->SetValue( - *node, base::android::ConvertJavaStringToUTF16(env, value)); + *node, base::android::ConvertJavaStringToUTF8(env, value)); } } @@ -909,7 +909,7 @@ value += (increment ? delta : -delta); value = std::max(std::min(value, max), min); if (value != original_value) { - node->manager()->SetValue(*node, base::NumberToString16(value)); + node->manager()->SetValue(*node, base::NumberToString(value)); return true; } return false;
diff --git a/content/browser/frame_host/render_frame_host_android.cc b/content/browser/frame_host/render_frame_host_android.cc index 8ef7214..63de23c 100644 --- a/content/browser/frame_host/render_frame_host_android.cc +++ b/content/browser/frame_host/render_frame_host_android.cc
@@ -4,6 +4,8 @@ #include "content/browser/frame_host/render_frame_host_android.h" +#include <utility> + #include "base/android/callback_android.h" #include "base/android/jni_string.h" #include "base/android/unguessable_token_android.h" @@ -28,12 +30,12 @@ const base::android::JavaRef<jobject>& jcallback, const base::Optional<GURL>& url) { if (!url) { - base::android::RunCallbackAndroid(jcallback, ScopedJavaLocalRef<jstring>()); + base::android::RunObjectCallbackAndroid(jcallback, + ScopedJavaLocalRef<jstring>()); return; } - base::android::RunCallbackAndroid( - jcallback, ConvertUTF8ToJavaString(AttachCurrentThread(), url->spec())); + base::android::RunStringCallbackAndroid(jcallback, url->spec()); } } // namespace
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index e544215..f65dc57 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -623,27 +623,12 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) { ResourceRequestInfoImpl* info = loader->GetRequestInfo(); - base::TimeDelta request_loading_time(base::TimeTicks::Now() - - loader->request()->creation_time()); - // Record final result of all resource loads. if (info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME) { // This enumeration has "3" appended to its name to distinguish it from // older versions. base::UmaHistogramSparse("Net.ErrorCodesForMainFrame3", -loader->request()->status().error()); - if (loader->request()->status().error() == net::OK) { - UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2Success.MainFrame", - request_loading_time); - } - if (loader->request()->status().error() == net::ERR_ABORTED) { - UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.SentBytes", - loader->request()->GetTotalSentBytes(), 1, - 50000000, 50); - UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.ReceivedBytes", - loader->request()->GetTotalReceivedBytes(), 1, - 50000000, 50); - } if (loader->request()->url().SchemeIsCryptographic()) { if (loader->request()->url().host_piece() == "www.google.com") { @@ -664,10 +649,6 @@ "Net.CertificateTransparency.MainFrameValidSCTCount", num_valid_scts); } } else { - if (loader->request()->status().error() == net::OK) { - UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2Success.Subresource", - request_loading_time); - } if (info->GetResourceType() == RESOURCE_TYPE_IMAGE) { base::UmaHistogramSparse("Net.ErrorCodesForImages", -loader->request()->status().error());
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 95eaa9c..4e4d681 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -630,8 +630,6 @@ request_->SetResponseHeadersCallback(base::Bind( &ResourceLoader::SetRawResponseHeaders, base::Unretained(this))); } - UMA_HISTOGRAM_TIMES("Net.ResourceLoader.TimeToURLRequestStart", - base::TimeTicks::Now() - request_->creation_time()); request_->Start(); delegate_->DidStartRequest(this);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index baa1e6f..1a60e3cd 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -397,7 +397,6 @@ bool SynchronizeVisualProperties() override; // AcceleratedWidgetMacNSView implementation. - NSView* AcceleratedWidgetGetNSView() const override; void AcceleratedWidgetCALayerParamsUpdated() override; void SetShowingContextMenu(bool showing) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index f0db8b5e..acb6a0f9 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -110,10 +110,6 @@ //////////////////////////////////////////////////////////////////////////////// // AcceleratedWidgetMacNSView, public: -NSView* RenderWidgetHostViewMac::AcceleratedWidgetGetNSView() const { - return cocoa_view(); -} - void RenderWidgetHostViewMac::AcceleratedWidgetCALayerParamsUpdated() { // Set the background color for the root layer from the frame that just // swapped. See RenderWidgetHostViewAura for more details. Note that this is
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 3e729fc..6b5e05d 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -610,7 +610,7 @@ // Enables developers to use the CSS safe-area-* and viewport-fit APIs which // allow them to support devices with a display cutout. const base::Feature kDisplayCutoutAPI{"DisplayCutoutAPI", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables hiding incorrectly-sized frames while in fullscreen. const base::Feature kHideIncorrectlySizedFullscreenFrames{
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index bf2d709..8de7792 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -652,7 +652,7 @@ target.SetSequentialFocusNavigationStartingPoint(); break; case ax::mojom::Action::kSetValue: - target.SetValue(blink::WebString::FromUTF16(data.value)); + target.SetValue(blink::WebString::FromUTF8(data.value)); HandleAXEvent(target, ax::mojom::Event::kValueChanged); break; case ax::mojom::Action::kShowContextMenu:
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn index 4e31cb1..e12421d 100644 --- a/device/fido/BUILD.gn +++ b/device/fido/BUILD.gn
@@ -110,6 +110,8 @@ "u2f_register_operation.h", "u2f_sign_operation.cc", "u2f_sign_operation.h", + "virtual_ctap2_device.cc", + "virtual_ctap2_device.h", "virtual_fido_device.cc", "virtual_fido_device.h", "virtual_u2f_device.cc",
diff --git a/device/fido/authenticator_get_info_response.cc b/device/fido/authenticator_get_info_response.cc index 67e5478..37de6493 100644 --- a/device/fido/authenticator_get_info_response.cc +++ b/device/fido/authenticator_get_info_response.cc
@@ -8,6 +8,7 @@ #include "components/cbor/cbor_values.h" #include "components/cbor/cbor_writer.h" +#include "device/fido/fido_parsing_utils.h" namespace device { @@ -26,8 +27,9 @@ AuthenticatorGetInfoResponse::AuthenticatorGetInfoResponse( base::flat_set<ProtocolVersion> versions, - std::vector<uint8_t> aaguid) - : versions_(std::move(versions)), aaguid_(std::move(aaguid)) {} + base::span<const uint8_t, kAaguidLength> aaguid) + : versions_(std::move(versions)), + aaguid_(fido_parsing_utils::Materialize(aaguid)) {} AuthenticatorGetInfoResponse::AuthenticatorGetInfoResponse( AuthenticatorGetInfoResponse&& that) = default;
diff --git a/device/fido/authenticator_get_info_response.h b/device/fido/authenticator_get_info_response.h index 46dee88..b6fd9b1 100644 --- a/device/fido/authenticator_get_info_response.h +++ b/device/fido/authenticator_get_info_response.h
@@ -26,7 +26,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorGetInfoResponse { public: AuthenticatorGetInfoResponse(base::flat_set<ProtocolVersion> versions, - std::vector<uint8_t> aaguid); + base::span<const uint8_t, kAaguidLength> aaguid); AuthenticatorGetInfoResponse(AuthenticatorGetInfoResponse&& that); AuthenticatorGetInfoResponse& operator=(AuthenticatorGetInfoResponse&& other); ~AuthenticatorGetInfoResponse(); @@ -40,7 +40,7 @@ AuthenticatorSupportedOptions options); const base::flat_set<ProtocolVersion>& versions() const { return versions_; } - const std::vector<uint8_t>& aaguid() const { return aaguid_; } + const std::array<uint8_t, kAaguidLength>& aaguid() const { return aaguid_; } const base::Optional<uint32_t>& max_msg_size() const { return max_msg_size_; } const base::Optional<std::vector<uint8_t>>& pin_protocol() const { return pin_protocols_; @@ -52,7 +52,7 @@ private: base::flat_set<ProtocolVersion> versions_; - std::vector<uint8_t> aaguid_; + std::array<uint8_t, kAaguidLength> aaguid_; base::Optional<uint32_t> max_msg_size_; base::Optional<std::vector<uint8_t>> pin_protocols_; base::Optional<std::vector<std::string>> extensions_;
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h index 556b55466..3b43491 100644 --- a/device/fido/ctap_make_credential_request.h +++ b/device/fido/ctap_make_credential_request.h
@@ -70,6 +70,9 @@ exclude_list() const { return exclude_list_; } + const base::Optional<std::vector<uint8_t>>& pin_auth() const { + return pin_auth_; + } private: std::array<uint8_t, kClientDataHashLength> client_data_hash_;
diff --git a/device/fido/ctap_response_unittest.cc b/device/fido/ctap_response_unittest.cc index 2d8e23b..567ac36 100644 --- a/device/fido/ctap_response_unittest.cc +++ b/device/fido/ctap_response_unittest.cc
@@ -198,9 +198,9 @@ // and test_data::kTestECPublicKeyCOSE. 0x58, 0xC4}; -constexpr uint8_t kTestDeviceAaguid[] = {0xF8, 0xA0, 0x11, 0xF3, 0x8C, 0x0A, - 0x4D, 0x15, 0x80, 0x06, 0x17, 0x11, - 0x1F, 0x9E, 0xDC, 0x7D}; +constexpr std::array<uint8_t, kAaguidLength> kTestDeviceAaguid = { + {0xF8, 0xA0, 0x11, 0xF3, 0x8C, 0x0A, 0x4D, 0x15, 0x80, 0x06, 0x17, 0x11, + 0x1F, 0x9E, 0xDC, 0x7D}}; std::vector<uint8_t> GetTestAttestedCredentialDataBytes() { // Combine kTestAttestedCredentialDataPrefix and kTestECPublicKeyCOSE.
diff --git a/device/fido/make_credential_task_unittest.cc b/device/fido/make_credential_task_unittest.cc index fa504c5..b97aa9b 100644 --- a/device/fido/make_credential_task_unittest.cc +++ b/device/fido/make_credential_task_unittest.cc
@@ -20,6 +20,7 @@ #include "device/fido/make_credential_task.h" #include "device/fido/mock_fido_device.h" #include "device/fido/test_callback_receiver.h" +#include "device/fido/virtual_ctap2_device.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -107,6 +108,21 @@ EXPECT_TRUE(device->device_info()); } +TEST_F(FidoMakeCredentialTaskTest, TestRegisterSuccessWithFake) { + auto device = std::make_unique<VirtualCtap2Device>(); + const auto task = CreateMakeCredentialTask(device.get()); + make_credential_callback_receiver().WaitForCallback(); + + EXPECT_EQ(CtapDeviceResponseCode::kSuccess, + make_credential_callback_receiver().status()); + + // We don't verify the response from the fake, but do a quick sanity check. + ASSERT_TRUE(make_credential_callback_receiver().value()); + EXPECT_EQ( + 32u, + make_credential_callback_receiver().value()->raw_credential_id().size()); +} + TEST_F(FidoMakeCredentialTaskTest, MakeCredentialWithIncorrectRpIdHash) { auto device = std::make_unique<MockFidoDevice>();
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc new file mode 100644 index 0000000..da36e42b --- /dev/null +++ b/device/fido/virtual_ctap2_device.cc
@@ -0,0 +1,278 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/fido/virtual_ctap2_device.h" + +#include <array> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/numerics/safe_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/cbor/cbor_writer.h" +#include "crypto/ec_private_key.h" +#include "device/fido/authenticator_make_credential_response.h" +#include "device/fido/ctap_make_credential_request.h" +#include "device/fido/ec_public_key.h" +#include "device/fido/fido_constants.h" +#include "device/fido/fido_parsing_utils.h" +#include "device/fido/opaque_attestation_statement.h" + +namespace device { + +namespace { + +constexpr std::array<uint8_t, kAaguidLength> kDeviceAaguid = { + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08}}; + +std::vector<uint8_t> ConstructResponse(CtapDeviceResponseCode response_code, + base::span<const uint8_t> data) { + std::vector<uint8_t> response{base::strict_cast<uint8_t>(response_code)}; + fido_parsing_utils::Append(&response, data); + return response; +} + +void ReturnCtap2Response( + FidoDevice::DeviceCallback cb, + CtapDeviceResponseCode response_code, + base::Optional<base::span<const uint8_t>> data = base::nullopt) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(cb), + ConstructResponse(response_code, + data.value_or(std::vector<uint8_t>{})))); +} + +bool AreMakeCredentialOptionsValid(const AuthenticatorSupportedOptions& options, + const CtapMakeCredentialRequest& request) { + if (request.resident_key_supported() && !options.supports_resident_key()) + return false; + + return !request.user_verification_required() || + options.user_verification_availability() == + AuthenticatorSupportedOptions::UserVerificationAvailability:: + kSupportedAndConfigured; +} + +// Checks that whether the received MakeCredential request includes EA256 +// algorithm in publicKeyCredParam. +bool AreMakeCredentialParamsValid(const CtapMakeCredentialRequest& request) { + const auto& params = + request.public_key_credential_params().public_key_credential_params(); + return std::any_of( + params.begin(), params.end(), [](const auto& credential_info) { + return credential_info.algorithm == + base::strict_cast<int>(CoseAlgorithmIdentifier::kCoseEs256); + }); +} + +std::unique_ptr<ECPublicKey> ConstructECPublicKey( + std::string public_key_string) { + DCHECK_EQ(64u, public_key_string.size()); + + const auto public_key_x_coordinate = + base::as_bytes(base::make_span(public_key_string)).first(32); + const auto public_key_y_coordinate = + base::as_bytes(base::make_span(public_key_string)).last(32); + return std::make_unique<ECPublicKey>( + fido_parsing_utils::kEs256, + fido_parsing_utils::Materialize(public_key_x_coordinate), + fido_parsing_utils::Materialize(public_key_y_coordinate)); +} + +std::vector<uint8_t> ConstructSignatureBuffer( + const AuthenticatorData& authenticator_data, + base::span<const uint8_t, kClientDataHashLength> client_data_hash) { + std::vector<uint8_t> signature_buffer; + fido_parsing_utils::Append(&signature_buffer, + authenticator_data.SerializeToByteArray()); + fido_parsing_utils::Append(&signature_buffer, client_data_hash); + return signature_buffer; +} + +std::vector<uint8_t> ConstructMakeCredentialResponse( + base::span<const uint8_t> attestation_certificate, + base::span<const uint8_t> signature, + AuthenticatorData authenticator_data) { + cbor::CBORValue::MapValue attestation_map; + attestation_map.emplace("alg", -7); + attestation_map.emplace("sig", fido_parsing_utils::Materialize(signature)); + + cbor::CBORValue::ArrayValue certificate_chain; + certificate_chain.emplace_back( + fido_parsing_utils::Materialize(attestation_certificate)); + attestation_map.emplace("x5c", std::move(certificate_chain)); + AuthenticatorMakeCredentialResponse make_credential_response( + AttestationObject( + std::move(authenticator_data), + std::make_unique<OpaqueAttestationStatement>( + "packed", cbor::CBORValue(std::move(attestation_map))))); + return GetSerializedCtapDeviceResponse(make_credential_response); +} + +} // namespace + +VirtualCtap2Device::VirtualCtap2Device() + : VirtualFidoDevice(), + device_info_(AuthenticatorGetInfoResponse({ProtocolVersion::kCtap}, + kDeviceAaguid)), + weak_factory_(this) {} + +VirtualCtap2Device::VirtualCtap2Device(scoped_refptr<State> state) + : VirtualFidoDevice(std::move(state)), + device_info_(AuthenticatorGetInfoResponse({ProtocolVersion::kCtap}, + kDeviceAaguid)), + weak_factory_(this) {} + +VirtualCtap2Device::~VirtualCtap2Device() = default; + +// As all operations for VirtualCtap2Device are synchronous and we do not wait +// for user touch, Cancel command is no-op. +void VirtualCtap2Device::Cancel() {} + +void VirtualCtap2Device::DeviceTransact(std::vector<uint8_t> command, + DeviceCallback cb) { + if (command.empty()) { + ReturnCtap2Response(std::move(cb), CtapDeviceResponseCode::kCtap2ErrOther); + return; + } + + auto cmd_type = command[0]; + const auto request_bytes = base::make_span(command).subspan(1); + CtapDeviceResponseCode response_code = CtapDeviceResponseCode::kCtap2ErrOther; + std::vector<uint8_t> response_data; + + switch (static_cast<CtapRequestCommand>(cmd_type)) { + case CtapRequestCommand::kAuthenticatorGetInfo: + if (!request_bytes.empty()) { + ReturnCtap2Response(std::move(cb), + CtapDeviceResponseCode::kCtap2ErrOther); + return; + } + + response_code = OnAuthenticatorGetInfo(&response_data); + break; + case CtapRequestCommand::kAuthenticatorMakeCredential: + response_code = OnMakeCredential(request_bytes, &response_data); + break; + default: + break; + } + + // Call |callback| via the |MessageLoop| because |AuthenticatorImpl| doesn't + // support callback hairpinning. + ReturnCtap2Response(std::move(cb), response_code, std::move(response_data)); +} + +base::WeakPtr<FidoDevice> VirtualCtap2Device::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void VirtualCtap2Device::SetAuthenticatorSupportedOptions( + AuthenticatorSupportedOptions options) { + device_info_.SetOptions(std::move(options)); +} + +CtapDeviceResponseCode VirtualCtap2Device::OnMakeCredential( + base::span<const uint8_t> request_bytes, + std::vector<uint8_t>* response) { + auto request = ParseCtapMakeCredentialRequest(request_bytes); + if (!request) + return CtapDeviceResponseCode::kCtap2ErrOther; + + if (!AreMakeCredentialOptionsValid(device_info_.options(), *request) || + !AreMakeCredentialParamsValid(*request)) { + return CtapDeviceResponseCode::kCtap2ErrOther; + } + + // Client pin is not supported. + if (request->pin_auth()) + return CtapDeviceResponseCode::kCtap2ErrPinInvalid; + + // Check for already registered credentials. + const auto rp_id_hash = + fido_parsing_utils::CreateSHA256Hash(request->rp().rp_id()); + if (request->exclude_list()) { + for (const auto& excluded_credential : *request->exclude_list()) { + if (FindRegistrationData(excluded_credential.id(), rp_id_hash)) + return CtapDeviceResponseCode::kCtap2ErrCredentialExcluded; + } + } + + // Create key to register. + // Note: Non-deterministic, you need to mock this out if you rely on + // deterministic behavior. + auto private_key = crypto::ECPrivateKey::Create(); + std::string public_key; + bool status = private_key->ExportRawPublicKey(&public_key); + DCHECK(status); + + // Our key handles are simple hashes of the public key. + auto hash = fido_parsing_utils::CreateSHA256Hash(public_key); + std::vector<uint8_t> key_handle(hash.begin(), hash.end()); + + AttestedCredentialData attested_credential_data( + kDeviceAaguid, {{0, crypto::kSHA256Length}}, key_handle, + ConstructECPublicKey(public_key)); + + auto authenticator_data = ConstructAuthenticatorData( + rp_id_hash, std::move(attested_credential_data)); + auto sign_buffer = + ConstructSignatureBuffer(authenticator_data, request->client_data_hash()); + + // Sign with attestation key. + // Note: Non-deterministic, you need to mock this out if you rely on + // deterministic behavior. + std::vector<uint8_t> sig; + std::unique_ptr<crypto::ECPrivateKey> attestation_private_key = + crypto::ECPrivateKey::CreateFromPrivateKeyInfo(GetAttestationKey()); + status = Sign(attestation_private_key.get(), std::move(sign_buffer), &sig); + DCHECK(status); + + auto attestation_cert = GenerateAttestationCertificate( + false /* individual_attestation_requested */); + if (!attestation_cert) + return CtapDeviceResponseCode::kCtap2ErrOther; + + *response = ConstructMakeCredentialResponse(std::move(*attestation_cert), sig, + std::move(authenticator_data)); + + StoreNewKey(rp_id_hash, key_handle, std::move(private_key)); + return CtapDeviceResponseCode::kSuccess; +} + +CtapDeviceResponseCode VirtualCtap2Device::OnAuthenticatorGetInfo( + std::vector<uint8_t>* response) const { + *response = EncodeToCBOR(device_info_); + return CtapDeviceResponseCode::kSuccess; +} + +AuthenticatorData VirtualCtap2Device::ConstructAuthenticatorData( + base::span<const uint8_t, kRpIdHashLength> rp_id_hash, + base::Optional<AttestedCredentialData> attested_credential_data) { + uint8_t flag = + base::strict_cast<uint8_t>(AuthenticatorData::Flag::kTestOfUserPresence); + std::array<uint8_t, kSignCounterLength> signature_counter; + + // Constructing AuthenticatorData for registration operation. + if (attested_credential_data) { + flag |= base::strict_cast<uint8_t>(AuthenticatorData::Flag::kAttestation); + signature_counter = {{0x00, 0x00, 0x00, 0x01}}; + // Constructing AuthenticatorData for sign operation. + } else { + auto* registration_data = FindRegistrationData( + attested_credential_data->credential_id(), rp_id_hash); + signature_counter[0] = (registration_data->counter >> 24) & 0xff; + signature_counter[1] = (registration_data->counter >> 16) & 0xff; + signature_counter[2] = (registration_data->counter >> 8) & 0xff; + signature_counter[3] = (registration_data->counter) & 0xff; + } + + return AuthenticatorData(rp_id_hash, flag, signature_counter, + std::move(attested_credential_data)); +} + +} // namespace device
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h new file mode 100644 index 0000000..7808b85 --- /dev/null +++ b/device/fido/virtual_ctap2_device.h
@@ -0,0 +1,59 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_FIDO_VIRTUAL_CTAP2_DEVICE_H_ +#define DEVICE_FIDO_VIRTUAL_CTAP2_DEVICE_H_ + +#include <stdint.h> + +#include <memory> +#include <vector> + +#include "base/component_export.h" +#include "base/containers/span.h" +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/optional.h" +#include "device/fido/attested_credential_data.h" +#include "device/fido/authenticator_data.h" +#include "device/fido/authenticator_supported_options.h" +#include "device/fido/fido_constants.h" +#include "device/fido/virtual_fido_device.h" + +namespace device { + +class COMPONENT_EXPORT(DEVICE_FIDO) VirtualCtap2Device + : public VirtualFidoDevice { + public: + VirtualCtap2Device(); + explicit VirtualCtap2Device(scoped_refptr<State> state); + ~VirtualCtap2Device() override; + + // FidoDevice: + void Cancel() override; + void DeviceTransact(std::vector<uint8_t> command, DeviceCallback cb) override; + base::WeakPtr<FidoDevice> GetWeakPtr() override; + + void SetAuthenticatorSupportedOptions(AuthenticatorSupportedOptions options); + + private: + CtapDeviceResponseCode OnMakeCredential(base::span<const uint8_t> request, + std::vector<uint8_t>* response); + + CtapDeviceResponseCode OnAuthenticatorGetInfo( + std::vector<uint8_t>* response) const; + + AuthenticatorData ConstructAuthenticatorData( + base::span<const uint8_t, kRpIdHashLength> rp_id_hash, + base::Optional<AttestedCredentialData> attested_credential_data); + + AuthenticatorGetInfoResponse device_info_; + base::WeakPtrFactory<FidoDevice> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(VirtualCtap2Device); +}; + +} // namespace device + +#endif // DEVICE_FIDO_VIRTUAL_CTAP2_DEVICE_H_
diff --git a/device/fido/virtual_fido_device.cc b/device/fido/virtual_fido_device.cc index fc73cbd1..06c5dac 100644 --- a/device/fido/virtual_fido_device.cc +++ b/device/fido/virtual_fido_device.cc
@@ -7,7 +7,6 @@ #include <tuple> #include <utility> -#include "crypto/ec_private_key.h" #include "crypto/ec_signature_creator.h" #include "device/fido/fido_parsing_utils.h" @@ -122,6 +121,34 @@ return std::vector<uint8_t>(attestation_cert.begin(), attestation_cert.end()); } +void VirtualFidoDevice::StoreNewKey( + base::span<const uint8_t, kRpIdHashLength> application_parameter, + base::span<const uint8_t> key_handle, + std::unique_ptr<crypto::ECPrivateKey> private_key) { + // Store the registration. Because the key handle is the hashed public key we + // just generated, no way this should already be registered. + bool did_insert = false; + std::tie(std::ignore, did_insert) = mutable_state()->registrations.emplace( + fido_parsing_utils::Materialize(key_handle), + RegistrationData(std::move(private_key), application_parameter, 1)); + DCHECK(did_insert); +} + +VirtualFidoDevice::RegistrationData* VirtualFidoDevice::FindRegistrationData( + base::span<const uint8_t> key_handle, + base::span<const uint8_t, kRpIdHashLength> application_parameter) { + // Check if this is our key_handle and it's for this appId. + auto it = mutable_state()->registrations.find(key_handle); + if (it == mutable_state()->registrations.end()) + return nullptr; + + if (application_parameter != + base::make_span(it->second.application_parameter)) + return nullptr; + + return &(it->second); +} + void VirtualFidoDevice::TryWink(WinkCallback cb) { std::move(cb).Run(); }
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h index e4ae439..92ad511e 100644 --- a/device/fido/virtual_fido_device.h +++ b/device/fido/virtual_fido_device.h
@@ -18,6 +18,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/optional.h" +#include "crypto/ec_private_key.h" #include "device/fido/fido_constants.h" #include "device/fido/fido_device.h" #include "device/fido/fido_parsing_utils.h" @@ -120,6 +121,15 @@ base::Optional<std::vector<uint8_t>> GenerateAttestationCertificate( bool individual_attestation_requested) const; + void StoreNewKey( + base::span<const uint8_t, kRpIdHashLength> application_parameter, + base::span<const uint8_t> key_handle, + std::unique_ptr<crypto::ECPrivateKey> private_key); + + RegistrationData* FindRegistrationData( + base::span<const uint8_t> key_handle, + base::span<const uint8_t, kRpIdHashLength> application_parameter); + // FidoDevice: void TryWink(WinkCallback cb) override; std::string GetId() const override;
diff --git a/device/fido/virtual_u2f_device.cc b/device/fido/virtual_u2f_device.cc index c39e67c..be3f07c0 100644 --- a/device/fido/virtual_u2f_device.cc +++ b/device/fido/virtual_u2f_device.cc
@@ -176,14 +176,7 @@ Append(&response, *attestation_cert); Append(&response, sig); - // Store the registration. Because the key handle is the hashed public key we - // just generated, no way this should already be registered. - bool did_insert = false; - std::tie(std::ignore, did_insert) = mutable_state()->registrations.emplace( - std::move(key_handle), - RegistrationData(std::move(private_key), application_parameter, 1)); - DCHECK(did_insert); - + StoreNewKey(application_parameter, key_handle, std::move(private_key)); return apdu::ApduResponse(std::move(response), apdu::ApduResponse::Status::SW_NO_ERROR) .GetEncodedResponse(); @@ -204,42 +197,29 @@ mutable_state()->simulate_press_callback.Run(); } - if (data.size() < 32 + 32 + 1) { + if (data.size() < 32 + 32 + 1) return ErrorStatus(apdu::ApduResponse::Status::SW_WRONG_LENGTH); - } auto challenge_param = data.first<32>(); auto application_parameter = data.subspan<32, 32>(); size_t key_handle_length = data[64]; - if (data.size() != 32 + 32 + 1 + key_handle_length) { + if (data.size() != 32 + 32 + 1 + key_handle_length) return ErrorStatus(apdu::ApduResponse::Status::SW_WRONG_LENGTH); - } + auto key_handle = data.last(key_handle_length); - - // Check if this is our key_handle and it's for this appId. - auto it = mutable_state()->registrations.find(key_handle); - if (it == mutable_state()->registrations.end()) { + auto* registration = FindRegistrationData(key_handle, application_parameter); + if (!registration) return ErrorStatus(apdu::ApduResponse::Status::SW_WRONG_DATA); - } - base::span<const uint8_t> registered_app_id_hash = - base::make_span(it->second.application_parameter); - if (application_parameter != registered_app_id_hash) { - // It's important this error looks identical to the previous one, as - // tokens should not reveal the existence of keyHandles to unrelated appIds. - return ErrorStatus(apdu::ApduResponse::Status::SW_WRONG_DATA); - } - - auto& registration = it->second; - ++registration.counter; + ++registration->counter; // First create the part of the response that gets signed over. std::vector<uint8_t> response; response.push_back(0x01); // Always pretend we got a touch. - response.push_back(registration.counter >> 24); - response.push_back(registration.counter >> 16); - response.push_back(registration.counter >> 8); - response.push_back(registration.counter); + response.push_back(registration->counter >> 24); + response.push_back(registration->counter >> 16); + response.push_back(registration->counter >> 8); + response.push_back(registration->counter); std::vector<uint8_t> sign_buffer; sign_buffer.reserve(application_parameter.size() + response.size() + @@ -250,7 +230,7 @@ // Sign with credential key. std::vector<uint8_t> sig; - bool status = Sign(registration.private_key.get(), sign_buffer, &sig); + bool status = Sign(registration->private_key.get(), sign_buffer, &sig); DCHECK(status); // Add signature for full response.
diff --git a/docs/clang_tool_refactoring.md b/docs/clang_tool_refactoring.md index b23d8d85..107ff8e 100644 --- a/docs/clang_tool_refactoring.md +++ b/docs/clang_tool_refactoring.md
@@ -123,9 +123,9 @@ ninja -d keeprsp -C out/Debug # For Windows # experimental alternative: -$gen_targets = $(ninja -C out/gn -t targets all \ +$gen_targets = $(ninja -C out/Debug -t targets all \ | grep '^gen/[^: ]*\.[ch][pc]*:' \ - | cut -f 1 -d :`) + | cut -f 1 -d :) ninja -C out/Debug $gen_targets ``` @@ -150,7 +150,7 @@ ```shell tools/clang/scripts/run_tool.py --tool empty_string \ - --generated-compdb \ + --generate-compdb \ -p out/Debug net >/tmp/list-of-edits.debug ```
diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc index b496d90..5760745 100644 --- a/extensions/common/permissions/permissions_data.cc +++ b/extensions/common/permissions/permissions_data.cc
@@ -309,14 +309,6 @@ manifest_type_)); } -bool PermissionsData::HasWithheldImpliedAllHosts() const { - base::AutoLock auto_lock(runtime_lock_); - // Since we currently only withhold all_hosts, it's sufficient to check - // that either set is not empty. - return !withheld_permissions_unsafe_->explicit_hosts().is_empty() || - !withheld_permissions_unsafe_->scriptable_hosts().is_empty(); -} - bool PermissionsData::CanAccessPage(const GURL& document_url, int tab_id, std::string* error) const {
diff --git a/extensions/common/permissions/permissions_data.h b/extensions/common/permissions/permissions_data.h index 265d2e8..68cba77 100644 --- a/extensions/common/permissions/permissions_data.h +++ b/extensions/common/permissions/permissions_data.h
@@ -176,10 +176,6 @@ PermissionMessages GetNewPermissionMessages( const PermissionSet& granted_permissions) const; - // Returns true if the extension has requested all-hosts permissions (or - // something close to it), but has had it withheld. - bool HasWithheldImpliedAllHosts() const; - // Returns true if the associated extension has permission to access and // interact with the specified page, in order to do things like inject // scripts or modify the content.
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 8221c4c..10b3292 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -663,7 +663,7 @@ 'GL_PIXEL_PACK_BUFFER', ], }, - 'FramebufferParameter': { + 'FramebufferAttachmentParameter': { 'type': 'GLenum', 'valid': [ 'GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE',
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 018ebeb..b90e63c 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -964,12 +964,12 @@ GLint* params) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); - GPU_CLIENT_LOG("[" << GetLogPrefix() - << "] glGetFramebufferAttachmentParameteriv(" - << GLES2Util::GetStringFramebufferTarget(target) << ", " - << GLES2Util::GetStringAttachmentQuery(attachment) << ", " - << GLES2Util::GetStringFramebufferParameter(pname) << ", " - << static_cast<const void*>(params) << ")"); + GPU_CLIENT_LOG( + "[" << GetLogPrefix() << "] glGetFramebufferAttachmentParameteriv(" + << GLES2Util::GetStringFramebufferTarget(target) << ", " + << GLES2Util::GetStringAttachmentQuery(attachment) << ", " + << GLES2Util::GetStringFramebufferAttachmentParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); TRACE_EVENT0("gpu", "GLES2Implementation::GetFramebufferAttachmentParameteriv"); if (GetFramebufferAttachmentParameterivHelper(target, attachment, pname,
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc index b9da433..f1d8764 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -257,6 +257,7 @@ viz::TextureStorageFormat(texture->format), width, height); } else { + DCHECK(GLSupportsFormat(texture->format)); gl_->TexImage2D(texture->target, 0, viz::GLInternalFormat(texture->format), width, height, 0, viz::GLDataFormat(texture->format), viz::GLDataType(texture->format), nullptr);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index c6bc86a..72bdd8c 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -34,7 +34,7 @@ static std::string GetStringEquation(uint32_t value); static std::string GetStringFaceMode(uint32_t value); static std::string GetStringFaceType(uint32_t value); -static std::string GetStringFramebufferParameter(uint32_t value); +static std::string GetStringFramebufferAttachmentParameter(uint32_t value); static std::string GetStringFramebufferTarget(uint32_t value); static std::string GetStringGLState(uint32_t value); static std::string GetStringGetMaxIndexType(uint32_t value);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index ec2707bc..4d63d1b4 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -4532,7 +4532,7 @@ arraysize(string_table), value); } -std::string GLES2Util::GetStringFramebufferParameter(uint32_t value) { +std::string GLES2Util::GetStringFramebufferAttachmentParameter(uint32_t value) { static const EnumToString string_table[] = { {GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE"},
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index fcc1484..3ae9356 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -92,7 +92,7 @@ GL_APICALL GLenum GL_APIENTRY glGetError (void); GL_APICALL void GL_APIENTRY glGetFloatv (GLenumGLState pname, GLfloat* params); GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLidProgram program, const char* name); -GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenumFramebufferTarget target, GLenumAttachmentQuery attachment, GLenumFramebufferParameter pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenumFramebufferTarget target, GLenumAttachmentQuery attachment, GLenumFramebufferAttachmentParameter pname, GLint* params); GL_APICALL void GL_APIENTRY glGetInteger64v (GLenumGLState pname, GLint64* params); GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenumIndexedGLState pname, GLuint index, GLint* data); GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenumIndexedGLState pname, GLuint index, GLint64* data);
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 7bc4600..a8ed234 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -698,7 +698,7 @@ validators_.texture_format.AddValue(GL_SRGB_EXT); validators_.texture_format.AddValue(GL_SRGB_ALPHA_EXT); validators_.render_buffer_format.AddValue(GL_SRGB8_ALPHA8_EXT); - validators_.framebuffer_parameter.AddValue( + validators_.framebuffer_attachment_parameter.AddValue( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT); validators_.texture_unsized_internal_format.AddValue(GL_SRGB_EXT); validators_.texture_unsized_internal_format.AddValue(GL_SRGB_ALPHA_EXT); @@ -934,7 +934,7 @@ if (feature_flags_.multisampled_render_to_texture) { validators_.render_buffer_parameter.AddValue(GL_RENDERBUFFER_SAMPLES_EXT); validators_.g_l_state.AddValue(GL_MAX_SAMPLES_EXT); - validators_.framebuffer_parameter.AddValue( + validators_.framebuffer_attachment_parameter.AddValue( GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT); AddExtensionString("GL_EXT_multisampled_render_to_texture"); }
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 17882dd8..83259d2 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -267,7 +267,7 @@ GL_SRGB_ALPHA_EXT)); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_SRGB8_ALPHA8_EXT)); - EXPECT_TRUE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_TRUE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } else { EXPECT_FALSE(gfx::HasExtension(info_->extensions(), "GL_EXT_sRGB")); @@ -280,7 +280,7 @@ GL_SRGB_ALPHA_EXT)); EXPECT_FALSE(info_->validators()->render_buffer_format.IsValid( GL_SRGB8_ALPHA8_EXT)); - EXPECT_FALSE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_FALSE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } @@ -633,7 +633,7 @@ GL_SRGB_ALPHA_EXT)); EXPECT_FALSE( info_->validators()->render_buffer_format.IsValid(GL_SRGB8_ALPHA8_EXT)); - EXPECT_FALSE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_FALSE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } else { EXPECT_TRUE(gfx::HasExtension(info_->extensions(), "GL_EXT_sRGB")); @@ -645,7 +645,7 @@ GL_SRGB_ALPHA_EXT)); EXPECT_TRUE( info_->validators()->render_buffer_format.IsValid(GL_SRGB8_ALPHA8_EXT)); - EXPECT_TRUE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_TRUE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } } @@ -977,7 +977,7 @@ GL_SRGB_ALPHA_EXT)); EXPECT_FALSE(info_->validators()->render_buffer_format.IsValid( GL_SRGB8_ALPHA8_EXT)); - EXPECT_FALSE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_FALSE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)); } @@ -1126,7 +1126,7 @@ GL_MAX_SAMPLES_EXT)); EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( GL_RENDERBUFFER_SAMPLES_EXT)); - EXPECT_TRUE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_TRUE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)); } @@ -1142,7 +1142,7 @@ GL_MAX_SAMPLES_EXT)); EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( GL_RENDERBUFFER_SAMPLES_EXT)); - EXPECT_TRUE(info_->validators()->framebuffer_parameter.IsValid( + EXPECT_TRUE(info_->validators()->framebuffer_attachment_parameter.IsValid( GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)); }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 3703197..1fc24c5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -1462,7 +1462,7 @@ attachment, "attachment"); return error::kNoError; } - if (!validators_->framebuffer_parameter.IsValid(pname)) { + if (!validators_->framebuffer_attachment_parameter.IsValid(pname)) { LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetFramebufferAttachmentParameteriv", pname, "pname"); return error::kNoError;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index c820cb53c4..96767ea8 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -113,7 +113,7 @@ }; FaceTypeValidator face_type; -ValueValidator<GLenum> framebuffer_parameter; +ValueValidator<GLenum> framebuffer_attachment_parameter; ValueValidator<GLenum> framebuffer_target; ValueValidator<GLenum> g_l_state; class GetMaxIndexTypeValidator {
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 555bef78..97f89cb 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -225,14 +225,14 @@ return false; } -static const GLenum valid_framebuffer_parameter_table[] = { +static const GLenum valid_framebuffer_attachment_parameter_table[] = { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, }; -static const GLenum valid_framebuffer_parameter_table_es3[] = { +static const GLenum valid_framebuffer_attachment_parameter_table_es3[] = { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, @@ -1395,8 +1395,9 @@ dst_blend_factor(valid_dst_blend_factor_table, arraysize(valid_dst_blend_factor_table)), equation(valid_equation_table, arraysize(valid_equation_table)), - framebuffer_parameter(valid_framebuffer_parameter_table, - arraysize(valid_framebuffer_parameter_table)), + framebuffer_attachment_parameter( + valid_framebuffer_attachment_parameter_table, + arraysize(valid_framebuffer_attachment_parameter_table)), framebuffer_target(valid_framebuffer_target_table, arraysize(valid_framebuffer_target_table)), g_l_state(valid_g_l_state_table, arraysize(valid_g_l_state_table)), @@ -1478,9 +1479,9 @@ arraysize(valid_dst_blend_factor_table_es3)); equation.AddValues(valid_equation_table_es3, arraysize(valid_equation_table_es3)); - framebuffer_parameter.AddValues( - valid_framebuffer_parameter_table_es3, - arraysize(valid_framebuffer_parameter_table_es3)); + framebuffer_attachment_parameter.AddValues( + valid_framebuffer_attachment_parameter_table_es3, + arraysize(valid_framebuffer_attachment_parameter_table_es3)); framebuffer_target.AddValues(valid_framebuffer_target_table_es3, arraysize(valid_framebuffer_target_table_es3)); g_l_state.AddValues(valid_g_l_state_table_es3,
diff --git a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h index 23601cb..e32ec2e 100644 --- a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
@@ -68,11 +68,17 @@ }; static const viz::ResourceFormat valid_viz_resource_format_table[] = { - viz::ResourceFormat::RGBA_8888, viz::ResourceFormat::RGBA_4444, - viz::ResourceFormat::BGRA_8888, viz::ResourceFormat::ALPHA_8, - viz::ResourceFormat::LUMINANCE_8, viz::ResourceFormat::RGB_565, - viz::ResourceFormat::RED_8, viz::ResourceFormat::LUMINANCE_F16, - viz::ResourceFormat::RGBA_F16, viz::ResourceFormat::R16_EXT, + viz::ResourceFormat::RGBA_8888, viz::ResourceFormat::RGBA_4444, + viz::ResourceFormat::BGRA_8888, viz::ResourceFormat::ALPHA_8, + viz::ResourceFormat::LUMINANCE_8, viz::ResourceFormat::RGB_565, + viz::ResourceFormat::RGB_565, viz::ResourceFormat::RED_8, + viz::ResourceFormat::RG_88, viz::ResourceFormat::LUMINANCE_F16, + viz::ResourceFormat::RGBA_F16, viz::ResourceFormat::R16_EXT, + viz::ResourceFormat::RGBX_8888, viz::ResourceFormat::BGRX_8888, + viz::ResourceFormat::RGBX_1010102, viz::ResourceFormat::BGRX_1010102, + viz::ResourceFormat::YVU_420, viz::ResourceFormat::YUV_420_BIPLANAR, + viz::ResourceFormat::UYVY_422 + }; Validators::Validators()
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 000bc461..a97a98aa 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2070,6 +2070,7 @@ bool use_buffer, gfx::BufferUsage buffer_usage, viz::ResourceFormat resource_format) { + DCHECK(GLSupportsFormat(resource_format)); texture_metadata_.emplace(std::make_pair( client_id, TextureMetadata(use_buffer, buffer_usage, resource_format, GetCapabilities()))); @@ -2387,6 +2388,7 @@ "Invalid buffer format"); return false; } + DCHECK(GLSupportsFormat(texture_metadata.format())); GLint untyped_format = viz::GLDataFormat(texture_metadata.format()); if (!GetContextGroup()->image_factory()) { @@ -2549,6 +2551,7 @@ return; } + DCHECK(GLSupportsFormat(texture_metadata->format())); // Check if we have enough memory. unsigned int internal_format = viz::GLInternalFormat(texture_metadata->format());
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h index 6563388e..9b047ae 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h
@@ -20,8 +20,7 @@ class ChromeBrowserState; } // namespace ios -using TimerGeneratorBlock = - std::unique_ptr<base::Timer> (^)(bool retain_user_task, bool is_repeating); +using TimerGeneratorBlock = std::unique_ptr<base::OneShotTimer> (^)(); @protocol ChromeSigninViewControllerDelegate<NSObject> @@ -119,7 +118,8 @@ // Exposes methods for testing. @interface ChromeSigninViewController (Testing) -// Timer generator. Should stay nil to use the default timer class: base::Timer. +// Timer generator. Should stay nil to use the default timer class: +// base::OneShotTimer. @property(nonatomic, copy) TimerGeneratorBlock timerGenerator; @end
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm index 483c661b..4e73e93b 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -734,15 +734,11 @@ [strongSelf->_activityIndicator stopAnimating]; strongSelf->_leavingPendingStateTimer.reset(); }; - const bool retain_user_task = false; - const bool is_repeating = false; if (self.timerGenerator) { - _leavingPendingStateTimer = - self.timerGenerator(retain_user_task, is_repeating); + _leavingPendingStateTimer = self.timerGenerator(); DCHECK(_leavingPendingStateTimer); } else { - _leavingPendingStateTimer = - std::make_unique<base::Timer>(retain_user_task, is_repeating); + _leavingPendingStateTimer = std::make_unique<base::OneShotTimer>(); } _leavingPendingStateTimer->Start(FROM_HERE, remainingTime, base::BindRepeating(completionBlock));
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm index c4db4f3..a9a0149 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm
@@ -180,12 +180,10 @@ dispatcher:nil]; vc_delegate_ = [[FakeChromeSigninViewControllerDelegate alloc] init]; vc_.delegate = vc_delegate_; - __block base::MockTimer* mock_timer_ptr = nullptr; + __block base::MockOneShotTimer* mock_timer_ptr = nullptr; if (!unified_consent_enabled_) { - vc_.timerGenerator = ^std::unique_ptr<base::Timer>(bool retain_user_task, - bool is_repeating) { - auto mock_timer = - std::make_unique<base::MockTimer>(retain_user_task, is_repeating); + vc_.timerGenerator = ^std::unique_ptr<base::OneShotTimer>() { + auto mock_timer = std::make_unique<base::MockOneShotTimer>(); mock_timer_ptr = mock_timer.get(); return mock_timer; }; @@ -406,7 +404,7 @@ FakeConsentAuditor* fake_consent_auditor_; AccountTrackerService* account_tracker_service_; base::test::ScopedFeatureList scoped_feature_list_; - base::MockTimer* mock_timer_ptr_ = nullptr; + base::MockOneShotTimer* mock_timer_ptr_ = nullptr; FakeChromeSigninViewControllerDelegate* vc_delegate_; };
diff --git a/ios/chrome/browser/ui/history/history_entry_inserter.mm b/ios/chrome/browser/ui/history/history_entry_inserter.mm index b0de08c..8ef149ef 100644 --- a/ios/chrome/browser/ui/history/history_entry_inserter.mm +++ b/ios/chrome/browser/ui/history/history_entry_inserter.mm
@@ -80,15 +80,22 @@ inSortedRange:range options:NSBinarySearchingInsertionIndex usingComparator:objectComparator]; + + // Calculate the new tableView indexPath row before inserting into the + // model. No matter where in the model the item is inserted, a new row will + // be created for the tableView. For this reason, make sure to insert a new + // index into the tableView after the item has been inserted into the model. + NSInteger section = + [_listModel sectionForSectionIdentifier:sectionIdentifier]; + NSInteger tableViewRow = [_listModel numberOfItemsInSection:section]; + NSIndexPath* tableIndexPath = + [NSIndexPath indexPathForRow:tableViewRow inSection:section]; + [_listModel insertItem:item inSectionWithIdentifier:sectionIdentifier atIndex:index]; - NSIndexPath* indexPath = [NSIndexPath - indexPathForItem:index - inSection:[_listModel - sectionForSectionIdentifier:sectionIdentifier]]; [self.delegate historyEntryInserter:self - didInsertItemAtIndexPath:indexPath]; + didInsertItemAtIndexPath:tableIndexPath]; } } @@ -120,6 +127,8 @@ usingComparator:comparator]; [_dates insertObject:date atIndex:index]; NSInteger insertionIndex = _firstSectionIndex + index; + [_listModel insertSectionWithIdentifier:sectionIdentifier + atIndex:insertionIndex]; if (IsUIRefreshPhase1Enabled()) { TableViewTextHeaderFooterItem* header = [[TableViewTextHeaderFooterItem alloc] initWithType:kItemTypeEnumZero]; @@ -134,8 +143,6 @@ base::SysUTF16ToNSString(history::GetRelativeDateLocalized(timestamp)); [_listModel setHeader:header forSectionWithIdentifier:sectionIdentifier]; } - [_listModel insertSectionWithIdentifier:sectionIdentifier - atIndex:insertionIndex]; [self.delegate historyEntryInserter:self didInsertSectionAtIndex:insertionIndex]; return sectionIdentifier;
diff --git a/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm b/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm index b4cf5be..4f2db2c 100644 --- a/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm +++ b/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm
@@ -75,7 +75,7 @@ [[mock_delegate expect] historyEntryInserter:inserter_ - didInsertItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]; + didInsertItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]]; [inserter_ insertHistoryEntryItem:entry1]; EXPECT_OCMOCK_VERIFY(mock_delegate); @@ -176,7 +176,7 @@ [[mock_delegate expect] historyEntryInserter:inserter_ - didInsertItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]]; + didInsertItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:2]]; [inserter_ insertHistoryEntryItem:day2_entry1]; EXPECT_EQ(4, [model_ numberOfSections]); EXPECT_EQ(0, [model_ numberOfItemsInSection:0]);
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index a8ea5c8..d3acbee2 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -11,8 +11,12 @@ "reading_list_coordinator.h", "reading_list_coordinator.mm", "reading_list_list_item.h", - "reading_list_list_view_item_util.h", - "reading_list_list_view_item_util.mm", + "reading_list_list_item_custom_action_factory.h", + "reading_list_list_item_custom_action_factory.mm", + "reading_list_list_item_factory.h", + "reading_list_list_item_factory.mm", + "reading_list_list_item_util.h", + "reading_list_list_item_util.mm", "reading_list_mediator.h", "reading_list_mediator.mm", "reading_list_menu_notification_delegate.h", @@ -67,6 +71,8 @@ source_set("reading_list_ui") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "empty_reading_list_background_view.h", + "empty_reading_list_background_view.mm", "number_badge_view.h", "number_badge_view.mm", "reading_list_collection_view_cell.h", @@ -75,11 +81,12 @@ "reading_list_collection_view_controller.mm", "reading_list_data_sink.h", "reading_list_data_source.h", - "reading_list_empty_collection_background.h", - "reading_list_empty_collection_background.mm", - "reading_list_list_view_item_accessibility_delegate.h", - "reading_list_list_view_item_custom_action_factory.h", - "reading_list_list_view_item_custom_action_factory.mm", + "reading_list_list_item_accessibility_delegate.h", + "reading_list_list_item_updater.h", + "reading_list_list_view_controller_audience.h", + "reading_list_list_view_controller_delegate.h", + "reading_list_table_view_controller.h", + "reading_list_table_view_controller.mm", "reading_list_toolbar.h", "reading_list_toolbar.mm", "reading_list_toolbar_button.h", @@ -112,6 +119,7 @@ "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/list_model", + "//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view/cells", "//ios/chrome/browser/ui/table_view/cells/resources:table_view_cell_check_mark", "//ios/chrome/browser/ui/util", @@ -136,6 +144,7 @@ "offline_page_native_content_unittest.mm", "reading_list_collection_view_controller_unittest.mm", "reading_list_coordinator_unittest.mm", + "reading_list_list_item_factory_unittest.mm", "reading_list_mediator_unittest.mm", "text_badge_view_unittest.mm", ]
diff --git a/ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h b/ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h new file mode 100644 index 0000000..869735f6 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_EMPTY_READING_LIST_BACKGROUND_VIEW_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_EMPTY_READING_LIST_BACKGROUND_VIEW_H_ + +#import <UIKit/UIKit.h> + +// The view to use as the background view for an empty reading list list view. +@interface EmptyReadingListBackgroundView : UIView + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; +- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; + ++ (NSString*)accessibilityIdentifier; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_EMPTY_READING_LIST_BACKGROUND_VIEW_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm b/ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.mm similarity index 95% rename from ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm rename to ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.mm index 6c6adde..ea5354a7 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm +++ b/ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h" +#import "ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h" #include "base/logging.h" #include "ios/chrome/browser/ui/rtl_geometry.h" @@ -41,7 +41,7 @@ } // namespace -@interface ReadingListEmptyCollectionBackground () +@interface EmptyReadingListBackgroundView () // Attaches the icon named |iconName| to |instructionString| and a |caret|. The // icon is positionned using the |iconOffset| and with the |attributes| (mainly @@ -62,7 +62,7 @@ @end -@implementation ReadingListEmptyCollectionBackground +@implementation EmptyReadingListBackgroundView #pragma mark - Public @@ -175,7 +175,7 @@ label.textAlignment = NSTextAlignmentCenter; label.accessibilityLabel = accessibilityLabel; label.accessibilityIdentifier = - [ReadingListEmptyCollectionBackground accessibilityIdentifier]; + [EmptyReadingListBackgroundView accessibilityIdentifier]; [label setTranslatesAutoresizingMaskIntoConstraints:NO]; [self addSubview:label]; @@ -214,9 +214,9 @@ appendAttributedString:[NSAttributedString attributedStringWithAttachment:toolbarIcon]]; - [instructionString appendAttributedString:[[NSAttributedString alloc] - initWithString:@" " - attributes:attributes]]; + [instructionString appendAttributedString:[[NSAttributedString alloc] + initWithString:@" " + attributes:attributes]]; [instructionString appendAttributedString:caret]; }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h index 25de322..314662c67 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h
@@ -7,60 +7,16 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" -@class ReadingListCollectionViewController; @protocol ReadingListDataSource; - -// Audience for the ReadingListCollectionViewController -@protocol ReadingListCollectionViewControllerAudience - -// Whether the collection has items. -- (void)readingListHasItems:(BOOL)hasItems; - -@end - -// Delegate for the ReadingListCollectionViewController, managing the visibility -// of the toolbar, dismissing the Reading List View and opening elements. -@protocol ReadingListCollectionViewControllerDelegate<NSObject> - -// Dismisses the Reading List View. -- (void)dismissReadingListCollectionViewController: - (ReadingListCollectionViewController*)readingListCollectionViewController; - -// Displays the context menu for the |readingListItem|. The |menuLocation| is -// the anchor of the context menu in the -// readingListCollectionViewController.collectionView coordinates. -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - displayContextMenuForItem:(CollectionViewItem*)readingListItem - atPoint:(CGPoint)menuLocation; - -// Opens the entry corresponding to the |readingListItem|. -- (void) -readingListCollectionViewController: - (ReadingListCollectionViewController*)readingListCollectionViewController - openItem:(CollectionViewItem*)readingListItem; - -// Opens the entry corresponding to the |item| in a new tab, |incognito| or not. -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - openItemInNewTab:(CollectionViewItem*)item - incognito:(BOOL)incognito; - -// Opens the offline version of the entry corresponding to the |item| in a new -// tab, if available. -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - openItemOfflineInNewTab:(CollectionViewItem*)item; - -@end +@protocol ReadingListListViewControllerAudience; +@protocol ReadingListListViewControllerDelegate; @interface ReadingListCollectionViewController - : CollectionViewController<ReadingListToolbarActions> + : CollectionViewController<ReadingListListItemAccessibilityDelegate, + ReadingListToolbarActions> - (instancetype)initWithDataSource:(id<ReadingListDataSource>)dataSource toolbar:(ReadingListToolbar*)toolbar @@ -69,10 +25,8 @@ style:(CollectionViewControllerStyle)style NS_UNAVAILABLE; -@property(nonatomic, weak) id<ReadingListCollectionViewControllerDelegate> - delegate; -@property(nonatomic, weak) id<ReadingListCollectionViewControllerAudience> - audience; +@property(nonatomic, weak) id<ReadingListListViewControllerDelegate> delegate; +@property(nonatomic, weak) id<ReadingListListViewControllerAudience> audience; @property(nonatomic, weak) id<ReadingListDataSource> dataSource; // Prepares this view controller to be dismissed.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm index e70ae61..a710730 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm
@@ -14,11 +14,12 @@ #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/list_model/list_item+Controller.h" +#import "ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h" #import "ios/chrome/browser/ui/reading_list/reading_list_data_sink.h" #import "ios/chrome/browser/ui/reading_list/reading_list_data_source.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_accessibility_delegate.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_updater.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_audience.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h" @@ -30,24 +31,19 @@ #endif namespace { - -typedef NS_ENUM(NSInteger, SectionIdentifier) { - SectionIdentifierUnread = kSectionIdentifierEnumZero, - SectionIdentifierRead, -}; - +// Types of ListItems used by the reading list UI. typedef NS_ENUM(NSInteger, ItemType) { ItemTypeHeader = kItemTypeEnumZero, ItemTypeItem, }; - -// Typedef for a block taking a CollectionViewItem as parameter and returning -// nothing. -typedef void (^EntryUpdater)(CollectionViewItem* item); -} +// Identifiers for sections in the reading list. +typedef NS_ENUM(NSInteger, SectionIdentifier) { + SectionIdentifierUnread = kSectionIdentifierEnumZero, + SectionIdentifierRead, +}; +} // namespace @interface ReadingListCollectionViewController ()< - ReadingListListViewItemAccessibilityDelegate, ReadingListDataSink, UIGestureRecognizerDelegate> { // Toolbar with the actions. @@ -60,20 +56,23 @@ BOOL _dataSourceHasBeenModified; } +// Redefine the model to return ReadingListListItems +@property(nonatomic, readonly) + CollectionViewModel<CollectionViewItem<ReadingListListItem>*>* + collectionViewModel; + // Whether the data source modifications should be taken into account. @property(nonatomic, assign) BOOL shouldMonitorDataSource; -// The factory that provides custom accessibility actions to the cells, using -// self as the accessibility delegate. -@property(nonatomic, strong) - ReadingListListViewItemCustomActionFactory* customActionFactory; - +// Casts |item| to a CollectionViewItem. +- (CollectionViewItem<ReadingListListItem>*)collectionItemForReadingListItem: + (id<ReadingListListItem>)item; // Handles "Done" button touches. - (void)donePressed; // Loads all the items in all sections. - (void)loadItems; // Fills section |sectionIdentifier| with the items from |array|. -- (void)loadItemsFromArray:(NSArray<CollectionViewItem*>*)array +- (void)loadItemsFromArray:(NSArray<id<ReadingListListItem>>*)array toSection:(SectionIdentifier)sectionIdentifier; // Reloads the data if a change occurred during editing - (void)applyPendingUpdates; @@ -114,12 +113,12 @@ // order. The monitoring of the data source updates are suspended during this // time. - (void)updateItemsInSectionIdentifier:(SectionIdentifier)identifier - usingEntryUpdater:(EntryUpdater)updater; + usingItemUpdater:(ReadingListListItemUpdater)updater; // Applies |updater| to the URL of every element in |indexPaths|. The updates // are done in reverse order |indexPaths| to keep the order. The monitoring of // the data source updates are suspended during this time. - (void)updateIndexPaths:(NSArray<NSIndexPath*>*)indexPaths - usingEntryUpdater:(EntryUpdater)updater; + usingItemUpdater:(ReadingListListItemUpdater)updater; // Move all the items from |sourceSectionIdentifier| to // |destinationSectionIdentifier| and removes the empty section from the // collection. @@ -147,8 +146,8 @@ @synthesize delegate = _delegate; @synthesize dataSource = _dataSource; +@dynamic collectionViewModel; @synthesize shouldMonitorDataSource = _shouldMonitorDataSource; -@synthesize customActionFactory = _customActionFactory; + (NSString*)accessibilityIdentifier { return @"ReadingListCollectionView"; @@ -165,16 +164,11 @@ _toolbar = toolbar; _dataSource = dataSource; - _emptyCollectionBackground = - [[ReadingListEmptyCollectionBackground alloc] init]; + _emptyCollectionBackground = [[EmptyReadingListBackgroundView alloc] init]; _shouldMonitorDataSource = YES; _dataSourceHasBeenModified = NO; - _customActionFactory = - [[ReadingListListViewItemCustomActionFactory alloc] init]; - _customActionFactory.accessibilityDelegate = self; - _dataSource.dataSink = self; } return self; @@ -186,7 +180,7 @@ [_toolbar setState:toolbarState]; } -- (void)setAudience:(id<ReadingListCollectionViewControllerAudience>)audience { +- (void)setAudience:(id<ReadingListListViewControllerAudience>)audience { _audience = audience; if (self.dataSource.ready) { [audience readingListHasItems:self.dataSource.hasElements]; @@ -236,10 +230,9 @@ if (self.editor.editing) { [self updateToolbarState]; } else { - [self.delegate - readingListCollectionViewController:self - openItem:[self.collectionViewModel - itemAtIndexPath:indexPath]]; + id<ReadingListListItem> item = + [self.collectionViewModel itemAtIndexPath:indexPath]; + [self.delegate readingListListViewController:self openItem:item]; } } @@ -297,34 +290,42 @@ } } -- (NSArray<CollectionViewItem*>*)readItems { - if (![self.collectionViewModel - hasSectionForSectionIdentifier:SectionIdentifierRead]) { - return nil; - } - return [self.collectionViewModel - itemsInSectionWithIdentifier:SectionIdentifierRead]; +- (NSArray<id<ReadingListListItem>>*)readItems { + return [self readingListItemsForSection:SectionIdentifierRead]; } -- (NSArray<CollectionViewItem*>*)unreadItems { - if (![self.collectionViewModel - hasSectionForSectionIdentifier:SectionIdentifierUnread]) { - return nil; - } - return [self.collectionViewModel - itemsInSectionWithIdentifier:SectionIdentifierUnread]; +- (NSArray<id<ReadingListListItem>>*)unreadItems { + return [self readingListItemsForSection:SectionIdentifierUnread]; } -- (void)itemHasChangedAfterDelay:(CollectionViewItem*)item { - if ([self.collectionViewModel hasItem:item]) { - [self reconfigureCellsForItems:@[ item ]]; +- (void)itemHasChangedAfterDelay:(id<ReadingListListItem>)item { + CollectionViewItem<ReadingListListItem>* collectionItem = + [self collectionItemForReadingListItem:item]; + if ([self.collectionViewModel hasItem:collectionItem]) { + [self reconfigureCellsForItems:@[ collectionItem ]]; } } -- (void)itemsHaveChanged:(NSArray<CollectionViewItem*>*)items { +- (void)itemsHaveChanged:(NSArray<id<ReadingListListItem>>*)items { [self reconfigureCellsForItems:items]; } +#pragma mark - ReadingListDataSink Helpers + +- (NSArray<id<ReadingListListItem>>*)readingListItemsForSection: + (SectionIdentifier)sectionID { + if (![self.collectionViewModel hasSectionForSectionIdentifier:sectionID]) { + return nil; + } + NSMutableArray<id<ReadingListListItem>>* items = [NSMutableArray array]; + NSArray<CollectionViewItem*>* sectionItems = + [self.collectionViewModel itemsInSectionWithIdentifier:sectionID]; + for (id<ReadingListListItem> item in sectionItems) { + [items addObject:item]; + } + return items; +} + #pragma mark - Public methods - (void)reloadData { @@ -339,63 +340,55 @@ [_actionSheet stop]; } -#pragma mark - ReadingListListViewItemAccessibilityDelegate +#pragma mark - ReadingListListItemAccessibilityDelegate -- (BOOL)isEntryRead:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - return [self.dataSource isEntryRead:item]; +- (BOOL)isItemRead:(id<ReadingListListItem>)item { + return [self.dataSource isItemRead:item]; } -- (void)deleteEntry:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - if ([self.collectionViewModel hasItem:item]) { +- (void)deleteItem:(id<ReadingListListItem>)item { + CollectionViewItem<ReadingListListItem>* collectionItem = + [self collectionItemForReadingListItem:item]; + if ([self.collectionViewModel hasItem:collectionItem]) { [self deleteItemsAtIndexPaths:@[ [self.collectionViewModel - indexPathForItem:item] ]]; + indexPathForItem:collectionItem] ]]; } } -- (void)openEntryInNewTab:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - [self.delegate readingListCollectionViewController:self - openItemInNewTab:item - incognito:NO]; +- (void)openItemInNewTab:(id<ReadingListListItem>)item { + [self.delegate readingListListViewController:self + openItemInNewTab:item + incognito:NO]; } -- (void)openEntryInNewIncognitoTab:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - [self.delegate readingListCollectionViewController:self - openItemInNewTab:item - incognito:YES]; +- (void)openItemInNewIncognitoTab:(id<ReadingListListItem>)item { + [self.delegate readingListListViewController:self + openItemInNewTab:item + incognito:YES]; } -- (void)openEntryOffline:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - [self.delegate readingListCollectionViewController:self - openItemOfflineInNewTab:item]; +- (void)openItemOffline:(id<ReadingListListItem>)item { + [self.delegate readingListListViewController:self + openItemOfflineInNewTab:item]; } -- (void)markEntryRead:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - if ([self.collectionViewModel hasItem:item +- (void)markItemRead:(id<ReadingListListItem>)item { + CollectionViewItem<ReadingListListItem>* collectionItem = + [self collectionItemForReadingListItem:item]; + if ([self.collectionViewModel hasItem:collectionItem inSectionWithIdentifier:SectionIdentifierUnread]) { [self markItemsReadAtIndexPath:@[ [self.collectionViewModel - indexPathForItem:item] ]]; + indexPathForItem:collectionItem] ]]; } } -- (void)markEntryUnread:(ListItem*)entry { - CollectionViewItem* item = - base::mac::ObjCCastStrict<CollectionViewItem>(entry); - if ([self.collectionViewModel hasItem:item +- (void)markItemUnread:(id<ReadingListListItem>)item { + CollectionViewItem<ReadingListListItem>* collectionItem = + [self collectionItemForReadingListItem:item]; + if ([self.collectionViewModel hasItem:collectionItem inSectionWithIdentifier:SectionIdentifierRead]) { [self markItemsUnreadAtIndexPath:@[ [self.collectionViewModel - indexPathForItem:item] ]]; + indexPathForItem:collectionItem] ]]; } } @@ -419,7 +412,7 @@ } - (void)dismiss { - [self.delegate dismissReadingListCollectionViewController:self]; + [self.delegate dismissReadingListListViewController:self]; } - (void)loadModel { @@ -436,7 +429,7 @@ } } -- (void)loadItemsFromArray:(NSArray<CollectionViewItem*>*)items +- (void)loadItemsFromArray:(NSArray<id<ReadingListListItem>>*)items toSection:(SectionIdentifier)sectionIdentifier { if (items.count == 0) { return; @@ -445,7 +438,7 @@ [model addSectionWithIdentifier:sectionIdentifier]; [model setHeader:[self headerForSection:sectionIdentifier] forSectionWithIdentifier:sectionIdentifier]; - for (CollectionViewItem* item in items) { + for (CollectionViewItem<ReadingListListItem>* item in items) { item.type = ItemTypeItem; [self.dataSource fetchFaviconForItem:item]; [model addItem:item toSectionWithIdentifier:sectionIdentifier]; @@ -453,11 +446,9 @@ } - (void)loadItems { - NSMutableArray<CollectionViewItem*>* readArray = [NSMutableArray array]; - NSMutableArray<CollectionViewItem*>* unreadArray = [NSMutableArray array]; - [self.dataSource fillReadItems:readArray - unreadItems:unreadArray - withCustomActionFactory:self.customActionFactory]; + NSMutableArray<id<ReadingListListItem>>* readArray = [NSMutableArray array]; + NSMutableArray<id<ReadingListListItem>>* unreadArray = [NSMutableArray array]; + [self.dataSource fillReadItems:readArray unreadItems:unreadArray]; [self loadItemsFromArray:unreadArray toSection:SectionIdentifierUnread]; [self loadItemsFromArray:readArray toSection:SectionIdentifierRead]; @@ -511,17 +502,17 @@ // Make sure there is an item at this position. return; } - CollectionViewItem* touchedItem = - [self.collectionViewModel itemAtIndexPath:touchedItemIndexPath]; - if (touchedItem.type != ItemTypeItem) { + CollectionViewItem<ReadingListListItem>* item = + [self.collectionViewModel itemAtIndexPath:touchedItemIndexPath]; + if (item.type != ItemTypeItem) { // Do not trigger context menu on headers. return; } - [self.delegate readingListCollectionViewController:self - displayContextMenuForItem:touchedItem - atPoint:touchLocation]; + [self.delegate readingListListViewController:self + displayContextMenuForItem:item + atPoint:touchLocation]; } #pragma mark - ReadingListToolbarDelegate @@ -577,6 +568,12 @@ #pragma mark - Private methods - Toolbar +- (CollectionViewItem<ReadingListListItem>*)collectionItemForReadingListItem: + (id<ReadingListListItem>)item { + return base::mac::ObjCCastStrict<CollectionViewItem<ReadingListListItem>>( + item); +} + - (void)updateToolbarState { BOOL readSelected = NO; BOOL unreadSelected = NO; @@ -685,9 +682,9 @@ } [self updateItemsInSectionIdentifier:SectionIdentifierUnread - usingEntryUpdater:^(CollectionViewItem* item) { - [self.dataSource setReadStatus:YES forItem:item]; - }]; + usingItemUpdater:^(id<ReadingListListItem> item) { + [self.dataSource setReadStatus:YES forItem:item]; + }]; [self exitEditingModeAnimated:YES]; [self moveItemsFromSection:SectionIdentifierUnread @@ -701,9 +698,9 @@ } [self updateItemsInSectionIdentifier:SectionIdentifierRead - usingEntryUpdater:^(CollectionViewItem* item) { - [self.dataSource setReadStatus:NO forItem:item]; - }]; + usingItemUpdater:^(id<ReadingListListItem> item) { + [self.dataSource setReadStatus:NO forItem:item]; + }]; [self exitEditingModeAnimated:YES]; [self moveItemsFromSection:SectionIdentifierRead @@ -715,9 +712,9 @@ NSArray* sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; [self updateIndexPaths:sortedIndexPaths - usingEntryUpdater:^(CollectionViewItem* item) { - [self.dataSource setReadStatus:YES forItem:item]; - }]; + usingItemUpdater:^(id<ReadingListListItem> item) { + [self.dataSource setReadStatus:YES forItem:item]; + }]; [self exitEditingModeAnimated:YES]; [self moveSelectedItems:sortedIndexPaths toSection:SectionIdentifierRead]; @@ -728,9 +725,9 @@ NSArray* sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; [self updateIndexPaths:sortedIndexPaths - usingEntryUpdater:^(CollectionViewItem* item) { - [self.dataSource setReadStatus:NO forItem:item]; - }]; + usingItemUpdater:^(id<ReadingListListItem> item) { + [self.dataSource setReadStatus:NO forItem:item]; + }]; [self exitEditingModeAnimated:YES]; [self moveSelectedItems:sortedIndexPaths toSection:SectionIdentifierUnread]; @@ -744,9 +741,9 @@ } [self updateItemsInSectionIdentifier:SectionIdentifierRead - usingEntryUpdater:^(CollectionViewItem* item) { - [self.dataSource removeEntryFromItem:item]; - }]; + usingItemUpdater:^(id<ReadingListListItem> item) { + [self.dataSource removeEntryFromItem:item]; + }]; [self exitEditingModeAnimated:YES]; [self.collectionView performBatchUpdates:^{ @@ -768,9 +765,9 @@ - (void)deleteItemsAtIndexPaths:(NSArray*)indexPaths { [self updateIndexPaths:indexPaths - usingEntryUpdater:^(CollectionViewItem* item) { - [self.dataSource removeEntryFromItem:item]; - }]; + usingItemUpdater:^(id<ReadingListListItem> item) { + [self.dataSource removeEntryFromItem:item]; + }]; [self exitEditingModeAnimated:YES]; @@ -790,7 +787,7 @@ } - (void)updateItemsInSectionIdentifier:(SectionIdentifier)identifier - usingEntryUpdater:(EntryUpdater)updater { + usingItemUpdater:(ReadingListListItemUpdater)updater { [self.dataSource beginBatchUpdates]; NSArray* readItems = [self.collectionViewModel itemsInSectionWithIdentifier:identifier]; @@ -803,11 +800,12 @@ } - (void)updateIndexPaths:(NSArray<NSIndexPath*>*)indexPaths - usingEntryUpdater:(EntryUpdater)updater { + usingItemUpdater:(ReadingListListItemUpdater)updater { [self.dataSource beginBatchUpdates]; // Read the objects in reverse order to keep the order (last modified first). for (NSIndexPath* index in [indexPaths reverseObjectEnumerator]) { - CollectionViewItem* item = [self.collectionViewModel itemAtIndexPath:index]; + id<ReadingListListItem> item = + [self.collectionViewModel itemAtIndexPath:index]; if (updater) updater(item); } @@ -954,7 +952,7 @@ if (!self.dataSource.hasElements) { [self collectionIsEmpty]; } else { - [_toolbar setHasReadItem:self.dataSource.hasRead]; + [_toolbar setHasReadItem:self.dataSource.hasReadElements]; } }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller_unittest.mm index 75282cb..1311a81b 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller_unittest.mm
@@ -20,6 +20,9 @@ #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h" #import "ios/chrome/browser/ui/reading_list/reading_list_mediator.h" #include "ios/web/public/test/test_web_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" @@ -61,16 +64,17 @@ nullptr, nullptr, base::DefaultClock::GetInstance())); large_icon_service_.reset(new favicon::LargeIconService( &mock_favicon_service_, /*image_fetcher=*/nullptr)); - mediator_ = - [[ReadingListMediator alloc] initWithModel:reading_list_model_.get() - largeIconService:large_icon_service_.get()]; + mediator_ = [[ReadingListMediator alloc] + initWithModel:reading_list_model_.get() + largeIconService:large_icon_service_.get() + listItemFactory:[ReadingListListItemFactory + collectionViewItemFactory]]; reading_list_view_controller_ = [[ReadingListCollectionViewController alloc] initWithDataSource:mediator_ toolbar:nil]; mock_delegate_ = [OCMockObject - niceMockForProtocol:@protocol( - ReadingListCollectionViewControllerDelegate)]; + niceMockForProtocol:@protocol(ReadingListListViewControllerDelegate)]; [reading_list_view_controller_ setDelegate:mock_delegate_]; } @@ -109,7 +113,7 @@ [reading_list_view_controller_ view]; [[mock_delegate_ expect] - dismissReadingListCollectionViewController:reading_list_view_controller_]; + dismissReadingListListViewController:reading_list_view_controller_]; // Simulate tap on "Done" button. UIBarButtonItem* done = @@ -142,8 +146,8 @@ itemAtIndexPath:indexPath]); [[mock_delegate_ expect] - readingListCollectionViewController:reading_list_view_controller_ - openItem:readingListItem]; + readingListListViewController:reading_list_view_controller_ + openItem:readingListItem]; // Simulate touch on second cell. [reading_list_view_controller_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm index a86c2ae..0f8a994 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
@@ -7,8 +7,8 @@ #include "base/strings/sys_string_conversions.h" #include "components/url_formatter/url_formatter.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_cell.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h" #import "ios/chrome/browser/ui/util/pasteboard_util.h" #import "ios/chrome/common/favicon/favicon_view.h" #include "ios/chrome/grit/ios_strings.h" @@ -55,9 +55,7 @@ cell.accessibilityLabel = GetReadingListCellAccessibilityLabel( self.title, subtitle, self.distillationState); cell.accessibilityCustomActions = - [self.customActionFactory customActionsForItem:self - withURL:self.entryURL - distillationStatus:self.distillationState]; + [self.customActionFactory customActionsForItem:self]; } #pragma mark - NSObject
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.h b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.h index 52e2eb65..acb71bb 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.h
@@ -6,7 +6,7 @@ #define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_COORDINATOR_H_ #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h" namespace ios { class ChromeBrowserState; @@ -17,7 +17,7 @@ // Coordinator for Reading List, displaying the Reading List when starting. @interface ReadingListCoordinator - : ChromeCoordinator<ReadingListCollectionViewControllerDelegate> + : ChromeCoordinator<ReadingListListViewControllerDelegate> // Mediator used by this coordinator. Reset when |-start| is called. @property(nonatomic, strong, nullable) ReadingListMediator* mediator;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm index 097f6a0..f372471 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -24,7 +24,9 @@ #import "ios/chrome/browser/ui/reading_list/context_menu/reading_list_context_menu_commands.h" #import "ios/chrome/browser/ui/reading_list/context_menu/reading_list_context_menu_coordinator.h" #import "ios/chrome/browser/ui/reading_list/context_menu/reading_list_context_menu_params.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" #import "ios/chrome/browser/ui/reading_list/reading_list_mediator.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" #import "ios/chrome/browser/ui/reading_list/reading_list_view_controller.h" @@ -90,9 +92,12 @@ favicon::LargeIconService* largeIconService = IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState); - self.mediator = - [[ReadingListMediator alloc] initWithModel:model - largeIconService:largeIconService]; + ReadingListListItemFactory* itemFactory = + [ReadingListListItemFactory collectionViewItemFactory]; + + self.mediator = [[ReadingListMediator alloc] initWithModel:model + largeIconService:largeIconService + listItemFactory:itemFactory]; ReadingListToolbar* toolbar = [[ReadingListToolbar alloc] init]; ReadingListCollectionViewController* collectionViewController = [[ReadingListCollectionViewController alloc] @@ -100,6 +105,7 @@ toolbar:toolbar]; collectionViewController.delegate = self; + itemFactory.accessibilityDelegate = collectionViewController; self.collectionViewController = collectionViewController; self.containerViewController = [[ReadingListViewController alloc] @@ -126,30 +132,29 @@ self.containerViewController = nil; } -#pragma mark - ReadingListCollectionViewControllerDelegate +#pragma mark - ReadingListListViewControllerDelegate -- (void)dismissReadingListCollectionViewController: - (ReadingListCollectionViewController*)readingListCollectionViewController { - [readingListCollectionViewController willBeDismissed]; +- (void)dismissReadingListListViewController:(UIViewController*)viewController { + DCHECK_EQ(viewController, self.collectionViewController); + [self.collectionViewController willBeDismissed]; [self stop]; } -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - displayContextMenuForItem:(CollectionViewItem*)item - atPoint:(CGPoint)menuLocation { +- (void)readingListListViewController:(UIViewController*)viewController + displayContextMenuForItem:(ListItem<ReadingListListItem>*)item + atPoint:(CGPoint)menuLocation { + DCHECK_EQ(viewController, self.collectionViewController); if (!self.containerViewController) { return; } - ReadingListCollectionViewItem* readingListItem = + ListItem<ReadingListListItem>* readingListItem = base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); - const ReadingListEntry* entry = [self.mediator entryFromItem:item]; + const ReadingListEntry* entry = [self.mediator entryFromItem:readingListItem]; if (!entry) { - [readingListCollectionViewController reloadData]; + [self.collectionViewController reloadData]; return; } const GURL entryURL = entry->URL(); @@ -165,7 +170,7 @@ params.title = readingListItem.title; params.message = base::SysUTF8ToNSString(readingListItem.entryURL.host()); params.rect = CGRectMake(menuLocation.x, menuLocation.y, 0, 0); - params.view = readingListCollectionViewController.collectionView; + params.view = self.collectionViewController.collectionView; params.entryURL = entryURL; params.offlineURL = offlineURL; @@ -176,65 +181,47 @@ [self.contextMenuCoordinator start]; } -- (void) -readingListCollectionViewController: - (ReadingListCollectionViewController*)readingListCollectionViewController - openItem:(CollectionViewItem*)readingListItem { - const ReadingListEntry* entry = [self.mediator entryFromItem:readingListItem]; - - if (!entry) { - [readingListCollectionViewController reloadData]; - return; - } - - base::RecordAction(base::UserMetricsAction("MobileReadingListOpen")); - - [readingListCollectionViewController willBeDismissed]; - - web::NavigationManager::WebLoadParams params(entry->URL()); - params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; - // Use a referrer with a specific URL to signal that this entry should not be - // taken into account for the Most Visited tiles. - params.referrer = - web::Referrer(GURL(kReadingListReferrerURL), web::ReferrerPolicyDefault); - [self.URLLoader loadURLWithParams:params]; - new_tab_page_uma::RecordAction( - self.browserState, new_tab_page_uma::ACTION_OPENED_READING_LIST_ENTRY); - - [self stop]; -} - -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - openItemInNewTab:(CollectionViewItem*)item - incognito:(BOOL)incognito { - ReadingListCollectionViewItem* readingListItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); - [self readingListCollectionViewController:readingListCollectionViewController - openNewTabWithURL:readingListItem.entryURL - incognito:incognito]; -} - -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - openItemOfflineInNewTab:(CollectionViewItem*)item { +- (void)readingListListViewController:(UIViewController*)viewController + openItem:(ListItem<ReadingListListItem>*)item { const ReadingListEntry* entry = [self.mediator entryFromItem:item]; - if (!entry) { + [self.collectionViewController reloadData]; return; } + [self loadEntryURL:entry->URL() + withOfflineURL:GURL::EmptyGURL() + inNewTab:NO + incognito:NO]; +} + +- (void)readingListListViewController:(UIViewController*)viewController + openItemInNewTab:(ListItem<ReadingListListItem>*)item + incognito:(BOOL)incognito { + const ReadingListEntry* entry = [self.mediator entryFromItem:item]; + if (!entry) { + [self.collectionViewController reloadData]; + return; + } + [self loadEntryURL:entry->URL() + withOfflineURL:GURL::EmptyGURL() + inNewTab:YES + incognito:incognito]; +} + +- (void)readingListListViewController:(UIViewController*)viewController + openItemOfflineInNewTab:(id<ReadingListListItem>)item { + const ReadingListEntry* entry = [self.mediator entryFromItem:item]; + if (!entry) + return; if (entry->DistilledState() == ReadingListEntry::PROCESSED) { const GURL entryURL = entry->URL(); GURL offlineURL = reading_list::OfflineURLForPath( entry->DistilledPath(), entryURL, entry->DistilledURL()); - - [self - readingListCollectionViewController:readingListCollectionViewController - openOfflineURL:offlineURL - correspondingEntryURL:entryURL]; + [self loadEntryURL:entry->URL() + withOfflineURL:offlineURL + inNewTab:YES + incognito:NO]; } } @@ -242,17 +229,19 @@ - (void)openURLInNewTabForContextMenuWithParams: (ReadingListContextMenuParams*)params { - [self readingListCollectionViewController:self.collectionViewController - openNewTabWithURL:params.entryURL - incognito:NO]; + [self loadEntryURL:params.entryURL + withOfflineURL:GURL::EmptyGURL() + inNewTab:YES + incognito:NO]; [self cleanUpContextMenu]; } - (void)openURLInNewIncognitoTabForContextMenuWithParams: (ReadingListContextMenuParams*)params { - [self readingListCollectionViewController:self.collectionViewController - openNewTabWithURL:params.entryURL - incognito:YES]; + [self loadEntryURL:params.entryURL + withOfflineURL:GURL::EmptyGURL() + inNewTab:YES + incognito:YES]; [self cleanUpContextMenu]; } @@ -263,9 +252,10 @@ - (void)openOfflineURLInNewTabForContextMenuWithParams: (ReadingListContextMenuParams*)params { - [self readingListCollectionViewController:self.collectionViewController - openOfflineURL:params.offlineURL - correspondingEntryURL:params.entryURL]; + [self loadEntryURL:params.entryURL + withOfflineURL:params.offlineURL + inNewTab:YES + incognito:NO]; [self cleanUpContextMenu]; } @@ -284,36 +274,51 @@ #pragma mark - Private -// Opens the offline url |offlineURL| of the entry saved in the reading list -// model with the |entryURL| url. -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - openOfflineURL:(const GURL&)offlineURL - correspondingEntryURL:(const GURL&)entryURL { - [self readingListCollectionViewController:readingListCollectionViewController - openNewTabWithURL:offlineURL - incognito:NO]; - - UMA_HISTOGRAM_BOOLEAN("ReadingList.OfflineVersionDisplayed", true); - const GURL updateURL = entryURL; - [self.mediator markEntryRead:updateURL]; -} - -// Opens |URL| in a new tab |incognito| or not. -- (void)readingListCollectionViewController: - (ReadingListCollectionViewController*) - readingListCollectionViewController - openNewTabWithURL:(const GURL&)URL - incognito:(BOOL)incognito { +// Loads reading list URLs. If |offlineURL| is valid, the item will be loaded +// offline; otherwise |entryURL| is loaded. |newTab| and |incognito| can be +// used to optionally open the URL in a new tab or in incognito. The +// coordinator is also stopped after the load is requested. +- (void)loadEntryURL:(const GURL&)entryURL + withOfflineURL:(const GURL&)offlineURL + inNewTab:(BOOL)newTab + incognito:(BOOL)incognito { + DCHECK(entryURL.is_valid()); base::RecordAction(base::UserMetricsAction("MobileReadingListOpen")); + new_tab_page_uma::RecordAction( + self.browserState, new_tab_page_uma::ACTION_OPENED_READING_LIST_ENTRY); - [readingListCollectionViewController willBeDismissed]; - [self.URLLoader webPageOrderedOpen:URL - referrer:web::Referrer() - inIncognito:incognito - inBackground:NO - appendTo:kLastTab]; + // Load the offline URL if available. + GURL loadURL = entryURL; + if (offlineURL.is_valid()) { + loadURL = offlineURL; + // Offline URLs should always be opened in new tabs. + newTab = YES; + // Record the offline load and update the model. + UMA_HISTOGRAM_BOOLEAN("ReadingList.OfflineVersionDisplayed", true); + const GURL updateURL = entryURL; + [self.mediator markEntryRead:updateURL]; + } + + // Prepare the collection for dismissal. + [self.collectionViewController willBeDismissed]; + + // Use a referrer with a specific URL to signal that this entry should not be + // taken into account for the Most Visited tiles. + web::Referrer referrer = + web::Referrer(GURL(kReadingListReferrerURL), web::ReferrerPolicyDefault); + if (newTab) { + [self.URLLoader webPageOrderedOpen:loadURL + referrer:referrer + inIncognito:incognito + inBackground:NO + appendTo:kLastTab]; + } else { + web::NavigationManager::WebLoadParams params(loadURL); + params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; + params.referrer = web::Referrer(GURL(kReadingListReferrerURL), + web::ReferrerPolicyDefault); + [self.URLLoader loadURLWithParams:params]; + } [self stop]; }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm index e46aefe..9cf5f3a4 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm
@@ -21,6 +21,7 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" #import "ios/chrome/browser/ui/reading_list/reading_list_mediator.h" #import "ios/chrome/browser/ui/reading_list/reading_list_utils.h" #import "ios/chrome/browser/ui/url_loader.h" @@ -57,9 +58,11 @@ nullptr, nullptr, base::DefaultClock::GetInstance())); large_icon_service_.reset(new favicon::LargeIconService( &mock_favicon_service_, /*image_fetcher=*/nullptr)); - mediator_ = - [[ReadingListMediator alloc] initWithModel:reading_list_model_.get() - largeIconService:large_icon_service_.get()]; + mediator_ = [[ReadingListMediator alloc] + initWithModel:reading_list_model_.get() + largeIconService:large_icon_service_.get() + listItemFactory:[ReadingListListItemFactory + collectionViewItemFactory]]; coordinator_ = [[ReadingListCoordinator alloc] initWithBaseViewController:nil browserState:browser_state_.get() @@ -117,9 +120,9 @@ item.distillationState = ReadingListUIDistillationStatusSuccess; // Action. - [GetCoordinator() readingListCollectionViewController: - GetAReadingListCollectionViewController() - openItem:item]; + [GetCoordinator() + readingListListViewController:GetAReadingListCollectionViewController() + openItem:item]; // Tests. FakeURLLoader* loader = GetLoader(); @@ -149,9 +152,9 @@ ASSERT_FALSE(model->GetEntryByURL(url)->IsRead()); // Action. - [GetCoordinator() readingListCollectionViewController: - GetAReadingListCollectionViewController() - openItemOfflineInNewTab:item]; + [GetCoordinator() + readingListListViewController:GetAReadingListCollectionViewController() + openItemOfflineInNewTab:item]; // Tests. FakeURLLoader* loader = GetLoader(); @@ -173,10 +176,10 @@ item.distillationState = ReadingListUIDistillationStatusSuccess; // Action. - [GetCoordinator() readingListCollectionViewController: - GetAReadingListCollectionViewController() - openItemInNewTab:item - incognito:YES]; + [GetCoordinator() + readingListListViewController:GetAReadingListCollectionViewController() + openItemInNewTab:item + incognito:YES]; // Tests. FakeURLLoader* loader = GetLoader();
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_data_sink.h b/ios/chrome/browser/ui/reading_list/reading_list_data_sink.h index 29203ef9..48337c7 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_data_sink.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_data_sink.h
@@ -6,6 +6,7 @@ #define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_DATA_SINK_H_ @protocol ReadingListDataSource; +@protocol ReadingListListItem; // Data Sink for the Reading List UI, receiving informations from the data // source. @@ -18,16 +19,16 @@ - (void)dataSourceChanged; // Returns the read items displayed. -- (NSArray<CollectionViewItem*>*)readItems; +- (NSArray<id<ReadingListListItem>>*)readItems; // Returns the unread items displayed. -- (NSArray<CollectionViewItem*>*)unreadItems; +- (NSArray<id<ReadingListListItem>>*)unreadItems; // Notifies the DataSink that the |item| has changed and it should be reloaded // if it is still displayed. -- (void)itemHasChangedAfterDelay:(CollectionViewItem*)item; +- (void)itemHasChangedAfterDelay:(id<ReadingListListItem>)item; // Notifies the DataSink that the |items| have changed and must be reloaded. The // |items| must be presented. -- (void)itemsHaveChanged:(NSArray<CollectionViewItem*>*)items; +- (void)itemsHaveChanged:(NSArray<id<ReadingListListItem>>*)items; @end
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_data_source.h b/ios/chrome/browser/ui/reading_list/reading_list_data_source.h index 6381151..3704ed2 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_data_source.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_data_source.h
@@ -7,9 +7,8 @@ #include <memory> -@class CollectionViewItem; @protocol ReadingListDataSink; -@class ReadingListListViewItemCustomActionFactory; +@protocol ReadingListListItem; // Data Source for the Reading List UI, providing the data sink with the data to // be displayed. Handle the interactions with the model. @@ -18,35 +17,33 @@ // The data sink associated with this data source. @property(nonatomic, weak, nullable) id<ReadingListDataSink> dataSink; // Whether the data source is ready to be used. -- (BOOL)ready; +@property(nonatomic, readonly, getter=isReady) BOOL ready; // Whether the data source has some elements. -- (BOOL)hasElements; +@property(nonatomic, readonly) BOOL hasElements; // Whether the data source has some read elements. -- (BOOL)hasRead; +@property(nonatomic, readonly) BOOL hasReadElements; + // Whether the entry corresponding to the |item| is read. -- (BOOL)isEntryRead:(nonnull CollectionViewItem*)item; +- (BOOL)isItemRead:(nonnull id<ReadingListListItem>)item; // Mark all entries as seen and stop sending updates to the data sink. - (void)dataSinkWillBeDismissed; // Set the read status of the entry associated with |item|. -- (void)setReadStatus:(BOOL)read forItem:(nonnull CollectionViewItem*)item; +- (void)setReadStatus:(BOOL)read forItem:(nonnull id<ReadingListListItem>)item; // Removes the entry associated with |item| and logs the deletion. -- (void)removeEntryFromItem:(nonnull CollectionViewItem*)item; +- (void)removeEntryFromItem:(nonnull id<ReadingListListItem>)item; // Fills the |readArray| and |unreadArray| with the corresponding items from the // model. The items are sorted most recent first. -- (void)fillReadItems:(nullable NSMutableArray<CollectionViewItem*>*)readArray - unreadItems: - (nullable NSMutableArray<CollectionViewItem*>*)unreadArray - withCustomActionFactory: - (nullable ReadingListListViewItemCustomActionFactory*) - customActionFactory; +- (void) +fillReadItems:(nullable NSMutableArray<id<ReadingListListItem>>*)readArray + unreadItems:(nullable NSMutableArray<id<ReadingListListItem>>*)unreadArray; // Fetches the |faviconURL| of this |item|, notifies the data sink when // receiving the favicon. -- (void)fetchFaviconForItem:(nonnull CollectionViewItem*)item; +- (void)fetchFaviconForItem:(nonnull id<ReadingListListItem>)item; // Prepares the data source for batch updates. The UI is not notified for the // updates happenning between |-beginBatchUpdates| and |-endBatchUpdates|.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm index ab35cf8..60558cde 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
@@ -16,10 +16,10 @@ #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" #import "ios/chrome/browser/ui/commands/reading_list_add_command.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h" +#import "ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_cell.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar_button.h" #include "ios/chrome/browser/ui/tools_menu/public/tools_menu_constants.h" #include "ios/chrome/browser/ui/ui_util.h" @@ -275,7 +275,7 @@ // Returns a match for the Reading List Empty Collection Background. id<GREYMatcher> EmptyBackground() { return grey_accessibilityID( - [ReadingListEmptyCollectionBackground accessibilityIdentifier]); + [EmptyReadingListBackgroundView accessibilityIdentifier]); } // Adds the current page to the Reading List.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h deleted file mode 100644 index edd28f6..0000000 --- a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_EMPTY_COLLECTION_BACKGROUND_H_ -#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_EMPTY_COLLECTION_BACKGROUND_H_ - -#import <UIKit/UIKit.h> - -@interface ReadingListEmptyCollectionBackground : UIView - -- (instancetype)init NS_DESIGNATED_INITIALIZER; - -- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; -- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; - -+ (NSString*)accessibilityIdentifier; - -@end - -#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_EMPTY_COLLECTION_BACKGROUND_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item.h b/ios/chrome/browser/ui/reading_list/reading_list_list_item.h index cd32c3c..2360ad9 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_list_item.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item.h
@@ -11,7 +11,7 @@ class GURL; @class FaviconAttributes; -@class ReadingListListViewItemCustomActionFactory; +@class ReadingListListItemCustomActionFactory; // Protocol used to supply reading list data to list items. @protocol ReadingListListItem<NSObject> @@ -30,7 +30,7 @@ @property(nonatomic, copy) NSString* distillationDateText; // The custom action factory. @property(nonatomic, weak) - ReadingListListViewItemCustomActionFactory* customActionFactory; + ReadingListListItemCustomActionFactory* customActionFactory; // Attributes for favicon. @property(nonatomic, strong) FaviconAttributes* attributes;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h b/ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h new file mode 100644 index 0000000..2bd0fca --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h
@@ -0,0 +1,26 @@ +// 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 IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_ACCESSIBILITY_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_ACCESSIBILITY_DELEGATE_H_ + +@protocol ReadingListListItem; + +// Protocol used to implement custom accessibility actions for cells set up by +// ReadingListListItems. +@protocol ReadingListListItemAccessibilityDelegate + +// Returns whether the entry is read. +- (BOOL)isItemRead:(id<ReadingListListItem>)item; + +- (void)deleteItem:(id<ReadingListListItem>)item; +- (void)openItemInNewTab:(id<ReadingListListItem>)item; +- (void)openItemInNewIncognitoTab:(id<ReadingListListItem>)item; +- (void)openItemOffline:(id<ReadingListListItem>)item; +- (void)markItemRead:(id<ReadingListListItem>)item; +- (void)markItemUnread:(id<ReadingListListItem>)item; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_ACCESSIBILITY_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h b/ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h new file mode 100644 index 0000000..cf3c517 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h
@@ -0,0 +1,28 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_CUSTOM_ACTION_FACTORY_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_CUSTOM_ACTION_FACTORY_H_ + +#import <UIKit/UIKit.h> + +@protocol ReadingListListItem; +@protocol ReadingListListItemAccessibilityDelegate; + +// Factory object that creates arrays of custom accessibility actions for +// ListItems used by the reading list. +@interface ReadingListListItemCustomActionFactory : NSObject + +// Delegate for the accessibility actions. +@property(nonatomic, weak) id<ReadingListListItemAccessibilityDelegate> + accessibilityDelegate; + +// Creates an array of custom a11y actions for a reading list cell configured +// for |item| with |status|. +- (NSArray<UIAccessibilityCustomAction*>*)customActionsForItem: + (id<ReadingListListItem>)item; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_CUSTOM_ACTION_FACTORY_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.mm b/ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.mm similarity index 67% rename from ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.mm rename to ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.mm index ac44a65..47e4fd9 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.mm
@@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_accessibility_delegate.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h" #import "ios/chrome/browser/ui/util/pasteboard_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -20,15 +21,13 @@ @interface ReadingListCustomAction : UIAccessibilityCustomAction // The reading list item. -@property(nonatomic, readonly, strong) ListItem* item; -// The URL. -@property(nonatomic, readonly) GURL itemURL; +@property(nonatomic, readonly, strong) id<ReadingListListItem> item; - (instancetype)initWithName:(NSString*)name target:(id)target selector:(SEL)selector - item:(ListItem*)item - URL:(const GURL&)URL NS_DESIGNATED_INITIALIZER; + item:(id<ReadingListListItem>)item + NS_DESIGNATED_INITIALIZER; - (instancetype)initWithName:(NSString*)name target:(id)target selector:(SEL)selector NS_UNAVAILABLE; @@ -36,54 +35,46 @@ @implementation ReadingListCustomAction @synthesize item = _item; -@synthesize itemURL = _itemURL; - (instancetype)initWithName:(NSString*)name target:(id)target selector:(SEL)selector - item:(ListItem*)item - URL:(const GURL&)URL { + item:(id<ReadingListListItem>)item { if (self = [super initWithName:name target:target selector:selector]) { _item = item; - _itemURL = URL; } return self; } @end -#pragma mark - ReadingListListViewItemCustomActionFactory +#pragma mark - ReadingListListItemCustomActionFactory -@implementation ReadingListListViewItemCustomActionFactory +@implementation ReadingListListItemCustomActionFactory @synthesize accessibilityDelegate = _accessibilityDelegate; -- (NSArray<UIAccessibilityCustomAction*>*) -customActionsForItem:(ListItem*)item - withURL:(const GURL&)URL - distillationStatus:(ReadingListUIDistillationStatus)status { +- (NSArray<UIAccessibilityCustomAction*>*)customActionsForItem: + (id<ReadingListListItem>)item { ReadingListCustomAction* deleteAction = [[ReadingListCustomAction alloc] initWithName:l10n_util::GetNSString(IDS_IOS_READING_LIST_DELETE_BUTTON) target:self - selector:@selector(deleteEntry:) - item:item - URL:URL]; + selector:@selector(deleteItem:) + item:item]; ReadingListCustomAction* toggleReadStatus = nil; - if ([self.accessibilityDelegate isEntryRead:item]) { + if ([self.accessibilityDelegate isItemRead:item]) { toggleReadStatus = [[ReadingListCustomAction alloc] initWithName:l10n_util::GetNSString( IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON) target:self selector:@selector(markUnread:) - item:item - URL:URL]; + item:item]; } else { toggleReadStatus = [[ReadingListCustomAction alloc] initWithName:l10n_util::GetNSString( IDS_IOS_READING_LIST_MARK_READ_BUTTON) target:self selector:@selector(markRead:) - item:item - URL:URL]; + item:item]; } ReadingListCustomAction* openInNewTabAction = [[ReadingListCustomAction alloc] @@ -91,28 +82,25 @@ IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) target:self selector:@selector(openInNewTab:) - item:item - URL:URL]; + item:item]; ReadingListCustomAction* openInNewIncognitoTabAction = [[ReadingListCustomAction alloc] initWithName:l10n_util::GetNSString( IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) target:self selector:@selector(openInNewIncognitoTab:) - item:item - URL:URL]; + item:item]; ReadingListCustomAction* copyURLAction = [[ReadingListCustomAction alloc] initWithName:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPY) target:self selector:@selector(copyURL:) - item:item - URL:URL]; + item:item]; NSMutableArray* customActions = [NSMutableArray arrayWithObjects:deleteAction, toggleReadStatus, openInNewTabAction, openInNewIncognitoTabAction, copyURLAction, nil]; - if (status == ReadingListUIDistillationStatusSuccess) { + if (item.distillationState == ReadingListUIDistillationStatusSuccess) { // Add the possibility to open offline version only if the entry is // distilled. ReadingListCustomAction* openOfflineAction = @@ -121,8 +109,7 @@ IDS_IOS_READING_LIST_CONTENT_CONTEXT_OFFLINE) target:self selector:@selector(openOffline:) - item:item - URL:URL]; + item:item]; [customActions addObject:openOfflineAction]; } @@ -130,38 +117,38 @@ return customActions; } -- (BOOL)deleteEntry:(ReadingListCustomAction*)action { - [self.accessibilityDelegate deleteEntry:action.item]; +- (BOOL)deleteItem:(ReadingListCustomAction*)action { + [self.accessibilityDelegate deleteItem:action.item]; return YES; } - (BOOL)markRead:(ReadingListCustomAction*)action { - [self.accessibilityDelegate markEntryRead:action.item]; + [self.accessibilityDelegate markItemRead:action.item]; return YES; } - (BOOL)markUnread:(ReadingListCustomAction*)action { - [self.accessibilityDelegate markEntryUnread:action.item]; + [self.accessibilityDelegate markItemUnread:action.item]; return YES; } - (BOOL)openInNewTab:(ReadingListCustomAction*)action { - [self.accessibilityDelegate openEntryInNewTab:action.item]; + [self.accessibilityDelegate openItemInNewTab:action.item]; return YES; } - (BOOL)openInNewIncognitoTab:(ReadingListCustomAction*)action { - [self.accessibilityDelegate openEntryInNewIncognitoTab:action.item]; + [self.accessibilityDelegate openItemInNewIncognitoTab:action.item]; return YES; } - (BOOL)copyURL:(ReadingListCustomAction*)action { - StoreURLInPasteboard(action.itemURL); + StoreURLInPasteboard(action.item.entryURL); return YES; } - (BOOL)openOffline:(ReadingListCustomAction*)action { - [self.accessibilityDelegate openEntryOffline:action.item]; + [self.accessibilityDelegate openItemOffline:action.item]; return YES; }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h b/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h new file mode 100644 index 0000000..ab76c21 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h
@@ -0,0 +1,37 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_FACTORY_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_FACTORY_H_ + +#import <UIKit/UIKit.h> + +@class ListItem; +class ReadingListEntry; +@protocol ReadingListListItem; +@protocol ReadingListListItemAccessibilityDelegate; + +// Factory object that produces ListItems for Reading List. +@interface ReadingListListItemFactory : NSObject + +// A factory that produces ReadingListTableViewItems. ++ (instancetype)tableViewItemFactory; + +// A factory that produces ReadingListCollectionViewItems. ++ (instancetype)collectionViewItemFactory; + +// Use either |+tableViewItemFactory| or |+collectionViewItemFactory|. +- (instancetype)init NS_UNAVAILABLE; + +// The accessibility delegate to use for the created items. +@property(nonatomic, weak) id<ReadingListListItemAccessibilityDelegate> + accessibilityDelegate; + +// Factory method that provides a ListItem for the reading list. +- (ListItem<ReadingListListItem>*)cellItemForReadingListEntry: + (const ReadingListEntry*)entry; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_FACTORY_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.mm b/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.mm new file mode 100644 index 0000000..5ca6401 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.mm
@@ -0,0 +1,105 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" + +#include "base/logging.h" +#include "base/mac/foundation_util.h" +#include "base/strings/sys_string_conversions.h" +#include "components/reading_list/core/reading_list_entry.h" +#include "components/url_formatter/url_formatter.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_table_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_utils.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +// The different types of items to be vended by the factory. +enum class ItemFactoryType { TABLE, COLLECTION }; +} // namespace + +@interface ReadingListListItemFactory () + +// The factory type. +@property(nonatomic, assign) ItemFactoryType factoryType; +// The factory supplying custom accessibility actions to the items. +@property(nonatomic, readonly, strong) + ReadingListListItemCustomActionFactory* customActionFactory; + +// Initializer for a factory of |factoryType|. +- (instancetype)initWithFactoryType:(ItemFactoryType)factoryType + NS_DESIGNATED_INITIALIZER; + +@end + +@implementation ReadingListListItemFactory +@synthesize factoryType = _factoryType; +@synthesize customActionFactory = _customActionFactory; + +- (instancetype)initWithFactoryType:(ItemFactoryType)factoryType { + if (self = [super init]) { + _factoryType = factoryType; + _customActionFactory = + [[ReadingListListItemCustomActionFactory alloc] init]; + } + return self; +} + +#pragma mark Accessors + +- (void)setAccessibilityDelegate: + (id<ReadingListListItemAccessibilityDelegate>)accessibilityDelegate { + self.customActionFactory.accessibilityDelegate = accessibilityDelegate; +} + +- (id<ReadingListListItemAccessibilityDelegate>)accessibilityDelegate { + return self.customActionFactory.accessibilityDelegate; +} + +#pragma mark Public + ++ (instancetype)tableViewItemFactory { + return [[ReadingListListItemFactory alloc] + initWithFactoryType:ItemFactoryType::TABLE]; +} + ++ (instancetype)collectionViewItemFactory { + return [[ReadingListListItemFactory alloc] + initWithFactoryType:ItemFactoryType::COLLECTION]; +} + +- (ListItem<ReadingListListItem>*)cellItemForReadingListEntry: + (const ReadingListEntry*)entry { + ListItem<ReadingListListItem>* item = + self.factoryType == ItemFactoryType::TABLE + ? [[ReadingListTableViewItem alloc] initWithType:0] + : [[ReadingListCollectionViewItem alloc] initWithType:0]; + item.title = base::SysUTF8ToNSString(entry->Title()); + const GURL& URL = entry->URL(); + item.entryURL = URL; + item.faviconPageURL = + entry->DistilledURL().is_valid() ? entry->DistilledURL() : URL; + item.distillationState = + reading_list::UIStatusFromModelStatus(entry->DistilledState()); + BOOL hasDistillationDetails = + entry->DistilledState() == ReadingListEntry::PROCESSED && + entry->DistillationSize() != 0 && entry->DistillationTime() != 0; + int64_t distillationDate = + hasDistillationDetails ? entry->DistillationTime() : 0; + item.distillationDateText = + GetReadingListCellDistillationDateText(distillationDate); + int64_t distillationSize = + hasDistillationDetails ? entry->DistillationSize() : 0; + item.distillationSizeText = + GetReadingListCellDistillationSizeText(distillationSize); + item.customActionFactory = self.customActionFactory; + return item; +} + +@end
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory_unittest.mm b/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory_unittest.mm new file mode 100644 index 0000000..08845a42 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_factory_unittest.mm
@@ -0,0 +1,63 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" + +#include "base/time/time.h" +#include "components/reading_list/core/reading_list_entry.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_table_view_item.h" +#include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#include "url/gurl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +class ReadingListListItemFactoryTest : public PlatformTest { + public: + ReadingListListItemFactoryTest() + : PlatformTest(), + entry_(GURL("https://www.google.com"), "Google", base::Time::Now()) {} + + protected: + const ReadingListEntry entry_; + + private: + DISALLOW_COPY_AND_ASSIGN(ReadingListListItemFactoryTest); +}; + +// Tests that the accessibility delegate is properly passed to the generated +// ListItems. +TEST_F(ReadingListListItemFactoryTest, SetA11yDelegate) { + id<ReadingListListItemAccessibilityDelegate> mockDelegate = + OCMProtocolMock(@protocol(ReadingListListItemAccessibilityDelegate)); + ReadingListListItemFactory* factory = + [ReadingListListItemFactory tableViewItemFactory]; + factory.accessibilityDelegate = mockDelegate; + id<ReadingListListItem> item = [factory cellItemForReadingListEntry:&entry_]; + EXPECT_EQ(item.customActionFactory.accessibilityDelegate, mockDelegate); +} + +// Tests that |+tableViewItemFactory| returns ReadingListTableViewItems. +TEST_F(ReadingListListItemFactoryTest, TableViewItem) { + ReadingListListItemFactory* factory = + [ReadingListListItemFactory tableViewItemFactory]; + id<ReadingListListItem> item = [factory cellItemForReadingListEntry:&entry_]; + EXPECT_TRUE([item isKindOfClass:[ReadingListTableViewItem class]]); +} + +// Tests that |+collectionViewItemFactory| returns +// ReadingListCollectionViewItems. +TEST_F(ReadingListListItemFactoryTest, CollectionViewItem) { + ReadingListListItemFactory* factory = + [ReadingListListItemFactory collectionViewItemFactory]; + id<ReadingListListItem> item = [factory cellItemForReadingListEntry:&entry_]; + EXPECT_TRUE([item isKindOfClass:[ReadingListCollectionViewItem class]]); +}
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_item_updater.h b/ios/chrome/browser/ui/reading_list/reading_list_list_item_updater.h new file mode 100644 index 0000000..b1c45af --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_updater.h
@@ -0,0 +1,16 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_UPDATER_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_UPDATER_H_ + +#import <Foundation/Foundation.h> + +@protocol ReadingListListItem; + +// Typedef for a block taking a ReadingListListItem as parameter and returning +// nothing. +typedef void (^ReadingListListItemUpdater)(id<ReadingListListItem> item); + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_UPDATER_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h b/ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h similarity index 87% rename from ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h rename to ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h index 577bed5..853f1c1 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_UTIL_H_ -#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_UTIL_H_ +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_UTIL_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_UTIL_H_ #import <Foundation/Foundation.h> @@ -30,4 +30,4 @@ BOOL AreReadingListListItemsEqual(id<ReadingListListItem> first, id<ReadingListListItem> second); -#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_UTIL_H_ +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_ITEM_UTIL_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.mm b/ios/chrome/browser/ui/reading_list/reading_list_list_item_util.mm similarity index 94% rename from ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.mm rename to ios/chrome/browser/ui/reading_list/reading_list_list_item_util.mm index a549460..9d15fdc 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_item_util.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h" #include "base/i18n/time_formatting.h" #include "base/strings/sys_string_conversions.h" @@ -35,12 +35,16 @@ } NSString* GetReadingListCellDistillationSizeText(int64_t distillation_size) { + if (!distillation_size) + return nil; return [NSByteCountFormatter stringFromByteCount:distillation_size countStyle:NSByteCountFormatterCountStyleFile]; } NSString* GetReadingListCellDistillationDateText(int64_t distillation_date) { + if (!distillation_date) + return nil; int64_t now = (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); int64_t elapsed = now - distillation_date; if (elapsed < base::Time::kMicrosecondsPerMinute) {
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_audience.h b/ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_audience.h new file mode 100644 index 0000000..594d151 --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_audience.h
@@ -0,0 +1,16 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_CONTROLLER_AUDIENCE_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_CONTROLLER_AUDIENCE_H_ + +// Audience for the Reading List view controllers. +@protocol ReadingListListViewControllerAudience + +// Whether the collection has items. +- (void)readingListHasItems:(BOOL)hasItems; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_CONTROLLER_AUDIENCE_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h b/ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h new file mode 100644 index 0000000..3e90fad --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h
@@ -0,0 +1,44 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_CONTROLLER_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +@class ListItem; +@protocol ReadingListListItem; + +// Delegate protocol for actions performed by the list view implementations, +// managing the visibility of the toolbar, dismissing the Reading List View and +// opening elements. +@protocol ReadingListListViewControllerDelegate<NSObject> + +// Dismisses the Reading List View. +- (void)dismissReadingListListViewController: + (UIViewController*)readingListCollectionViewController; + +// Displays the context menu for the |item|. |menuLocation| is used as the +// anchor of the context menu in the |viewController.view|'s coordinates. +- (void)readingListListViewController:(UIViewController*)viewController + displayContextMenuForItem:(id<ReadingListListItem>)item + atPoint:(CGPoint)menuLocation; + +// Opens |item.entryURL|. +- (void)readingListListViewController:(UIViewController*)viewController + openItem:(id<ReadingListListItem>)item; + +// Opens the entry corresponding to the |item| in a new tab, |incognito| or not. +- (void)readingListListViewController:(UIViewController*)viewController + openItemInNewTab:(id<ReadingListListItem>)item + incognito:(BOOL)incognito; + +// Opens the offline version of the entry corresponding to the |item| in a new +// tab, if available. +- (void)readingListListViewController:(UIViewController*)viewController + openItemOfflineInNewTab:(id<ReadingListListItem>)item; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_accessibility_delegate.h b/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_accessibility_delegate.h deleted file mode 100644 index be7387b..0000000 --- a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_accessibility_delegate.h +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_ACCESSIBILITY_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_ACCESSIBILITY_DELEGATE_H_ - -@class ListItem; - -@protocol ReadingListListViewItemAccessibilityDelegate - -// Returns whether the entry is read. -- (BOOL)isEntryRead:(ListItem*)item; - -- (void)deleteEntry:(ListItem*)item; -- (void)openEntryInNewTab:(ListItem*)item; -- (void)openEntryInNewIncognitoTab:(ListItem*)item; -- (void)openEntryOffline:(ListItem*)item; -- (void)markEntryRead:(ListItem*)item; -- (void)markEntryUnread:(ListItem*)item; - -@end - -#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_ACCESSIBILITY_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h b/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h deleted file mode 100644 index b0887c39b..0000000 --- a/ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_CUSTOM_ACTION_FACTORY_H_ -#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_CUSTOM_ACTION_FACTORY_H_ - -#import <UIKit/UIKit.h> - -#import "ios/chrome/browser/ui/reading_list/reading_list_ui_distillation_status.h" - -class GURL; -@class ListItem; -@protocol ReadingListListViewItemAccessibilityDelegate; - -// Factory object that creates arrays of custom accessibility actions for -// ListItems used by the reading list. -@interface ReadingListListViewItemCustomActionFactory : NSObject - -// Delegate for the accessibility actions. -@property(nonatomic, weak) id<ReadingListListViewItemAccessibilityDelegate> - accessibilityDelegate; - -// Creates an array of custom a11y actions for a reading list cell configured -// for |item| with |status|. -- (NSArray<UIAccessibilityCustomAction*>*) -customActionsForItem:(ListItem*)item - withURL:(const GURL&)URL - distillationStatus:(ReadingListUIDistillationStatus)status; - -@end - -#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_LIST_VIEW_ITEM_CUSTOM_ACTION_FACTORY_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_mediator.h b/ios/chrome/browser/ui/reading_list/reading_list_mediator.h index 2e66c90..70f34380 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_mediator.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_mediator.h
@@ -15,6 +15,7 @@ class GURL; class ReadingListEntry; +@class ReadingListListItemFactory; class ReadingListModel; // Mediator between the Model and the UI. @@ -22,16 +23,17 @@ - (nullable instancetype)init NS_UNAVAILABLE; -- (nullable instancetype)initWithModel:(nonnull ReadingListModel*)model - largeIconService: - (nonnull favicon::LargeIconService*)largeIconService +- (nullable instancetype) + initWithModel:(nonnull ReadingListModel*)model +largeIconService:(nonnull favicon::LargeIconService*)largeIconService + listItemFactory:(nonnull ReadingListListItemFactory*)itemFactory NS_DESIGNATED_INITIALIZER; // Returns the entry corresponding to the |item|. The item should be of type // ReadingListCollectionViewItem. Returns nullptr if there is no corresponding // entry. - (nullable const ReadingListEntry*)entryFromItem: - (nonnull CollectionViewItem*)item; + (nonnull id<ReadingListListItem>)item; // Marks the entry with |URL| as read. - (void)markEntryRead:(const GURL&)URL;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_mediator.mm b/ios/chrome/browser/ui/reading_list/reading_list_mediator.mm index 71d77155..4b255b7 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_mediator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_mediator.mm
@@ -16,7 +16,10 @@ #import "ios/chrome/browser/ui/favicon/favicon_attributes_provider.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" #import "ios/chrome/browser/ui/reading_list/reading_list_data_sink.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_table_view_item.h" #import "ios/chrome/browser/ui/reading_list/reading_list_utils.h" #import "ios/chrome/common/favicon/favicon_view.h" @@ -25,6 +28,7 @@ #endif namespace { +// Sorter function that orders ReadingListEntries by their update time. bool EntrySorter(const ReadingListEntry* rhs, const ReadingListEntry* lhs) { return rhs->UpdateTime() > lhs->UpdateTime(); } @@ -35,10 +39,15 @@ std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> _batchToken; } +// The model passed on initialization. @property(nonatomic, assign) ReadingListModel* model; +// Whether the consumer should be notified of model changes. @property(nonatomic, assign) BOOL shouldMonitorModel; +// The ListItem factory passed on initialization. +@property(nonatomic, strong) ReadingListListItemFactory* itemFactory; + // Lazily instantiated. @property(nonatomic, strong, readonly) FaviconAttributesProvider* attributesProvider; @@ -50,20 +59,23 @@ @implementation ReadingListMediator -@synthesize model = _model; @synthesize dataSink = _dataSink; +@synthesize model = _model; @synthesize shouldMonitorModel = _shouldMonitorModel; +@synthesize itemFactory = _itemFactory; @synthesize attributesProvider = _attributesProvider; @synthesize largeIconService = _largeIconService; #pragma mark - Public - (instancetype)initWithModel:(ReadingListModel*)model - largeIconService:(favicon::LargeIconService*)largeIconService { + largeIconService:(favicon::LargeIconService*)largeIconService + listItemFactory:(ReadingListListItemFactory*)itemFactory { self = [super init]; if (self) { _model = model; _largeIconService = largeIconService; + _itemFactory = itemFactory; _shouldMonitorModel = YES; // This triggers the callback method. Should be created last. @@ -72,10 +84,8 @@ return self; } -- (const ReadingListEntry*)entryFromItem:(CollectionViewItem*)item { - ReadingListCollectionViewItem* readingListItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); - return self.model->GetEntryByURL(readingListItem.entryURL); +- (const ReadingListEntry*)entryFromItem:(id<ReadingListListItem>)item { + return self.model->GetEntryByURL(item.entryURL); } - (void)markEntryRead:(const GURL&)URL { @@ -84,11 +94,9 @@ #pragma mark - ReadingListDataSource -- (BOOL)isEntryRead:(CollectionViewItem*)item { - ReadingListCollectionViewItem* readingListItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); +- (BOOL)isItemRead:(id<ReadingListListItem>)item { const ReadingListEntry* readingListEntry = - self.model->GetEntryByURL(readingListItem.entryURL); + self.model->GetEntryByURL(item.entryURL); if (!readingListEntry) { return NO; @@ -103,27 +111,21 @@ self.dataSink = nil; } -- (void)setReadStatus:(BOOL)read forItem:(CollectionViewItem*)item { - ReadingListCollectionViewItem* readingListItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); - self.model->SetReadStatus(readingListItem.entryURL, read); +- (void)setReadStatus:(BOOL)read forItem:(id<ReadingListListItem>)item { + self.model->SetReadStatus(item.entryURL, read); } - (const ReadingListEntry*)entryWithURL:(const GURL&)URL { return self.model->GetEntryByURL(URL); } -- (void)removeEntryFromItem:(CollectionViewItem*)item { - ReadingListCollectionViewItem* readingListItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); - [self logDeletionOfItem:readingListItem]; - self.model->RemoveEntryByURL(readingListItem.entryURL); +- (void)removeEntryFromItem:(id<ReadingListListItem>)item { + [self logDeletionOfItem:item]; + self.model->RemoveEntryByURL(item.entryURL); } -- (void)fillReadItems:(NSMutableArray<CollectionViewItem*>*)readArray - unreadItems:(NSMutableArray<CollectionViewItem*>*)unreadArray - withCustomActionFactory: - (ReadingListListViewItemCustomActionFactory*)customActionFactory { +- (void)fillReadItems:(NSMutableArray<id<ReadingListListItem>>*)readArray + unreadItems:(NSMutableArray<id<ReadingListListItem>>*)unreadArray { std::vector<const ReadingListEntry*> readEntries; std::vector<const ReadingListEntry*> unreadEntries; @@ -141,28 +143,23 @@ std::sort(unreadEntries.begin(), unreadEntries.end(), EntrySorter); for (const ReadingListEntry* entry : readEntries) { - [readArray - addObject:[self cellItemForReadingListEntry:entry - withCustomActionFactory:customActionFactory]]; + [readArray addObject:[self.itemFactory cellItemForReadingListEntry:entry]]; } for (const ReadingListEntry* entry : unreadEntries) { [unreadArray - addObject:[self cellItemForReadingListEntry:entry - withCustomActionFactory:customActionFactory]]; + addObject:[self.itemFactory cellItemForReadingListEntry:entry]]; } DCHECK(self.model->Keys().size() == [readArray count] + [unreadArray count]); } -- (void)fetchFaviconForItem:(CollectionViewItem*)item { - ReadingListCollectionViewItem* readingListItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>(item); - __weak ReadingListCollectionViewItem* weakItem = readingListItem; +- (void)fetchFaviconForItem:(id<ReadingListListItem>)item { + __weak id<ReadingListListItem> weakItem = item; __weak ReadingListMediator* weakSelf = self; void (^completionBlock)(FaviconAttributes* attributes) = ^(FaviconAttributes* attributes) { - ReadingListCollectionViewItem* strongItem = weakItem; + id<ReadingListListItem> strongItem = weakItem; ReadingListMediator* strongSelf = weakSelf; if (!strongSelf || !strongItem) { return; @@ -173,9 +170,8 @@ [strongSelf.dataSink itemHasChangedAfterDelay:strongItem]; }; - [self.attributesProvider - fetchFaviconAttributesForURL:readingListItem.faviconPageURL - completion:completionBlock]; + [self.attributesProvider fetchFaviconAttributesForURL:item.faviconPageURL + completion:completionBlock]; } - (void)beginBatchUpdates { @@ -212,7 +208,7 @@ } } -- (BOOL)ready { +- (BOOL)isReady { return self.model->loaded(); } @@ -220,7 +216,7 @@ return self.model->size() > 0; } -- (BOOL)hasRead { +- (BOOL)hasReadElements { return self.model->size() != self.model->unread_size(); } @@ -258,53 +254,11 @@ #pragma mark - Private -// Creates a ReadingListCollectionViewItem from a ReadingListEntry |entry|. -- (ReadingListCollectionViewItem*) -cellItemForReadingListEntry:(const ReadingListEntry*)entry - withCustomActionFactory: - (ReadingListListViewItemCustomActionFactory*)customActionFactory { - const GURL& url = entry->URL(); - ReadingListCollectionViewItem* item = - [[ReadingListCollectionViewItem alloc] initWithType:0]; - item.entryURL = entry->URL(); - item.faviconPageURL = - entry->DistilledURL().is_valid() ? entry->DistilledURL() : url; - - BOOL hasDistillationDetails = - entry->DistilledState() == ReadingListEntry::PROCESSED && - entry->DistillationSize() != 0 && entry->DistillationTime() != 0; - NSString* title = base::SysUTF8ToNSString(entry->Title()); - if ([title length]) { - item.title = title; - } else { - item.title = - base::SysUTF16ToNSString(url_formatter::FormatUrl(url.GetOrigin())); - } - int64_t distillationDate = - hasDistillationDetails ? entry->DistillationTime() : 0; - int64_t distillationSize = - hasDistillationDetails ? entry->DistillationSize() : 0; - item.distillationDateText = - distillationDate > 0 - ? GetReadingListCellDistillationDateText(distillationDate) - : nil; - item.distillationSizeText = - distillationSize > 0 - ? GetReadingListCellDistillationSizeText(distillationSize) - : nil; - item.distillationState = - reading_list::UIStatusFromModelStatus(entry->DistilledState()); - item.customActionFactory = customActionFactory; - return item; -} - // Whether the data source has changed. - (BOOL)hasDataSourceChanged { - NSMutableArray<CollectionViewItem*>* readArray = [NSMutableArray array]; - NSMutableArray<CollectionViewItem*>* unreadArray = [NSMutableArray array]; - [self fillReadItems:readArray - unreadItems:unreadArray - withCustomActionFactory:nil]; + NSMutableArray<id<ReadingListListItem>>* readArray = [NSMutableArray array]; + NSMutableArray<id<ReadingListListItem>>* unreadArray = [NSMutableArray array]; + [self fillReadItems:readArray unreadItems:unreadArray]; return [self currentSection:[self.dataSink readItems] isDifferentOfArray:readArray] || @@ -316,27 +270,25 @@ // |sectionIdentifier| and those in the |array|. The comparison is done with the // URL of the elements. If an element exist in both, the one in |currentSection| // will be overwriten with the informations contained in the one from|array|. -- (BOOL)currentSection:(NSArray<CollectionViewItem*>*)currentSection - isDifferentOfArray:(NSArray<CollectionViewItem*>*)array { +- (BOOL)currentSection:(NSArray<id<ReadingListListItem>>*)currentSection + isDifferentOfArray:(NSArray<id<ReadingListListItem>>*)array { if (currentSection.count != array.count) return YES; - NSMutableArray<ReadingListCollectionViewItem*>* itemsToReconfigure = + NSMutableArray<id<ReadingListListItem>>* itemsToReconfigure = [NSMutableArray array]; NSInteger index = 0; - for (ReadingListCollectionViewItem* newItem in array) { - ReadingListCollectionViewItem* oldItem = - base::mac::ObjCCastStrict<ReadingListCollectionViewItem>( - currentSection[index]); + for (id<ReadingListListItem> newItem in array) { + id<ReadingListListItem> oldItem = currentSection[index]; if (oldItem.entryURL == newItem.entryURL) { if (![oldItem isEqual:newItem]) { + [itemsToReconfigure addObject:oldItem]; oldItem.title = newItem.title; oldItem.entryURL = newItem.entryURL; oldItem.distillationState = newItem.distillationState; oldItem.distillationDateText = newItem.distillationDateText; oldItem.distillationSizeText = newItem.distillationSizeText; - [itemsToReconfigure addObject:oldItem]; } if (oldItem.faviconPageURL != newItem.faviconPageURL) { oldItem.faviconPageURL = newItem.faviconPageURL; @@ -353,7 +305,7 @@ } // Logs the deletions histograms for the entry associated with |item|. -- (void)logDeletionOfItem:(CollectionViewItem*)item { +- (void)logDeletionOfItem:(id<ReadingListListItem>)item { const ReadingListEntry* entry = [self entryFromItem:item]; if (!entry)
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm b/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm index a888055d..f99875a 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm
@@ -14,8 +14,9 @@ #include "components/url_formatter/url_formatter.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_accessibility_delegate.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_factory.h" #include "ios/web/public/test/test_web_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -57,9 +58,11 @@ large_icon_service_.reset(new favicon::LargeIconService( &mock_favicon_service_, /*image_fetcher=*/nullptr)); - mediator_ = - [[ReadingListMediator alloc] initWithModel:model_.get() - largeIconService:large_icon_service_.get()]; + mediator_ = [[ReadingListMediator alloc] + initWithModel:model_.get() + largeIconService:large_icon_service_.get() + listItemFactory:[ReadingListListItemFactory + collectionViewItemFactory]]; } protected: @@ -77,29 +80,18 @@ TEST_F(ReadingListMediatorTest, fillItems) { // Setup. - NSMutableArray<CollectionViewItem*>* readArray = [NSMutableArray array]; - NSMutableArray<CollectionViewItem*>* unreadArray = [NSMutableArray array]; - ReadingListListViewItemCustomActionFactory* customActionFactory = - [[ReadingListListViewItemCustomActionFactory alloc] init]; + NSMutableArray<id<ReadingListListItem>>* readArray = [NSMutableArray array]; + NSMutableArray<id<ReadingListListItem>>* unreadArray = [NSMutableArray array]; // Action. - [mediator_ fillReadItems:readArray - unreadItems:unreadArray - withCustomActionFactory:customActionFactory]; + [mediator_ fillReadItems:readArray unreadItems:unreadArray]; // Tests. EXPECT_EQ(3U, [unreadArray count]); EXPECT_EQ(2U, [readArray count]); NSArray<ReadingListCollectionViewItem*>* rlReadArray = [readArray copy]; NSArray<ReadingListCollectionViewItem*>* rlUneadArray = [unreadArray copy]; - EXPECT_TRUE([rlUneadArray[0].title - isEqualToString:base::SysUTF16ToNSString(url_formatter::FormatUrl( - no_title_entry_url_.GetOrigin()))]); + EXPECT_TRUE([rlUneadArray[0].title isEqualToString:@""]); EXPECT_TRUE([rlReadArray[0].title isEqualToString:@"read2"]); EXPECT_TRUE([rlReadArray[1].title isEqualToString:@"read1"]); - EXPECT_EQ(customActionFactory, rlReadArray[0].customActionFactory); - EXPECT_EQ(customActionFactory, rlReadArray[1].customActionFactory); - EXPECT_EQ(customActionFactory, rlUneadArray[0].customActionFactory); - EXPECT_EQ(customActionFactory, rlUneadArray[1].customActionFactory); - EXPECT_EQ(customActionFactory, rlUneadArray[2].customActionFactory); }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h new file mode 100644 index 0000000..29e91ce --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h
@@ -0,0 +1,41 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_TABLE_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_TABLE_VIEW_CONTROLLER_H_ + +#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h" + +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_accessibility_delegate.h" + +@protocol ReadingListDataSource; +@protocol ReadingListListViewControllerAudience; +@protocol ReadingListListViewControllerDelegate; + +// View controller that displays reading list items in a table view. +@interface ReadingListTableViewController + : ChromeTableViewController<ReadingListListItemAccessibilityDelegate> + +// The delegate. +@property(nonatomic, weak) id<ReadingListListViewControllerDelegate> delegate; +// The audience that is interested in whether the table has any items. +@property(nonatomic, weak) id<ReadingListListViewControllerAudience> audience; +// The table's data source. +@property(nonatomic, weak) id<ReadingListDataSource> dataSource; + +// Initializers. +- (instancetype)init NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithTableViewStyle:(UITableViewStyle)style + appBarStyle: + (ChromeTableViewControllerStyle)appBarStyle + NS_UNAVAILABLE; + +// Prepares this view controller to be dismissed. +- (void)willBeDismissed; + +// Reloads all the data. +- (void)reloadData; + +@end +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm new file mode 100644 index 0000000..2596dee --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
@@ -0,0 +1,852 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h" + +#include "base/logging.h" +#include "base/mac/foundation_util.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" +#include "base/stl_util.h" +#include "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" +#import "ios/chrome/browser/ui/list_model/list_item+Controller.h" +#import "ios/chrome/browser/ui/reading_list/empty_reading_list_background_view.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_data_sink.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_data_source.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_updater.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_audience.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_toolbar_button_commands.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_toolbar_button_manager.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util_mac.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +// Types of ListItems used by the reading list UI. +typedef NS_ENUM(NSInteger, ItemType) { + ItemTypeHeader = kItemTypeEnumZero, + ItemTypeItem, +}; +// Identifiers for sections in the reading list. +typedef NS_ENUM(NSInteger, SectionIdentifier) { + SectionIdentifierUnread = kSectionIdentifierEnumZero, + SectionIdentifierRead, +}; +// Returns the ReadingListSelectionState corresponding with the provided numbers +// of read and unread items. +ReadingListSelectionState GetSelectionStateForSelectedCounts( + NSUInteger selected_unread_count, + NSUInteger selected_read_count) { + if (selected_read_count > 0 && selected_unread_count > 0) + return ReadingListSelectionState::READ_AND_UNREAD_ITEMS; + if (selected_read_count > 0) + return ReadingListSelectionState::ONLY_READ_ITEMS; + if (selected_unread_count > 0) + return ReadingListSelectionState::ONLY_UNREAD_ITEMS; + return ReadingListSelectionState::NONE; +} +} // namespace + +@interface ReadingListTableViewController ()<ReadingListDataSink, + ReadingListToolbarButtonCommands> + +// Redefine the model to return ReadingListListItems +@property(nonatomic, readonly) + TableViewModel<TableViewItem<ReadingListListItem>*>* tableViewModel; + +// Whether the data source has been modified while in editing mode. +@property(nonatomic, assign) BOOL dataSourceModifiedWhileEditing; +// The toolbar button manager. +@property(nonatomic, strong) ReadingListToolbarButtonManager* toolbarManager; +// The number of read and unread cells that are currently selected. +@property(nonatomic, assign) NSUInteger selectedUnreadItemCount; +@property(nonatomic, assign) NSUInteger selectedReadItemCount; +// The action sheet used to confirm whether items should be marked as read or +// unread. +@property(nonatomic, strong) ActionSheetCoordinator* markConfirmationSheet; +// The background to use when the table is empty. +@property(nonatomic, strong) UIView* emptyStateBackgroundView; + +@end + +@implementation ReadingListTableViewController +@synthesize delegate = _delegate; +@synthesize audience = _audience; +@synthesize dataSource = _dataSource; +@dynamic tableViewModel; +@synthesize dataSourceModifiedWhileEditing = _dataSourceModifiedWhileEditing; +@synthesize toolbarManager = _toolbarManager; +@synthesize selectedUnreadItemCount = _selectedUnreadItemCount; +@synthesize selectedReadItemCount = _selectedReadItemCount; +@synthesize markConfirmationSheet = _markConfirmationSheet; +@synthesize emptyStateBackgroundView = _emptyStateBackgroundView; + +- (instancetype)init { + self = [super initWithTableViewStyle:UITableViewStylePlain + appBarStyle:ChromeTableViewControllerStyleNoAppBar]; + if (self) { + _toolbarManager = [[ReadingListToolbarButtonManager alloc] init]; + _toolbarManager.commandHandler = self; + _emptyStateBackgroundView = [[EmptyReadingListBackgroundView alloc] init]; + } + return self; +} + +#pragma mark - Accessors + +- (void)setAudience:(id<ReadingListListViewControllerAudience>)audience { + if (_audience == audience) + return; + _audience = audience; + BOOL hasItems = self.dataSource.ready && self.dataSource.hasElements; + [_audience readingListHasItems:hasItems]; +} + +- (void)setDataSource:(id<ReadingListDataSource>)dataSource { + if (_dataSource == dataSource) + return; + _dataSource.dataSink = nil; + _dataSource = dataSource; + _dataSource.dataSink = self; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + if (self.editing == editing) + return; + [super setEditing:editing animated:animated]; + self.selectedUnreadItemCount = 0; + self.selectedReadItemCount = 0; + [self updateToolbarItems]; +} + +- (void)setSelectedUnreadItemCount:(NSUInteger)selectedUnreadItemCount { + if (_selectedUnreadItemCount == selectedUnreadItemCount) + return; + BOOL hadSelectedUnreadItems = _selectedUnreadItemCount > 0; + _selectedUnreadItemCount = selectedUnreadItemCount; + if ((_selectedUnreadItemCount > 0) != hadSelectedUnreadItems) + [self updateToolbarItems]; +} + +- (void)setSelectedReadItemCount:(NSUInteger)selectedReadItemCount { + if (_selectedReadItemCount == selectedReadItemCount) + return; + BOOL hadSelectedReadItems = _selectedReadItemCount > 0; + _selectedReadItemCount = selectedReadItemCount; + if ((_selectedReadItemCount > 0) != hadSelectedReadItems) + [self updateToolbarItems]; +} + +- (void)setMarkConfirmationSheet: + (ActionSheetCoordinator*)markConfirmationSheet { + if (_markConfirmationSheet == markConfirmationSheet) + return; + [_markConfirmationSheet stop]; + _markConfirmationSheet = markConfirmationSheet; +} + +#pragma mark - Public + +- (void)reloadData { + [self loadModel]; + if (self.viewLoaded) + [self.tableView reloadData]; +} + +- (void)willBeDismissed { + [self.dataSource dataSinkWillBeDismissed]; + self.markConfirmationSheet = nil; +} + ++ (NSString*)accessibilityIdentifier { + return @"ReadingListTableView"; +} + +#pragma mark - UIViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = l10n_util::GetNSString(IDS_IOS_TOOLS_MENU_READING_LIST); + + self.tableView.accessibilityIdentifier = + [[self class] accessibilityIdentifier]; + self.tableView.estimatedRowHeight = 56; + self.tableView.rowHeight = UITableViewAutomaticDimension; + self.tableView.estimatedSectionHeaderHeight = 56; + self.tableView.allowsMultipleSelectionDuringEditing = YES; + self.tableView.allowsMultipleSelection = YES; + + // Add gesture recognizer for the context menu. + UILongPressGestureRecognizer* longPressRecognizer = + [[UILongPressGestureRecognizer alloc] + initWithTarget:self + action:@selector(handleLongPress:)]; + [self.tableView addGestureRecognizer:longPressRecognizer]; +} + +#pragma mark - UITableViewDelegate + +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + if (self.editing) { + // Update the selected item counts and the toolbar buttons. + NSInteger sectionID = + [self.tableViewModel sectionIdentifierForSection:indexPath.section]; + if (sectionID == SectionIdentifierUnread) + self.selectedUnreadItemCount++; + if (sectionID == SectionIdentifierRead) + self.selectedReadItemCount++; + } else { + // Open the URL. + id<ReadingListListItem> item = + [self.tableViewModel itemAtIndexPath:indexPath]; + [self.delegate readingListListViewController:self openItem:item]; + } +} + +- (void)tableView:(UITableView*)tableView + didDeselectRowAtIndexPath:(NSIndexPath*)indexPath { + if (self.editing) { + // Update the selected item counts and the toolbar buttons. + NSInteger sectionID = + [self.tableViewModel sectionIdentifierForSection:indexPath.section]; + if (sectionID == SectionIdentifierUnread) + self.selectedUnreadItemCount--; + if (sectionID == SectionIdentifierRead) + self.selectedReadItemCount--; + } +} + +- (BOOL)tableView:(UITableView*)tableView + canEditRowAtIndexPath:(NSIndexPath*)indexPath { + return [self.tableViewModel itemAtIndexPath:indexPath].type == ItemTypeItem; +} + +#pragma mark - ChromeTableViewController + +- (void)loadModel { + [super loadModel]; + self.dataSourceModifiedWhileEditing = NO; + + if (self.dataSource.hasElements) { + [self loadItems]; + [self.audience readingListHasItems:YES]; + self.tableView.alwaysBounceVertical = YES; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; + self.tableView.backgroundView = nil; + } else { + [self tableIsEmpty]; + } +} + +#pragma mark - ReadingListDataSink + +- (void)dataSourceReady:(id<ReadingListDataSource>)dataSource { + [self reloadData]; +} + +- (void)dataSourceChanged { + // If we are editing and monitoring the model updates, set a flag to reload + // the data at the end of the editing. + if (self.editing) { + self.dataSourceModifiedWhileEditing = YES; + } else { + [self reloadData]; + } +} + +- (NSArray<id<ReadingListListItem>>*)readItems { + return [self itemsForSection:SectionIdentifierRead]; +} + +- (NSArray<id<ReadingListListItem>>*)unreadItems { + return [self itemsForSection:SectionIdentifierUnread]; +} + +- (void)itemHasChangedAfterDelay:(id<ReadingListListItem>)item { + TableViewItem<ReadingListListItem>* tableItem = + [self tableItemForReadingListItem:item]; + if ([self.tableViewModel hasItem:tableItem]) + [self reconfigureCellsForItems:@[ tableItem ]]; +} + +- (void)itemsHaveChanged:(NSArray<ListItem*>*)items { + [self reconfigureCellsForItems:items]; +} + +#pragma mark - ReadingListDataSink Helpers + +// Returns the items for the |sectionID|. +- (NSArray<id<ReadingListListItem>>*)itemsForSection: + (SectionIdentifier)sectionID { + TableViewModel* model = self.tableViewModel; + return [model hasSectionForSectionIdentifier:sectionID] + ? [model itemsInSectionWithIdentifier:sectionID] + : nil; +} + +#pragma mark - ReadingListListItemAccessibilityDelegate + +- (BOOL)isItemRead:(id<ReadingListListItem>)item { + return [self.dataSource isItemRead:item]; +} + +- (void)deleteItem:(id<ReadingListListItem>)item { + TableViewModel* model = self.tableViewModel; + TableViewItem* tableViewItem = base::mac::ObjCCastStrict<TableViewItem>(item); + if ([model hasItem:tableViewItem]) + [self deleteItemsAtIndexPaths:@[ [model indexPathForItem:tableViewItem] ]]; +} + +- (void)openItemInNewTab:(id<ReadingListListItem>)item { + [self.delegate readingListListViewController:self + openItemInNewTab:item + incognito:NO]; +} + +- (void)openItemInNewIncognitoTab:(id<ReadingListListItem>)item { + [self.delegate readingListListViewController:self + openItemInNewTab:item + incognito:YES]; +} + +- (void)openItemOffline:(id<ReadingListListItem>)item { + [self.delegate readingListListViewController:self + openItemOfflineInNewTab:item]; +} + +- (void)markItemRead:(id<ReadingListListItem>)item { + TableViewModel* model = self.tableViewModel; + TableViewItem* tableViewItem = base::mac::ObjCCastStrict<TableViewItem>(item); + if ([model hasItem:tableViewItem + inSectionWithIdentifier:SectionIdentifierUnread]) { + [self markItemsAtIndexPaths:@[ [model indexPathForItem:tableViewItem] ] + withReadStatus:YES]; + } +} + +- (void)markItemUnread:(id<ReadingListListItem>)item { + TableViewModel* model = self.tableViewModel; + TableViewItem* tableViewItem = base::mac::ObjCCastStrict<TableViewItem>(item); + if ([model hasItem:tableViewItem + inSectionWithIdentifier:SectionIdentifierRead]) { + [self markItemsAtIndexPaths:@[ [model indexPathForItem:tableViewItem] ] + withReadStatus:NO]; + } +} + +#pragma mark - ReadingListToolbarButtonCommands + +- (void)enterReadingListEditMode { + if (self.editing) + return; + [self setEditing:YES animated:YES]; +} + +- (void)exitReadingListEditMode { + if (!self.editing) + return; + [self exitEditingModeAnimated:YES]; +} + +- (void)deleteAllReadReadingListItems { + base::RecordAction(base::UserMetricsAction("MobileReadingListDeleteRead")); + if (![self hasItemInSection:SectionIdentifierRead]) { + [self exitEditingModeAnimated:YES]; + return; + } + + // Delete the items in the data source and exit editing mode. + ReadingListListItemUpdater updater = ^(id<ReadingListListItem> item) { + [self.dataSource removeEntryFromItem:item]; + }; + [self updateItemsInSection:SectionIdentifierRead withItemUpdater:updater]; + [self exitEditingModeAnimated:YES]; + + // Update the model and table view for the deleted items. + UITableView* tableView = self.tableView; + TableViewModel* model = self.tableViewModel; + void (^updates)(void) = ^{ + NSInteger sectionIndex = + [model sectionForSectionIdentifier:SectionIdentifierRead]; + [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] + withRowAnimation:UITableViewRowAnimationFade]; + [model removeSectionWithIdentifier:SectionIdentifierRead]; + }; + void (^completion)(BOOL) = ^(BOOL) { + [self batchEditDidFinish]; + }; + [self performBatchTableViewUpdates:updates completion:completion]; +} + +- (void)deleteSelectedReadingListItems { + [self deleteItemsAtIndexPaths:self.tableView.indexPathsForSelectedRows]; + [self exitEditingModeAnimated:YES]; +} + +- (void)markSelectedReadingListItemsRead { + [self markItemsAtIndexPaths:self.tableView.indexPathsForSelectedRows + withReadStatus:YES]; +} + +- (void)markSelectedReadingListItemsUnread { + [self markItemsAtIndexPaths:self.tableView.indexPathsForSelectedRows + withReadStatus:NO]; +} + +- (void)markSelectedReadingListItemsAfterConfirmation { + [self initializeMarkConfirmationSheet]; + __weak ReadingListTableViewController* weakSelf = self; + __weak NSArray<NSIndexPath*>* weakSelectedIndexPaths = + self.tableView.indexPathsForSelectedRows; + NSString* markAsReadTitle = + l10n_util::GetNSStringWithFixup(IDS_IOS_READING_LIST_MARK_READ_BUTTON); + [self.markConfirmationSheet + addItemWithTitle:markAsReadTitle + action:^{ + [weakSelf markItemsAtIndexPaths:weakSelectedIndexPaths + withReadStatus:YES]; + weakSelf.markConfirmationSheet = nil; + } + style:UIAlertActionStyleDefault]; + NSString* markAsUnreadTitle = + l10n_util::GetNSStringWithFixup(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); + [self.markConfirmationSheet + addItemWithTitle:markAsUnreadTitle + action:^{ + [weakSelf markItemsAtIndexPaths:weakSelectedIndexPaths + withReadStatus:NO]; + weakSelf.markConfirmationSheet = nil; + } + style:UIAlertActionStyleDefault]; + [self.markConfirmationSheet start]; +} + +- (void)markAllReadingListItemsAfterConfirmation { + [self initializeMarkConfirmationSheet]; + __weak ReadingListTableViewController* weakSelf = self; + NSString* markAsReadTitle = l10n_util::GetNSStringWithFixup( + IDS_IOS_READING_LIST_MARK_ALL_READ_ACTION); + [self.markConfirmationSheet + addItemWithTitle:markAsReadTitle + action:^{ + [weakSelf markItemsInSection:SectionIdentifierUnread + withReadStatus:YES]; + weakSelf.markConfirmationSheet = nil; + } + style:UIAlertActionStyleDefault]; + NSString* markAsUnreadTitle = l10n_util::GetNSStringWithFixup( + IDS_IOS_READING_LIST_MARK_ALL_UNREAD_ACTION); + [self.markConfirmationSheet + addItemWithTitle:markAsUnreadTitle + action:^{ + [weakSelf markItemsInSection:SectionIdentifierRead + withReadStatus:NO]; + weakSelf.markConfirmationSheet = nil; + } + style:UIAlertActionStyleDefault]; + [self.markConfirmationSheet start]; +} + +#pragma mark - ReadingListToolbarButtonCommands Helpers + +// Creates a confirmation action sheet for the "Mark" toolbar button item. +- (void)initializeMarkConfirmationSheet { + self.markConfirmationSheet = + [self.toolbarManager markButtonConfirmationWithBaseViewController:self]; + + [self.markConfirmationSheet + addItemWithTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL) + action:nil + style:UIAlertActionStyleCancel]; +} + +#pragma mark - Item Loading Helpers + +// Uses self.dataSource to load the TableViewItems into self.tableViewModel. +- (void)loadItems { + NSMutableArray<id<ReadingListListItem>>* readArray = [NSMutableArray array]; + NSMutableArray<id<ReadingListListItem>>* unreadArray = [NSMutableArray array]; + [self.dataSource fillReadItems:readArray unreadItems:unreadArray]; + [self loadItemsFromArray:unreadArray toSection:SectionIdentifierUnread]; + [self loadItemsFromArray:readArray toSection:SectionIdentifierRead]; + + [self updateToolbarItems]; +} + +// Adds |items| to self.tableViewModel for the section designated by +// |sectionID|. +- (void)loadItemsFromArray:(NSArray<id<ReadingListListItem>>*)items + toSection:(SectionIdentifier)sectionID { + if (!items.count) + return; + + TableViewModel* model = self.tableViewModel; + [model addSectionWithIdentifier:sectionID]; + [model setHeader:[self headerForSection:sectionID] + forSectionWithIdentifier:sectionID]; + for (TableViewItem<ReadingListListItem>* item in items) { + item.type = ItemTypeItem; + [self.dataSource fetchFaviconForItem:item]; + [model addItem:item toSectionWithIdentifier:sectionID]; + } +} + +// Returns a TableViewTextItem that displays the title for the section +// designated by |sectionID|. +- (TableViewHeaderFooterItem*)headerForSection:(SectionIdentifier)sectionID { + TableViewTextHeaderFooterItem* header = + [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader]; + + switch (sectionID) { + case SectionIdentifierRead: + header.text = l10n_util::GetNSString(IDS_IOS_READING_LIST_READ_HEADER); + break; + case SectionIdentifierUnread: + header.text = l10n_util::GetNSString(IDS_IOS_READING_LIST_UNREAD_HEADER); + break; + } + return header; +} + +#pragma mark - Toolbar Helpers + +// Updates buttons displayed in the bottom toolbar. +- (void)updateToolbarItems { + self.toolbarManager.editing = self.tableView.editing; + self.toolbarManager.hasReadItems = + self.dataSource.hasElements && self.dataSource.hasReadElements; + self.toolbarManager.selectionState = GetSelectionStateForSelectedCounts( + self.selectedUnreadItemCount, self.selectedReadItemCount); + if (self.toolbarManager.buttonItemsUpdated) + [self setToolbarItems:[self.toolbarManager buttonItems] animated:YES]; +} + +#pragma mark - Item Editing Helpers + +// Returns |item| cast as a TableViewItem. +- (TableViewItem<ReadingListListItem>*)tableItemForReadingListItem: + (id<ReadingListListItem>)item { + return base::mac::ObjCCastStrict<TableViewItem<ReadingListListItem>>(item); +} + +// Applies |updater| to the items in |section|. The updates are done in reverse +// order of the cells in the section to keep the order. Monitoring of the +// data source updates are suspended during this time. +- (void)updateItemsInSection:(SectionIdentifier)section + withItemUpdater:(ReadingListListItemUpdater)updater { + DCHECK(updater); + [self.dataSource beginBatchUpdates]; + NSArray* items = [self.tableViewModel itemsInSectionWithIdentifier:section]; + // Read the objects in reverse order to keep the order (last modified first). + for (id<ReadingListListItem> item in [items reverseObjectEnumerator]) { + updater(item); + } + [self.dataSource endBatchUpdates]; +} + +// Applies |updater| to the items in |indexPaths|. The updates are done in +// reverse order |indexPaths| to keep the order. The monitoring of the data +// source updates are suspended during this time. +- (void)updateItemsAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths + withItemUpdater:(ReadingListListItemUpdater)updater { + DCHECK(updater); + [self.dataSource beginBatchUpdates]; + // Read the objects in reverse order to keep the order (last modified first). + for (NSIndexPath* indexPath in [indexPaths reverseObjectEnumerator]) { + updater([self.tableViewModel itemAtIndexPath:indexPath]); + } + [self.dataSource endBatchUpdates]; +} + +// Moves all the items from |fromSection| to |toSection| and removes the empty +// section from the collection. +- (void)moveItemsFromSection:(SectionIdentifier)fromSection + toSection:(SectionIdentifier)toSection { + NSInteger sourceSection = + [self.tableViewModel sectionForSectionIdentifier:fromSection]; + NSInteger itemCount = + [self.tableViewModel numberOfItemsInSection:sourceSection]; + + NSMutableArray* sortedIndexPaths = [NSMutableArray array]; + for (NSInteger row = 0; row < itemCount; ++row) { + NSIndexPath* itemPath = + [NSIndexPath indexPathForRow:row inSection:sourceSection]; + [sortedIndexPaths addObject:itemPath]; + } + + [self moveItemsAtIndexPaths:sortedIndexPaths toSection:toSection]; +} + +// Moves the items at |sortedIndexPaths| to |toSection|, removing any empty +// sections. +- (void)moveItemsAtIndexPaths:(NSArray*)sortedIndexPaths + toSection:(SectionIdentifier)toSection { + // Reconfigure cells, allowing the custom actions to be updated. + for (NSIndexPath* indexPath in sortedIndexPaths) { + [[self.tableViewModel itemAtIndexPath:indexPath] + configureCell:[self.tableView cellForRowAtIndexPath:indexPath] + withStyler:self.styler]; + } + + NSInteger sectionCreatedIndex = [self initializeTableViewSection:toSection]; + void (^updates)(void) = ^{ + NSInteger sectionIndex = + [self.tableViewModel sectionForSectionIdentifier:toSection]; + + NSInteger newItemIndex = 0; + for (NSIndexPath* indexPath in sortedIndexPaths) { + // The |sortedIndexPaths| is a copy of the index paths before the + // destination section has been added if necessary. The section part of + // the index potentially needs to be updated. + NSInteger updatedSection = indexPath.section; + if (updatedSection >= sectionCreatedIndex) + updatedSection++; + if (updatedSection == sectionIndex) { + // The item is already in the targeted section, there is no need to move + // it. + continue; + } + + NSIndexPath* updatedIndexPath = + [NSIndexPath indexPathForItem:indexPath.row inSection:updatedSection]; + NSIndexPath* indexPathForModel = + [NSIndexPath indexPathForItem:indexPath.item - newItemIndex + inSection:updatedSection]; + + // Index of the item in the new section. The newItemIndex is the index of + // this item in the targeted section. + NSIndexPath* newIndexPath = + [NSIndexPath indexPathForItem:newItemIndex++ inSection:sectionIndex]; + + [self moveItemWithModelIndex:indexPathForModel + tableViewIndex:updatedIndexPath + toIndex:newIndexPath]; + } + }; + void (^completion)(BOOL) = ^(BOOL) { + [self batchEditDidFinish]; + }; + [self performBatchTableViewUpdates:updates completion:completion]; +} + +// Moves the ListItem within self.tableViewModel at |modelIndex| and the +// UITableViewCell at |tableViewIndex| to |toIndexPath|. +- (void)moveItemWithModelIndex:(NSIndexPath*)modelIndex + tableViewIndex:(NSIndexPath*)tableViewIndex + toIndex:(NSIndexPath*)toIndexPath { + TableViewModel* model = self.tableViewModel; + TableViewItem* item = [model itemAtIndexPath:modelIndex]; + + // Move the item in |model|. + [self deleteItemAtIndexPathFromModel:modelIndex]; + NSInteger toSectionID = + [model sectionIdentifierForSection:toIndexPath.section]; + [model insertItem:item + inSectionWithIdentifier:toSectionID + atIndex:toIndexPath.row]; + + // Move the cells in the table view. + [self.tableView moveRowAtIndexPath:tableViewIndex toIndexPath:toIndexPath]; +} + +// Makes sure the table view section with |sectionID| exists with the correct +// header. Returns the index of the new section in the table view, or +// NSIntegerMax if no section has been created. +- (NSInteger)initializeTableViewSection:(SectionIdentifier)sectionID { + TableViewModel* model = self.tableViewModel; + if ([model hasSectionForSectionIdentifier:sectionID]) + return NSIntegerMax; + + // There are at most two sections in the table. The only time this creation + // will result in the index of 1 is while creating the read section when there + // are also unread items. + BOOL hasUnreadItems = [self hasItemInSection:SectionIdentifierUnread]; + BOOL creatingReadSection = (sectionID == SectionIdentifierRead); + NSInteger sectionIndex = (hasUnreadItems && creatingReadSection) ? 1 : 0; + + void (^updates)(void) = ^{ + [model insertSectionWithIdentifier:sectionID atIndex:sectionIndex]; + [model setHeader:[self headerForSection:sectionID] + forSectionWithIdentifier:sectionID]; + [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] + withRowAnimation:UITableViewRowAnimationFade]; + }; + [self performBatchTableViewUpdates:updates completion:nil]; + + return sectionIndex; +} + +// Whether the model has items in |sectionID|. +- (BOOL)hasItemInSection:(SectionIdentifier)sectionID { + return [self itemsForSection:sectionID].count > 0; +} + +// Deletes the items at |indexPaths|. +- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths { + // Delete the items in the data source and exit editing mode. + ReadingListListItemUpdater updater = ^(id<ReadingListListItem> item) { + [self.dataSource removeEntryFromItem:item]; + }; + [self updateItemsAtIndexPaths:indexPaths withItemUpdater:updater]; + [self exitEditingModeAnimated:YES]; + + // Update the model and table view for the deleted items. + UITableView* tableView = self.tableView; + NSArray* sortedIndexPaths = + [indexPaths sortedArrayUsingSelector:@selector(compare:)]; + void (^updates)(void) = ^{ + // Enumerate in reverse order to delete the items from the model. + for (NSIndexPath* indexPath in [sortedIndexPaths reverseObjectEnumerator]) { + [self deleteItemAtIndexPathFromModel:indexPath]; + } + [tableView deleteRowsAtIndexPaths:indexPaths + withRowAnimation:UITableViewRowAnimationFade]; + }; + void (^completion)(BOOL) = ^(BOOL) { + [self batchEditDidFinish]; + }; + [self performBatchTableViewUpdates:updates completion:completion]; +} + +// Deletes the ListItem corresponding to |indexPath| in the model. +- (void)deleteItemAtIndexPathFromModel:(NSIndexPath*)indexPath { + TableViewModel* model = self.tableViewModel; + NSInteger sectionID = [model sectionIdentifierForSection:indexPath.section]; + NSInteger itemType = [model itemTypeForIndexPath:indexPath]; + NSUInteger index = [model indexInItemTypeForIndexPath:indexPath]; + [model removeItemWithType:itemType + fromSectionWithIdentifier:sectionID + atIndex:index]; +} + +// Marks all the items at |indexPaths| as read or unread depending on |read|. +- (void)markItemsAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths + withReadStatus:(BOOL)read { + // Record metric. + base::RecordAction(base::UserMetricsAction( + read ? "MobileReadingListMarkRead" : "MobileReadingListMarkUnread")); + + // Mark the items as |read| and exit editing. + ReadingListListItemUpdater updater = ^(id<ReadingListListItem> item) { + [self.dataSource setReadStatus:read forItem:item]; + }; + NSArray* sortedIndexPaths = + [indexPaths sortedArrayUsingSelector:@selector(compare:)]; + [self updateItemsAtIndexPaths:sortedIndexPaths withItemUpdater:updater]; + [self exitEditingModeAnimated:YES]; + + // Move the items to the appropriate section. + SectionIdentifier toSection = + read ? SectionIdentifierRead : SectionIdentifierUnread; + [self moveItemsAtIndexPaths:sortedIndexPaths toSection:toSection]; +} + +// Marks items from |section| with as read or unread dending on |read|. +- (void)markItemsInSection:(SectionIdentifier)section + withReadStatus:(BOOL)read { + // Mark the items as |read| and exit editing. + ReadingListListItemUpdater updater = ^(id<ReadingListListItem> item) { + [self.dataSource setReadStatus:read forItem:item]; + }; + [self updateItemsInSection:section withItemUpdater:updater]; + [self exitEditingModeAnimated:YES]; + + // Move the items to the appropriate section. + SectionIdentifier toSection = + read ? SectionIdentifierRead : SectionIdentifierUnread; + [self moveItemsFromSection:section toSection:toSection]; +} + +// Cleanup function called in the completion block of editing operations. +- (void)batchEditDidFinish { + // Reload the items if the datasource was modified during the edit. + if (self.dataSourceModifiedWhileEditing) + [self reloadData]; + // Remove any newly emptied sections. + [self removeEmptySections]; +} + +// Removes the empty sections from the table and the model. +- (void)removeEmptySections { + UITableView* tableView = self.tableView; + TableViewModel* model = self.tableViewModel; + void (^updates)(void) = ^{ + SectionIdentifier sections[] = {SectionIdentifierRead, + SectionIdentifierUnread}; + for (size_t i = 0; i < base::size(sections); ++i) { + SectionIdentifier section = sections[i]; + + if ([model hasSectionForSectionIdentifier:section] && + ![self hasItemInSection:section]) { + // If |section| has no items, remove it from the model and the table + // view. + NSInteger sectionIndex = [model sectionForSectionIdentifier:section]; + [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] + withRowAnimation:UITableViewRowAnimationFade]; + [model removeSectionWithIdentifier:section]; + } + } + }; + [self performBatchTableViewUpdates:updates completion:nil]; + + if (!self.dataSource.hasElements) + [self tableIsEmpty]; + else + [self updateToolbarItems]; +} + +// Resets self.editing to NO, optionally with animation. +- (void)exitEditingModeAnimated:(BOOL)animated { + self.markConfirmationSheet = nil; + [self setEditing:NO animated:animated]; + [self updateToolbarItems]; +} + +#pragma mark - Emtpy Table Helpers + +// Called when the table is empty. +- (void)tableIsEmpty { + if (self.tableView.backgroundView == self.emptyStateBackgroundView) + return; + self.tableView.alwaysBounceVertical = NO; + self.tableView.backgroundView = self.emptyStateBackgroundView; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.audience readingListHasItems:NO]; +} + +#pragma mark - Gesture Helpers + +// Shows the context menu for a long press from |recognizer|. +- (void)handleLongPress:(UILongPressGestureRecognizer*)recognizer { + if (self.editing || recognizer.state != UIGestureRecognizerStateBegan) + return; + + CGPoint location = [recognizer locationOfTouch:0 inView:self.tableView]; + NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:location]; + if (!indexPath) + return; + + if (![self.tableViewModel hasItemAtIndexPath:indexPath]) + return; + + TableViewItem<ReadingListListItem>* item = + [self.tableViewModel itemAtIndexPath:indexPath]; + if (item.type != ItemTypeItem) + return; + + [self.delegate readingListListViewController:self + displayContextMenuForItem:item + atPoint:location]; +} + +@end
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm index 6488429..0014184 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm
@@ -9,8 +9,8 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_custom_action_factory.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_item_util.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_custom_action_factory.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_item_util.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #include "ios/chrome/browser/ui/ui_util.h" @@ -108,9 +108,7 @@ self.title, base::SysUTF8ToNSString(self.entryURL.host()), self.distillationState); cell.accessibilityCustomActions = - [self.customActionFactory customActionsForItem:self - withURL:self.entryURL - distillationStatus:self.distillationState]; + [self.customActionFactory customActionsForItem:self]; } #pragma mark - NSObject
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h index 7584304..3c4ce7e 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h
@@ -8,7 +8,7 @@ #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" @class ReadingListCollectionViewController; -@protocol ReadingListCollectionViewControllerDelegate; +@protocol ReadingListListViewControllerDelegate; // Container for the ReadingList Collection View Controller and the toolbar. It // handles the interactions between the two. @@ -25,8 +25,7 @@ - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; -@property(nonatomic, weak) id<ReadingListCollectionViewControllerDelegate> - delegate; +@property(nonatomic, weak) id<ReadingListListViewControllerDelegate> delegate; @end
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm index 27f1359..a0bee46 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm
@@ -8,6 +8,8 @@ #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_audience.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_list_view_controller_delegate.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" @@ -22,9 +24,8 @@ }; } -@interface ReadingListViewController ()< - ReadingListToolbarActions, - ReadingListCollectionViewControllerAudience> +@interface ReadingListViewController ()<ReadingListToolbarActions, + ReadingListListViewControllerAudience> @property(nonatomic, strong, readonly) ReadingListCollectionViewController* readingListCollectionViewController; @@ -86,7 +87,7 @@ #pragma mark UIAccessibilityAction - (BOOL)accessibilityPerformEscape { - [self.delegate dismissReadingListCollectionViewController: + [self.delegate dismissReadingListListViewController: self.readingListCollectionViewController]; return YES; } @@ -113,7 +114,7 @@ [self.readingListCollectionViewController exitEditingModePressed]; } -#pragma mark - ReadingListCollectionViewControllerAudience +#pragma mark - ReadingListListViewControllerAudience - (void)readingListHasItems:(BOOL)hasItems { if (hasItems) { @@ -140,15 +141,13 @@ - (NSArray*)keyCommands { __weak ReadingListViewController* weakSelf = self; - return @[ [UIKeyCommand - cr_keyCommandWithInput:UIKeyInputEscape - modifierFlags:Cr_UIKeyModifierNone - title:nil - action:^{ - [weakSelf.delegate - dismissReadingListCollectionViewController: - weakSelf.readingListCollectionViewController]; - }] ]; + return + @[ [UIKeyCommand cr_keyCommandWithInput:UIKeyInputEscape + modifierFlags:Cr_UIKeyModifierNone + title:nil + action:^{ + [weakSelf accessibilityPerformEscape]; + }] ]; } @end
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index 9a7bbfb..3ef6614 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -104,7 +104,6 @@ @interface RecentTabsTableViewController ()<SigninPromoViewConsumer, SigninPresenter, SyncPresenter, - TextButtonItemDelegate, UIGestureRecognizerDelegate> { std::unique_ptr<synced_sessions::SyncedSessions> _syncedSessions; } @@ -426,7 +425,6 @@ l10n_util::GetNSString(IDS_IOS_OPEN_TABS_SYNC_IS_OFF_MOBILE); signinSyncOffItem.buttonText = l10n_util::GetNSString(IDS_IOS_OPEN_TABS_ENABLE_SYNC_MOBILE); - signinSyncOffItem.delegate = self; [self.tableViewModel addItem:signinSyncOffItem toSectionWithIdentifier:SectionIdentifierOtherDevices]; } @@ -659,6 +657,14 @@ if (itemTypeSelected == ItemTypeOtherDevicesNoSessions) { cell.selectionStyle = UITableViewCellSelectionStyleNone; } + // Set button action method for ItemTypeOtherDevicesSyncOff. + if (itemTypeSelected == ItemTypeOtherDevicesSyncOff) { + TableViewTextButtonCell* tableViewTextButtonCell = + base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell); + [tableViewTextButtonCell.button addTarget:self + action:@selector(updateSyncState) + forControlEvents:UIControlEventTouchUpInside]; + } return cell; } @@ -1093,9 +1099,15 @@ [self.dispatcher showSyncPassphraseSettingsFromViewController:self]; } -#pragma mark - TextButtonItemDelegate +#pragma mark - SigninPresenter -- (void)performButtonAction { +- (void)showSignin:(ShowSigninCommand*)command { + [self.dispatcher showSignin:command baseViewController:self]; +} + +#pragma mark - Private Helpers + +- (void)updateSyncState { SyncSetupService::SyncServiceState syncState = GetSyncStateForBrowserState(_browserState); if (ShouldShowSyncSignin(syncState)) { @@ -1107,10 +1119,4 @@ } } -#pragma mark - SigninPresenter - -- (void)showSignin:(ShowSigninCommand*)command { - [self.dispatcher showSignin:command baseViewController:self]; -} - @end
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data_table_view_controller.mm index 7527009..2abb57f 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data_table_view_controller.mm
@@ -30,8 +30,7 @@ } @interface ClearBrowsingDataTableViewController ()< - TableViewTextLinkCellDelegate, - TextButtonItemDelegate> + TableViewTextLinkCellDelegate> // TODO(crbug.com/850699): remove direct dependency and replace with // delegate. @@ -121,7 +120,10 @@ base::mac::ObjCCastStrict<TableViewTextButtonCell>(cellToReturn); tableViewTextButtonCell.selectionStyle = UITableViewCellSelectionStyleNone; - tableViewTextButtonCell.delegate = self; + [tableViewTextButtonCell.button + addTarget:self + action:@selector(showClearBrowsingDataAlertController) + forControlEvents:UIControlEventTouchUpInside]; break; } case ItemTypeDataTypeBrowsingHistory: @@ -178,9 +180,9 @@ [self.localDispatcher openURL:copiedURL]; } -#pragma mark - TextButtonItemDelegate +#pragma mark - Private Helpers -- (void)performButtonAction { +- (void)showClearBrowsingDataAlertController { BrowsingDataRemoveMask dataTypeMaskToRemove = BrowsingDataRemoveMask::REMOVE_NOTHING; NSArray* dataTypeItems = [self.tableViewModel
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h index 82af8c1..d410400 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h
@@ -7,18 +7,10 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" -@protocol TextButtonItemDelegate<NSObject> -// Delegates an action to be performed by the presenter. -- (void)performButtonAction; - -@end - // TableViewTextButtonItem contains the model for // TableViewTextButtonCell. @interface TableViewTextButtonItem : TableViewItem -// EnableSyncActionDelegate to perform TableViewTextButtonCell actions. -@property(nonatomic, weak) id<TextButtonItemDelegate> delegate; // Text being displayed above the button. @property(nonatomic, readwrite, strong) NSString* text; // Text for cell button. @@ -33,11 +25,9 @@ // laid out vertically and centered. @interface TableViewTextButtonCell : UITableViewCell -// Delegate used to show sync settings options. -@property(nonatomic, weak) id<TextButtonItemDelegate> delegate; // Cell text information. @property(nonatomic, strong) UILabel* textLabel; -// Action button. +// Action button. Note: Set action method in the TableView datasource method. @property(nonatomic, strong) UIButton* button; @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm index fdd368d..394dc044 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm
@@ -33,7 +33,6 @@ @implementation TableViewTextButtonItem @synthesize buttonBackgroundColor = _buttonBackgroundColor; @synthesize buttonText = _buttonText; -@synthesize delegate = _delegate; @synthesize text = _text; - (instancetype)initWithType:(NSInteger)type { @@ -49,7 +48,6 @@ [super configureCell:tableCell withStyler:styler]; TableViewTextButtonCell* cell = base::mac::ObjCCastStrict<TableViewTextButtonCell>(tableCell); - cell.delegate = self.delegate; cell.textLabel.text = self.text; [cell.button setTitle:self.buttonText forState:UIControlStateNormal]; cell.button.backgroundColor = self.buttonBackgroundColor @@ -61,7 +59,6 @@ @end @implementation TableViewTextButtonCell -@synthesize delegate = _delegate; @synthesize textLabel = _textLabel; @synthesize button = _button; @@ -90,9 +87,6 @@ self.button.contentEdgeInsets = UIEdgeInsetsMake( buttonTitleVerticalContentInset, buttonTitleHorizontalContentInset, buttonTitleVerticalContentInset, buttonTitleHorizontalContentInset); - [self.button addTarget:self - action:@selector(performButtonAction) - forControlEvents:UIControlEventTouchUpInside]; // Vertical stackView to hold label and button. UIStackView* verticalStackView = [[UIStackView alloc] @@ -123,10 +117,4 @@ return self; } -#pragma mark - TextButtonItemDelegate - -- (void)performButtonAction { - [self.delegate performButtonAction]; -} - @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item_unittest.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item_unittest.mm index 33c53e2f..682b3e48 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item_unittest.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item_unittest.mm
@@ -20,20 +20,15 @@ using TableViewTextButtonItemTest = PlatformTest; } -// Tests that the UILabels and delegate are set properly after a call to -// |configureCell:|. +// Tests that the UILabels are set properly after a call to |configureCell:|. TEST_F(TableViewTextButtonItemTest, SetProperties) { NSString* text = @"You need to do something."; NSString* buttonText = @"Tap to do something."; - id<TextButtonItemDelegate> mock_delegate = - [OCMockObject mockForProtocol:@protocol(TextButtonItemDelegate)]; - TableViewTextButtonItem* item = [[TableViewTextButtonItem alloc] initWithType:0]; item.text = text; item.buttonText = buttonText; - item.delegate = mock_delegate; id cell = [[[item cellClass] alloc] init]; ASSERT_TRUE([cell isMemberOfClass:[TableViewTextButtonCell class]]); @@ -42,31 +37,9 @@ base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell); EXPECT_FALSE(textButtonCell.textLabel.text); EXPECT_FALSE(textButtonCell.button.titleLabel.text); - EXPECT_FALSE(textButtonCell.delegate); [item configureCell:textButtonCell withStyler:[[ChromeTableViewStyler alloc] init]]; EXPECT_NSEQ(text, textButtonCell.textLabel.text); EXPECT_NSEQ(buttonText, textButtonCell.button.titleLabel.text); - EXPECT_TRUE(textButtonCell.delegate); -} - -// Test that pressing the button invokes delegate. -TEST_F(TableViewTextButtonItemTest, DelegateCalled) { - TableViewTextButtonItem* item = - [[TableViewTextButtonItem alloc] initWithType:0]; - id cell = [[[item cellClass] alloc] init]; - ASSERT_TRUE([cell isMemberOfClass:[TableViewTextButtonCell class]]); - - TableViewTextButtonCell* textButtonCell = - base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell); - id<TextButtonItemDelegate> mock_delegate = - [OCMockObject mockForProtocol:@protocol(TextButtonItemDelegate)]; - [textButtonCell setDelegate:mock_delegate]; - - OCMockObject* mock_delegate_obj = (OCMockObject*)mock_delegate; - [[mock_delegate_obj expect] performButtonAction]; - UIButton* button = textButtonCell.button; - [button sendActionsForControlEvents:UIControlEventTouchUpInside]; - EXPECT_OCMOCK_VERIFY(mock_delegate_obj); }
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h index 9c1bd26..fb578a99 100644 --- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h +++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h
@@ -66,6 +66,11 @@ // Removes the empty table view, if one is present. - (void)removeEmptyTableView; +// Performs batch table view updates described by |updates|, using |completion| +// as the completion block. +- (void)performBatchTableViewUpdates:(void (^)(void))updates + completion:(void (^)(BOOL finished))completion; + // Methods for reconfiguring and reloading the table view are provided by // ChromeTableViewConsumer.
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm index 86957a5..d7c1be7 100644 --- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm +++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm
@@ -145,6 +145,20 @@ } } +- (void)performBatchTableViewUpdates:(void (^)(void))updates + completion:(void (^)(BOOL finished))completion { + if (@available(iOS 11, *)) { + [self.tableView performBatchUpdates:updates completion:completion]; + } else { + [self.tableView beginUpdates]; + if (updates) + updates(); + [self.tableView endUpdates]; + if (completion) + completion(YES); + } +} + #pragma mark - UITableViewDataSource - (UITableViewCell*)tableView:(UITableView*)tableView
diff --git a/media/base/OWNERS b/media/base/OWNERS index c83a845..f4ecf46 100644 --- a/media/base/OWNERS +++ b/media/base/OWNERS
@@ -1 +1,4 @@ per-file *audio*=file://media/audio/OWNERS + +per-file media_switches.*=beccahughes@chromium.org +per-file media_switches.*=mlamouri@chromium.org
diff --git a/media/base/android/media_drm_storage_bridge.cc b/media/base/android/media_drm_storage_bridge.cc index 040f8edc..d72e965 100644 --- a/media/base/android/media_drm_storage_bridge.cc +++ b/media/base/android/media_drm_storage_bridge.cc
@@ -23,7 +23,8 @@ using base::android::ConvertUTF8ToJavaString; using base::android::JavaByteArrayToByteVector; using base::android::JavaParamRef; -using base::android::RunCallbackAndroid; +using base::android::RunBooleanCallbackAndroid; +using base::android::RunObjectCallbackAndroid; using base::android::ScopedJavaLocalRef; using base::android::ToJavaByteArray; @@ -128,7 +129,7 @@ void MediaDrmStorageBridge::RunAndroidBoolCallback(JavaObjectPtr j_callback, bool success) { - RunCallbackAndroid(*j_callback, success); + RunBooleanCallbackAndroid(*j_callback, success); } void MediaDrmStorageBridge::OnInitialized( @@ -147,7 +148,7 @@ const std::string& session_id, std::unique_ptr<MediaDrmStorage::SessionData> session_data) { if (!session_data) { - RunCallbackAndroid(*j_callback, ScopedJavaLocalRef<jobject>()); + RunObjectCallbackAndroid(*j_callback, ScopedJavaLocalRef<jobject>()); return; } @@ -158,8 +159,9 @@ ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, session_data->mime_type); - RunCallbackAndroid(*j_callback, Java_PersistentInfo_create( - env, j_eme_id, j_key_set_id, j_mime)); + RunObjectCallbackAndroid( + *j_callback, + Java_PersistentInfo_create(env, j_eme_id, j_key_set_id, j_mime)); } } // namespace media
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index daa15d7..11736c8 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -354,7 +354,7 @@ #if defined(OS_ANDROID) // Enable a gesture to make the media controls expaned into the display cutout. const base::Feature kMediaControlsExpandGesture{ - "MediaControlsExpandGesture", base::FEATURE_DISABLED_BY_DEFAULT}; + "MediaControlsExpandGesture", base::FEATURE_ENABLED_BY_DEFAULT}; // Lock the screen orientation when a video goes fullscreen. const base::Feature kVideoFullscreenOrientationLock{
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index 2cb330f..efb9234 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -675,7 +675,6 @@ hardware_resource->mailbox(), GL_LINEAR, GL_TEXTURE_2D, sync_token); transferable_resource.color_space = resource_color_space; transferable_resource.format = copy_resource_format; - transferable_resource.buffer_format = viz::BufferFormat(copy_resource_format); external_resources->resources.push_back(std::move(transferable_resource)); external_resources->release_callbacks.push_back(base::BindOnce( @@ -705,6 +704,7 @@ external_resources.type = ExternalResourceTypeForHardwarePlanes( video_frame->format(), target, video_frame->NumTextures(), &buffer_format, use_stream_video_draw_quad_); + if (external_resources.type == VideoFrameResourceType::NONE) { DLOG(ERROR) << "Unsupported Texture format" << VideoPixelFormatToString(video_frame->format()); @@ -734,7 +734,8 @@ transfer_resource.read_lock_fences_enabled = video_frame->metadata()->IsTrue( VideoFrameMetadata::READ_LOCK_FENCES_ENABLED); - transfer_resource.buffer_format = buffer_format; + transfer_resource.format = viz::GetResourceFormat(buffer_format); + #if defined(OS_ANDROID) transfer_resource.is_backed_by_surface_texture = video_frame->metadata()->IsTrue(VideoFrameMetadata::TEXTURE_OWNER); @@ -915,8 +916,6 @@ transferable_resource.color_space = output_color_space; transferable_resource.format = viz::ResourceFormat::RGBA_8888; - transferable_resource.buffer_format = - viz::BufferFormat(viz::ResourceFormat::RGBA_8888); external_resources.resources.push_back(std::move(transferable_resource)); external_resources.release_callbacks.push_back(base::BindOnce( &VideoResourceUpdater::RecycleResource, weak_ptr_factory_.GetWeakPtr(), @@ -1039,6 +1038,7 @@ auto* gl = context_provider_->ContextGL(); gl->BindTexture(plane_resource->texture_target(), plane_resource->texture_id()); + DCHECK(GLSupportsFormat(plane_resource_format)); gl->TexSubImage2D( plane_resource->texture_target(), 0, 0, 0, resource_size_pixels.width(), resource_size_pixels.height(), GLDataFormat(plane_resource_format), @@ -1059,8 +1059,6 @@ plane_resource->overlay_candidate()); transferable_resource.color_space = output_color_space; transferable_resource.format = output_resource_format; - transferable_resource.buffer_format = - viz::BufferFormat(output_resource_format); external_resources.resources.push_back(std::move(transferable_resource)); external_resources.release_callbacks.push_back(base::BindOnce( &VideoResourceUpdater::RecycleResource, weak_ptr_factory_.GetWeakPtr(),
diff --git a/media/renderers/video_resource_updater_unittest.cc b/media/renderers/video_resource_updater_unittest.cc index c82d7018..02743bd 100644 --- a/media/renderers/video_resource_updater_unittest.cc +++ b/media/renderers/video_resource_updater_unittest.cc
@@ -705,8 +705,7 @@ EXPECT_EQ(1u, resources.resources.size()); EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES, resources.resources[0].mailbox_holder.texture_target); - EXPECT_EQ(gfx::BufferFormat::YUV_420_BIPLANAR, - resources.resources[0].buffer_format); + EXPECT_EQ(viz::YUV_420_BIPLANAR, resources.resources[0].format); video_frame = CreateTestYuvHardwareVideoFrame(media::PIXEL_FORMAT_NV12, 1, GL_TEXTURE_RECTANGLE_ARB); @@ -715,8 +714,7 @@ EXPECT_EQ(1u, resources.resources.size()); EXPECT_EQ((GLenum)GL_TEXTURE_RECTANGLE_ARB, resources.resources[0].mailbox_holder.texture_target); - EXPECT_EQ(gfx::BufferFormat::YUV_420_BIPLANAR, - resources.resources[0].buffer_format); + EXPECT_EQ(viz::YUV_420_BIPLANAR, resources.resources[0].format); EXPECT_EQ(0, gl_->TextureCreationCount()); } @@ -736,7 +734,7 @@ EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES, resources.resources[0].mailbox_holder.texture_target); // |updater| doesn't set |buffer_format| in this case. - EXPECT_EQ(gfx::BufferFormat::RGBA_8888, resources.resources[0].buffer_format); + EXPECT_EQ(viz::RGBA_8888, resources.resources[0].format); video_frame = CreateTestYuvHardwareVideoFrame(media::PIXEL_FORMAT_NV12, 2, GL_TEXTURE_RECTANGLE_ARB); @@ -745,7 +743,7 @@ EXPECT_EQ(2u, resources.resources.size()); EXPECT_EQ((GLenum)GL_TEXTURE_RECTANGLE_ARB, resources.resources[0].mailbox_holder.texture_target); - EXPECT_EQ(gfx::BufferFormat::RGBA_8888, resources.resources[0].buffer_format); + EXPECT_EQ(viz::RGBA_8888, resources.resources[0].format); EXPECT_EQ(0, gl_->TextureCreationCount()); }
diff --git a/net/BUILD.gn b/net/BUILD.gn index 30c0f2f..2f1e3c11 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -269,8 +269,6 @@ "der/parser.h", "der/tag.cc", "der/tag.h", - "extras/preload_data/decoder.cc", - "extras/preload_data/decoder.h", "http/http_auth_challenge_tokenizer.cc", "http/http_auth_challenge_tokenizer.h", "http/http_auth_scheme.cc", @@ -2133,6 +2131,7 @@ public_deps = [ ":constants", ":net_resources", + ":preload_decoder", "//base", "//net/base/registry_controlled_domains", "//third_party/protobuf:protobuf_lite", @@ -2248,17 +2247,6 @@ extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] } -proto_library("net_quic_trace_proto") { - visibility = [ ":simple_quic_tools" ] - - sources = [ - "third_party/quic/core/proto/quic_trace.proto", - ] - component_build_force_source_set = true - - extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] -} - if (!is_proto_quic) { static_library("extras") { sources = [ @@ -2277,6 +2265,16 @@ } } +static_library("preload_decoder") { + sources = [ + "extras/preload_data/decoder.cc", + "extras/preload_data/decoder.h", + ] + deps = [ + "//base", + ] +} + if (!is_ios) { executable("dump_cache") { testonly = true @@ -3050,6 +3048,8 @@ testonly = true sources = [ "quic/chromium/crypto_test_utils_chromium.cc", + "third_party/quic/core/quic_trace_visitor.cc", + "third_party/quic/core/quic_trace_visitor.h", "third_party/quic/platform/api/quic_hkdf_test.cc", "third_party/quic/platform/api/quic_mock_log.h", "third_party/quic/platform/api/quic_test.h", @@ -3169,6 +3169,7 @@ "//testing/gtest", "//third_party/boringssl", "//third_party/protobuf:protobuf_lite", + "//third_party/quic_trace:quic_trace_proto", ] if (is_linux) { @@ -3222,8 +3223,6 @@ "third_party/quic/core/quic_spdy_server_stream_base.h", "third_party/quic/core/quic_time_wait_list_manager.cc", "third_party/quic/core/quic_time_wait_list_manager.h", - "third_party/quic/core/quic_trace_visitor.cc", - "third_party/quic/core/quic_trace_visitor.h", "third_party/quic/core/stateless_rejector.cc", "third_party/quic/core/stateless_rejector.h", "third_party/quic/tools/quic_backend_response.cc", @@ -3268,9 +3267,6 @@ "//third_party/protobuf:protobuf_lite", "//url", ] - public_deps = [ - ":net_quic_trace_proto", - ] } if (!is_ios) { @@ -3335,17 +3331,6 @@ "//build/win:default_exe_manifest", ] } - executable("quic_trace_to_time_sequence_gnuplot") { - sources = [ - "third_party/quic/tools/trace/quic_trace_to_time_sequence_gnuplot.cc", - ] - deps = [ - ":net", - ":simple_quic_tools", - "//base", - "//build/win:default_exe_manifest", - ] - } } # This section can be updated from globbing rules using: @@ -5111,6 +5096,7 @@ "third_party/quic/core/quic_sustained_bandwidth_recorder_test.cc", "third_party/quic/core/quic_tag_test.cc", "third_party/quic/core/quic_time_test.cc", + "third_party/quic/core/quic_time_wait_list_manager_test.cc", "third_party/quic/core/quic_trace_visitor_test.cc", "third_party/quic/core/quic_unacked_packet_map_test.cc", "third_party/quic/core/quic_utils_test.cc", @@ -5301,7 +5287,6 @@ "third_party/quic/core/quic_spdy_client_session_test.cc", "third_party/quic/core/quic_spdy_client_stream_test.cc", "third_party/quic/core/quic_spdy_server_stream_base_test.cc", - "third_party/quic/core/quic_time_wait_list_manager_test.cc", "third_party/quic/core/stateless_rejector_test.cc", "third_party/quic/platform/impl/quic_epoll_clock_test.cc", "third_party/quic/platform/impl/quic_socket_utils_test.cc",
diff --git a/net/cert/caching_cert_verifier.cc b/net/cert/caching_cert_verifier.cc index 82f83ca4..f0f5cc93 100644 --- a/net/cert/caching_cert_verifier.cc +++ b/net/cert/caching_cert_verifier.cc
@@ -63,25 +63,6 @@ return result; } -bool CachingCertVerifier::AddEntry(const RequestParams& params, - int error, - const CertVerifyResult& verify_result, - base::Time verification_time) { - // If the cache is full, don't bother. - if (cache_.size() == cache_.max_entries()) - return false; - - // If there is an existing entry, don't bother updating it. - const CertVerificationCache::value_type* entry = - cache_.Get(params, CacheValidityPeriod(base::Time::Now())); - if (entry) - return false; - - // Otherwise, go and add it. - AddResultToCache(params, verification_time, verify_result, error); - return true; -} - CachingCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} CachingCertVerifier::CachedResult::~CachedResult() = default;
diff --git a/net/cert/caching_cert_verifier.h b/net/cert/caching_cert_verifier.h index b634af6..e74a915 100644 --- a/net/cert/caching_cert_verifier.h +++ b/net/cert/caching_cert_verifier.h
@@ -49,18 +49,6 @@ std::unique_ptr<Request>* out_req, const NetLogWithSource& net_log) override; - // Opportunistically attempts to add |error| and |verify_result| as the - // result for |params|, which was obtained at |verification_time| and - // expires at |expiration_time|. - // This is opportunistic because it is not guaranteed that the entry - // will be added (such as if the cache is full or an entry already - // exists). - // Returns true if the entry was added. - bool AddEntry(const RequestParams& params, - int error, - const CertVerifyResult& verify_result, - base::Time verification_time); - private: FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierTest, CacheHit); FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierTest, Visitor);
diff --git a/net/cert/caching_cert_verifier_unittest.cc b/net/cert/caching_cert_verifier_unittest.cc index a178b14..d63352e 100644 --- a/net/cert/caching_cert_verifier_unittest.cc +++ b/net/cert/caching_cert_verifier_unittest.cc
@@ -74,66 +74,6 @@ ASSERT_EQ(1u, verifier_.GetCacheSize()); } -TEST_F(CachingCertVerifierTest, AddsEntries) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(certs_dir, "ok_cert.pem")); - ASSERT_TRUE(test_cert.get()); - - CertVerifyResult result_1; - result_1.verified_cert = test_cert; - result_1.cert_status = CERT_STATUS_WEAK_SIGNATURE_ALGORITHM; - result_1.has_md2 = true; - result_1.is_issued_by_known_root = false; - - CertVerifyResult result_2; - result_2.verified_cert = test_cert; - result_2.cert_status = CERT_STATUS_IS_EV; - result_2.is_issued_by_known_root = true; - - CertVerifier::RequestParams params(test_cert, "www.example.com", 0, - std::string(), CertificateList()); - - base::Time now = base::Time::Now(); - - // On an empty cache, it should be fine to add an entry. - EXPECT_TRUE(verifier_.AddEntry(params, ERR_CERT_WEAK_KEY, result_1, now)); - ASSERT_EQ(0u, verifier_.requests()); - ASSERT_EQ(0u, verifier_.cache_hits()); - ASSERT_EQ(1u, verifier_.GetCacheSize()); - - TestCompletionCallback callback; - std::unique_ptr<CertVerifier::Request> request; - - CertVerifyResult cached_result; - int error = callback.GetResult( - verifier_.Verify(params, nullptr, &cached_result, callback.callback(), - &request, NetLogWithSource())); - ASSERT_THAT(error, IsError(ERR_CERT_WEAK_KEY)); - EXPECT_TRUE(cached_result.has_md2); - EXPECT_FALSE(cached_result.is_issued_by_known_root); - - ASSERT_EQ(1u, verifier_.requests()); - ASSERT_EQ(1u, verifier_.cache_hits()); - ASSERT_EQ(1u, verifier_.GetCacheSize()); - - // But it should not be fine to replace it with an existing entry, even - // if that entry is 'newer'. - EXPECT_FALSE(verifier_.AddEntry(params, OK, result_2, - now + base::TimeDelta::FromMinutes(1))); - - error = callback.GetResult(verifier_.Verify(params, nullptr, &cached_result, - callback.callback(), &request, - NetLogWithSource())); - ASSERT_THAT(error, IsError(ERR_CERT_WEAK_KEY)); - EXPECT_TRUE(cached_result.has_md2); - EXPECT_FALSE(cached_result.is_issued_by_known_root); - - ASSERT_EQ(2u, verifier_.requests()); - ASSERT_EQ(2u, verifier_.cache_hits()); - ASSERT_EQ(1u, verifier_.GetCacheSize()); -} - // Tests the same server certificate with different intermediate CA // certificates. These should be treated as different certificate chains even // though the two X509Certificate objects contain the same server certificate.
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc index a89292e..1e7d3a4 100644 --- a/net/cert/cert_verify_proc_builtin.cc +++ b/net/cert/cert_verify_proc_builtin.cc
@@ -82,22 +82,24 @@ }; // TODO(eroman): The path building code in this file enforces its idea of weak -// keys, and separately cert_verify_proc.cc also checks the chains with its -// own policy. These policies should be aligned, to give path building the -// best chance of finding a good path. +// keys, and signature algorithms, but separately cert_verify_proc.cc also +// checks the chains with its own policy. These policies must be aligned to +// give path building the best chance of finding a good path. class PathBuilderDelegateImpl : public SimplePathBuilderDelegate { public: // Uses the default policy from SimplePathBuilderDelegate, which requires RSA - // keys to be at least 1024-bits large, and accepts SHA1 certificates. + // keys to be at least 1024-bits large, and optionally accepts SHA1 + // certificates. PathBuilderDelegateImpl(const CRLSet* crl_set, CertNetFetcher* net_fetcher, VerificationType verification_type, + SimplePathBuilderDelegate::DigestPolicy digest_policy, int flags, const SystemTrustStore* ssl_trust_store, base::StringPiece stapled_leaf_ocsp_response, const EVRootCAMetadata* ev_metadata, bool* checked_revocation_for_some_path) - : SimplePathBuilderDelegate(1024), + : SimplePathBuilderDelegate(1024, digest_policy), crl_set_(crl_set), net_fetcher_(net_fetcher), verification_type_(verification_type), @@ -390,11 +392,28 @@ return result; } +// Describes the parameters for a single path building attempt. Path building +// may be re-tried with different parameters for EV and for accepting SHA1 +// certificates. +struct BuildPathAttempt { + BuildPathAttempt(VerificationType verification_type, + SimplePathBuilderDelegate::DigestPolicy digest_policy) + : verification_type(verification_type), digest_policy(digest_policy) {} + + explicit BuildPathAttempt(VerificationType verification_type) + : BuildPathAttempt(verification_type, + SimplePathBuilderDelegate::DigestPolicy::kStrong) {} + + VerificationType verification_type; + SimplePathBuilderDelegate::DigestPolicy digest_policy; +}; + void TryBuildPath(const scoped_refptr<ParsedCertificate>& target, CertIssuerSourceStatic* intermediates, SystemTrustStore* ssl_trust_store, base::Time verification_time, VerificationType verification_type, + SimplePathBuilderDelegate::DigestPolicy digest_policy, int flags, const std::string& ocsp_response, const CRLSet* crl_set, @@ -421,8 +440,8 @@ } PathBuilderDelegateImpl path_builder_delegate( - crl_set, net_fetcher, verification_type, flags, ssl_trust_store, - ocsp_response, ev_metadata, checked_revocation); + crl_set, net_fetcher, verification_type, digest_policy, flags, + ssl_trust_store, ocsp_response, ev_metadata, checked_revocation); // Initialize the path builder. CertPathBuilder path_builder( @@ -455,7 +474,10 @@ bool checked_revocation_for_some_path, SystemTrustStore* ssl_trust_store, CertVerifyResult* verify_result) { - if (result.best_result_index >= result.paths.size()) { + const CertPathBuilderResultPath* best_path_possibly_invalid = + result.GetBestPathPossiblyInvalid(); + + if (!best_path_possibly_invalid) { // TODO(crbug.com/634443): What errors to communicate? Maybe the path // builder should always return some partial path (even if just containing // the target), then there is a CertErrors to test. @@ -463,10 +485,7 @@ return ERR_CERT_AUTHORITY_INVALID; } - // Use the best path that was built. This could be a partial path, or it could - // be a valid complete path. - const CertPathBuilderResultPath& partial_path = - *result.paths[result.best_result_index].get(); + const CertPathBuilderResultPath& partial_path = *best_path_possibly_invalid; AppendPublicKeyHashes(partial_path, &verify_result->public_key_hashes); @@ -523,6 +542,22 @@ : OK; } +// Returns true if retrying path building with a less stringent signature +// algorithm *might* successfully build a path, based on the earlier failed +// |result|. +// +// This implementation is simplistic, and looks only for the presence of the +// kUnacceptableSignatureAlgorithm error somewhere among the built paths. +bool CanTryAgainWithWeakerDigestPolicy(const CertPathBuilder::Result& result) { + for (const auto& path : result.paths) { + if (path->errors.ContainsError( + cert_errors::kUnacceptableSignatureAlgorithm)) + return true; + } + + return false; +} + int CertVerifyProcBuiltin::VerifyInternal( X509Certificate* input_cert, const std::string& hostname, @@ -571,31 +606,59 @@ // setting output flag CERT_STATUS_REV_CHECKING_ENABLED). bool checked_revocation_for_some_path = false; - // Only attempt to build EV paths if the target could possibly be an EV - // certificate. - const bool should_try_ev = IsEVCandidate(ev_metadata, target.get()); - // Run path building with the different parameters (attempts) until a valid // path is found. Earlier successful attempts have priority over later // attempts. + // + // Attempts are enqueued into |attempts| and drained in FIFO order. + std::vector<BuildPathAttempt> attempts; + + // First try EV validation. Can skip this if the leaf certificate has no + // chance of verifying as EV (lacks an EV policy). + if (IsEVCandidate(ev_metadata, target.get())) + attempts.emplace_back(VerificationType::kEV); + + // Next try DV validation. + attempts.emplace_back(VerificationType::kDV); CertPathBuilder::Result result; VerificationType verification_type = VerificationType::kDV; - for (VerificationType cur_attempt : - {VerificationType::kEV, VerificationType::kDV}) { - // Only attempt EV if it was requested. - if (cur_attempt == VerificationType::kEV && !should_try_ev) - continue; + // Iterate over |attempts| until there are none left to try, or an attempt + // succeeded. + for (size_t cur_attempt_index = 0; cur_attempt_index < attempts.size(); + ++cur_attempt_index) { + const auto& cur_attempt = attempts[cur_attempt_index]; + verification_type = cur_attempt.verification_type; - verification_type = cur_attempt; + // Run the attempt through the path builder. TryBuildPath(target, &intermediates, ssl_trust_store.get(), - verification_time, verification_type, flags, ocsp_response, - crl_set, net_fetcher, ev_metadata, &result, + verification_time, cur_attempt.verification_type, + cur_attempt.digest_policy, flags, ocsp_response, crl_set, + net_fetcher, ev_metadata, &result, &checked_revocation_for_some_path); if (result.HasValidPath()) break; + + // If this path building attempt (may have) failed due to the chain using a + // weak signature algorithm, enqueue a similar attempt but with weaker + // signature algorithms (SHA1) permitted. + // + // This fallback is necessary because the CertVerifyProc layer may decide to + // allow SHA1 based on its own policy, so path building should return + // possibly weak chains too. + // + // TODO(eroman): Would be better for the SHA1 policy to be part of the + // delegate instead so it can interact with path building. + if (cur_attempt.digest_policy == + SimplePathBuilderDelegate::DigestPolicy::kStrong && + CanTryAgainWithWeakerDigestPolicy(result)) { + BuildPathAttempt sha1_fallback_attempt = cur_attempt; + sha1_fallback_attempt.digest_policy = + SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1; + attempts.push_back(sha1_fallback_attempt); + } } // Write the results to |*verify_result|.
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 39fe675b2..902eea9 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -2393,6 +2393,38 @@ SetExtension(SubjectAltNameOid(), FinishCBB(cbb.get())); } + // Sets the signature algorithm for the certificate to either + // sha256WithRSAEncryption or sha1WithRSAEncryption. + void SetSignatureAlgorithmRsaPkca1(DigestAlgorithm digest) { + switch (digest) { + case DigestAlgorithm::Sha256: { + const uint8_t kSha256WithRSAEncryption[] = { + 0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00}; + SetSignatureAlgorithm(std::string(std::begin(kSha256WithRSAEncryption), + std::end(kSha256WithRSAEncryption))); + break; + } + + case DigestAlgorithm::Sha1: { + const uint8_t kSha1WithRSAEncryption[] = {0x30, 0x0D, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00}; + SetSignatureAlgorithm(std::string(std::begin(kSha1WithRSAEncryption), + std::end(kSha1WithRSAEncryption))); + break; + } + + default: + ASSERT_TRUE(false); + } + } + + void SetSignatureAlgorithm(std::string algorithm_tlv) { + signature_algorithm_tlv_ = std::move(algorithm_tlv); + Invalidate(); + } + void SetRandomSerialNumber() { serial_number_ = base::RandUint64(); Invalidate(); @@ -2831,6 +2863,95 @@ EXPECT_THAT(error, IsOk()); } +// Tries verifying a certificate chain that uses a SHA1 intermediate, +// however, chasing the AIA can discover a SHA256 version of the intermediate. +// +// Path building should discover the stronger intermediate and use it. +TEST_P(CertVerifyProcInternalWithNetFetchingTest, + Sha1IntermediateButAIAHasSha256) { + const char kHostname[] = "www.example.com"; + + base::FilePath certs_dir = + GetTestNetDataDirectory() + .AppendASCII("verify_certificate_chain_unittest") + .AppendASCII("target-and-intermediate"); + + CertificateList orig_certs = CreateCertificateListFromFile( + certs_dir, "chain.pem", X509Certificate::FORMAT_AUTO); + ASSERT_EQ(3U, orig_certs.size()); + + // Build slightly modified variants of |orig_certs|. + CertBuilder root(orig_certs[2]->cert_buffer(), nullptr); + CertBuilder intermediate(orig_certs[1]->cert_buffer(), &root); + CertBuilder leaf(orig_certs[0]->cert_buffer(), &intermediate); + + // Make the leaf certificate have an AIA (CA Issuers) that points to the + // embedded test server. This uses a random URL for predictable behavior in + // the presence of global caching. + std::string ca_issuers_relative_path = MakeRandomPath(".cer"); + GURL ca_issuers_url = GetTestServerAbsoluteUrl(ca_issuers_relative_path); + leaf.SetCaIssuersUrl(ca_issuers_url); + leaf.SetSubjectAltName(kHostname); + + // Make two versions of the intermediate - one that is SHA256 signed, and one + // that is SHA1 signed. + intermediate.SetSignatureAlgorithmRsaPkca1(DigestAlgorithm::Sha256); + intermediate.SetRandomSerialNumber(); + auto intermediate_sha256 = intermediate.DupCertBuffer(); + + intermediate.SetSignatureAlgorithmRsaPkca1(DigestAlgorithm::Sha1); + intermediate.SetRandomSerialNumber(); + auto intermediate_sha1 = intermediate.DupCertBuffer(); + + // Trust the root certificate. + auto root_cert = root.GetX509Certificate(); + ScopedTestRoot scoped_root(root_cert.get()); + + // Setup the test server to reply with the SHA256 intermediate. + RegisterSimpleTestServerHandler( + ca_issuers_relative_path, "application/pkix-cert", + x509_util::CryptoBufferAsStringPiece(intermediate_sha256.get()) + .as_string()); + + // Build a chain to verify that includes the SHA1 intermediate. + std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates; + intermediates.push_back(x509_util::DupCryptoBuffer(intermediate_sha1.get())); + scoped_refptr<X509Certificate> chain_sha1 = X509Certificate::CreateFromBuffer( + leaf.DupCertBuffer(), std::move(intermediates)); + ASSERT_TRUE(chain_sha1.get()); + + const int flags = 0; + CertVerifyResult verify_result; + int error = Verify(chain_sha1.get(), kHostname, flags, nullptr, + CertificateList(), &verify_result); + + if (verify_proc_type() == CERT_VERIFY_PROC_BUILTIN || + verify_proc_type() == CERT_VERIFY_PROC_MAC) { + // Should have built a chain through the SHA256 intermediate. This was only + // available via AIA, and not the (SHA1) one provided directly to path + // building. + ASSERT_EQ(2u, verify_result.verified_cert->intermediate_buffers().size()); + EXPECT_TRUE(x509_util::CryptoBufferEqual( + verify_result.verified_cert->intermediate_buffers()[0].get(), + intermediate_sha256.get())); + ASSERT_EQ(2u, verify_result.verified_cert->intermediate_buffers().size()); + + EXPECT_FALSE(verify_result.has_sha1); + EXPECT_THAT(error, IsOk()); + } else if (verify_proc_type() == CERT_VERIFY_PROC_WIN) { + // TODO(eroman): Make these test expectations exact. + // This seemed to be working on Windows when !AreSHA1IntermediatesAllowed() + // from previous testing, but then failed on the Windows 10 bot. + if (error != OK) { + EXPECT_TRUE(verify_result.has_sha1); + EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); + } + } else { + EXPECT_TRUE(verify_result.has_sha1); + EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); + } +} + TEST(CertVerifyProcTest, RejectsMD2) { scoped_refptr<X509Certificate> cert( ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
diff --git a/net/cert/internal/path_builder.cc b/net/cert/internal/path_builder.cc index 969aae9..44e6636 100644 --- a/net/cert/internal/path_builder.cc +++ b/net/cert/internal/path_builder.cc
@@ -478,17 +478,23 @@ const CertPathBuilderResultPath* CertPathBuilder::Result::GetBestValidPath() const { + const CertPathBuilderResultPath* result_path = GetBestPathPossiblyInvalid(); + + if (result_path && result_path->IsValid()) + return result_path; + + return nullptr; +} + +const CertPathBuilderResultPath* +CertPathBuilder::Result::GetBestPathPossiblyInvalid() const { DCHECK((paths.empty() && best_result_index == 0) || best_result_index < paths.size()); if (best_result_index >= paths.size()) return nullptr; - const CertPathBuilderResultPath* result_path = paths[best_result_index].get(); - if (result_path->IsValid()) - return result_path; - - return nullptr; + return paths[best_result_index].get(); } void CertPathBuilder::Result::Clear() {
diff --git a/net/cert/internal/path_builder.h b/net/cert/internal/path_builder.h index 3ac0464..21dcb24 100644 --- a/net/cert/internal/path_builder.h +++ b/net/cert/internal/path_builder.h
@@ -115,6 +115,9 @@ // if there was none. const CertPathBuilderResultPath* GetBestValidPath() const; + // Returns the best CertPathBuilderResultPath or nullptr if there was none. + const CertPathBuilderResultPath* GetBestPathPossiblyInvalid() const; + // Resets to the initial value. void Clear();
diff --git a/net/cert/internal/path_builder_pkits_unittest.cc b/net/cert/internal/path_builder_pkits_unittest.cc index d5fbe859..5bec8a6 100644 --- a/net/cert/internal/path_builder_pkits_unittest.cc +++ b/net/cert/internal/path_builder_pkits_unittest.cc
@@ -56,7 +56,8 @@ scoped_refptr<ParsedCertificate> target_cert(certs.back()); - SimplePathBuilderDelegate path_builder_delegate(1024); + SimplePathBuilderDelegate path_builder_delegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); CertPathBuilder::Result result; CertPathBuilder path_builder(
diff --git a/net/cert/internal/path_builder_unittest.cc b/net/cert/internal/path_builder_unittest.cc index 81c253c9..f45ede2 100644 --- a/net/cert/internal/path_builder_unittest.cc +++ b/net/cert/internal/path_builder_unittest.cc
@@ -117,7 +117,9 @@ class PathBuilderMultiRootTest : public ::testing::Test { public: - PathBuilderMultiRootTest() : delegate_(1024) {} + PathBuilderMultiRootTest() + : delegate_(1024, + SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {} void SetUp() override { ASSERT_TRUE(ReadTestCert("multi-root-A-by-B.pem", &a_by_b_)); @@ -449,7 +451,9 @@ class PathBuilderKeyRolloverTest : public ::testing::Test { public: - PathBuilderKeyRolloverTest() : delegate_(1024) {} + PathBuilderKeyRolloverTest() + : delegate_(1024, + SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {} void SetUp() override { ParsedCertificateList path; @@ -1182,7 +1186,8 @@ CertIssuerSourceStatic intermediates; intermediates.AddCert(test_.chain[1]); - SimplePathBuilderDelegate default_delegate(1024); + SimplePathBuilderDelegate default_delegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); CertPathBuilderDelegate* delegate = optional_delegate ? optional_delegate : &default_delegate; @@ -1294,7 +1299,10 @@ class CertPathBuilderDelegateBase : public SimplePathBuilderDelegate { public: - CertPathBuilderDelegateBase() : SimplePathBuilderDelegate(1024) {} + CertPathBuilderDelegateBase() + : SimplePathBuilderDelegate( + 1024, + SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {} void CheckPathAfterVerification(CertPathBuilderResultPath* path) override { ADD_FAILURE() << "Tests must override this"; }
diff --git a/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc b/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc index 9ef6631..3fb8451 100644 --- a/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc +++ b/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc
@@ -17,7 +17,8 @@ public: static void Verify(const VerifyCertChainTest& test, const std::string& test_file_path) { - SimplePathBuilderDelegate path_builder_delegate(1024); + SimplePathBuilderDelegate path_builder_delegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); ASSERT_FALSE(test.chain.empty()); TrustStoreInMemory trust_store;
diff --git a/net/cert/internal/simple_path_builder_delegate.cc b/net/cert/internal/simple_path_builder_delegate.cc index 65508c97..584eeed 100644 --- a/net/cert/internal/simple_path_builder_delegate.cc +++ b/net/cert/internal/simple_path_builder_delegate.cc
@@ -28,24 +28,6 @@ DEFINE_CERT_ERROR_ID(kUnacceptableCurveForEcdsa, "Only P-256, P-384, P-521 are supported for ECDSA"); -// Whitelist of default permitted signature digest algorithms. -WARN_UNUSED_RESULT bool IsAcceptableDigest(DigestAlgorithm digest) { - switch (digest) { - case DigestAlgorithm::Md2: - case DigestAlgorithm::Md4: - case DigestAlgorithm::Md5: - return false; - - case DigestAlgorithm::Sha1: - case DigestAlgorithm::Sha256: - case DigestAlgorithm::Sha384: - case DigestAlgorithm::Sha512: - return true; - } - - return false; -} - bool IsAcceptableCurveForEcdsa(int curve_nid) { // Whitelist default permitted named curves. switch (curve_nid) { @@ -61,8 +43,10 @@ } // namespace SimplePathBuilderDelegate::SimplePathBuilderDelegate( - size_t min_rsa_modulus_length_bits) - : min_rsa_modulus_length_bits_(min_rsa_modulus_length_bits) {} + size_t min_rsa_modulus_length_bits, + DigestPolicy digest_policy) + : min_rsa_modulus_length_bits_(min_rsa_modulus_length_bits), + digest_policy_(digest_policy) {} void SimplePathBuilderDelegate::CheckPathAfterVerification( CertPathBuilderResultPath* path) { @@ -77,13 +61,6 @@ // RSA PKCS#1 v1.5 // RSASSA-PSS // ECDSA - // - // When used with digest algorithms: - // - // SHA1 - // SHA256 - // SHA384 - // SHA512 switch (algorithm.algorithm()) { case SignatureAlgorithmId::Dsa: return false; @@ -138,4 +115,30 @@ return false; } +// Restricted signature digest algorithms to: +// +// SHA1 (if digest_policy_ == kWeakAllowSha1) +// SHA256 +// SHA384 +// SHA512 +bool SimplePathBuilderDelegate::IsAcceptableDigest( + DigestAlgorithm digest) const { + switch (digest) { + case DigestAlgorithm::Md2: + case DigestAlgorithm::Md4: + case DigestAlgorithm::Md5: + return false; + + case DigestAlgorithm::Sha1: + return digest_policy_ == + SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1; + case DigestAlgorithm::Sha256: + case DigestAlgorithm::Sha384: + case DigestAlgorithm::Sha512: + return true; + } + + return false; +} + } // namespace net
diff --git a/net/cert/internal/simple_path_builder_delegate.h b/net/cert/internal/simple_path_builder_delegate.h index 4b43870..ede49e5 100644 --- a/net/cert/internal/simple_path_builder_delegate.h +++ b/net/cert/internal/simple_path_builder_delegate.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "net/base/net_export.h" #include "net/cert/internal/path_builder.h" +#include "net/cert/internal/signature_algorithm.h" namespace net { @@ -21,15 +22,26 @@ // // * RSA public keys must be >= |min_rsa_modulus_length_bits|. // * Signature algorithm can be RSA PKCS#1, RSASSA-PSS or ECDSA -// * Hash algorithm can be SHA1, SHA256, SHA348 or SHA512 +// * Digest algorithm can be SHA256, SHA348 or SHA512. +// * If the |digest_policy| was set to kAllowSha1, then SHA1 is +// additionally accepted. // * EC named curve can be P-256, P-384, P-521. class NET_EXPORT SimplePathBuilderDelegate : public CertPathBuilderDelegate { public: + enum class DigestPolicy { + // Accepts digests of SHA256, SHA348 or SHA512 + kStrong, + + // Accepts everything that kStrong does, plus SHA1. + kWeakAllowSha1, + }; + // Error emitted when a public key is rejected because it is an RSA key with a // modulus size that is too small. static const CertErrorId kRsaModulusTooSmall; - explicit SimplePathBuilderDelegate(size_t min_rsa_modulus_length_bits); + SimplePathBuilderDelegate(size_t min_rsa_modulus_length_bits, + DigestPolicy digest_policy); // Accepts RSA PKCS#1, RSASSA-PSS or ECDA using any of the SHA* digests // (including SHA1). @@ -44,7 +56,10 @@ void CheckPathAfterVerification(CertPathBuilderResultPath* path) override; private: + bool IsAcceptableDigest(DigestAlgorithm digest) const WARN_UNUSED_RESULT; + const size_t min_rsa_modulus_length_bits_; + const DigestPolicy digest_policy_; }; } // namespace net
diff --git a/net/cert/internal/simple_path_builder_delegate_unittest.cc b/net/cert/internal/simple_path_builder_delegate_unittest.cc index 507b115..dd222a4 100644 --- a/net/cert/internal/simple_path_builder_delegate_unittest.cc +++ b/net/cert/internal/simple_path_builder_delegate_unittest.cc
@@ -72,7 +72,8 @@ ASSERT_TRUE(public_key); CertErrors errors; - SimplePathBuilderDelegate delegate(1024); + SimplePathBuilderDelegate delegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); EXPECT_TRUE( delegate.IsSignatureAlgorithmAcceptable(*signature_algorithm, &errors)); @@ -98,7 +99,8 @@ ASSERT_TRUE(public_key); CertErrors errors; - SimplePathBuilderDelegate delegate(2048); + SimplePathBuilderDelegate delegate( + 2048, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); EXPECT_TRUE( delegate.IsSignatureAlgorithmAcceptable(*signature_algorithm, &errors));
diff --git a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc index 4443dd7..1040f3c3 100644 --- a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc +++ b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
@@ -42,7 +42,8 @@ << parsing_errors.ToDebugString(); } - SimplePathBuilderDelegate path_builder_delegate(1024); + SimplePathBuilderDelegate path_builder_delegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); std::set<der::Input> user_constrained_policy_set;
diff --git a/net/cert/internal/verify_certificate_chain_unittest.cc b/net/cert/internal/verify_certificate_chain_unittest.cc index 70595839..0a53bef 100644 --- a/net/cert/internal/verify_certificate_chain_unittest.cc +++ b/net/cert/internal/verify_certificate_chain_unittest.cc
@@ -17,7 +17,8 @@ public: static void Verify(const VerifyCertChainTest& test, const std::string& test_file_path) { - SimplePathBuilderDelegate delegate(1024); + SimplePathBuilderDelegate delegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); CertPathErrors errors; // TODO(eroman): Check user_constrained_policy_set.
diff --git a/net/extras/preload_data/decoder.cc b/net/extras/preload_data/decoder.cc index ad0d18f5..b91cc48 100644 --- a/net/extras/preload_data/decoder.cc +++ b/net/extras/preload_data/decoder.cc
@@ -5,52 +5,6 @@ #include "net/extras/preload_data/decoder.h" #include "base/logging.h" -namespace { - -// HuffmanDecoder is a very simple Huffman reader. The input Huffman tree is -// simply encoded as a series of two-byte structures. The first byte determines -// the "0" pointer for that node and the second the "1" pointer. Each byte -// either has the MSB set, in which case the bottom 7 bits are the value for -// that position, or else the bottom seven bits contain the index of a node. -// -// The tree is decoded by walking rather than a table-driven approach. -class HuffmanDecoder { - public: - HuffmanDecoder(const uint8_t* tree, size_t tree_bytes) - : tree_(tree), tree_bytes_(tree_bytes) {} - - bool Decode(net::extras::PreloadDecoder::BitReader* reader, char* out) { - const uint8_t* current = &tree_[tree_bytes_ - 2]; - - for (;;) { - bool bit; - if (!reader->Next(&bit)) { - return false; - } - - uint8_t b = current[bit]; - if (b & 0x80) { - *out = static_cast<char>(b & 0x7f); - return true; - } - - unsigned offset = static_cast<unsigned>(b) * 2; - DCHECK_LT(offset, tree_bytes_); - if (offset >= tree_bytes_) { - return false; - } - - current = &tree_[offset]; - } - } - - private: - const uint8_t* const tree_; - const size_t tree_bytes_; -}; - -} // namespace - namespace net { namespace extras { @@ -131,26 +85,49 @@ return true; } +PreloadDecoder::HuffmanDecoder::HuffmanDecoder(const uint8_t* tree, + size_t tree_bytes) + : tree_(tree), tree_bytes_(tree_bytes) {} + +bool PreloadDecoder::HuffmanDecoder::Decode(PreloadDecoder::BitReader* reader, + char* out) const { + const uint8_t* current = &tree_[tree_bytes_ - 2]; + + for (;;) { + bool bit; + if (!reader->Next(&bit)) { + return false; + } + + uint8_t b = current[bit]; + if (b & 0x80) { + *out = static_cast<char>(b & 0x7f); + return true; + } + + unsigned offset = static_cast<unsigned>(b) * 2; + DCHECK_LT(offset, tree_bytes_); + if (offset >= tree_bytes_) { + return false; + } + + current = &tree_[offset]; + } +} + PreloadDecoder::PreloadDecoder(const uint8_t* huffman_tree, size_t huffman_tree_size, const uint8_t* trie, size_t trie_bits, size_t trie_root_position) - : huffman_tree_(huffman_tree), - huffman_tree_size_(huffman_tree_size), - trie_(trie), - trie_bits_(trie_bits), + : huffman_decoder_(huffman_tree, huffman_tree_size), + bit_reader_(trie, trie_bits), trie_root_position_(trie_root_position) {} PreloadDecoder::~PreloadDecoder() {} bool PreloadDecoder::Decode(const std::string& search, bool* out_found) { - HuffmanDecoder huffman(huffman_tree_, huffman_tree_size_); - BitReader reader(trie_, trie_bits_); size_t bit_offset = trie_root_position_; - static const char kEndOfString = 0; - static const char kEndOfTable = 127; - *out_found = false; // current_search_offset contains one more than the index of the current @@ -161,13 +138,13 @@ for (;;) { // Seek to the desired location. - if (!reader.Seek(bit_offset)) { + if (!bit_reader_.Seek(bit_offset)) { return false; } // Decode the unary length of the common prefix. size_t prefix_length; - if (!reader.Unary(&prefix_length)) { + if (!bit_reader_.Unary(&prefix_length)) { return false; } @@ -179,7 +156,7 @@ } char c; - if (!huffman.Decode(&reader, &c)) { + if (!huffman_decoder_.Decode(&bit_reader_, &c)) { return false; } if (search[current_search_offset - 1] != c) { @@ -194,7 +171,7 @@ // Next is the dispatch table. for (;;) { char c; - if (!huffman.Decode(&reader, &c)) { + if (!huffman_decoder_.Decode(&bit_reader_, &c)) { return false; } if (c == kEndOfTable) { @@ -203,7 +180,8 @@ } if (c == kEndOfString) { - if (!ReadEntry(&reader, search, current_search_offset, out_found)) { + if (!ReadEntry(&bit_reader_, search, current_search_offset, + out_found)) { return false; } if (current_search_offset == 0) { @@ -223,8 +201,8 @@ // The first offset is backwards from the current position. uint32_t jump_delta_bits; uint32_t jump_delta; - if (!reader.Read(5, &jump_delta_bits) || - !reader.Read(jump_delta_bits, &jump_delta)) { + if (!bit_reader_.Read(5, &jump_delta_bits) || + !bit_reader_.Read(jump_delta_bits, &jump_delta)) { return false; } @@ -237,19 +215,19 @@ } else { // Subsequent offsets are forward from the target of the first offset. uint32_t is_long_jump; - if (!reader.Read(1, &is_long_jump)) { + if (!bit_reader_.Read(1, &is_long_jump)) { return false; } uint32_t jump_delta; if (!is_long_jump) { - if (!reader.Read(7, &jump_delta)) { + if (!bit_reader_.Read(7, &jump_delta)) { return false; } } else { uint32_t jump_delta_bits; - if (!reader.Read(4, &jump_delta_bits) || - !reader.Read(jump_delta_bits + 8, &jump_delta)) { + if (!bit_reader_.Read(4, &jump_delta_bits) || + !bit_reader_.Read(jump_delta_bits + 8, &jump_delta)) { return false; } }
diff --git a/net/extras/preload_data/decoder.h b/net/extras/preload_data/decoder.h index b31c97e..6afa7a7 100644 --- a/net/extras/preload_data/decoder.h +++ b/net/extras/preload_data/decoder.h
@@ -5,8 +5,12 @@ #ifndef NET_EXTRAS_PRELOAD_DATA_DECODER_H_ #define NET_EXTRAS_PRELOAD_DATA_DECODER_H_ +#include <stdint.h> + #include <string> +#include "base/macros.h" + namespace net { namespace extras { @@ -16,6 +20,9 @@ // they are interested in. class PreloadDecoder { public: + // These must match the values in net/tools/huffman_trie/trie/trie_writer.h. + enum : char { kEndOfString = 0, kEndOfTable = 127 }; + // BitReader is a class that allows a bytestring to be read bit-by-bit. class BitReader { public: @@ -51,6 +58,29 @@ // num_bits_used_ contains the number of bits of |current_byte_| that have // been read. unsigned num_bits_used_; + + DISALLOW_COPY_AND_ASSIGN(BitReader); + }; + + // HuffmanDecoder is a very simple Huffman reader. The input Huffman tree is + // simply encoded as a series of two-byte structures. The first byte + // determines the "0" pointer for that node and the second the "1" pointer. + // Each byte either has the MSB set, in which case the bottom 7 bits are the + // value for that position, or else the bottom seven bits contain the index of + // a node. + // + // The tree is decoded by walking rather than a table-driven approach. + class HuffmanDecoder { + public: + HuffmanDecoder(const uint8_t* tree, size_t tree_bytes); + + bool Decode(PreloadDecoder::BitReader* reader, char* out) const; + + private: + const uint8_t* const tree_; + const size_t tree_bytes_; + + DISALLOW_COPY_AND_ASSIGN(HuffmanDecoder); }; PreloadDecoder(const uint8_t* huffman_tree, @@ -84,17 +114,21 @@ // value always comes before an entry for '.'. bool Decode(const std::string& search, bool* out_found); + protected: virtual bool ReadEntry(BitReader* reader, const std::string& search, size_t current_search_offset, bool* out_found) = 0; + const HuffmanDecoder& huffman_decoder() const { return huffman_decoder_; } + private: - const uint8_t* huffman_tree_; - const size_t huffman_tree_size_; - const uint8_t* trie_; - const size_t trie_bits_; + HuffmanDecoder huffman_decoder_; + BitReader bit_reader_; + const size_t trie_root_position_; + + DISALLOW_COPY_AND_ASSIGN(PreloadDecoder); }; } // namespace extras
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc index aba283a..62dfecd 100644 --- a/net/http/http_server_properties_manager_unittest.cc +++ b/net/http/http_server_properties_manager_unittest.cc
@@ -1304,7 +1304,7 @@ base::Time expiration1; ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1)); quic::QuicTransportVersionVector advertised_versions = { - quic::QUIC_VERSION_37, quic::QUIC_VERSION_35}; + quic::QUIC_VERSION_41, quic::QUIC_VERSION_35}; alternative_service_info_vector.push_back( AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( quic_alternative_service1, expiration1, advertised_versions)); @@ -1352,7 +1352,7 @@ "{\"quic_servers\":{\"https://mail.google.com:80\":{" "\"server_info\":\"quic_server_info1\"}},\"servers\":[" "{\"https://www.google.com:80\":{\"alternative_service\":[{" - "\"advertised_versions\":[35,37],\"expiration\":\"13756212000000000\"," + "\"advertised_versions\":[35,41],\"expiration\":\"13756212000000000\"," "\"port\":443,\"protocol_str\":\"quic\"},{\"advertised_versions\":[]," "\"expiration\":\"13758804000000000\",\"host\":\"www.google.com\"," "\"port\":1234,\"protocol_str\":\"h2\"}]}}," @@ -1376,7 +1376,7 @@ "{\"port\":443,\"protocol_str\":\"quic\"}," "{\"port\":123,\"protocol_str\":\"quic\"," "\"expiration\":\"9223372036854775807\"," - "\"advertised_versions\":[37,35]}]}"); + "\"advertised_versions\":[41,35]}]}"); ASSERT_TRUE(server_value); base::DictionaryValue* server_dict; ASSERT_TRUE(server_value->GetAsDictionary(&server_dict)); @@ -1414,7 +1414,7 @@ alternative_service_info_vector[1].advertised_versions(); EXPECT_EQ(2u, loaded_advertised_versions.size()); EXPECT_EQ(quic::QUIC_VERSION_35, loaded_advertised_versions[0]); - EXPECT_EQ(quic::QUIC_VERSION_37, loaded_advertised_versions[1]); + EXPECT_EQ(quic::QUIC_VERSION_41, loaded_advertised_versions[1]); } TEST_P(HttpServerPropertiesManagerTest, @@ -1424,7 +1424,7 @@ // #1: Set alternate protocol. AlternativeServiceInfoVector alternative_service_info_vector; // Quic alternative service set with a single QUIC version: - // quic::QUIC_VERSION_37. + // quic::QUIC_VERSION_41. AlternativeService quic_alternative_service1(kProtoQUIC, "", 443); base::Time expiration1; ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1)); @@ -1472,7 +1472,7 @@ AlternativeServiceInfoVector alternative_service_info_vector_2; // Quic alternative service set with two advertised QUIC versions. quic::QuicTransportVersionVector advertised_versions = { - quic::QUIC_VERSION_37, quic::QUIC_VERSION_35}; + quic::QUIC_VERSION_41, quic::QUIC_VERSION_35}; alternative_service_info_vector_2.push_back( AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( quic_alternative_service1, expiration1, advertised_versions)); @@ -1490,7 +1490,7 @@ "{\"quic_servers\":{\"https://mail.google.com:80\":" "{\"server_info\":\"quic_server_info1\"}},\"servers\":[" "{\"https://www.google.com:80\":" - "{\"alternative_service\":[{\"advertised_versions\":[35,37]," + "{\"alternative_service\":[{\"advertised_versions\":[35,41]," "\"expiration\":\"13756212000000000\",\"port\":443," "\"protocol_str\":\"quic\"}]}}],\"supports_quic\":" "{\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":5}"; @@ -1502,7 +1502,7 @@ AlternativeServiceInfoVector alternative_service_info_vector_3; // A same set of QUIC versions but listed in a different order. quic::QuicTransportVersionVector advertised_versions_2 = { - quic::QUIC_VERSION_35, quic::QUIC_VERSION_37}; + quic::QUIC_VERSION_35, quic::QUIC_VERSION_41}; alternative_service_info_vector_3.push_back( AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( quic_alternative_service1, expiration1, advertised_versions_2));
diff --git a/net/quic/chromium/quic_chromium_packet_writer.cc b/net/quic/chromium/quic_chromium_packet_writer.cc index 50fb70c5..a892e1b 100644 --- a/net/quic/chromium/quic_chromium_packet_writer.cc +++ b/net/quic/chromium/quic_chromium_packet_writer.cc
@@ -204,8 +204,11 @@ // HandleWriteError returns the outcome of that rewrite attempt. rv = delegate_->HandleWriteError(rv, std::move(packet_)); DCHECK(packet_ == nullptr); - if (rv == ERR_IO_PENDING) + if (rv == ERR_IO_PENDING) { + // Set write blocked back as HandleWriteError hasn't complete migration. + write_blocked_ = true; return; + } } if (retry_count_ != 0) { RecordRetryCount(retry_count_);
diff --git a/net/quic/chromium/quic_http_stream.cc b/net/quic/chromium/quic_http_stream.cc index 4b45a17..cefedde 100644 --- a/net/quic/chromium/quic_http_stream.cc +++ b/net/quic/chromium/quic_http_stream.cc
@@ -82,10 +82,6 @@ return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION; case quic::QUIC_VERSION_35: return HttpResponseInfo::CONNECTION_INFO_QUIC_35; - case quic::QUIC_VERSION_37: - return HttpResponseInfo::CONNECTION_INFO_QUIC_37; - case quic::QUIC_VERSION_38: - return HttpResponseInfo::CONNECTION_INFO_QUIC_38; case quic::QUIC_VERSION_39: return HttpResponseInfo::CONNECTION_INFO_QUIC_39; case quic::QUIC_VERSION_41:
diff --git a/net/quic/chromium/quic_http_utils_test.cc b/net/quic/chromium/quic_http_utils_test.cc index 416604f..e50f364bd 100644 --- a/net/quic/chromium/quic_http_utils_test.cc +++ b/net/quic/chromium/quic_http_utils_test.cc
@@ -39,18 +39,16 @@ TEST(QuicHttpUtilsTest, FilterSupportedAltSvcVersions) { quic::QuicTransportVersionVector supported_versions = { - quic::QUIC_VERSION_37, quic::QUIC_VERSION_38, quic::QUIC_VERSION_39, - quic::QUIC_VERSION_41}; + quic::QUIC_VERSION_35, quic::QUIC_VERSION_39, quic::QUIC_VERSION_41}; - std::vector<uint32_t> alt_svc_versions_google = { - quic::QUIC_VERSION_38, quic::QUIC_VERSION_41, quic::QUIC_VERSION_42}; + std::vector<uint32_t> alt_svc_versions_google = {quic::QUIC_VERSION_41, + quic::QUIC_VERSION_42}; std::vector<uint32_t> alt_svc_versions_ietf = { - QuicVersionToQuicVersionLabel(quic::QUIC_VERSION_38), QuicVersionToQuicVersionLabel(quic::QUIC_VERSION_41), QuicVersionToQuicVersionLabel(quic::QUIC_VERSION_42)}; quic::QuicTransportVersionVector supported_alt_svc_versions = { - quic::QUIC_VERSION_38, quic::QUIC_VERSION_41}; + quic::QUIC_VERSION_41}; spdy::SpdyAltSvcWireFormat::AlternativeService altsvc; altsvc.protocol_id = "quic";
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index 76ad708..8e1022e 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -436,6 +436,7 @@ std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket( quic::QuicPacketNumber packet_number, quic::QuicStreamId stream_id, + quic::QuicStreamId parent_stream_id, bool should_include_version, bool fin, quic::QuicStreamOffset* offset) { @@ -446,7 +447,18 @@ size_t spdy_headers_frame_len; return client_maker_.MakeRequestHeadersPacket( packet_number, stream_id, should_include_version, fin, priority, - std::move(headers), 0, &spdy_headers_frame_len, offset); + std::move(headers), parent_stream_id, &spdy_headers_frame_len, offset); + } + + std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket( + quic::QuicPacketNumber packet_number, + quic::QuicStreamId stream_id, + bool should_include_version, + bool fin, + quic::QuicStreamOffset* offset) { + return ConstructGetRequestPacket(packet_number, stream_id, + /*parent_stream_id=*/0, + should_include_version, fin, offset); } std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket( @@ -3830,6 +3842,145 @@ EXPECT_TRUE(socket_data.AllWriteDataConsumed()); } +// Regression test for http://crbug.com/791886. +// This test verifies that the old packet writer which encountered an +// asynchronous write error will be blocked during migration on write error. New +// packets would not be written until the one with write error is rewritten on +// the new network. +TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) { + InitializeConnectionMigrationV2Test( + {kDefaultNetworkForTests, kNewNetworkForTests}); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Using a testing task runner so that we can control time. + // base::RunLoop() controls mocked socket writes and reads. + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get()); + + MockQuicData socket_data; + quic::QuicStreamOffset header_stream_offset = 0; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite( + SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset)); + socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE); + socket_data.AddSocketDataToFactory(socket_factory_.get()); + + // Set up second socket data provider that is used after + // migration. The request is rewritten to this new socket, and the + // response to the request is read on this new socket. + MockQuicData socket_data1; + socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket( + 2, GetNthClientInitiatedStreamId(0), + true, true, &header_stream_offset)); + socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket( + 3, GetNthClientInitiatedStreamId(1), + GetNthClientInitiatedStreamId(0), true, + true, &header_stream_offset)); + socket_data1.AddRead( + ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0), + false, false)); + socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data1.AddWrite(SYNCHRONOUS, + client_maker_.MakeAckAndRstPacket( + 4, false, GetNthClientInitiatedStreamId(0), + quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true)); + socket_data1.AddWrite( + SYNCHRONOUS, + client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(1), + quic::QUIC_STREAM_CANCELLED, 0)); + + socket_data1.AddSocketDataToFactory(socket_factory_.get()); + + // Create request #1 and QuicHttpStream. + QuicStreamRequest request1(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request1.Request(host_port_pair_, version_, privacy_mode_, + DEFAULT_PRIORITY, SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, + &net_error_details_, callback_.callback())); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<HttpStream> stream1 = CreateStream(&request1); + EXPECT_TRUE(stream1.get()); + + HttpRequestInfo request_info1; + request_info1.method = "GET"; + request_info1.url = GURL("https://www.example.org/"); + request_info1.traffic_annotation = + MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_EQ(OK, + stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY, + net_log_, CompletionOnceCallback())); + + // Request #2 returns synchronously because it pools to existing session. + TestCompletionCallback callback2; + QuicStreamRequest request2(factory_.get()); + EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_, + DEFAULT_PRIORITY, SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, + &net_error_details_, callback2.callback())); + std::unique_ptr<HttpStream> stream2 = CreateStream(&request2); + EXPECT_TRUE(stream2.get()); + + HttpRequestInfo request_info2; + request_info2.method = "GET"; + request_info2.url = GURL("https://www.example.org/"); + request_info2.traffic_annotation = + MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_EQ(OK, + stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY, + net_log_, CompletionOnceCallback())); + + // Ensure that session is alive and active. + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); + EXPECT_EQ(2u, session->GetNumActiveStreams()); + + // Send GET request on stream1. This should cause an async write error. + HttpResponseInfo response; + HttpRequestHeaders request_headers; + EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response, + callback_.callback())); + EXPECT_EQ(0u, task_runner->GetPendingTaskCount()); + + // Run the message loop so that asynchronous write completes and a connection + // migration on write error attempt is posted in QuicStreamFactory's task + // runner. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1u, task_runner->GetPendingTaskCount()); + + // Send GET request on stream. This will cause another write attempt before + // migration on write error is exectued. + HttpResponseInfo response2; + HttpRequestHeaders request_headers2; + EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2, + callback2.callback())); + + // Run the task runner so that migration on write error is finally executed. + task_runner->RunUntilIdle(); + + // The session should now be marked as going away. Ensure that + // while it is still alive, it is no longer active. + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_EQ(2u, session->GetNumActiveStreams()); + + // Verify that response headers on the migrated socket were delivered to the + // stream. + EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); + EXPECT_EQ(200, response.headers->response_code()); + + stream1.reset(); + stream2.reset(); + + EXPECT_TRUE(socket_data.AllReadDataConsumed()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_TRUE(socket_data1.AllReadDataConsumed()); + EXPECT_TRUE(socket_data1.AllWriteDataConsumed()); +} + void QuicStreamFactoryTestBase::TestMigrationOnWriteError( IoMode write_error_mode) { InitializeConnectionMigrationV2Test( @@ -3838,6 +3989,8 @@ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + MockQuicData socket_data; quic::QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
diff --git a/net/reporting/reporting_cache.cc b/net/reporting/reporting_cache.cc index f6db40c4..3f30793 100644 --- a/net/reporting/reporting_cache.cc +++ b/net/reporting/reporting_cache.cc
@@ -197,27 +197,19 @@ context_->NotifyCacheUpdated(); } - void IncrementEndpointDeliveries( - const GURL& endpoint, - const std::vector<const ReportingReport*>& reports, - bool successful) override { - std::unordered_map<const ReportingClient*, int> reports_per_client; - for (const ReportingReport* report : reports) { - DCHECK(base::ContainsKey(reports_, report)); - url::Origin origin = url::Origin::Create(report->url); - const ReportingClient* client = - GetClientByOriginAndEndpoint(origin, endpoint); - DCHECK(client); - reports_per_client[client]++; - } - - for (const auto& client_and_report_count : reports_per_client) { - auto& metadata = client_metadata_[client_and_report_count.first]; + void IncrementEndpointDeliveries(const url::Origin& origin, + const GURL& endpoint, + int reports_delivered, + bool successful) override { + const ReportingClient* client = + GetClientByOriginAndEndpoint(origin, endpoint); + if (client) { + auto& metadata = client_metadata_[client]; metadata.stats.attempted_uploads++; - metadata.stats.attempted_reports += client_and_report_count.second; + metadata.stats.attempted_reports += reports_delivered; if (successful) { metadata.stats.successful_uploads++; - metadata.stats.successful_reports += client_and_report_count.second; + metadata.stats.successful_reports += reports_delivered; } } } @@ -292,10 +284,7 @@ context_->NotifyCacheUpdated(); } - void MarkClientUsed(const url::Origin& origin, - const GURL& endpoint) override { - const ReportingClient* client = - GetClientByOriginAndEndpoint(origin, endpoint); + void MarkClientUsed(const ReportingClient* client) override { DCHECK(client); client_metadata_[client].last_used = tick_clock()->NowTicks(); }
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h index 1c19b98..eda09b3 100644 --- a/net/reporting/reporting_cache.h +++ b/net/reporting/reporting_cache.h
@@ -104,10 +104,10 @@ // Records that we attempted (and possibly succeeded at) delivering |reports| // to |endpoint|. - virtual void IncrementEndpointDeliveries( - const GURL& endpoint, - const std::vector<const ReportingReport*>& reports, - bool successful) = 0; + virtual void IncrementEndpointDeliveries(const url::Origin& origin, + const GURL& endpoint, + int reports_delivered, + bool successful) = 0; // Removes a set of reports. Any reports that are pending will not be removed // immediately, but rather marked doomed and removed once they are no longer @@ -134,8 +134,7 @@ int priority, int client) = 0; - virtual void MarkClientUsed(const url::Origin& origin, - const GURL& endpoint) = 0; + virtual void MarkClientUsed(const ReportingClient* client) = 0; // Gets all of the clients in the cache, regardless of origin or group. //
diff --git a/net/reporting/reporting_cache_unittest.cc b/net/reporting/reporting_cache_unittest.cc index a2fbb9e..6d4dd30 100644 --- a/net/reporting/reporting_cache_unittest.cc +++ b/net/reporting/reporting_cache_unittest.cc
@@ -411,18 +411,8 @@ SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, expires); SetClient(kOrigin2_, kEndpoint2_, true, kGroup1_, expires); - // Add some reports so that we can test the upload counts. - const ReportingReport* report1a = AddAndReturnReport( - kUrl1_, kGroup1_, kType_, std::make_unique<base::DictionaryValue>(), 0, - expires, 0); - const ReportingReport* report1b = AddAndReturnReport( - kUrl1_, kGroup1_, kType_, std::make_unique<base::DictionaryValue>(), 0, - expires, 1); - const ReportingReport* report2 = AddAndReturnReport( - kUrl2_, kGroup1_, kType_, std::make_unique<base::DictionaryValue>(), 0, - expires, 1); - cache()->IncrementEndpointDeliveries(kEndpoint1_, {report1a, report1b}, true); - cache()->IncrementEndpointDeliveries(kEndpoint2_, {report2}, false); + cache()->IncrementEndpointDeliveries(kOrigin1_, kEndpoint1_, 2, true); + cache()->IncrementEndpointDeliveries(kOrigin2_, kEndpoint2_, 1, false); base::Value actual = cache()->GetClientsAsValue(); std::unique_ptr<base::Value> expected = base::test::ParseJson(R"json( @@ -651,7 +641,9 @@ // Use clients in reverse order, so client (max_client_count - 1) is LRU. for (size_t i = 1; i <= max_client_count; ++i) { - cache()->MarkClientUsed(kOrigin1_, MakeEndpoint(max_client_count - i)); + const ReportingClient* client = FindClientInCache( + cache(), kOrigin1_, MakeEndpoint(max_client_count - i)); + cache()->MarkClientUsed(client); tick_clock()->Advance(base::TimeDelta::FromSeconds(1)); }
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc index 238d37d..9d3105a 100644 --- a/net/reporting/reporting_delivery_agent.cc +++ b/net/reporting/reporting_delivery_agent.cc
@@ -80,13 +80,19 @@ private: class Delivery { public: - Delivery(const GURL& endpoint, std::vector<const ReportingReport*> reports) - : endpoint(endpoint), reports(std::move(reports)) {} + Delivery(const GURL& endpoint) : endpoint(endpoint) {} ~Delivery() = default; + void AddReports(const ReportingClient* client, + const std::vector<const ReportingReport*>& to_add) { + reports_per_client[client->origin][client->endpoint] += to_add.size(); + reports.insert(reports.end(), to_add.begin(), to_add.end()); + } + const GURL endpoint; std::vector<const ReportingReport*> reports; + std::map<url::Origin, std::map<GURL, int>> reports_per_client; }; using OriginGroup = std::pair<url::Origin, std::string>; @@ -146,24 +152,32 @@ // Find endpoint for each (origin, group) bucket and sort reports into // endpoint buckets. Don't allow concurrent deliveries to the same (origin, // group) bucket. - std::map<GURL, std::vector<const ReportingReport*>> endpoint_reports; + std::map<GURL, std::unique_ptr<Delivery>> deliveries; for (auto& it : origin_group_reports) { const OriginGroup& origin_group = it.first; if (base::ContainsKey(pending_origin_groups_, origin_group)) continue; - GURL endpoint_url; - if (!endpoint_manager()->FindEndpointForOriginAndGroup( - origin_group.first, origin_group.second, &endpoint_url)) { + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(origin_group.first, + origin_group.second); + if (client == nullptr) { continue; } + cache()->MarkClientUsed(client); - cache()->MarkClientUsed(origin_group.first, endpoint_url); + Delivery* delivery; + auto delivery_it = deliveries.find(client->endpoint); + if (delivery_it == deliveries.end()) { + auto new_delivery = std::make_unique<Delivery>(client->endpoint); + delivery = new_delivery.get(); + deliveries[client->endpoint] = std::move(new_delivery); + } else { + delivery = delivery_it->second.get(); + } - endpoint_reports[endpoint_url].insert( - endpoint_reports[endpoint_url].end(), it.second.begin(), - it.second.end()); + delivery->AddReports(client, it.second); pending_origin_groups_.insert(origin_group); } @@ -172,18 +186,18 @@ std::unordered_set<const ReportingReport*> undelivered_reports( reports.begin(), reports.end()); - // Start a delivery to each endpoint. - for (auto& it : endpoint_reports) { + // Start an upload for each delivery. + for (auto& it : deliveries) { const GURL& endpoint = it.first; - const std::vector<const ReportingReport*>& reports = it.second; + std::unique_ptr<Delivery>& delivery = it.second; endpoint_manager()->SetEndpointPending(endpoint); std::string json; - SerializeReports(reports, tick_clock()->NowTicks(), &json); + SerializeReports(delivery->reports, tick_clock()->NowTicks(), &json); int max_depth = 0; - for (const ReportingReport* report : reports) { + for (const ReportingReport* report : delivery->reports) { undelivered_reports.erase(report); if (report->depth > max_depth) max_depth = report->depth; @@ -192,10 +206,8 @@ // TODO: Calculate actual max depth. uploader()->StartUpload( endpoint, json, max_depth, - base::BindOnce( - &ReportingDeliveryAgentImpl::OnUploadComplete, - weak_factory_.GetWeakPtr(), - std::make_unique<Delivery>(endpoint, std::move(reports)))); + base::BindOnce(&ReportingDeliveryAgentImpl::OnUploadComplete, + weak_factory_.GetWeakPtr(), std::move(delivery))); } cache()->ClearReportsPending( @@ -204,9 +216,16 @@ void OnUploadComplete(const std::unique_ptr<Delivery>& delivery, ReportingUploader::Outcome outcome) { - cache()->IncrementEndpointDeliveries( - delivery->endpoint, delivery->reports, - outcome == ReportingUploader::Outcome::SUCCESS); + for (const auto& origin_and_pair : delivery->reports_per_client) { + const url::Origin& origin = origin_and_pair.first; + for (const auto& endpoint_and_count : origin_and_pair.second) { + const GURL& endpoint = endpoint_and_count.first; + int report_count = endpoint_and_count.second; + cache()->IncrementEndpointDeliveries( + origin, endpoint, report_count, + outcome == ReportingUploader::Outcome::SUCCESS); + } + } if (outcome == ReportingUploader::Outcome::SUCCESS) { cache()->RemoveReports(delivery->reports,
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index 6bf623a8..976ed4f 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -44,13 +44,16 @@ void SetClient(const url::Origin& origin, const GURL& endpoint, - const std::string& group) { - cache()->SetClient(origin, endpoint, ReportingClient::Subdomains::EXCLUDE, - group, tomorrow(), ReportingClient::kDefaultPriority, + const std::string& group, + ReportingClient::Subdomains subdomains = + ReportingClient::Subdomains::EXCLUDE) { + cache()->SetClient(origin, endpoint, subdomains, group, tomorrow(), + ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight); } const GURL kUrl_ = GURL("https://origin/path"); + const GURL kSubdomainUrl_ = GURL("https://sub.origin/path"); const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/")); const GURL kEndpoint_ = GURL("https://endpoint/"); const std::string kGroup_ = "group"; @@ -92,7 +95,70 @@ cache()->GetReports(&reports); EXPECT_TRUE(reports.empty()); - // TODO(juliatuttle): Check that BackoffEntry was informed of success. + // TODO(dcreager): Check that BackoffEntry was informed of success. +} + +TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) { + base::DictionaryValue body; + body.SetString("key", "value"); + + SetClient(kOrigin_, kEndpoint_, kGroup_, + ReportingClient::Subdomains::INCLUDE); + cache()->AddReport(kSubdomainUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0, + tick_clock()->NowTicks(), 0); + + // Upload is automatically started when cache is modified. + + ASSERT_EQ(1u, pending_uploads().size()); + EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url()); + { + auto value = pending_uploads()[0]->GetValue(); + + base::ListValue* list; + ASSERT_TRUE(value->GetAsList(&list)); + EXPECT_EQ(1u, list->GetSize()); + + base::DictionaryValue* report; + ASSERT_TRUE(list->GetDictionary(0, &report)); + EXPECT_EQ(4u, report->size()); + + ExpectDictIntegerValue(0, *report, "age"); + ExpectDictStringValue(kType_, *report, "type"); + ExpectDictStringValue(kSubdomainUrl_.spec(), *report, "url"); + ExpectDictDictionaryValue(body, *report, "report"); + } + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + + // Successful upload should remove delivered reports. + std::vector<const ReportingReport*> reports; + cache()->GetReports(&reports); + EXPECT_TRUE(reports.empty()); + + // TODO(dcreager): Check that BackoffEntry was informed of success. +} + +TEST_F(ReportingDeliveryAgentTest, + SuccessfulImmediateSubdomainUploadWithEvictedClient) { + base::DictionaryValue body; + body.SetString("key", "value"); + + SetClient(kOrigin_, kEndpoint_, kGroup_, + ReportingClient::Subdomains::INCLUDE); + cache()->AddReport(kSubdomainUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0, + tick_clock()->NowTicks(), 0); + + // Upload is automatically started when cache is modified. + + ASSERT_EQ(1u, pending_uploads().size()); + // Evict the client + SetClient(kOrigin_, kEndpoint_, kGroup_, + ReportingClient::Subdomains::EXCLUDE); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + + // Successful upload should remove delivered reports. + std::vector<const ReportingReport*> reports; + cache()->GetReports(&reports); + EXPECT_TRUE(reports.empty()); } TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
diff --git a/net/reporting/reporting_endpoint_manager.cc b/net/reporting/reporting_endpoint_manager.cc index b5aec56..4284648 100644 --- a/net/reporting/reporting_endpoint_manager.cc +++ b/net/reporting/reporting_endpoint_manager.cc
@@ -35,9 +35,9 @@ ~ReportingEndpointManagerImpl() override = default; - bool FindEndpointForOriginAndGroup(const url::Origin& origin, - const std::string& group, - GURL* endpoint_url_out) override { + const ReportingClient* FindClientForOriginAndGroup( + const url::Origin& origin, + const std::string& group) override { std::vector<const ReportingClient*> clients; cache()->GetClientsForOriginAndGroup(origin, group, &clients); @@ -79,8 +79,7 @@ } if (available_clients.empty()) { - *endpoint_url_out = GURL(); - return false; + return nullptr; } int random_index = rand_callback_.Run(0, total_weight - 1); @@ -89,14 +88,13 @@ const ReportingClient* client = available_clients[i]; weight_so_far += client->weight; if (random_index < weight_so_far) { - *endpoint_url_out = client->endpoint; - return true; + return client; } } // TODO(juliatuttle): Can we reach this in some weird overflow case? NOTREACHED(); - return false; + return nullptr; } void SetEndpointPending(const GURL& endpoint) override {
diff --git a/net/reporting/reporting_endpoint_manager.h b/net/reporting/reporting_endpoint_manager.h index 6df5f38..7d18da0 100644 --- a/net/reporting/reporting_endpoint_manager.h +++ b/net/reporting/reporting_endpoint_manager.h
@@ -21,6 +21,8 @@ namespace net { +struct ReportingClient; + // Keeps track of which endpoints are pending (have active delivery attempts to // them) or in exponential backoff after one or more failures, and chooses an // endpoint from an endpoint group to receive reports for an origin. @@ -39,12 +41,11 @@ // Deliberately chooses an endpoint randomly to ensure sites aren't relying on // any sort of fallback ordering. // - // Returns true and sets |*endpoint_url_out| to the endpoint URL if an - // endpoint was chosen; returns false (and leaves |*endpoint_url_out| invalid) - // if no endpoint was found. - virtual bool FindEndpointForOriginAndGroup(const url::Origin& origin, - const std::string& group, - GURL* endpoint_url_out) = 0; + // Returns the endpoint's |ReportingClient| if endpoint was chosen; returns + // nullptr if no endpoint was found. + virtual const ReportingClient* FindClientForOriginAndGroup( + const url::Origin& origin, + const std::string& group) = 0; // Adds |endpoint| to the set of pending endpoints, preventing it from being // chosen for a second parallel delivery attempt.
diff --git a/net/reporting/reporting_endpoint_manager_unittest.cc b/net/reporting/reporting_endpoint_manager_unittest.cc index de26c00..26b6f32 100644 --- a/net/reporting/reporting_endpoint_manager_unittest.cc +++ b/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -33,21 +33,19 @@ }; TEST_F(ReportingEndpointManagerTest, NoEndpoint) { - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); } TEST_F(ReportingEndpointManagerTest, Endpoint) { SetClient(kEndpoint_, ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight); - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_TRUE(found_endpoint); - EXPECT_EQ(kEndpoint_, endpoint_url); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kEndpoint_, client->endpoint); } TEST_F(ReportingEndpointManagerTest, ExpiredEndpoint) { @@ -57,10 +55,9 @@ // Default expiration is "tomorrow", so make sure we're past that. tick_clock()->Advance(base::TimeDelta::FromDays(2)); - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); } TEST_F(ReportingEndpointManagerTest, PendingEndpoint) { @@ -69,17 +66,15 @@ endpoint_manager()->SetEndpointPending(kEndpoint_); - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); endpoint_manager()->ClearEndpointPending(kEndpoint_); - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_TRUE(found_endpoint); - EXPECT_EQ(kEndpoint_, endpoint_url); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kEndpoint_, client->endpoint); } TEST_F(ReportingEndpointManagerTest, BackedOffEndpoint) { @@ -94,40 +89,35 @@ endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false); // After one failure, endpoint is in exponential backoff. - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); // After initial delay, endpoint is usable again. tick_clock()->Advance(initial_delay); - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_TRUE(found_endpoint); - EXPECT_EQ(kEndpoint_, endpoint_url); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kEndpoint_, client->endpoint); endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false); // After a second failure, endpoint is backed off again. - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); tick_clock()->Advance(initial_delay); // Next backoff is longer -- 2x the first -- so endpoint isn't usable yet. - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); tick_clock()->Advance(initial_delay); // After 2x the initial delay, the endpoint is usable again. - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_TRUE(found_endpoint); - EXPECT_EQ(kEndpoint_, endpoint_url); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kEndpoint_, client->endpoint); endpoint_manager()->InformOfEndpointRequest(kEndpoint_, true); endpoint_manager()->InformOfEndpointRequest(kEndpoint_, true); @@ -136,15 +126,13 @@ // again. endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false); - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_FALSE(found_endpoint); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client == nullptr); tick_clock()->Advance(initial_delay); - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - EXPECT_TRUE(found_endpoint); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + EXPECT_TRUE(client != nullptr); } // Make sure that multiple endpoints will all be returned at some point, to @@ -163,15 +151,15 @@ bool endpoint2_seen = false; for (int i = 0; i < kMaxAttempts; ++i) { - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - ASSERT_TRUE(found_endpoint); - ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + ASSERT_TRUE(client->endpoint == kEndpoint1 || + client->endpoint == kEndpoint2); - if (endpoint_url == kEndpoint1) + if (client->endpoint == kEndpoint1) endpoint1_seen = true; - else if (endpoint_url == kEndpoint2) + else if (client->endpoint == kEndpoint2) endpoint2_seen = true; if (endpoint1_seen && endpoint2_seen) @@ -189,26 +177,22 @@ SetClient(kPrimaryEndpoint, 10, ReportingClient::kDefaultWeight); SetClient(kBackupEndpoint, 20, ReportingClient::kDefaultWeight); - GURL endpoint_url; - - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - ASSERT_TRUE(found_endpoint); - EXPECT_EQ(kPrimaryEndpoint, endpoint_url); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kPrimaryEndpoint, client->endpoint); endpoint_manager()->SetEndpointPending(kPrimaryEndpoint); - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - ASSERT_TRUE(found_endpoint); - EXPECT_EQ(kBackupEndpoint, endpoint_url); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kBackupEndpoint, client->endpoint); endpoint_manager()->ClearEndpointPending(kPrimaryEndpoint); - found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - ASSERT_TRUE(found_endpoint); - EXPECT_EQ(kPrimaryEndpoint, endpoint_url); + client = endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + EXPECT_EQ(kPrimaryEndpoint, client->endpoint); } // Note: This test depends on the deterministic mock RandIntCallback set up in @@ -229,15 +213,15 @@ int endpoint2_count = 0; for (int i = 0; i < kTotalEndpointWeight; ++i) { - GURL endpoint_url; - bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( - kOrigin_, kGroup_, &endpoint_url); - ASSERT_TRUE(found_endpoint); - ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2); + const ReportingClient* client = + endpoint_manager()->FindClientForOriginAndGroup(kOrigin_, kGroup_); + ASSERT_TRUE(client != nullptr); + ASSERT_TRUE(client->endpoint == kEndpoint1 || + client->endpoint == kEndpoint2); - if (endpoint_url == kEndpoint1) + if (client->endpoint == kEndpoint1) ++endpoint1_count; - else if (endpoint_url == kEndpoint2) + else if (client->endpoint == kEndpoint2) ++endpoint2_count; }
diff --git a/net/third_party/quic/core/chlo_extractor.cc b/net/third_party/quic/core/chlo_extractor.cc index 9278c67..d299f2c 100644 --- a/net/third_party/quic/core/chlo_extractor.cc +++ b/net/third_party/quic/core/chlo_extractor.cc
@@ -38,7 +38,6 @@ void OnDecryptedPacket(EncryptionLevel level) override {} bool OnPacketHeader(const QuicPacketHeader& header) override; bool OnStreamFrame(const QuicStreamFrame& frame) override; - bool OnAckFrame(const QuicAckFrame& frame) override; bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override; bool OnAckRange(QuicPacketNumber start, @@ -140,10 +139,6 @@ return true; } -bool ChloFramerVisitor::OnAckFrame(const QuicAckFrame& frame) { - return true; -} - bool ChloFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/, QuicTime::Delta /*ack_delay_time*/) { return true;
diff --git a/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc b/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc index e7fe2cf..d765575 100644 --- a/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc +++ b/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc
@@ -9,6 +9,7 @@ #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" +#include "net/third_party/quic/platform/api/quic_logging.h" namespace quic { BandwidthSampler::BandwidthSampler() @@ -119,10 +120,11 @@ // always larger than the time of the previous packet, otherwise division by // zero or integer underflow can occur. if (ack_time <= sent_packet.last_acked_packet_ack_time) { - QUIC_BUG << "Time of the previously acked packet:" - << sent_packet.last_acked_packet_ack_time.ToDebuggingValue() - << " is larger than the ack time of the current packet:" - << ack_time.ToDebuggingValue(); + QUIC_LOG(DFATAL) + << "Time of the previously acked packet:" + << sent_packet.last_acked_packet_ack_time.ToDebuggingValue() + << " is larger than the ack time of the current packet:" + << ack_time.ToDebuggingValue(); return BandwidthSample(); } QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender.cc b/net/third_party/quic/core/congestion_control/bbr_sender.cc index 094f683..7bd00e7 100644 --- a/net/third_party/quic/core/congestion_control/bbr_sender.cc +++ b/net/third_party/quic/core/congestion_control/bbr_sender.cc
@@ -25,13 +25,11 @@ const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize; // The gain used for the slow start, equal to 2/ln(2). -const float kHighGain = 2.885f; +const float kDefaultHighGain = 2.885f; // The gain used in STARTUP after loss has been detected. // 1.5 is enough to allow for 25% exogenous loss and still observe a 25% growth // in measured bandwidth. const float kStartupAfterLossGain = 1.5f; -// The gain used to drain the queue after the slow start. -const float kDrainGain = 1.f / kHighGain; // The cycle of gains used during the PROBE_BW stage. const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1}; @@ -99,13 +97,13 @@ kDefaultTCPMSS), max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), min_congestion_window_(kDefaultMinimumCongestionWindow), + high_gain_(kDefaultHighGain), + drain_gain_(1.f / kDefaultHighGain), pacing_rate_(QuicBandwidth::Zero()), pacing_gain_(1), congestion_window_gain_(1), congestion_window_gain_constant_( static_cast<float>(FLAGS_quic_bbr_cwnd_gain)), - rtt_variance_weight_( - static_cast<float>(FLAGS_quic_bbr_rtt_variation_weight)), num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup), exit_startup_on_loss_(false), cycle_current_offset_(0), @@ -117,11 +115,11 @@ exit_probe_rtt_at_(QuicTime::Zero()), probe_rtt_round_passed_(false), last_sample_is_app_limited_(false), - has_non_app_limited_sample_( - !GetQuicReloadableFlag(quic_bbr_slower_startup2)), + has_non_app_limited_sample_(false), recovery_state_(NOT_IN_RECOVERY), end_recovery_at_(0), recovery_window_(max_congestion_window_), + is_app_limited_recovery_(false), slower_startup_(false), rate_based_startup_(false), initial_conservation_in_startup_(CONSERVATION), @@ -131,9 +129,6 @@ probe_rtt_disabled_if_app_limited_(false), app_limited_since_last_probe_rtt_(false), min_rtt_since_last_probe_rtt_(QuicTime::Delta::Infinite()) { - if (!has_non_app_limited_sample_) { - QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_slower_startup2); - } EnterStartupMode(); } @@ -176,8 +171,8 @@ QuicBandwidth BbrSender::PacingRate(QuicByteCount bytes_in_flight) const { if (pacing_rate_.IsZero()) { - return kHighGain * QuicBandwidth::FromBytesAndTimeDelta( - initial_congestion_window_, GetMinRtt()); + return high_gain_ * QuicBandwidth::FromBytesAndTimeDelta( + initial_congestion_window_, GetMinRtt()); } return pacing_rate_; } @@ -359,8 +354,8 @@ void BbrSender::EnterStartupMode() { mode_ = STARTUP; - pacing_gain_ = kHighGain; - congestion_window_gain_ = kHighGain; + pacing_gain_ = high_gain_; + congestion_window_gain_ = high_gain_; } void BbrSender::EnterProbeBandwidthMode(QuicTime now) { @@ -400,8 +395,7 @@ const AckedPacketVector& acked_packets) { QuicTime::Delta sample_min_rtt = QuicTime::Delta::Infinite(); for (const auto& packet : acked_packets) { - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4) && - packet.bytes_acked == 0) { + if (packet.bytes_acked == 0) { // Skip acked packets with 0 in flight bytes when updating bandwidth. continue; } @@ -469,11 +463,7 @@ void BbrSender::UpdateGainCyclePhase(QuicTime now, QuicByteCount prior_in_flight, bool has_losses) { - QuicByteCount bytes_in_flight = prior_in_flight; - if (GetQuicReloadableFlag(quic_bbr_fix_probe_bw)) { - QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_fix_probe_bw); - bytes_in_flight = unacked_packets_->bytes_in_flight(); - } + const QuicByteCount bytes_in_flight = unacked_packets_->bytes_in_flight(); // In most cases, the cycle is advanced after an RTT passes. bool should_advance_gain_cycling = now - last_cycle_start_ > GetMinRtt(); @@ -532,8 +522,8 @@ void BbrSender::MaybeExitStartupOrDrain(QuicTime now) { if (mode_ == STARTUP && is_at_full_bandwidth_) { mode_ = DRAIN; - pacing_gain_ = kDrainGain; - congestion_window_gain_ = kHighGain; + pacing_gain_ = drain_gain_; + congestion_window_gain_ = high_gain_; } if (mode_ == DRAIN && unacked_packets_->bytes_in_flight() <= GetTargetCongestionWindow(1)) { @@ -605,6 +595,11 @@ // Since the conservation phase is meant to be lasting for a whole // round, extend the current round as if it were started right now. current_round_trip_end_ = last_sent_packet_; + if (GetQuicReloadableFlag(quic_bbr_app_limited_recovery) && + last_sample_is_app_limited_) { + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_app_limited_recovery); + is_app_limited_recovery_ = true; + } } break; @@ -619,10 +614,14 @@ // Exit recovery if appropriate. if (!has_losses && last_acked_packet > end_recovery_at_) { recovery_state_ = NOT_IN_RECOVERY; + is_app_limited_recovery_ = false; } break; } + if (recovery_state_ != NOT_IN_RECOVERY && is_app_limited_recovery_) { + sampler_->OnAppLimited(); + } } // TODO(ianswett): Move this logic into BandwidthSampler. @@ -685,11 +684,8 @@ QuicByteCount target_window = GetTargetCongestionWindow(congestion_window_gain_); - - if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { - target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * - BandwidthEstimate(); - } else if (is_at_full_bandwidth_) { + if (is_at_full_bandwidth_) { + // Add the max recently measured ack aggregation to CWND. target_window += max_ack_height_.GetBest(); }
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender.h b/net/third_party/quic/core/congestion_control/bbr_sender.h index 9656aed..ee2bae7 100644 --- a/net/third_party/quic/core/congestion_control/bbr_sender.h +++ b/net/third_party/quic/core/congestion_control/bbr_sender.h
@@ -139,6 +139,18 @@ return has_non_app_limited_sample_; } + // Sets the pacing and CWND gain used in STARTUP. Must be greater than 1. + void set_high_gain(float high_gain) { + DCHECK_LT(1.0f, high_gain); + high_gain_ = high_gain; + } + + // Sets the gain used in DRAIN. Must be less than 1. + void set_drain_gain(float drain_gain) { + DCHECK_GT(1.0f, drain_gain); + drain_gain_ = drain_gain; + } + DebugState ExportDebugState() const; private: @@ -148,12 +160,6 @@ QuicRoundTripCount> MaxBandwidthFilter; - typedef WindowedFilter<QuicTime::Delta, - MaxFilter<QuicTime::Delta>, - QuicRoundTripCount, - QuicRoundTripCount> - MaxAckDelayFilter; - typedef WindowedFilter<QuicByteCount, MaxFilter<QuicByteCount>, QuicRoundTripCount, @@ -269,6 +275,12 @@ // The smallest value the |congestion_window_| can achieve. QuicByteCount min_congestion_window_; + // The pacing and CWND gain applied during the STARTUP phase. + float high_gain_; + + // The pacing gain applied during the DRAIN phase. + float drain_gain_; + // The current pacing rate of the connection. QuicBandwidth pacing_rate_; @@ -280,9 +292,6 @@ // The gain used for the congestion window during PROBE_BW. Latched from // quic_bbr_cwnd_gain flag. const float congestion_window_gain_constant_; - // The coefficient by which mean RTT variance is added to the congestion - // window. Latched from quic_bbr_rtt_variation_weight flag. - const float rtt_variance_weight_; // The number of RTTs to stay in STARTUP mode. Defaults to 3. QuicRoundTripCount num_startup_rtts_; // If true, exit startup if 1RTT has passed with no bandwidth increase and @@ -326,6 +335,8 @@ QuicPacketNumber end_recovery_at_; // A window used to limit the number of bytes in flight during loss recovery. QuicByteCount recovery_window_; + // If true, consider all samples in recovery app-limited. + bool is_app_limited_recovery_; // When true, pace at 1.5x and disable packet conservation in STARTUP. bool slower_startup_;
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender_test.cc b/net/third_party/quic/core/congestion_control/bbr_sender_test.cc index 854d055..c173686 100644 --- a/net/third_party/quic/core/congestion_control/bbr_sender_test.cc +++ b/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
@@ -684,6 +684,48 @@ EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start); } +// Verify that the first sample after PROBE_RTT is not used as the bandwidth, +// because the round counter doesn't advance during PROBE_RTT. +TEST_F(BbrSenderTest, AppLimitedRecoveryNoBandwidthDecrease) { + SetQuicReloadableFlag(quic_bbr_app_limited_recovery, true); + CreateDefaultSetup(); + DriveOutOfStartup(); + + // We have no intention of ever finishing this transfer. + bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024); + + // Wait until the connection enters PROBE_RTT. + const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12); + bool simulator_result = simulator_.RunUntilOrTimeout( + [this]() { + return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT; + }, + timeout); + ASSERT_TRUE(simulator_result); + ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode); + + const QuicBandwidth beginning_bw = sender_->BandwidthEstimate(); + + // Run for most of PROBE_RTT. + const QuicTime probe_rtt_start = clock_->Now(); + const QuicTime::Delta time_to_exit_probe_rtt = + kTestRtt + QuicTime::Delta::FromMilliseconds(200); + simulator_.RunFor(0.60 * time_to_exit_probe_rtt); + EXPECT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode); + EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited); + // Lose a packet before exiting PROBE_RTT, which puts us in packet + // conservation and then continue there for a while and ensure the bandwidth + // estimate doesn't decrease. + for (int i = 0; i < 20; ++i) { + receiver_.DropNextIncomingPacket(); + simulator_.RunFor(0.9 * kTestRtt); + // Ensure the bandwidth didn't decrease and the samples are app limited. + EXPECT_LE(beginning_bw, sender_->BandwidthEstimate()); + EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited); + } + EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start); +} + // Verify that the connection enters and exits PROBE_RTT correctly. TEST_F(BbrSenderTest, ProbeRttBDPBasedCWNDTarget) { CreateDefaultSetup();
diff --git a/net/third_party/quic/core/congestion_control/cubic_bytes_test.cc b/net/third_party/quic/core/congestion_control/cubic_bytes_test.cc index 681c08c..d45f0001 100644 --- a/net/third_party/quic/core/congestion_control/cubic_bytes_test.cc +++ b/net/third_party/quic/core/congestion_control/cubic_bytes_test.cc
@@ -11,8 +11,6 @@ #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quic/test_tools/mock_clock.h" -using std::string; - namespace quic { namespace test { namespace {
diff --git a/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc b/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc index 517b343..6324815 100644 --- a/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc +++ b/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -49,8 +49,8 @@ void VerifyLosses(QuicPacketNumber largest_newly_acked, const std::vector<QuicPacketNumber>& losses_expected) { - if (largest_newly_acked > unacked_packets_.largest_observed()) { - unacked_packets_.IncreaseLargestObserved(largest_newly_acked); + if (largest_newly_acked > unacked_packets_.largest_acked()) { + unacked_packets_.IncreaseLargestAcked(largest_newly_acked); } LostPacketVector lost_packets; loss_algorithm_.DetectLosses(unacked_packets_, clock_.Now(), rtt_stats_, @@ -173,7 +173,7 @@ clock_.AdvanceTime(rtt_stats_.smoothed_rtt()); // Early retransmit when the final packet gets acked and the first is nacked. - unacked_packets_.IncreaseLargestObserved(2); + unacked_packets_.IncreaseLargestAcked(2); unacked_packets_.RemoveFromInFlight(2); VerifyLosses(2, std::vector<QuicPacketNumber>{}); EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(), @@ -188,7 +188,7 @@ clock_.AdvanceTime(rtt_stats_.smoothed_rtt()); // Early retransmit when the final packet gets acked and the first is nacked. - unacked_packets_.IncreaseLargestObserved(2); + unacked_packets_.IncreaseLargestAcked(2); unacked_packets_.RemoveFromInFlight(2); VerifyLosses(2, std::vector<QuicPacketNumber>{}); EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(), @@ -212,7 +212,7 @@ // Wait another RTT and ack 2. clock_.AdvanceTime(rtt_stats_.smoothed_rtt()); - unacked_packets_.IncreaseLargestObserved(2); + unacked_packets_.IncreaseLargestAcked(2); unacked_packets_.RemoveFromInFlight(2); VerifyLosses(2, {1}); }
diff --git a/net/third_party/quic/core/congestion_control/pacing_sender.cc b/net/third_party/quic/core/congestion_control/pacing_sender.cc index 157bf87..afedefb 100644 --- a/net/third_party/quic/core/congestion_control/pacing_sender.cc +++ b/net/third_party/quic/core/congestion_control/pacing_sender.cc
@@ -24,7 +24,12 @@ initial_burst_size_(kInitialUnpacedBurst), lumpy_tokens_(0), alarm_granularity_(QuicTime::Delta::FromMilliseconds(1)), - pacing_limited_(false) {} + pacing_limited_(false) { + if (GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) { + QUIC_FLAG_COUNT( + quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time); + } +} PacingSender::~PacingSender() {} @@ -70,7 +75,9 @@ } if (burst_tokens_ > 0) { --burst_tokens_; - ideal_next_packet_send_time_ = QuicTime::Zero(); + if (!GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) { + ideal_next_packet_send_time_ = QuicTime::Zero(); + } pacing_limited_ = false; return; }
diff --git a/net/third_party/quic/core/congestion_control/send_algorithm_interface.cc b/net/third_party/quic/core/congestion_control/send_algorithm_interface.cc index 814927d..5e4b471 100644 --- a/net/third_party/quic/core/congestion_control/send_algorithm_interface.cc +++ b/net/third_party/quic/core/congestion_control/send_algorithm_interface.cc
@@ -33,7 +33,7 @@ initial_congestion_window, max_congestion_window, random); case kPCC: - if (GetQuicReloadableFlag(quic_enable_pcc2)) { + if (GetQuicReloadableFlag(quic_enable_pcc3)) { return CreatePccSender(clock, rtt_stats, unacked_packets, random, stats, initial_congestion_window, max_congestion_window);
diff --git a/net/third_party/quic/core/crypto/crypto_protocol.h b/net/third_party/quic/core/crypto/crypto_protocol.h index 5faeb36..886697c 100644 --- a/net/third_party/quic/core/crypto/crypto_protocol.h +++ b/net/third_party/quic/core/crypto/crypto_protocol.h
@@ -142,13 +142,12 @@ const QuicTag kSSLR = TAG('S', 'S', 'L', 'R'); // Slow Start Large Reduction. const QuicTag kNPRR = TAG('N', 'P', 'R', 'R'); // Pace at unity instead of PRR const QuicTag k5RTO = TAG('5', 'R', 'T', 'O'); // Close connection on 5 RTOs -const QuicTag k3RTO = TAG('3', 'R', 'T', 'O'); // Close connection on 3 RTOs const QuicTag kCONH = TAG('C', 'O', 'N', 'H'); // Conservative Handshake // Retransmissions. const QuicTag kLFAK = TAG('L', 'F', 'A', 'K'); // Don't invoke FACK on the // first ack. -// TODO(fayang): Remove this connection option in QUIC_VERSION_37, in which -// MAX_HEADER_LIST_SIZE settings frame should be supported. +// TODO(fayang): Remove this connection option when QUIC_VERSION_35, is removed +// Since MAX_HEADER_LIST_SIZE settings frame is supported instead. const QuicTag kSMHL = TAG('S', 'M', 'H', 'L'); // Support MAX_HEADER_LIST_SIZE // settings frame. const QuicTag kNSTP = TAG('N', 'S', 'T', 'P'); // No stop waiting frames.
diff --git a/net/third_party/quic/core/crypto/crypto_utils.cc b/net/third_party/quic/core/crypto/crypto_utils.cc index 7a4bbd5..67b30762 100644 --- a/net/third_party/quic/core/crypto/crypto_utils.cc +++ b/net/third_party/quic/core/crypto/crypto_utils.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "crypto/hkdf.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_decrypter.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_encrypter.h" #include "net/third_party/quic/core/crypto/crypto_handshake.h"
diff --git a/net/third_party/quic/core/crypto/null_decrypter_test.cc b/net/third_party/quic/core/crypto/null_decrypter_test.cc index a6c48124..f0d05a0 100644 --- a/net/third_party/quic/core/crypto/null_decrypter_test.cc +++ b/net/third_party/quic/core/crypto/null_decrypter_test.cc
@@ -24,7 +24,7 @@ NullDecrypter decrypter(Perspective::IS_SERVER); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_37, 0, "hello world!", + ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_39, 0, "hello world!", QuicStringPiece(data, len), buffer, &length, 256)); EXPECT_LT(0u, length); @@ -43,7 +43,7 @@ NullDecrypter decrypter(Perspective::IS_CLIENT); char buffer[256]; size_t length = 0; - ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_37, 0, "hello world!", + ASSERT_TRUE(decrypter.DecryptPacket(QUIC_VERSION_39, 0, "hello world!", QuicStringPiece(data, len), buffer, &length, 256)); EXPECT_LT(0u, length);
diff --git a/net/third_party/quic/core/crypto/null_encrypter_test.cc b/net/third_party/quic/core/crypto/null_encrypter_test.cc index db0ce358..143e84f7 100644 --- a/net/third_party/quic/core/crypto/null_encrypter_test.cc +++ b/net/third_party/quic/core/crypto/null_encrypter_test.cc
@@ -22,7 +22,7 @@ char encrypted[256]; size_t encrypted_len = 0; NullEncrypter encrypter(Perspective::IS_CLIENT); - ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_37, 0, "hello world!", + ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_39, 0, "hello world!", "goodbye!", encrypted, &encrypted_len, 256)); test::CompareCharArraysWithHexError( @@ -40,7 +40,7 @@ char encrypted[256]; size_t encrypted_len = 0; NullEncrypter encrypter(Perspective::IS_SERVER); - ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_37, 0, "hello world!", + ASSERT_TRUE(encrypter.EncryptPacket(QUIC_VERSION_39, 0, "hello world!", "goodbye!", encrypted, &encrypted_len, 256)); test::CompareCharArraysWithHexError(
diff --git a/net/third_party/quic/core/crypto/quic_crypto_server_config.cc b/net/third_party/quic/core/crypto/quic_crypto_server_config.cc index 6e51958..e41a69d4 100644 --- a/net/third_party/quic/core/crypto/quic_crypto_server_config.cc +++ b/net/third_party/quic/core/crypto/quic_crypto_server_config.cc
@@ -10,7 +10,6 @@ #include <memory> #include "base/macros.h" -#include "crypto/hkdf.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_12_decrypter.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/third_party/quic/core/crypto/cert_compressor.h"
diff --git a/net/third_party/quic/core/crypto/quic_decrypter.cc b/net/third_party/quic/core/crypto/quic_decrypter.cc index df130aa..1bf4b37 100644 --- a/net/third_party/quic/core/crypto/quic_decrypter.cc +++ b/net/third_party/quic/core/crypto/quic_decrypter.cc
@@ -4,7 +4,6 @@ #include "net/third_party/quic/core/crypto/quic_decrypter.h" -#include "crypto/hkdf.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_12_decrypter.h" #include "net/third_party/quic/core/crypto/aes_128_gcm_decrypter.h" #include "net/third_party/quic/core/crypto/aes_256_gcm_decrypter.h"
diff --git a/net/third_party/quic/core/crypto/quic_random.cc b/net/third_party/quic/core/crypto/quic_random.cc index f912c57..a7a9569 100644 --- a/net/third_party/quic/core/crypto/quic_random.cc +++ b/net/third_party/quic/core/crypto/quic_random.cc
@@ -5,7 +5,6 @@ #include "net/third_party/quic/core/crypto/quic_random.h" #include "base/macros.h" -#include "base/memory/singleton.h" #include "crypto/random.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_singleton.h" @@ -21,7 +20,6 @@ // QuicRandom implementation void RandBytes(void* data, size_t len) override; uint64_t RandUint64() override; - void Reseed(const void* additional_entropy, size_t entropy_len) override; private: DefaultRandom() {} @@ -45,10 +43,6 @@ return value; } -void DefaultRandom::Reseed(const void* additional_entropy, size_t entropy_len) { - // No such function exists in crypto/random.h. -} - } // namespace // static
diff --git a/net/third_party/quic/core/crypto/quic_random.h b/net/third_party/quic/core/crypto/quic_random.h index 659a2e48..1e31a6e 100644 --- a/net/third_party/quic/core/crypto/quic_random.h +++ b/net/third_party/quic/core/crypto/quic_random.h
@@ -26,11 +26,6 @@ // Returns a random number in the range [0, kuint64max]. virtual uint64_t RandUint64() = 0; - - // Reseeds the random number generator with additional entropy input. - // NOTE: the constructor of a QuicRandom object is responsible for seeding - // itself with enough entropy input. - virtual void Reseed(const void* additional_entropy, size_t entropy_len) = 0; }; } // namespace quic
diff --git a/net/third_party/quic/core/crypto/quic_random_test.cc b/net/third_party/quic/core/crypto/quic_random_test.cc index 6e25cd6..8621be1 100644 --- a/net/third_party/quic/core/crypto/quic_random_test.cc +++ b/net/third_party/quic/core/crypto/quic_random_test.cc
@@ -30,13 +30,5 @@ EXPECT_NE(value1, value2); } -TEST_F(QuicRandomTest, Reseed) { - char buf[1024]; - memset(buf, 0xaf, sizeof(buf)); - - QuicRandom* rng = QuicRandom::GetInstance(); - rng->Reseed(buf, sizeof(buf)); -} - } // namespace test } // namespace quic
diff --git a/net/third_party/quic/core/end_to_end_test.cc b/net/third_party/quic/core/end_to_end_test.cc index 8fd7c73c..d26e7ec 100644 --- a/net/third_party/quic/core/end_to_end_test.cc +++ b/net/third_party/quic/core/end_to_end_test.cc
@@ -70,8 +70,14 @@ #include "net/tools/epoll_server/epoll_server.h" #include "testing/gtest/include/gtest/gtest.h" -using base::IntToString; -using base::WaitableEvent; +using net::EpollEvent; +using net::EpollServer; +using spdy::kV3LowestPriority; +using spdy::SETTINGS_MAX_HEADER_LIST_SIZE; +using spdy::SpdyFramer; +using spdy::SpdyHeaderBlock; +using spdy::SpdySerializedFrame; +using spdy::SpdySettingsIR; namespace quic { namespace test { @@ -259,7 +265,7 @@ explicit ClientDelegate(QuicClient* client) : client_(client) {} ~ClientDelegate() override = default; void OnCanWrite() override { - net::EpollEvent event(EPOLLOUT); + EpollEvent event(EPOLLOUT); client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event); } @@ -394,7 +400,7 @@ // client as well according to the test parameter. copt.push_back(GetParam().congestion_control_tag); if (GetParam().congestion_control_tag == kTPCC && - GetQuicReloadableFlag(quic_enable_pcc2)) { + GetQuicReloadableFlag(quic_enable_pcc3)) { copt.push_back(kTPCC); } @@ -411,7 +417,7 @@ StartServer(); CreateClientWithWriter(); - static net::EpollEvent event(EPOLLOUT); + static EpollEvent event(EPOLLOUT); if (client_writer_ != nullptr) { client_writer_->Initialize( QuicConnectionPeer::GetHelper( @@ -688,7 +694,7 @@ ASSERT_TRUE(Initialize()); // Send a request in two parts: the request and then an empty packet with FIN. - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -723,7 +729,7 @@ const int kNumRequests = 10; - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -746,7 +752,7 @@ ASSERT_TRUE(Initialize()); std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr)); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -797,7 +803,7 @@ ASSERT_TRUE(Initialize()); // Add a content length header with no body. - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -819,7 +825,7 @@ // 1 MB body. QuicString body(1024 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -840,7 +846,7 @@ // 100 KB body. QuicString body(100 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -868,7 +874,7 @@ // 10 KB body. QuicString body(1024 * 10, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -896,7 +902,7 @@ // 10 KB body. QuicString body(1024 * 10, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -916,7 +922,7 @@ // 1 MB body. QuicString body(1024 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -932,7 +938,7 @@ ASSERT_TRUE(Initialize()); QuicString body(20480, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1042,7 +1048,7 @@ ASSERT_TRUE(Initialize()); QuicString body(20480, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1142,7 +1148,7 @@ // 1 MB body. QuicString body(1024 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1159,7 +1165,7 @@ // Regression test for b/14677858. // Test that the resume write alarm is not set in QuicConnection::OnCanWrite // if currently connection level flow control blocked. If set, this results in - // an infinite loop in the net::EpollServer, as the alarm fires and is + // an infinite loop in the EpollServer, as the alarm fires and is // immediately rescheduled. ASSERT_TRUE(Initialize()); EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); @@ -1203,7 +1209,7 @@ EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); QuicString body(kMaxPacketSize, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1226,7 +1232,7 @@ EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); QuicString body(kMaxPacketSize, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1245,7 +1251,7 @@ EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); QuicString large_body(1024 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1309,7 +1315,7 @@ QuicSessionPeer::SetMaxOpenOutgoingStreams( client_->client()->client_session(), kServerMaxStreams + 1); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -1675,7 +1681,7 @@ // Register the new FD for epoll events. int new_fd = client_->client()->GetLatestFD(); - net::EpollServer* eps = client_->epoll_server(); + EpollServer* eps = client_->epoll_server(); eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(), EPOLLIN | EPOLLOUT | EPOLLET); @@ -1873,56 +1879,46 @@ ->flow_controller(), QuicSessionPeer::GetMutableCryptoStream(server_session) ->flow_controller()); - spdy::SpdyFramer spdy_framer(spdy::SpdyFramer::ENABLE_COMPRESSION); - spdy::SpdySettingsIR settings_frame; - settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, + SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION); + SpdySettingsIR settings_frame; + settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize); - spdy::SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame)); + SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame)); QuicFlowController* client_header_stream_flow_controller = QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller(); QuicFlowController* server_header_stream_flow_controller = QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller(); - if (GetQuicReloadableFlag(quic_send_max_header_list_size)) { - // Both client and server are sending this SETTINGS frame, and the send - // window is consumed. But because of timing issue, the server may send or - // not send the frame, and the client may send/ not send / receive / not - // receive the frame. - // TODO(fayang): Rewrite this part because it is hacky. - QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize( - server_header_stream_flow_controller) - - QuicFlowControllerPeer::SendWindowSize( - client_header_stream_flow_controller); - QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize( - client_header_stream_flow_controller) - - QuicFlowControllerPeer::SendWindowSize( - server_header_stream_flow_controller); - EXPECT_TRUE(win_difference1 == 0 || win_difference1 == frame.size()); - EXPECT_TRUE(win_difference2 == 0 || win_difference2 == frame.size()); - } else { - ExpectFlowControlsSynced( - QuicSpdySessionPeer::GetHeadersStream(client_session) - ->flow_controller(), - QuicSpdySessionPeer::GetHeadersStream(server_session) - ->flow_controller()); - } + // Both client and server are sending this SETTINGS frame, and the send + // window is consumed. But because of timing issue, the server may send or + // not send the frame, and the client may send/ not send / receive / not + // receive the frame. + // TODO(fayang): Rewrite this part because it is hacky. + QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize( + server_header_stream_flow_controller) - + QuicFlowControllerPeer::SendWindowSize( + client_header_stream_flow_controller); + QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize( + client_header_stream_flow_controller) - + QuicFlowControllerPeer::SendWindowSize( + server_header_stream_flow_controller); + EXPECT_TRUE(win_difference1 == 0 || win_difference1 == frame.size()); + EXPECT_TRUE(win_difference2 == 0 || win_difference2 == frame.size()); - if (GetQuicReloadableFlag(quic_send_max_header_list_size)) { - // Client *may* have received the SETTINGs frame. - // TODO(fayang): Rewrite this part because it is hacky. - float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( - client_session->flow_controller())) / - QuicFlowControllerPeer::ReceiveWindowSize( - QuicSpdySessionPeer::GetHeadersStream(client_session) - ->flow_controller()); - float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( - client_session->flow_controller())) / - (QuicFlowControllerPeer::ReceiveWindowSize( - QuicSpdySessionPeer::GetHeadersStream(client_session) - ->flow_controller()) + - frame.size()); - EXPECT_TRUE(ratio1 == kSessionToStreamRatio || - ratio2 == kSessionToStreamRatio); - } + // Client *may* have received the SETTINGs frame. + // TODO(fayang): Rewrite this part because it is hacky. + float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( + client_session->flow_controller())) / + QuicFlowControllerPeer::ReceiveWindowSize( + QuicSpdySessionPeer::GetHeadersStream(client_session) + ->flow_controller()); + float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( + client_session->flow_controller())) / + (QuicFlowControllerPeer::ReceiveWindowSize( + QuicSpdySessionPeer::GetHeadersStream(client_session) + ->flow_controller()) + + frame.size()); + EXPECT_TRUE(ratio1 == kSessionToStreamRatio || + ratio2 == kSessionToStreamRatio); server_thread_->Resume(); } @@ -1973,7 +1969,7 @@ class TestResponseListener : public QuicSpdyClientBase::ResponseListener { public: void OnCompleteResponse(QuicStreamId id, - const spdy::SpdyHeaderBlock& response_headers, + const SpdyHeaderBlock& response_headers, const QuicString& response_body) override { QUIC_DVLOG(1) << "response for stream " << id << " " << response_headers.DebugString() << "\n" @@ -1999,7 +1995,7 @@ client_writer_->set_fake_blocked_socket_percentage(10); // Create a POST request and send the headers only. - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -2315,7 +2311,7 @@ EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); // Lose the request. SetPacketLossPercentage(100); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -2347,7 +2343,7 @@ protected: void SendErrorResponse() override { QUIC_DLOG(INFO) << "Sending error response for stream " << id(); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":status"] = "500"; headers["content-length"] = QuicTextUtils::Uint64ToString(response_body_.size()); @@ -2510,7 +2506,7 @@ // and before the body is received, due to invalid content-length. // Set an invalid content-length, so the request will receive an early 500 // response. - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/garbage"; headers[":scheme"] = "https"; @@ -2561,12 +2557,12 @@ // Add a response with headers, body, and trailers. const QuicString kBody = "body content"; - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":status"] = "200"; headers[":version"] = "HTTP/1.1"; headers["content-length"] = QuicTextUtils::Uint64ToString(kBody.size()); - spdy::SpdyHeaderBlock trailers; + SpdyHeaderBlock trailers; trailers["some-trailing-header"] = "trailing-header-value"; memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url", @@ -2614,14 +2610,13 @@ use_large_response ? large_resource : QuicStrCat("This is server push response body for ", url); - spdy::SpdyHeaderBlock response_headers; + SpdyHeaderBlock response_headers; response_headers[":version"] = "HTTP/1.1"; response_headers[":status"] = "200"; response_headers["content-length"] = QuicTextUtils::Uint64ToString(body.size()); push_resources.push_back(QuicBackendResponse::ServerPushInfo( - resource_url, std::move(response_headers), spdy::kV3LowestPriority, - body)); + resource_url, std::move(response_headers), kV3LowestPriority, body)); } memory_cache_backend_.AddSimpleResponseWithServerPushResources( @@ -2872,7 +2867,7 @@ ASSERT_LT(INT64_C(4294967296), request_body_size_bytes); QuicString body(kSizeBytes, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -2912,7 +2907,7 @@ client->UseWriter(client_writer_); client->Connect(); client_.reset(client); - static net::EpollEvent event(EPOLLOUT); + static EpollEvent event(EPOLLOUT); client_writer_->Initialize( QuicConnectionPeer::GetHelper( client_->client()->client_session()->connection()), @@ -2945,7 +2940,7 @@ TEST_P(EndToEndTest, WayTooLongRequestHeaders) { ASSERT_TRUE(Initialize()); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "GET"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -2988,7 +2983,7 @@ QuicTransportVersion version = client_connection->transport_version(); // 100KB body. QuicString body(100 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -2997,7 +2992,7 @@ EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(headers, body)); client_->Disconnect(); - if (version > QUIC_VERSION_38) { + if (version != QUIC_VERSION_35) { EXPECT_LT(0u, observer.num_window_update_frames()); EXPECT_EQ(0u, observer.num_ping_frames()); } else { @@ -3025,7 +3020,7 @@ // 1 MB body. QuicString body(1024 * 1024, 'a'); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/foo"; headers[":scheme"] = "https"; @@ -3112,7 +3107,7 @@ // INCOMPLETE_RESPONSE will cause the server to not to send the trailer // (and the FIN) after the response body. QuicString response_body(1305, 'a'); - spdy::SpdyHeaderBlock response_headers; + SpdyHeaderBlock response_headers; response_headers[":status"] = QuicTextUtils::Uint64ToString(200); response_headers["content-length"] = QuicTextUtils::Uint64ToString(response_body.length()); @@ -3143,7 +3138,7 @@ class EndToEndPacketReorderingTest : public EndToEndTest { public: void CreateClientWithWriter() override { - QUIC_LOG(ERROR) << "create client with reorder_writer_ "; + QUIC_LOG(ERROR) << "create client with reorder_writer_"; reorder_writer_ = new PacketReorderingWriter(); client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_)); } @@ -3223,7 +3218,7 @@ ASSERT_TRUE(client_->client()->connected()); // Send a request before handshake finishes. - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[":method"] = "POST"; headers[":path"] = "/bar"; headers[":scheme"] = "https";
diff --git a/net/third_party/quic/core/proto/quic_trace.proto b/net/third_party/quic/core/proto/quic_trace.proto deleted file mode 100644 index c6aa954..0000000 --- a/net/third_party/quic/core/proto/quic_trace.proto +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright (c) 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file describes a format for a trace containing all events related to the -// QUIC connection. It is primarily focused on representing information related -// to congestion control and loss recovery. It's entirely up to implementation -// which fields to populate; the consumers of the data should not assume all of -// the frames are recorded in either direction. -// -// This format is intended to be usable by any QUIC implementation. It is -// primarily based on IETF QUIC (draft 11), but has a few legacy gQUIC entries, -// and can be potentially extended in the future. -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package quic_trace; - -enum FrameType { - UNKNOWN_FRAME = 0; - - STREAM = 1; - ACK = 2; - RESET_STREAM = 3; - CONNECTION_CLOSE = 4; - MAX_DATA = 5; - MAX_STREAM_DATA = 6; - PING = 7; - BLOCKED = 8; - STREAM_BLOCKED = 9; - PADDING = 10; -}; - -// Metadata for STREAM frames. -message StreamFrameInfo { - optional uint64 stream_id = 1; - optional bool fin = 2; - optional uint64 length = 3; - optional uint64 offset = 4; -}; - -// The intervals are closed, i.e. the interval represented here is -// [first_packet, last_packet]. -message AckBlock { - optional uint64 first_packet = 1; - optional uint64 last_packet = 2; -}; - -// Metadata for ACK frames. -message AckInfo { - repeated AckBlock acked_packets = 1; - optional uint64 ack_delay_us = 2; -}; - -// Metadata for RST_STREAM frames. -message ResetStreamInfo { - optional uint64 stream_id = 1; - optional uint32 application_error_code = 2; - optional uint64 final_offset = 3; -}; - -// Metadata for CONNECTION_CLOSE/APPLICATION_CLOSE frames. -message CloseInfo { - optional uint32 error_code = 1; - optional string reason_phrase = 2; -}; - -// Metadata for MAX_DATA/MAX_STREAM_DATA frames. -message FlowControlInfo { - optional uint64 max_data = 1; - optional uint64 stream_id = 2; -}; - -// A message representing a frame, either sent or received. -message Frame { - optional FrameType frame_type = 1; - - optional StreamFrameInfo stream_frame_info = 2; - optional AckInfo ack_info = 3; - optional ResetStreamInfo reset_stream_info = 4; - optional CloseInfo close_info = 5; - optional FlowControlInfo flow_control_info = 6; -}; - -// Metadata that represents transport stack's understanding of the current state -// of the transport channel. -message TransportState { - optional uint64 min_rtt_us = 1; - // Smoothed RTT, usually computed using EWMA. - optional uint64 smoothed_rtt_us = 2; - // The latest RTT measureent available. - optional uint64 last_rtt_us = 3; - - optional uint64 in_flight_bytes = 4; - optional uint64 cwnd_bytes = 5; - // Pacing rate, in bits per second. - optional uint64 pacing_rate_bps = 6; - - // Any arbitrary information about congestion control state that is not - // representable via parameters above. - optional string congestion_control_state = 7; -}; - -enum EncryptionLevel { - ENCRYPTION_UNKNOWN = 0; - - ENCRYPTION_INITIAL = 1; - ENCRYPTION_0RTT = 2; - ENCRYPTION_1RTT = 3; -}; - -enum EventType { - UNKNOWN_EVENT = 0; - - PACKET_SENT = 1; - PACKET_RECEIVED = 2; - PACKET_LOST = 3; -}; - -// An event that has occurred over duration of the connection. -message Event { - optional uint64 time_us = 1; - optional EventType event_type = 2; - - optional uint64 packet_number = 3; - repeated Frame frames = 4; - optional uint64 packet_size = 5; - optional EncryptionLevel encryption_level = 6; - // State of the transport stack after the event has happened. - optional TransportState transport_state = 7; -}; - -message Trace { - // QUIC version tag, as represented on wire. Should be always 4 bytes long. - optional bytes protocol_version = 1; - - // Source and destination connection ID. If multiple connection IDs are used, - // record the first one used with short-form header. - optional bytes source_connection_id = 2; - optional bytes destination_connection_id = 3; - - repeated Event events = 4; -};
diff --git a/net/third_party/quic/core/quic_config.cc b/net/third_party/quic/core/quic_config.cc index b516ac8..23fe58e 100644 --- a/net/third_party/quic/core/quic_config.cc +++ b/net/third_party/quic/core/quic_config.cc
@@ -668,9 +668,7 @@ SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow); SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow); - if (GetQuicReloadableFlag(quic_send_max_header_list_size)) { - SetSupportMaxHeaderListSize(); - } + SetSupportMaxHeaderListSize(); } void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
diff --git a/net/third_party/quic/core/quic_connection.cc b/net/third_party/quic/core/quic_connection.cc index 94393e0..12892037 100644 --- a/net/third_party/quic/core/quic_connection.cc +++ b/net/third_party/quic/core/quic_connection.cc
@@ -49,7 +49,7 @@ const QuicPacketNumber kMaxPacketGap = 5000; // Maximum number of acks received before sending an ack in response. -// TODO(fayang): Remove this constant when deprecating QUIC_VERSION_38. +// TODO(fayang): Remove this constant when deprecating QUIC_VERSION_35. const QuicPacketCount kMaxPacketsReceivedBeforeAckSend = 20; // Maximum number of consecutive sent nonretransmittable packets. @@ -239,7 +239,6 @@ idle_timeout_connection_close_behavior_( ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET), close_connection_after_five_rtos_(false), - close_connection_after_three_rtos_(false), received_packet_manager_(&stats_), ack_queued_(false), num_retransmittable_packets_received_since_last_ack_sent_(0), @@ -321,7 +320,10 @@ deprecate_scheduler_( GetQuicReloadableFlag(quic_deprecate_scoped_scheduler2)), add_to_blocked_list_if_writer_blocked_( - GetQuicReloadableFlag(quic_add_to_blocked_list_if_writer_blocked)) { + GetQuicReloadableFlag(quic_add_to_blocked_list_if_writer_blocked)), + ack_reordered_packets_(GetQuicReloadableFlag(quic_ack_reordered_packets)), + retransmissions_app_limited_( + GetQuicReloadableFlag(quic_retransmissions_app_limited)) { if (ack_mode_ == ACK_DECIMATION) { QUIC_FLAG_COUNT(quic_reloadable_flag_quic_enable_ack_decimation); } @@ -431,12 +433,7 @@ if (config.HasClientSentConnectionOption(k5RTO, perspective_)) { close_connection_after_five_rtos_ = true; } - if (GetQuicReloadableFlag(quic_enable_3rtos) && - config.HasClientSentConnectionOption(k3RTO, perspective_)) { - QUIC_FLAG_COUNT(quic_reloadable_flag_quic_enable_3rtos); - close_connection_after_three_rtos_ = true; - } - if (transport_version() > QUIC_VERSION_37 && + if (transport_version() != QUIC_VERSION_35 && config.HasClientSentConnectionOption(kNSTP, perspective_)) { no_stop_waiting_frames_ = true; } @@ -864,59 +861,9 @@ return connected_; } -bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { - DCHECK(connected_); - DCHECK(!framer_.use_incremental_ack_processing()); - - // Since an ack frame was received, this is not a connectivity probe. - // A probe only contains a PING and full padding. - UpdatePacketContent(NOT_PADDED_PING); - - if (debug_visitor_ != nullptr) { - debug_visitor_->OnAckFrame(incoming_ack); - } - QUIC_DVLOG(1) << ENDPOINT << "OnAckFrame: " << incoming_ack; - - if (last_header_.packet_number <= largest_seen_packet_with_ack_) { - QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring"; - return true; - } - - const char* error = ValidateAckFrame(incoming_ack); - if (error != nullptr) { - CloseConnection(QUIC_INVALID_ACK_DATA, error, - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); - return false; - } - - if (send_alarm_->IsSet()) { - send_alarm_->Cancel(); - } - - if (LargestAcked(incoming_ack) > sent_packet_manager_.GetLargestObserved()) { - visitor_->OnForwardProgressConfirmed(); - } - - largest_seen_packet_with_ack_ = last_header_.packet_number; - bool acked_new_packet = sent_packet_manager_.OnIncomingAck( - incoming_ack, time_of_last_received_packet_); - // If the incoming ack's packets set expresses missing packets: peer is still - // waiting for a packet lower than a packet that we are no longer planning to - // send. - // If the incoming ack's packets set expresses received packets: peer is still - // acking packets which we never care about. - // Send an ack to raise the high water mark. - PostProcessAfterAckFrame(!incoming_ack.packets.Empty() && - GetLeastUnacked() > incoming_ack.packets.Min(), - acked_new_packet); - - return connected_; -} - bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) { DCHECK(connected_); - DCHECK(framer_.use_incremental_ack_processing()); if (processing_ack_frame_) { CloseConnection(QUIC_INVALID_ACK_DATA, @@ -977,7 +924,6 @@ QuicPacketNumber end, bool last_range) { DCHECK(connected_); - DCHECK(framer_.use_incremental_ack_processing()); QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << "), last_range: " << last_range; @@ -992,6 +938,9 @@ } bool acked_new_packet = sent_packet_manager_.OnAckFrameEnd(time_of_last_received_packet_); + // Cancel the send alarm because new packets likely have been acked, which + // may change the congestion window and/or pacing rate. Canceling the alarm + // causes CanWrite to recalculate the next send time. if (send_alarm_->IsSet()) { send_alarm_->Cancel(); } @@ -1336,7 +1285,7 @@ ++num_packets_received_since_last_ack_sent_; // Always send an ack every 20 packets in order to allow the peer to discard // information from the SentPacketManager and provide an RTT measurement. - if (transport_version() <= QUIC_VERSION_38 && + if (transport_version() == QUIC_VERSION_35 && num_packets_received_since_last_ack_sent_ >= kMaxPacketsReceivedBeforeAckSend) { ack_queued_ = true; @@ -1344,11 +1293,24 @@ // Determine whether the newly received packet was missing before recording // the received packet. - // Ack decimation with reordering relies on the timer to send an ack, but if - // missing packets we reported in the previous ack, send an ack immediately. - if (was_missing && (ack_mode_ != ACK_DECIMATION_WITH_REORDERING || - last_ack_had_missing_packets_)) { - ack_queued_ = true; + if (was_missing) { + if (ack_reordered_packets_) { + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_ack_reordered_packets); + // Only ack immediately if an ACK frame was sent with a larger + // largest acked than the newly received packet number. + if (last_header_.packet_number < + sent_packet_manager_.unacked_packets().largest_sent_largest_acked()) { + ack_queued_ = true; + } + } else { + // Ack decimation with reordering relies on the timer to send an ack, + // but if missing packets we reported in the previous ack, send an ack + // immediately. + if (ack_mode_ != ACK_DECIMATION_WITH_REORDERING || + last_ack_had_missing_packets_) { + ack_queued_ = true; + } + } } if (should_last_packet_instigate_acks_ && !ack_queued_) { @@ -1726,11 +1688,22 @@ void QuicConnection::OnCanWrite() { DCHECK(!writer_->IsWriteBlocked()); + std::unique_ptr<ScopedPacketFlusher> flusher; + if (retransmissions_app_limited_) { + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_retransmissions_app_limited); + // Add a flusher to ensure the connection is marked app-limited. + flusher.reset(new ScopedPacketFlusher(this, NO_ACK)); + } + WriteQueuedPackets(); if (!session_decides_what_to_write()) { WritePendingRetransmissions(); } + WriteNewData(); +} + +void QuicConnection::WriteNewData() { // Sending queued packets may have caused the socket to become write blocked, // or the congestion manager to prohibit sending. If we've sent everything // we had queued and we're still not blocked, let the visitor know it can @@ -1907,12 +1880,10 @@ DCHECK(!session_decides_what_to_write()); // Keep writing as long as there's a pending retransmission which can be // written. - while (sent_packet_manager_.HasPendingRetransmissions()) { + while (sent_packet_manager_.HasPendingRetransmissions() && + CanWrite(HAS_RETRANSMITTABLE_DATA)) { const QuicPendingRetransmission pending = sent_packet_manager_.NextPendingRetransmission(); - if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) { - break; - } // Re-packetize the frames with a new packet number for retransmission. // Retransmitted packets use the same packet number length as the @@ -1927,6 +1898,7 @@ ScopedPacketFlusher flusher(this, NO_ACK); packet_generator_.FlushAllQueuedFrames(); } + DCHECK(!packet_generator_.HasQueuedFrames()); char buffer[kMaxPacketSize]; packet_generator_.ReserializeAllFrames(pending, buffer, kMaxPacketSize); } @@ -2270,7 +2242,7 @@ return; } - if (transport_version() > QUIC_VERSION_38) { + if (transport_version() != QUIC_VERSION_35) { if (serialized_packet->retransmittable_frames.empty() && serialized_packet->original_packet_number == 0) { // Increment consecutive_num_packets_with_no_retransmittable_frames_ if @@ -2350,7 +2322,10 @@ ack_queued_ = false; stop_waiting_count_ = 0; num_retransmittable_packets_received_since_last_ack_sent_ = 0; - last_ack_had_missing_packets_ = received_packet_manager_.HasMissingPackets(); + if (!ack_reordered_packets_) { + last_ack_had_missing_packets_ = + received_packet_manager_.HasMissingPackets(); + } num_packets_received_since_last_ack_sent_ = 0; packet_generator_.SetShouldSendAck(!no_stop_waiting_frames_); @@ -2374,15 +2349,6 @@ void QuicConnection::OnRetransmissionTimeout() { DCHECK(sent_packet_manager_.HasUnackedPackets()); - - if (close_connection_after_three_rtos_ && - sent_packet_manager_.GetConsecutiveRtoCount() >= 2 && - !visitor_->HasOpenDynamicStreams()) { - // Close on the 3rd consecutive RTO, so after 2 previous RTOs have occurred. - CloseConnection(QUIC_TOO_MANY_RTOS, "3 consecutive retransmission timeouts", - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); - return; - } if (close_connection_after_five_rtos_ && sent_packet_manager_.GetConsecutiveRtoCount() >= 4) { // Close on the 5th consecutive RTO, so after 4 previous RTOs have occurred.
diff --git a/net/third_party/quic/core/quic_connection.h b/net/third_party/quic/core/quic_connection.h index 1fd4e0e..404a8902 100644 --- a/net/third_party/quic/core/quic_connection.h +++ b/net/third_party/quic/core/quic_connection.h
@@ -416,7 +416,7 @@ // Called when an error occurs while attempting to write a packet to the // network. - void OnWriteError(int error_code); + virtual void OnWriteError(int error_code); // Whether |result| represents a MSG TOO BIG write error. bool IsMsgTooBig(const WriteResult& result); @@ -468,7 +468,6 @@ void OnDecryptedPacket(EncryptionLevel level) override; bool OnPacketHeader(const QuicPacketHeader& header) override; bool OnStreamFrame(const QuicStreamFrame& frame) override; - bool OnAckFrame(const QuicAckFrame& frame) override; bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override; bool OnAckRange(QuicPacketNumber start, @@ -927,6 +926,9 @@ // Writes as many pending retransmissions as possible. void WritePendingRetransmissions(); + // Writes new data if congestion control allows. + void WriteNewData(); + // Queues |packet| in the hopes that it can be decrypted in the // future, when a new key is installed. void QueueUndecryptablePacket(const QuicEncryptedPacket& packet); @@ -1106,9 +1108,6 @@ // When true, close the QUIC connection after 5 RTOs. Due to the min rto of // 200ms, this is over 5 seconds. bool close_connection_after_five_rtos_; - // When true, close the QUIC connection when there are no open streams after - // 3 consecutive RTOs. - bool close_connection_after_three_rtos_; QuicReceivedPacketManager received_packet_manager_; @@ -1117,6 +1116,8 @@ // How many retransmittable packets have arrived without sending an ack. QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_; // Whether there were missing packets in the last sent ack. + // TODO(ianswett): Deprecate with + // quic_reloadable_flag_quic_ack_reordered_packets. bool last_ack_had_missing_packets_; // How many consecutive packets have arrived without sending an ack. QuicPacketCount num_packets_received_since_last_ack_sent_; @@ -1317,6 +1318,12 @@ // gfe2_reloadable_flag_quic_add_to_blocked_list_if_writer_blocked. const bool add_to_blocked_list_if_writer_blocked_; + // Latched value of quic_reloadable_flag_quic_ack_reordered_packets. + const bool ack_reordered_packets_; + + // Latched value of quic_reloadable_flag_quic_retransmissions_app_limited. + const bool retransmissions_app_limited_; + DISALLOW_COPY_AND_ASSIGN(QuicConnection); };
diff --git a/net/third_party/quic/core/quic_connection_test.cc b/net/third_party/quic/core/quic_connection_test.cc index 5848e41..72afe38 100644 --- a/net/third_party/quic/core/quic_connection_test.cc +++ b/net/third_party/quic/core/quic_connection_test.cc
@@ -2155,7 +2155,7 @@ } TEST_P(QuicConnectionTest, 20AcksCausesAckSend) { - if (connection_.version().transport_version > QUIC_VERSION_38) { + if (connection_.version().transport_version != QUIC_VERSION_35) { return; } EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); @@ -2177,7 +2177,7 @@ } TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) { - if (connection_.version().transport_version <= QUIC_VERSION_38) { + if (connection_.version().transport_version == QUIC_VERSION_35) { return; } @@ -2843,6 +2843,12 @@ // Ensure that the data is still in flight, but the retransmission alarm is no // longer set. EXPECT_GT(QuicSentPacketManagerPeer::GetBytesInFlight(manager_), 0u); + if (GetQuicReloadableFlag(quic_optimize_inflight_check)) { + EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); + // Firing the alarm should remove all bytes_in_flight. + connection_.GetRetransmissionAlarm()->Fire(); + EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_)); + } EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); } @@ -2957,9 +2963,7 @@ // Now, ack the previous transmission. EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _)); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _)); - } + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _)); QuicAckFrame ack_all = InitAckFrame(3); ProcessAckPacket(&ack_all); @@ -3084,6 +3088,12 @@ writer_->SetWritable(); connection_.OnCanWrite(); // There is now a pending packet, but with no retransmittable frames. + if (GetQuicReloadableFlag(quic_optimize_inflight_check)) { + EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); + // Firing the alarm should remove all bytes_in_flight. + connection_.GetRetransmissionAlarm()->Fire(); + EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_)); + } EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 2)); } @@ -4482,39 +4492,6 @@ EXPECT_FALSE(connection_.connected()); } -TEST_P(QuicConnectionTest, TimeoutAfter3ClientRTOs) { - SetQuicReloadableFlag(quic_enable_3rtos, true); - connection_.SetMaxTailLossProbes(2); - EXPECT_TRUE(connection_.connected()); - EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); - QuicConfig config; - QuicTagVector connection_options; - connection_options.push_back(k3RTO); - config.SetConnectionOptionsToSend(connection_options); - connection_.SetFromConfig(config); - - // Send stream data. - SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, FIN, nullptr); - - // Fire the retransmission alarm 4 times, twice for TLP and 2 times for RTO. - for (int i = 0; i < 4; ++i) { - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); - connection_.GetRetransmissionAlarm()->Fire(); - EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet()); - EXPECT_TRUE(connection_.connected()); - } - - EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveTlpCount()); - EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveRtoCount()); - // This time, we should time out. - EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_TOO_MANY_RTOS, _, - ConnectionCloseSource::FROM_SELF)); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); - connection_.GetRetransmissionAlarm()->Fire(); - EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet()); - EXPECT_FALSE(connection_.connected()); -} - TEST_P(QuicConnectionTest, SendScheduler) { // Test that if we send a packet without delay, it is not queued. QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT); @@ -5102,41 +5079,42 @@ ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL); } EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); - // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used - // instead of ENCRYPTION_NONE. - EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); - ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting, - ENCRYPTION_INITIAL); - // Check if delayed ack timer is running for the expected interval. - EXPECT_TRUE(connection_.GetAckAlarm()->IsSet()); - EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline()); - - // Process packet 10 first and ensure the alarm is one eighth min_rtt. - EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); - ProcessDataPacketAtLevel(kFirstDecimatedPacket + 9, !kHasStopWaiting, - ENCRYPTION_INITIAL); - ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5); - EXPECT_TRUE(connection_.GetAckAlarm()->IsSet()); - EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline()); - - // The 10th received packet causes an ack to be sent. - for (int i = 0; i < 8; ++i) { - EXPECT_TRUE(connection_.GetAckAlarm()->IsSet()); + // Receive one packet out of order and then the rest in order. + // The loop leaves a one packet gap between acks sent to simulate some loss. + for (int j = 0; j < 3; ++j) { + // Process packet 10 first and ensure the alarm is one eighth min_rtt. EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); - ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting, - ENCRYPTION_INITIAL); + ProcessDataPacketAtLevel(kFirstDecimatedPacket + 9 + (j * 11), + !kHasStopWaiting, ENCRYPTION_INITIAL); + ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5); + EXPECT_TRUE(connection_.GetAckAlarm()->IsSet()); + EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline()); + + // The 10th received packet causes an ack to be sent. + writer_->Reset(); + for (int i = 0; i < 9; ++i) { + EXPECT_TRUE(connection_.GetAckAlarm()->IsSet()); + EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1); + // The ACK shouldn't be sent until the 10th packet is processed. + EXPECT_TRUE(writer_->ack_frames().empty()); + ProcessDataPacketAtLevel(kFirstDecimatedPacket + i + (j * 11), + !kHasStopWaiting, ENCRYPTION_INITIAL); + } + // Check that ack is sent and that delayed ack alarm is reset. + if (GetParam().no_stop_waiting) { + EXPECT_EQ(1u, writer_->frame_count()); + EXPECT_TRUE(writer_->stop_waiting_frames().empty()); + } else { + EXPECT_EQ(2u, writer_->frame_count()); + EXPECT_FALSE(writer_->stop_waiting_frames().empty()); + } + EXPECT_FALSE(writer_->ack_frames().empty()); + EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); + if (!GetQuicReloadableFlag(quic_ack_reordered_packets)) { + break; + } } - // Check that ack is sent and that delayed ack alarm is reset. - if (GetParam().no_stop_waiting) { - EXPECT_EQ(1u, writer_->frame_count()); - EXPECT_TRUE(writer_->stop_waiting_frames().empty()); - } else { - EXPECT_EQ(2u, writer_->frame_count()); - EXPECT_FALSE(writer_->stop_waiting_frames().empty()); - } - EXPECT_FALSE(writer_->ack_frames().empty()); - EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); } TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) { @@ -5514,7 +5492,7 @@ } EXPECT_EQ(1u, writer_->stream_frames().size()); EXPECT_EQ(1u, writer_->padding_frames().size()); - EXPECT_FALSE(writer_->ack_frames().empty()); + ASSERT_FALSE(writer_->ack_frames().empty()); EXPECT_EQ(2u, LargestAcked(writer_->ack_frames().front())); EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); } @@ -5543,7 +5521,7 @@ } EXPECT_EQ(1u, writer_->stream_frames().size()); EXPECT_EQ(1u, writer_->padding_frames().size()); - EXPECT_FALSE(writer_->ack_frames().empty()); + ASSERT_FALSE(writer_->ack_frames().empty()); EXPECT_EQ(2u, LargestAcked(writer_->ack_frames().front())); EXPECT_FALSE(connection_.GetAckAlarm()->IsSet()); } @@ -6650,6 +6628,21 @@ BlockOnNextWrite(); connection_.SendStreamData3(); + + if (!GetQuicReloadableFlag(quic_retransmissions_app_limited)) { + return; + } + // Now unblock the writer, become congestion control blocked, + // and ensure we become app-limited after writing. + writer_->SetWritable(); + CongestionBlockWrites(); + EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false)); + { + InSequence seq; + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)); + EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1); + } + connection_.OnCanWrite(); } // Test the mode in which the link is filled up with probing retransmissions if
diff --git a/net/third_party/quic/core/quic_crypto_server_stream_test.cc b/net/third_party/quic/core/quic_crypto_server_stream_test.cc index 933105b..4365e058 100644 --- a/net/third_party/quic/core/quic_crypto_server_stream_test.cc +++ b/net/third_party/quic/core/quic_crypto_server_stream_test.cc
@@ -449,12 +449,6 @@ } TEST_P(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) { - // Do not send MAX_HEADER_LIST_SIZE SETTING frame. - // TODO(fayang): This SETTING frame cannot be decrypted and - // crypto_test_utils::MovePackets stops processing parsing following packets. - // Actually, crypto stream test should use QuicSession instead of - // QuicSpdySession (b/32366134). - SetQuicReloadableFlag(quic_send_max_header_list_size, false); Initialize(); InitializeFakeClient(/* supports_stateless_rejects= */ false);
diff --git a/net/third_party/quic/core/quic_dispatcher.cc b/net/third_party/quic/core/quic_dispatcher.cc index b3a0523..77d7d46 100644 --- a/net/third_party/quic/core/quic_dispatcher.cc +++ b/net/third_party/quic/core/quic_dispatcher.cc
@@ -702,11 +702,6 @@ return false; } -bool QuicDispatcher::OnAckFrame(const QuicAckFrame& /*frame*/) { - DCHECK(false); - return false; -} - bool QuicDispatcher::OnAckFrameStart(QuicPacketNumber /*largest_acked*/, QuicTime::Delta /*ack_delay_time*/) { DCHECK(false); @@ -875,7 +870,7 @@ } QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { - return new QuicTimeWaitListManager(writer_.get(), this, helper_.get(), + return new QuicTimeWaitListManager(writer_.get(), this, helper_->GetClock(), alarm_factory_.get()); } @@ -1080,17 +1075,14 @@ const QuicSocketAddress& current_self_address, std::unique_ptr<QuicReceivedPacket> current_packet, ParsedQuicVersion first_version) { - const bool enable_l1_munge = GetQuicRestartFlag(quic_enable_l1_munge); - if (enable_l1_munge) { - // Reset current_* to correspond to the packet which initiated the stateless - // reject logic. - current_client_address_ = current_client_address; - current_peer_address_ = current_peer_address; - current_self_address_ = current_self_address; - current_packet_ = current_packet.get(); - current_connection_id_ = rejector->connection_id(); - framer_.set_version(first_version); - } + // Reset current_* to correspond to the packet which initiated the stateless + // reject logic. + current_client_address_ = current_client_address; + current_peer_address_ = current_peer_address; + current_self_address_ = current_self_address; + current_packet_ = current_packet.get(); + current_connection_id_ = rejector->connection_id(); + framer_.set_version(first_version); // Stop buffering packets on this connection const auto num_erased = @@ -1108,17 +1100,6 @@ return; } - if (!enable_l1_munge) { - // Reset current_* to correspond to the packet which initiated the stateless - // reject logic. - current_client_address_ = current_client_address; - current_peer_address_ = current_peer_address; - current_self_address_ = current_self_address; - current_packet_ = current_packet.get(); - current_connection_id_ = rejector->connection_id(); - framer_.set_version(first_version); - } - ProcessStatelessRejectorState(std::move(rejector), first_version.transport_version); }
diff --git a/net/third_party/quic/core/quic_dispatcher.h b/net/third_party/quic/core/quic_dispatcher.h index 7cb5349..1e993440 100644 --- a/net/third_party/quic/core/quic_dispatcher.h +++ b/net/third_party/quic/core/quic_dispatcher.h
@@ -134,7 +134,6 @@ void OnDecryptedPacket(EncryptionLevel level) override; bool OnPacketHeader(const QuicPacketHeader& header) override; bool OnStreamFrame(const QuicStreamFrame& frame) override; - bool OnAckFrame(const QuicAckFrame& frame) override; bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override; bool OnAckRange(QuicPacketNumber start,
diff --git a/net/third_party/quic/core/quic_dispatcher_test.cc b/net/third_party/quic/core/quic_dispatcher_test.cc index 1ea814d..0d269186 100644 --- a/net/third_party/quic/core/quic_dispatcher_test.cc +++ b/net/third_party/quic/core/quic_dispatcher_test.cc
@@ -330,7 +330,7 @@ void CreateTimeWaitListManager() { time_wait_list_manager_ = new MockTimeWaitListManager( QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), - &helper_, &alarm_factory_); + helper_.GetClock(), &alarm_factory_); // dispatcher_ takes the ownership of time_wait_list_manager_. QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), time_wait_list_manager_); @@ -648,11 +648,9 @@ } TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) { - static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 9u, + static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u, "Supported versions out of sync"); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, false); - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_41_2, false); SetQuicReloadableFlag(quic_enable_version_43, true); SetQuicReloadableFlag(quic_enable_version_44, true); SetQuicFlag(&FLAGS_quic_enable_version_99, true); @@ -774,7 +772,7 @@ PACKET_4BYTE_PACKET_NUMBER, 1); // Turn off version 41. - SetQuicReloadableFlag(quic_disable_version_41, true); + SetQuicReloadableFlag(quic_disable_version_41_2, true); ++connection_id; EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, QuicStringPiece("hq"))) @@ -785,7 +783,7 @@ PACKET_4BYTE_PACKET_NUMBER, 1); // Turn on version 41. - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_41_2, false); ++connection_id; EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, QuicStringPiece("hq"))) @@ -805,72 +803,6 @@ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_41), SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, 1); - - // Turn off version 38. - SetQuicReloadableFlag(quic_disable_version_38, true); - ++connection_id; - EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, - QuicStringPiece("hq"))) - .Times(0); - ProcessPacket(client_address, connection_id, true, - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38), - SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, - PACKET_4BYTE_PACKET_NUMBER, 1); - - // Turn on version 38. - SetQuicReloadableFlag(quic_disable_version_38, false); - ++connection_id; - EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, - QuicStringPiece("hq"))) - .WillOnce(testing::Return(CreateSession( - dispatcher_.get(), config_, connection_id, client_address, - &mock_helper_, &mock_alarm_factory_, &crypto_config_, - QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); - EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), - ProcessUdpPacket(_, _, _)) - .WillOnce(WithArg<2>( - Invoke([this, connection_id](const QuicEncryptedPacket& packet) { - ValidatePacket(connection_id, packet); - }))); - EXPECT_CALL(*dispatcher_, - ShouldCreateOrBufferPacketForConnection(connection_id)); - ProcessPacket(client_address, connection_id, true, - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38), - SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, - PACKET_4BYTE_PACKET_NUMBER, 1); - - // Turn off version 37. - SetQuicReloadableFlag(quic_disable_version_37, true); - ++connection_id; - EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, - QuicStringPiece("hq"))) - .Times(0); - ProcessPacket(client_address, connection_id, true, - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37), - SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, - PACKET_4BYTE_PACKET_NUMBER, 1); - - // Turn on version 37. - SetQuicReloadableFlag(quic_disable_version_37, false); - ++connection_id; - EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address, - QuicStringPiece("hq"))) - .WillOnce(testing::Return(CreateSession( - dispatcher_.get(), config_, connection_id, client_address, - &mock_helper_, &mock_alarm_factory_, &crypto_config_, - QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); - EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), - ProcessUdpPacket(_, _, _)) - .WillOnce(WithArg<2>( - Invoke([this, connection_id](const QuicEncryptedPacket& packet) { - ValidatePacket(connection_id, packet); - }))); - EXPECT_CALL(*dispatcher_, - ShouldCreateOrBufferPacketForConnection(connection_id)); - ProcessPacket(client_address, connection_id, true, - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37), - SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, - PACKET_4BYTE_PACKET_NUMBER, 1); } // Enables mocking of the handshake-confirmation for stateless rejects.
diff --git a/net/third_party/quic/core/quic_flags_list.h b/net/third_party/quic/core/quic_flags_list.h index 7ecf0792..3940e15 100644 --- a/net/third_party/quic/core/quic_flags_list.h +++ b/net/third_party/quic/core/quic_flags_list.h
@@ -49,10 +49,6 @@ // allow CHLO packets to be buffered until next iteration of the event loop. QUIC_FLAG(bool, FLAGS_quic_allow_chlo_buffering, true) -// If true, GFE sends spdy::SETTINGS_MAX_HEADER_LIST_SIZE to the client at the -// beginning of a connection. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_send_max_header_list_size, true) - // If greater than zero, mean RTT variation is multiplied by the specified // factor and added to the congestion window limit. QUIC_FLAG(double, FLAGS_quic_bbr_rtt_variation_weight, 0.0f) @@ -68,9 +64,6 @@ // 3RTOs if there are no open streams. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_3rtos, false) -// If true, enable experiment for testing PCC congestion-control. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_pcc2, false) - // When true, defaults to BBR congestion control instead of Cubic. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_default_to_bbr, false) @@ -100,14 +93,7 @@ // If true, enable QUIC v99. QUIC_FLAG(bool, FLAGS_quic_enable_version_99, false) -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_37, true) -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_38, true) -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_41, false) - -// If true, framer will process and report ack frame incrementally. -QUIC_FLAG(bool, - FLAGS_quic_reloadable_flag_quic_use_incremental_ack_processing4, - true) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_41_2, false) // If this flag and // FLAGS_quic_reloadable_flag_quic_fix_write_out_of_order_queued_packet_crash @@ -141,17 +127,6 @@ // incoming initial RTT values. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_no_irtt, false) -// Fixed QUIC's PROBE_BW logic to exit low gain mode based on bytes_in_flight, -// not prior_in_flight. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_fix_probe_bw, true) - -// If true, changes when the dispatcher changes internal state. -QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_enable_l1_munge, true) - -// Don't slow down the pacing rate in STARTUP upon loss if there hasn't been -// at least one non app-limited sample. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_slower_startup2, true) - // If true, put ScopedRetransmissionScheduler's functionality to // ScopedPacketFlusher. QUIC_FLAG(bool, @@ -196,3 +171,40 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_add_to_blocked_list_if_writer_blocked, false) + +// Only send an ack immediately when a previously missing packet is received if +// an ack with a larger largest acked has already been sent. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_ack_reordered_packets, false) + +// If true, QuicWriteBlockedList will use StaticStreamCollection to speed up +// operations on static streams. +QUIC_FLAG( + bool, + FLAGS_quic_reloadable_flag_quic_use_static_stream_collection_in_write_blocked_list, + false) + +// If true, disables QUIC v42. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_42, false) + +// Stop checking QuicUnackedPacketMap::HasUnackedRetransmittableFrames and +// instead rely on the existing check that bytes_in_flight > 0 +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_optimize_inflight_check, false) + +// When you\'re app-limited entering recovery, stay app-limited until you exit +// recovery in QUIC BBR. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_app_limited_recovery, false) + +// If true, mark QUIC as app-limited after sending queued packets or +// retransmisssions and we then become congestion control blocked. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_retransmissions_app_limited, + false) + +// If true, stop resetting ideal_next_packet_send_time_ in pacing sender. +QUIC_FLAG( + bool, + FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, + false) + +// If true, enable experiment for testing PCC congestion-control. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_pcc3, false)
diff --git a/net/third_party/quic/core/quic_framer.cc b/net/third_party/quic/core/quic_framer.cc index 60e6f1d8..2e103059 100644 --- a/net/third_party/quic/core/quic_framer.cc +++ b/net/third_party/quic/core/quic_framer.cc
@@ -272,15 +272,8 @@ alternative_decrypter_latch_(false), perspective_(perspective), validate_flags_(true), - creation_time_(creation_time), - last_timestamp_(QuicTime::Delta::Zero()), data_producer_(nullptr), - use_incremental_ack_processing_( - GetQuicReloadableFlag(quic_use_incremental_ack_processing4)), decrypted_payload_reader_(nullptr) { - if (use_incremental_ack_processing_) { - QUIC_FLAG_COUNT(quic_reloadable_flag_quic_use_incremental_ack_processing4); - } DCHECK(!supported_versions.empty()); version_ = supported_versions_[0]; decrypter_ = QuicMakeUnique<NullDecrypter>(perspective); @@ -998,8 +991,7 @@ } for (const ParsedQuicVersion& version : versions) { - // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use WriteUInt32() once QUIC_VERSION_35 is removed. if (!writer.WriteTag( QuicEndian::HostToNet32(CreateQuicVersionLabel(version)))) { return nullptr; @@ -1039,8 +1031,7 @@ } for (const ParsedQuicVersion& version : versions) { - // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use WriteUInt32() once QUIC_VERSION_35 is removed. if (!writer.WriteTag( QuicEndian::HostToNet32(CreateQuicVersionLabel(version)))) { return nullptr; @@ -1135,8 +1126,7 @@ set_detailed_error("Unable to read supported version in negotiation."); return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET); } - // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use ReadUInt32() once QUIC_VERSION_35 is removed. version_label = QuicEndian::NetToHost32(version_label); packet.versions.push_back(ParseQuicVersionLabel(version_label)); } while (!reader->IsDoneReading()); @@ -1405,8 +1395,7 @@ if (header.version_flag) { DCHECK_EQ(Perspective::IS_CLIENT, perspective_); QuicVersionLabel version_label = CreateQuicVersionLabel(version_); - // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use WriteUInt32() once QUIC_VERSION_35 is removed. if (!writer->WriteTag(QuicEndian::NetToHost32(version_label))) { return false; } @@ -1450,8 +1439,7 @@ if (header.version_flag) { // Append version for long header. QuicVersionLabel version_label = CreateQuicVersionLabel(version_); - // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use WriteUInt32() once QUIC_VERSION_35 is removed. if (!writer->WriteTag(QuicEndian::NetToHost32(version_label))) { return false; } @@ -1488,29 +1476,6 @@ return true; } -const QuicTime::Delta QuicFramer::CalculateTimestampFromWire( - uint32_t time_delta_us) { - // The new time_delta might have wrapped to the next epoch, or it - // might have reverse wrapped to the previous epoch, or it might - // remain in the same epoch. Select the time closest to the previous - // time. - // - // epoch_delta is the delta between epochs. A delta is 4 bytes of - // microseconds. - const uint64_t epoch_delta = UINT64_C(1) << 32; - uint64_t epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1); - // Wrapping is safe here because a wrapped value will not be ClosestTo below. - uint64_t prev_epoch = epoch - epoch_delta; - uint64_t next_epoch = epoch + epoch_delta; - - uint64_t time = ClosestTo( - last_timestamp_.ToMicroseconds(), epoch + time_delta_us, - ClosestTo(last_timestamp_.ToMicroseconds(), prev_epoch + time_delta_us, - next_epoch + time_delta_us)); - - return QuicTime::Delta::FromMicroseconds(time); -} - QuicPacketNumber QuicFramer::CalculatePacketNumberFromWire( QuicPacketNumberLength packet_number_length, QuicPacketNumber base_packet_number, @@ -1585,8 +1550,7 @@ set_detailed_error("Unable to read protocol version."); return false; } - // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use ReadUInt32() once QUIC_VERSION_35 is removed. version_label = QuicEndian::NetToHost32(version_label); // If the version from the new packet is the same as the version of this @@ -1780,8 +1744,7 @@ set_detailed_error("Unable to read protocol version."); return false; } - // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier - // are removed. + // TODO(rch): Use ReadUInt32() once QUIC_VERSION_35 is removed. version_label = QuicEndian::NetToHost32(version_label); if (header->long_packet_type == VERSION_NEGOTIATION && version_label) { // Version negotiation is identified by the version field. @@ -1899,18 +1862,9 @@ (version_.transport_version >= QUIC_VERSION_41 && ((frame_type & kQuicFrameTypeSpecialMask) == kQuicFrameTypeAckMask_v41))) { - // TODO(fayang): Remove frame when deprecating - // quic_reloadable_flag_quic_use_incremental_ack_processing4. - QuicAckFrame frame; - if (!ProcessAckFrame(reader, frame_type, &frame)) { + if (!ProcessAckFrame(reader, frame_type)) { return RaiseError(QUIC_INVALID_ACK_DATA); } - if (!use_incremental_ack_processing_ && !visitor_->OnAckFrame(frame)) { - QUIC_DVLOG(1) << ENDPOINT - << "Visitor asked to stop further processing."; - // Returning true since there was no parsing error. - return true; - } continue; } @@ -2231,12 +2185,6 @@ if (!ProcessIetfAckFrame(reader, &frame)) { return RaiseError(QUIC_INVALID_ACK_DATA); } - if (!use_incremental_ack_processing_ && - !visitor_->OnAckFrame(frame)) { - QUIC_DVLOG(1) << "Visitor asked to stop further processing."; - // Returning true since there was no parsing error. - return true; - } break; } case IETF_PATH_CHALLENGE: { @@ -2437,9 +2385,7 @@ return true; } -bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, - uint8_t frame_type, - QuicAckFrame* ack_frame) { +bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) { bool has_ack_blocks = ExtractBit(frame_type, version_.transport_version != QUIC_VERSION_41 ? kQuicHasMultipleAckBlocksOffset @@ -2481,17 +2427,7 @@ return false; } - if (!use_incremental_ack_processing_) { - if (ack_delay_time_us == kUFloat16MaxValue) { - ack_frame->ack_delay_time = QuicTime::Delta::Infinite(); - } else { - ack_frame->ack_delay_time = - QuicTime::Delta::FromMicroseconds(ack_delay_time_us); - } - } - - if (use_incremental_ack_processing_ && - !visitor_->OnAckFrameStart( + if (!visitor_->OnAckFrameStart( largest_acked, ack_delay_time_us == kUFloat16MaxValue ? QuicTime::Delta::Infinite() @@ -2539,18 +2475,13 @@ } QuicPacketNumber first_received = largest_acked + 1 - first_block_length; - if (use_incremental_ack_processing_) { - if (!visitor_->OnAckRange(first_received, largest_acked + 1, - /*last_range=*/!has_ack_blocks)) { - // The visitor suppresses further processing of the packet. Although - // this is not a parsing error, returns false as this is in middle - // of processing an ack frame, - set_detailed_error("Visitor suppresses further processing of ack frame."); - return false; - } - } else { - ack_frame->largest_acked = largest_acked; - ack_frame->packets.AddRange(first_received, largest_acked + 1); + if (!visitor_->OnAckRange(first_received, largest_acked + 1, + /*last_range=*/!has_ack_blocks)) { + // The visitor suppresses further processing of the packet. Although + // this is not a parsing error, returns false as this is in middle + // of processing an ack frame, + set_detailed_error("Visitor suppresses further processing of ack frame."); + return false; } if (num_ack_blocks > 0) { @@ -2575,8 +2506,7 @@ first_received -= (gap + current_block_length); const bool last_range = i + 1 == num_ack_blocks; - if (use_incremental_ack_processing_ && - (current_block_length > 0 || last_range)) { + if (current_block_length > 0 || last_range) { if (!visitor_->OnAckRange(first_received, first_received + current_block_length, last_range)) { @@ -2588,10 +2518,6 @@ return false; } } - if (!use_incremental_ack_processing_ && current_block_length > 0) { - ack_frame->packets.AddRange(first_received, - first_received + current_block_length); - } } } @@ -2601,7 +2527,7 @@ return false; } - if (!ProcessTimestampsInAckFrame(num_received_packets, reader, ack_frame)) { + if (!ProcessTimestampsInAckFrame(num_received_packets, reader)) { return false; } @@ -2609,16 +2535,13 @@ } bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets, - QuicDataReader* reader, - QuicAckFrame* ack_frame) { + QuicDataReader* reader) { if (num_received_packets > 0) { uint8_t delta_from_largest_observed; if (!reader->ReadUInt8(&delta_from_largest_observed)) { set_detailed_error("Unable to read sequence delta in received packets."); return false; } - QuicPacketNumber seq_num = - LargestAcked(*ack_frame) - delta_from_largest_observed; // Time delta from the framer creation. uint32_t time_delta_us; @@ -2627,19 +2550,12 @@ return false; } - last_timestamp_ = CalculateTimestampFromWire(time_delta_us); - - ack_frame->received_packet_times.reserve(num_received_packets); - ack_frame->received_packet_times.emplace_back( - seq_num, creation_time_ + last_timestamp_); - for (uint8_t i = 1; i < num_received_packets; ++i) { if (!reader->ReadUInt8(&delta_from_largest_observed)) { set_detailed_error( "Unable to read sequence delta in received packets."); return false; } - seq_num = LargestAcked(*ack_frame) - delta_from_largest_observed; // Time delta from the previous timestamp. uint64_t incremental_time_delta_us; @@ -2648,11 +2564,6 @@ "Unable to read incremental time delta in received packets."); return false; } - - last_timestamp_ = last_timestamp_ + QuicTime::Delta::FromMicroseconds( - incremental_time_delta_us); - ack_frame->received_packet_times.emplace_back( - seq_num, creation_time_ + last_timestamp_); } } return true; @@ -2682,8 +2593,7 @@ QuicTime::Delta::FromMicroseconds(ack_delay_time_in_us); } - if (use_incremental_ack_processing_ && - !visitor_->OnAckFrameStart(largest_acked, ack_frame->ack_delay_time)) { + if (!visitor_->OnAckFrameStart(largest_acked, ack_frame->ack_delay_time)) { // The visitor suppresses further processing of the packet. Although this is // not a parsing error, returns false as this is in middle of processing an // ACK frame. @@ -2723,17 +2633,13 @@ return false; } - if (use_incremental_ack_processing_) { - if (!visitor_->OnAckRange(block_low, block_high, - /* last_range= */ (ack_block_count == 0))) { - // The visitor suppresses further processing of the packet. Although - // this is not a parsing error, returns false as this is in middle - // of processing an ACK frame. - set_detailed_error("Visitor suppresses further processing of ACK frame."); - return false; - } - } else { - ack_frame->packets.AddRange(block_low, block_high); + if (!visitor_->OnAckRange(block_low, block_high, + /* last_range= */ (ack_block_count == 0))) { + // The visitor suppresses further processing of the packet. Although + // this is not a parsing error, returns false as this is in middle + // of processing an ACK frame. + set_detailed_error("Visitor suppresses further processing of ACK frame."); + return false; } while (ack_block_count != 0) { @@ -2781,18 +2687,13 @@ // Calculate the low end of the new nth ack block. The +1 is // because the encoded value is the blocksize-1. block_low = block_high - 1 - ack_block_value; - if (use_incremental_ack_processing_) { - if (!visitor_->OnAckRange(block_low, block_high, - /*last_range=*/(ack_block_count == 1))) { - // The visitor suppresses further processing of the packet. Although - // this is not a parsing error, returns false as this is in middle - // of processing an ACK frame. - set_detailed_error( - "Visitor suppresses further processing of ACK frame."); - return false; - } - } else { - ack_frame->packets.AddRange(block_low, block_high); + if (!visitor_->OnAckRange(block_low, block_high, + /*last_range=*/(ack_block_count == 1))) { + // The visitor suppresses further processing of the packet. Although + // this is not a parsing error, returns false as this is in middle + // of processing an ACK frame. + set_detailed_error("Visitor suppresses further processing of ACK frame."); + return false; } // Another one done. @@ -2942,7 +2843,7 @@ void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame) { - if (version_.transport_version <= QUIC_VERSION_37) { + if (version_.transport_version == QUIC_VERSION_35) { frame->num_padding_bytes = reader->BytesRemaining() + 1; reader->ReadRemainingPayload(); return; @@ -3138,15 +3039,6 @@ return true; } -size_t QuicFramer::GetAckFrameTimeStampSize(const QuicAckFrame& ack) { - DCHECK(!use_incremental_ack_processing_); - if (ack.received_packet_times.empty()) { - return 0; - } - - return 5 + 3 * (ack.received_packet_times.size() - 1); -} - size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) { // Type byte, largest_acked, and delay_time are straight-forward. size_t ack_frame_size = kQuicFrameTypeSize; @@ -3248,11 +3140,6 @@ (ack_block_length + PACKET_1BYTE_PACKET_NUMBER); } - // Include timestamps. - if (!use_incremental_ack_processing_) { - ack_size += GetAckFrameTimeStampSize(ack); - } - return ack_size; } @@ -3857,93 +3744,13 @@ // Timestamps. // If we don't have enough available space to append all the timestamps, don't // append any of them. - if (!use_incremental_ack_processing_ && - writer->capacity() - writer->length() >= - GetAckFrameTimeStampSize(frame)) { - if (!AppendTimestampsToAckFrame(frame, num_timestamps_offset, writer)) { - return false; - } - } else { - if (transport_version() != QUIC_VERSION_41) { - uint8_t num_received_packets = 0; - if (!writer->WriteBytes(&num_received_packets, 1)) { - return false; - } - } - } - - return true; -} - -bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame, - size_t num_timestamps_offset, - QuicDataWriter* writer) { - DCHECK_GE(std::numeric_limits<uint8_t>::max(), - frame.received_packet_times.size()); - // num_received_packets is only 1 byte. - if (frame.received_packet_times.size() > - std::numeric_limits<uint8_t>::max()) { - return false; - } - - uint8_t num_received_packets = frame.received_packet_times.size(); - if (version_.transport_version != QUIC_VERSION_41) { + if (transport_version() != QUIC_VERSION_41) { + uint8_t num_received_packets = 0; if (!writer->WriteBytes(&num_received_packets, 1)) { return false; } - } else { - if (!writer->WriteUInt8AtOffset(num_received_packets, - num_timestamps_offset)) { - return false; - } - } - if (num_received_packets == 0) { - return true; } - PacketTimeVector::const_iterator it = frame.received_packet_times.begin(); - QuicPacketNumber packet_number = it->first; - QuicPacketNumber delta_from_largest_observed = - LargestAcked(frame) - packet_number; - - DCHECK_GE(std::numeric_limits<uint8_t>::max(), delta_from_largest_observed); - if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) { - return false; - } - - if (!writer->WriteUInt8(delta_from_largest_observed)) { - return false; - } - - // Use the lowest 4 bytes of the time delta from the creation_time_. - const uint64_t time_epoch_delta_us = UINT64_C(1) << 32; - uint32_t time_delta_us = - static_cast<uint32_t>((it->second - creation_time_).ToMicroseconds() & - (time_epoch_delta_us - 1)); - if (!writer->WriteUInt32(time_delta_us)) { - return false; - } - - QuicTime prev_time = it->second; - - for (++it; it != frame.received_packet_times.end(); ++it) { - packet_number = it->first; - delta_from_largest_observed = LargestAcked(frame) - packet_number; - - if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) { - return false; - } - - if (!writer->WriteUInt8(delta_from_largest_observed)) { - return false; - } - - uint64_t frame_time_delta_us = (it->second - prev_time).ToMicroseconds(); - prev_time = it->second; - if (!writer->WriteUFloat16(frame_time_delta_us)) { - return false; - } - } return true; } @@ -4217,7 +4024,7 @@ bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame, QuicDataWriter* writer) { - if (version_.transport_version <= QUIC_VERSION_37) { + if (version_.transport_version == QUIC_VERSION_35) { writer->WritePadding(); return true; } @@ -4256,8 +4063,8 @@ } Endianness QuicFramer::endianness() const { - return version_.transport_version > QUIC_VERSION_38 ? NETWORK_BYTE_ORDER - : HOST_BYTE_ORDER; + return version_.transport_version != QUIC_VERSION_35 ? NETWORK_BYTE_ORDER + : HOST_BYTE_ORDER; } bool QuicFramer::StartsWithChlo(QuicStreamId id,
diff --git a/net/third_party/quic/core/quic_framer.h b/net/third_party/quic/core/quic_framer.h index ebe80535..e3ac38f 100644 --- a/net/third_party/quic/core/quic_framer.h +++ b/net/third_party/quic/core/quic_framer.h
@@ -114,10 +114,6 @@ // Called when a StreamFrame has been parsed. virtual bool OnStreamFrame(const QuicStreamFrame& frame) = 0; - // Called when a AckFrame has been parsed. If OnAckFrame returns false, - // the framer will stop parsing the current packet. - virtual bool OnAckFrame(const QuicAckFrame& frame) = 0; - // Called when largest acked of an AckFrame has been parsed. virtual bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) = 0; @@ -234,10 +230,6 @@ QuicErrorCode error() const { return error_; } - bool use_incremental_ack_processing() const { - return use_incremental_ack_processing_; - } - // Pass a UDP packet into the framer for parsing. // Return true if the packet was processed succesfully. |packet| must be a // single, complete UDP packet (not a frame of a packet). This packet @@ -538,12 +530,9 @@ bool ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type, QuicStreamFrame* frame); - bool ProcessAckFrame(QuicDataReader* reader, - uint8_t frame_type, - QuicAckFrame* frame); + bool ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type); bool ProcessTimestampsInAckFrame(uint8_t num_received_packets, - QuicDataReader* reader, - QuicAckFrame* ack_frame); + QuicDataReader* reader); bool ProcessIetfAckFrame(QuicDataReader* reader, QuicAckFrame* ack_frame); bool ProcessStopWaitingFrame(QuicDataReader* reader, const QuicPacketHeader& header, @@ -571,13 +560,6 @@ QuicPacketNumber base_packet_number, QuicPacketNumber packet_number) const; - // Returns the QuicTime::Delta corresponding to the time from when the framer - // was created. - const QuicTime::Delta CalculateTimestampFromWire(uint32_t time_delta_us); - - // Computes the wire size in bytes of time stamps in |ack|. - size_t GetAckFrameTimeStampSize(const QuicAckFrame& ack); - // Computes the wire size in bytes of the |ack| frame. size_t GetAckFrameSize(const QuicAckFrame& ack, QuicPacketNumberLength packet_number_length); @@ -627,9 +609,6 @@ bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame, QuicDataWriter* builder); - bool AppendTimestampsToAckFrame(const QuicAckFrame& frame, - size_t num_timestamps_offset, - QuicDataWriter* writer); // Append IETF format ACK frame. // @@ -780,12 +759,6 @@ Perspective perspective_; // If false, skip validation that the public flags are set to legal values. bool validate_flags_; - // The time this framer was created. Time written to the wire will be - // written as a delta from this value. - QuicTime creation_time_; - // The time delta computed for the last timestamp frame. This is relative to - // the creation_time. - QuicTime::Delta last_timestamp_; // The diversification nonce from the last received packet. DiversificationNonce last_nonce_; @@ -793,9 +766,6 @@ // owned. TODO(fayang): Consider add data producer to framer's constructor. QuicStreamFrameDataProducer* data_producer_; - // Latched value of quic_reloadable_flag_quic_use_incremental_ack_processing4. - const bool use_incremental_ack_processing_; - // If the framer is processing a decrypted payload of a data packet, // |decrypted_payload_reader_| will be set to the reader of that payload, // otherwise nullptr.
diff --git a/net/third_party/quic/core/quic_framer_test.cc b/net/third_party/quic/core/quic_framer_test.cc index afa7955..b0e4a6d 100644 --- a/net/third_party/quic/core/quic_framer_test.cc +++ b/net/third_party/quic/core/quic_framer_test.cc
@@ -212,12 +212,6 @@ return true; } - bool OnAckFrame(const QuicAckFrame& frame) override { - ++frame_count_; - ack_frames_.push_back(QuicMakeUnique<QuicAckFrame>(frame)); - return true; - } - bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override { ++frame_count_; @@ -770,7 +764,7 @@ } PacketFragments& fragments = - framer_.transport_version() <= QUIC_VERSION_38 ? packet38 : packet39; + framer_.transport_version() == QUIC_VERSION_35 ? packet38 : packet39; std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); @@ -864,7 +858,7 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 ? packet + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); @@ -933,7 +927,7 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 ? packet + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); @@ -993,7 +987,7 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 ? packet + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); @@ -1052,7 +1046,7 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 ? packet + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); @@ -1242,7 +1236,7 @@ if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -1310,7 +1304,7 @@ QuicEncryptedPacket encrypted( AsChars(framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39)), framer_.transport_version() > QUIC_VERSION_43 ? QUIC_ARRAYSIZE(packet44) @@ -1354,7 +1348,7 @@ }; // clang-format on - if (framer_.transport_version() > QUIC_VERSION_37) { + if (framer_.transport_version() != QUIC_VERSION_35) { return; } @@ -1519,7 +1513,7 @@ }; // clang-format on - if (framer_.transport_version() <= QUIC_VERSION_37) { + if (framer_.transport_version() == QUIC_VERSION_35) { return; } unsigned char* p = packet; @@ -1532,7 +1526,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -1715,7 +1709,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -1849,7 +1843,7 @@ p = packet44; } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } QuicEncryptedPacket encrypted(AsChars(p), @@ -1966,7 +1960,8 @@ PacketFragments& fragments = framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); @@ -2148,7 +2143,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -2332,7 +2327,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -2537,7 +2532,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -2663,7 +2658,7 @@ p = packet44; } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } QuicEncryptedPacket encrypted(AsChars(p), @@ -2874,7 +2869,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -3048,7 +3043,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -3503,8 +3498,8 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 - : packet)); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet)); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); @@ -3518,11 +3513,7 @@ PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID)); EXPECT_EQ(0u, visitor_.stream_frames_.size()); - if (framer_.use_incremental_ack_processing()) { - ASSERT_EQ(1u, visitor_.ack_frames_.size()); - } else { - ASSERT_EQ(0u, visitor_.ack_frames_.size()); - } + ASSERT_EQ(1u, visitor_.ack_frames_.size()); CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA); } @@ -3676,7 +3667,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -4038,7 +4029,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); @@ -4125,7 +4116,8 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); @@ -4194,7 +4186,7 @@ QuicEncryptedPacket encrypted( AsChars(framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39)), framer_.transport_version() > QUIC_VERSION_43 ? QUIC_ARRAYSIZE(packet44) @@ -4339,7 +4331,7 @@ ? packet44 : (framer_.transport_version() == QUIC_VERSION_41 ? packet41 - : (framer_.transport_version() > QUIC_VERSION_38 + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 : packet))); std::unique_ptr<QuicEncryptedPacket> encrypted( @@ -4478,8 +4470,8 @@ ? packet99 : (framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 - : packet)); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet)); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); @@ -4661,7 +4653,8 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); @@ -4757,7 +4750,8 @@ PacketFragments& fragments = framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); @@ -4944,8 +4938,8 @@ ? packet99 : (framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 - : packet)); + : (framer_.transport_version() != QUIC_VERSION_35 ? packet39 + : packet)); std::unique_ptr<QuicEncryptedPacket> encrypted( AssemblePacketFromFragments(fragments)); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); @@ -5012,7 +5006,7 @@ QuicEncryptedPacket encrypted( AsChars(framer_.transport_version() > QUIC_VERSION_43 ? packet44 - : (framer_.transport_version() <= QUIC_VERSION_38 + : (framer_.transport_version() == QUIC_VERSION_35 ? packet : packet39)), framer_.transport_version() > QUIC_VERSION_43 ? QUIC_ARRAYSIZE(packet44) @@ -5444,7 +5438,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -5464,7 +5458,7 @@ } TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) { - if (framer_.transport_version() <= QUIC_VERSION_37) { + if (framer_.transport_version() == QUIC_VERSION_35) { return; } QuicPacketHeader header; @@ -5628,7 +5622,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -5691,7 +5685,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -5764,7 +5758,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -5973,7 +5967,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } test::CompareCharArraysWithHexError("constructed packet", data->data(), @@ -6115,7 +6109,7 @@ } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; p_size = QUIC_ARRAYSIZE(packet41); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } test::CompareCharArraysWithHexError("constructed packet", data->data(), @@ -6289,7 +6283,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -6427,7 +6421,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -6656,7 +6650,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -7154,7 +7148,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -7212,7 +7206,7 @@ // clang-format on unsigned char* p = packet; - if (framer_.transport_version() > QUIC_VERSION_38) { + if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -7221,8 +7215,8 @@ test::CompareCharArraysWithHexError( "constructed packet", data->data(), data->length(), AsChars(p), - framer_.transport_version() > QUIC_VERSION_38 ? QUIC_ARRAYSIZE(packet39) - : QUIC_ARRAYSIZE(packet)); + framer_.transport_version() != QUIC_VERSION_35 ? QUIC_ARRAYSIZE(packet39) + : QUIC_ARRAYSIZE(packet)); } TEST_P(QuicFramerTest, BuildRstFramePacketQuic) { @@ -7352,7 +7346,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -7473,7 +7467,7 @@ } else if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -7707,7 +7701,7 @@ } else if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -7938,7 +7932,7 @@ if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8127,7 +8121,7 @@ if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8232,7 +8226,7 @@ } else if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8410,7 +8404,7 @@ } else if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; p_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8468,7 +8462,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8542,7 +8536,7 @@ if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; packet_size = QUIC_ARRAYSIZE(packet44); - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; packet_size = QUIC_ARRAYSIZE(packet39); } @@ -8617,7 +8611,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8789,7 +8783,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -8865,7 +8859,7 @@ unsigned char* p = packet; if (framer_.transport_version() > QUIC_VERSION_43) { p = packet44; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } @@ -9202,7 +9196,6 @@ EXPECT_CALL(visitor, OnPacket()); EXPECT_CALL(visitor, OnPacketHeader(_)); EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false)); - EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); EXPECT_CALL(visitor, OnPacketComplete()); EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true)); EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)).WillOnce(Return(true)); @@ -9218,7 +9211,7 @@ p_size = QUIC_ARRAYSIZE(packet44); } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } QuicEncryptedPacket encrypted(AsChars(p), p_size, false); @@ -9266,7 +9259,6 @@ EXPECT_CALL(visitor, OnError(_)).Times(0); EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0); EXPECT_CALL(visitor, OnStreamFrame(Truly(ExpectedStreamFrame))).Times(1); - EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); EXPECT_CALL(visitor, OnPacketComplete()).Times(1); EXPECT_TRUE(framer_.ProcessPacket(*packet)); @@ -9302,7 +9294,6 @@ EXPECT_CALL(visitor, OnDecryptedPacket(_)).Times(1); EXPECT_CALL(visitor, OnError(_)).Times(1); EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0); - EXPECT_CALL(visitor, OnAckFrame(_)).Times(0); EXPECT_CALL(visitor, OnPacketComplete()).Times(0); EXPECT_FALSE(framer_.ProcessPacket(*packet)); @@ -9445,7 +9436,7 @@ p = packet44; } else if (framer_.transport_version() == QUIC_VERSION_41) { p = packet41; - } else if (framer_.transport_version() > QUIC_VERSION_38) { + } else if (framer_.transport_version() != QUIC_VERSION_35) { p = packet39; } QuicFramerFuzzFunc(p,
diff --git a/net/third_party/quic/core/quic_headers_stream_test.cc b/net/third_party/quic/core/quic_headers_stream_test.cc index a2ea32b..86744f0 100644 --- a/net/third_party/quic/core/quic_headers_stream_test.cc +++ b/net/third_party/quic/core/quic_headers_stream_test.cc
@@ -600,7 +600,6 @@ } TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) { - SetQuicReloadableFlag(quic_send_max_header_list_size, true); const uint32_t kTestHeaderTableSize = 1000; SpdySettingsIR data; // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE, @@ -616,7 +615,6 @@ } TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) { - SetQuicReloadableFlag(quic_send_max_header_list_size, true); SpdySettingsIR data; // Does not support SETTINGS_MAX_CONCURRENT_STREAMS, // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
diff --git a/net/third_party/quic/core/quic_ietf_framer_test.cc b/net/third_party/quic/core/quic_ietf_framer_test.cc index 329a754..5a15137 100644 --- a/net/third_party/quic/core/quic_ietf_framer_test.cc +++ b/net/third_party/quic/core/quic_ietf_framer_test.cc
@@ -106,8 +106,6 @@ bool OnStreamFrame(const QuicStreamFrame& frame) override { return true; } - bool OnAckFrame(const QuicAckFrame& frame) override { return true; } - bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override { return true; @@ -297,24 +295,6 @@ // framing and upshift on deframing results in clearing the 3 // low-order bits ... The masking basically does the same thing, // so the compare works properly. - if (!framer_.use_incremental_ack_processing()) { - // incremental ack processing does not set these in the - // QuicAckFrame so test them only if we are not doing - // incremental ack. - EXPECT_EQ(transmit_frame.ack_delay_time.ToMicroseconds() & ~0x7, - receive_frame.ack_delay_time.ToMicroseconds() & ~0x7); - EXPECT_EQ(transmit_frame.packets.NumIntervals(), - receive_frame.packets.NumIntervals()); - // now go through the two sets of intervals.... - auto xmit_itr = transmit_frame.packets.begin(); // first range - auto recv_itr = receive_frame.packets.begin(); // first range - while (xmit_itr != transmit_frame.packets.end()) { - EXPECT_EQ(xmit_itr->max(), recv_itr->max()); - EXPECT_EQ(xmit_itr->min(), recv_itr->min()); - xmit_itr++; - recv_itr++; - } - } return true; } @@ -727,16 +707,6 @@ // Now check that the received frame matches the sent frame. EXPECT_EQ(transmit_frame.largest_acked, receive_frame.largest_acked); - - if (!framer_.use_incremental_ack_processing()) { - // Transmit QuicAckFrame had no explicit ranges -- which means no - // intervals are in the frame. - EXPECT_EQ(0u, transmit_frame.packets.NumIntervals()); - // However, the actual serialization generates a FirstAckBlock and, - // therefore, when we deserialize, we should get a single interval - // in the Receive QuicAckFrame. - EXPECT_EQ(1u, receive_frame.packets.NumIntervals()); - } } TEST_F(QuicIetfFramerTest, PathChallengeFrame) {
diff --git a/net/third_party/quic/core/quic_packet_creator_test.cc b/net/third_party/quic/core/quic_packet_creator_test.cc index 9f0b91e..dc9959d 100644 --- a/net/third_party/quic/core/quic_packet_creator_test.cc +++ b/net/third_party/quic/core/quic_packet_creator_test.cc
@@ -281,26 +281,22 @@ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_)); EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_)); EXPECT_CALL(framer_visitor_, OnPacketHeader(_)); - if (client_framer_.use_incremental_ack_processing()) { - EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _)) + EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _)) + .WillOnce(Return(true)); + // This test includes an ack frame with largest_acked == 0 and + // the size of the first ack-block == 1 (serialized as + // 0). This is an invalid format for pre-version99, valid + // for version 99. + if (client_framer_.transport_version() != QUIC_VERSION_99) { + // pre-version 99; ensure that the error is gracefully + // handled. + EXPECT_CALL(framer_visitor_, OnAckRange(1, 1, true)) .WillOnce(Return(true)); - // This test includes an ack frame with largest_acked == 0 and - // the size of the first ack-block == 1 (serialized as - // 0). This is an invalid format for pre-version99, valid - // for version 99. - if (client_framer_.transport_version() != QUIC_VERSION_99) { - // pre-version 99; ensure that the error is gracefully - // handled. - EXPECT_CALL(framer_visitor_, OnAckRange(1, 1, true)) - .WillOnce(Return(true)); - } else { - // version 99; ensure that the correct packet is signalled - // properly. - EXPECT_CALL(framer_visitor_, OnAckRange(0, 1, true)) - .WillOnce(Return(true)); - } } else { - EXPECT_CALL(framer_visitor_, OnAckFrame(_)); + // version 99; ensure that the correct packet is signalled + // properly. + EXPECT_CALL(framer_visitor_, OnAckRange(0, 1, true)) + .WillOnce(Return(true)); } EXPECT_CALL(framer_visitor_, OnStreamFrame(_)); EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.cc b/net/third_party/quic/core/quic_sent_packet_manager.cc index f1f2fc5..8bc4104 100644 --- a/net/third_party/quic/core/quic_sent_packet_manager.cc +++ b/net/third_party/quic/core/quic_sent_packet_manager.cc
@@ -170,7 +170,7 @@ config.HasClientRequestedIndependentOption(kQBIC, perspective_))) { SetSendAlgorithm(kCubicBytes); - } else if (GetQuicReloadableFlag(quic_enable_pcc2) && + } else if (GetQuicReloadableFlag(quic_enable_pcc3) && config.HasClientRequestedIndependentOption(kTPCC, perspective_)) { SetSendAlgorithm(kPCC); } @@ -267,22 +267,6 @@ } } -bool QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, - QuicTime ack_receive_time) { - DCHECK_LE(LargestAcked(ack_frame), unacked_packets_.largest_sent_packet()); - QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight(); - bool rtt_updated = MaybeUpdateRTT(LargestAcked(ack_frame), - ack_frame.ack_delay_time, ack_receive_time); - DCHECK_GE(LargestAcked(ack_frame), unacked_packets_.largest_observed()); - unacked_packets_.IncreaseLargestObserved(LargestAcked(ack_frame)); - - HandleAckForSentPackets(ack_frame); - const bool acked_new_packet = !packets_acked_.empty(); - PostProcessAfterMarkingPacketHandled(ack_frame, ack_receive_time, rtt_updated, - prior_in_flight); - return acked_new_packet; -} - void QuicSentPacketManager::PostProcessAfterMarkingPacketHandled( const QuicAckFrame& ack_frame, QuicTime ack_receive_time, @@ -326,9 +310,12 @@ if (debug_delegate_ != nullptr) { debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, - unacked_packets_.largest_observed(), + unacked_packets_.largest_acked(), rtt_updated, GetLeastUnacked()); } + // Remove packets below least unacked from all_packets_acked_ and + // last_ack_frame_. + last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked()); } void QuicSentPacketManager::MaybeInvokeCongestionEvent( @@ -352,44 +339,6 @@ } } -void QuicSentPacketManager::HandleAckForSentPackets( - const QuicAckFrame& ack_frame) { - // Go through the packets we have not received an ack for and see if this - // incoming_ack shows they've been seen by the peer. - QuicTime::Delta ack_delay_time = ack_frame.ack_delay_time; - QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); - for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin(); - it != unacked_packets_.end(); ++it, ++packet_number) { - if (packet_number > LargestAcked(ack_frame)) { - // These packets are still in flight. - break; - } - if (!QuicUtils::IsAckable(it->state)) { - continue; - } - if (!ack_frame.packets.Contains(packet_number)) { - // Packet is still missing. - continue; - } - // Packet was acked, so remove it from our unacked packet list. - QUIC_DVLOG(1) << ENDPOINT << "Got an ack for packet " << packet_number; - if (it->largest_acked > 0) { - largest_packet_peer_knows_is_acked_ = - std::max(largest_packet_peer_knows_is_acked_, it->largest_acked); - } - // If data is associated with the most recent transmission of this - // packet, then inform the caller. - if (it->in_flight) { - packets_acked_.emplace_back(packet_number, it->bytes_sent, - QuicTime::Zero()); - } else { - // Unackable packets are skipped earlier. - largest_newly_acked_ = packet_number; - } - MarkPacketHandled(packet_number, &(*it), ack_delay_time); - } -} - void QuicSentPacketManager::RetransmitUnackedPackets( TransmissionType retransmission_type) { DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION || @@ -683,8 +632,6 @@ return; } case TLP_MODE: - // If no tail loss probe can be sent, because there are no retransmittable - // packets, execute a conventional RTO to abandon old packets. ++stats_->tlp_count; ++consecutive_tlp_count_; pending_timer_transmission_count_ = 1; @@ -729,6 +676,23 @@ } } +bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() { + if (pending_timer_transmission_count_ == 0) { + return false; + } + if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) { + // If no tail loss probe can be sent, because there are no retransmittable + // packets, execute a conventional RTO to abandon old packets. + if (GetQuicReloadableFlag(quic_optimize_inflight_check)) { + QUIC_FLAG_COUNT(quic_reloadable_flag_quic_optimize_inflight_check); + pending_timer_transmission_count_ = 0; + RetransmitRtoPackets(); + } + return false; + } + return true; +} + bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) { QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); @@ -806,7 +770,8 @@ return LOSS_MODE; } if (consecutive_tlp_count_ < max_tail_loss_probes_) { - if (unacked_packets_.HasUnackedRetransmittableFrames()) { + if (GetQuicReloadableFlag(quic_optimize_inflight_check) || + unacked_packets_.HasUnackedRetransmittableFrames()) { return TLP_MODE; } } @@ -855,7 +820,7 @@ unacked_packets_.GetTransmissionInfo(largest_acked); // Ensure the packet has a valid sent time. if (transmission_info.sent_time == QuicTime::Zero()) { - QUIC_BUG << "Acked packet has zero sent time, largest_observed:" + QUIC_BUG << "Acked packet has zero sent time, largest_acked:" << largest_acked; return false; } @@ -890,7 +855,8 @@ pending_timer_transmission_count_ > 0) { return QuicTime::Zero(); } - if (!unacked_packets_.HasUnackedRetransmittableFrames()) { + if (!GetQuicReloadableFlag(quic_optimize_inflight_check) && + !unacked_packets_.HasUnackedRetransmittableFrames()) { return QuicTime::Zero(); } switch (GetRetransmissionMode()) { @@ -1051,7 +1017,7 @@ DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet()); rtt_updated_ = MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time); - DCHECK_GE(largest_acked, unacked_packets_.largest_observed()); + DCHECK_GE(largest_acked, unacked_packets_.largest_acked()); last_ack_frame_.ack_delay_time = ack_delay_time; acked_packets_iter_ = last_ack_frame_.packets.rbegin(); } @@ -1060,7 +1026,7 @@ QuicPacketNumber end) { if (end > last_ack_frame_.largest_acked + 1) { // Largest acked increases. - unacked_packets_.IncreaseLargestObserved(end - 1); + unacked_packets_.IncreaseLargestAcked(end - 1); last_ack_frame_.largest_acked = end - 1; } // Drop ack ranges which ack packets below least_unacked. @@ -1137,11 +1103,6 @@ const bool acked_new_packet = !packets_acked_.empty(); PostProcessAfterMarkingPacketHandled(last_ack_frame_, ack_receive_time, rtt_updated_, prior_bytes_in_flight); - // TODO(fayang): Move this line to PostProcessAfterMarkingPacketHandled - // when deprecating quic_reloadable_flag_quic_use_incremental_ack_processing4. - // Remove packets below least unacked from all_packets_acked_ and - // last_ack_frame_. - last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked()); return acked_new_packet; }
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.h b/net/third_party/quic/core/quic_sent_packet_manager.h index 3aafc96..7037836 100644 --- a/net/third_party/quic/core/quic_sent_packet_manager.h +++ b/net/third_party/quic/core/quic_sent_packet_manager.h
@@ -123,10 +123,6 @@ void SetHandshakeConfirmed() { handshake_confirmed_ = true; } - // Processes the incoming ack. Returns true if a previously-unacked packet is - // acked. - bool OnIncomingAck(const QuicAckFrame& ack_frame, QuicTime ack_receive_time); - // Requests retransmission of all unacked packets of |retransmission_type|. // The behavior of this method depends on the value of |retransmission_type|: // ALL_UNACKED_RETRANSMISSION - All unacked packets will be retransmitted. @@ -143,12 +139,7 @@ // Retransmits the oldest pending packet there is still a tail loss probe // pending. Invoked after OnRetransmissionTimeout. - bool MaybeRetransmitTailLossProbe() { - if (pending_timer_transmission_count_ == 0) { - return false; - } - return MaybeRetransmitOldestPacket(TLP_RETRANSMISSION); - } + bool MaybeRetransmitTailLossProbe(); // Retransmits the oldest pending packet. bool MaybeRetransmitOldestPacket(TransmissionType type); @@ -289,7 +280,7 @@ } QuicPacketNumber GetLargestObserved() const { - return unacked_packets_.largest_observed(); + return unacked_packets_.largest_acked(); } QuicPacketNumber GetLargestSentPacket() const { @@ -341,6 +332,8 @@ QuicTime::Delta delayed_ack_time() const { return delayed_ack_time_; } void set_delayed_ack_time(QuicTime::Delta delayed_ack_time) { + // The delayed ack time should never be more than one half the min RTO time. + DCHECK_LE(delayed_ack_time, (min_rto_timeout_ * 0.5)); delayed_ack_time_ = delayed_ack_time; } @@ -369,9 +362,6 @@ typedef QuicLinkedHashMap<QuicPacketNumber, TransmissionType> PendingRetransmissionMap; - // Process the incoming ack looking for newly ack'd data packets. - void HandleAckForSentPackets(const QuicAckFrame& ack_frame); - // Returns the current retransmission mode. RetransmissionTimeoutMode GetRetransmissionMode() const; @@ -568,8 +558,7 @@ // Latest received ack frame. QuicAckFrame last_ack_frame_; - // Record whether RTT gets updated by last largest acked. This is only used - // when quic_reloadable_flag_quic_use_incremental_ack_processing4 is true. + // Record whether RTT gets updated by last largest acked.. bool rtt_updated_; // Latched value of quic_reloadable_flag_quic_extra_checks_in_ack_processing. @@ -577,8 +566,7 @@ QuicDebugInfoProviderInterface* debug_info_provider_; // A reverse iterator of last_ack_frame_.packets. This is reset in - // OnAckRangeStart, and gradually moves in OnAckRange. This is only used - // when quic_reloadable_flag_quic_use_incremental_ack_processing4 is true. + // OnAckRangeStart, and gradually moves in OnAckRange.. PacketNumberQueue::const_reverse_iterator acked_packets_iter_; DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager);
diff --git a/net/third_party/quic/core/quic_sent_packet_manager_test.cc b/net/third_party/quic/core/quic_sent_packet_manager_test.cc index 0214e9a..e4c7af3 100644 --- a/net/third_party/quic/core/quic_sent_packet_manager_test.cc +++ b/net/third_party/quic/core/quic_sent_packet_manager_test.cc
@@ -348,16 +348,10 @@ RetransmitAndSendPacket(1, 2); // Ack 2 but not 1. - QuicAckFrame ack_frame = InitAckFrame({{2, 3}}); - ExpectAck(2); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(2, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(2, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); if (manager_.session_decides_what_to_write()) { EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); } @@ -384,15 +378,10 @@ EXPECT_TRUE(manager_.HasPendingRetransmissions()); } // Ack 1. - QuicAckFrame ack_frame = InitAckFrame(1); ExpectAck(1); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); // There should no longer be a pending retransmission. EXPECT_FALSE(manager_.HasPendingRetransmissions()); @@ -443,14 +432,9 @@ // Ack 1 but not 2. ExpectAck(1); - QuicAckFrame ack_frame = InitAckFrame(1); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); if (manager_.session_decides_what_to_write()) { EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); } @@ -463,14 +447,9 @@ // Ack 2 causes 2 be considered as spurious retransmission. EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false)); ExpectAck(2); - QuicAckFrame ack_frame2 = InitAckFrame(2); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - manager_.OnIncomingAck(ack_frame2, clock_.ApproximateNow()); - } + manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); } EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted); @@ -484,14 +463,9 @@ // First, ACK packet 1 which makes packet 2 non-retransmittable. ExpectAck(1); - QuicAckFrame ack_frame = InitAckFrame(1); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); SendDataPacket(3); SendDataPacket(4); @@ -499,43 +473,27 @@ clock_.AdvanceTime(rtt); // Next, NACK packet 2 three times. - ack_frame = InitAckFrame({{1, 2}, {3, 4}}); - ExpectAck(3); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 4); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 4); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - ack_frame = InitAckFrame({{1, 2}, {3, 5}}); ExpectAck(4); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 5); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 5); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - ack_frame = InitAckFrame({{1, 2}, {3, 6}}); ExpectAckAndLoss(true, 5, 2); if (manager_.session_decides_what_to_write()) { // Frames in all packets are acked. EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 6); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 6); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); // No packets remain unacked. VerifyUnackedPackets(nullptr, 0); @@ -561,16 +519,11 @@ // Ack 1 but not 2, before 2 is able to be sent. // Since 1 has been retransmitted, it has already been lost, and so the // send algorithm is not informed that it has been ACK'd. - QuicAckFrame ack_frame = InitAckFrame(1); ExpectUpdatedRtt(1); EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout()); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT. QuicPacketNumber unacked[] = {2}; @@ -604,14 +557,9 @@ // Ack 1 but not 2 or 3. ExpectAck(1); - QuicAckFrame ack_frame = InitAckFrame(1); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); if (manager_.session_decides_what_to_write()) { // Frames in packets 2 and 3 are acked. EXPECT_CALL(notifier_, IsFrameOutstanding(_)) @@ -633,38 +581,28 @@ .WillOnce(Return(false)) .WillRepeatedly(Return(true)); } - ack_frame = InitAckFrame({{1, 2}, {3, 5}}); QuicPacketNumber acked[] = {3, 4}; ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 5); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 5); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); QuicPacketNumber unacked2[] = {2}; VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2)); EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); SendDataPacket(5); - ack_frame = InitAckFrame({{1, 2}, {3, 6}}); ExpectAckAndLoss(true, 5, 2); EXPECT_CALL(debug_delegate, OnPacketLoss(2, LOSS_RETRANSMISSION, _)); if (manager_.session_decides_what_to_write()) { // Frames in all packetss are acked. EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 6); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 6); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); VerifyUnackedPackets(nullptr, 0); EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); @@ -687,53 +625,36 @@ // Ack original transmission, but that wasn't lost via fast retransmit, // so no call on OnSpuriousRetransmission is expected. { - QuicAckFrame ack_frame = InitAckFrame(1); ExpectAck(1); EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); } SendDataPacket(3); SendDataPacket(4); // Ack 4, which causes 3 to be retransmitted. { - QuicAckFrame ack_frame = InitAckFrame({{1, 2}, {4, 5}}); ExpectAck(4); EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(4, 5); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(4, 5); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION); } // Ack 3, which causes SpuriousRetransmitDetected to be called. { - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - QuicPacketNumber acked[] = {3}; - ExpectAcksAndLosses(false, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - } - QuicAckFrame ack_frame = InitAckFrame({{1, 2}, {3, 5}}); + QuicPacketNumber acked[] = {3}; + ExpectAcksAndLosses(false, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)); EXPECT_CALL(*loss_algorithm, SpuriousRetransmitDetected(_, _, _, 5)); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 5); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 5); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); if (manager_.session_decides_what_to_write()) { // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack // 5 will cause 5 be considered as a spurious retransmission as no new @@ -741,15 +662,10 @@ ExpectAck(5); EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)); EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false)); - QuicAckFrame ack_frame2 = InitAckFrame({{1, 2}, {3, 6}}); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 6); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - manager_.OnIncomingAck(ack_frame2, clock_.Now()); - } + manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 6); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); } } } @@ -769,42 +685,22 @@ SendAckPacket(2, 1); // Now ack the ack and expect an RTT update. - QuicAckFrame ack_frame = InitAckFrame(2); - ack_frame.ack_delay_time = QuicTime::Delta::FromMilliseconds(5); - - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - QuicPacketNumber acked[] = {1, 2}; - ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - } else { - ExpectAck(1); - } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::FromMilliseconds(5), - clock_.Now()); - manager_.OnAckRange(1, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + QuicPacketNumber acked[] = {1, 2}; + ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); + manager_.OnAckFrameStart(2, QuicTime::Delta::FromMilliseconds(5), + clock_.Now()); + manager_.OnAckRange(1, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_EQ(1u, manager_.largest_packet_peer_knows_is_acked()); SendAckPacket(3, 3); // Now ack the ack and expect only an RTT update. - ack_frame = InitAckFrame(3); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - QuicPacketNumber acked[] = {3}; - ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - } else { - ExpectUpdatedRtt(3); - } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 4); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + QuicPacketNumber acked2[] = {3}; + ExpectAcksAndLosses(true, acked2, QUIC_ARRAYSIZE(acked2), nullptr, 0); + manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 4); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_EQ(3u, manager_.largest_packet_peer_knows_is_acked()); } @@ -815,14 +711,9 @@ clock_.AdvanceTime(expected_rtt); ExpectAck(packet_number); - QuicAckFrame ack_frame = InitAckFrame(packet_number); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt()); } @@ -836,16 +727,10 @@ clock_.AdvanceTime(expected_rtt); ExpectAck(packet_number); - QuicAckFrame ack_frame = InitAckFrame(packet_number); - ack_frame.ack_delay_time = QuicTime::Delta::FromMilliseconds(11); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::FromMilliseconds(11), - clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::FromMilliseconds(11), + clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt()); } @@ -858,15 +743,9 @@ clock_.AdvanceTime(expected_rtt); ExpectAck(packet_number); - QuicAckFrame ack_frame = InitAckFrame(packet_number); - ack_frame.ack_delay_time = QuicTime::Delta::Infinite(); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt()); } @@ -879,15 +758,9 @@ clock_.AdvanceTime(expected_rtt); ExpectAck(packet_number); - QuicAckFrame ack_frame = InitAckFrame(packet_number); - ack_frame.ack_delay_time = QuicTime::Delta::Zero(); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Zero(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Zero(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt()); } @@ -935,21 +808,15 @@ // Ack the third and ensure the first two are still pending. ExpectAck(3); - QuicAckFrame ack_frame = InitAckFrame({{3, 4}}); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 4); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 4); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); // Acking two more packets will lose both of them due to nacks. SendDataPacket(4); SendDataPacket(5); - ack_frame = InitAckFrame({{3, 6}}); QuicPacketNumber acked[] = {4, 5}; QuicPacketNumber lost[] = {1, 2}; ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), lost, @@ -958,13 +825,9 @@ // Frames in all packets are acked. EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 6); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 6); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_FALSE(manager_.HasPendingRetransmissions()); EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); @@ -1055,7 +918,6 @@ EXPECT_TRUE(manager_.HasPendingRetransmissions()); RetransmitNextPacket(103); } - QuicAckFrame ack_frame = InitAckFrame({{103, 104}}); QuicPacketNumber largest_acked = 103; EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); EXPECT_CALL(*send_algorithm_, @@ -1072,13 +934,9 @@ // Packets 1, 2 and [4, 102] are lost. EXPECT_CALL(notifier_, OnFrameLost(_)).Times(101); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(103, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(103, 104); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(103, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(103, 104); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); // All packets before 103 should be lost. if (manager_.session_decides_what_to_write()) { // Packet 104 is still in flight. @@ -1136,19 +994,14 @@ // and ensure the first four crypto packets get abandoned, but not lost. QuicPacketNumber acked[] = {3, 4, 5, 8, 9}; ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - QuicAckFrame ack_frame = InitAckFrame({{3, 6}, {8, 10}}); if (manager_.session_decides_what_to_write()) { EXPECT_CALL(notifier_, HasPendingCryptoData()) .WillRepeatedly(Return(false)); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(8, 10); - manager_.OnAckRange(3, 6); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(8, 10); + manager_.OnAckRange(3, 6); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_)); } @@ -1214,14 +1067,9 @@ // crypto packets. QuicPacketNumber acked[] = {8, 9}; ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - QuicAckFrame ack_frame = InitAckFrame({{8, 10}}); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(8, 10); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(8, 10); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); if (manager_.session_decides_what_to_write()) { EXPECT_CALL(notifier_, HasPendingCryptoData()) .WillRepeatedly(Return(false)); @@ -1256,25 +1104,16 @@ // Now ack the second crypto packet, and ensure the first gets removed, but // the third does not. - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - QuicPacketNumber acked[] = {2}; - ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - } else { - ExpectUpdatedRtt(2); - } - QuicAckFrame ack_frame = InitAckFrame({{2, 3}}); + QuicPacketNumber acked[] = {2}; + ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); if (manager_.session_decides_what_to_write()) { EXPECT_CALL(notifier_, HasPendingCryptoData()) .WillRepeatedly(Return(false)); EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false)); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(2, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(2, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_)); QuicPacketNumber unacked[] = {3}; @@ -1389,20 +1228,11 @@ EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_)); // Ensure both packets get discarded when packet 2 is acked. - QuicAckFrame ack_frame = InitAckFrame({{3, 4}}); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - QuicPacketNumber acked[] = {3}; - ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); - } else { - ExpectUpdatedRtt(3); - } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(3, 4); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + QuicPacketNumber acked[] = {3}; + ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); + manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(3, 4); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); VerifyUnackedPackets(nullptr, 0); VerifyRetransmittablePackets(nullptr, 0); } @@ -1443,8 +1273,6 @@ } // Ack a retransmission. - QuicAckFrame ack_frame = InitAckFrame({{102, 103}}); - ack_frame.ack_delay_time = QuicTime::Delta::Zero(); // Ensure no packets are lost. QuicPacketNumber largest_acked = 102; EXPECT_CALL(*send_algorithm_, @@ -1470,13 +1298,9 @@ // retransmittable frames as packet 102 is acked. EXPECT_CALL(notifier_, OnFrameLost(_)).Times(98); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now()); - manager_.OnAckRange(102, 103); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now()); + manager_.OnAckRange(102, 103); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); } TEST_P(QuicSentPacketManagerTest, RetransmissionTimeoutOnePacket) { @@ -1573,8 +1397,6 @@ } // Ack a retransmission and expect no call to OnRetransmissionTimeout. - QuicAckFrame ack_frame = InitAckFrame({{102, 103}}); - ack_frame.ack_delay_time = QuicTime::Delta::Zero(); // This will include packets in the lost packet map. QuicPacketNumber largest_acked = 102; EXPECT_CALL(*send_algorithm_, @@ -1594,13 +1416,9 @@ // retransmittable frames as packet 102 is acked. EXPECT_CALL(notifier_, OnFrameLost(_)).Times(98); } - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now()); - manager_.OnAckRange(102, 103); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now()); + manager_.OnAckRange(102, 103); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); } TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) { @@ -1644,16 +1462,10 @@ // Ack a retransmission and ensure OnRetransmissionTimeout is called. EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - QuicAckFrame ack_frame = InitAckFrame({{2, 3}}); - ack_frame.ack_delay_time = QuicTime::Delta::Zero(); ExpectAck(2); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::Zero(), clock_.Now()); - manager_.OnAckRange(2, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(2, QuicTime::Delta::Zero(), clock_.Now()); + manager_.OnAckRange(2, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); // The original packet and newest should be outstanding. EXPECT_EQ(2 * kDefaultLength, @@ -1701,16 +1513,10 @@ // Ack a retransmission and ensure OnRetransmissionTimeout is called. EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true)); - QuicAckFrame ack_frame = InitAckFrame({{3, 4}}); - ack_frame.ack_delay_time = QuicTime::Delta::Zero(); ExpectAck(3); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(3, QuicTime::Delta::Zero(), clock_.Now()); - manager_.OnAckRange(3, 4); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(3, QuicTime::Delta::Zero(), clock_.Now()); + manager_.OnAckRange(3, 4); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); // The first two packets should still be outstanding. EXPECT_EQ(2 * kDefaultLength, @@ -1890,15 +1696,10 @@ // Ack a packet before the first RTO and ensure the RTO timeout returns to the // original value and OnRetransmissionTimeout is not called or reverted. - QuicAckFrame ack_frame = InitAckFrame({{2, 3}}); ExpectAck(2); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(2, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow())); - } + manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(2, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); EXPECT_FALSE(manager_.HasPendingRetransmissions()); EXPECT_EQ(5 * kDefaultLength, QuicSentPacketManagerPeer::GetBytesInFlight(&manager_)); @@ -2030,14 +1831,9 @@ // set the loss timeout. ExpectAck(2); EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)); - QuicAckFrame ack_frame = InitAckFrame({{2, 3}}); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(2, 3); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(2, 3); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)); EXPECT_CALL(*loss_algorithm, GetLossTimeout()) @@ -2558,17 +2354,12 @@ EXPECT_CALL(*network_change_visitor_, OnPathMtuIncreased(kDefaultLength + 100)); QuicAckFrame ack_frame = InitAckFrame(1); - if (GetQuicReloadableFlag(quic_use_incremental_ack_processing4)) { - manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); - manager_.OnAckRange(1, 2); - EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); - } else { - EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now())); - } + manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now()); + manager_.OnAckRange(1, 2); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); } TEST_P(QuicSentPacketManagerTest, OnAckRangeSlowPath) { - SetQuicReloadableFlag(quic_use_incremental_ack_processing4, true); // Send packets 1 - 20. for (size_t i = 1; i <= 20; ++i) { SendDataPacket(i);
diff --git a/net/third_party/quic/core/quic_spdy_client_session.cc b/net/third_party/quic/core/quic_spdy_client_session.cc index fae3e83..e06c9c8 100644 --- a/net/third_party/quic/core/quic_spdy_client_session.cc +++ b/net/third_party/quic/core/quic_spdy_client_session.cc
@@ -8,6 +8,7 @@ #include "net/quic/chromium/crypto/proof_verifier_chromium.h" #include "net/third_party/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quic/core/quic_server_id.h" +#include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quic/platform/api/quic_logging.h"
diff --git a/net/third_party/quic/core/quic_spdy_client_session_base.cc b/net/third_party/quic/core/quic_spdy_client_session_base.cc index 3145fc0..c1d959f 100644 --- a/net/third_party/quic/core/quic_spdy_client_session_base.cc +++ b/net/third_party/quic/core/quic_spdy_client_session_base.cc
@@ -10,6 +10,8 @@ #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_string.h" +using spdy::SpdyHeaderBlock; + namespace quic { QuicSpdyClientSessionBase::QuicSpdyClientSessionBase( @@ -40,7 +42,7 @@ void QuicSpdyClientSessionBase::OnInitialHeadersComplete( QuicStreamId stream_id, - const spdy::SpdyHeaderBlock& response_headers) { + const SpdyHeaderBlock& response_headers) { // Note that the strong ordering of the headers stream means that // QuicSpdyClientStream::OnPromiseHeadersComplete must have already // been called (on the associated stream) if this is a promised @@ -77,10 +79,9 @@ stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list); } -bool QuicSpdyClientSessionBase::HandlePromised( - QuicStreamId /* associated_id */, - QuicStreamId promised_id, - const spdy::SpdyHeaderBlock& headers) { +bool QuicSpdyClientSessionBase::HandlePromised(QuicStreamId /* associated_id */, + QuicStreamId promised_id, + const SpdyHeaderBlock& headers) { // Due to pathalogical packet re-ordering, it is possible that // frames for the promised stream have already arrived, and the // promised stream could be active or closed.
diff --git a/net/third_party/quic/core/quic_spdy_client_session_test.cc b/net/third_party/quic/core/quic_spdy_client_session_test.cc index 5b00f180..142fe2af 100644 --- a/net/third_party/quic/core/quic_spdy_client_session_test.cc +++ b/net/third_party/quic/core/quic_spdy_client_session_test.cc
@@ -4,13 +4,14 @@ #include "net/third_party/quic/core/quic_spdy_client_session.h" +#include <memory> #include <vector> #include "net/third_party/quic/core/crypto/aes_128_gcm_12_encrypter.h" #include "net/third_party/quic/core/quic_spdy_client_stream.h" #include "net/third_party/quic/core/spdy_utils.h" #include "net/third_party/quic/core/tls_client_handshaker.h" -#include "net/third_party/quic/platform/api/quic_flags.h" +#include "net/third_party/quic/platform/api/quic_arraysize.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/platform/api/quic_socket_address.h" #include "net/third_party/quic/platform/api/quic_str_cat.h" @@ -25,7 +26,7 @@ #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" -using google::protobuf::implicit_cast; +using spdy::SpdyHeaderBlock; using testing::_; using testing::AnyNumber; using testing::Invoke; @@ -125,7 +126,7 @@ PacketSavingConnection* connection_; std::unique_ptr<TestQuicSpdyClientSession> session_; QuicClientPushPromiseIndex push_promise_index_; - spdy::SpdyHeaderBlock push_promise_; + SpdyHeaderBlock push_promise_; QuicString promise_url_; QuicStreamId promised_stream_id_; QuicStreamId associated_stream_id_; @@ -178,8 +179,8 @@ EXPECT_TRUE(session_->CreateOutgoingDynamicStream() == nullptr); // Verify that no data may be send on existing streams. char data[] = "hello world"; - QuicConsumedData consumed = - session_->WritevData(stream, stream->id(), arraysize(data), 0, NO_FIN); + QuicConsumedData consumed = session_->WritevData( + stream, stream->id(), QUIC_ARRAYSIZE(data), 0, NO_FIN); EXPECT_FALSE(consumed.fin_consumed); EXPECT_EQ(0u, consumed.bytes_consumed); } @@ -462,7 +463,7 @@ OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM)); session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM); - spdy::SpdyHeaderBlock promise_headers; + SpdyHeaderBlock promise_headers; EXPECT_FALSE(session_->HandlePromised(associated_stream_id_, promised_stream_id_, promise_headers)); @@ -559,16 +560,14 @@ EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr); EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr); - session_->OnInitialHeadersComplete(promised_stream_id_, - spdy::SpdyHeaderBlock()); + session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock()); } TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) { // Initialize crypto before the client session will create a stream. CompleteCryptoHandshake(); session_->CreateOutgoingDynamicStream(); - session_->OnInitialHeadersComplete(promised_stream_id_, - spdy::SpdyHeaderBlock()); + session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock()); } TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
diff --git a/net/third_party/quic/core/quic_spdy_client_stream.cc b/net/third_party/quic/core/quic_spdy_client_stream.cc index 88517ba2..c03f47d 100644 --- a/net/third_party/quic/core/quic_spdy_client_stream.cc +++ b/net/third_party/quic/core/quic_spdy_client_stream.cc
@@ -13,7 +13,7 @@ #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/spdy/core/spdy_protocol.h" -using std::string; +using spdy::SpdyHeaderBlock; namespace quic { @@ -80,7 +80,7 @@ const QuicHeaderList& header_list) { header_bytes_read_ += frame_len; int64_t content_length = -1; - spdy::SpdyHeaderBlock promise_headers; + SpdyHeaderBlock promise_headers; if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length, &promise_headers)) { QUIC_DLOG(ERROR) << "Failed to parse promise headers: " @@ -127,7 +127,7 @@ } } -size_t QuicSpdyClientStream::SendRequest(spdy::SpdyHeaderBlock headers, +size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers, QuicStringPiece body, bool fin) { QuicConnection::ScopedPacketFlusher flusher(
diff --git a/net/third_party/quic/core/quic_spdy_client_stream.h b/net/third_party/quic/core/quic_spdy_client_stream.h index 9710404..5fe0e36 100644 --- a/net/third_party/quic/core/quic_spdy_client_stream.h +++ b/net/third_party/quic/core/quic_spdy_client_stream.h
@@ -5,8 +5,7 @@ #ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_STREAM_H_ #define NET_THIRD_PARTY_QUIC_CORE_QUIC_SPDY_CLIENT_STREAM_H_ -#include <stddef.h> -#include <sys/types.h> +#include <cstddef> #include "base/macros.h" #include "net/third_party/quic/core/quic_packets.h"
diff --git a/net/third_party/quic/core/quic_spdy_client_stream_test.cc b/net/third_party/quic/core/quic_spdy_client_stream_test.cc index 391efe64..33c713b 100644 --- a/net/third_party/quic/core/quic_spdy_client_stream_test.cc +++ b/net/third_party/quic/core/quic_spdy_client_stream_test.cc
@@ -21,7 +21,7 @@ #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" -using base::IntToString; +using spdy::SpdyHeaderBlock; using testing::_; using testing::StrictMock; @@ -88,7 +88,7 @@ MockQuicSpdyClientSession session_; std::unique_ptr<QuicSpdyClientStream> stream_; std::unique_ptr<StreamVisitor> stream_visitor_; - spdy::SpdyHeaderBlock headers_; + SpdyHeaderBlock headers_; QuicString body_; }; @@ -162,6 +162,7 @@ TEST_F(QuicSpdyClientStreamTest, ReceivingTrailers) { // Test that receiving trailing headers, containing a final offset, results in // the stream being closed at that byte offset. + // Send headers as usual. auto headers = AsHeaderList(headers_); stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), @@ -170,7 +171,7 @@ // Send trailers before sending the body. Even though a FIN has been received // the stream should not be closed, as it does not yet have all the data bytes // promised by the final offset field. - spdy::SpdyHeaderBlock trailer_block; + SpdyHeaderBlock trailer_block; trailer_block["trailer key"] = "trailer value"; trailer_block[kFinalOffsetHeaderKey] = QuicTextUtils::Uint64ToString(body_.size());
diff --git a/net/third_party/quic/core/quic_spdy_session.cc b/net/third_party/quic/core/quic_spdy_session.cc index 87f6ff5..9127014 100644 --- a/net/third_party/quic/core/quic_spdy_session.cc +++ b/net/third_party/quic/core/quic_spdy_session.cc
@@ -20,23 +20,48 @@ #include "net/third_party/quic/platform/api/quic_text_utils.h" #include "net/third_party/spdy/core/http2_frame_decoder_adapter.h" +using http2::Http2DecoderAdapter; +using spdy::HpackEntry; +using spdy::HpackHeaderTable; +using spdy::Http2WeightToSpdy3Priority; +using spdy::SETTINGS_ENABLE_PUSH; +using spdy::SETTINGS_HEADER_TABLE_SIZE; +using spdy::SETTINGS_MAX_HEADER_LIST_SIZE; +using spdy::Spdy3PriorityToHttp2Weight; +using spdy::SpdyErrorCode; +using spdy::SpdyFramer; +using spdy::SpdyFramerDebugVisitorInterface; +using spdy::SpdyFramerVisitorInterface; +using spdy::SpdyFrameType; +using spdy::SpdyHeaderBlock; +using spdy::SpdyHeadersHandlerInterface; +using spdy::SpdyHeadersIR; +using spdy::SpdyKnownSettingsId; +using spdy::SpdyPingId; +using spdy::SpdyPriority; +using spdy::SpdyPriorityIR; +using spdy::SpdyPushPromiseIR; +using spdy::SpdySerializedFrame; +using spdy::SpdySettingsId; +using spdy::SpdySettingsIR; +using spdy::SpdyStreamId; + namespace quic { namespace { -class HeaderTableDebugVisitor - : public spdy::HpackHeaderTable::DebugVisitorInterface { +class HeaderTableDebugVisitor : public HpackHeaderTable::DebugVisitorInterface { public: HeaderTableDebugVisitor(const QuicClock* clock, std::unique_ptr<QuicHpackDebugVisitor> visitor) : clock_(clock), headers_stream_hpack_visitor_(std::move(visitor)) {} - int64_t OnNewEntry(const spdy::HpackEntry& entry) override { + int64_t OnNewEntry(const HpackEntry& entry) override { QUIC_DVLOG(1) << entry.GetDebugString(); return (clock_->ApproximateNow() - QuicTime::Zero()).ToMicroseconds(); } - void OnUseEntry(const spdy::HpackEntry& entry) override { + void OnUseEntry(const HpackEntry& entry) override { const QuicTime::Delta elapsed( clock_->ApproximateNow() - QuicTime::Delta::FromMicroseconds(entry.time_added()) - @@ -58,44 +83,44 @@ // A SpdyFramerVisitor that passes HEADERS frames to the QuicSpdyStream, and // closes the connection if any unexpected frames are received. class QuicSpdySession::SpdyFramerVisitor - : public spdy::SpdyFramerVisitorInterface, - public spdy::SpdyFramerDebugVisitorInterface { + : public SpdyFramerVisitorInterface, + public SpdyFramerDebugVisitorInterface { public: explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {} - spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart( - spdy::SpdyStreamId /* stream_id */) override { + SpdyHeadersHandlerInterface* OnHeaderFrameStart( + SpdyStreamId /* stream_id */) override { return &header_list_; } - void OnHeaderFrameEnd(spdy::SpdyStreamId /* stream_id */) override { + void OnHeaderFrameEnd(SpdyStreamId /* stream_id */) override { if (session_->IsConnected()) { session_->OnHeaderList(header_list_); } header_list_.Clear(); } - void OnStreamFrameData(spdy::SpdyStreamId stream_id, + void OnStreamFrameData(SpdyStreamId stream_id, const char* data, size_t len) override { CloseConnection("SPDY DATA frame received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnStreamEnd(spdy::SpdyStreamId stream_id) override { + void OnStreamEnd(SpdyStreamId stream_id) override { // The framer invokes OnStreamEnd after processing a frame that had the fin // bit set. } - void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override { + void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { CloseConnection("SPDY frame padding received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnError(http2::Http2DecoderAdapter::SpdyFramerError error) override { + void OnError(Http2DecoderAdapter::SpdyFramerError error) override { QuicErrorCode code = QUIC_INVALID_HEADERS_STREAM_DATA; switch (error) { - case http2::Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE: + case Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE: code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE; break; default: @@ -103,35 +128,33 @@ } CloseConnection( QuicStrCat("SPDY framing error: ", - http2::Http2DecoderAdapter::SpdyFramerErrorToString(error)), + Http2DecoderAdapter::SpdyFramerErrorToString(error)), code); } - void OnDataFrameHeader(spdy::SpdyStreamId stream_id, + void OnDataFrameHeader(SpdyStreamId stream_id, size_t length, bool fin) override { CloseConnection("SPDY DATA frame received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnRstStream(spdy::SpdyStreamId stream_id, - spdy::SpdyErrorCode error_code) override { + void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override { CloseConnection("SPDY RST_STREAM frame received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnSetting(spdy::SpdySettingsId id, uint32_t value) override { + void OnSetting(SpdySettingsId id, uint32_t value) override { switch (id) { - case spdy::SETTINGS_HEADER_TABLE_SIZE: + case SETTINGS_HEADER_TABLE_SIZE: session_->UpdateHeaderEncoderTableSize(value); break; - case spdy::SETTINGS_ENABLE_PUSH: + case SETTINGS_ENABLE_PUSH: if (session_->perspective() == Perspective::IS_SERVER) { // See rfc7540, Section 6.5.2. if (value > 1) { CloseConnection( - QuicStrCat("Invalid value for spdy::SETTINGS_ENABLE_PUSH: ", - value), + QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value), QUIC_INVALID_HEADERS_STREAM_DATA); return; } @@ -143,13 +166,10 @@ QUIC_INVALID_HEADERS_STREAM_DATA); } break; - // TODO(fayang): Need to support spdy::SETTINGS_MAX_HEADER_LIST_SIZE when + // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when // clients are actually sending it. - case spdy::SETTINGS_MAX_HEADER_LIST_SIZE: - if (GetQuicReloadableFlag(quic_send_max_header_list_size)) { - break; - } - QUIC_FALLTHROUGH_INTENDED; + case SETTINGS_MAX_HEADER_LIST_SIZE: + break; default: CloseConnection( QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id), @@ -159,21 +179,21 @@ void OnSettingsEnd() override {} - void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override { + void OnPing(SpdyPingId unique_id, bool is_ack) override { CloseConnection("SPDY PING frame received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id, - spdy::SpdyErrorCode error_code) override { + void OnGoAway(SpdyStreamId last_accepted_stream_id, + SpdyErrorCode error_code) override { CloseConnection("SPDY GOAWAY frame received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnHeaders(spdy::SpdyStreamId stream_id, + void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight, - spdy::SpdyStreamId /*parent_stream_id*/, + SpdyStreamId /*parent_stream_id*/, bool /*exclusive*/, bool fin, bool end) override { @@ -181,21 +201,20 @@ return; } - // TODO(mpw): avoid down-conversion and plumb spdy::SpdyStreamPrecedence - // through QuicHeadersStream. - spdy::SpdyPriority priority = - has_priority ? spdy::Http2WeightToSpdy3Priority(weight) : 0; + // TODO(mpw): avoid down-conversion and plumb SpdyStreamPrecedence through + // QuicHeadersStream. + SpdyPriority priority = + has_priority ? Http2WeightToSpdy3Priority(weight) : 0; session_->OnHeaders(stream_id, has_priority, priority, fin); } - void OnWindowUpdate(spdy::SpdyStreamId stream_id, - int delta_window_size) override { + void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override { CloseConnection("SPDY WINDOW_UPDATE frame received.", QUIC_INVALID_HEADERS_STREAM_DATA); } - void OnPushPromise(spdy::SpdyStreamId stream_id, - spdy::SpdyStreamId promised_stream_id, + void OnPushPromise(SpdyStreamId stream_id, + SpdyStreamId promised_stream_id, bool end) override { if (!session_->supports_push_promise()) { CloseConnection("PUSH_PROMISE not supported.", @@ -208,10 +227,10 @@ session_->OnPushPromise(stream_id, promised_stream_id, end); } - void OnContinuation(spdy::SpdyStreamId stream_id, bool end) override {} + void OnContinuation(SpdyStreamId stream_id, bool end) override {} - void OnPriority(spdy::SpdyStreamId stream_id, - spdy::SpdyStreamId parent_id, + void OnPriority(SpdyStreamId stream_id, + SpdyStreamId parent_id, int weight, bool exclusive) override { if (session_->connection()->transport_version() <= QUIC_VERSION_42) { @@ -223,21 +242,20 @@ return; } // TODO (wangyix): implement real HTTP/2 weights and dependencies instead of - // converting to spdy::SpdyPriority. - spdy::SpdyPriority priority = spdy::Http2WeightToSpdy3Priority(weight); + // converting to SpdyPriority. + SpdyPriority priority = Http2WeightToSpdy3Priority(weight); session_->OnPriority(stream_id, priority); } - bool OnUnknownFrame(spdy::SpdyStreamId stream_id, - uint8_t frame_type) override { + bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override { CloseConnection("Unknown frame type received.", QUIC_INVALID_HEADERS_STREAM_DATA); return false; } - // spdy::SpdyFramerDebugVisitorInterface implementation - void OnSendCompressedFrame(spdy::SpdyStreamId stream_id, - spdy::SpdyFrameType type, + // SpdyFramerDebugVisitorInterface implementation + void OnSendCompressedFrame(SpdyStreamId stream_id, + SpdyFrameType type, size_t payload_len, size_t frame_len) override { if (payload_len == 0) { @@ -248,8 +266,8 @@ QUIC_DVLOG(1) << "Net.QuicHpackCompressionPercentage: " << compression_pct; } - void OnReceiveCompressedFrame(spdy::SpdyStreamId stream_id, - spdy::SpdyFrameType type, + void OnReceiveCompressedFrame(SpdyStreamId stream_id, + SpdyFrameType type, size_t frame_len) override { if (session_->IsConnected()) { session_->OnCompressedFrameSize(frame_len); @@ -291,7 +309,7 @@ frame_len_(0), uncompressed_frame_len_(0), supports_push_promise_(perspective() == Perspective::IS_CLIENT), - spdy_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION), + spdy_framer_(SpdyFramer::ENABLE_COMPRESSION), spdy_framer_visitor_(new SpdyFramerVisitor(this)) { h2_deframer_.set_visitor(spdy_framer_visitor_.get()); h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get()); @@ -333,7 +351,7 @@ } void QuicSpdySession::OnStreamHeadersPriority(QuicStreamId stream_id, - spdy::SpdyPriority priority) { + SpdyPriority priority) { QuicSpdyStream* stream = GetSpdyDataStream(stream_id); if (!stream) { // It's quite possible to receive headers after a stream has been reset. @@ -375,7 +393,7 @@ } void QuicSpdySession::OnPriorityFrame(QuicStreamId stream_id, - spdy::SpdyPriority priority) { + SpdyPriority priority) { QuicSpdyStream* stream = GetSpdyDataStream(stream_id); if (!stream) { // It's quite possible to receive a PRIORITY frame after a stream has been @@ -392,24 +410,24 @@ size_t QuicSpdySession::WriteHeaders( QuicStreamId id, - spdy::SpdyHeaderBlock headers, + SpdyHeaderBlock headers, bool fin, - spdy::SpdyPriority priority, + SpdyPriority priority, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { return WriteHeadersImpl( - id, std::move(headers), fin, spdy::Spdy3PriorityToHttp2Weight(priority), + id, std::move(headers), fin, Spdy3PriorityToHttp2Weight(priority), /*parent_stream_id=*/0, /*exclusive=*/false, std::move(ack_listener)); } size_t QuicSpdySession::WriteHeadersImpl( QuicStreamId id, - spdy::SpdyHeaderBlock headers, + SpdyHeaderBlock headers, bool fin, int weight, QuicStreamId parent_stream_id, bool exclusive, QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { - spdy::SpdyHeadersIR headers_frame(id, std::move(headers)); + SpdyHeadersIR headers_frame(id, std::move(headers)); headers_frame.set_fin(fin); if (perspective() == Perspective::IS_CLIENT) { headers_frame.set_has_priority(true); @@ -417,7 +435,7 @@ headers_frame.set_parent_stream_id(parent_stream_id); headers_frame.set_exclusive(exclusive); } - spdy::SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); + SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); headers_stream_->WriteOrBufferData( QuicStringPiece(frame.data(), frame.size()), false, std::move(ack_listener)); @@ -431,9 +449,8 @@ if (connection()->transport_version() <= QUIC_VERSION_42) { return 0; } - spdy::SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive); - - spdy::SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame)); + SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive); + SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame)); headers_stream_->WriteOrBufferData( QuicStringPiece(frame.data(), frame.size()), false, nullptr); return frame.size(); @@ -441,29 +458,29 @@ size_t QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id, QuicStreamId promised_stream_id, - spdy::SpdyHeaderBlock headers) { + SpdyHeaderBlock headers) { if (perspective() == Perspective::IS_CLIENT) { QUIC_BUG << "Client shouldn't send PUSH_PROMISE"; return 0; } - spdy::SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id, - std::move(headers)); + SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id, + std::move(headers)); // PUSH_PROMISE must not be the last frame sent out, at least followed by // response headers. push_promise.set_fin(false); - spdy::SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); + SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); headers_stream_->WriteOrBufferData( QuicStringPiece(frame.data(), frame.size()), false, nullptr); return frame.size(); } size_t QuicSpdySession::SendMaxHeaderListSize(size_t value) { - spdy::SpdySettingsIR settings_frame; - settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, value); + SpdySettingsIR settings_frame; + settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, value); - spdy::SpdySerializedFrame frame(spdy_framer_.SerializeFrame(settings_frame)); + SpdySerializedFrame frame(spdy_framer_.SerializeFrame(settings_frame)); headers_stream_->WriteOrBufferData( QuicStringPiece(frame.data(), frame.size()), false, nullptr); return frame.size(); @@ -476,8 +493,7 @@ void QuicSpdySession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { QuicSession::OnCryptoHandshakeEvent(event); - if (GetQuicReloadableFlag(quic_send_max_header_list_size) && - event == HANDSHAKE_CONFIRMED && config()->SupportMaxHeaderListSize()) { + if (event == HANDSHAKE_CONFIRMED && config()->SupportMaxHeaderListSize()) { SendMaxHeaderListSize(max_inbound_header_list_size_); } } @@ -497,9 +513,9 @@ return false; } -void QuicSpdySession::OnHeaders(spdy::SpdyStreamId stream_id, +void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, bool has_priority, - spdy::SpdyPriority priority, + SpdyPriority priority, bool fin) { if (has_priority) { if (perspective() == Perspective::IS_CLIENT) { @@ -521,8 +537,8 @@ fin_ = fin; } -void QuicSpdySession::OnPushPromise(spdy::SpdyStreamId stream_id, - spdy::SpdyStreamId promised_stream_id, +void QuicSpdySession::OnPushPromise(SpdyStreamId stream_id, + SpdyStreamId promised_stream_id, bool end) { DCHECK_EQ(kInvalidStreamId, stream_id_); DCHECK_EQ(kInvalidStreamId, promised_stream_id_); @@ -530,10 +546,10 @@ promised_stream_id_ = promised_stream_id; } -// TODO (wangyix): Why is spdy::SpdyStreamId used instead of QuicStreamId? +// TODO (wangyix): Why is SpdyStreamId used instead of QuicStreamId? // This occurs in many places in this file. -void QuicSpdySession::OnPriority(spdy::SpdyStreamId stream_id, - spdy::SpdyPriority priority) { +void QuicSpdySession::OnPriority(SpdyStreamId stream_id, + SpdyPriority priority) { if (perspective() == Perspective::IS_CLIENT) { CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, "Server must not send PRIORITY frames."); @@ -563,7 +579,6 @@ frame_len_ += frame_len; } - void QuicSpdySession::SetHpackEncoderDebugVisitor( std::unique_ptr<QuicHpackDebugVisitor> visitor) { spdy_framer_.SetEncoderHeaderTableDebugVisitor(
diff --git a/net/third_party/quic/core/quic_spdy_session.h b/net/third_party/quic/core/quic_spdy_session.h index ec29258..74ed443 100644 --- a/net/third_party/quic/core/quic_spdy_session.h +++ b/net/third_party/quic/core/quic_spdy_session.h
@@ -111,7 +111,7 @@ QuicStreamId promised_stream_id, spdy::SpdyHeaderBlock headers); - // Sends spdy::SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame. + // Sends SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame. size_t SendMaxHeaderListSize(size_t value); QuicHeadersStream* headers_stream() { return headers_stream_.get(); } @@ -119,7 +119,7 @@ bool server_push_enabled() const { return server_push_enabled_; } // Called by |QuicHeadersStream::UpdateEnableServerPush()| with - // value from spdy::SETTINGS_ENABLE_PUSH. + // value from SETTINGS_ENABLE_PUSH. void set_server_push_enabled(bool enable) { server_push_enabled_ = enable; } // Return true if this session wants to release headers stream's buffer @@ -139,6 +139,7 @@ // QuicSpdyStreams. QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override = 0; QuicSpdyStream* CreateOutgoingDynamicStream() override = 0; + QuicSpdyStream* GetSpdyDataStream(const QuicStreamId stream_id); // If an incoming stream can be created, return true. @@ -173,7 +174,7 @@ // willing to use to encode header blocks. void UpdateHeaderEncoderTableSize(uint32_t value); - // Called when spdy::SETTINGS_ENABLE_PUSH is received, only supported on + // Called when SETTINGS_ENABLE_PUSH is received, only supported on // server side. void UpdateEnableServerPush(bool value);
diff --git a/net/third_party/quic/core/quic_spdy_session_test.cc b/net/third_party/quic/core/quic_spdy_session_test.cc index 6396669c3..8696d8f 100644 --- a/net/third_party/quic/core/quic_spdy_session_test.cc +++ b/net/third_party/quic/core/quic_spdy_session_test.cc
@@ -8,10 +8,6 @@ #include <set> #include <utility> -#include "base/callback.h" -#include "base/rand_util.h" -#include "build/build_config.h" -#include "net/test/gtest_util.h" #include "net/third_party/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quic/core/crypto/null_encrypter.h" #include "net/third_party/quic/core/quic_crypto_stream.h" @@ -36,8 +32,14 @@ #include "net/third_party/quic/test_tools/quic_stream_send_buffer_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" #include "net/third_party/spdy/core/spdy_framer.h" -#include "testing/gmock_mutant.h" +using spdy::kV3HighestPriority; +using spdy::Spdy3PriorityToHttp2Weight; +using spdy::SpdyFramer; +using spdy::SpdyHeaderBlock; +using spdy::SpdyPriority; +using spdy::SpdyPriorityIR; +using spdy::SpdySerializedFrame; using testing::_; using testing::AtLeast; using testing::InSequence; @@ -327,7 +329,7 @@ StrictMock<MockQuicConnection>* connection_; TestSession session_; std::set<QuicStreamId> closed_streams_; - spdy::SpdyHeaderBlock headers_; + SpdyHeaderBlock headers_; }; class QuicSpdySessionTestServer : public QuicSpdySessionTestBase { @@ -522,7 +524,7 @@ // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high // priority stream 6. 4 should be preempted. 6 will write but *not* block so // will cede back to 4. - stream6->SetPriority(spdy::kV3HighestPriority); + stream6->SetPriority(kV3HighestPriority); EXPECT_CALL(*stream4, OnCanWrite()) .WillOnce(Invoke([this, stream4, stream6]() { session_.SendLargeFakeData(stream4, 6000); @@ -554,10 +556,8 @@ CryptoHandshakeMessage msg; MockPacketWriter* writer = static_cast<MockPacketWriter*>( QuicConnectionPeer::GetWriter(session_.connection())); - if (GetQuicReloadableFlag(quic_send_max_header_list_size)) { - EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); - } + EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)) + .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); // Drive congestion control manually. @@ -1014,12 +1014,13 @@ // Write until the header stream is flow control blocked. EXPECT_CALL(*connection_, SendControlFrame(_)) .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame)); - spdy::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; + SimpleRandom random; while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); - headers["header"] = QuicStrCat("", base::RandUint64(), base::RandUint64(), - base::RandUint64()); + headers["header"] = QuicStrCat("", random.RandUint64(), random.RandUint64(), + random.RandUint64()); session_.WriteHeaders(stream_id, headers.Clone(), true, 0, nullptr); stream_id += 2; } @@ -1407,22 +1408,20 @@ const QuicStreamId id = 4; const QuicStreamId parent_stream_id = 9; - const spdy::SpdyPriority priority = spdy::kV3HighestPriority; + const SpdyPriority priority = kV3HighestPriority; const bool exclusive = true; session_.WritePriority(id, parent_stream_id, - spdy::Spdy3PriorityToHttp2Weight(priority), exclusive); + Spdy3PriorityToHttp2Weight(priority), exclusive); QuicStreamSendBuffer& send_buffer = QuicStreamPeer::SendBuffer(headers_stream); if (transport_version() > QUIC_VERSION_42) { ASSERT_EQ(1u, send_buffer.size()); - spdy::SpdyPriorityIR priority_frame( - id, parent_stream_id, spdy::Spdy3PriorityToHttp2Weight(priority), - exclusive); - spdy::SpdyFramer spdy_framer(spdy::SpdyFramer::ENABLE_COMPRESSION); - spdy::SpdySerializedFrame frame = - spdy_framer.SerializeFrame(priority_frame); + SpdyPriorityIR priority_frame( + id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive); + SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION); + SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame); const QuicMemSlice& slice = QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice; @@ -1589,8 +1588,8 @@ TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) { QuicStreamId stream_id = GetNthClientInitiatedId(0); TestStream* stream = session_.CreateIncomingDynamicStream(stream_id); - session_.OnPriorityFrame(stream_id, spdy::kV3HighestPriority); - EXPECT_EQ(spdy::kV3HighestPriority, stream->priority()); + session_.OnPriorityFrame(stream_id, kV3HighestPriority); + EXPECT_EQ(kV3HighestPriority, stream->priority()); } } // namespace
diff --git a/net/third_party/quic/core/quic_time_wait_list_manager.cc b/net/third_party/quic/core/quic_time_wait_list_manager.cc index 2963f9e7..c751a2e 100644 --- a/net/third_party/quic/core/quic_time_wait_list_manager.cc +++ b/net/third_party/quic/core/quic_time_wait_list_manager.cc
@@ -75,13 +75,13 @@ QuicTimeWaitListManager::QuicTimeWaitListManager( QuicPacketWriter* writer, Visitor* visitor, - QuicConnectionHelperInterface* helper, + const QuicClock* clock, QuicAlarmFactory* alarm_factory) : time_wait_period_( QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)), connection_id_clean_up_alarm_( alarm_factory->CreateAlarm(new ConnectionIdCleanUpAlarm(this))), - clock_(helper->GetClock()), + clock_(clock), writer_(writer), visitor_(visitor) { SetConnectionIdCleanUpAlarm();
diff --git a/net/third_party/quic/core/quic_time_wait_list_manager.h b/net/third_party/quic/core/quic_time_wait_list_manager.h index 0d84c82..bae6a2c 100644 --- a/net/third_party/quic/core/quic_time_wait_list_manager.h +++ b/net/third_party/quic/core/quic_time_wait_list_manager.h
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "net/third_party/quic/core/quic_blocked_writer_interface.h" -#include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_framer.h" #include "net/third_party/quic/core/quic_packet_writer.h" #include "net/third_party/quic/core/quic_packets.h" @@ -59,13 +58,13 @@ QuicConnectionId connection_id) = 0; }; - // writer - the entity that writes to the socket. (Owned by the dispatcher) - // visitor - the entity that manages blocked writers. (The dispatcher) - // helper - provides a clock (Owned by the dispatcher) - // alarm_factory - used to run clean up alarms. (Owned by the dispatcher) + // writer - the entity that writes to the socket. (Owned by the caller) + // visitor - the entity that manages blocked writers. (Owned by the caller) + // clock - provide a clock (Owned by the caller) + // alarm_factory - used to run clean up alarms. (Owned by the caller) QuicTimeWaitListManager(QuicPacketWriter* writer, Visitor* visitor, - QuicConnectionHelperInterface* helper, + const QuicClock* clock, QuicAlarmFactory* alarm_factory); ~QuicTimeWaitListManager() override;
diff --git a/net/third_party/quic/core/quic_time_wait_list_manager_test.cc b/net/third_party/quic/core/quic_time_wait_list_manager_test.cc index fe4314d3..4901405 100644 --- a/net/third_party/quic/core/quic_time_wait_list_manager_test.cc +++ b/net/third_party/quic/core/quic_time_wait_list_manager_test.cc
@@ -13,15 +13,12 @@ #include "net/third_party/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quic/core/quic_data_reader.h" -#include "net/third_party/quic/core/quic_epoll_alarm_factory.h" -#include "net/third_party/quic/core/quic_epoll_connection_helper.h" #include "net/third_party/quic/core/quic_framer.h" #include "net/third_party/quic/core/quic_packet_writer.h" #include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_test.h" -#include "net/third_party/quic/test_tools/mock_epoll_server.h" #include "net/third_party/quic/test_tools/mock_quic_session_visitor.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" #include "net/third_party/quic/test_tools/quic_time_wait_list_manager_peer.h" @@ -74,19 +71,65 @@ QuicConnectionId connection_id_; }; -class MockFakeTimeEpollServer : public FakeTimeEpollServer { +class MockAlarmFactory; +class MockAlarm : public QuicAlarm { public: - MOCK_METHOD2(RegisterAlarm, - void(int64_t timeout_in_us, - net::EpollAlarmCallbackInterface* alarm)); + explicit MockAlarm(QuicArenaScopedPtr<Delegate> delegate, + int alarm_index, + MockAlarmFactory* factory) + : QuicAlarm(std::move(delegate)), + alarm_index_(alarm_index), + factory_(factory) {} + virtual ~MockAlarm() {} + + void SetImpl() override; + void CancelImpl() override; + + private: + int alarm_index_; + MockAlarmFactory* factory_; }; +class MockAlarmFactory : public QuicAlarmFactory { + public: + ~MockAlarmFactory() override {} + + // Creates a new platform-specific alarm which will be configured to notify + // |delegate| when the alarm fires. Returns an alarm allocated on the heap. + // Caller takes ownership of the new alarm, which will not yet be "set" to + // fire. + QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override { + return new MockAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate), + alarm_index_++, this); + } + QuicArenaScopedPtr<QuicAlarm> CreateAlarm( + QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, + QuicConnectionArena* arena) override { + if (arena != nullptr) { + return arena->New<MockAlarm>(std::move(delegate), alarm_index_++, this); + } + return QuicArenaScopedPtr<MockAlarm>( + new MockAlarm(std::move(delegate), alarm_index_++, this)); + } + MOCK_METHOD2(OnAlarmSet, void(int, QuicTime)); + MOCK_METHOD1(OnAlarmCancelled, void(int)); + + private: + int alarm_index_ = 0; +}; + +void MockAlarm::SetImpl() { + factory_->OnAlarmSet(alarm_index_, deadline()); +} + +void MockAlarm::CancelImpl() { + factory_->OnAlarmCancelled(alarm_index_); +} + class QuicTimeWaitListManagerTest : public QuicTest { protected: QuicTimeWaitListManagerTest() - : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL), - alarm_factory_(&epoll_server_), - time_wait_list_manager_(&writer_, &visitor_, &helper_, &alarm_factory_), + : time_wait_list_manager_(&writer_, &visitor_, &clock_, &alarm_factory_), connection_id_(45), client_address_(TestPeerIPAddress(), kTestPort), writer_is_blocked_(false) {} @@ -142,9 +185,8 @@ false, packet_number, "data"); } - NiceMock<MockFakeTimeEpollServer> epoll_server_; - QuicEpollConnectionHelper helper_; - QuicEpollAlarmFactory alarm_factory_; + MockClock clock_; + MockAlarmFactory alarm_factory_; StrictMock<MockPacketWriter> writer_; StrictMock<MockQuicSessionVisitor> visitor_; QuicTimeWaitListManager time_wait_list_manager_; @@ -304,7 +346,6 @@ const size_t kOldConnectionIdCount = 31; // Add connection_ids such that their expiry time is time_wait_period_. - epoll_server_.set_now_in_usec(0); for (size_t connection_id = 1; connection_id <= kOldConnectionIdCount; ++connection_id) { EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id)); @@ -316,7 +357,7 @@ // 2 * time_wait_period_. const QuicTime::Delta time_wait_period = QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_); - epoll_server_.set_now_in_usec(time_wait_period.ToMicroseconds()); + clock_.AdvanceTime(time_wait_period); for (size_t connection_id = kOldConnectionIdCount + 1; connection_id <= kConnectionIdCount; ++connection_id) { EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id)); @@ -326,12 +367,11 @@ QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39); // Now set the current time as time_wait_period + offset usecs. - epoll_server_.set_now_in_usec((time_wait_period + offset).ToMicroseconds()); + clock_.AdvanceTime(offset); // After all the old connection_ids are cleaned up, check the next alarm // interval. - int64_t next_alarm_time = epoll_server_.ApproximateNowInUsec() + - (time_wait_period - offset).ToMicroseconds(); - EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _)); + QuicTime next_alarm_time = clock_.Now() + time_wait_period - offset; + EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time)); time_wait_list_manager_.CleanUpOldConnectionIds(); for (size_t connection_id = 1; connection_id <= kConnectionIdCount; @@ -399,7 +439,6 @@ TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) { // Add connection_ids such that their expiry time is time_wait_period_. - epoll_server_.set_now_in_usec(0); EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING); EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_)); @@ -424,13 +463,11 @@ QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_); QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39); + clock_.AdvanceTime(offset + time_wait_period); // Now set the current time as time_wait_period + offset usecs. - epoll_server_.set_now_in_usec((time_wait_period + offset).ToMicroseconds()); - // After the connection_ids are cleaned up, check the next alarm interval. - int64_t next_alarm_time = - epoll_server_.ApproximateNowInUsec() + time_wait_period.ToMicroseconds(); + QuicTime next_alarm_time = clock_.Now() + time_wait_period; + EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time)); - EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _)); time_wait_list_manager_.CleanUpOldConnectionIds(); EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_)); EXPECT_EQ(0u, time_wait_list_manager_.num_connections()); @@ -445,19 +482,18 @@ // 1 will hash lower than 2, but we add it later. They should come out in the // add order, not hash order. - epoll_server_.set_now_in_usec(0); EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1)); AddConnectionId(connection_id1, QuicTimeWaitListManager::DO_NOTHING); - epoll_server_.set_now_in_usec(10); + clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(10)); EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2)); AddConnectionId(connection_id2, QuicTimeWaitListManager::DO_NOTHING); EXPECT_EQ(2u, time_wait_list_manager_.num_connections()); const QuicTime::Delta time_wait_period = QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_); - epoll_server_.set_now_in_usec(time_wait_period.ToMicroseconds() + 1); + clock_.AdvanceTime(time_wait_period - QuicTime::Delta::FromMicroseconds(9)); - EXPECT_CALL(epoll_server_, RegisterAlarm(_, _)); + EXPECT_CALL(alarm_factory_, OnAlarmSet(_, _)); time_wait_list_manager_.CleanUpOldConnectionIds(); EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
diff --git a/net/third_party/quic/core/quic_trace_visitor.h b/net/third_party/quic/core/quic_trace_visitor.h index 876776d9..279c8d9f 100644 --- a/net/third_party/quic/core/quic_trace_visitor.h +++ b/net/third_party/quic/core/quic_trace_visitor.h
@@ -5,9 +5,9 @@ #ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_TRACE_VISITOR_H_ #define NET_THIRD_PARTY_QUIC_CORE_QUIC_TRACE_VISITOR_H_ -#include "net/third_party/quic/core/proto/quic_trace.pb.h" #include "net/third_party/quic/core/quic_connection.h" #include "net/third_party/quic/core/quic_types.h" +#include "third_party/quic_trace/lib/quic_trace.pb.h" namespace quic {
diff --git a/net/third_party/quic/core/quic_unacked_packet_map.cc b/net/third_party/quic/core/quic_unacked_packet_map.cc index 4e034c90..a707bcf7 100644 --- a/net/third_party/quic/core/quic_unacked_packet_map.cc +++ b/net/third_party/quic/core/quic_unacked_packet_map.cc
@@ -13,7 +13,8 @@ QuicUnackedPacketMap::QuicUnackedPacketMap() : largest_sent_packet_(0), largest_sent_retransmittable_packet_(0), - largest_observed_(0), + largest_sent_largest_acked_(0), + largest_acked_(0), least_unacked_(1), bytes_in_flight_(0), pending_crypto_packet_count_(0), @@ -47,6 +48,8 @@ packet->encryption_level, packet->packet_number_length, transmission_type, sent_time, bytes_sent, has_crypto_handshake, packet->num_padding_bytes); info.largest_acked = packet->largest_acked; + largest_sent_largest_acked_ = + std::max(largest_sent_largest_acked_, packet->largest_acked); if (old_packet_number > 0) { TransferRetransmissionInfo(old_packet_number, packet_number, transmission_type, &info); @@ -193,10 +196,10 @@ RemoveRetransmittability(info); } -void QuicUnackedPacketMap::IncreaseLargestObserved( - QuicPacketNumber largest_observed) { - DCHECK_LE(largest_observed_, largest_observed); - largest_observed_ = largest_observed; +void QuicUnackedPacketMap::IncreaseLargestAcked( + QuicPacketNumber largest_acked) { + DCHECK_LE(largest_acked_, largest_acked); + largest_acked_ = largest_acked; } bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt( @@ -204,7 +207,7 @@ const QuicTransmissionInfo& info) const { // Packet can be used for RTT measurement if it may yet be acked as the // largest observed packet by the receiver. - return QuicUtils::IsAckable(info.state) && packet_number > largest_observed_; + return QuicUtils::IsAckable(info.state) && packet_number > largest_acked_; } bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl( @@ -219,7 +222,7 @@ // retransmitted with a new packet number. return HasRetransmittableFrames(info) || // Allow for an extra 1 RTT before stopping to track old packets. - info.retransmission > largest_observed_; + info.retransmission > largest_acked_; } bool QuicUnackedPacketMap::IsPacketUseless( @@ -345,6 +348,7 @@ } bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { + DCHECK(!GetQuicReloadableFlag(quic_optimize_inflight_check)); for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { if (it->in_flight && HasRetransmittableFrames(*it)) {
diff --git a/net/third_party/quic/core/quic_unacked_packet_map.h b/net/third_party/quic/core/quic_unacked_packet_map.h index ce8bec5..4587ccc 100644 --- a/net/third_party/quic/core/quic_unacked_packet_map.h +++ b/net/third_party/quic/core/quic_unacked_packet_map.h
@@ -99,8 +99,12 @@ return largest_sent_retransmittable_packet_; } + QuicPacketNumber largest_sent_largest_acked() const { + return largest_sent_largest_acked_; + } + // Returns the largest packet number that has been acked. - QuicPacketNumber largest_observed() const { return largest_observed_; } + QuicPacketNumber largest_acked() const { return largest_acked_; } // Returns the sum of bytes from all packets in flight. QuicByteCount bytes_in_flight() const { return bytes_in_flight_; } @@ -160,9 +164,9 @@ // RemoveRetransmittability. void RemoveRetransmittability(QuicPacketNumber packet_number); - // Increases the largest observed. Any packets less or equal to - // |largest_acked_packet| are discarded if they are only for the RTT purposes. - void IncreaseLargestObserved(QuicPacketNumber largest_observed); + // Increases the largest acked. Any packets less or equal to + // |largest_acked| are discarded if they are only for the RTT purposes. + void IncreaseLargestAcked(QuicPacketNumber largest_acked); // Remove any packets no longer needed for retransmission, congestion, or // RTT measurement purposes. @@ -207,7 +211,10 @@ QuicPacketNumber largest_sent_packet_; // The largest sent packet we expect to receive an ack for. QuicPacketNumber largest_sent_retransmittable_packet_; - QuicPacketNumber largest_observed_; + // The largest sent largest_acked in an ACK frame. + QuicPacketNumber largest_sent_largest_acked_; + // The largest received largest_acked from an ACK frame. + QuicPacketNumber largest_acked_; // Newly serialized retransmittable packets are added to this map, which // contains owning pointers to any contained frames. If a packet is
diff --git a/net/third_party/quic/core/quic_unacked_packet_map_test.cc b/net/third_party/quic/core/quic_unacked_packet_map_test.cc index 76961a0..296d313 100644 --- a/net/third_party/quic/core/quic_unacked_packet_map_test.cc +++ b/net/third_party/quic/core/quic_unacked_packet_map_test.cc
@@ -87,7 +87,9 @@ unacked_packets_.RemoveObsoletePackets(); if (num_packets == 0) { EXPECT_FALSE(unacked_packets_.HasUnackedPackets()); - EXPECT_FALSE(unacked_packets_.HasUnackedRetransmittableFrames()); + if (!GetQuicReloadableFlag(quic_optimize_inflight_check)) { + EXPECT_FALSE(unacked_packets_.HasUnackedRetransmittableFrames()); + } return; } EXPECT_TRUE(unacked_packets_.HasUnackedPackets()); @@ -163,7 +165,7 @@ VerifyInFlightPackets(nullptr, 0); VerifyRetransmittablePackets(nullptr, 0); - unacked_packets_.IncreaseLargestObserved(1); + unacked_packets_.IncreaseLargestAcked(1); VerifyUnackedPackets(nullptr, 0); VerifyInFlightPackets(nullptr, 0); VerifyRetransmittablePackets(nullptr, 0); @@ -184,7 +186,7 @@ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); - unacked_packets_.IncreaseLargestObserved(1); + unacked_packets_.IncreaseLargestAcked(1); VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked)); VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); @@ -290,7 +292,7 @@ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); - unacked_packets_.IncreaseLargestObserved(2); + unacked_packets_.IncreaseLargestAcked(2); VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked)); VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked)); VerifyRetransmittablePackets(nullptr, 0); @@ -322,7 +324,7 @@ QUIC_ARRAYSIZE(retransmittable)); // Early retransmit 1 as 3 and send new data as 4. - unacked_packets_.IncreaseLargestObserved(2); + unacked_packets_.IncreaseLargestAcked(2); unacked_packets_.RemoveFromInFlight(2); unacked_packets_.RemoveRetransmittability(2); unacked_packets_.RemoveFromInFlight(1); @@ -343,7 +345,7 @@ VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size()); // Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked. - unacked_packets_.IncreaseLargestObserved(4); + unacked_packets_.IncreaseLargestAcked(4); unacked_packets_.RemoveFromInFlight(4); unacked_packets_.RemoveRetransmittability(4); RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION); @@ -365,7 +367,7 @@ VerifyInFlightPackets(pending3, QUIC_ARRAYSIZE(pending3)); // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed. - unacked_packets_.IncreaseLargestObserved(6); + unacked_packets_.IncreaseLargestAcked(6); unacked_packets_.RemoveFromInFlight(6); unacked_packets_.RemoveRetransmittability(6); RetransmitAndSendPacket(5, 7, LOSS_RETRANSMISSION); @@ -406,7 +408,7 @@ QUIC_ARRAYSIZE(retransmittable)); // Early retransmit 1 as 3. - unacked_packets_.IncreaseLargestObserved(2); + unacked_packets_.IncreaseLargestAcked(2); unacked_packets_.RemoveFromInFlight(2); unacked_packets_.RemoveRetransmittability(2); unacked_packets_.RemoveFromInFlight(1); @@ -442,7 +444,7 @@ VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size()); // Early retransmit 4 as 6 and ensure in flight packet 3 is removed. - unacked_packets_.IncreaseLargestObserved(5); + unacked_packets_.IncreaseLargestAcked(5); unacked_packets_.RemoveFromInFlight(5); unacked_packets_.RemoveRetransmittability(5); unacked_packets_.RemoveFromInFlight(3);
diff --git a/net/third_party/quic/core/quic_version_manager.cc b/net/third_party/quic/core/quic_version_manager.cc index 0a71f0e..07ab540 100644 --- a/net/third_party/quic/core/quic_version_manager.cc +++ b/net/third_party/quic/core/quic_version_manager.cc
@@ -17,9 +17,8 @@ : enable_version_99_(GetQuicFlag(FLAGS_quic_enable_version_99)), enable_version_44_(GetQuicReloadableFlag(quic_enable_version_44)), enable_version_43_(GetQuicReloadableFlag(quic_enable_version_43)), - disable_version_41_(GetQuicReloadableFlag(quic_disable_version_41)), - disable_version_38_(GetQuicReloadableFlag(quic_disable_version_38)), - disable_version_37_(GetQuicReloadableFlag(quic_disable_version_37)), + disable_version_42_(GetQuicReloadableFlag(quic_disable_version_42)), + disable_version_41_(GetQuicReloadableFlag(quic_disable_version_41_2)), allowed_supported_versions_(std::move(supported_versions)) { RefilterSupportedVersions(); } @@ -41,15 +40,13 @@ if (enable_version_99_ != GetQuicFlag(FLAGS_quic_enable_version_99) || enable_version_44_ != GetQuicReloadableFlag(quic_enable_version_44) || enable_version_43_ != GetQuicReloadableFlag(quic_enable_version_43) || - disable_version_41_ != GetQuicReloadableFlag(quic_disable_version_41) || - disable_version_38_ != GetQuicReloadableFlag(quic_disable_version_38) || - disable_version_37_ != GetQuicReloadableFlag(quic_disable_version_37)) { + disable_version_42_ != GetQuicReloadableFlag(quic_disable_version_42) || + disable_version_41_ != GetQuicReloadableFlag(quic_disable_version_41_2)) { enable_version_99_ = GetQuicFlag(FLAGS_quic_enable_version_99); enable_version_44_ = GetQuicReloadableFlag(quic_enable_version_44); enable_version_43_ = GetQuicReloadableFlag(quic_enable_version_43); - disable_version_37_ = GetQuicReloadableFlag(quic_disable_version_37); - disable_version_38_ = GetQuicReloadableFlag(quic_disable_version_38); - disable_version_41_ = GetQuicReloadableFlag(quic_disable_version_41); + disable_version_42_ = GetQuicReloadableFlag(quic_disable_version_42); + disable_version_41_ = GetQuicReloadableFlag(quic_disable_version_41_2); RefilterSupportedVersions(); } }
diff --git a/net/third_party/quic/core/quic_version_manager.h b/net/third_party/quic/core/quic_version_manager.h index cbf6bf6..839e813 100644 --- a/net/third_party/quic/core/quic_version_manager.h +++ b/net/third_party/quic/core/quic_version_manager.h
@@ -41,12 +41,10 @@ bool enable_version_44_; // FLAGS_quic_reloadable_flag_quic_disable_version_43 bool enable_version_43_; + // FLAGS_quic_reloadable_flag_quic_disable_version_42 + bool disable_version_42_; // FLAGS_quic_reloadable_flag_quic_disable_version_41 bool disable_version_41_; - // FLAGS_quic_reloadable_flag_quic_disable_version_38 - bool disable_version_38_; - // FLAGS_quic_reloadable_flag_quic_disable_version_37 - bool disable_version_37_; // The list of versions that may be supported. ParsedQuicVersionVector allowed_supported_versions_; // This vector contains QUIC versions which are currently supported based on
diff --git a/net/third_party/quic/core/quic_version_manager_test.cc b/net/third_party/quic/core/quic_version_manager_test.cc index ea9261b..beb6fcc6 100644 --- a/net/third_party/quic/core/quic_version_manager_test.cc +++ b/net/third_party/quic/core/quic_version_manager_test.cc
@@ -16,60 +16,49 @@ class QuicVersionManagerTest : public QuicTest {}; TEST_F(QuicVersionManagerTest, QuicVersionManager) { - static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 9u, + static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u, "Supported versions out of sync"); SetQuicFlag(&FLAGS_quic_enable_version_99, false); SetQuicReloadableFlag(quic_enable_version_44, false); SetQuicReloadableFlag(quic_enable_version_43, false); - SetQuicReloadableFlag(quic_disable_version_41, true); - SetQuicReloadableFlag(quic_disable_version_38, true); - SetQuicReloadableFlag(quic_disable_version_37, true); + SetQuicReloadableFlag(quic_disable_version_42, true); + SetQuicReloadableFlag(quic_disable_version_41_2, true); QuicVersionManager manager(AllSupportedVersions()); EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()), manager.GetSupportedTransportVersions()); + EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_39, QUIC_VERSION_35}), + manager.GetSupportedTransportVersions()); + + SetQuicReloadableFlag(quic_disable_version_41_2, false); EXPECT_EQ(QuicTransportVersionVector( - {QUIC_VERSION_42, QUIC_VERSION_39, QUIC_VERSION_35}), + {QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35}), manager.GetSupportedTransportVersions()); - SetQuicReloadableFlag(quic_disable_version_37, false); - EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_42, QUIC_VERSION_39, - QUIC_VERSION_37, QUIC_VERSION_35}), - manager.GetSupportedTransportVersions()); - - SetQuicReloadableFlag(quic_disable_version_38, false); - EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_42, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, - QUIC_VERSION_35}), - manager.GetSupportedTransportVersions()); - - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_42, false); EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_42, QUIC_VERSION_41, - QUIC_VERSION_39, QUIC_VERSION_38, - QUIC_VERSION_37, QUIC_VERSION_35}), + QUIC_VERSION_39, QUIC_VERSION_35}), manager.GetSupportedTransportVersions()); SetQuicReloadableFlag(quic_enable_version_43, true); - EXPECT_EQ( - QuicTransportVersionVector( - {QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}), - manager.GetSupportedTransportVersions()); + EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_43, QUIC_VERSION_42, + QUIC_VERSION_41, QUIC_VERSION_39, + QUIC_VERSION_35}), + manager.GetSupportedTransportVersions()); SetQuicReloadableFlag(quic_enable_version_44, true); - EXPECT_EQ( - QuicTransportVersionVector( - {QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, - QUIC_VERSION_39, QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}), - manager.GetSupportedTransportVersions()); + EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_44, QUIC_VERSION_43, + QUIC_VERSION_42, QUIC_VERSION_41, + QUIC_VERSION_39, QUIC_VERSION_35}), + manager.GetSupportedTransportVersions()); SetQuicFlag(&FLAGS_quic_enable_version_99, true); - EXPECT_EQ(QuicTransportVersionVector( - {QUIC_VERSION_99, QUIC_VERSION_44, QUIC_VERSION_43, - QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}), - manager.GetSupportedTransportVersions()); + EXPECT_EQ( + QuicTransportVersionVector( + {QUIC_VERSION_99, QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_42, + QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35}), + manager.GetSupportedTransportVersions()); // Ensure that all versions are now supported. EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()),
diff --git a/net/third_party/quic/core/quic_versions.cc b/net/third_party/quic/core/quic_versions.cc index e6540f4..60bb2ed 100644 --- a/net/third_party/quic/core/quic_versions.cc +++ b/net/third_party/quic/core/quic_versions.cc
@@ -56,10 +56,6 @@ switch (parsed_version.transport_version) { case QUIC_VERSION_35: return MakeVersionLabel(proto, '0', '3', '5'); - case QUIC_VERSION_37: - return MakeVersionLabel(proto, '0', '3', '7'); - case QUIC_VERSION_38: - return MakeVersionLabel(proto, '0', '3', '8'); case QUIC_VERSION_39: return MakeVersionLabel(proto, '0', '3', '9'); case QUIC_VERSION_41: @@ -176,16 +172,12 @@ if (GetQuicReloadableFlag(quic_enable_version_43)) { filtered_versions.push_back(version); } + } else if (version.transport_version == QUIC_VERSION_42) { + if (!GetQuicReloadableFlag(quic_disable_version_42)) { + filtered_versions.push_back(version); + } } else if (version.transport_version == QUIC_VERSION_41) { - if (!GetQuicReloadableFlag(quic_disable_version_41)) { - filtered_versions.push_back(version); - } - } else if (version.transport_version == QUIC_VERSION_38) { - if (!GetQuicReloadableFlag(quic_disable_version_38)) { - filtered_versions.push_back(version); - } - } else if (version.transport_version == QUIC_VERSION_37) { - if (!GetQuicReloadableFlag(quic_disable_version_37)) { + if (!GetQuicReloadableFlag(quic_disable_version_41_2)) { filtered_versions.push_back(version); } } else { @@ -278,8 +270,6 @@ QuicString QuicVersionToString(QuicTransportVersion transport_version) { switch (transport_version) { RETURN_STRING_LITERAL(QUIC_VERSION_35); - RETURN_STRING_LITERAL(QUIC_VERSION_37); - RETURN_STRING_LITERAL(QUIC_VERSION_38); RETURN_STRING_LITERAL(QUIC_VERSION_39); RETURN_STRING_LITERAL(QUIC_VERSION_41); RETURN_STRING_LITERAL(QUIC_VERSION_42);
diff --git a/net/third_party/quic/core/quic_versions.h b/net/third_party/quic/core/quic_versions.h index 0da58b4b..dc3ff33 100644 --- a/net/third_party/quic/core/quic_versions.h +++ b/net/third_party/quic/core/quic_versions.h
@@ -25,9 +25,6 @@ QUIC_VERSION_UNSUPPORTED = 0, QUIC_VERSION_35 = 35, // Allows endpoints to independently set stream limit. - QUIC_VERSION_37 = 37, // Add perspective into null encryption. - QUIC_VERSION_38 = 38, // PADDING frame is a 1-byte frame with type 0x00. - // Respect NSTP connection option. QUIC_VERSION_39 = 39, // Integers and floating numbers are written in big // endian. Dot not ack acks. Send a connection level // WINDOW_UPDATE every 20 sent packets which do not @@ -101,9 +98,8 @@ // IMPORTANT: if you are adding to this list, follow the instructions at // http://sites/quic/adding-and-removing-versions static const QuicTransportVersion kSupportedTransportVersions[] = { - QUIC_VERSION_99, QUIC_VERSION_44, QUIC_VERSION_43, - QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; + QUIC_VERSION_99, QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_42, + QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35}; // This vector contains all crypto handshake protocols that are supported. static const HandshakeProtocol kSupportedHandshakeProtocols[] = {
diff --git a/net/third_party/quic/core/quic_versions_test.cc b/net/third_party/quic/core/quic_versions_test.cc index 8e40ead..0f68492 100644 --- a/net/third_party/quic/core/quic_versions_test.cc +++ b/net/third_party/quic/core/quic_versions_test.cc
@@ -132,10 +132,6 @@ TEST_F(QuicVersionsTest, ParseQuicVersionLabel) { EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_35), ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '3', '5'))); - EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37), - ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '3', '7'))); - EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38), - ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '3', '8'))); EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39), ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '3', '9'))); EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_41), @@ -151,10 +147,6 @@ FLAGS_quic_supports_tls_handshake = true; EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_35), ParseQuicVersionLabel(MakeVersionLabel('T', '0', '3', '5'))); - EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_37), - ParseQuicVersionLabel(MakeVersionLabel('T', '0', '3', '7'))); - EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_38), - ParseQuicVersionLabel(MakeVersionLabel('T', '0', '3', '8'))); EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_39), ParseQuicVersionLabel(MakeVersionLabel('T', '0', '3', '9'))); EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_41), @@ -189,12 +181,6 @@ EXPECT_EQ(MakeVersionLabel('Q', '0', '3', '5'), CreateQuicVersionLabel( ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_35))); - EXPECT_EQ(MakeVersionLabel('Q', '0', '3', '7'), - CreateQuicVersionLabel( - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37))); - EXPECT_EQ(MakeVersionLabel('Q', '0', '3', '8'), - CreateQuicVersionLabel( - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38))); EXPECT_EQ(MakeVersionLabel('Q', '0', '3', '9'), CreateQuicVersionLabel( ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39))); @@ -216,12 +202,6 @@ EXPECT_EQ(MakeVersionLabel('T', '0', '3', '5'), CreateQuicVersionLabel( ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_35))); - EXPECT_EQ(MakeVersionLabel('T', '0', '3', '7'), - CreateQuicVersionLabel( - ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_37))); - EXPECT_EQ(MakeVersionLabel('T', '0', '3', '8'), - CreateQuicVersionLabel( - ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_38))); EXPECT_EQ(MakeVersionLabel('T', '0', '3', '9'), CreateQuicVersionLabel( ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_39))); @@ -338,9 +318,8 @@ TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsAllVersions) { QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, false); - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_41_2, false); + SetQuicReloadableFlag(quic_disable_version_42, false); SetQuicReloadableFlag(quic_enable_version_43, true); SetQuicReloadableFlag(quic_enable_version_44, true); SetQuicFlag(&FLAGS_quic_enable_version_99, true); @@ -349,9 +328,8 @@ parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); } QuicTransportVersionVector expected_versions = { - QUIC_VERSION_99, QUIC_VERSION_44, QUIC_VERSION_43, - QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; + QUIC_VERSION_99, QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_42, + QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35}; ParsedQuicVersionVector expected_parsed_versions; for (QuicTransportVersion version : expected_versions) { expected_parsed_versions.push_back( @@ -364,9 +342,7 @@ TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo99) { QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, false); - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_41_2, false); SetQuicReloadableFlag(quic_enable_version_43, true); SetQuicReloadableFlag(quic_enable_version_44, true); SetQuicFlag(&FLAGS_quic_enable_version_99, false); @@ -375,8 +351,8 @@ parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); } QuicTransportVersionVector expected_versions = { - QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, - QUIC_VERSION_39, QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; + QUIC_VERSION_44, QUIC_VERSION_43, QUIC_VERSION_42, + QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35}; ParsedQuicVersionVector expected_parsed_versions; for (QuicTransportVersion version : expected_versions) { expected_parsed_versions.push_back( @@ -389,9 +365,7 @@ TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo44) { QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, false); - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_41_2, false); SetQuicReloadableFlag(quic_enable_version_43, true); SetQuicReloadableFlag(quic_enable_version_44, false); SetQuicFlag(&FLAGS_quic_enable_version_99, false); @@ -401,7 +375,7 @@ } QuicTransportVersionVector expected_versions = { QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; + QUIC_VERSION_35}; ParsedQuicVersionVector expected_parsed_versions; for (QuicTransportVersion version : expected_versions) { expected_parsed_versions.push_back( @@ -412,11 +386,10 @@ ASSERT_EQ(expected_parsed_versions, FilterSupportedVersions(parsed_versions)); } -TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo43) { +TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo42) { QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, false); - SetQuicReloadableFlag(quic_disable_version_41, false); + SetQuicReloadableFlag(quic_disable_version_41_2, false); + SetQuicReloadableFlag(quic_disable_version_42, true); SetQuicReloadableFlag(quic_enable_version_43, false); SetQuicReloadableFlag(quic_enable_version_44, false); SetQuicFlag(&FLAGS_quic_enable_version_99, false); @@ -425,8 +398,7 @@ parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); } QuicTransportVersionVector expected_versions = { - QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, - QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35}; + QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35}; ParsedQuicVersionVector expected_parsed_versions; for (QuicTransportVersion version : expected_versions) { expected_parsed_versions.push_back( @@ -439,9 +411,8 @@ TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo41) { QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, true); - SetQuicReloadableFlag(quic_disable_version_41, true); + SetQuicReloadableFlag(quic_disable_version_41_2, true); + SetQuicReloadableFlag(quic_disable_version_42, true); SetQuicReloadableFlag(quic_enable_version_43, false); SetQuicReloadableFlag(quic_enable_version_44, false); SetQuicFlag(&FLAGS_quic_enable_version_99, false); @@ -449,58 +420,8 @@ for (QuicTransportVersion version : all_versions) { parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); } - QuicTransportVersionVector expected_versions = { - QUIC_VERSION_42, QUIC_VERSION_39, QUIC_VERSION_37, QUIC_VERSION_35}; - ParsedQuicVersionVector expected_parsed_versions; - for (QuicTransportVersion version : expected_versions) { - expected_parsed_versions.push_back( - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); - } - - ASSERT_EQ(expected_versions, FilterSupportedTransportVersions(all_versions)); - ASSERT_EQ(expected_parsed_versions, FilterSupportedVersions(parsed_versions)); -} - -TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo38) { - QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, false); - SetQuicReloadableFlag(quic_disable_version_38, true); - SetQuicReloadableFlag(quic_disable_version_41, false); - SetQuicReloadableFlag(quic_enable_version_43, false); - SetQuicReloadableFlag(quic_enable_version_44, false); - SetQuicFlag(&FLAGS_quic_enable_version_99, false); - ParsedQuicVersionVector parsed_versions; - for (QuicTransportVersion version : all_versions) { - parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); - } - QuicTransportVersionVector expected_versions = { - QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_37, - QUIC_VERSION_35}; - ParsedQuicVersionVector expected_parsed_versions; - for (QuicTransportVersion version : expected_versions) { - expected_parsed_versions.push_back( - ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); - } - - ASSERT_EQ(expected_versions, FilterSupportedTransportVersions(all_versions)); - ASSERT_EQ(expected_parsed_versions, FilterSupportedVersions(parsed_versions)); -} - -TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo37) { - QuicTransportVersionVector all_versions = AllSupportedTransportVersions(); - SetQuicReloadableFlag(quic_disable_version_37, true); - SetQuicReloadableFlag(quic_disable_version_38, false); - SetQuicReloadableFlag(quic_disable_version_41, false); - SetQuicReloadableFlag(quic_enable_version_43, false); - SetQuicReloadableFlag(quic_enable_version_44, false); - SetQuicFlag(&FLAGS_quic_enable_version_99, false); - ParsedQuicVersionVector parsed_versions; - for (QuicTransportVersion version : all_versions) { - parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version)); - } - QuicTransportVersionVector expected_versions = { - QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_38, - QUIC_VERSION_35}; + QuicTransportVersionVector expected_versions = {QUIC_VERSION_39, + QUIC_VERSION_35}; ParsedQuicVersionVector expected_parsed_versions; for (QuicTransportVersion version : expected_versions) { expected_parsed_versions.push_back( @@ -512,8 +433,7 @@ } TEST_F(QuicVersionsTest, LookUpVersionByIndex) { - QuicTransportVersionVector all_versions = {QUIC_VERSION_35, QUIC_VERSION_37, - QUIC_VERSION_38, QUIC_VERSION_39}; + QuicTransportVersionVector all_versions = {QUIC_VERSION_35, QUIC_VERSION_39}; int version_count = all_versions.size(); for (int i = -5; i <= version_count + 1; ++i) { if (i >= 0 && i < version_count) { @@ -552,11 +472,9 @@ // yet a typo was made in doing the #defines and it was caught // only in some test far removed from here... Better safe than sorry. TEST_F(QuicVersionsTest, CheckVersionNumbersForTypos) { - static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 9u, + static_assert(QUIC_ARRAYSIZE(quic::kSupportedTransportVersions) == 7u, "Supported versions out of sync"); EXPECT_EQ(QUIC_VERSION_35, 35); - EXPECT_EQ(QUIC_VERSION_37, 37); - EXPECT_EQ(QUIC_VERSION_38, 38); EXPECT_EQ(QUIC_VERSION_39, 39); EXPECT_EQ(QUIC_VERSION_41, 41); EXPECT_EQ(QUIC_VERSION_42, 42);
diff --git a/net/third_party/quic/core/quic_write_blocked_list.cc b/net/third_party/quic/core/quic_write_blocked_list.cc index f6b2e18..80a8512 100644 --- a/net/third_party/quic/core/quic_write_blocked_list.cc +++ b/net/third_party/quic/core/quic_write_blocked_list.cc
@@ -9,7 +9,10 @@ namespace quic { -QuicWriteBlockedList::QuicWriteBlockedList() : last_priority_popped_(0) { +QuicWriteBlockedList::QuicWriteBlockedList() + : last_priority_popped_(0), + use_static_stream_collection_(GetQuicReloadableFlag( + quic_use_static_stream_collection_in_write_blocked_list)) { memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_)); memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_)); }
diff --git a/net/third_party/quic/core/quic_write_blocked_list.h b/net/third_party/quic/core/quic_write_blocked_list.h index 03262ad..793f8a1 100644 --- a/net/third_party/quic/core/quic_write_blocked_list.h +++ b/net/third_party/quic/core/quic_write_blocked_list.h
@@ -32,6 +32,10 @@ } bool HasWriteBlockedSpecialStream() const { + if (use_static_stream_collection_) { + return static_stream_collection_.num_blocked() > 0; + } + for (const auto& stream : static_streams_) { if (stream.second) { return true; @@ -41,6 +45,10 @@ } size_t NumBlockedSpecialStreams() const { + if (use_static_stream_collection_) { + return static_stream_collection_.num_blocked(); + } + size_t num_blocked = 0; for (const auto& stream : static_streams_) { if (stream.second) { @@ -56,14 +64,27 @@ } bool ShouldYield(QuicStreamId id) const { - for (const auto& stream : static_streams_) { - if (stream.first == id) { - // Static streams should never yield to data streams, or to lower - // priority static stream. - return false; + if (use_static_stream_collection_) { + for (const auto& stream : static_stream_collection_) { + if (stream.id == id) { + // Static streams should never yield to data streams, or to lower + // priority static stream. + return false; + } + if (stream.is_blocked) { + return true; // All data streams yield to static streams. + } } - if (stream.second) { - return true; // All data streams yield to static streams. + } else { + for (const auto& stream : static_streams_) { + if (stream.first == id) { + // Static streams should never yield to data streams, or to lower + // priority static stream. + return false; + } + if (stream.second) { + return true; // All data streams yield to static streams. + } } } return priority_write_scheduler_.ShouldYield(id); @@ -72,10 +93,17 @@ // Pops the highest priorty stream, special casing crypto and headers streams. // Latches the most recently popped data stream for batch writing purposes. QuicStreamId PopFront() { - for (auto& stream : static_streams_) { - if (stream.second) { - stream.second = false; - return stream.first; + if (use_static_stream_collection_) { + QuicStreamId static_stream_id; + if (static_stream_collection_.UnblockFirstBlocked(&static_stream_id)) { + return static_stream_id; + } + } else { + for (auto& stream : static_streams_) { + if (stream.second) { + stream.second = false; + return stream.first; + } } } @@ -103,24 +131,39 @@ void RegisterStream(QuicStreamId stream_id, bool is_static_stream, spdy::SpdyPriority priority) { - if (is_static_stream) { + if (use_static_stream_collection_) { DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id)); - DCHECK(!QuicContainsKey(static_streams_, stream_id)); - DCHECK(static_streams_.empty() || - stream_id > static_streams_.back().first) - << "stream_id: " << stream_id - << " last static stream: " << static_streams_.back().first; - static_streams_[stream_id] = false; - return; + if (is_static_stream) { + static_stream_collection_.Register(stream_id); + return; + } + + priority_write_scheduler_.RegisterStream( + stream_id, spdy::SpdyStreamPrecedence(priority)); + } else { + if (is_static_stream) { + DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id)); + DCHECK(!QuicContainsKey(static_streams_, stream_id)); + DCHECK(static_streams_.empty() || + stream_id > static_streams_.back().first) + << "stream_id: " << stream_id + << " last static stream: " << static_streams_.back().first; + static_streams_[stream_id] = false; + return; + } + DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id)); + priority_write_scheduler_.RegisterStream( + stream_id, spdy::SpdyStreamPrecedence(priority)); } - DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id)); - priority_write_scheduler_.RegisterStream( - stream_id, spdy::SpdyStreamPrecedence(priority)); } void UnregisterStream(QuicStreamId stream_id, bool is_static) { if (is_static) { - static_streams_.erase(stream_id); + if (use_static_stream_collection_) { + static_stream_collection_.Unregister(stream_id); + } else { + static_streams_.erase(stream_id); + } return; } priority_write_scheduler_.UnregisterStream(stream_id); @@ -128,7 +171,10 @@ void UpdateStreamPriority(QuicStreamId stream_id, spdy::SpdyPriority new_priority) { - DCHECK(!QuicContainsKey(static_streams_, stream_id)); + DCHECK(use_static_stream_collection_ || + !QuicContainsKey(static_streams_, stream_id)); + DCHECK(!use_static_stream_collection_ || + !static_stream_collection_.IsRegistered(stream_id)); priority_write_scheduler_.UpdateStreamPrecedence( stream_id, spdy::SpdyStreamPrecedence(new_priority)); } @@ -147,10 +193,16 @@ // the list for its priority level. // Headers and crypto streams are special cased to always resume first. void AddStream(QuicStreamId stream_id) { - auto it = static_streams_.find(stream_id); - if (it != static_streams_.end()) { - it->second = true; - return; + if (use_static_stream_collection_) { + if (static_stream_collection_.SetBlocked(stream_id)) { + return; + } + } else { + auto it = static_streams_.find(stream_id); + if (it != static_streams_.end()) { + it->second = true; + return; + } } bool push_front = stream_id == batch_write_stream_id_[last_priority_popped_] && @@ -158,12 +210,19 @@ priority_write_scheduler_.MarkStreamReady(stream_id, push_front); } - // This function is used for debugging and test only. Returns true if stream - // with |stream_id| is write blocked. + // Returns true if stream with |stream_id| is write blocked. bool IsStreamBlocked(QuicStreamId stream_id) const { - auto it = static_streams_.find(stream_id); - if (it != static_streams_.end()) { - return it->second; + if (use_static_stream_collection_) { + for (const auto& stream : static_stream_collection_) { + if (stream.id == stream_id) { + return stream.is_blocked; + } + } + } else { + auto it = static_streams_.find(stream_id); + if (it != static_streams_.end()) { + return it->second; + } } return priority_write_scheduler_.IsStreamReady(stream_id); @@ -184,8 +243,104 @@ // Tracks the last priority popped for UpdateBytesForStream. spdy::SpdyPriority last_priority_popped_; + // A StaticStreamCollection is a vector of <QuicStreamId, bool> pairs plus a + // eagerly-computed number of blocked static streams. + class StaticStreamCollection { + public: + struct StreamIdBlockedPair { + QuicStreamId id; + bool is_blocked; + }; + + std::vector<StreamIdBlockedPair>::const_iterator begin() const { + return streams_.cbegin(); + } + + std::vector<StreamIdBlockedPair>::const_iterator end() const { + return streams_.cend(); + } + + size_t num_blocked() const { return num_blocked_; } + + // Add |id| to the collection in unblocked state. + void Register(QuicStreamId id) { + DCHECK(!IsRegistered(id)); + DCHECK(streams_.empty() || id > streams_.back().id) + << "stream_id: " << id + << " last static stream: " << streams_.back().id; + streams_.push_back({id, false}); + } + + // True if |id| is in the collection, regardless of its state. + bool IsRegistered(QuicStreamId id) const { + for (const auto& stream : streams_) { + if (stream.id == id) { + return true; + } + } + return false; + } + + // Remove |id| from the collection, if it is in the blocked state, reduce + // |num_blocked_| by 1. + void Unregister(QuicStreamId id) { + for (auto it = streams_.begin(); it != streams_.end(); ++it) { + if (it->id == id) { + if (it->is_blocked) { + --num_blocked_; + } + streams_.erase(it); + return; + } + } + DCHECK(false) << "Erasing a non-exist stream with id " << id; + } + + // Set |id| to be blocked. If |id| is not already blocked, increase + // |num_blocked_| by 1. + // Return true if |id| is in the collection. + bool SetBlocked(QuicStreamId id) { + for (auto& stream : streams_) { + if (stream.id == id) { + if (!stream.is_blocked) { + stream.is_blocked = true; + ++num_blocked_; + } + return true; + } + } + return false; + } + + // Unblock the first blocked stream in the collection. + // If no stream is blocked, return false. Otherwise return true, set *id to + // the unblocked stream id and reduce |num_blocked_| by 1. + bool UnblockFirstBlocked(QuicStreamId* id) { + for (auto& stream : streams_) { + if (stream.is_blocked) { + --num_blocked_; + stream.is_blocked = false; + *id = stream.id; + return true; + } + } + return false; + } + + private: + size_t num_blocked_ = 0; + std::vector<StreamIdBlockedPair> streams_; + }; + + // Used iff use_static_stream_collection_ is true. + StaticStreamCollection static_stream_collection_; + + // Used iff use_static_stream_collection_ is false. QuicLinkedHashMapImpl<QuicStreamId, bool> static_streams_; + // Latched value of quic_use_static_stream_collection_in_write_blocked_list. + const bool use_static_stream_collection_; + DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList); };
diff --git a/net/third_party/quic/core/spdy_utils_test.cc b/net/third_party/quic/core/spdy_utils_test.cc index 93640eb..4910e72 100644 --- a/net/third_party/quic/core/spdy_utils_test.cc +++ b/net/third_party/quic/core/spdy_utils_test.cc
@@ -11,13 +11,13 @@ #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quic/platform/api/quic_text_utils.h" -namespace quic { -namespace test { - using spdy::SpdyHeaderBlock; using testing::Pair; using testing::UnorderedElementsAre; +namespace quic { +namespace test { + static std::unique_ptr<QuicHeaderList> FromList( const QuicHeaderList::ListType& src) { std::unique_ptr<QuicHeaderList> headers(new QuicHeaderList);
diff --git a/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.cc b/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.cc index 22157e2..56eafde 100644 --- a/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.cc +++ b/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.cc
@@ -13,9 +13,9 @@ MockTimeWaitListManager::MockTimeWaitListManager( QuicPacketWriter* writer, Visitor* visitor, - QuicConnectionHelperInterface* helper, + const QuicClock* clock, QuicAlarmFactory* alarm_factory) - : QuicTimeWaitListManager(writer, visitor, helper, alarm_factory) { + : QuicTimeWaitListManager(writer, visitor, clock, alarm_factory) { // Though AddConnectionIdToTimeWait is mocked, we want to retain its // functionality. EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _))
diff --git a/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.h b/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.h index 13600e0..6dfe8d3 100644 --- a/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.h +++ b/net/third_party/quic/test_tools/mock_quic_time_wait_list_manager.h
@@ -15,7 +15,7 @@ public: MockTimeWaitListManager(QuicPacketWriter* writer, Visitor* visitor, - QuicConnectionHelperInterface* helper, + const QuicClock* clock, QuicAlarmFactory* alarm_factory); ~MockTimeWaitListManager() override;
diff --git a/net/third_party/quic/test_tools/mock_random.cc b/net/third_party/quic/test_tools/mock_random.cc index baf29ee..3809dd8 100644 --- a/net/third_party/quic/test_tools/mock_random.cc +++ b/net/third_party/quic/test_tools/mock_random.cc
@@ -21,8 +21,6 @@ return base_ + increment_; } -void MockRandom::Reseed(const void* additional_entropy, size_t entropy_len) {} - void MockRandom::ChangeValue() { increment_++; }
diff --git a/net/third_party/quic/test_tools/mock_random.h b/net/third_party/quic/test_tools/mock_random.h index 728249e6..090bab6 100644 --- a/net/third_party/quic/test_tools/mock_random.h +++ b/net/third_party/quic/test_tools/mock_random.h
@@ -23,8 +23,6 @@ void RandBytes(void* data, size_t len) override; // Returns base + the current increment. uint64_t RandUint64() override; - // Does nothing. - void Reseed(const void* additional_entropy, size_t entropy_len) override; // ChangeValue increments |increment_|. This causes the value returned by // |RandUint64| and the byte that |RandBytes| fills with, to change.
diff --git a/net/third_party/quic/test_tools/quic_test_utils.cc b/net/third_party/quic/test_tools/quic_test_utils.cc index 407621b6..8608302 100644 --- a/net/third_party/quic/test_tools/quic_test_utils.cc +++ b/net/third_party/quic/test_tools/quic_test_utils.cc
@@ -124,15 +124,6 @@ } } -void SimpleRandom::Reseed(const void* additional_entropy, size_t len) { - const uint8_t* real_entropy = static_cast<const uint8_t*>(additional_entropy); - for (size_t offset = 0; offset < len; offset++) { - // Note: this is not actually a well-established way to incorporate new - // entropy, but good enough for tests. - seed_ *= real_entropy[len]; - } -} - MockFramerVisitor::MockFramerVisitor() { // By default, we want to accept packets. ON_CALL(*this, OnProtocolVersionMismatch(_)) @@ -149,8 +140,6 @@ ON_CALL(*this, OnStreamFrame(_)).WillByDefault(testing::Return(true)); - ON_CALL(*this, OnAckFrame(_)).WillByDefault(testing::Return(true)); - ON_CALL(*this, OnStopWaitingFrame(_)).WillByDefault(testing::Return(true)); ON_CALL(*this, OnPaddingFrame(_)).WillByDefault(testing::Return(true)); @@ -201,10 +190,6 @@ return true; } -bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) { - return true; -} - bool NoOpFramerVisitor::OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) { return true; @@ -572,6 +557,11 @@ &helper_); } +void TestQuicSpdyServerSession::OnCryptoHandshakeEvent( + CryptoHandshakeEvent event) { + QuicSession::OnCryptoHandshakeEvent(event); +} + QuicCryptoServerStream* TestQuicSpdyServerSession::GetMutableCryptoStream() { return static_cast<QuicCryptoServerStream*>( QuicServerSessionBase::GetMutableCryptoStream()); @@ -601,6 +591,11 @@ return true; } +void TestQuicSpdyClientSession::OnCryptoHandshakeEvent( + CryptoHandshakeEvent event) { + QuicSession::OnCryptoHandshakeEvent(event); +} + QuicCryptoClientStream* TestQuicSpdyClientSession::GetMutableCryptoStream() { return crypto_stream_.get(); }
diff --git a/net/third_party/quic/test_tools/quic_test_utils.h b/net/third_party/quic/test_tools/quic_test_utils.h index 5e58ae1..6c14259 100644 --- a/net/third_party/quic/test_tools/quic_test_utils.h +++ b/net/third_party/quic/test_tools/quic_test_utils.h
@@ -231,7 +231,6 @@ uint64_t RandUint64() override; void RandBytes(void* data, size_t len) override; - void Reseed(const void* additional_entropy, size_t len) override; void set_seed(uint64_t seed) { seed_ = seed; } @@ -261,7 +260,6 @@ MOCK_METHOD1(OnDecryptedPacket, void(EncryptionLevel level)); MOCK_METHOD1(OnPacketHeader, bool(const QuicPacketHeader& header)); MOCK_METHOD1(OnStreamFrame, bool(const QuicStreamFrame& frame)); - MOCK_METHOD1(OnAckFrame, bool(const QuicAckFrame& frame)); MOCK_METHOD2(OnAckFrameStart, bool(QuicPacketNumber, QuicTime::Delta)); MOCK_METHOD3(OnAckRange, bool(QuicPacketNumber, QuicPacketNumber, bool)); MOCK_METHOD1(OnStopWaitingFrame, bool(const QuicStopWaitingFrame& frame)); @@ -307,7 +305,6 @@ void OnDecryptedPacket(EncryptionLevel level) override {} bool OnPacketHeader(const QuicPacketHeader& header) override; bool OnStreamFrame(const QuicStreamFrame& frame) override; - bool OnAckFrame(const QuicAckFrame& frame) override; bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override; bool OnAckRange(QuicPacketNumber start, @@ -722,6 +719,9 @@ const QuicCryptoServerConfig* crypto_config, QuicCompressedCertsCache* compressed_certs_cache) override; + // Override to not send max header list size. + void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; + QuicCryptoServerStream* GetMutableCryptoStream() override; const QuicCryptoServerStream* GetCryptoStream() const override; @@ -779,6 +779,8 @@ MOCK_METHOD1(ShouldCreateIncomingDynamicStream, bool(QuicStreamId id)); MOCK_METHOD0(ShouldCreateOutgoingDynamicStream, bool()); + // Override to not send max header list size. + void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; QuicCryptoClientStream* GetMutableCryptoStream() override; const QuicCryptoClientStream* GetCryptoStream() const override;
diff --git a/net/third_party/quic/test_tools/simple_quic_framer.cc b/net/third_party/quic/test_tools/simple_quic_framer.cc index be8c955..06725384 100644 --- a/net/third_party/quic/test_tools/simple_quic_framer.cc +++ b/net/third_party/quic/test_tools/simple_quic_framer.cc
@@ -63,11 +63,6 @@ return true; } - bool OnAckFrame(const QuicAckFrame& frame) override { - ack_frames_.push_back(frame); - return true; - } - bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta ack_delay_time) override { QuicAckFrame ack_frame;
diff --git a/net/third_party/quic/test_tools/simulator/quic_endpoint.cc b/net/third_party/quic/test_tools/simulator/quic_endpoint.cc index 1332c93..0525ffe 100644 --- a/net/third_party/quic/test_tools/simulator/quic_endpoint.cc +++ b/net/third_party/quic/test_tools/simulator/quic_endpoint.cc
@@ -81,6 +81,7 @@ bytes_transferred_(0), write_blocked_count_(0), wrong_data_received_(false), + drop_next_packet_(false), notifier_(nullptr) { nic_tx_queue_.set_listener_interface(this); @@ -170,6 +171,10 @@ WriteStreamData(); } +void QuicEndpoint::DropNextIncomingPacket() { + drop_next_packet_ = true; +} + void QuicEndpoint::RecordTrace() { trace_visitor_ = QuicMakeUnique<QuicTraceVisitor>(&connection_); connection_.set_debug_visitor(trace_visitor_.get()); @@ -179,6 +184,10 @@ if (packet->destination != name_) { return; } + if (drop_next_packet_) { + drop_next_packet_ = false; + return; + } QuicReceivedPacket received_packet(packet->contents.data(), packet->contents.size(), clock_->Now());
diff --git a/net/third_party/quic/test_tools/simulator/quic_endpoint.h b/net/third_party/quic/test_tools/simulator/quic_endpoint.h index 78a32d77..feb6e68 100644 --- a/net/third_party/quic/test_tools/simulator/quic_endpoint.h +++ b/net/third_party/quic/test_tools/simulator/quic_endpoint.h
@@ -57,6 +57,9 @@ // progress. void AddBytesToTransfer(QuicByteCount bytes); + // Drop the next packet upon receipt. + void DropNextIncomingPacket(); + // UnconstrainedPortInterface method. Called whenever the endpoint receives a // packet. void AcceptPacket(std::unique_ptr<Packet> packet) override; @@ -175,6 +178,9 @@ // expects. bool wrong_data_received_; + // If true, drop the next packet when receiving it. + bool drop_next_packet_; + // Record of received offsets in the data stream. QuicIntervalSet<QuicStreamOffset> offsets_received_;
diff --git a/net/third_party/quic/tools/quic_client_base.cc b/net/third_party/quic/tools/quic_client_base.cc index 3f29e8e4..8166c4e 100644 --- a/net/third_party/quic/tools/quic_client_base.cc +++ b/net/third_party/quic/tools/quic_client_base.cc
@@ -180,6 +180,12 @@ } bool QuicClientBase::MigrateSocket(const QuicIpAddress& new_host) { + return MigrateSocketWithSpecifiedPort(new_host, local_port_); +} + +bool QuicClientBase::MigrateSocketWithSpecifiedPort( + const QuicIpAddress& new_host, + int port) { if (!connected()) { return false; } @@ -188,7 +194,7 @@ set_bind_to_address(new_host); if (!network_helper_->CreateUDPSocketAndBind(server_address_, - bind_to_address_, local_port_)) { + bind_to_address_, port)) { return false; }
diff --git a/net/third_party/quic/tools/quic_client_base.h b/net/third_party/quic/tools/quic_client_base.h index d1f2eb12..4503085 100644 --- a/net/third_party/quic/tools/quic_client_base.h +++ b/net/third_party/quic/tools/quic_client_base.h
@@ -106,9 +106,12 @@ // Returns true if there are any outstanding requests. bool WaitForEvents(); - // Migrate to a new socket during an active connection. + // Migrate to a new socket (new_host) during an active connection. bool MigrateSocket(const QuicIpAddress& new_host); + // Migrate to a new socket (new_host, port) during an active connection. + bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port); + QuicSession* session(); bool connected() const;
diff --git a/net/third_party/quic/tools/quic_packet_printer_bin.cc b/net/third_party/quic/tools/quic_packet_printer_bin.cc index 44689525..743d114 100644 --- a/net/third_party/quic/tools/quic_packet_printer_bin.cc +++ b/net/third_party/quic/tools/quic_packet_printer_bin.cc
@@ -105,10 +105,6 @@ << " }\n"; return true; } - bool OnAckFrame(const QuicAckFrame& frame) override { - std::cerr << "OnAckFrame: " << frame; - return true; - } bool OnAckFrameStart(QuicPacketNumber largest_acked, QuicTime::Delta /*ack_delay_time*/) override { std::cerr << "OnAckFrameStart, largest_acked: " << largest_acked;
diff --git a/net/third_party/quic/tools/trace/quic_trace_to_time_sequence_gnuplot.cc b/net/third_party/quic/tools/trace/quic_trace_to_time_sequence_gnuplot.cc deleted file mode 100644 index 0adfeca..0000000 --- a/net/third_party/quic/tools/trace/quic_trace_to_time_sequence_gnuplot.cc +++ /dev/null
@@ -1,143 +0,0 @@ -// Copyright (c) 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Helper script to generate time sequence plot using gnuplot. -// Accepts the trace on stdin, and outputs the gnuplot-consumable time series -// file into stdout. - -#include <iostream> -#include <streambuf> -#include <string> -#include <unordered_map> -#include <unordered_set> - -#include "base/command_line.h" -#include "net/third_party/quic/core/proto/quic_trace.pb.h" - -std::string FLAGS_sequence = ""; -bool FLAGS_filter_old_acks = true; - -namespace quic_trace { -namespace { - -// Calculates the amount of actual data in the packet. -size_t FrameDataInSentPacket(const Event& packet) { - if (packet.event_type() != PACKET_SENT) { - return 0; - } - - size_t sent_in_packet = 0; - for (const Frame& frame : packet.frames()) { - if (frame.frame_type() != STREAM || !frame.has_stream_frame_info()) { - continue; - } - sent_in_packet += frame.stream_frame_info().length(); - } - return sent_in_packet; -} - -struct SentPacket { - // Offset of the stream data sent in the frame with respect to the beginning - // of the connection. - size_t offset; - // Size of frame data in the packet. - size_t size; -}; -// Map of the sent packets, keyed by packet number. -using SentPacketMap = std::unordered_map<uint64_t, SentPacket>; - -void PrintSentPacket(const SentPacketMap& packet_map, - uint64_t packet_number, - uint64_t time) { - auto original_packet_it = packet_map.find(packet_number); - if (original_packet_it == packet_map.end()) { - return; - } - - const SentPacket& original_packet = original_packet_it->second; - - std::cout << time << " " << original_packet.offset << std::endl; - std::cout << time << " " << (original_packet.offset + original_packet.size) - << std::endl; - std::cout << std::endl; -} - -void PrintTimeSequence(std::istream* trace_source) { - Trace trace; - std::string trace_raw((std::istreambuf_iterator<char>(std::cin)), - std::istreambuf_iterator<char>()); - trace.ParseFromString(trace_raw); - - size_t total_sent = 0; - SentPacketMap packet_map; - std::unordered_set<uint64_t> already_acknowledged; - // In a single pass, compute |packet_map| and output the requested sequence. - for (const Event& event : trace.events()) { - // Track all sent packets and their offsets in the plot. - size_t sent_in_packet = FrameDataInSentPacket(event); - if (sent_in_packet != 0) { - packet_map.emplace(event.packet_number(), - SentPacket{total_sent, sent_in_packet}); - } - total_sent += sent_in_packet; - - // Output sent packets. - if (sent_in_packet != 0 && FLAGS_sequence == "send") { - std::cout << event.time_us() << " " << (total_sent - sent_in_packet) - << std::endl; - std::cout << event.time_us() << " " << total_sent << std::endl; - std::cout << std::endl; - } - - // Output loss events. - if (event.event_type() == PACKET_LOST && FLAGS_sequence == "loss") { - PrintSentPacket(packet_map, event.packet_number(), event.time_us()); - } - - // Output acks. - if (event.event_type() == PACKET_RECEIVED) { - for (const Frame& frame : event.frames()) { - if (frame.frame_type() == ACK && FLAGS_sequence == "ack") { - for (const AckBlock& block : frame.ack_info().acked_packets()) { - for (uint64_t packet = block.first_packet(); - packet <= block.last_packet(); packet++) { - if (FLAGS_filter_old_acks) { - if (already_acknowledged.count(packet) > 0) { - continue; - } - already_acknowledged.insert(packet); - } - PrintSentPacket(packet_map, packet, event.time_us()); - } - } - } - } - } - } -} - -} // namespace -} // namespace quic_trace - -int main(int argc, char* argv[]) { - base::CommandLine::Init(argc, argv); - base::CommandLine* line = base::CommandLine::ForCurrentProcess(); - if (line->HasSwitch("sequence")) { - FLAGS_sequence = line->GetSwitchValueASCII("sequence"); - } - if (line->HasSwitch("nofilter_old_acks")) { - FLAGS_filter_old_acks = false; - } - - if (FLAGS_sequence != "send" && FLAGS_sequence != "ack" && - FLAGS_sequence != "loss") { - std::cerr << "The --type parameter has to be set to either 'send', 'ack' " - "or 'loss'." - << std::endl; - return 1; - } - - quic_trace::PrintTimeSequence(&std::cin); - return 0; -}
diff --git a/net/third_party/quic/tools/trace/time_sequence_gnuplot.sh b/net/third_party/quic/tools/trace/time_sequence_gnuplot.sh deleted file mode 100755 index 7d9abd20..0000000 --- a/net/third_party/quic/tools/trace/time_sequence_gnuplot.sh +++ /dev/null
@@ -1,58 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# -# Render a trace using gnuplot into a png file. -# - -if [ -z "$1" ]; then - echo "Usage: time_sequence_gnuplot.sh path/to/trace output.png" - exit 1 -fi - -if [ ! -f "$1" ]; then - echo "File $1 does not exist or is not a file" - exit 1 -fi - -if [ -z "$2" ]; then - echo "Output file not specified" - exit 1 -fi - -if [ ! -x "$QUIC_TRACE_CONV_BIN" ]; then - SCRIPT_SOURCE_DIR="$(dirname "${BASH_SOURCE[0]}")" - QUIC_TRACE_CONV_BIN="$SCRIPT_SOURCE_DIR/../../../../../out/Default/quic_trace_to_time_sequence_gnuplot" -fi - -if [ ! -x "$QUIC_TRACE_CONV_BIN" ]; then - echo "Cannot find conversion tool binary" - exit 1 -fi - -TMPDIR="$(mktemp -d)" -for event_type in send ack loss; do - "$QUIC_TRACE_CONV_BIN" --sequence=$event_type < "$1" > "$TMPDIR/$event_type.txt" -done - -if [ -z "$GNUPLOT_SIZE" ]; then - GNUPLOT_SIZE="7680,4320" -fi -if [ -z "$GNUPLOT_TERMINAL" ]; then - GNUPLOT_TERMINAL="png size $GNUPLOT_SIZE" -fi - - -gnuplot <<EOF -set terminal $GNUPLOT_TERMINAL -set output "$2" -plot \ - "$TMPDIR/send.txt" with lines lt rgb "blue" title "Sent", \ - "$TMPDIR/ack.txt" with lines lt rgb "green" title "Ack", \ - "$TMPDIR/loss.txt" with lines lt rgb "red" title "Loss" -EOF - -rm -rf "$TMPDIR"
diff --git a/net/tools/cert_verify_tool/verify_using_path_builder.cc b/net/tools/cert_verify_tool/verify_using_path_builder.cc index 8621c76..8a933a6 100644 --- a/net/tools/cert_verify_tool/verify_using_path_builder.cc +++ b/net/tools/cert_verify_tool/verify_using_path_builder.cc
@@ -163,7 +163,8 @@ return false; // Verify the chain. - net::SimplePathBuilderDelegate delegate(2048); + net::SimplePathBuilderDelegate delegate( + 2048, net::SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); net::CertPathBuilder::Result result; net::CertPathBuilder path_builder( target_cert, ssl_trust_store->GetTrustStore(), &delegate, time, @@ -193,11 +194,11 @@ } // TODO(mattm): add flag to dump all paths, not just the final one? - if (!dump_prefix_path.empty() && result.paths.size()) { + if (!dump_prefix_path.empty() && !result.paths.empty()) { if (!DumpParsedCertificateChain( dump_prefix_path.AddExtension( FILE_PATH_LITERAL(".CertPathBuilder.pem")), - *result.paths[result.best_result_index])) { + *result.GetBestPathPossiblyInvalid())) { return false; } }
diff --git a/net/tools/huffman_trie/BUILD.gn b/net/tools/huffman_trie/BUILD.gn index a4d1e3a..c172af0f2 100644 --- a/net/tools/huffman_trie/BUILD.gn +++ b/net/tools/huffman_trie/BUILD.gn
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -assert(current_toolchain == host_toolchain) - source_set("huffman_trie_generator_sources") { sources = [ "bit_writer.cc",
diff --git a/net/tools/huffman_trie/trie/trie_writer.cc b/net/tools/huffman_trie/trie/trie_writer.cc index 9f85f132..6dc38eb 100644 --- a/net/tools/huffman_trie/trie/trie_writer.cc +++ b/net/tools/huffman_trie/trie/trie_writer.cc
@@ -123,7 +123,7 @@ uint32_t* position) { DCHECK(start != end) << "No entries passed to WriteDispatchTables"; - huffman_trie::TrieBitBuffer writer; + TrieBitBuffer writer; std::vector<uint8_t> prefix = LongestCommonPrefix(start, end); for (size_t i = 0; i < prefix.size(); ++i) {
diff --git a/net/tools/huffman_trie/trie/trie_writer.h b/net/tools/huffman_trie/trie/trie_writer.h index 6bf3e9bedb..3c824e7 100644 --- a/net/tools/huffman_trie/trie/trie_writer.h +++ b/net/tools/huffman_trie/trie/trie_writer.h
@@ -20,8 +20,8 @@ class TrieWriter { public: - TrieWriter(const huffman_trie::HuffmanRepresentationTable& huffman_table, - huffman_trie::HuffmanBuilder* huffman_builder); + TrieWriter(const HuffmanRepresentationTable& huffman_table, + HuffmanBuilder* huffman_builder); ~TrieWriter(); // Constructs a trie containing all |entries|. The output is written to @@ -40,18 +40,25 @@ // complete. const std::vector<uint8_t>& bytes() const { return buffer_.bytes(); } + protected: + const HuffmanRepresentationTable& huffman_table() const { + return huffman_table_; + } + + HuffmanBuilder* huffman_builder() { return huffman_builder_; } + private: bool WriteDispatchTables(ReversedEntries::iterator start, ReversedEntries::iterator end, uint32_t* position); - huffman_trie::BitWriter buffer_; - const huffman_trie::HuffmanRepresentationTable& huffman_table_; - huffman_trie::HuffmanBuilder* huffman_builder_; + BitWriter buffer_; + const HuffmanRepresentationTable& huffman_table_; + HuffmanBuilder* huffman_builder_; }; } // namespace huffman_trie } // namespace net -#endif // NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRIE_TRIE_WRITER_H_ +#endif // NET_TOOLS_HUFFMAN_TRIE_TRIE_TRIE_WRITER_H_
diff --git a/net/tools/huffman_trie/trie_entry.h b/net/tools/huffman_trie/trie_entry.h index 79273ed..fe70260 100644 --- a/net/tools/huffman_trie/trie_entry.h +++ b/net/tools/huffman_trie/trie_entry.h
@@ -20,6 +20,8 @@ TrieEntry(); virtual ~TrieEntry(); + // The name to be used when inserting the entry to the trie. E.g. for HSTS + // preload list, this is the hostname. virtual std::string name() const = 0; virtual bool WriteEntry(huffman_trie::TrieBitBuffer* writer) const = 0; }; @@ -28,6 +30,8 @@ // of raw pointers instead. using TrieEntries = std::vector<TrieEntry*>; +// ReversedEntry points to a TrieEntry and contains the reversed name for +// that entry. This is used to construct the trie. struct ReversedEntry { ReversedEntry(std::vector<uint8_t> reversed_name, const TrieEntry* entry); ~ReversedEntry();
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 86ae8fb..5d72a7c 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -14,20 +14,7 @@ : signin_manager_(signin_manager), token_service_(token_service), account_tracker_service_(account_tracker_service) { - // Initialize the state of the primary account. primary_account_info_ = signin_manager_->GetAuthenticatedAccountInfo(); - - // Initialize the state of accounts with refresh tokens. - // |account_id| is moved into |accounts_with_refresh_tokens_|. - // Do not change this to "const std::string&". - for (std::string account_id : token_service->GetAccounts()) { - AccountInfo account_info = - account_tracker_service_->GetAccountInfo(account_id); - DCHECK(!account_info.IsEmpty()); - accounts_with_refresh_tokens_.emplace(std::move(account_id), - std::move(account_info)); - } - signin_manager_->AddObserver(this); #if !defined(OS_CHROMEOS) SigninManager::FromSigninManagerBase(signin_manager_) @@ -96,29 +83,6 @@ return !primary_account_info_.account_id.empty(); } -std::vector<AccountInfo> IdentityManager::GetAccountsWithRefreshTokens() { - // TODO(blundell): It seems wasteful to construct this vector every time this - // method is called, but it also seems bad to maintain the vector as an ivar - // along the map. - std::vector<AccountInfo> accounts; - accounts.reserve(accounts_with_refresh_tokens_.size()); - - for (const auto& pair : accounts_with_refresh_tokens_) { - accounts.push_back(pair.second); - } - - return accounts; -} - -bool IdentityManager::HasAccountWithRefreshToken( - const std::string& account_id) { - return base::ContainsKey(accounts_with_refresh_tokens_, account_id); -} - -bool IdentityManager::HasPrimaryAccountWithRefreshToken() { - return HasAccountWithRefreshToken(GetPrimaryAccountInfo().account_id); -} - std::unique_ptr<AccessTokenFetcher> IdentityManager::CreateAccessTokenFetcherForAccount( const std::string& account_id, @@ -233,20 +197,6 @@ AccountInfo account_info = account_tracker_service_->GetAccountInfo(account_id); DCHECK(!account_info.IsEmpty()); - - // Insert the account into |accounts_with_refresh_tokens_|. - auto insertion_result = accounts_with_refresh_tokens_.emplace( - account_id, std::move(account_info)); - - // The account might have already been present (e.g., this method can fire on - // updating an invalid token to a valid one or vice versa); in this case we - // sanity-check that the cached account info has the expected values. - if (!insertion_result.second) { - AccountInfo cached_account_info = insertion_result.first->second; - DCHECK_EQ(account_info.gaia, cached_account_info.gaia); - DCHECK_EQ(account_info.email, cached_account_info.email); - } - for (auto& observer : observer_list_) { observer.OnRefreshTokenUpdatedForAccount(account_info, is_valid); } @@ -257,11 +207,6 @@ AccountInfo account_info = account_tracker_service_->GetAccountInfo(account_id); DCHECK(!account_info.IsEmpty()); - - auto iterator = accounts_with_refresh_tokens_.find(account_id); - DCHECK(iterator != accounts_with_refresh_tokens_.end()); - accounts_with_refresh_tokens_.erase(iterator); - for (auto& observer : observer_list_) { observer.OnRefreshTokenRemovedForAccount(account_info); }
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 68aaa157..7597be4 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -120,20 +120,6 @@ // primary account info has a valid account ID. bool HasPrimaryAccount(); - // Provides access to the latest cached information of all accounts that have - // refresh tokens. - // NOTE: The accounts should not be assumed to be in any particular order; in - // particular, they are not guaranteed to be in the order in which the - // refresh tokens were added. - std::vector<AccountInfo> GetAccountsWithRefreshTokens(); - - // Returns true if a refresh token exists for |account_id|. - bool HasAccountWithRefreshToken(const std::string& account_id); - - // Returns true if (a) the primary account exists, and (b) a refresh token - // exists for the primary account. - bool HasPrimaryAccountWithRefreshToken(); - // Creates an AccessTokenFetcher given the passed-in information. std::unique_ptr<AccessTokenFetcher> CreateAccessTokenFetcherForAccount( const std::string& account_id, @@ -232,10 +218,6 @@ // The latest (cached) value of the primary account. AccountInfo primary_account_info_; - // The latest (cached) value of the accounts with refresh tokens. - using AccountIDToAccountInfoMap = std::map<std::string, AccountInfo>; - AccountIDToAccountInfoMap accounts_with_refresh_tokens_; - // Lists of observers. // Makes sure lists are empty on destruction. base::ObserverList<Observer, true> observer_list_;
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index c2c9f88..c0b490f 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -25,11 +25,8 @@ #endif // OS_CHROMEOS const char kTestGaiaId[] = "dummyId"; -const char kTestGaiaId2[] = "dummyId2"; -const char kTestGaiaId3[] = "dummyId3"; const char kTestEmail[] = "me@gmail.com"; const char kTestEmail2[] = "me2@gmail.com"; -const char kTestEmail3[] = "me3@gmail.com"; #if defined(OS_CHROMEOS) const char kTestEmailWithPeriod[] = "m.e@gmail.com"; @@ -482,395 +479,6 @@ #endif } -TEST_F(IdentityManagerTest, GetAccountsInteractionWithPrimaryAccount) { - // Should not have any refresh tokens at initialization. - EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); - - std::string account_id = signin_manager()->GetAuthenticatedAccountId(); - - // Add a refresh token for the primary account and check that it shows up in - // GetAccountsWithRefreshTokens(). - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - std::vector<AccountInfo> accounts_after_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_update.size()); - EXPECT_EQ(accounts_after_update[0].account_id, account_id); - EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId); - EXPECT_EQ(accounts_after_update[0].email, kTestEmail); - - // Update the token and check that it doesn't change the state (or blow up). - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - std::vector<AccountInfo> accounts_after_second_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_second_update.size()); - EXPECT_EQ(accounts_after_second_update[0].account_id, account_id); - EXPECT_EQ(accounts_after_second_update[0].gaia, kTestGaiaId); - EXPECT_EQ(accounts_after_second_update[0].email, kTestEmail); - - // Remove the token for the primary account and check that this is likewise - // reflected. - RemoveRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); -} - -TEST_F(IdentityManagerTest, - QueryingOfRefreshTokensInteractionWithPrimaryAccount) { - AccountInfo account_info = identity_manager()->GetPrimaryAccountInfo(); - std::string account_id = account_info.account_id; - - // Should not have a refresh token for the primary account at initialization. - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Add a refresh token for the primary account and check that it affects this - // state. - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Update the token and check that it doesn't change the state (or blow up). - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Remove the token for the primary account and check that this is likewise - // reflected. - RemoveRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); -} - -TEST_F(IdentityManagerTest, GetAccountsReflectsNonemptyInitialState) { - EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); - - std::string account_id = signin_manager()->GetAuthenticatedAccountId(); - - // Add a refresh token for the primary account and sanity-check that it shows - // up in GetAccountsWithRefreshTokens(). - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - std::vector<AccountInfo> accounts_after_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_update.size()); - EXPECT_EQ(accounts_after_update[0].account_id, account_id); - EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId); - EXPECT_EQ(accounts_after_update[0].email, kTestEmail); - - // Recreate the IdentityManager and check that the newly-created instance - // reflects the current state. - RecreateIdentityManager(); - - std::vector<AccountInfo> accounts_after_recreation = - identity_manager()->GetAccountsWithRefreshTokens(); - EXPECT_EQ(1u, accounts_after_recreation.size()); - EXPECT_EQ(accounts_after_recreation[0].account_id, account_id); - EXPECT_EQ(accounts_after_recreation[0].gaia, kTestGaiaId); - EXPECT_EQ(accounts_after_recreation[0].email, kTestEmail); -} - -TEST_F(IdentityManagerTest, - QueryingOfRefreshTokensReflectsNonemptyInitialState) { - AccountInfo account_info = identity_manager()->GetPrimaryAccountInfo(); - std::string account_id = account_info.account_id; - - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Recreate the IdentityManager and check that the newly-created instance - // reflects the current state. - RecreateIdentityManager(); - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info.account_id)); - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); -} - -TEST_F(IdentityManagerTest, GetAccountsInteractionWithSecondaryAccounts) { - // Should not have any refresh tokens at initialization. - EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); - - // Add a refresh token for a secondary account and check that it shows up in - // GetAccountsWithRefreshTokens(). - account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2); - std::string account_id2 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id; - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id2); - - std::vector<AccountInfo> accounts_after_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_update.size()); - EXPECT_EQ(accounts_after_update[0].account_id, account_id2); - EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId2); - EXPECT_EQ(accounts_after_update[0].email, kTestEmail2); - - // Add a refresh token for a different secondary account and check that it - // also shows up in GetAccountsWithRefreshTokens(). - account_tracker()->SeedAccountInfo(kTestGaiaId3, kTestEmail3); - std::string account_id3 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId3).account_id; - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id3); - - std::vector<AccountInfo> accounts_after_second_update = - identity_manager()->GetAccountsWithRefreshTokens(); - EXPECT_EQ(2u, accounts_after_second_update.size()); - - for (AccountInfo account_info : accounts_after_second_update) { - if (account_info.account_id == account_id2) { - EXPECT_EQ(account_info.gaia, kTestGaiaId2); - EXPECT_EQ(account_info.email, kTestEmail2); - } else { - EXPECT_EQ(account_info.gaia, kTestGaiaId3); - EXPECT_EQ(account_info.email, kTestEmail3); - } - } - - // Remove the token for account2 and check that account3 is still present. - RemoveRefreshTokenForAccount(token_service(), identity_manager(), - account_id2); - - std::vector<AccountInfo> accounts_after_third_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_third_update.size()); - EXPECT_EQ(accounts_after_third_update[0].account_id, account_id3); - EXPECT_EQ(accounts_after_third_update[0].gaia, kTestGaiaId3); - EXPECT_EQ(accounts_after_third_update[0].email, kTestEmail3); -} - -TEST_F(IdentityManagerTest, - HasPrimaryAccountWithRefreshTokenInteractionWithSecondaryAccounts) { - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Adding a refresh token for a secondary account shouldn't change anything - // about the primary account - account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2); - std::string account_id2 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id; - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id2); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Adding a refresh token for a different secondary account should not do so - // either. - account_tracker()->SeedAccountInfo(kTestGaiaId3, kTestEmail3); - std::string account_id3 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId3).account_id; - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id3); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Removing the token for account2 should have no effect. - RemoveRefreshTokenForAccount(token_service(), identity_manager(), - account_id2); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); -} - -TEST_F(IdentityManagerTest, - HasAccountWithRefreshTokenInteractionWithSecondaryAccounts) { - account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2); - AccountInfo account_info2 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2); - std::string account_id2 = account_info2.account_id; - - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - - // Add a refresh token for account_info2 and check that this is reflected by - // HasAccountWithRefreshToken(.account_id). - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id2); - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - - // Go through the same process for a different secondary account. - account_tracker()->SeedAccountInfo(kTestGaiaId3, kTestEmail3); - AccountInfo account_info3 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId3); - std::string account_id3 = account_info3.account_id; - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info3.account_id)); - - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id3); - - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info3.account_id)); - - // Remove the token for account2. - RemoveRefreshTokenForAccount(token_service(), identity_manager(), - account_id2); - - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info3.account_id)); -} - -TEST_F(IdentityManagerTest, - GetAccountsInteractionBetweenPrimaryAndSecondaryAccounts) { - // Should not have any refresh tokens at initialization. - EXPECT_TRUE(identity_manager()->GetAccountsWithRefreshTokens().empty()); - - // Add a refresh token for a secondary account and check that it shows up in - // GetAccountsWithRefreshTokens(). - account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2); - std::string account_id2 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id; - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id2); - - std::vector<AccountInfo> accounts_after_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_update.size()); - EXPECT_EQ(accounts_after_update[0].account_id, account_id2); - EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId2); - EXPECT_EQ(accounts_after_update[0].email, kTestEmail2); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Add a refresh token for the primary account and check that it - // also shows up in GetAccountsWithRefreshTokens(). - std::string primary_account_id = - signin_manager()->GetAuthenticatedAccountId(); - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - std::vector<AccountInfo> accounts_after_second_update = - identity_manager()->GetAccountsWithRefreshTokens(); - EXPECT_EQ(2u, accounts_after_second_update.size()); - - for (AccountInfo account_info : accounts_after_second_update) { - if (account_info.account_id == account_id2) { - EXPECT_EQ(account_info.gaia, kTestGaiaId2); - EXPECT_EQ(account_info.email, kTestEmail2); - } else { - EXPECT_EQ(account_info.gaia, kTestGaiaId); - EXPECT_EQ(account_info.email, kTestEmail); - } - } - - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Remove the token for the primary account and check that account2 is still - // present. - RemoveRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - std::vector<AccountInfo> accounts_after_third_update = - identity_manager()->GetAccountsWithRefreshTokens(); - - EXPECT_EQ(1u, accounts_after_third_update.size()); - EXPECT_EQ(accounts_after_update[0].account_id, account_id2); - EXPECT_EQ(accounts_after_update[0].gaia, kTestGaiaId2); - EXPECT_EQ(accounts_after_update[0].email, kTestEmail2); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); -} - -TEST_F( - IdentityManagerTest, - HasPrimaryAccountWithRefreshTokenInteractionBetweenPrimaryAndSecondaryAccounts) { - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Add a refresh token for a secondary account and check that it doesn't - // impact the above state. - account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2); - std::string account_id2 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id; - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id2); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Add a refresh token for the primary account and check that it - // *does* impact the stsate of HasPrimaryAccountWithRefreshToken(). - std::string primary_account_id = - signin_manager()->GetAuthenticatedAccountId(); - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Remove the token for the secondary account and check that this doesn't flip - // the state. - RemoveRefreshTokenForAccount(token_service(), identity_manager(), - account_id2); - - EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken()); - - // Remove the token for the primary account and check that this flips the - // state. - RemoveRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken()); -} - -TEST_F( - IdentityManagerTest, - HasAccountWithRefreshTokenInteractionBetweenPrimaryAndSecondaryAccounts) { - AccountInfo primary_account_info = - identity_manager()->GetPrimaryAccountInfo(); - std::string primary_account_id = primary_account_info.account_id; - - account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2); - AccountInfo account_info2 = - account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2); - std::string account_id2 = account_info2.account_id; - - EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken( - primary_account_info.account_id)); - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - - // Add a refresh token for account_info2 and check that this is reflected by - // HasAccountWithRefreshToken(.account_id). - SetRefreshTokenForAccount(token_service(), identity_manager(), account_id2); - - EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken( - primary_account_info.account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - - // Go through the same process for the primary account. - SetRefreshTokenForPrimaryAccount(token_service(), identity_manager()); - - EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( - primary_account_info.account_id)); - EXPECT_TRUE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); - - // Remove the token for account2. - RemoveRefreshTokenForAccount(token_service(), identity_manager(), - account_id2); - - EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken( - primary_account_info.account_id)); - EXPECT_FALSE( - identity_manager()->HasAccountWithRefreshToken(account_info2.account_id)); -} - TEST_F(IdentityManagerTest, RemoveAccessTokenFromCache) { std::set<std::string> scopes{"scope"}; std::string access_token = "access_token";
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 51d7ca5..aa8029e0 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -486,13 +486,11 @@ // TransferableResource constants. const uint32_t tr_id = 1337; const ResourceFormat tr_format = ALPHA_8; - const gfx::BufferFormat tr_buffer_format = gfx::BufferFormat::R_8; const uint32_t tr_filter = 1234; const gfx::Size tr_size(1234, 5678); TransferableResource resource; resource.id = tr_id; resource.format = tr_format; - resource.buffer_format = tr_buffer_format; resource.filter = tr_filter; resource.size = tr_size; @@ -528,7 +526,6 @@ TransferableResource out_resource = output.resource_list[0]; EXPECT_EQ(tr_id, out_resource.id); EXPECT_EQ(tr_format, out_resource.format); - EXPECT_EQ(tr_buffer_format, out_resource.buffer_format); EXPECT_EQ(tr_filter, out_resource.filter); EXPECT_EQ(tr_size, out_resource.size);
diff --git a/services/viz/public/cpp/compositing/transferable_resource_struct_traits.cc b/services/viz/public/cpp/compositing/transferable_resource_struct_traits.cc index df773cf..623889d1 100644 --- a/services/viz/public/cpp/compositing/transferable_resource_struct_traits.cc +++ b/services/viz/public/cpp/compositing/transferable_resource_struct_traits.cc
@@ -25,7 +25,6 @@ return false; out->id = data.id(); out->format = static_cast<viz::ResourceFormat>(data.format()); - out->buffer_format = static_cast<gfx::BufferFormat>(data.buffer_format()); out->filter = data.filter(); out->read_lock_fences_enabled = data.read_lock_fences_enabled(); out->is_software = data.is_software();
diff --git a/services/viz/public/cpp/compositing/transferable_resource_struct_traits.h b/services/viz/public/cpp/compositing/transferable_resource_struct_traits.h index 9f7b390..57238e81 100644 --- a/services/viz/public/cpp/compositing/transferable_resource_struct_traits.h +++ b/services/viz/public/cpp/compositing/transferable_resource_struct_traits.h
@@ -24,11 +24,6 @@ return static_cast<viz::mojom::ResourceFormat>(resource.format); } - static gfx::mojom::BufferFormat buffer_format( - const viz::TransferableResource& resource) { - return static_cast<gfx::mojom::BufferFormat>(resource.buffer_format); - } - static uint32_t filter(const viz::TransferableResource& resource) { return resource.filter; }
diff --git a/services/viz/public/interfaces/compositing/transferable_resource.mojom b/services/viz/public/interfaces/compositing/transferable_resource.mojom index e2aed0f..015f3d1 100644 --- a/services/viz/public/interfaces/compositing/transferable_resource.mojom +++ b/services/viz/public/interfaces/compositing/transferable_resource.mojom
@@ -17,18 +17,26 @@ ALPHA_8, LUMINANCE_8, RGB_565, + BGR_565, ETC1, RED_8, + RG_88, LUMINANCE_F16, RGBA_F16, R16_EXT, + RGBX_8888, + BGRX_8888, + RGBX_1010102, + BGRX_1010102, + YVU_420, + YUV_420_BIPLANAR, + UYVY_422, }; // See components/viz/common/resources/transferable_resource.h. struct TransferableResource { uint32 id; ResourceFormat format; - gfx.mojom.BufferFormat buffer_format; uint32 filter; gfx.mojom.Size size; gpu.mojom.MailboxHolder mailbox_holder;
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index b9c58ec..4ffa1673 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -3254,6 +3254,7 @@ "--browser=cros-chrome", "--remote=127.0.0.1", "--remote-ssh-port=9222", + "--skip=telemetry.core.tracing_controller_unittest.TracingControllerTest.testBattOrTracing", "--skip=telemetry.internal.app.android_app_unittest.AndroidAppTest.testWebView" ], "isolate_name": "telemetry_unittests",
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index cdbd3ee..ddeb9fc 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -3294,6 +3294,7 @@ "dimension_sets": [ { "gpu": "none", + "os": "Mac-10.13", "pool": "Chrome-quarantine" } ], @@ -3306,7 +3307,12 @@ "--disable-features=ViewsBrowserWindows" ], "swarming": { - "can_use_on_swarming_builders": true + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Mac-10.13" + } + ] }, "test": "components_browsertests" }, @@ -3315,7 +3321,12 @@ "--disable-features=ViewsBrowserWindows" ], "swarming": { - "can_use_on_swarming_builders": true + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Mac-10.13" + } + ] }, "test": "content_browsertests" }, @@ -3325,6 +3336,11 @@ ], "swarming": { "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Mac-10.13" + } + ], "shards": 3 }, "test": "interactive_ui_tests"
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index bd03915..b51d196 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -562,7 +562,7 @@ { "gpu": "8086:0a2e", "os": "Mac-10.12", - "pool": "Chrome-perf-fyi" + "pool": "chrome.tests.perf-fyi" } ], "expiration": 36000, @@ -606,7 +606,7 @@ { "gpu": "8086:0a2e", "os": "Mac-10.12", - "pool": "Chrome-perf-fyi" + "pool": "chrome.tests.perf-fyi" } ], "expiration": 36000, @@ -647,7 +647,7 @@ { "gpu": "8086:0a2e", "os": "Mac-10.12", - "pool": "Chrome-perf-fyi" + "pool": "chrome.tests.perf-fyi" } ], "expiration": 36000,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index e18c874a..7bec85fc 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -410,6 +410,9 @@ # By default, CrOS VMs' ssh servers listen on local port 9222. '--remote=127.0.0.1', '--remote-ssh-port=9222', + # Flaky. + '--skip=telemetry.core.tracing_controller_unittest.TracingControllerTest.testBattOrTracing', + # Always fails. '--skip=telemetry.internal.app.android_app_unittest.AndroidAppTest.testWebView', ], 'swarming': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 3574b6f..e831d28 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2881,6 +2881,13 @@ ], }, 'mac-cocoa-rel': { + 'swarming': { + 'dimension_sets': [ + { + 'os': 'Mac-10.13', + }, + ], + }, 'test_suites': { 'gtest_tests': 'chromium_browser_tests', },
diff --git a/testing/scripts/common.py b/testing/scripts/common.py index 28758fe..786e98f 100644 --- a/testing/scripts/common.py +++ b/testing/scripts/common.py
@@ -167,6 +167,24 @@ def get_gtest_summary_passes(output): """Returns a mapping of test to boolean indicating if the test passed. + """ + if not output: + return {} + + mapping = {} + + for test_suite in output.get('testsuites', []): + suite_name = test_suite['name'] + for test in test_suite['testsuite']: + full_name = '%s.%s' % (suite_name, test['name']) + + mapping[full_name] = 'failures' in test + + return mapping + + +def get_chromium_gtest_summary_passes(output): + """Returns a mapping of test to boolean indicating if the test passed. Only partially parses the format. This code is based on code in tools/build, specifically
diff --git a/testing/scripts/run_gtest_perf_test.py b/testing/scripts/run_gtest_perf_test.py index 83198f5c..e1dd0d5 100755 --- a/testing/scripts/run_gtest_perf_test.py +++ b/testing/scripts/run_gtest_perf_test.py
@@ -32,6 +32,7 @@ import os import shutil import sys +import time import tempfile import traceback @@ -82,7 +83,7 @@ args, rest_args = parser.parse_known_args() - rc, charts, output_json = execute_perf_test(args, rest_args) + rc, charts, output_json = execute_perf_test(args, rest_args, True) # TODO(eakuefner): Make isolated_script_test_perf_output mandatory after # flipping flag in swarming. @@ -100,7 +101,7 @@ return rc -def execute_perf_test(args, rest_args): +def execute_perf_test(args, rest_args, chromium_gtest): env = os.environ.copy() # Assume we want to set up the sandbox environment variables all the # time; doing so is harmless on non-Linux platforms and is needed @@ -108,53 +109,95 @@ env[CHROME_SANDBOX_ENV] = CHROME_SANDBOX_PATH rc = 0 - try: - executable = rest_args[0] - extra_flags = [] - if len(rest_args) > 1: - extra_flags = rest_args[1:] + start_time = time.time() + test_results = {} + with common.temporary_file() as results_path: + try: + executable = rest_args[0] + extra_flags = [] + if len(rest_args) > 1: + extra_flags = rest_args[1:] - # These flags are to make sure that test output perf metrics in the log. - if not '--verbose' in extra_flags: - extra_flags.append('--verbose') - if not '--test-launcher-print-test-stdio=always' in extra_flags: - extra_flags.append('--test-launcher-print-test-stdio=always') - if args.isolated_script_test_filter: - filter_list = common.extract_filter_list( - args.isolated_script_test_filter) - extra_flags.append('--gtest_filter=' + ':'.join(filter_list)) - - if IsWindows(): - executable = '.\%s.exe' % executable - else: - executable = './%s' % executable - with common.temporary_file() as tempfile_path: - env['CHROME_HEADLESS'] = '1' - cmd = [executable] + extra_flags - - if args.xvfb: - rc = xvfb.run_executable(cmd, env, stdoutfile=tempfile_path) + if chromium_gtest: + output_flag = '--test-launcher-summary-output' + output_file = results_path else: - rc = test_env.run_command_with_output(cmd, env=env, - stdoutfile=tempfile_path) + output_flag = '--gtest_output' + output_file = 'json:%s' % results_path - # Now get the correct json format from the stdout to write to the perf - # results file - results_processor = ( - generate_legacy_perf_dashboard_json.LegacyResultsProcessor()) - charts = results_processor.GenerateJsonResults(tempfile_path) - except Exception: - traceback.print_exc() - rc = 1 + assert not any(output_flag in flag for flag in extra_flags), ( + 'Duplicate %s flag detected.' % output_flag) + extra_flags.append('%s=%s' % (output_flag, output_file)) - valid = (rc == 0) - failures = [] if valid else ['(entire test suite)'] + # These flags are to make sure that test output perf metrics in the log. + if not '--verbose' in extra_flags: + extra_flags.append('--verbose') + if not '--test-launcher-print-test-stdio=always' in extra_flags: + extra_flags.append('--test-launcher-print-test-stdio=always') + if args.isolated_script_test_filter: + filter_list = common.extract_filter_list( + args.isolated_script_test_filter) + extra_flags.append('--gtest_filter=' + ':'.join(filter_list)) + + if IsWindows(): + executable = '.\%s.exe' % executable + else: + executable = './%s' % executable + with common.temporary_file() as tempfile_path: + env['CHROME_HEADLESS'] = '1' + cmd = [executable] + extra_flags + + print ' '.join(cmd) + if args.xvfb: + rc = xvfb.run_executable(cmd, env, stdoutfile=tempfile_path) + else: + rc = test_env.run_command_with_output(cmd, env=env, + stdoutfile=tempfile_path) + + # Now get the correct json format from the stdout to write to the perf + # results file + results_processor = ( + generate_legacy_perf_dashboard_json.LegacyResultsProcessor()) + charts = results_processor.GenerateJsonResults(tempfile_path) + except Exception: + traceback.print_exc() + rc = 1 + + if os.path.exists(results_path): + with open(results_path) as f: + if chromium_gtest: + func = common.get_chromium_gtest_summary_passes + else: + func = common.get_gtest_summary_passes + test_results = func(json.load(f)) + output_json = { - 'valid': valid, - 'failures': failures, + 'version': 3, + 'interrupted': False, + 'path_delimiter': '/', + 'seconds_since_epoch': start_time, + 'num_failures_by_type': { + 'PASS': sum(1 for success in test_results.values() if success), + 'FAIL': sum(1 for success in test_results.values() if not success), + }, + 'tests': { + test: test_result_entry(success) for ( + test, success) in test_results.items() } + } + return rc, charts, output_json + +def test_result_entry(success): + test = { + 'expected': 'PASS', + 'actual': 'PASS' if success else 'FAIL', + } + if not success: + test['unexpected'] = True + return test + # This is not really a "script test" so does not need to manually add # any additional compile targets. def main_compile_targets(args):
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index a491fcd..aab7c26 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -197,7 +197,7 @@ # For non telemetry tests the benchmark name is the name of the executable. benchmark_name = rest_args[0] return_code, charts, output_json = run_gtest_perf_test.execute_perf_test( - args, rest_args) + args, rest_args, False) write_results(benchmark_name, charts, output_json, benchmark_log='Not available for C++ perf test',
diff --git a/third_party/.gitignore b/third_party/.gitignore index 07047b1..fe30811e 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -176,6 +176,7 @@ /python_26 /pywebsocket/src /pywebsocket/src +/quic_trace/src /r8/lib /re2/src /requests/src
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index f49e56ff..54a55e0 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -17,9 +17,6 @@ crbug.com/854889 accessibility/css-generated-content.html [ Failure ] crbug.com/854889 accessibility/css-styles.html [ Failure ] -# Hit test failure due to vertical-rl writing mode -crbug.com/851075 fast/writing-mode/vertical-inline-block-hittest.html [ Failure ] - # Wrong image alignment in vertical-rl writing mode crbug.com/636993 fast/writing-mode/vertical-baseline-alignment.html [ Failure ] @@ -111,6 +108,7 @@ crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-in-inline-remove-006.xht [ Pass ] crbug.com/591099 external/wpt/css/CSS2/text/white-space-mixed-003.xht [ Pass ] crbug.com/591099 external/wpt/css/css-backgrounds/box-shadow-syntax-001.xht [ Failure ] +crbug.com/859233 external/wpt/css/css-break/hit-test-inline-fragmentation-with-border-radius.html [ Failure ] crbug.com/591099 external/wpt/css/css-contain/contain-paint-007.html [ Pass ] crbug.com/591099 external/wpt/css/css-filter/filtered-inline-is-container.html [ Crash ] crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-1.html [ Pass ] @@ -304,7 +302,6 @@ crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html [ Failure ] crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html [ Failure ] -crbug.com/591099 external/wpt/html/semantics/interactive-elements/the-dialog-element/centering.html [ Crash ] crbug.com/591099 external/wpt/payment-handler/can-make-payment-event-constructor.https.worker.html [ Pass ] crbug.com/591099 external/wpt/payment-request/payment-allowed-by-feature-policy.https.sub.html [ Pass ] crbug.com/591099 external/wpt/payment-request/payment-disabled-by-feature-policy.https.sub.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees index 2e6544b..214fa76 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -406,6 +406,12 @@ Bug(none) compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped.html [ Failure ] Bug(none) compositing/overflow/siblings-with-border-radius-ancestor.html [ Failure ] Bug(none) compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ Crash Failure ] +Bug(none) fast/borders/border-radius-mask-canvas-border.html [ Failure ] +Bug(none) fast/borders/border-radius-mask-canvas-with-mask.html [ Failure ] +Bug(none) fast/borders/border-radius-mask-canvas.html [ Failure ] +Bug(none) fast/borders/border-radius-mask-video-ratio.html [ Failure ] +Bug(none) fast/borders/border-radius-mask-video-shadow.html [ Failure ] +Bug(none) fast/borders/border-radius-mask-video.html [ Failure ] Bug(none) fast/clip/overflow-border-radius-composited-parent.html [ Failure ] Bug(none) fast/clip/overflow-border-radius-composited.html [ Failure ] @@ -471,18 +477,6 @@ # Something wrong with vertical-rl scrollbars crbug.com/853945 fast/block/positioning/vertical-rl/002.html [ Failure ] -# Border radius mask wrong. -crbug.com/853943 fast/borders/border-radius-mask-canvas-all.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-canvas-border.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-canvas-padding.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-canvas-with-mask.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-canvas-with-shadow.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-canvas.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-video-ratio.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-video-shadow.html [ Failure ] -crbug.com/853943 fast/borders/border-radius-mask-video.html [ Failure ] -crbug.com/853943 fast/borders/overflow-hidden-border-radius-force-backing-store.html [ Failure ] - # Something with the pattern is wrong. Needs investigation. crbug.com/853947 fast/canvas/synchronous-create-pattern.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 41e1da4..4a9dffa 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -285,6 +285,9 @@ crbug.com/591099 external/wpt/css/css-sizing/intrinsic-percent-non-replaced-004.html [ Failure ] crbug.com/591099 external/wpt/css/css-sizing/intrinsic-percent-non-replaced-005.html [ Failure ] +# Currently also fails in LayoutNG and to be fixed there +crbug.com/859233 external/wpt/css/css-break/hit-test-inline-fragmentation-with-border-radius.html [ Failure ] + ### virtual/layout_ng/external/wpt/css/CSS2/floats crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht [ Failure ] crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule3-outside-right-002.xht [ Failure ] @@ -475,7 +478,6 @@ crbug.com/714962 [ Mac Win ] virtual/layout_ng/fast/writing-mode/english-lr-text.html [ Failure ] crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/japanese-rl-text.html [ Failure ] crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/text-orientation-basic.html [ Failure ] -crbug.com/851075 virtual/layout_ng/fast/writing-mode/vertical-inline-block-hittest.html [ Failure ] # Crashes/asserts due to inline item reuse. crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-after-spanner.html [ Failure Crash Timeout ] @@ -2799,6 +2801,8 @@ crbug.com/849859 external/wpt/web-animations/timing-model/animations/pausing-an-animation.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/css-scoping/host-specificity-002.html [ Failure ] +crbug.com/626703 external/wpt/css/css-scoping/slotted-specificity.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/white-space/break-spaces-001.html [ Failure ] crbug.com/626703 external/wpt/html/editing/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-negative.html [ Timeout ] crbug.com/626703 [ Mac10.12 Mac10.13 ] external/wpt/compat/webkit-text-fill-color-property-002.html [ Failure ] @@ -4736,3 +4740,6 @@ crbug.com/859064 [ Linux Win10 Mac10.13 ] http/tests/devtools/console-resource-errors.js [ Failure ] crbug.com/859169 [ Win7 ] http/tests/devtools/layers/layer-scroll-rects-get.js [ Failure Pass ] crbug.com/859270 [ Mac10.12 ] external/wpt/gyroscope/Gyroscope-iframe-access.https.html [ Timeout ] + +# Sheriff 2018-07-02 +crbug.com/859605 [ Mac10.10 ] external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-002.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 84d1894d..8189255 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -52537,6 +52537,30 @@ {} ] ], + "css/css-scoping/host-specificity-002.html": [ + [ + "/css/css-scoping/host-specificity-002.html", + [ + [ + "/css/css-scoping/reference/green-box.html", + "==" + ] + ], + {} + ] + ], + "css/css-scoping/host-specificity.html": [ + [ + "/css/css-scoping/host-specificity.html", + [ + [ + "/css/css-scoping/reference/green-box.html", + "==" + ] + ], + {} + ] + ], "css/css-scoping/shadow-assign-dynamic-001.html": [ [ "/css/css-scoping/shadow-assign-dynamic-001.html", @@ -52729,6 +52753,18 @@ {} ] ], + "css/css-scoping/slotted-specificity.html": [ + [ + "/css/css-scoping/slotted-specificity.html", + [ + [ + "/css/css-scoping/reference/green-box.html", + "==" + ] + ], + {} + ] + ], "css/css-scoping/slotted-with-pseudo-element.html": [ [ "/css/css-scoping/slotted-with-pseudo-element.html", @@ -111634,6 +111670,11 @@ {} ] ], + "css/css-color/parsing/resources/parsing-testcommon.js": [ + [ + {} + ] + ], "css/css-color/rebeccapurple-ref.html": [ [ {} @@ -188506,6 +188547,12 @@ {} ] ], + "css/css-break/hit-test-inline-fragmentation-with-border-radius.html": [ + [ + "/css/css-break/hit-test-inline-fragmentation-with-border-radius.html", + {} + ] + ], "css/css-cascade/all-prop-initial-xml.html": [ [ "/css/css-cascade/all-prop-initial-xml.html", @@ -188556,6 +188603,30 @@ {} ] ], + "css/css-color/parsing/color-invalid.html": [ + [ + "/css/css-color/parsing/color-invalid.html", + {} + ] + ], + "css/css-color/parsing/color-valid.html": [ + [ + "/css/css-color/parsing/color-valid.html", + {} + ] + ], + "css/css-color/parsing/opacity-invalid.html": [ + [ + "/css/css-color/parsing/opacity-invalid.html", + {} + ] + ], + "css/css-color/parsing/opacity-valid.html": [ + [ + "/css/css-color/parsing/opacity-valid.html", + {} + ] + ], "css/css-color/rgb-rounding-001.html": [ [ "/css/css-color/rgb-rounding-001.html", @@ -296781,6 +296852,10 @@ "926ed3f96ba7b5c6dee79ea417746cbd60342579", "visual" ], + "css/css-break/hit-test-inline-fragmentation-with-border-radius.html": [ + "d0b63d150a77ee6e84c05110fb97cc2befa0e251", + "testharness" + ], "css/css-cascade/META.yml": [ "d1a7ec7e6b46b861cff2ce11a7f793635a81a0c6", "support" @@ -297101,6 +297176,26 @@ "fad454c9b86d70e19fb89265c8e131ff381ed2a0", "reftest" ], + "css/css-color/parsing/color-invalid.html": [ + "a716957996b6441d1bba1d6d4fa636d4368f68c5", + "testharness" + ], + "css/css-color/parsing/color-valid.html": [ + "462c103850d5880ccecdf4e7a79ac55d28380bf0", + "testharness" + ], + "css/css-color/parsing/opacity-invalid.html": [ + "7ba8ffc6bbb4c27d43e9e6a11edbe52f8ca21613", + "testharness" + ], + "css/css-color/parsing/opacity-valid.html": [ + "edf3b52c29261dd0d4993f076ddd01dbe7edb805", + "testharness" + ], + "css/css-color/parsing/resources/parsing-testcommon.js": [ + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", + "support" + ], "css/css-color/rebeccapurple-ref.html": [ "e089e2daad5e5db7131015bf45739e64050c6b36", "support" @@ -315869,6 +315964,14 @@ "918bd04b95a276c6035383f2fe4dcfe4274bceeb", "reftest" ], + "css/css-scoping/host-specificity-002.html": [ + "0ac361f08fa020664457c457c8c0de308f4f1b68", + "reftest" + ], + "css/css-scoping/host-specificity.html": [ + "011fe73fba24b6046d73c64b3e99d8cd46501385", + "reftest" + ], "css/css-scoping/keyframes-001.html": [ "1b72da32df7b17edbd42429d2dc8b791b9f49eff", "testharness" @@ -315973,6 +316076,10 @@ "263bcbe53e7703a2ea0a7ffae8f9ec4fcb10c7d2", "testharness" ], + "css/css-scoping/slotted-specificity.html": [ + "db5d7abd272e8ee2270876ab8cba5d86390dec34", + "reftest" + ], "css/css-scoping/slotted-with-pseudo-element-ref.html": [ "48561a3dff973b7ad1bfa9702461e50fd4a67c2d", "support" @@ -371942,11 +372049,11 @@ "support" ], "html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt": [ - "4283a063a51cfb5bbb02028a79be1df50e704852", + "b347c3e1d9ed6a9902ea1d4cd2a7e024777fe8a0", "support" ], "html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html": [ - "3328350068373e6ad5cfd06f1180468ea4dccfb8", + "be7fd0cc365f59413abfd57287675596c8124f80", "testharness" ], "html/semantics/scripting-1/the-script-element/module/import-something-namespace.js": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.sub.https.html similarity index 97% rename from third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html rename to third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.sub.https.html index 78c7ad0e..43c1fb12 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.sub.https.html
@@ -16,7 +16,7 @@ // of client hints it receives in the request headers. promise_test(t => { - return fetch("https://{{domains[]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py", {"mode": "no-cors"}).then(r => { + return fetch("https://{{domains[]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py").then(r => { assert_equals(r.status, 200) // Verify that the browser includes client hints in the headers for a // same-origin fetch.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html.headers b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.sub.https.html.headers similarity index 100% rename from third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html.headers rename to third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.sub.https.html.headers
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html new file mode 100644 index 0000000..2bdced2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.http.html
@@ -0,0 +1,35 @@ +<html> +<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect"> +<title>Accept-CH http-equiv insecure transport test</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> + +// Even though this HTML file contains "Accept-CH" http-equiv headers, the +// browser should NOT attach the specified client hints in the HTTP request +// headers since the page is being fetched over an insecure transport. +// Test this functionality by fetching an XHR from this page hosted on +// an insecure HTTP server. + +// echo_client_hints_received.py sets the response headers depending on the set +// of client hints it receives in the request headers. + +promise_test(t => { + return fetch("/client-hints/echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser does not include client hints in the headers + // when fetching the XHR from an insecure HTTP server. + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + assert_false(r.headers.has("dpr-received"), "dpr-received"); + assert_false(r.headers.has("viewport-width-received"), "viewport-width-received"); + assert_false(r.headers.has("rtt-received"), "rtt-received"); + assert_false(r.headers.has("downlink-received"), "downlink-received"); + assert_false(r.headers.has("ect-received"), "ect-received"); + }); +}, "Accept-CH http-equiv test over insecure transport"); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html new file mode 100644 index 0000000..3e4d638 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.https.html
@@ -0,0 +1,49 @@ +<html> +<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect"> +<title>Accept-CH http-equiv cross-navigation test</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div id=test> + <p>Apart from this webpage, the test opens another html web page. One test + is run in this web page, and another in the second web page. +</div> + +<script> + +// This test contains accept-ch http-equiv header. Due to the missing +// Accept-CH-Lifetime header, the user-agent should not persist origin +// preferences for the client hints specified in Accept-CH header. + +// Next, to verify that the origin preferences were not persisted by the user +// agent, this test fetches resources/do_not_expect_client_hints_headers.html +// in a new window. Fetching of +// resources/do_not_expect_client_hints_headers.html +// verifies that the user agent does not send the client hints in the request +// headers. + +// Test is marked as tentative until https://github.com/whatwg/fetch/issues/726 +// is resolved. +promise_test(t => { + return fetch("echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser includes client hints in the request + // headers when fetching echo_client_hints_received.py within this page. + assert_true(r.headers.has("device-memory-received"), "device-memory-received"); + }); +}, "Test that the browser attaches client hints on subresources in the same navigation"); + +// Verify that the browser does not attach client hints on resources in a +// different navigation. This verifies that the client hint preferences were +// not persisted for the origin. +window.open("resources/do_not_expect_client_hints_headers.html"); +async_test(t => { +window.addEventListener('message', function(event) { + t.done(); +}) +}, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html similarity index 78% copy from third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html copy to third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html index 78c7ad0e..459b00e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.sub.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch.tentative.sub.https.html
@@ -1,22 +1,23 @@ <html> +<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width, Device-Memory, rtt, downlink, ect"> +<title>Accept-CH http-equiv same-origin and cross-origin test</title> <body> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script> -// If the response for the HTML file contains "Accept-CH" in the response -// headers, then the browser should attach the specified client hints in the -// HTTP request headers depending on whether the resource is being fetched from +// Since this HTML file contains "Accept-CH" http-equiv headers the browser +// should attach the specified client hints in the HTTP request headers +// depending on whether the resource is being fetched from // the same origin or a different origin. Test this functionality by fetching -// same-origin and cross-origin resources from this page. The response headers -// for this page include "Accept-CH: device-memory, dpr, viewport-width, rtt, downlink, ect". +// same-origin and cross-origin resources from this page. // // echo_client_hints_received.py sets the response headers depending on the set // of client hints it receives in the request headers. promise_test(t => { - return fetch("https://{{domains[]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py", {"mode": "no-cors"}).then(r => { + return fetch("https://{{domains[]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py").then(r => { assert_equals(r.status, 200) // Verify that the browser includes client hints in the headers for a // same-origin fetch. @@ -38,7 +39,7 @@ assert_in_array(r.headers.get("ect-received"), ["slow-2g", "2g", "3g", "4g"], 'ect-received is unexpected'); }); -}, "Accept-CH header test"); +}, "Same origin Accept-CH http-equiv test"); promise_test(t => { return fetch("https://{{domains[www]}}:{{ports[https][0]}}/client-hints/echo_client_hints_received.py").then(r => { @@ -52,11 +53,10 @@ assert_false(r.headers.has("downlink-received"), "downlink-received"); assert_false(r.headers.has("ect-received"), "ect-received"); }); -}, "Cross-Origin Accept-CH header test"); +}, "Cross-Origin Accept-CH http-equiv test"); </script> - </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_malformed_header.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_malformed_header.tentative.https.html new file mode 100644 index 0000000..dd516a9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_malformed_header.tentative.https.html
@@ -0,0 +1,28 @@ +<html> +<meta http-equiv="Accept-CH" content="DPR Width"> +<title>Accept-CH malformed http-equiv test</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> + +promise_test(t => { + return fetch("/client-hints/echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser does not include client hints in the headers + // since Accept-CH value in http-equiv is malformed (includes whitespace + // between attributes instead of comma). + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + assert_false(r.headers.has("dpr-received"), "dpr-received"); + assert_false(r.headers.has("viewport-width-received"), "viewport-width-received"); + assert_false(r.headers.has("rtt-received"), "rtt-received"); + assert_false(r.headers.has("downlink-received"), "downlink-received"); + assert_false(r.headers.has("ect-received"), "ect-received"); + }); +}, "Accept-CH malformed http-equiv test"); + +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-break/hit-test-inline-fragmentation-with-border-radius.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-break/hit-test-inline-fragmentation-with-border-radius.html new file mode 100644 index 0000000..b0610b1a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-break/hit-test-inline-fragmentation-with-border-radius.html
@@ -0,0 +1,268 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#break-decoration"/> +<style> +div { + margin: 20px; +} + +span.round { + padding: 20px; + line-height: 100px; + font-size: 40px; + border-radius: 40px; + background-color: yellow; +} +</style> + +<div> +<span id="horizontal" class="round">FOO<br>BAR</span> +</div> + +<div style="writing-mode:vertical-lr"> +<span id="vertical-lr" class="round">FOO<br>BAR</span> +</div> + +<div style="writing-mode:vertical-rl"> +<span id="vertical-rl" class="round">FOO<br>BAR</span> +</div> + +<script> +// Hit test horizontal span with border radius +const horizontalSpan = document.getElementById('horizontal'); +const horizontalDiv = horizontalSpan.parentNode; +const horizontalRects = horizontalSpan.getClientRects(); +const horizontalLine1 = horizontalRects[0]; +const horizontalLine2 = horizontalRects[1]; + +test(() => { + const x = horizontalLine1.left + 1; + const y = horizontalLine1.top + 1; + assert_equals(document.elementFromPoint(x, y), horizontalDiv); +}, 'Horizontal line 1, hit test outside top-left rounded corner'); + +test(() => { + const x = horizontalLine1.left + 20; + const y = horizontalLine1.top + 20; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 1, hit test inside top-left rounded corner'); + +test(() => { + const x = horizontalLine1.left + 1; + const y = horizontalLine1.bottom - 1; + assert_equals(document.elementFromPoint(x, y), horizontalDiv); +}, 'Horizontal line 1, hit test outside bottom-left rounded corner'); + +test(() => { + const x = horizontalLine1.left + 20; + const y = horizontalLine1.bottom - 20; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 1, hit test inside bottom-left rounded corner'); + +test(() => { + const x = horizontalLine1.right - 1; + const y = horizontalLine1.top + 1; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 1, hit test inside top-right right-angled corner') + +test(() => { + const x = horizontalLine1.right - 1; + const y = horizontalLine1.bottom - 1; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 1, hit test inside bottom-right right-angled corner') + +test(() => { + const x = horizontalLine2.right - 1; + const y = horizontalLine2.top + 1; + assert_equals(document.elementFromPoint(x, y), horizontalDiv); +}, 'Horizontal line 2, hit test outside top-right rounded corner'); + +test(() => { + const x = horizontalLine2.right - 20; + const y = horizontalLine2.top + 20; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 2, hit test inside top-right rounded corner'); + +test(() => { + const x = horizontalLine2.right - 1; + const y = horizontalLine2.bottom - 1; + assert_equals(document.elementFromPoint(x, y), horizontalDiv); +}, 'Horizontal line 2, hit test outside bottom-right rounded corner'); + +test(() => { + const x = horizontalLine2.right - 20; + const y = horizontalLine2.bottom - 20; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 2, hit test inside bottom-right rounded corner'); + +test(() => { + const x = horizontalLine2.left + 1; + const y = horizontalLine2.top + 1; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 2, hit test inside top-left right-angled corner') + +test(() => { + const x = horizontalLine2.left + 1; + const y = horizontalLine2.bottom - 1; + assert_equals(document.elementFromPoint(x, y), horizontalSpan); +}, 'Horizontal line 2, hit test inside bottom-left right-angled corner') + +// Hit test vertical-lr span with border radius +const verticalLRSpan = document.getElementById('vertical-lr'); +const verticalLRDiv = verticalLRSpan.parentNode; +const verticalLRRects = verticalLRSpan.getClientRects(); +const verticalLRLine1 = verticalLRRects[0]; +const verticalLRLine2 = verticalLRRects[1]; + +test(() => { + const x = verticalLRLine1.left + 1; + const y = verticalLRLine1.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalLRDiv); +}, 'Vertical LR line 1, hit test outside top-left rounded corner'); + +test(() => { + const x = verticalLRLine1.left + 20; + const y = verticalLRLine1.top + 20; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 1, hit test inside top-left rounded corner'); + +test(() => { + const x = verticalLRLine1.right - 1; + const y = verticalLRLine1.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalLRDiv); +}, 'Vertical LR line 1, hit test outside top-right rounded corner'); + +test(() => { + const x = verticalLRLine1.right - 20; + const y = verticalLRLine1.top + 20; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 1, hit test inside top-right rounded corner'); + +test(() => { + const x = verticalLRLine1.left + 1; + const y = verticalLRLine1.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 1, hit test inside bottom-left right-angled corner') + +test(() => { + const x = verticalLRLine1.right - 1; + const y = verticalLRLine1.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 1, hit test inside bottom-right right-angled corner') + +test(() => { + const x = verticalLRLine2.left + 1; + const y = verticalLRLine2.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalLRDiv); +}, 'Vertical LR line 2, hit test outside bottom-left rounded corner'); + +test(() => { + const x = verticalLRLine2.left + 20; + const y = verticalLRLine2.bottom - 20; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 2, hit test inside bottom-left rounded corner'); + +test(() => { + const x = verticalLRLine2.right - 1; + const y = verticalLRLine2.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalLRDiv); +}, 'Vertical LR line 2, hit test outside bottom-right rounded corner'); + +test(() => { + const x = verticalLRLine2.right - 20; + const y = verticalLRLine2.bottom - 20; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 2, hit test inside bottom-right rounded corner'); + +test(() => { + const x = verticalLRLine2.left + 1; + const y = verticalLRLine2.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 2, hit test inside top-left right-angled corner') + +test(() => { + const x = verticalLRLine2.right - 1; + const y = verticalLRLine2.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalLRSpan); +}, 'Vertical LR line 2, hit test inside top-right right-angled corner') + +// Hit test vertical-rl span with border radius +const verticalRLSpan = document.getElementById('vertical-rl'); +const verticalRLDiv = verticalRLSpan.parentNode; +const verticalRLRects = verticalRLSpan.getClientRects(); +const verticalRLLine1 = verticalRLRects[0].left > verticalRLRects[1].left ? verticalRLRects[0] : verticalRLRects[1]; +const verticalRLLine2 = verticalRLRects[0].left > verticalRLRects[1].left ? verticalRLRects[1] : verticalRLRects[0]; + +test(() => { + const x = verticalRLLine1.left + 1; + const y = verticalRLLine1.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalRLDiv); +}, 'Vertical RL line 1, hit test outside top-left rounded corner'); + +test(() => { + const x = verticalRLLine1.left + 20; + const y = verticalRLLine1.top + 20; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 1, hit test inside top-left rounded corner'); + +test(() => { + const x = verticalRLLine1.right - 1; + const y = verticalRLLine1.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalRLDiv); +}, 'Vertical RL line 1, hit test outside top-right rounded corner'); + +test(() => { + const x = verticalRLLine1.right - 20; + const y = verticalRLLine1.top + 20; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 1, hit test inside top-right rounded corner'); + +test(() => { + const x = verticalRLLine1.left + 1; + const y = verticalRLLine1.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 1, hit test inside bottom-left right-angled corner') + +test(() => { + const x = verticalRLLine1.right - 1; + const y = verticalRLLine1.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 1, hit test inside bottom-right right-angled corner') + +test(() => { + const x = verticalRLLine2.left + 1; + const y = verticalRLLine2.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalRLDiv); +}, 'Vertical RL line 2, hit test outside bottom-left rounded corner'); + +test(() => { + const x = verticalRLLine2.left + 20; + const y = verticalRLLine2.bottom - 20; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 2, hit test inside bottom-left rounded corner'); + +test(() => { + const x = verticalRLLine2.right - 1; + const y = verticalRLLine2.bottom - 1; + assert_equals(document.elementFromPoint(x, y), verticalRLDiv); +}, 'Vertical RL line 2, hit test outside bottom-right rounded corner'); + +test(() => { + const x = verticalRLLine2.right - 20; + const y = verticalRLLine2.bottom - 20; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 2, hit test inside bottom-right rounded corner'); + +test(() => { + const x = verticalRLLine2.left + 1; + const y = verticalRLLine2.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 2, hit test inside top-left right-angled corner') + +test(() => { + const x = verticalRLLine2.right - 1; + const y = verticalRLLine2.top + 1; + assert_equals(document.elementFromPoint(x, y), verticalRLSpan); +}, 'Vertical RL line 2, hit test inside top-right right-angled corner') +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-invalid.html new file mode 100644 index 0000000..978eb89 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-invalid.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Color Module Level 3: parsing color with invalid values</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-color-3/#color0"> +<meta name="assert" content="color supports only the grammar '<color>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("color", "auto"); +test_invalid_value("color", "123"); +test_invalid_value("color", "#12"); +test_invalid_value("color", "#123456789"); +test_invalid_value("color", "rgb"); +test_invalid_value("color", "rgb(1)"); +test_invalid_value("color", "rgb(1,2,3,4,5)"); +test_invalid_value("color", "hsla(1,2,3,4,5)"); +test_invalid_value("color", "rgb(10%, 20, 30%)"); +test_invalid_value("color", "rgba(-2, 300, 400%, -0.5)"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html new file mode 100644 index 0000000..76e84847 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Color Module Level 3: parsing color with valid values</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-color-3/#color0"> +<meta name="assert" content="color supports the full grammar '<color>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("color", "currentcolor"); // Edge serializes as currentColor. +test_valid_value("color", "transparent"); +test_valid_value("color", "red"); +test_valid_value("color", "magenta"); +test_valid_value("color", "#234", "rgb(34, 51, 68)"); +test_valid_value("color", "#FEDCBA", "rgb(254, 220, 186)"); +test_valid_value("color", "rgb(2, 3, 4)"); +test_valid_value("color", "rgb(100%, 0%, 0%)", "rgb(255, 0, 0)"); +test_valid_value("color", "rgba(2, 3, 4, 0.5)"); // Safari serializes alpha-value 0.498039 +test_valid_value("color", "hsl(120, 100%, 50%)", ["rgb(0, 255, 0)", "hsl(120, 100%, 50%)"]); +test_valid_value("color", "hsla(120, 100%, 50%, 0.25)", ["rgba(0, 255, 0, 0.25)", "hsla(120, 100%, 50%, 0.25)"]); // Safari serializes alpha-value 0.247059 +test_valid_value("color", "rgb(-2, 3, 4)", "rgb(0, 3, 4)"); +test_valid_value("color", "rgb(100, 200, 300)", "rgb(100, 200, 255)"); +test_valid_value("color", "rgb(20, 10, 0, -10)", "rgba(20, 10, 0, 0)"); // Not supported by Edge/Safari. +test_valid_value("color", "rgb(100%, 200%, 300%)", "rgb(255, 255, 255)"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/opacity-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/opacity-invalid.html new file mode 100644 index 0000000..955903f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/opacity-invalid.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS opacity Module Level 3: parsing opacity with invalid values</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-color-3/#opacity"> +<meta name="assert" content="opacity supports only the grammar '<alphavalue>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("opacity", "auto"); +test_invalid_value("opacity", "10px"); +test_invalid_value("opacity", "0 1"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/opacity-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/opacity-valid.html new file mode 100644 index 0000000..738c3d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/opacity-valid.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS opacity Module Level 3: parsing opacity with valid values</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-color-3/#opacity"> +<meta name="assert" content="opacity supports the full grammar '<alphavalue>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("opacity", "1"); +test_valid_value("opacity", "0.5"); +test_valid_value("opacity", "0"); +test_valid_value("opacity", "-2"); +test_valid_value("opacity", "3"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/resources/parsing-testcommon.js new file mode 100644 index 0000000..b075882 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/resources/parsing-testcommon.js
@@ -0,0 +1,39 @@ +'use strict'; + +// serializedValue can be the expected serialization of value, +// or an array of permitted serializations, +// or omitted if value should serialize as value. +function test_valid_value(property, value, serializedValue) { + if (arguments.length < 3) + serializedValue = value; + + var stringifiedValue = JSON.stringify(value); + + test(function(){ + var div = document.createElement('div'); + div.style[property] = value; + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); + + var div = document.createElement('div'); + div.style[property] = value; + var readValue = div.style.getPropertyValue(property); + if (serializedValue instanceof Array) + assert_in_array(readValue, serializedValue, "serialization should be sound"); + else + assert_equals(readValue, serializedValue, "serialization should be canonical"); + + div.style[property] = readValue; + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); + + }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); +} + +function test_invalid_value(property, value) { + var stringifiedValue = JSON.stringify(value); + + test(function(){ + var div = document.createElement('div'); + div.style[property] = value; + assert_equals(div.style.getPropertyValue(property), ""); + }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/host-specificity-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/host-specificity-002.html new file mode 100644 index 0000000..3132d3a3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/host-specificity-002.html
@@ -0,0 +1,26 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: :host is accounted for during specificity computation</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector"> +<link rel="help" href="https://drafts.csswg.org/selectors/#specificity-rules"> +<link rel="help" href="https://bugzil.la/1454165"> +<link rel="match" href="reference/green-box.html"> +<p>Test passes if you see a single 100px by 100px green box below.</p> +<div id="host"></div> +<script> + host.attachShadow({ mode: 'open' }).innerHTML = ` + <style> + .foo span { + display: block; + width: 100px; + height: 100px; + background: red; + } + :host span { + background: green; + } + </style> + <div class="foo"><span></span></div> + `; +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/host-specificity.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/host-specificity.html new file mode 100644 index 0000000..3ef61d4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/host-specificity.html
@@ -0,0 +1,25 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: the selector inside :host() affects specificity</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1915"> +<link rel="help" href="https://bugzil.la/1454165"> +<link rel="match" href="reference/green-box.html"> +<p>Test passes if you see a single 100px by 100px green box below.</p> +<div id="host"></div> +<script> + host.attachShadow({ mode: 'open' }).innerHTML = ` + <style> + :host(#host) { + width: 100px; + height: 100px; + background: green; + } + :host { + background: red; + } + </style> + <slot></slot> + `; +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/slotted-specificity.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/slotted-specificity.html new file mode 100644 index 0000000..d049182 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/slotted-specificity.html
@@ -0,0 +1,25 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: the selector inside ::slotted() affects specificity</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1915"> +<link rel="help" href="https://bugzil.la/1454165"> +<link rel="match" href="reference/green-box.html"> +<p>Test passes if you see a single 100px by 100px green box below.</p> +<div id="host"><div id="slotted"></div></div> +<script> + host.attachShadow({ mode: 'open' }).innerHTML = ` + <style> + ::slotted(#slotted) { + width: 100px; + height: 100px; + background: green; + } + ::slotted(*) { + background: red; + } + </style> + <slot></slot> + `; +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt index 4c25322..091a0ca 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt
@@ -2,6 +2,9 @@ PASS import.meta.url in a root inline script PASS import.meta.url in a root external script PASS import.meta.url in a dependent external script +PASS import.meta is an object +PASS import.meta is extensible +PASS import.meta's properties are writable, configurable, and enumerable FAIL import.meta.url when importing the module with different fragments assert_equals: expected "http://web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js#1" but got "http://web-platform.test:8001/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-root.js" Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html index fa1c7dee..79f08eba 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-url.html
@@ -21,6 +21,27 @@ base + "/import-meta-dependent.js"); }, "import.meta.url in a dependent external script"); +test(() => { + assert_equals(typeof importMetaOnRootModule, "object"); + assert_not_equals(importMetaOnRootModule, null); +}, "import.meta is an object"); + +test(() => { + importMetaOnRootModule.newProperty = 1; + assert_true(Object.isExtensible(importMetaOnRootModule)); +}, "import.meta is extensible"); + +test(() => { + let names = new Set(Reflect.ownKeys(importMetaOnRootModule)); + for (name of names) { + var desc = Object.getOwnPropertyDescriptor(importMetaOnRootModule, name); + assert_equals(desc.writable, true); + assert_equals(desc.enumerable, true); + assert_equals(desc.configurable, true); + } +}, "import.meta's properties are writable, configurable, and enumerable"); + + import { importMetaOnRootModule as hashedImportMetaOnRootModule1, importMetaOnDependentModule as hashedImportMetaOnDependentModule1 } from "./import-meta-root.js#1";
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt index 87812d6..cb26c6d 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 213 tests; 139 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 213 tests; 140 PASS, 73 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Simplest possible test ("<div>abc") PASS Leading whitespace removed ("<div> abc") PASS Trailing whitespace removed ("<div>abc ") @@ -202,7 +202,7 @@ PASS innerText not supported on MathML elements ("<math>abc") PASS <rt> and no <rp> ("<div><ruby>abc<rt>def</rt></ruby>") PASS <rp> ("<div><ruby>abc<rp>(</rp><rt>def</rt><rp>)</rp></ruby>") -FAIL Lone <rp> ("<div><rp>abc</rp>") assert_equals: expected "" but got "abc" +PASS Lone <rp> ("<div><rp>abc</rp>") PASS visibility:hidden <rp> ("<div><rp style='visibility:hidden'>abc</rp>") PASS display:block <rp> ("<div><rp style='display:block'>abc</rp>def") PASS display:block <rp> with whitespace ("<div><rp style='display:block'> abc </rp>def")
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-gen-property-trees/fast/borders/overflow-hidden-border-radius-force-backing-store-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-gen-property-trees/fast/borders/overflow-hidden-border-radius-force-backing-store-expected.txt new file mode 100644 index 0000000..475ca2d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-gen-property-trees/fast/borders/overflow-hidden-border-radius-force-backing-store-expected.txt
@@ -0,0 +1,44 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow (positioned) DIV id='outer'", + "position": [50, 50], + "bounds": [300, 300] + }, + { + "name": "LayoutBlockFlow DIV id='content'", + "bounds": [285, 1000], + "contentsOpaque": true, + "transform": 1 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [50, 50, 0, 1] + ] + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-002-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-002-expected.txt deleted file mode 100644 index 02f3a06..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/external/wpt/shadow-dom/untriaged/events/retargeting-focus-events/test-002-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL A_05_03_02_T01 assert_true: Event listener was not invoked expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 66b2905b..a2ce21b 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -8858,6 +8858,19 @@ interface WebGLVertexArrayObject attribute @@toStringTag method constructor +interface WebGPU + attribute @@toStringTag + method constructor + method getAdapter +interface WebGPUAdapter + attribute @@toStringTag + getter name + method constructor + method createDevice +interface WebGPUDevice + attribute @@toStringTag + getter adapter + method constructor interface WebKitAnimationEvent : Event attribute @@toStringTag getter animationName @@ -9555,6 +9568,7 @@ getter styleMedia getter toolbar getter visualViewport + getter webgpu getter webkitStorageInfo method NodeFilter method alert @@ -9736,6 +9750,7 @@ setter statusbar setter toolbar setter visualViewport + setter webgpu PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h index be88239..79ed940 100644 --- a/third_party/blink/public/platform/web_url_response.h +++ b/third_party/blink/public/platform/web_url_response.h
@@ -305,15 +305,13 @@ #endif private: - struct ResourceResponseContainer; - // If this instance owns a ResourceResponse then |owned_resource_response_| // is non-null and |resource_response_| points to the ResourceResponse // instance it contains. - std::unique_ptr<ResourceResponseContainer> owned_resource_response_; + const std::unique_ptr<ResourceResponse> owned_resource_response_; // Should never be null. - ResourceResponse* resource_response_; + ResourceResponse* const resource_response_; }; } // namespace blink
diff --git a/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py b/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py index 756991ff..9f28d3ad 100644 --- a/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py +++ b/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py
@@ -22,6 +22,7 @@ 'Uint16', 'Uint32', 'WebGL2', + 'WebGPU', 'ASCII', 'CSSOM', 'CType',
diff --git a/third_party/blink/renderer/core/css/document_style_environment_variables.cc b/third_party/blink/renderer/core/css/document_style_environment_variables.cc index 20cca093..dbb6dfae 100644 --- a/third_party/blink/renderer/core/css/document_style_environment_variables.cc +++ b/third_party/blink/renderer/core/css/document_style_environment_variables.cc
@@ -42,15 +42,22 @@ } CSSVariableData* DocumentStyleEnvironmentVariables::ResolveVariable( - const AtomicString& name) { + const AtomicString& name, + bool record_metrics) { unsigned id = GenerateHashFromName(name); - RecordVariableUsage(id); + if (record_metrics) + RecordVariableUsage(id); // Mark the variable as seen so we will invalidate the style if we change it. seen_variables_.insert(id); return StyleEnvironmentVariables::ResolveVariable(name); } +CSSVariableData* DocumentStyleEnvironmentVariables::ResolveVariable( + const AtomicString& name) { + return ResolveVariable(name, true /* record_metrics */); +} + void DocumentStyleEnvironmentVariables::InvalidateVariable( const AtomicString& name) { DCHECK(document_);
diff --git a/third_party/blink/renderer/core/css/document_style_environment_variables.h b/third_party/blink/renderer/core/css/document_style_environment_variables.h index 165121b..032f5f1 100644 --- a/third_party/blink/renderer/core/css/document_style_environment_variables.h +++ b/third_party/blink/renderer/core/css/document_style_environment_variables.h
@@ -28,7 +28,14 @@ // Resolve the variable |name| and return the data. This will also cause // future changes to this variable to invalidate the associated document's - // style. + // style. If |record_metrics| is true we will record UseCounter metrics when + // this function is called. + CSSVariableData* ResolveVariable(const AtomicString& name, + bool record_metrics); + + // Resolve the variable |name| and return the data. This will also cause + // future changes to this variable to invalidate the associated document's + // style. UseCounter metrics will be recorded when this function is used. CSSVariableData* ResolveVariable(const AtomicString& name) override; protected:
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc index e000027..5074fd9 100644 --- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/css_property_names.h" #include "third_party/blink/renderer/core/css_value_keywords.h" +#include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/style_inherited_variables.h" #include "third_party/blink/renderer/core/style/style_non_inherited_variables.h" @@ -240,10 +241,15 @@ CSSVariableData* CSSVariableResolver::ValueForEnvironmentVariable( const AtomicString& name) { + // If we are in a User Agent Shadow DOM then we should not record metrics. + ContainerNode& scope_root = state_.GetTreeScope().RootNode(); + bool is_ua_scope = + scope_root.IsShadowRoot() && ToShadowRoot(scope_root).IsUserAgent(); + return state_.GetDocument() .GetStyleEngine() .EnsureEnvironmentVariables() - .ResolveVariable(name); + .ResolveVariable(name, !is_ua_scope); } bool CSSVariableResolver::ResolveTokenRange(
diff --git a/third_party/blink/renderer/core/css/style_environment_variables_test.cc b/third_party/blink/renderer/core/css/style_environment_variables_test.cc index 881481d..a4fb69a 100644 --- a/third_party/blink/renderer/core/css/style_environment_variables_test.cc +++ b/third_party/blink/renderer/core/css/style_environment_variables_test.cc
@@ -39,6 +39,9 @@ PageTestBase::SetUp(); RuntimeEnabledFeatures::SetCSSEnvironmentVariablesEnabled(true); + + // Needed for RecordUseCounter_IgnoreMediaControls. + RuntimeEnabledFeatures::SetModernMediaControlsEnabled(true); } void TearDown() override { @@ -337,6 +340,21 @@ } } +TEST_F(StyleEnvironmentVariablesTest, RecordUseCounter_IgnoreMediaControls) { + InitializeWithHTML(GetFrame(), "<video controls />"); + + EXPECT_FALSE(UseCounter::IsCounted(GetDocument(), + WebFeature::kCSSEnvironmentVariable)); + EXPECT_FALSE(UseCounter::IsCounted( + GetDocument(), WebFeature::kCSSEnvironmentVariable_SafeAreaInsetTop)); + EXPECT_FALSE(UseCounter::IsCounted( + GetDocument(), WebFeature::kCSSEnvironmentVariable_SafeAreaInsetLeft)); + EXPECT_FALSE(UseCounter::IsCounted( + GetDocument(), WebFeature::kCSSEnvironmentVariable_SafeAreaInsetBottom)); + EXPECT_FALSE(UseCounter::IsCounted( + GetDocument(), WebFeature::kCSSEnvironmentVariable_SafeAreaInsetRight)); +} + TEST_F(StyleEnvironmentVariablesTest, RecordUseCounter_InvalidProperty) { InitializeTestPageWithVariableNamed(GetFrame(), kVariableName); EXPECT_TRUE(UseCounter::IsCounted(GetDocument(),
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 4360c9e..e1f2f96f 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2694,32 +2694,29 @@ if (!layer || layer->Client().ShouldThrottleRendering()) return; - scoped_refptr<cc::Layer> contents_layer = layer->ContentsLayer(); - if (layer->DrawsContent() || contents_layer) { + if (layer->DrawsContent()) { ScopedPaintChunkProperties scope(context.GetPaintController(), layer->GetPropertyTreeState(), *layer, DisplayItem::kForeignLayerWrapper); + // TODO(trchen): Currently the GraphicsLayer hierarchy is still built + // during CompositingUpdate, and we have to clear them here to ensure no + // extraneous layers are still attached. In future we will disable all + // those layer hierarchy code so we won't need this line. + layer->CcLayer()->RemoveAllChildren(); + RecordForeignLayer(context, *layer, DisplayItem::kForeignLayerWrapper, + layer->CcLayer(), layer->GetOffsetFromTransformNode(), + layer->Size()); + } - if (layer->DrawsContent()) { - // TODO(trchen): Currently the GraphicsLayer hierarchy is still built - // during CompositingUpdate, and we have to clear them here to ensure no - // extraneous layers are still attached. In future we will disable all - // those layer hierarchy code so we won't need this line. - layer->CcLayer()->RemoveAllChildren(); - RecordForeignLayer(context, *layer, DisplayItem::kForeignLayerWrapper, - layer->CcLayer(), layer->GetOffsetFromTransformNode(), - layer->Size()); - } - if (contents_layer) { - auto position = contents_layer->position(); - auto size = contents_layer->bounds(); - RecordForeignLayer(context, *layer, - DisplayItem::kForeignLayerContentsWrapper, - std::move(contents_layer), - layer->GetOffsetFromTransformNode() + - FloatSize(position.x(), position.y()), - IntSize(size.width(), size.height())); - } + if (scoped_refptr<cc::Layer> contents_layer = layer->ContentsLayer()) { + ScopedPaintChunkProperties scope( + context.GetPaintController(), layer->GetContentsPropertyTreeState(), + *layer, DisplayItem::kForeignLayerContentsWrapper); + auto size = contents_layer->bounds(); + RecordForeignLayer( + context, *layer, DisplayItem::kForeignLayerContentsWrapper, + std::move(contents_layer), layer->GetContentsOffsetFromTransformNode(), + IntSize(size.width(), size.height())); } DCHECK(!layer->ContentsClippingMaskLayer()); @@ -3824,6 +3821,16 @@ }); } +void LocalFrameView::SetSelfVisible(bool visible) { + if (visible != self_visible_) { + // Frame view visibility affects PLC::CanBeComposited, which in turn + // affects compositing inputs. + if (LayoutView* view = GetLayoutView()) + view->Layer()->SetNeedsCompositingInputsUpdate(); + } + self_visible_ = visible; +} + void LocalFrameView::Show() { if (!IsSelfVisible()) { SetSelfVisible(true);
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index c55b3a2..e77966e 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -421,7 +421,7 @@ return self_visible_ && parent_visible_; } // Whether or not we are actually visible. void SetParentVisible(bool) override; - void SetSelfVisible(bool v) { self_visible_ = v; } + void SetSelfVisible(bool); void AttachToLayout() override; void DetachFromLayout() override; bool IsAttached() const override { return is_attached_; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 340e12fb94..8b061ad 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -40,11 +40,14 @@ default_containing_block_.style = &container_style; default_containing_block_.content_size = container_builder_->Size(); - default_containing_block_.content_size.inline_size -= - borders_and_scrollers.InlineSum(); - default_containing_block_.content_size.block_size -= - borders_and_scrollers.BlockSum(); - + default_containing_block_.content_size.inline_size = + std::max(default_containing_block_.content_size.inline_size - + borders_and_scrollers.InlineSum(), + LayoutUnit()); + default_containing_block_.content_size.block_size = + std::max(default_containing_block_.content_size.block_size - + borders_and_scrollers.BlockSum(), + LayoutUnit()); default_containing_block_.content_offset = NGLogicalOffset{ borders_and_scrollers.inline_start, borders_and_scrollers.block_start}; default_containing_block_.content_physical_offset =
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc index 53fcf3e..40e428e 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
@@ -190,6 +190,9 @@ info.needs_reparent_scroll_for_fixed = false; } + PaintLayerCompositor* compositor = + layer->GetLayoutObject().View()->Compositor(); + // The sequence of updates to compositing triggers goes like this: // 1. Apply all triggers from kComboAllDirectNonStyleDeterminedReasons for // |layer|. This may depend on ancestor composited scrolling (i.e. step @@ -212,7 +215,7 @@ if (layer->GetScrollableArea()) { layer->GetScrollableArea()->UpdateNeedsCompositedScrolling( - layer->GetLayoutObject().View()->Compositor()->CanBeComposited(layer) && + compositor->CanBeComposited(layer) && layer->DirectCompositingReasons()); layer->GetScrollableArea()->SetHasPaintLayerScrollChild(false); } @@ -228,7 +231,9 @@ UpdateRecursive(child, update_type, info); descendant_has_direct_compositing_reason |= child->DescendantHasDirectOrScrollingCompositingReason() || - child->DirectCompositingReasons() || child->NeedsCompositedScrolling(); + child->NeedsCompositedScrolling() || + (compositor->CanBeComposited(child) && + child->DirectCompositingReasons()); } layer->SetDescendantHasDirectOrScrollingCompositingReason( descendant_has_direct_compositing_reason);
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc index 7af3911..d27606af 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
@@ -125,6 +125,15 @@ SetContainerLayerState(mapping->ForegroundLayer()); } + auto* main_graphics_layer = mapping->MainGraphicsLayer(); + if (const auto* contents_layer = main_graphics_layer->ContentsLayer()) { + auto position = contents_layer->position(); + main_graphics_layer->SetContentsLayerState( + fragment_data.ContentsProperties(), + snapped_paint_offset + main_graphics_layer->OffsetFromLayoutObject() + + IntSize(position.x(), position.y())); + } + if (auto* squashing_layer = mapping->SquashingLayer()) { auto state = fragment_data.PreEffectProperties(); // The squashing layer's ClippingContainer is the common ancestor of clip
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc index fcb17c4..d4a5d96 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
@@ -248,7 +248,8 @@ kNegativeZOrderChildren | kNormalFlowChildren | kPositiveZOrderChildren); while (PaintLayer* cur_layer = iterator.Next()) { DCHECK(cur_layer->GetCompositingState() == kNotComposited); - DCHECK(!cur_layer->DirectCompositingReasons()); + DCHECK(!cur_layer->DirectCompositingReasons() || + !layer->Compositor()->CanBeComposited(cur_layer)); CheckSubtreeHasNoCompositing(cur_layer); } } @@ -287,8 +288,11 @@ !current_recursion_data.compositing_ancestor_->IsRootLayer(); const bool ignore_lcd_text = has_non_root_composited_scrolling_ancestor; - CompositingReasons direct_from_paint_layer = - layer->DirectCompositingReasons(); + const bool layer_can_be_composited = compositor->CanBeComposited(layer); + + CompositingReasons direct_from_paint_layer = 0; + if (layer_can_be_composited) + direct_from_paint_layer = layer->DirectCompositingReasons(); if (compositing_reason_finder_.RequiresCompositingForScrollDependentPosition( layer, @@ -296,14 +300,18 @@ direct_from_paint_layer |= CompositingReason::kScrollDependentPosition; } - DCHECK( - direct_from_paint_layer == - compositing_reason_finder_.DirectReasons( - layer, ignore_lcd_text || moves_with_respect_to_compositing_ancestor)) - << " Expected: " - << CompositingReason::ToString( - compositing_reason_finder_.DirectReasons(layer, ignore_lcd_text)) - << " Actual: " << CompositingReason::ToString(direct_from_paint_layer); +#if DCHECK_IS_ON() + if (layer_can_be_composited) { + DCHECK(direct_from_paint_layer == + compositing_reason_finder_.DirectReasons( + layer, + ignore_lcd_text || moves_with_respect_to_compositing_ancestor)) + << " Expected: " + << CompositingReason::ToString( + compositing_reason_finder_.DirectReasons(layer, ignore_lcd_text)) + << " Actual: " << CompositingReason::ToString(direct_from_paint_layer); + } +#endif direct_reasons |= direct_from_paint_layer; @@ -320,7 +328,8 @@ // testing is not used, we must assume we overlap if there is anything // composited behind us in paint-order. CompositingReasons overlap_compositing_reason = - current_recursion_data.subtree_is_compositing_ + (layer_can_be_composited && + current_recursion_data.subtree_is_compositing_) ? CompositingReason::kAssumedOverlap : CompositingReason::kNone; @@ -337,7 +346,8 @@ unclipped_descendants_to_remove.push_back(i); continue; } - if (layer->ScrollsWithRespectTo(unclipped_descendant)) + if (layer_can_be_composited && + layer->ScrollsWithRespectTo(unclipped_descendant)) reasons_to_composite |= CompositingReason::kAssumedOverlap; } @@ -372,7 +382,7 @@ } absolute_descendant_bounding_box = abs_bounds; - if (current_recursion_data.testing_overlap_ && + if (layer_can_be_composited && current_recursion_data.testing_overlap_ && !RequiresCompositingOrSquashing(direct_reasons)) { bool overlaps = overlap_map.OverlapsLayers(abs_bounds, use_clipped_bounding_rect); @@ -573,7 +583,8 @@ compositing_reason_finder_, layer, child_recursion_data.subtree_is_compositing_, any_descendant_has3d_transform); - reasons_to_composite |= subtree_compositing_reasons; + if (layer_can_be_composited) + reasons_to_composite |= subtree_compositing_reasons; if (!will_be_composited_or_squashed && can_be_composited && RequiresCompositingOrSquashing(subtree_compositing_reasons)) { child_recursion_data.compositing_ancestor_ = layer;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc index b0398c0..8ad4a737 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
@@ -47,4 +47,86 @@ EXPECT_EQ(CompositingReason::kNone, fixed->Layer()->GetCompositingReasons()); } +TEST_F(CompositingRequirementsUpdaterTest, + NoOverlapReasonForNonSelfPaintingLayer) { + SetBodyInnerHTML(R"HTML( + <style> + #target { + overflow: auto; + width: 100px; + height: 100px; + margin-top: -50px; + } + </style> + <div style="position: relative; width: 500px; height: 300px; + will-change: transform"></div> + <div id=target></div> + )HTML"); + + PaintLayer* target = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer(); + EXPECT_FALSE(target->GetCompositingReasons()); + + // Now make |target| self-painting. + GetDocument().getElementById("target")->setAttribute(HTMLNames::styleAttr, + "position: relative"); + GetDocument().View()->UpdateAllLifecyclePhases(); + + EXPECT_EQ(CompositingReason::kOverlap, target->GetCompositingReasons()); +} + +TEST_F(CompositingRequirementsUpdaterTest, + NoAssumedOverlapReasonForNonSelfPaintingLayer) { + SetBodyInnerHTML(R"HTML( + <style> + #target { + overflow: auto; + width: 100px; + height: 100px; + } + </style> + <div style="position: relative; width: 500px; height: 300px; + transform: translateZ(0)"></div> + <div id=target></div> + )HTML"); + + PaintLayer* target = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer(); + EXPECT_FALSE(target->GetCompositingReasons()); + + // Now make |target| self-painting. + GetDocument().getElementById("target")->setAttribute(HTMLNames::styleAttr, + "position: relative"); + GetDocument().View()->UpdateAllLifecyclePhases(); + EXPECT_EQ(CompositingReason::kAssumedOverlap, + target->GetCompositingReasons()); +} + +TEST_F(CompositingRequirementsUpdaterTest, + NoDescendantReasonForNonSelfPaintingLayer) { + SetBodyInnerHTML(R"HTML( + <style> + #target { + overflow: auto; + width: 100px; + height: 100px; + } + </style> + <div id=target> + <div style="backface-visibility: hidden"></div> + </div> + )HTML"); + + PaintLayer* target = + ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer(); + EXPECT_FALSE(target->GetCompositingReasons()); + + // Now make |target| self-painting. + GetDocument().getElementById("target")->setAttribute(HTMLNames::styleAttr, + "position: relative"); + GetDocument().View()->UpdateAllLifecyclePhases(); + EXPECT_EQ(CompositingReason::kClipsCompositingDescendants, + target->GetCompositingReasons()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/inline_text_box_painter.cc b/third_party/blink/renderer/core/paint/inline_text_box_painter.cc index bf8ca7a..cf03d6f 100644 --- a/third_party/blink/renderer/core/paint/inline_text_box_painter.cc +++ b/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
@@ -127,16 +127,11 @@ (inline_text_box_.IsHorizontal() ? paint_offset.X() : paint_offset.Y()); LayoutUnit logical_extent = logical_visual_overflow.Width(); - // We round the y-axis to ensure consistent line heights. - LayoutPoint adjusted_paint_offset(paint_offset); - if (inline_text_box_.IsHorizontal()) { - adjusted_paint_offset.SetY(LayoutUnit(adjusted_paint_offset.Y().Round())); if (!paint_info.GetCullRect().IntersectsHorizontalRange( logical_start, logical_start + logical_extent)) return; } else { - adjusted_paint_offset.SetX(LayoutUnit(adjusted_paint_offset.X().Round())); if (!paint_info.GetCullRect().IntersectsVerticalRange( logical_start, logical_start + logical_extent)) return; @@ -173,6 +168,7 @@ LayoutPoint box_origin(inline_text_box_.PhysicalLocation() + paint_offset); + // We round the y-axis to ensure consistent line heights. if (inline_text_box_.IsHorizontal()) { box_origin.SetY(LayoutUnit(box_origin.Y().Round())); } else {
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/third_party/blink/renderer/core/paint/link_highlight_impl.cc index a85dd15..620f511 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -29,7 +29,6 @@ #include <utility> #include "base/memory/ptr_util.h" -#include "cc/layers/layer.h" #include "cc/layers/picture_layer.h" #include "cc/paint/display_item_list.h" #include "third_party/blink/public/platform/platform.h" @@ -87,9 +86,7 @@ DCHECK(node_); DCHECK(owning_web_view); content_layer_ = cc::PictureLayer::Create(this); - clip_layer_ = cc::Layer::Create(); - clip_layer_->SetTransformOrigin(FloatPoint3D()); - clip_layer_->AddChild(content_layer_); + content_layer_->SetTransformOrigin(FloatPoint3D()); compositor_animation_ = CompositorAnimation::Create(); DCHECK(compositor_animation_); @@ -118,14 +115,6 @@ ReleaseResources(); } -cc::PictureLayer* LinkHighlightImpl::ContentLayer() { - return content_layer_.get(); -} - -cc::Layer* LinkHighlightImpl::ClipLayer() { - return clip_layer_.get(); -} - void LinkHighlightImpl::ReleaseResources() { node_.Clear(); } @@ -144,8 +133,6 @@ if (!new_graphics_layer) return; - clip_layer_->SetTransform(gfx::Transform()); - if (current_graphics_layer_ != new_graphics_layer) { if (current_graphics_layer_) ClearGraphicsLayerLinkHighlightPointer(); @@ -408,7 +395,7 @@ } cc::Layer* LinkHighlightImpl::Layer() { - return ClipLayer(); + return content_layer_.get(); } CompositorAnimation* LinkHighlightImpl::GetCompositorAnimation() const {
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.h b/third_party/blink/renderer/core/paint/link_highlight_impl.h index 116aef5..9c4a76d8f 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl.h +++ b/third_party/blink/renderer/core/paint/link_highlight_impl.h
@@ -60,8 +60,6 @@ static std::unique_ptr<LinkHighlightImpl> Create(Node*, WebViewImpl*); ~LinkHighlightImpl() override; - cc::PictureLayer* ContentLayer(); - cc::Layer* ClipLayer(); void StartHighlightAnimationIfNeeded(); void UpdateGeometry(); @@ -103,7 +101,6 @@ bool ComputeHighlightLayerPathAndPosition(const LayoutBoxModelObject&); scoped_refptr<cc::PictureLayer> content_layer_; - scoped_refptr<cc::Layer> clip_layer_; Path path_; Persistent<Node> node_;
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc index e5b9130..b24337a 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -105,8 +105,7 @@ GetTargetedEvent(web_view_impl, touch_event)); EXPECT_TRUE(web_view_impl->GetLinkHighlight(0)); - EXPECT_TRUE(web_view_impl->GetLinkHighlight(0)->ContentLayer()); - EXPECT_TRUE(web_view_impl->GetLinkHighlight(0)->ClipLayer()); + EXPECT_TRUE(web_view_impl->GetLinkHighlight(0)->Layer()); // Find a target inside a scrollable div touch_event.SetPositionInWidget(WebFloatPoint(20, 100));
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index cfe8033..977c07e6 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -54,25 +54,6 @@ return !ToLayoutTableCell(object).Table()->ShouldCollapseBorders(); } -// In hit testing, legacy and NG assumes different semantics for the -// |accumulated_offset| parameter: -// - Legacy: offset of the containing block of |child| (excluding |child| when -// it is block by itslef) in the paint layer. -// - NG: offset of the fragment itself in the paint layer -// This function converts the NG offset to legacy so that hit testing can fall -// back to legacy with the correct |accumulated_offset|. -LayoutPoint FallbackAccumulatedOffset(const NGPaintFragment& child, - const LayoutPoint& accumulated_offset) { - DCHECK(child.Parent()); - const NGPaintFragment& parent = *child.Parent(); - if (parent.PhysicalFragment().IsBlockFlow()) { - return accumulated_offset - - LayoutSize(child.Offset().left, child.Offset().top); - } - const NGPhysicalOffset inline_offset = child.InlineOffsetToContainerBox(); - return accumulated_offset - LayoutSize(inline_offset.left, inline_offset.top); -} - bool FragmentVisibleToHitTestRequest(const NGPaintFragment& fragment, const HitTestRequest& request) { return fragment.Style().Visibility() == EVisibility::kVisible && @@ -92,8 +73,10 @@ DCHECK(fragment.Parent()); DCHECK(fragment.PhysicalFragment().IsInline()); const NGPaintFragment& parent = *fragment.Parent(); + // To be passed as |accumulated_offset| to LayoutInline::HitTestCulledInline, + // where it equals the physical offset of the containing block in paint layer. const LayoutPoint fallback_accumulated_offset = - FallbackAccumulatedOffset(fragment, physical_offset); + physical_offset - fragment.InlineOffsetToContainerBox().ToLayoutSize(); const LayoutObject* limit_layout_object = parent.PhysicalFragment().IsLineBox() ? parent.Parent()->GetLayoutObject() : parent.GetLayoutObject(); @@ -1079,8 +1062,12 @@ // atomically, as if it created its own stacking context. (See Appendix // E.2, section 7.4 on inline block/table elements in CSS2.2 spec) bool should_hit_test_all_phases = fragment.IsAtomicInline(); + // To be passed as |accumulated_offset| to legacy hit test functions of + // LayoutBox or subclass overrides, where it isn't in any well-defined + // coordinate space, but only equals the difference below. LayoutPoint fallback_accumulated_offset = - FallbackAccumulatedOffset(*child, child_physical_offset); + child_physical_offset - + ToLayoutSize(ToLayoutBox(fragment.GetLayoutObject())->Location()); if (should_hit_test_all_phases) { stop_hit_testing = fragment.GetLayoutObject()->HitTestAllPhases( result, location_in_container, fallback_accumulated_offset);
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 0a4aab2..c66b7c1 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -233,7 +233,6 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='scroll' style='width: 100px; height: 100px; overflow: scroll; will-change: transform'> @@ -486,7 +485,6 @@ } TEST_P(PaintLayerTest, HasVisibleDescendant) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='invisible' style='position:relative'> <div id='visible' style='visibility: visible; position: relative'> @@ -504,7 +502,6 @@ } TEST_P(PaintLayerTest, Has3DTransformedDescendant) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='parent' style='position:relative; z-index: 0'> <div id='child' style='transform: translateZ(1px)'> @@ -519,7 +516,6 @@ } TEST_P(PaintLayerTest, Has3DTransformedDescendantChangeStyle) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='parent' style='position:relative; z-index: 0'> <div id='child' style='position:relative '> @@ -541,7 +537,6 @@ } TEST_P(PaintLayerTest, Has3DTransformedDescendantNotStacking) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='parent' style='position:relative;'> <div id='child' style='transform: translateZ(1px)'> @@ -558,7 +553,6 @@ } TEST_P(PaintLayerTest, Has3DTransformedGrandchildWithPreserve3d) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='parent' style='position:relative; z-index: 0'> <div id='child' style='transform-style: preserve-3d'> @@ -577,7 +571,6 @@ } TEST_P(PaintLayerTest, DescendantDependentFlagsStopsAtThrottledFrames) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <style>body { margin: 0; }</style> <div id='transform' style='transform: translate3d(4px, 5px, 6px);'> @@ -669,7 +662,6 @@ } TEST_P(PaintLayerTest, PaintInvalidationOnCompositedScroll) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <style>* { margin: 0 } ::-webkit-scrollbar { display: none }</style> <div id='scroller' style='overflow: scroll; width: 50px; height: 50px; @@ -699,7 +691,6 @@ } TEST_P(PaintLayerTest, CompositingContainerStackedFloatUnderStackingInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -724,7 +715,6 @@ TEST_P(PaintLayerTest, CompositingContainerStackedFloatUnderStackingCompositedInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -749,7 +739,6 @@ } TEST_P(PaintLayerTest, CompositingContainerNonStackedFloatUnderStackingInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -775,7 +764,6 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedFloatUnderStackingCompositedInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -801,7 +789,6 @@ TEST_P(PaintLayerTest, CompositingContainerStackedUnderFloatUnderStackingInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -828,7 +815,6 @@ TEST_P(PaintLayerTest, CompositingContainerStackedUnderFloatUnderStackingCompositedInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -856,7 +842,6 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedUnderFloatUnderStackingInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -884,7 +869,6 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedUnderFloatUnderStackingCompositedInline) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -1090,7 +1074,6 @@ } TEST_P(PaintLayerTest, CompositingContainerFloatingIframe) { - EnableCompositing(); SetBodyInnerHTML(R"HTML( <div id='compositedContainer' style='position: relative; will-change: transform'> @@ -1229,7 +1212,6 @@ } TEST_P(PaintLayerTest, NeedsRepaintOnRemovingStackedLayer) { - EnableCompositing(); SetBodyInnerHTML( "<style>body {margin-top: 200px; backface-visibility: hidden}</style>" "<div id='target' style='position: absolute; top: 0'>Text</div>");
diff --git a/third_party/blink/renderer/devtools/front_end/elements/ComputedStyleWidget.js b/third_party/blink/renderer/devtools/front_end/elements/ComputedStyleWidget.js index aceeed5..ae3fe2b 100644 --- a/third_party/blink/renderer/devtools/front_end/elements/ComputedStyleWidget.js +++ b/third_party/blink/renderer/devtools/front_end/elements/ComputedStyleWidget.js
@@ -47,8 +47,8 @@ const hbox = this.contentElement.createChild('div', 'hbox styles-sidebar-pane-toolbar'); const filterContainerElement = hbox.createChild('div', 'styles-sidebar-pane-filter-box'); - const filterInput = Elements.StylesSidebarPane.createPropertyFilterElement( - Common.UIString('Filter'), hbox, filterCallback.bind(this), 'styles-filter-engaged'); + const filterInput = + Elements.StylesSidebarPane.createPropertyFilterElement(ls`Filter`, hbox, filterCallback.bind(this)); UI.ARIAUtils.setAccessibleName(filterInput, Common.UIString('Filter Computed Styles')); filterContainerElement.appendChild(filterInput); this.setDefaultFocusedElement(filterInput); @@ -57,6 +57,9 @@ toolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox( this._showInheritedComputedStylePropertiesSetting, undefined, Common.UIString('Show all'))); + this._noMatchesElement = this.contentElement.createChild('div', 'gray-info-message'); + this._noMatchesElement.textContent = ls`No matching property`; + this._propertiesOutline = new UI.TreeOutlineInShadow(); this._propertiesOutline.hideOverflow(); this._propertiesOutline.registerRequiredCSS('elements/computedStyleWidgetTree.css'); @@ -336,11 +339,14 @@ */ _updateFilter(regex) { const children = this._propertiesOutline.rootElement().children(); + let hasMatch = false; for (const child of children) { const property = child[Elements.ComputedStyleWidget._propertySymbol]; const matched = !regex || regex.test(property.name) || regex.test(property.value); child.hidden = !matched; + hasMatch |= matched; } + this._noMatchesElement.classList.toggle('hidden', hasMatch); } };
diff --git a/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js b/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js index 166b5d5..2845ba43 100644 --- a/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js +++ b/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js
@@ -47,6 +47,9 @@ this._pendingWidgetToggle = null; this._toolbarPaneElement = this._createStylesSidebarToolbar(); + this._noMatchesElement = this.contentElement.createChild('div', 'gray-info-message hidden'); + this._noMatchesElement.textContent = ls`No matching selector or style`; + this._sectionsContainer = this.contentElement.createChild('div'); UI.ARIAUtils.markAsTree(this._sectionsContainer); this._sectionsContainer.addEventListener('keydown', this._sectionsContainerKeyDown.bind(this), false); @@ -144,17 +147,15 @@ * @param {string} placeholder * @param {!Element} container * @param {function(?RegExp)} filterCallback - * @param {string} activeClassName * @return {!Element} */ - static createPropertyFilterElement(placeholder, container, filterCallback, activeClassName) { + static createPropertyFilterElement(placeholder, container, filterCallback) { const input = createElementWithClass('input'); input.placeholder = placeholder; function searchHandler() { const regex = input.value ? new RegExp(input.value.escapeForRegExp(), 'i') : null; filterCallback(regex); - container.classList.toggle(activeClassName, !!input.value); } input.addEventListener('input', searchHandler, false); @@ -579,8 +580,10 @@ } _updateFilter() { + let hasAnyVisibleBlock = false; for (const block of this._sectionBlocks) - block.updateFilter(); + hasAnyVisibleBlock |= block.updateFilter(); + this._noMatchesElement.classList.toggle('hidden', hasAnyVisibleBlock); } /** @@ -615,8 +618,8 @@ const container = this.contentElement.createChild('div', 'styles-sidebar-pane-toolbar-container'); const hbox = container.createChild('div', 'hbox styles-sidebar-pane-toolbar'); const filterContainerElement = hbox.createChild('div', 'styles-sidebar-pane-filter-box'); - const filterInput = Elements.StylesSidebarPane.createPropertyFilterElement( - Common.UIString('Filter'), hbox, this._onFilterChanged.bind(this), 'styles-filter-engaged'); + const filterInput = + Elements.StylesSidebarPane.createPropertyFilterElement(ls`Filter`, hbox, this._onFilterChanged.bind(this)); UI.ARIAUtils.setAccessibleName(filterInput, Common.UIString('Filter Styles')); filterContainerElement.appendChild(filterInput); const toolbar = new UI.Toolbar('styles-pane-toolbar', hbox); @@ -743,12 +746,16 @@ return new Elements.SectionBlock(separatorElement); } + /** + * @return {boolean} + */ updateFilter() { let hasAnyVisibleSection = false; for (const section of this.sections) hasAnyVisibleSection |= section._updateFilter(); if (this._titleElement) this._titleElement.classList.toggle('hidden', !hasAnyVisibleSection); + return hasAnyVisibleSection; } /**
diff --git a/third_party/blink/renderer/devtools/front_end/elements/computedStyleSidebarPane.css b/third_party/blink/renderer/devtools/front_end/elements/computedStyleSidebarPane.css index d6055ad..21a0057e 100644 --- a/third_party/blink/renderer/devtools/front_end/elements/computedStyleSidebarPane.css +++ b/third_party/blink/renderer/devtools/front_end/elements/computedStyleSidebarPane.css
@@ -23,14 +23,12 @@ outline: none !important; border: none; width: 100%; - background: transparent; - margin-left: 4px; + background: white; + padding-left: 4px; + margin: 3px; } -.styles-filter-engaged { - background-color: rgba(255, 255, 0, 0.5); -} - -:host-context(.-theme-with-dark-background) .styles-filter-engaged { - background-color: hsla(133, 100%, 30%, 0.5); +.styles-sidebar-pane-filter-box > input:focus, +.styles-sidebar-pane-filter-box > input:not(:placeholder-shown) { + box-shadow: var(--focus-ring-active-shadow); }
diff --git a/third_party/blink/renderer/devtools/front_end/elements/stylesSidebarPane.css b/third_party/blink/renderer/devtools/front_end/elements/stylesSidebarPane.css index a4f3b7c..b6f41b9 100644 --- a/third_party/blink/renderer/devtools/front_end/elements/stylesSidebarPane.css +++ b/third_party/blink/renderer/devtools/front_end/elements/stylesSidebarPane.css
@@ -34,12 +34,10 @@ background-color: hsl(215, 25%, 91%); } -.styles-filter-engaged, .styles-section .simple-selector.filter-match { background-color: rgba(255, 255, 0, 0.5); } -:host-context(.-theme-with-dark-background) .styles-filter-engaged, :host-context(.-theme-with-dark-background) .styles-section .simple-selector.filter-match { background-color: hsla(133, 100%, 30%, 0.5); } @@ -179,7 +177,8 @@ box-shadow: var(--focus-ring-inactive-shadow); } -.styles-sidebar-pane-filter-box > input:focus { +.styles-sidebar-pane-filter-box > input:focus, +.styles-sidebar-pane-filter-box > input:not(:placeholder-shown) { box-shadow: var(--focus-ring-active-shadow); }
diff --git a/third_party/blink/renderer/devtools/front_end/ui/filter.css b/third_party/blink/renderer/devtools/front_end/ui/filter.css index 5afc729..025789e 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/filter.css +++ b/third_party/blink/renderer/devtools/front_end/ui/filter.css
@@ -151,6 +151,7 @@ box-shadow: var(--focus-ring-inactive-shadow); } -.filter-input-field:focus { +.filter-input-field:focus, +.filter-input-field:not(:empty) { box-shadow: var(--focus-ring-active-shadow); }
diff --git a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css index 6dcd7d3..d45a3f95 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css +++ b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css
@@ -242,7 +242,8 @@ box-shadow: var(--focus-ring-inactive-shadow); } -.toolbar-input.focused { +.toolbar-input.focused, +.toolbar-input:not(.toolbar-input-empty) { box-shadow: var(--focus-ring-active-shadow); } @@ -334,7 +335,8 @@ box-shadow: var(--focus-ring-inactive-shadow); } -input[is=history-input]:focus { +input[is=history-input]:focus, +input[is=history-input]:not(:placeholder-shown) { box-shadow: var(--focus-ring-active-shadow); }
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 8c03825e..3e21134 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -156,6 +156,7 @@ "//third_party/blink/renderer/modules/webaudio", "//third_party/blink/renderer/modules/webdatabase", "//third_party/blink/renderer/modules/webgl", + "//third_party/blink/renderer/modules/webgpu", "//third_party/blink/renderer/modules/webmidi", "//third_party/blink/renderer/modules/webshare", "//third_party/blink/renderer/modules/websockets",
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc index 7223b2b9..a279118 100644 --- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -137,8 +137,9 @@ origin->Protocol() != url::kHttpsScheme) { resolver->Reject(DOMException::Create( DOMExceptionCode::kNotAllowedError, - "Public-key credentials are only available to secure HTTP or HTTPS " - "origins. See https://crbug.com/824383")); + "Public-key credentials are only available to HTTPS origin or " + "HTTP origins that fall under 'localhost'. See " + "https://crbug.com/824383")); return false; }
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index dae1d97..9fca2cb 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -397,6 +397,9 @@ "webgl/webgl_uniform_location.idl", "webgl/webgl_vertex_array_object.idl", "webgl/webgl_vertex_array_object_oes.idl", + "webgpu/webgpu.idl", + "webgpu/webgpu_adapter.idl", + "webgpu/webgpu_device.idl", "webmidi/midi_access.idl", "webmidi/midi_connection_event.idl", "webmidi/midi_input.idl", @@ -645,6 +648,7 @@ "webaudio/wave_shaper_options.idl", "webgl/webgl_context_attributes.idl", "webgl/webgl_context_event_init.idl", + "webgpu/webgpu_adapter_descriptor.idl", "webmidi/midi_connection_event_init.idl", "webmidi/midi_message_event_init.idl", "webmidi/midi_options.idl", @@ -758,6 +762,7 @@ "webdatabase/window_web_database.idl", "webgl/webgl2_rendering_context_base.idl", "webgl/webgl_rendering_context_base.idl", + "webgpu/window_webgpu.idl", "webmidi/navigator_web_midi.idl", "webshare/navigator_share.idl", "webusb/navigator_usb.idl",
diff --git a/third_party/blink/renderer/modules/webgpu/BUILD.gn b/third_party/blink/renderer/modules/webgpu/BUILD.gn new file mode 100644 index 0000000..3e2e9ff --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/blink/renderer/modules/modules.gni") + +blink_modules_sources("webgpu") { + sources = [ + "webgpu.cc", + "webgpu.h", + "webgpu_adapter.cc", + "webgpu_adapter.h", + "webgpu_device.cc", + "webgpu_device.h", + "window_webgpu.cc", + "window_webgpu.h", + ] +}
diff --git a/third_party/blink/renderer/modules/webgpu/OWNERS b/third_party/blink/renderer/modules/webgpu/OWNERS new file mode 100644 index 0000000..1a2169f --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/OWNERS
@@ -0,0 +1,5 @@ +cwallez@chromium.org +kainino@chromium.org +kbr@chromium.org + +# COMPONENT: Blink>WebGPU
diff --git a/third_party/blink/renderer/modules/webgpu/README.md b/third_party/blink/renderer/modules/webgpu/README.md new file mode 100644 index 0000000..fc38f89 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/README.md
@@ -0,0 +1,7 @@ +# WebGPU Blink module + +The WebGPU API is the successor to the WebGL and WebGL 2 graphics APIs for the Web. +It will provide modern features such as “GPU compute” as well as lower overhead access to GPU hardware and better, more predictable performance. +WebGPU is being developed by the [“GPU for the Web”](https://www.w3.org/community/gpu/) W3C community group. + +This Blink module implements the WebGPU API's [sketch WebIDL](https://github.com/gpuweb/gpuweb/blob/master/design/sketch.webidl) that will evolve as WebGPU gets closer to an MVP.
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu.cc b/third_party/blink/renderer/modules/webgpu/webgpu.cc new file mode 100644 index 0000000..4ec95c9 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu.cc
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webgpu/webgpu.h" + +#include "third_party/blink/renderer/modules/webgpu/webgpu_adapter.h" +#include "third_party/blink/renderer/modules/webgpu/webgpu_adapter_descriptor.h" + +namespace blink { + +// static +WebGPU* WebGPU::Create() { + return new WebGPU(); +} + +WebGPUAdapter* WebGPU::getAdapter(const WebGPUAdapterDescriptor& descriptor) { + return WebGPUAdapter::Create(descriptor.powerPreference()); +} + +WebGPU::WebGPU() {} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu.h b/third_party/blink/renderer/modules/webgpu/webgpu.h new file mode 100644 index 0000000..d989b7a --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu.h
@@ -0,0 +1,30 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class WebGPUAdapter; +class WebGPUAdapterDescriptor; + +class WebGPU final : public ScriptWrappable { + DISALLOW_COPY_AND_ASSIGN(WebGPU); + DEFINE_WRAPPERTYPEINFO(); + + public: + static WebGPU* Create(); + + WebGPUAdapter* getAdapter(const WebGPUAdapterDescriptor&); + + private: + WebGPU(); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_H_
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu.idl b/third_party/blink/renderer/modules/webgpu/webgpu.idl new file mode 100644 index 0000000..8877baf --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu.idl
@@ -0,0 +1,9 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + RuntimeEnabled=WebGPU +] interface WebGPU { + WebGPUAdapter getAdapter(WebGPUAdapterDescriptor descriptor); +};
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc new file mode 100644 index 0000000..1e1f49e --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc
@@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webgpu/webgpu_adapter.h" + +#include "third_party/blink/renderer/modules/webgpu/webgpu_device.h" + +namespace blink { + +// static +WebGPUAdapter* WebGPUAdapter::Create(const String& name) { + return new WebGPUAdapter(name); +} + +const String& WebGPUAdapter::name() const { + return name_; +} + +WebGPUDevice* WebGPUAdapter::createDevice() { + return WebGPUDevice::Create(this); +} + +WebGPUAdapter::WebGPUAdapter(const String& name) : name_(name) {} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h b/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h new file mode 100644 index 0000000..d1342c60 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h
@@ -0,0 +1,34 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_ADAPTER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_ADAPTER_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class WebGPUDevice; + +class WebGPUAdapter final : public ScriptWrappable { + DISALLOW_COPY_AND_ASSIGN(WebGPUAdapter); + DEFINE_WRAPPERTYPEINFO(); + + public: + static WebGPUAdapter* Create(const String& name); + + const String& name() const; + + WebGPUDevice* createDevice(); + + private: + WebGPUAdapter(const String& name); + + String name_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_ADAPTER_H_
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl b/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl new file mode 100644 index 0000000..7623ef7 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl
@@ -0,0 +1,11 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + RuntimeEnabled=WebGPU +] interface WebGPUAdapter { + readonly attribute DOMString name; + + WebGPUDevice createDevice(); +};
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_adapter_descriptor.idl b/third_party/blink/renderer/modules/webgpu/webgpu_adapter_descriptor.idl new file mode 100644 index 0000000..4c9a6ca --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_adapter_descriptor.idl
@@ -0,0 +1,13 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +enum WebGPUPowerPreference { + "default", + "low-power", + "high-performance", +}; + +dictionary WebGPUAdapterDescriptor { + WebGPUPowerPreference powerPreference = "default"; +};
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_device.cc b/third_party/blink/renderer/modules/webgpu/webgpu_device.cc new file mode 100644 index 0000000..2364f6e --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_device.cc
@@ -0,0 +1,27 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webgpu/webgpu_device.h" + +#include "third_party/blink/renderer/modules/webgpu/webgpu_adapter.h" + +namespace blink { + +// static +WebGPUDevice* WebGPUDevice::Create(WebGPUAdapter* adapter) { + return new WebGPUDevice(adapter); +} + +WebGPUAdapter* WebGPUDevice::adapter() const { + return adapter_; +} + +void WebGPUDevice::Trace(blink::Visitor* visitor) { + visitor->Trace(adapter_); + ScriptWrappable::Trace(visitor); +} + +WebGPUDevice::WebGPUDevice(WebGPUAdapter* adapter) : adapter_(adapter) {} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_device.h b/third_party/blink/renderer/modules/webgpu/webgpu_device.h new file mode 100644 index 0000000..9fa78127 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_device.h
@@ -0,0 +1,33 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_DEVICE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_DEVICE_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class WebGPUAdapter; + +class WebGPUDevice final : public ScriptWrappable { + DISALLOW_COPY_AND_ASSIGN(WebGPUDevice); + DEFINE_WRAPPERTYPEINFO(); + + public: + static WebGPUDevice* Create(WebGPUAdapter*); + + WebGPUAdapter* adapter() const; + + void Trace(blink::Visitor*) override; + + private: + WebGPUDevice(WebGPUAdapter*); + + Member<WebGPUAdapter> adapter_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_DEVICE_H_
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_device.idl b/third_party/blink/renderer/modules/webgpu/webgpu_device.idl new file mode 100644 index 0000000..e7fb903 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/webgpu_device.idl
@@ -0,0 +1,9 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + RuntimeEnabled=WebGPU +] interface WebGPUDevice { + readonly attribute WebGPUAdapter adapter; +};
diff --git a/third_party/blink/renderer/modules/webgpu/window_webgpu.cc b/third_party/blink/renderer/modules/webgpu/window_webgpu.cc new file mode 100644 index 0000000..1a57845 --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/window_webgpu.cc
@@ -0,0 +1,45 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webgpu/window_webgpu.h" + +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/modules/webgpu/webgpu.h" + +namespace blink { + +const char WindowWebGPU::kSupplementName[] = "WindowWebGPU"; + +// static +WindowWebGPU& WindowWebGPU::From(LocalDOMWindow& window) { + WindowWebGPU* supplement = + Supplement<LocalDOMWindow>::From<WindowWebGPU>(window); + if (!supplement) { + supplement = new WindowWebGPU(window); + ProvideTo(window, supplement); + } + return *supplement; +} + +// static +WebGPU* WindowWebGPU::webgpu(LocalDOMWindow& window) { + return WindowWebGPU::From(window).webgpu(); +} + +WebGPU* WindowWebGPU::webgpu() const { + if (!webgpu_) { + webgpu_ = WebGPU::Create(); + } + return webgpu_.Get(); +} + +void WindowWebGPU::Trace(blink::Visitor* visitor) { + visitor->Trace(webgpu_); + Supplement<LocalDOMWindow>::Trace(visitor); +} + +WindowWebGPU::WindowWebGPU(LocalDOMWindow& window) + : Supplement<LocalDOMWindow>(window) {} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/window_webgpu.h b/third_party/blink/renderer/modules/webgpu/window_webgpu.h new file mode 100644 index 0000000..426040f --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/window_webgpu.h
@@ -0,0 +1,37 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WINDOW_WEBGPU_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WINDOW_WEBGPU_H_ + +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class WebGPU; +class LocalDOMWindow; + +class WindowWebGPU final : public GarbageCollected<WindowWebGPU>, + public Supplement<LocalDOMWindow> { + USING_GARBAGE_COLLECTED_MIXIN(WindowWebGPU); + + public: + static const char kSupplementName[]; + + static WindowWebGPU& From(LocalDOMWindow&); + static WebGPU* webgpu(LocalDOMWindow&); + WebGPU* webgpu() const; + + void Trace(blink::Visitor*) override; + + private: + explicit WindowWebGPU(LocalDOMWindow&); + + mutable Member<WebGPU> webgpu_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WINDOW_WEBGPU_H_
diff --git a/third_party/blink/renderer/modules/webgpu/window_webgpu.idl b/third_party/blink/renderer/modules/webgpu/window_webgpu.idl new file mode 100644 index 0000000..344cd7d --- /dev/null +++ b/third_party/blink/renderer/modules/webgpu/window_webgpu.idl
@@ -0,0 +1,10 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + RuntimeEnabled=WebGPU, + ImplementedAs=WindowWebGPU +] partial interface Window { + [Replaceable, SameObject] readonly attribute WebGPU webgpu; +};
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc index 3c4dde6..eee8ae58 100644 --- a/third_party/blink/renderer/platform/exported/web_url_response.cc +++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -70,28 +70,16 @@ } // namespace -// The purpose of this struct is to permit allocating a ResourceResponse on the -// heap, which is otherwise disallowed by the DISALLOW_NEW_EXCEPT_PLACEMENT_NEW -// annotation on ResourceResponse. -struct WebURLResponse::ResourceResponseContainer { - ResourceResponseContainer() = default; - - explicit ResourceResponseContainer(const ResourceResponse& r) - : resource_response(r) {} - - ResourceResponse resource_response; -}; - WebURLResponse::~WebURLResponse() = default; WebURLResponse::WebURLResponse() - : owned_resource_response_(new ResourceResponseContainer()), - resource_response_(&owned_resource_response_->resource_response) {} + : owned_resource_response_(std::make_unique<ResourceResponse>()), + resource_response_(owned_resource_response_.get()) {} WebURLResponse::WebURLResponse(const WebURLResponse& r) : owned_resource_response_( - new ResourceResponseContainer(*r.resource_response_)), - resource_response_(&owned_resource_response_->resource_response) {} + std::make_unique<ResourceResponse>(*r.resource_response_)), + resource_response_(owned_resource_response_.get()) {} WebURLResponse::WebURLResponse(const WebURL& url) : WebURLResponse() { SetURL(url);
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc index 2fce804..40395ce 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -1361,6 +1361,17 @@ layer_state_->offset = layer_offset; } +void GraphicsLayer::SetContentsLayerState(const PropertyTreeState& layer_state, + const IntPoint& layer_offset) { + if (!contents_layer_state_) { + contents_layer_state_ = + std::make_unique<LayerState>(LayerState{layer_state, layer_offset}); + return; + } + contents_layer_state_->state = layer_state; + contents_layer_state_->offset = layer_offset; +} + scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList( PaintingControlSetting painting_control) { TRACE_EVENT0("blink,benchmark", "GraphicsLayer::PaintContents");
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.h b/third_party/blink/renderer/platform/graphics/graphics_layer.h index 2d00839..bd93646 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.h +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -290,6 +290,17 @@ } IntPoint GetOffsetFromTransformNode() const { return layer_state_->offset; } + void SetContentsLayerState(const PropertyTreeState&, + const IntPoint& layer_offset); + const PropertyTreeState& GetContentsPropertyTreeState() const { + return contents_layer_state_ ? contents_layer_state_->state + : GetPropertyTreeState(); + } + IntPoint GetContentsOffsetFromTransformNode() const { + return contents_layer_state_ ? contents_layer_state_->offset + : GetOffsetFromTransformNode(); + } + // Capture the last painted result into a PaintRecord. This GraphicsLayer // must DrawsContent. The result is never nullptr. sk_sp<PaintRecord> CapturePaintRecord() const; @@ -438,6 +449,7 @@ IntPoint offset; }; std::unique_ptr<LayerState> layer_state_; + std::unique_ptr<LayerState> contents_layer_state_; std::unique_ptr<RasterInvalidator> raster_invalidator_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h index fec4db50..05ba712 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -61,8 +61,6 @@ // member variable to this class, do not forget to add the corresponding // one in CrossThreadResourceResponseData and write copying logic. class PLATFORM_EXPORT ResourceResponse final { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); - public: enum HTTPVersion : uint8_t { kHTTPVersionUnknown,
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 09552079..4d9dc45d 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -255,7 +255,7 @@ }, { name: "CSSEnvironmentVariables", - status: "experimental", + status: "stable", }, { name: "CSSFocusVisible",
diff --git a/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h b/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h index 3b01b24..e3ee7c91 100644 --- a/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h +++ b/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h
@@ -23,7 +23,6 @@ : public RefCountedThreadSafe<GracefulQueueShutdownHelper> { public: GracefulQueueShutdownHelper(); - ~GracefulQueueShutdownHelper(); void GracefullyShutdownTaskQueue( std::unique_ptr<internal::TaskQueueImpl> queue); @@ -33,6 +32,10 @@ std::vector<std::unique_ptr<internal::TaskQueueImpl>> TakeQueues(); private: + // This class is ref-counted so it controls its own lifetime. + ~GracefulQueueShutdownHelper(); + friend class RefCountedThreadSafe<GracefulQueueShutdownHelper>; + Lock lock_; bool sequence_manager_deleted_; std::vector<std::unique_ptr<internal::TaskQueueImpl>> queues_;
diff --git a/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc b/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc index 797d0fc..03ef8432 100644 --- a/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc +++ b/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc
@@ -4,9 +4,7 @@ #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" -#include "base/bind.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" namespace base { namespace sequence_manager {
diff --git a/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h b/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h index 3465ba4..7489b83f 100644 --- a/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h +++ b/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h
@@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_ -#include <set> - #include "base/macros.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain_forward.h"
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.cc index 30e37a3..b3aae71 100644 --- a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.cc
@@ -11,14 +11,15 @@ #include "base/bit_cast.h" #include "base/compiler_specific.h" #include "base/debug/crash_logging.h" +#include "base/memory/ptr_util.h" #include "base/rand_util.h" #include "base/task/sequence_manager/task_time_observer.h" #include "base/time/default_tick_clock.h" #include "base/time/tick_clock.h" #include "base/trace_event/trace_event.h" +#include "build/build_config.h" #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" #include "third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" @@ -26,6 +27,12 @@ namespace base { namespace sequence_manager { +std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread() { + return internal::SequenceManagerImpl::CreateOnCurrentThread(); +} + +namespace internal { + namespace { constexpr base::TimeDelta kLongTaskTraceEventThreshold = @@ -47,10 +54,6 @@ } // namespace -std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread() { - return SequenceManagerImpl::CreateOnCurrentThread(); -} - SequenceManagerImpl::SequenceManagerImpl( std::unique_ptr<internal::ThreadController> controller) : graceful_shutdown_helper_(new internal::GracefulQueueShutdownHelper()), @@ -113,7 +116,7 @@ // static std::unique_ptr<SequenceManagerImpl> SequenceManagerImpl::CreateOnCurrentThread() { - return std::unique_ptr<SequenceManagerImpl>( + return WrapUnique( new SequenceManagerImpl(internal::ThreadControllerImpl::Create( MessageLoop::current(), DefaultTickClock::GetInstance()))); } @@ -402,12 +405,14 @@ if (executing_task->task_queue->GetQuiescenceMonitored()) main_thread_only().task_was_run_on_quiescence_monitored_queue = true; +#if !defined(OS_NACL) debug::SetCrashKeyString( main_thread_only().file_name_crash_key, executing_task->pending_task.posted_from.file_name()); debug::SetCrashKeyString( main_thread_only().function_name_crash_key, executing_task->pending_task.posted_from.function_name()); +#endif // OS_NACL if (executing_task->task_queue->GetShouldNotifyObservers()) { { @@ -685,10 +690,12 @@ const char* function_name_crash_key_name) { DCHECK(!main_thread_only().file_name_crash_key); DCHECK(!main_thread_only().function_name_crash_key); +#if !defined(OS_NACL) main_thread_only().file_name_crash_key = debug::AllocateCrashKeyString( file_name_crash_key_name, debug::CrashKeySize::Size64); main_thread_only().function_name_crash_key = debug::AllocateCrashKeyString( function_name_crash_key_name, debug::CrashKeySize::Size64); +#endif // OS_NACL } internal::TaskQueueImpl* SequenceManagerImpl::currently_executing_task_queue() @@ -698,5 +705,6 @@ return main_thread_only().task_execution_stack.rbegin()->task_queue; } +} // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h index 1a87728..dd3a94e 100644 --- a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h
@@ -35,6 +35,7 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" namespace base { + namespace debug { struct CrashKeyString; } // namespace debug @@ -42,20 +43,19 @@ namespace trace_event { class ConvertableToTraceFormat; } // namespace trace_event -} // namespace base -namespace base { namespace sequence_manager { -namespace internal { -class RealTimeDomain; -class TaskQueueImpl; -} // namespace internal - +class SequenceManagerForTest; class TaskQueue; class TaskTimeObserver; class TimeDomain; +namespace internal { + +class RealTimeDomain; +class TaskQueueImpl; + // The task queue manager provides N task queues and a selector interface for // choosing which task queue to service next. Each task queue consists of two // sub queues: @@ -145,7 +145,7 @@ std::unique_ptr<internal::ThreadController> controller); friend class internal::TaskQueueImpl; - friend class SequenceManagerForTest; + friend class ::base::sequence_manager::SequenceManagerForTest; private: enum class ProcessTaskResult { @@ -325,6 +325,7 @@ DISALLOW_COPY_AND_ASSIGN(SequenceManagerImpl); }; +} // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc index 9ffc98b..b160bf8 100644 --- a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc
@@ -47,6 +47,9 @@ namespace base { namespace sequence_manager { +namespace internal { +// To avoid symbol collisions in jumbo builds. +namespace sequence_manager_impl_unittest { class SequenceManagerTestBase : public testing::Test { protected: @@ -3184,5 +3187,7 @@ test_executed.Wait(); } +} // namespace sequence_manager_impl_unittest +} // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_perftest.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_perftest.cc index 477fcb4..70bd824 100644 --- a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_perftest.cc +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_perftest.cc
@@ -18,12 +18,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" #include "third_party/blink/renderer/platform/scheduler/base/test/mock_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/test/test_task_time_observer.h" -#include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" namespace base { namespace sequence_manager {
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue.cc index c03b41e7..2a7aafb 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue.cc +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue.cc
@@ -4,8 +4,7 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" -#include "base/bind_helpers.h" -#include "base/optional.h" +#include "base/bind.h" #include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h"
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h index 9cb7c114..3db0a4e5c 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h
@@ -7,9 +7,6 @@ #include <stddef.h> -#include <set> - -#include "base/compiler_specific.h" #include "base/macros.h" #include "base/pending_task.h" #include "base/threading/thread_checker.h"
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h index 0e85d67..7c8e91c 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h
@@ -7,6 +7,7 @@ namespace base { namespace sequence_manager { +namespace internal { // Used to describe the logic trigerred when a task queue is selected to // service. @@ -29,6 +30,7 @@ kCount = 9, }; +} // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h b/third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h index 566350e..460911a 100644 --- a/third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h +++ b/third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h
@@ -16,7 +16,7 @@ namespace base { namespace sequence_manager { -class SequenceManagerForTest : public SequenceManagerImpl { +class SequenceManagerForTest : public internal::SequenceManagerImpl { public: explicit SequenceManagerForTest( std::unique_ptr<internal::ThreadController> thread_controller); @@ -37,8 +37,8 @@ size_t QueuesToDeleteCount() const; size_t QueuesToShutdownCount(); - using SequenceManagerImpl::GetNextSequenceNumber; - using SequenceManagerImpl::WakeUpReadyDelayedQueues; + using internal::SequenceManagerImpl::GetNextSequenceNumber; + using internal::SequenceManagerImpl::WakeUpReadyDelayedQueues; }; } // namespace sequence_manager
diff --git a/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h b/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h index e6473caf..5e005c2 100644 --- a/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h +++ b/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h
@@ -17,6 +17,8 @@ namespace base { +// TODO(kraynov): https://crbug.com/828835 +// Consider going away from using MessageLoop in the renderer process. class MessageLoop; namespace sequence_manager { @@ -113,7 +115,7 @@ RepeatingClosure immediate_do_work_closure_; RepeatingClosure delayed_do_work_closure_; CancelableClosure cancelable_delayed_do_work_closure_; - SequencedTaskSource* sequence_ = nullptr; // NOT OWNED + SequencedTaskSource* sequence_ = nullptr; // Not owned. debug::TaskAnnotator task_annotator_; WeakPtrFactory<ThreadControllerImpl> weak_factory_;
diff --git a/third_party/blink/renderer/platform/scheduler/base/time_domain.cc b/third_party/blink/renderer/platform/scheduler/base/time_domain.cc index 25298477c..bcf7f0e 100644 --- a/third_party/blink/renderer/platform/scheduler/base/time_domain.cc +++ b/third_party/blink/renderer/platform/scheduler/base/time_domain.cc
@@ -20,7 +20,7 @@ } void TimeDomain::OnRegisterWithSequenceManager( - SequenceManagerImpl* sequence_manager) { + internal::SequenceManagerImpl* sequence_manager) { DCHECK(sequence_manager); DCHECK(!sequence_manager_); sequence_manager_ = sequence_manager;
diff --git a/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc b/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc index c744a854..476485e 100644 --- a/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc
@@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/test/simple_test_tick_clock.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" @@ -22,7 +22,7 @@ class TaskQueueImplForTest : public internal::TaskQueueImpl { public: - TaskQueueImplForTest(SequenceManagerImpl* sequence_manager, + TaskQueueImplForTest(internal::SequenceManagerImpl* sequence_manager, TimeDomain* time_domain, const TaskQueue::Spec& spec) : TaskQueueImpl(sequence_manager, time_domain, spec) {}
diff --git a/third_party/blink/renderer/platform/scheduler/base/work_queue.h b/third_party/blink/renderer/platform/scheduler/base/work_queue.h index 30c80640..fe1c7d5a 100644 --- a/third_party/blink/renderer/platform/scheduler/base/work_queue.h +++ b/third_party/blink/renderer/platform/scheduler/base/work_queue.h
@@ -5,10 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_WORK_QUEUE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_WORK_QUEUE_H_ -#include <stddef.h> - -#include <set> - #include "base/task/sequence_manager/enqueue_order.h" #include "base/task/sequence_manager/intrusive_heap.h" #include "base/task/sequence_manager/sequenced_task_source.h"
diff --git a/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc b/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc index 0d34d146b..94235c9 100644 --- a/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc +++ b/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc
@@ -70,8 +70,8 @@ bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); DCHECK(has_enqueue_order); size_t set_index = work_queue->work_queue_set_index(); - DCHECK_LT(set_index, work_queue_heaps_.size()) << " set_index = " - << set_index; + DCHECK_LT(set_index, work_queue_heaps_.size()) + << " set_index = " << set_index; // |work_queue| should not be in work_queue_heaps_[set_index]. DCHECK(!work_queue->heap_handle().IsValid()); work_queue_heaps_[set_index].insert({enqueue_order, work_queue}); @@ -136,8 +136,8 @@ } bool WorkQueueSets::IsSetEmpty(size_t set_index) const { - DCHECK_LT(set_index, work_queue_heaps_.size()) << " set_index = " - << set_index; + DCHECK_LT(set_index, work_queue_heaps_.size()) + << " set_index = " << set_index; return work_queue_heaps_[set_index].empty(); }
diff --git a/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h b/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h index aab5294..8e9fb97e 100644 --- a/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h +++ b/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h
@@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_WORK_QUEUE_SETS_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_WORK_QUEUE_SETS_H_ -#include <stddef.h> - #include <map> #include <vector>
diff --git a/third_party/blink/renderer/platform/scheduler/common/idle_helper.h b/third_party/blink/renderer/platform/scheduler/common/idle_helper.h index c14ed39..a7f5f49 100644 --- a/third_party/blink/renderer/platform/scheduler/common/idle_helper.h +++ b/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
@@ -10,7 +10,6 @@ #include "base/message_loop/message_loop.h" #include "third_party/blink/public/platform/scheduler/single_thread_idle_task_runner.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" #include "third_party/blink/renderer/platform/scheduler/common/cancelable_closure_holder.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h index 05b9930..42e7ca8 100644 --- a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h +++ b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
@@ -8,6 +8,7 @@ #include "base/optional.h" #include "base/time/time.h" #include "third_party/blink/public/platform/web_thread_type.h" +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" #include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h index 3ee6026..81963783 100644 --- a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h +++ b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
@@ -12,6 +12,7 @@ #include "base/message_loop/message_loop.h" #include "base/time/tick_clock.h" #include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h b/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h index 959a788..8d7bb3e 100644 --- a/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h +++ b/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_THROTTLED_TIME_DOMAIN_H_ #include "base/macros.h" +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain_forward.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h index bebf668..09526dc 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/time/time_override.h" +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain_forward.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index a1cc862b..5739991 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -30,7 +30,6 @@ #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/child/process_state.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc index dde8b23..daf1088 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -24,7 +24,6 @@ #include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/public/platform/web_mouse_wheel_event.h" #include "third_party/blink/public/platform/web_touch_event.h" -#include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h b/third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h index bb331955..903d7eb 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_PRIORITIZE_COMPOSITING_AFTER_INPUT_EXPERIMENT_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_PRIORITIZE_COMPOSITING_AFTER_INPUT_EXPERIMENT_H_ +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/test/lazy_thread_controller_for_test.h b/third_party/blink/renderer/platform/scheduler/test/lazy_thread_controller_for_test.h index 5b67686..325baf6 100644 --- a/third_party/blink/renderer/platform/scheduler/test/lazy_thread_controller_for_test.h +++ b/third_party/blink/renderer/platform/scheduler/test/lazy_thread_controller_for_test.h
@@ -10,6 +10,9 @@ #include "base/threading/platform_thread.h" #include "third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h" +// TODO(kraynov): Move to //base/task/sequence_manager/test to avoid +// cross-component exposure of internal ThreadControllerImpl. + namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc b/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc index 3bfb76a6d..75e3dad 100644 --- a/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc +++ b/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc
@@ -9,7 +9,6 @@ #include "base/single_thread_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/test/lazy_thread_controller_for_test.h"
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h index 4e4c1e44..b247336c 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h +++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_TASK_QUEUE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_TASK_QUEUE_H_ +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" namespace blink {
diff --git a/third_party/quic_trace/BUILD.gn b/third_party/quic_trace/BUILD.gn new file mode 100644 index 0000000..eb83eeaf --- /dev/null +++ b/third_party/quic_trace/BUILD.gn
@@ -0,0 +1,36 @@ +import("//third_party/protobuf/proto_library.gni") + +# Since most of the Chromium uses proto_lite, modify the source proto file to +# use the lite runtime. +action("quic_trace_proto_lite_runtime") { + script = "append_lite_runtime.py" + inputs = [ + "src/lib/quic_trace.proto", + ] + outputs = [ + "$target_gen_dir/quic_trace.proto", + ] + args = + rebase_path(inputs, root_build_dir) + rebase_path(outputs, root_build_dir) +} + +proto_library("quic_trace_proto") { + # QUIC trace is only used in unit tests and stand-alone command line tools. + # It is not linked into the network stack itself due to the Cronet binary + # size concerns. + visibility = [ "//net:quic_test_tools" ] + + sources = [ + "$target_gen_dir/quic_trace.proto", + ] + deps = [ + ":quic_trace_proto_lite_runtime", + ] + component_build_force_source_set = true + testonly = true + + # The result can be included as third_party/quic_trace/lib/quic_trace.pb.h + proto_out_dir = rebase_path(".", "//") + "/lib" + + extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] +}
diff --git a/third_party/quic_trace/OWNERS b/third_party/quic_trace/OWNERS new file mode 100644 index 0000000..3a9a3cb --- /dev/null +++ b/third_party/quic_trace/OWNERS
@@ -0,0 +1,5 @@ +rch@chromium.org +vasilvv@chromium.org +zhongyi@chromium.org + +file://net/OWNERS
diff --git a/third_party/quic_trace/README.chromium b/third_party/quic_trace/README.chromium new file mode 100644 index 0000000..e2112438 --- /dev/null +++ b/third_party/quic_trace/README.chromium
@@ -0,0 +1,11 @@ +Name: QUIC trace format description and utilities +Short Name: quic-trace +URL: https://github.com/google/quic-trace +Version: git +License: Apache 2.0 +License File: NOT_SHIPPED +Security Critical: no + +Description: +A format for transcribing all connection-related events that has occurred +througout a QUIC session.
diff --git a/third_party/quic_trace/append_lite_runtime.py b/third_party/quic_trace/append_lite_runtime.py new file mode 100755 index 0000000..7d1aeb0 --- /dev/null +++ b/third_party/quic_trace/append_lite_runtime.py
@@ -0,0 +1,21 @@ +#!/usr/bin/env python +# Copyright (c) 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +Appends the LITE_RUNTIME annotation to a proto2 protocol buffer file. +""" + +import sys + +if len(sys.argv) != 3: + sys.stderr.write("Usage: append_lite_runtime.py in.proto out.proto\n") + sys.exit(1) + +with open(sys.argv[1], "rb") as source: + with open(sys.argv[2], "wb") as output: + for line in source: + output.write(line) + if line.strip() == 'syntax = "proto2";': + output.write("option optimize_for = LITE_RUNTIME;\n")
diff --git a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp index b906f7ad..9df0b47 100644 --- a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp +++ b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
@@ -161,9 +161,8 @@ auto constructor_conversion = cxxConstructExpr( is_once_callback, argumentCountIs(1), hasArgument(0, ignoringImplicit(parameter_construction))); - auto implicit_conversion = implicitCastExpr( - is_once_callback, hasSourceExpression(constructor_conversion)); - return implicit_conversion; + return implicitCastExpr(is_once_callback, + hasSourceExpression(constructor_conversion)); } void run(const MatchFinder::MatchResult& result) override { @@ -577,6 +576,64 @@ Replacements* replacements_; }; +// Remove base::AdaptCallbackForRepeating() where resulting +// base::RepeatingCallback is implicitly converted into base::OnceCallback. +// Example: +// // Before +// base::PostTask( +// FROM_HERE, +// base::AdaptCallbackForRepeating(base::BindOnce(&Foo))); +// base::OnceCallback<void()> cb = base::AdaptCallbackForRepeating( +// base::OnceBind(&Foo)); +// +// // After +// base::PostTask(FROM_HERE, base::BindOnce(&Foo)); +// base::OnceCallback<void()> cb = base::BindOnce(&Foo); +class AdaptCallbackForRepeatingRewriter : public MatchFinder::MatchCallback, + public Rewriter { + public: + explicit AdaptCallbackForRepeatingRewriter(Replacements* replacements) + : replacements_(replacements) {} + + StatementMatcher GetMatcher() { + auto is_once_callback = hasType(hasCanonicalType(hasDeclaration( + classTemplateSpecializationDecl(hasName("::base::OnceCallback"))))); + auto is_repeating_callback = + hasType(hasCanonicalType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::base::RepeatingCallback"))))); + + auto adapt_callback_call = + callExpr( + callee(namedDecl(hasName("::base::AdaptCallbackForRepeating")))) + .bind("target"); + auto parameter_construction = + cxxConstructExpr(is_repeating_callback, argumentCountIs(1), + hasArgument(0, ignoringImplicit(adapt_callback_call))); + auto constructor_conversion = cxxConstructExpr( + is_once_callback, argumentCountIs(1), + hasArgument(0, ignoringImplicit(parameter_construction))); + return implicitCastExpr(is_once_callback, + hasSourceExpression(constructor_conversion)); + } + + void run(const MatchFinder::MatchResult& result) override { + auto* target = result.Nodes.getNodeAs<clang::CallExpr>("target"); + + auto left = clang::CharSourceRange::getTokenRange( + result.SourceManager->getSpellingLoc(target->getLocStart()), + result.SourceManager->getSpellingLoc(target->getArg(0)->getExprLoc()) + .getLocWithOffset(-1)); + replacements_->emplace_back(*result.SourceManager, left, ""); + auto r_paren = clang::CharSourceRange::getTokenRange( + result.SourceManager->getSpellingLoc(target->getRParenLoc()), + result.SourceManager->getSpellingLoc(target->getRParenLoc())); + replacements_->emplace_back(*result.SourceManager, r_paren, ""); + } + + private: + Replacements* replacements_; +}; + llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); llvm::cl::OptionCategory rewriter_category("Rewriter Options"); @@ -588,6 +645,7 @@ bind_to_bind_once pass_by_value add_std_move + remove_unneeded_adapt_callback The default is remove_unneeded_passed. )"), llvm::cl::init("remove_unneeded_passed"), @@ -623,6 +681,12 @@ auto add_std_move = llvm::make_unique<AddStdMoveRewriter>(&replacements); match_finder.addMatcher(add_std_move->GetMatcher(), add_std_move.get()); rewriter = std::move(add_std_move); + } else if (rewriter_option == "remove_unneeded_adapt_callback") { + auto remove_unneeded_adapt_callback = + llvm::make_unique<AdaptCallbackForRepeatingRewriter>(&replacements); + match_finder.addMatcher(remove_unneeded_adapt_callback->GetMatcher(), + remove_unneeded_adapt_callback.get()); + rewriter = std::move(remove_unneeded_adapt_callback); } else { abort(); }
diff --git a/tools/clang/base_bind_rewriters/tests/callback.h b/tools/clang/base_bind_rewriters/tests/callback.h index f89836ed..2872039 100644 --- a/tools/clang/base_bind_rewriters/tests/callback.h +++ b/tools/clang/base_bind_rewriters/tests/callback.h
@@ -95,6 +95,11 @@ return RepeatingCallback<void()>(); } +RepeatingCallback<void()> AdaptCallbackForRepeating( + OnceCallback<void()> callback) { + return Callback<void()>(); +} + } // namespace base #endif // TOOLS_CLANG_BASE_BIND_REWRITERS_TESTS_CALLBACK_H_
diff --git a/tools/clang/base_bind_rewriters/tests/remove-adapt-callback-for-repeating-expected.cc b/tools/clang/base_bind_rewriters/tests/remove-adapt-callback-for-repeating-expected.cc new file mode 100644 index 0000000..62275279 --- /dev/null +++ b/tools/clang/base_bind_rewriters/tests/remove-adapt-callback-for-repeating-expected.cc
@@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "callback.h" + +void Foo(base::OnceClosure) {} + +void Test() { + base::OnceClosure cb = base::BindOnce([] {}); + Foo(base::BindOnce([] {})); + + using namespace base; + + OnceClosure cb2 = BindOnce([] {}); + Foo(BindOnce([] {})); + + OnceClosure cb3 = base::BindOnce([] {}); +}
diff --git a/tools/clang/base_bind_rewriters/tests/remove-adapt-callback-for-repeating-original.cc b/tools/clang/base_bind_rewriters/tests/remove-adapt-callback-for-repeating-original.cc new file mode 100644 index 0000000..233e262 --- /dev/null +++ b/tools/clang/base_bind_rewriters/tests/remove-adapt-callback-for-repeating-original.cc
@@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "callback.h" + +void Foo(base::OnceClosure) {} + +void Test() { + base::OnceClosure cb = base::AdaptCallbackForRepeating(base::BindOnce([] {})); + Foo(base::AdaptCallbackForRepeating(base::BindOnce([] {}))); + + using namespace base; + + OnceClosure cb2 = AdaptCallbackForRepeating(BindOnce([] {})); + Foo(AdaptCallbackForRepeating(BindOnce([] {}))); + + OnceClosure cb3 = base::BindOnce([] {}); +}
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index fb86347a..9c1b447 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2999,6 +2999,7 @@ <int value="11" label="Offline content notification task"/> <int value="12" label="WebAPK update task"/> <int value="13" label="Download resumption task"/> + <int value="14" label="Feed refresh task"/> </enum> <enum name="BackgroundTracingState"> @@ -28014,6 +28015,7 @@ <int value="-78035185" label="custom_summary"/> <int value="-77872983" label="BookmarkAppsMac:disabled"/> <int value="-76631048" label="disable-offline-auto-reload-visible-only"/> + <int value="-75418012" label="ContextualSuggestionsOptOut:disabled"/> <int value="-72455054" label="WebVrAutopresent:disabled"/> <int value="-70595606" label="ash-enable-unified-desktop"/> <int value="-69427025" label="OfflinePagesPrefetchingUI:enabled"/> @@ -29036,6 +29038,7 @@ <int value="2101151142" label="disable-direct-write"/> <int value="2104788328" label="use-winrt-midi-api"/> <int value="2113804526" label="EnableAppShortcutSearch:enabled"/> + <int value="2114843059" label="ContextualSuggestionsOptOut:enabled"/> <int value="2119964154" label="enable-download-resumption"/> <int value="2121056855" label="IncreaseInputAudioBufferSize:disabled"/> <int value="2121550859" label="PreferHtmlOverPlugins:enabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 44445b7..e18ad55 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -49734,6 +49734,9 @@ </histogram> <histogram name="Net.ErrAborted.ReceivedBytes" units="bytes"> + <obsolete> + Removed from Chromium as of 2018/7/2. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> The TotalReceivedBytes() at the time the request finishes with ERR_ABORTED. @@ -49741,6 +49744,9 @@ </histogram> <histogram name="Net.ErrAborted.SentBytes" units="bytes"> + <obsolete> + Removed from Chromium as of 2018/7/2. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> The TotalSentBytes() at the time the request finishes with ERR_ABORTED. @@ -53767,6 +53773,9 @@ </histogram> <histogram name="Net.RequestTime2Success.MainFrame" units="ms"> + <obsolete> + Removed from Chromium as of 2018/7/2. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> The amount of time between request initiation and request completion for @@ -53775,6 +53784,9 @@ </histogram> <histogram name="Net.RequestTime2Success.Subresource" units="ms"> + <obsolete> + Removed from Chromium as of 2018/7/2. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> The amount of time between request initiation and request completion for @@ -53892,6 +53904,9 @@ </histogram> <histogram name="Net.ResourceLoader.TimeToURLRequestStart" units="ms"> + <obsolete> + Removed from Chromium as of 2018/7/2. + </obsolete> <owner>csharrison@chromium.org</owner> <summary> The time elapsed from URLRequest creation to when a ResourceLoader actually
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py index 36f79963..815ce9b1 100644 --- a/tools/perf/benchmarks/media.py +++ b/tools/perf/benchmarks/media.py
@@ -37,10 +37,6 @@ # 'toplevel' category provides CPU time slices used by # cpuTimeMetric. category_filter.AddIncludedCategory('toplevel') - # 'rail' category is used by powerMetric to attribute different period of - # time to different activities, such as video_animation, etc. - category_filter.AddIncludedCategory('rail') - # Collect media related events required by mediaMetric. category_filter.AddIncludedCategory('media') @@ -48,15 +44,14 @@ category_filter.AddDisabledByDefault('disabled-by-default-memory-infra') options = timeline_based_measurement.Options(category_filter) - options.config.enable_battor_trace = True options.config.enable_android_graphics_memtrack = True # Setting an empty memory dump config disables periodic dumps. options.config.chrome_trace_config.SetMemoryDumpConfig( chrome_trace_config.MemoryDumpConfig()) - options.SetTimelineBasedMetrics(['powerMetric', 'mediaMetric', - 'cpuTimeMetric', 'memoryMetric']) + options.SetTimelineBasedMetrics(['mediaMetric', 'cpuTimeMetric', + 'memoryMetric']) return options @classmethod
diff --git a/tools/perf/benchmarks/power.py b/tools/perf/benchmarks/power.py index 71d6843..f97accb4 100644 --- a/tools/perf/benchmarks/power.py +++ b/tools/perf/benchmarks/power.py
@@ -12,20 +12,16 @@ from telemetry.web_perf import timeline_based_measurement -class _BattOrPowerBenchmark(perf_benchmark.PerfBenchmark): +class _PowerBenchmark(perf_benchmark.PerfBenchmark): + """A benchmark that indirectly measures power through CPU time.""" def CreateCoreTimelineBasedMeasurementOptions(self): category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter( filter_string='toplevel') options = timeline_based_measurement.Options(category_filter) - options.config.chrome_trace_config.category_filter.AddFilterString('rail') - options.config.enable_atrace_trace = True - options.config.atrace_config.categories = ['sched'] - options.config.enable_battor_trace = True options.config.enable_chrome_trace = True options.config.enable_cpu_trace = True - options.SetTimelineBasedMetrics( - ['powerMetric', 'clockSyncLatencyMetric', 'cpuTimeMetric']) + options.SetTimelineBasedMetrics(['cpuTimeMetric']) return options @@ -44,6 +40,8 @@ return 'power.typical_10_mobile' +# TODO(charliea): Delete this benchmark now that we're no longer measuring +# ground-truth power. @benchmark.Owner(emails=['charliea@chromium.org']) class IdlePlatformBenchmark(perf_benchmark.PerfBenchmark): """Idle platform benchmark. @@ -55,14 +53,11 @@ def CreateCoreTimelineBasedMeasurementOptions(self): options = timeline_based_measurement.Options( chrome_trace_category_filter.ChromeTraceCategoryFilter()) - options.config.enable_battor_trace = True options.config.enable_cpu_trace = True # Atrace tracing agent autodetects if its android and only runs if it is. options.config.enable_atrace_trace = True options.config.enable_chrome_trace = False options.SetTimelineBasedMetrics([ - 'clockSyncLatencyMetric', - 'powerMetric', 'tracingMetric' ]) return options @@ -76,7 +71,7 @@ @benchmark.Owner(emails=['charliea@chromium.org']) -class PowerDesktop(_BattOrPowerBenchmark): +class PowerDesktop(_PowerBenchmark): SUPPORTED_PLATFORMS = [story.expectations.ALL_DESKTOP] def CreateStorySet(self, options):
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py index 4e672089..a0217c84 100644 --- a/tools/perf/benchmarks/system_health.py +++ b/tools/perf/benchmarks/system_health.py
@@ -41,13 +41,10 @@ cat_filter.AddIncludedCategory('accessibility') options = timeline_based_measurement.Options(cat_filter) - options.config.enable_battor_trace = True options.config.enable_chrome_trace = True options.config.enable_cpu_trace = True options.SetTimelineBasedMetrics([ - 'clockSyncLatencyMetric', 'cpuTimeMetric', - 'powerMetric', 'tracingMetric', 'accessibilityMetric', 'limitedCpuTimeMetric'
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 3b89d4fe..3a356d9 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -696,9 +696,9 @@ def get_tests_in_performance_test_suite(): tests = sets.Set() add_benchmarks_from_sharding_map( - tests, "shard_maps/desktop_26_shard_map.json") + tests, "shard_maps/linux_perf_shard_map.json") add_benchmarks_from_sharding_map( - tests, "shard_maps/mobile_39_shard_map.json") + tests, "shard_maps/pixel2_7_shard_map.json") return tests @@ -707,7 +707,9 @@ if os.path.exists(path): with open(path) as f: sharding_map = json.load(f) - for _, benchmarks in sharding_map.iteritems(): + for shard, benchmarks in sharding_map.iteritems(): + if "extra_infos" in shard: + continue for benchmark, _ in benchmarks['benchmarks'].iteritems(): tests.add(benchmark) @@ -855,7 +857,7 @@ ], 'platform': 'mac', 'dimension': { - 'pool': 'Chrome-perf-fyi', + 'pool': 'chrome.tests.perf-fyi', 'os': 'Mac-10.12', 'gpu': '8086:0a2e' },
diff --git a/tools/perf/core/perf_json_config_validator.py b/tools/perf/core/perf_json_config_validator.py index b997378..28a92ba 100644 --- a/tools/perf/core/perf_json_config_validator.py +++ b/tools/perf/core/perf_json_config_validator.py
@@ -12,7 +12,7 @@ 'gpu', 'device_ids', 'os', 'pool', 'perf_tests', 'perf_tests_with_args', 'device_os', 'device_type', 'device_os_flavor', 'id'} _VALID_PERF_POOLS = { - 'Chrome-perf', 'Chrome-perf-fyi', + 'Chrome-perf', 'chrome.tests.perf', 'chrome.tests.perf-webview', 'chrome.tests.perf-fyi', 'chrome.tests.perf-webview-fyi'}
diff --git a/tools/perf/core/shard_maps/android_go_14_shard_map.json b/tools/perf/core/shard_maps/android_go_14_shard_map.json index 59603bc..704ff65 100644 --- a/tools/perf/core/shard_maps/android_go_14_shard_map.json +++ b/tools/perf/core/shard_maps/android_go_14_shard_map.json
@@ -1,215 +1,126 @@ { "0": { "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": { - "end": 1 + "system_health.common_mobile": {}, + "start_with_url.warm.startup_pages": {}, + "start_with_url.cold.startup_pages": {}, + "system_health.memory_mobile": {}, + "system_health.webview_startup": {}, + "power.typical_10_mobile": { + "end": 3 } } }, "1": { "benchmarks": { - "blink_perf.dom": { - "begin": 1 - }, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": {}, - "blink_perf.owp_storage": { - "end": 3 + "power.typical_10_mobile": { + "begin": 3, + "end": 6 } } }, "2": { "benchmarks": { - "blink_perf.owp_storage": { - "begin": 3 - }, - "blink_perf.paint": {}, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": { - "end": 6 + "power.typical_10_mobile": { + "begin": 6, + "end": 9 } } }, "3": { "benchmarks": { - "blink_perf.svg": { - "begin": 6 + "power.typical_10_mobile": { + "begin": 9 }, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {}, - "kraken": {}, - "loading.desktop": {}, - "loading.mobile": { - "end": 9 + "memory.top_10_mobile": { + "end": 1 } } }, "4": { "benchmarks": { - "loading.mobile": { - "begin": 9, - "end": 34 + "memory.top_10_mobile": { + "begin": 1, + "end": 3 } } }, "5": { "benchmarks": { - "loading.mobile": { - "begin": 34, - "end": 90 + "memory.top_10_mobile": { + "begin": 3, + "end": 5 } } }, "6": { "benchmarks": { - "loading.mobile": { - "begin": 90 - }, - "media.desktop": {}, - "media.mobile": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { - "end": 12 + "begin": 5, + "end": 7 } } }, "7": { "benchmarks": { "memory.top_10_mobile": { - "begin": 12 - }, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, - "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": { - "end": 16 + "begin": 7, + "end": 9 } } }, "8": { "benchmarks": { - "rasterize_and_record_micro.top_25": { - "begin": 16 - }, - "rendering.desktop": {}, - "rendering.mobile": { - "end": 93 + "memory.top_10_mobile": { + "begin": 9, + "end": 10 } } }, "9": { "benchmarks": { - "rendering.mobile": { - "begin": 93 - }, - "scheduler.tough_scheduling_cases": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": { - "end": 9 + "memory.top_10_mobile": { + "begin": 10, + "end": 12 } } }, "10": { "benchmarks": { - "smoothness.gpu_rasterization.tough_scrolling_cases": { - "begin": 9 - }, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "smoothness.image_decoding_cases": {}, - "smoothness.key_desktop_move_cases": {}, - "smoothness.key_mobile_sites_smooth": {}, - "smoothness.key_silk_cases": {}, - "smoothness.maps": {}, - "smoothness.pathological_mobile_sites": {}, - "smoothness.simple_mobile_sites": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "smoothness.top_25_smooth": {} + "memory.top_10_mobile": { + "begin": 12, + "end": 14 + } } }, "11": { "benchmarks": { - "smoothness.tough_ad_cases": {}, - "smoothness.tough_animation_cases": {}, - "smoothness.tough_canvas_cases": {}, - "smoothness.tough_filters_cases": {}, - "smoothness.tough_image_decode_cases": {}, - "smoothness.tough_path_rendering_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "smoothness.tough_scrolling_cases": {}, - "smoothness.tough_texture_upload_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "smoothness.tough_webgl_cases": {}, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": {}, - "system_health.common_mobile": {}, - "system_health.memory_desktop": {}, - "system_health.memory_mobile": {}, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "thread_times.key_hit_test_cases": {}, - "thread_times.key_idle_power_cases": {}, - "thread_times.key_mobile_sites_smooth": {}, - "thread_times.key_noop_cases": {}, - "thread_times.key_silk_cases": {}, - "thread_times.simple_mobile_sites": {}, - "thread_times.tough_compositor_cases": {}, - "thread_times.tough_scrolling_cases": { - "end": 32 + "memory.top_10_mobile": { + "begin": 14, + "end": 16 } } }, "12": { "benchmarks": { - "thread_times.tough_scrolling_cases": { - "begin": 32 - }, - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, - "v8.browsing_mobile": { - "end": 24 + "memory.top_10_mobile": { + "begin": 16, + "end": 18 } } }, "13": { "benchmarks": { - "v8.browsing_mobile": { - "begin": 24 - }, - "v8.browsing_mobile-future": {}, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} + "memory.top_10_mobile": { + "begin": 18 + } } }, "extra_infos": { - "num_stories": 2401, - "predicted_min_shard_time": 6936.110622523241, - "predicted_min_shard_index": 4, - "predicted_max_shard_time": 7595.144805609757, - "predicted_max_shard_index": 5 + "num_stories": 160, + "predicted_min_shard_time": 224.836488080808, + "predicted_min_shard_index": 8, + "predicted_max_shard_time": 599.3532815757576, + "predicted_max_shard_index": 3 } }
diff --git a/tools/perf/core/shard_maps/benchmark_android_bot_map.json b/tools/perf/core/shard_maps/benchmark_android_bot_map.json deleted file mode 100644 index 087ea7cd..0000000 --- a/tools/perf/core/shard_maps/benchmark_android_bot_map.json +++ /dev/null
@@ -1,250 +0,0 @@ -{ - "0": { - "benchmarks": { - "power.desktop": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "tab_switching.typical_25": {} - } - }, - "1": { - "benchmarks": { - "smoothness.gpu_rasterization.polymer": {}, - "thread_times.key_hit_test_cases": {} - } - }, - "10": { - "benchmarks": { - "blink_perf.paint": {}, - "smoothness.key_mobile_sites_smooth": {}, - "v8.browsing_desktop": {} - } - }, - "11": { - "benchmarks": { - "blink_perf.parser": {}, - "smoothness.key_silk_cases": {}, - "v8.browsing_desktop-future": {} - } - }, - "12": { - "benchmarks": { - "blink_perf.shadow_dom": {}, - "smoothness.maps": {}, - "v8.browsing_mobile": {} - } - }, - "13": { - "benchmarks": { - "blink_perf.svg": {}, - "smoothness.pathological_mobile_sites": {}, - "v8.browsing_mobile-future": {} - } - }, - "14": { - "benchmarks": { - "dromaeo": {}, - "smoothness.simple_mobile_sites": {} - } - }, - "15": { - "benchmarks": { - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "v8.runtime_stats.top_25": {} - } - }, - "16": { - "benchmarks": { - "smoothness.top_25_smooth": {}, - "rendering.mobile": {} - } - }, - "17": { - "benchmarks": { - "smoothness.tough_ad_cases": {}, - "rendering.desktop": {} - } - }, - "18": { - "benchmarks": { - "smoothness.tough_animation_cases": {}, - "wasm": {} - } - }, - "19": { - "benchmarks": { - "dummy_benchmark.histogram_benchmark_1": {}, - "smoothness.tough_canvas_cases": {}, - "webrtc": {} - } - }, - "2": { - "benchmarks": { - "blink_perf.bindings": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "thread_times.key_idle_power_cases": {} - } - }, - "20": { - "benchmarks": { - "dummy_benchmark.noisy_benchmark_1": {}, - "smoothness.tough_filters_cases": {} - } - }, - "21": { - "benchmarks": { - "dummy_benchmark.stable_benchmark_1": {}, - "smoothness.tough_image_decode_cases": {} - } - }, - "22": { - "benchmarks": { - "jetstream": {}, - "smoothness.tough_path_rendering_cases": {} - } - }, - "23": { - "benchmarks": { - "kraken": {}, - "smoothness.tough_pinch_zoom_cases": {} - } - }, - "24": { - "benchmarks": { - "loading.desktop": {}, - "smoothness.tough_scrolling_cases": {} - } - }, - "25": { - "benchmarks": { - "loading.mobile": {}, - "smoothness.tough_texture_upload_cases": {} - } - }, - "26": { - "benchmarks": { - "media.desktop": {}, - "smoothness.tough_webgl_ad_cases": {} - } - }, - "27": { - "benchmarks": { - "media.mobile": {}, - "smoothness.tough_webgl_cases": {} - } - }, - "28": { - "benchmarks": { - "memory.desktop": {}, - "speedometer": {} - } - }, - "29": { - "benchmarks": { - "memory.long_running_idle_gmail_background_tbmv2": {}, - "speedometer-future": {} - } - }, - "3": { - "benchmarks": { - "blink_perf.canvas": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "thread_times.key_mobile_sites_smooth": {} - } - }, - "30": { - "benchmarks": { - "memory.long_running_idle_gmail_tbmv2": {}, - "speedometer2": {} - } - }, - "31": { - "benchmarks": { - "memory.top_10_mobile": {}, - "speedometer2-future": {} - } - }, - "32": { - "benchmarks": { - "octane": {}, - "start_with_url.cold.startup_pages": {} - } - }, - "33": { - "benchmarks": { - "oortonline_tbmv2": {}, - "start_with_url.warm.startup_pages": {} - } - }, - "34": { - "benchmarks": { - "power.idle_platform": {}, - "system_health.common_desktop": {} - } - }, - "35": { - "benchmarks": { - "power.typical_10_mobile": {}, - "system_health.common_mobile": {} - } - }, - "36": { - "benchmarks": { - "rasterize_and_record_micro.partial_invalidation": {}, - "system_health.memory_desktop": {} - } - }, - "37": { - "benchmarks": { - "rasterize_and_record_micro.top_25": {}, - "system_health.memory_mobile": {} - } - }, - "38": { - "benchmarks": { - "scheduler.tough_scheduling_cases": {}, - "system_health.webview_startup": {} - } - }, - "4": { - "benchmarks": { - "blink_perf.css": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "thread_times.key_noop_cases": {} - } - }, - "5": { - "benchmarks": { - "blink_perf.dom": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "thread_times.key_silk_cases": {} - } - }, - "6": { - "benchmarks": { - "blink_perf.events": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": {}, - "thread_times.simple_mobile_sites": {} - } - }, - "7": { - "benchmarks": { - "blink_perf.image_decoder": {}, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "thread_times.tough_compositor_cases": {} - } - }, - "8": { - "benchmarks": { - "blink_perf.layout": {}, - "smoothness.image_decoding_cases": {}, - "thread_times.tough_scrolling_cases": {} - } - }, - "9": { - "benchmarks": { - "blink_perf.owp_storage": {}, - "smoothness.key_desktop_move_cases": {}, - "tracing.tracing_with_background_memory_infra": {} - } - } -}
diff --git a/tools/perf/core/shard_maps/benchmark_desktop_bot_map.json b/tools/perf/core/shard_maps/benchmark_desktop_bot_map.json deleted file mode 100644 index efd97c5..0000000 --- a/tools/perf/core/shard_maps/benchmark_desktop_bot_map.json +++ /dev/null
@@ -1,198 +0,0 @@ -{ - "0": { - "benchmarks": { - "media.desktop": {}, - "smoothness.pathological_mobile_sites": {}, - "tab_switching.typical_25": {} - } - }, - "1": { - "benchmarks": { - "media.mobile": {}, - "power.desktop": {}, - "smoothness.simple_mobile_sites": {}, - "thread_times.key_hit_test_cases": {} - } - }, - "10": { - "benchmarks": { - "blink_perf.paint": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "v8.browsing_desktop": {} - } - }, - "11": { - "benchmarks": { - "blink_perf.parser": {}, - "rasterize_and_record_micro.top_25": {}, - "smoothness.tough_scrolling_cases": {}, - "v8.browsing_desktop-future": {} - } - }, - "12": { - "benchmarks": { - "blink_perf.shadow_dom": {}, - "scheduler.tough_scheduling_cases": {}, - "smoothness.tough_texture_upload_cases": {}, - "v8.browsing_mobile": {} - } - }, - "13": { - "benchmarks": { - "blink_perf.svg": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "v8.browsing_mobile-future": {} - } - }, - "14": { - "benchmarks": { - "dromaeo": {}, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.tough_webgl_cases": {} - } - }, - "15": { - "benchmarks": { - "smoothness.gpu_rasterization.top_25_smooth": {}, - "speedometer": {}, - "v8.runtime_stats.top_25": {} - } - }, - "16": { - "benchmarks": { - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "speedometer-future": {}, - "rendering.mobile": {} - } - }, - "17": { - "benchmarks": { - "rendering.desktop": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "speedometer2": {} - } - }, - "18": { - "benchmarks": { - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "speedometer2-future": {}, - "wasm": {} - } - }, - "19": { - "benchmarks": { - "dummy_benchmark.histogram_benchmark_1": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": {}, - "start_with_url.cold.startup_pages": {}, - "webrtc": {} - } - }, - "2": { - "benchmarks": { - "blink_perf.bindings": {}, - "memory.desktop": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "thread_times.key_idle_power_cases": {} - } - }, - "20": { - "benchmarks": { - "dummy_benchmark.noisy_benchmark_1": {}, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "start_with_url.warm.startup_pages": {} - } - }, - "21": { - "benchmarks": { - "dummy_benchmark.stable_benchmark_1": {}, - "smoothness.image_decoding_cases": {}, - "system_health.common_desktop": {} - } - }, - "22": { - "benchmarks": { - "jetstream": {}, - "smoothness.key_desktop_move_cases": {}, - "system_health.common_mobile": {} - } - }, - "23": { - "benchmarks": { - "kraken": {}, - "smoothness.key_mobile_sites_smooth": {}, - "system_health.memory_desktop": {} - } - }, - "24": { - "benchmarks": { - "loading.desktop": {}, - "smoothness.key_silk_cases": {}, - "system_health.memory_mobile": {} - } - }, - "25": { - "benchmarks": { - "loading.mobile": {}, - "smoothness.maps": {}, - "system_health.webview_startup": {} - } - }, - "3": { - "benchmarks": { - "blink_perf.canvas": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "smoothness.top_25_smooth": {}, - "thread_times.key_mobile_sites_smooth": {} - } - }, - "4": { - "benchmarks": { - "blink_perf.css": {}, - "memory.long_running_idle_gmail_tbmv2": {}, - "smoothness.tough_ad_cases": {}, - "thread_times.key_noop_cases": {} - } - }, - "5": { - "benchmarks": { - "blink_perf.dom": {}, - "memory.top_10_mobile": {}, - "smoothness.tough_animation_cases": {}, - "thread_times.key_silk_cases": {} - } - }, - "6": { - "benchmarks": { - "blink_perf.events": {}, - "octane": {}, - "smoothness.tough_canvas_cases": {}, - "thread_times.simple_mobile_sites": {} - } - }, - "7": { - "benchmarks": { - "blink_perf.image_decoder": {}, - "oortonline_tbmv2": {}, - "smoothness.tough_filters_cases": {}, - "thread_times.tough_compositor_cases": {} - } - }, - "8": { - "benchmarks": { - "blink_perf.layout": {}, - "power.idle_platform": {}, - "smoothness.tough_image_decode_cases": {}, - "thread_times.tough_scrolling_cases": {} - } - }, - "9": { - "benchmarks": { - "blink_perf.owp_storage": {}, - "power.typical_10_mobile": {}, - "smoothness.tough_path_rendering_cases": {}, - "tracing.tracing_with_background_memory_infra": {} - } - } -}
diff --git a/tools/perf/core/shard_maps/desktop_26_shard_map.json b/tools/perf/core/shard_maps/desktop_26_shard_map.json deleted file mode 100644 index 6292fc7..0000000 --- a/tools/perf/core/shard_maps/desktop_26_shard_map.json +++ /dev/null
@@ -1,232 +0,0 @@ -{ - "0": { - "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": {}, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": { - "end": 47 - } - } - }, - "1": { - "benchmarks": { - "blink_perf.layout": { - "begin": 47 - }, - "blink_perf.owp_storage": {}, - "blink_perf.paint": {}, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": {}, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {}, - "kraken": {}, - "loading.desktop": { - "end": 2 - } - } - }, - "2": { - "benchmarks": { - "loading.desktop": { - "begin": 2, - "end": 40 - } - } - }, - "3": { - "benchmarks": { - "loading.desktop": { - "begin": 40 - }, - "loading.mobile": {}, - "media.desktop": { - "end": 27 - } - } - }, - "4": { - "benchmarks": { - "media.desktop": { - "begin": 27 - }, - "media.mobile": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {} - } - }, - "5": { - "benchmarks": { - "memory.top_10_mobile": {}, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, - "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": { - "end": 2 - } - } - }, - "6": { - "benchmarks": { - "rasterize_and_record_micro.top_25": { - "begin": 2 - }, - "rendering.desktop": { - "end": 40 - } - } - }, - "7": { - "benchmarks": { - "rendering.desktop": { - "begin": 40, - "end": 101 - } - } - }, - "8": { - "benchmarks": { - "rendering.desktop": { - "begin": 101 - }, - "rendering.mobile": {} - } - }, - "9": { - "benchmarks": { - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": { - "end": 8 - } - } - }, - "10": { - "benchmarks": { - "system_health.common_desktop": { - "begin": 8, - "end": 45 - } - } - }, - "11": { - "benchmarks": { - "system_health.common_desktop": { - "begin": 45 - } - } - }, - "12": { - "benchmarks": { - "system_health.common_mobile": {}, - "system_health.memory_desktop": { - "end": 12 - } - } - }, - "13": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 12, - "end": 26 - } - } - }, - "14": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 26, - "end": 46 - } - } - }, - "15": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 46, - "end": 54 - } - } - }, - "16": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 54, - "end": 62 - } - } - }, - "17": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 62 - }, - "system_health.memory_mobile": {}, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "tracing.tracing_with_background_memory_infra": { - "end": 1 - } - } - }, - "18": { - "benchmarks": { - "tracing.tracing_with_background_memory_infra": { - "begin": 1 - }, - "v8.browsing_desktop": { - "end": 13 - } - } - }, - "19": { - "benchmarks": { - "v8.browsing_desktop": { - "begin": 13 - }, - "v8.browsing_desktop-future": { - "end": 8 - } - } - }, - "20": { - "benchmarks": { - "v8.browsing_desktop-future": { - "begin": 8 - }, - "v8.browsing_mobile": {}, - "v8.browsing_mobile-future": {}, - "v8.runtime_stats.top_25": { - "end": 3 - } - } - }, - "21": { - "benchmarks": { - "v8.runtime_stats.top_25": { - "begin": 3 - } - } - }, - "22": { - "benchmarks": { - "wasm": {}, - "webrtc": {} - } - } -}
diff --git a/tools/perf/core/shard_maps/desktop_5_shard_map.json b/tools/perf/core/shard_maps/desktop_5_shard_map.json deleted file mode 100644 index 4d32f8e2..0000000 --- a/tools/perf/core/shard_maps/desktop_5_shard_map.json +++ /dev/null
@@ -1,134 +0,0 @@ -{ - "0": { - "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": {}, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": {}, - "blink_perf.owp_storage": {}, - "blink_perf.paint": {}, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": {}, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {}, - "kraken": {}, - "loading.desktop": {}, - "loading.mobile": {}, - "media.desktop": {}, - "media.mobile": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": {}, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": { - "end": 2 - } - } - }, - "1": { - "benchmarks": { - "power.desktop": { - "begin": 2 - }, - "power.idle_platform": {}, - "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": {}, - "scheduler.tough_scheduling_cases": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": {}, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "smoothness.image_decoding_cases": {}, - "smoothness.key_desktop_move_cases": {}, - "smoothness.key_mobile_sites_smooth": {}, - "smoothness.key_silk_cases": {}, - "smoothness.maps": {}, - "smoothness.pathological_mobile_sites": {}, - "smoothness.simple_mobile_sites": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "smoothness.top_25_smooth": {}, - "smoothness.tough_ad_cases": {}, - "smoothness.tough_animation_cases": { - "end": 19 - } - } - }, - "2": { - "benchmarks": { - "smoothness.tough_animation_cases": { - "begin": 19 - }, - "smoothness.tough_canvas_cases": {}, - "smoothness.tough_filters_cases": {}, - "smoothness.tough_image_decode_cases": {}, - "smoothness.tough_path_rendering_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "smoothness.tough_scrolling_cases": {}, - "smoothness.tough_texture_upload_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "smoothness.tough_webgl_cases": {}, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": {}, - "system_health.common_mobile": {}, - "system_health.memory_desktop": { - "end": 8 - } - } - }, - "3": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 8 - }, - "system_health.memory_mobile": {}, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "thread_times.key_hit_test_cases": {}, - "thread_times.key_idle_power_cases": {}, - "thread_times.key_mobile_sites_smooth": {}, - "thread_times.key_noop_cases": {}, - "thread_times.key_silk_cases": {}, - "thread_times.simple_mobile_sites": {}, - "thread_times.tough_compositor_cases": {}, - "thread_times.tough_scrolling_cases": { - "end": 23 - } - } - }, - "4": { - "benchmarks": { - "thread_times.tough_scrolling_cases": { - "begin": 23 - }, - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, - "v8.browsing_mobile": {}, - "v8.browsing_mobile-future": {}, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} - } - } -} \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/mac1012_5_shard_map.json b/tools/perf/core/shard_maps/mac1012_5_shard_map.json index 1397aec..4e38c8c 100644 --- a/tools/perf/core/shard_maps/mac1012_5_shard_map.json +++ b/tools/perf/core/shard_maps/mac1012_5_shard_map.json
@@ -1,134 +1,105 @@ { "0": { "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": {}, - "blink_perf.events": {}, + "system_health.common_mobile": {}, + "v8.browsing_mobile-future": {}, + "rendering.mobile": {}, "blink_perf.image_decoder": {}, - "blink_perf.layout": {}, + "power.desktop": {}, + "speedometer-future": {}, "blink_perf.owp_storage": {}, - "blink_perf.paint": {}, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": {}, - "dromaeo": {}, + "memory.desktop": {}, + "start_with_url.warm.startup_pages": {}, + "wasm": {}, "dummy_benchmark.histogram_benchmark_1": {}, + "speedometer": {}, + "memory.long_running_idle_gmail_tbmv2": {}, + "octane": {}, "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, + "blink_perf.svg": {}, + "system_health.webview_startup": {}, + "speedometer2-future": {}, "jetstream": {}, - "kraken": {}, - "loading.desktop": {}, - "loading.mobile": {}, - "media.desktop": {}, - "media.mobile": {}, - "memory.desktop": { - "end": 6 + "smoothness.tough_pinch_zoom_cases": {}, + "power.idle_platform": {}, + "power.typical_10_mobile": {}, + "v8.runtime_stats.top_25": { + "end": 79 } } }, "1": { "benchmarks": { - "memory.desktop": { - "begin": 6 + "v8.runtime_stats.top_25": { + "begin": 79 }, + "loading.mobile": {}, + "speedometer2": {}, + "v8.browsing_desktop-future": {}, + "webrtc": {}, + "blink_perf.shadow_dom": {}, + "blink_perf.events": {}, + "blink_perf.layout": {}, "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": {}, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, - "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": {}, - "scheduler.tough_scheduling_cases": {}, - "smoothness.desktop_tough_pinch_zoom_cases": { - "end": 6 + "tab_switching.typical_25": {}, + "blink_perf.dom": {}, + "media.mobile": {}, + "start_with_url.cold.startup_pages": {}, + "blink_perf.bindings": {}, + "system_health.memory_desktop": { + "end": 22 } } }, "2": { "benchmarks": { - "smoothness.desktop_tough_pinch_zoom_cases": { - "begin": 6 - }, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": {}, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "smoothness.image_decoding_cases": {}, - "smoothness.key_desktop_move_cases": {}, - "smoothness.key_mobile_sites_smooth": {}, - "smoothness.key_silk_cases": {}, - "smoothness.maps": {}, - "smoothness.pathological_mobile_sites": {}, - "smoothness.simple_mobile_sites": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "smoothness.top_25_smooth": {}, - "smoothness.tough_ad_cases": {}, - "smoothness.tough_animation_cases": {}, - "smoothness.tough_canvas_cases": {}, - "smoothness.tough_filters_cases": {}, - "smoothness.tough_image_decode_cases": {}, - "smoothness.tough_path_rendering_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "smoothness.tough_scrolling_cases": {}, - "smoothness.tough_texture_upload_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "smoothness.tough_webgl_cases": {}, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": {}, - "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 8 + "begin": 22, + "end": 60 } } }, "3": { "benchmarks": { "system_health.memory_desktop": { - "begin": 8 + "begin": 60 }, - "system_health.memory_mobile": {}, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "thread_times.key_hit_test_cases": {}, - "thread_times.key_idle_power_cases": {}, - "thread_times.key_mobile_sites_smooth": {}, - "thread_times.key_noop_cases": {}, - "thread_times.key_silk_cases": {}, - "thread_times.simple_mobile_sites": {}, - "thread_times.tough_compositor_cases": {}, - "thread_times.tough_scrolling_cases": {}, - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": { - "end": 16 + "media.desktop": {}, + "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, + "rasterize_and_record_micro.partial_invalidation": {}, + "v8.browsing_desktop": {}, + "blink_perf.parser": {}, + "memory.top_10_mobile": {}, + "blink_perf.canvas": {}, + "loading.desktop": { + "end": 79 } } }, "4": { "benchmarks": { - "v8.browsing_desktop": { - "begin": 16 + "loading.desktop": { + "begin": 79 }, - "v8.browsing_desktop-future": {}, + "dromaeo": {}, + "kraken": {}, + "oortonline_tbmv2": {}, + "system_health.common_desktop": {}, + "rasterize_and_record_micro.top_25": {}, + "dummy_benchmark.stable_benchmark_1": {}, + "system_health.memory_mobile": {}, + "rendering.desktop": {}, + "blink_perf.css": {}, "v8.browsing_mobile": {}, - "v8.browsing_mobile-future": {}, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} + "blink_perf.paint": {}, + "tracing.tracing_with_background_memory_infra": {} } + }, + "extra_infos": { + "num_stories": 1831, + "predicted_min_shard_time": 19266.939837765593, + "predicted_min_shard_index": 3, + "predicted_max_shard_time": 19772.160803, + "predicted_max_shard_index": 2 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/mobile_21_shard_map.json b/tools/perf/core/shard_maps/mobile_21_shard_map.json deleted file mode 100644 index a259256..0000000 --- a/tools/perf/core/shard_maps/mobile_21_shard_map.json +++ /dev/null
@@ -1,263 +0,0 @@ -{ - "0": { - "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": {}, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": { - "end": 5 - } - } - }, - "1": { - "benchmarks": { - "blink_perf.layout": { - "begin": 5 - }, - "blink_perf.owp_storage": {}, - "blink_perf.paint": {}, - "blink_perf.parser": { - "end": 16 - } - } - }, - "2": { - "benchmarks": { - "blink_perf.parser": { - "begin": 16 - }, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": {}, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {}, - "kraken": {}, - "loading.desktop": {}, - "loading.mobile": { - "end": 5 - } - } - }, - "3": { - "benchmarks": { - "loading.mobile": { - "begin": 5 - }, - "media.desktop": {}, - "media.mobile": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {} - } - }, - "4": { - "benchmarks": { - "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": {}, - "octane": {} - } - }, - "5": { - "benchmarks": { - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, - "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": { - "end": 27 - } - } - }, - "6": { - "benchmarks": { - "rendering.mobile": { - "begin": 27, - "end": 124 - } - } - }, - "7": { - "benchmarks": { - "rendering.mobile": { - "begin": 124, - "end": 223 - } - } - }, - "8": { - "benchmarks": { - "rendering.mobile": { - "begin": 223 - }, - "scheduler.tough_scheduling_cases": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": { - "end": 28 - } - } - }, - "9": { - "benchmarks": { - "smoothness.gpu_rasterization.tough_scrolling_cases": { - "begin": 28 - }, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "smoothness.image_decoding_cases": {}, - "smoothness.key_desktop_move_cases": {}, - "smoothness.key_mobile_sites_smooth": {}, - "smoothness.key_silk_cases": {}, - "smoothness.maps": {}, - "smoothness.pathological_mobile_sites": {}, - "smoothness.simple_mobile_sites": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": { - "end": 21 - } - } - }, - "10": { - "benchmarks": { - "smoothness.sync_scroll.key_mobile_sites_smooth": { - "begin": 21 - }, - "smoothness.top_25_smooth": {}, - "smoothness.tough_ad_cases": {}, - "smoothness.tough_animation_cases": { - "end": 47 - } - } - }, - "11": { - "benchmarks": { - "smoothness.tough_animation_cases": { - "begin": 47 - }, - "smoothness.tough_canvas_cases": {}, - "smoothness.tough_filters_cases": {}, - "smoothness.tough_image_decode_cases": {}, - "smoothness.tough_path_rendering_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "smoothness.tough_scrolling_cases": { - "end": 37 - } - } - }, - "12": { - "benchmarks": { - "smoothness.tough_scrolling_cases": { - "begin": 37 - }, - "smoothness.tough_texture_upload_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "smoothness.tough_webgl_cases": {}, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": {}, - "system_health.common_mobile": { - "end": 8 - } - } - }, - "13": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 8, - "end": 59 - } - } - }, - "14": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 59 - }, - "system_health.memory_desktop": {}, - "system_health.memory_mobile": { - "end": 18 - } - } - }, - "15": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 18, - "end": 42 - } - } - }, - "16": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 42, - "end": 55 - } - } - }, - "17": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 55 - }, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "thread_times.key_hit_test_cases": {}, - "thread_times.key_idle_power_cases": {}, - "thread_times.key_mobile_sites_smooth": { - "end": 15 - } - } - }, - "18": { - "benchmarks": { - "thread_times.key_mobile_sites_smooth": { - "begin": 15 - }, - "thread_times.key_noop_cases": {}, - "thread_times.key_silk_cases": {}, - "thread_times.simple_mobile_sites": {}, - "thread_times.tough_compositor_cases": {}, - "thread_times.tough_scrolling_cases": {}, - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, - "v8.browsing_mobile": { - "end": 8 - } - } - }, - "19": { - "benchmarks": { - "v8.browsing_mobile": { - "begin": 8 - }, - "v8.browsing_mobile-future": { - "end": 8 - } - } - }, - "20": { - "benchmarks": { - "v8.browsing_mobile-future": { - "begin": 8 - }, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} - } - } -} \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/mobile_39_shard_map.json b/tools/perf/core/shard_maps/mobile_39_shard_map.json deleted file mode 100644 index 3b8e9d2..0000000 --- a/tools/perf/core/shard_maps/mobile_39_shard_map.json +++ /dev/null
@@ -1,315 +0,0 @@ -{ - "0": { - "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": { - "end": 4 - } - } - }, - "1": { - "benchmarks": { - "blink_perf.css": { - "begin": 4 - }, - "blink_perf.dom": {}, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": { - "end": 16 - } - } - }, - "2": { - "benchmarks": { - "blink_perf.layout": { - "begin": 16 - }, - "blink_perf.owp_storage": {}, - "blink_perf.paint": { - "end": 2 - } - } - }, - "3": { - "benchmarks": { - "blink_perf.paint": { - "begin": 2 - }, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": { - "end": 6 - } - } - }, - "4": { - "benchmarks": { - "blink_perf.shadow_dom": { - "begin": 6 - }, - "blink_perf.svg": {}, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {} - } - }, - "5": { - "benchmarks": { - "kraken": {}, - "loading.desktop": {}, - "loading.mobile": { - "end": 18 - } - } - }, - "6": { - "benchmarks": { - "loading.mobile": { - "begin": 18 - }, - "media.desktop": {}, - "media.mobile": { - "end": 13 - } - } - }, - "7": { - "benchmarks": { - "media.mobile": { - "begin": 13 - }, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": { - "end": 4 - } - } - }, - "8": { - "benchmarks": { - "memory.top_10_mobile": { - "begin": 4, - "end": 17 - } - } - }, - "9": { - "benchmarks": { - "memory.top_10_mobile": { - "begin": 17 - }, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, - "power.typical_10_mobile": {} - } - }, - "10": { - "benchmarks": { - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": { - "end": 20 - } - } - }, - "11": { - "benchmarks": { - "rendering.mobile": { - "begin": 20, - "end": 70 - } - } - }, - "12": { - "benchmarks": { - "rendering.mobile": { - "begin": 70, - "end": 124 - } - } - }, - "13": { - "benchmarks": { - "rendering.mobile": { - "begin": 124, - "end": 178 - } - } - }, - "14": { - "benchmarks": { - "rendering.mobile": { - "begin": 178, - "end": 228 - } - } - }, - "15": { - "benchmarks": { - "rendering.mobile": { - "begin": 228 - } - } - }, - "16": { - "benchmarks": { - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {} - } - }, - "17": { - "benchmarks": { - "smoothness.tough_pinch_zoom_cases": {} - } - }, - "18": { - "benchmarks": { - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {} - } - }, - "19": { - "benchmarks": { - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": {}, - "system_health.common_mobile": { - "end": 2 - } - } - }, - "20": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 2, - "end": 26 - } - } - }, - "21": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 26, - "end": 59 - } - } - }, - "22": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 59 - }, - "system_health.memory_desktop": {}, - "system_health.memory_mobile": { - "end": 9 - } - } - }, - "23": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 9, - "end": 18 - } - } - }, - "24": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 18, - "end": 29 - } - } - }, - "25": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 29, - "end": 47 - } - } - }, - "26": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 47, - "end": 53 - } - } - }, - "27": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 53, - "end": 59 - } - } - }, - "28": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 59 - }, - "system_health.webview_startup": {} - } - }, - "29": { - "benchmarks": { - "tab_switching.typical_25": {} - } - }, - "30": { - "benchmarks": { - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, - "v8.browsing_mobile": { - "end": 1 - } - } - }, - "31": { - "benchmarks": { - "v8.browsing_mobile": { - "begin": 1, - "end": 16 - } - } - }, - "32": { - "benchmarks": { - "v8.browsing_mobile": { - "begin": 16 - }, - "v8.browsing_mobile-future": { - "end": 6 - } - } - }, - "33": { - "benchmarks": { - "v8.browsing_mobile-future": { - "begin": 6, - "end": 18 - } - } - }, - "34": { - "benchmarks": { - "v8.browsing_mobile-future": { - "begin": 18 - }, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} - } - } -}
diff --git a/tools/perf/core/shard_maps/mobile_7_shard_map.json b/tools/perf/core/shard_maps/mobile_7_shard_map.json deleted file mode 100644 index 5b589f5..0000000 --- a/tools/perf/core/shard_maps/mobile_7_shard_map.json +++ /dev/null
@@ -1,142 +0,0 @@ -{ - "0": { - "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": {}, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": {}, - "blink_perf.owp_storage": {}, - "blink_perf.paint": {}, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": {}, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {}, - "kraken": {} - } - }, - "1": { - "benchmarks": { - "loading.desktop": {}, - "loading.mobile": {}, - "media.desktop": {}, - "media.mobile": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": {}, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, - "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": { - "end": 7 - } - } - }, - "2": { - "benchmarks": { - "rendering.mobile": { - "begin": 7 - }, - "scheduler.tough_scheduling_cases": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {} - } - }, - "3": { - "benchmarks": { - "smoothness.gpu_rasterization.tough_scrolling_cases": {}, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "smoothness.image_decoding_cases": {}, - "smoothness.key_desktop_move_cases": {}, - "smoothness.key_mobile_sites_smooth": {}, - "smoothness.key_silk_cases": {}, - "smoothness.maps": {}, - "smoothness.pathological_mobile_sites": {}, - "smoothness.simple_mobile_sites": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "smoothness.top_25_smooth": {}, - "smoothness.tough_ad_cases": {}, - "smoothness.tough_animation_cases": {}, - "smoothness.tough_canvas_cases": {}, - "smoothness.tough_filters_cases": {}, - "smoothness.tough_image_decode_cases": {}, - "smoothness.tough_path_rendering_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "smoothness.tough_scrolling_cases": { - "end": 35 - } - } - }, - "4": { - "benchmarks": { - "smoothness.tough_scrolling_cases": { - "begin": 35 - }, - "smoothness.tough_texture_upload_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "smoothness.tough_webgl_cases": {}, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, - "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, - "system_health.common_desktop": {}, - "system_health.common_mobile": {}, - "system_health.memory_desktop": {}, - "system_health.memory_mobile": { - "end": 17 - } - } - }, - "5": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 17 - }, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "thread_times.key_hit_test_cases": {}, - "thread_times.key_idle_power_cases": { - "end": 3 - } - } - }, - "6": { - "benchmarks": { - "thread_times.key_idle_power_cases": { - "begin": 3 - }, - "thread_times.key_mobile_sites_smooth": {}, - "thread_times.key_noop_cases": {}, - "thread_times.key_silk_cases": {}, - "thread_times.simple_mobile_sites": {}, - "thread_times.tough_compositor_cases": {}, - "thread_times.tough_scrolling_cases": {}, - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, - "v8.browsing_mobile": {}, - "v8.browsing_mobile-future": {}, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} - } - } -} \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/pixel2_7_shard_map.json b/tools/perf/core/shard_maps/pixel2_7_shard_map.json index c42ead3..5796e80 100644 --- a/tools/perf/core/shard_maps/pixel2_7_shard_map.json +++ b/tools/perf/core/shard_maps/pixel2_7_shard_map.json
@@ -1,152 +1,114 @@ { "0": { "benchmarks": { - "blink_perf.bindings": {}, - "blink_perf.canvas": {}, - "blink_perf.css": {}, - "blink_perf.dom": {}, - "blink_perf.events": {}, - "blink_perf.image_decoder": {}, - "blink_perf.layout": {}, - "blink_perf.owp_storage": {}, - "blink_perf.paint": {}, - "blink_perf.parser": {}, - "blink_perf.shadow_dom": {}, - "blink_perf.svg": {}, - "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, - "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {}, - "kraken": {}, - "loading.desktop": {}, - "loading.mobile": { - "end": 35 + "system_health.common_mobile": {}, + "v8.browsing_mobile-future": {}, + "rendering.mobile": { + "end": 284 } } }, "1": { "benchmarks": { - "loading.mobile": { - "begin": 35 + "rendering.mobile": { + "begin": 284 }, - "media.desktop": {}, - "media.mobile": {}, + "blink_perf.image_decoder": {}, + "power.desktop": {}, + "speedometer-future": {}, + "blink_perf.owp_storage": {}, "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, + "start_with_url.warm.startup_pages": {}, + "wasm": {}, + "dummy_benchmark.histogram_benchmark_1": {}, + "speedometer": {}, "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": { - "end": 6 - } + "octane": {}, + "dummy_benchmark.noisy_benchmark_1": {}, + "blink_perf.svg": {}, + "system_health.webview_startup": {}, + "speedometer2-future": {}, + "jetstream": {}, + "smoothness.tough_pinch_zoom_cases": {}, + "power.idle_platform": {} } }, "2": { "benchmarks": { - "memory.top_10_mobile": { - "begin": 6 - }, - "octane": {}, - "oortonline_tbmv2": {}, - "power.desktop": {}, - "power.idle_platform": {}, "power.typical_10_mobile": {}, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": { - "end": 185 + "v8.runtime_stats.top_25": {}, + "loading.mobile": { + "end": 53 } } }, "3": { "benchmarks": { - "rendering.mobile": { - "begin": 185 + "loading.mobile": { + "begin": 53 }, - "scheduler.tough_scheduling_cases": {}, - "smoothness.desktop_tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.polymer": {}, - "smoothness.gpu_rasterization.top_25_smooth": {}, - "smoothness.gpu_rasterization.tough_filters_cases": {}, - "smoothness.gpu_rasterization.tough_path_rendering_cases": {}, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.gpu_rasterization.tough_scrolling_cases": {}, - "smoothness.gpu_rasterization_and_decoding.image_decoding_cases": {}, - "smoothness.image_decoding_cases": {}, - "smoothness.key_desktop_move_cases": {}, - "smoothness.key_mobile_sites_smooth": {}, - "smoothness.key_silk_cases": { - "end": 14 - } + "speedometer2": {}, + "v8.browsing_desktop-future": {}, + "webrtc": {}, + "blink_perf.shadow_dom": {}, + "blink_perf.events": {}, + "blink_perf.layout": {}, + "memory.long_running_idle_gmail_background_tbmv2": {}, + "tab_switching.typical_25": {}, + "blink_perf.dom": {}, + "media.mobile": {} } }, "4": { "benchmarks": { - "smoothness.key_silk_cases": { - "begin": 14 - }, - "smoothness.maps": {}, - "smoothness.pathological_mobile_sites": {}, - "smoothness.simple_mobile_sites": {}, - "smoothness.sync_scroll.key_mobile_sites_smooth": {}, - "smoothness.top_25_smooth": {}, - "smoothness.tough_ad_cases": {}, - "smoothness.tough_animation_cases": {}, - "smoothness.tough_canvas_cases": {}, - "smoothness.tough_filters_cases": {}, - "smoothness.tough_image_decode_cases": {}, - "smoothness.tough_path_rendering_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, - "smoothness.tough_scrolling_cases": {}, - "smoothness.tough_texture_upload_cases": {}, - "smoothness.tough_webgl_ad_cases": {}, - "smoothness.tough_webgl_cases": {}, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, - "speedometer2-future": {}, "start_with_url.cold.startup_pages": {}, - "start_with_url.warm.startup_pages": {}, + "blink_perf.bindings": {}, + "system_health.memory_desktop": {}, + "media.desktop": {}, + "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, + "rasterize_and_record_micro.partial_invalidation": {}, + "v8.browsing_desktop": {}, + "blink_perf.parser": {}, + "memory.top_10_mobile": {}, + "blink_perf.canvas": {}, + "loading.desktop": {}, + "dromaeo": {}, + "kraken": {}, + "oortonline_tbmv2": {}, "system_health.common_desktop": {}, - "system_health.common_mobile": { - "end": 33 + "rasterize_and_record_micro.top_25": { + "end": 22 } } }, "5": { "benchmarks": { - "system_health.common_mobile": { - "begin": 33 + "rasterize_and_record_micro.top_25": { + "begin": 22 }, - "system_health.memory_desktop": {}, + "dummy_benchmark.stable_benchmark_1": {}, "system_health.memory_mobile": { - "end": 59 + "end": 48 } } }, "6": { "benchmarks": { "system_health.memory_mobile": { - "begin": 59 + "begin": 48 }, - "system_health.webview_startup": {}, - "tab_switching.typical_25": {}, - "thread_times.key_hit_test_cases": {}, - "thread_times.key_idle_power_cases": {}, - "thread_times.key_mobile_sites_smooth": {}, - "thread_times.key_noop_cases": {}, - "thread_times.key_silk_cases": {}, - "thread_times.simple_mobile_sites": {}, - "thread_times.tough_compositor_cases": {}, - "thread_times.tough_scrolling_cases": {}, - "tracing.tracing_with_background_memory_infra": {}, - "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, + "rendering.desktop": {}, + "blink_perf.css": {}, "v8.browsing_mobile": {}, - "v8.browsing_mobile-future": {}, - "v8.runtime_stats.top_25": {}, - "wasm": {}, - "webrtc": {} + "blink_perf.paint": {}, + "tracing.tracing_with_background_memory_infra": {} } + }, + "extra_infos": { + "num_stories": 1831, + "predicted_min_shard_time": 26525.673782491664, + "predicted_min_shard_index": 2, + "predicted_max_shard_time": 26868.289459214655, + "predicted_max_shard_index": 6 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/pixel2_webview_7_shard_map.json b/tools/perf/core/shard_maps/pixel2_webview_7_shard_map.json index be05bc0..1c5b9342 100644 --- a/tools/perf/core/shard_maps/pixel2_webview_7_shard_map.json +++ b/tools/perf/core/shard_maps/pixel2_webview_7_shard_map.json
@@ -1,6 +1,64 @@ { "0": { - "benchmarks": {} + "benchmarks": { + "system_health.common_mobile": {}, + "v8.browsing_mobile-future": {}, + "rendering.mobile": {}, + "blink_perf.image_decoder": {}, + "power.desktop": {}, + "speedometer-future": {}, + "blink_perf.owp_storage": {}, + "memory.desktop": {}, + "start_with_url.warm.startup_pages": {}, + "wasm": {}, + "dummy_benchmark.histogram_benchmark_1": {}, + "speedometer": {}, + "memory.long_running_idle_gmail_tbmv2": {}, + "octane": {}, + "dummy_benchmark.noisy_benchmark_1": {}, + "blink_perf.svg": {}, + "system_health.webview_startup": {}, + "speedometer2-future": {}, + "jetstream": {}, + "smoothness.tough_pinch_zoom_cases": {}, + "power.idle_platform": {}, + "power.typical_10_mobile": {}, + "v8.runtime_stats.top_25": {}, + "loading.mobile": {}, + "speedometer2": {}, + "v8.browsing_desktop-future": {}, + "webrtc": {}, + "blink_perf.shadow_dom": {}, + "blink_perf.events": {}, + "blink_perf.layout": {}, + "memory.long_running_idle_gmail_background_tbmv2": {}, + "tab_switching.typical_25": {}, + "blink_perf.dom": {}, + "media.mobile": {}, + "start_with_url.cold.startup_pages": {}, + "blink_perf.bindings": {}, + "system_health.memory_desktop": {}, + "media.desktop": {}, + "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, + "rasterize_and_record_micro.partial_invalidation": {}, + "v8.browsing_desktop": {}, + "blink_perf.parser": {}, + "memory.top_10_mobile": {}, + "blink_perf.canvas": {}, + "loading.desktop": {}, + "dromaeo": {}, + "kraken": {}, + "oortonline_tbmv2": {}, + "system_health.common_desktop": {}, + "rasterize_and_record_micro.top_25": {}, + "dummy_benchmark.stable_benchmark_1": {}, + "system_health.memory_mobile": {}, + "rendering.desktop": {}, + "blink_perf.css": {}, + "v8.browsing_mobile": {}, + "blink_perf.paint": {}, + "tracing.tracing_with_background_memory_infra": {} + } }, "1": { "benchmarks": {} @@ -19,5 +77,12 @@ }, "6": { "benchmarks": {} + }, + "extra_infos": { + "num_stories": 1831, + "predicted_min_shard_time": 0, + "predicted_min_shard_index": 0, + "predicted_max_shard_time": 0, + "predicted_max_shard_index": null } } \ No newline at end of file
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 4978e31..c2e2f82 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -298,10 +298,14 @@ crbug.com/842731 [ Android_One ] system_health.memory_mobile/background:news:nytimes [ Skip ] crbug.com/843547 [ Android_Go ] system_health.memory_mobile/background:news:nytimes [ Skip ] crbug.com/852888 [ Nexus_5X ] system_health.memory_mobile/background:news:nytimes [ Skip ] +crbug.com/859500 [ Nexus_5X ] system_health.memory_mobile/browse:social:tumblr_infinite_scroll [ Skip ] # Benchmark: tab_switching.typical_25 crbug.com/747026 [ Mac ] tab_switching.typical_25/multitab:misc:typical24 [ Skip ] +# Benchmark: media.desktop +crbug.com/859660 [ All ] media.desktop/video.html?src=tulip2.vp9.webm_Regular-3G [ Skip ] + # Benchmark: v8.browsing_desktop crbug.com/773084 [ Mac ] v8.browsing_desktop/browse:tools:maps [ Skip ] crbug.com/788796 [ Linux ] v8.browsing_desktop/browse:media:imgur [ Skip ]
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.h b/ui/accelerated_widget_mac/accelerated_widget_mac.h index 468234d..44b1dfc 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.h +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.h
@@ -19,11 +19,6 @@ // throughout its lifetime (one at a time, though). class AcceleratedWidgetMacNSView { public: - // The CALayer tree provided by the CALayerParams sent to the - // AcceleratedWidgetMac will be installed under the -[NSView layer] of this - // NSView. - virtual NSView* AcceleratedWidgetGetNSView() const = 0; - // Called when the AcceleratedWidgetMac's CALayerFrameSink interface's // UpdateCALayerTree method is called. This is used to update background // colors and to suppressing drawing of blank windows until content is @@ -57,11 +52,6 @@ // a call is made with |suspended| as false. void SetSuspended(bool suspended); - // Translate from a gfx::AcceleratedWidget to the NSView in which it will - // appear. This may return nil if |widget| is invalid or is not currently - // attached to an NSView. - static NSView* GetNSView(gfx::AcceleratedWidget widget); - private: // For CALayerFrameSink::FromAcceleratedWidget to access Get. friend class CALayerFrameSink;
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/ui/accelerated_widget_mac/accelerated_widget_mac.mm index a58c695..7bd2567 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.mm +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
@@ -73,14 +73,6 @@ return found->second; } -// static -NSView* AcceleratedWidgetMac::GetNSView(gfx::AcceleratedWidget widget) { - AcceleratedWidgetMac* widget_mac = Get(widget); - if (!widget_mac || !widget_mac->view_) - return nil; - return widget_mac->view_->AcceleratedWidgetGetNSView(); -} - void AcceleratedWidgetMac::SetSuspended(bool is_suspended) { is_suspended_ = is_suspended; }
diff --git a/ui/accessibility/ax_action_data.h b/ui/accessibility/ax_action_data.h index 2040b90..bc3fc27 100644 --- a/ui/accessibility/ax_action_data.h +++ b/ui/accessibility/ax_action_data.h
@@ -5,7 +5,6 @@ #ifndef UI_ACCESSIBILITY_AX_ACTION_DATA_H_ #define UI_ACCESSIBILITY_AX_ACTION_DATA_H_ -#include "base/strings/string16.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_export.h" #include "ui/gfx/geometry/rect.h" @@ -63,8 +62,8 @@ // The target point for the action. gfx::Point target_point; - // The new value for a node, for the SET_VALUE action. - base::string16 value; + // The new value for a node, for the SET_VALUE action. UTF-8 encoded. + std::string value; // The event to fire in response to a HIT_TEST action. ax::mojom::Event hit_test_event_to_fire = ax::mojom::Event::kNone;
diff --git a/ui/accessibility/mojom/ax_action_data.mojom b/ui/accessibility/mojom/ax_action_data.mojom index 35557cb..69ca868 100644 --- a/ui/accessibility/mojom/ax_action_data.mojom +++ b/ui/accessibility/mojom/ax_action_data.mojom
@@ -4,7 +4,6 @@ module ax.mojom; -import "mojo/public/mojom/base/string16.mojom"; import "ui/accessibility/ax_enums.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; @@ -24,6 +23,6 @@ int32 custom_action_id; gfx.mojom.Rect target_rect; gfx.mojom.Point target_point; - mojo_base.mojom.String16 value; + string value; Event hit_test_event_to_fire; };
diff --git a/ui/accessibility/mojom/ax_action_data_mojom_traits.h b/ui/accessibility/mojom/ax_action_data_mojom_traits.h index 65fd6ab..39782b5 100644 --- a/ui/accessibility/mojom/ax_action_data_mojom_traits.h +++ b/ui/accessibility/mojom/ax_action_data_mojom_traits.h
@@ -5,7 +5,6 @@ #ifndef UI_ACCESSIBILITY_MOJOM_AX_ACTION_DATA_MOJOM_TRAITS_H_ #define UI_ACCESSIBILITY_MOJOM_AX_ACTION_DATA_MOJOM_TRAITS_H_ -#include "mojo/public/cpp/base/string16_mojom_traits.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/mojom/ax_action_data.mojom-shared.h" #include "ui/gfx/geometry/mojo/geometry_struct_traits.h" @@ -49,7 +48,7 @@ static gfx::Point target_point(const ui::AXActionData& a) { return a.target_point; } - static base::string16 value(const ui::AXActionData& a) { return a.value; } + static std::string value(const ui::AXActionData& a) { return a.value; } static ax::mojom::Event hit_test_event_to_fire(const ui::AXActionData& a) { return a.hit_test_event_to_fire; }
diff --git a/ui/accessibility/mojom/ax_action_data_mojom_traits_unittest.cc b/ui/accessibility/mojom/ax_action_data_mojom_traits_unittest.cc index 2d583002..5ff45af 100644 --- a/ui/accessibility/mojom/ax_action_data_mojom_traits_unittest.cc +++ b/ui/accessibility/mojom/ax_action_data_mojom_traits_unittest.cc
@@ -29,7 +29,7 @@ input.custom_action_id = 9; input.target_rect = gfx::Rect(10, 11, 12, 13); input.target_point = gfx::Point(14, 15); - input.value = base::ASCIIToUTF16("value"); + input.value = "value"; input.hit_test_event_to_fire = ax::mojom::Event::kFocus; ui::AXActionData output; @@ -49,6 +49,6 @@ EXPECT_EQ(output.custom_action_id, 9); EXPECT_EQ(output.target_rect, gfx::Rect(10, 11, 12, 13)); EXPECT_EQ(output.target_point, gfx::Point(14, 15)); - EXPECT_EQ(output.value, base::ASCIIToUTF16("value")); + EXPECT_EQ(output.value, "value"); EXPECT_EQ(output.hit_test_event_to_fire, ax::mojom::Event::kFocus); }
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm index 714bde4..f91bb5f 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -651,7 +651,7 @@ // Set type-specific information as necessary for actions set above. if ([value isKindOfClass:[NSString class]]) { - data.value = base::SysNSStringToUTF16(value); + data.value = base::SysNSStringToUTF8(value); } else if (data.action == ax::mojom::Action::kSetSelection && [value isKindOfClass:[NSValue class]]) { NSRange range = [value rangeValue];
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index c7d41dd..9d127ab 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -952,7 +952,7 @@ AXActionData data; data.action = ax::mojom::Action::kSetValue; - data.value = new_value; + data.value = base::WideToUTF8(new_value); if (target->delegate_->AccessibilityPerformAction(data)) return S_OK; return E_FAIL; @@ -1496,7 +1496,7 @@ AXActionData data; data.action = ax::mojom::Action::kSetValue; - data.value = base::string16(value); + data.value = base::WideToUTF8(value); if (delegate_->AccessibilityPerformAction(data)) return S_OK; return E_FAIL; @@ -1527,7 +1527,7 @@ STDMETHODIMP AXPlatformNodeWin::SetValue(double value) { AXActionData data; data.action = ax::mojom::Action::kSetValue; - data.value = base::NumberToString16(value); + data.value = base::NumberToString(value); if (delegate_->AccessibilityPerformAction(data)) return S_OK; return E_FAIL;
diff --git a/ui/compositor/test/test_compositor_host_mac.mm b/ui/compositor/test/test_compositor_host_mac.mm index f643f0a..04301aa 100644 --- a/ui/compositor/test/test_compositor_host_mac.mm +++ b/ui/compositor/test/test_compositor_host_mac.mm
@@ -83,7 +83,6 @@ virtual ~TestAcceleratedWidgetMacNSView() { [view_ release]; } // AcceleratedWidgetMacNSView - NSView* AcceleratedWidgetGetNSView() const override { return view_; } void AcceleratedWidgetCALayerParamsUpdated() override {} private:
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index 151cacf..8766c67 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -145,7 +145,8 @@ flags = GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; break; case gfx::BufferUsage::SCANOUT_VDA_WRITE: - flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; + flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING | + GBM_BO_USE_HW_VIDEO_DECODER; break; case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT:
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc index f581490..519d09c 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.cc +++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -4,7 +4,6 @@ #include "ui/views/accessibility/ax_aura_obj_cache.h" -#include "base/memory/ptr_util.h" #include "base/memory/singleton.h" #include "base/strings/string_util.h" #include "ui/aura/client/aura_constants.h" @@ -70,8 +69,9 @@ // When an entire widget is deleted, it doesn't always send a notification // on each of its views, so we need to explore them recursively. - if (widget->GetRootView()) - RemoveViewSubtree(widget->GetRootView()); + auto* view = widget->GetRootView(); + if (view) + RemoveViewSubtree(view); } void AXAuraObjCache::Remove(aura::Window* window, aura::Window* parent) { @@ -84,28 +84,14 @@ AXAuraObjWrapper* AXAuraObjCache::Get(int32_t id) { auto it = cache_.find(id); - - if (it == cache_.end()) - return nullptr; - - return it->second.get(); -} - -void AXAuraObjCache::Remove(int32_t id) { - AXAuraObjWrapper* obj = Get(id); - - if (id == -1 || !obj) - return; - - cache_.erase(id); + return it != cache_.end() ? it->second.get() : nullptr; } void AXAuraObjCache::GetTopLevelWindows( std::vector<AXAuraObjWrapper*>* children) { - for (auto it = window_to_id_map_.begin(); it != window_to_id_map_.end(); - ++it) { - if (!it->first->parent()) - children->push_back(GetOrCreate(it->first)); + for (const auto& it : window_to_id_map_) { + if (!it.first->parent()) + children->push_back(GetOrCreate(it.first)); } } @@ -213,11 +199,11 @@ if (it != aura_view_to_id_map.end()) return Get(it->second); - AXAuraObjWrapper* wrapper = new AuraViewWrapper(aura_view); + auto wrapper = std::make_unique<AuraViewWrapper>(aura_view); int32_t id = wrapper->GetUniqueId().Get(); aura_view_to_id_map[aura_view] = id; - cache_[id] = base::WrapUnique(wrapper); - return wrapper; + cache_[id] = std::move(wrapper); + return cache_[id].get(); } template <typename AuraView> @@ -228,10 +214,7 @@ return -1; auto it = aura_view_to_id_map.find(aura_view); - if (it != aura_view_to_id_map.end()) - return it->second; - - return -1; + return it != aura_view_to_id_map.end() ? it->second : -1; } template <typename AuraView> @@ -242,7 +225,7 @@ if (id == -1) return; aura_view_to_id_map.erase(aura_view); - Remove(id); + cache_.erase(id); } } // namespace views
diff --git a/ui/views/accessibility/ax_aura_obj_cache.h b/ui/views/accessibility/ax_aura_obj_cache.h index ee01b96..f798bdb 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.h +++ b/ui/views/accessibility/ax_aura_obj_cache.h
@@ -69,9 +69,6 @@ // Lookup a cached entry based on an id. AXAuraObjWrapper* Get(int32_t id); - // Remove a cached entry based on an id. - void Remove(int32_t id); - // Get all top level windows this cache knows about. void GetTopLevelWindows(std::vector<AXAuraObjWrapper*>* children);
diff --git a/ui/views/accessibility/ax_view_obj_wrapper.cc b/ui/views/accessibility/ax_view_obj_wrapper.cc index 2645da5..f9b4ab6 100644 --- a/ui/views/accessibility/ax_view_obj_wrapper.cc +++ b/ui/views/accessibility/ax_view_obj_wrapper.cc
@@ -4,10 +4,8 @@ #include "ui/views/accessibility/ax_view_obj_wrapper.h" -#include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_node_data.h" -#include "ui/events/event_utils.h" #include "ui/views/accessibility/ax_aura_obj_cache.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/view.h" @@ -30,7 +28,7 @@ if (view_->GetWidget()) return cache->GetOrCreate(view_->GetWidget()); - return NULL; + return nullptr; } void AXViewObjWrapper::GetChildren(
diff --git a/ui/views/accessibility/ax_view_obj_wrapper.h b/ui/views/accessibility/ax_view_obj_wrapper.h index c14058a..2de3a6d 100644 --- a/ui/views/accessibility/ax_view_obj_wrapper.h +++ b/ui/views/accessibility/ax_view_obj_wrapper.h
@@ -29,7 +29,7 @@ bool HandleAccessibleAction(const ui::AXActionData& action) override; private: - View* view_; + View* const view_; DISALLOW_COPY_AND_ASSIGN(AXViewObjWrapper); };
diff --git a/ui/views/animation/bounds_animator.cc b/ui/views/animation/bounds_animator.cc index 52a4756..fc4e04c 100644 --- a/ui/views/animation/bounds_animator.cc +++ b/ui/views/animation/bounds_animator.cc
@@ -25,8 +25,8 @@ // Delete all the animations, but don't remove any child views. We assume the // view owns us and is going to be deleted anyway. - for (ViewToDataMap::iterator i = data_.begin(); i != data_.end(); ++i) - CleanupData(false, &(i->second), i->first); + for (auto& entry : data_) + CleanupData(false, &entry.second); } void BoundsAnimator::AnimateViewTo(View* view, const gfx::Rect& target) { @@ -36,8 +36,8 @@ Data existing_data; if (IsAnimating(view)) { - // Don't immediatly delete the animation, that might trigger a callback from - // the animationcontainer. + // Don't immediately delete the animation, that might trigger a callback + // from the animation container. existing_data = RemoveFromMaps(view); } @@ -55,22 +55,20 @@ data.animation->Show(); - CleanupData(true, &existing_data, nullptr); + CleanupData(true, &existing_data); } void BoundsAnimator::SetTargetBounds(View* view, const gfx::Rect& target) { - if (!IsAnimating(view)) { + const auto i = data_.find(view); + if (i == data_.end()) AnimateViewTo(view, target); - return; - } - - data_[view].target_bounds = target; + else + i->second.target_bounds = target; } -gfx::Rect BoundsAnimator::GetTargetBounds(View* view) { - if (!IsAnimating(view)) - return view->bounds(); - return data_[view].target_bounds; +gfx::Rect BoundsAnimator::GetTargetBounds(const View* view) const { + const auto i = data_.find(view); + return (i == data_.end()) ? view->bounds() : i->second.target_bounds; } void BoundsAnimator::SetAnimationForView( @@ -78,7 +76,8 @@ std::unique_ptr<gfx::SlideAnimation> animation) { DCHECK(animation); - if (!IsAnimating(view)) + const auto i = data_.find(view); + if (i == data_.end()) return; // We delay deleting the animation until the end so that we don't prematurely @@ -86,7 +85,7 @@ std::unique_ptr<gfx::Animation> old_animation = ResetAnimationForView(view); gfx::SlideAnimation* animation_ptr = animation.get(); - data_[view].animation = std::move(animation); + i->second.animation = std::move(animation); animation_to_view_[animation_ptr] = view; animation_ptr->set_delegate(this); @@ -95,22 +94,23 @@ } const gfx::SlideAnimation* BoundsAnimator::GetAnimationForView(View* view) { - return !IsAnimating(view) ? nullptr : data_[view].animation.get(); + const auto i = data_.find(view); + return (i == data_.end()) ? nullptr : i->second.animation.get(); } void BoundsAnimator::SetAnimationDelegate( View* view, std::unique_ptr<AnimationDelegate> delegate) { - DCHECK(IsAnimating(view)); + const auto i = data_.find(view); + DCHECK(i != data_.end()); - data_[view].delegate = std::move(delegate); + i->second.delegate = std::move(delegate); } void BoundsAnimator::StopAnimatingView(View* view) { - if (!IsAnimating(view)) - return; - - data_[view].animation->Stop(); + const auto i = data_.find(view); + if (i != data_.end()) + i->second.animation->Stop(); } bool BoundsAnimator::IsAnimating(View* view) const { @@ -158,16 +158,17 @@ BoundsAnimator::Data::~Data() = default; BoundsAnimator::Data BoundsAnimator::RemoveFromMaps(View* view) { - DCHECK(data_.count(view) > 0); - DCHECK(animation_to_view_.count(data_[view].animation.get()) > 0); + const auto i = data_.find(view); + DCHECK(i != data_.end()); + DCHECK(animation_to_view_.count(i->second.animation.get()) > 0); - Data old_data = std::move(data_[view]); + Data old_data = std::move(i->second); data_.erase(view); animation_to_view_.erase(old_data.animation.get()); return old_data; } -void BoundsAnimator::CleanupData(bool send_cancel, Data* data, View* view) { +void BoundsAnimator::CleanupData(bool send_cancel, Data* data) { if (send_cancel && data->delegate) data->delegate->AnimationCanceled(data->animation.get()); @@ -181,11 +182,12 @@ std::unique_ptr<gfx::Animation> BoundsAnimator::ResetAnimationForView( View* view) { - if (!IsAnimating(view)) + const auto i = data_.find(view); + if (i == data_.end()) return nullptr; std::unique_ptr<gfx::Animation> old_animation = - std::move(data_[view].animation); + std::move(i->second.animation); animation_to_view_.erase(old_animation.get()); // Reset the delegate so that we don't attempt any processing when the // animation calls us back. @@ -212,7 +214,7 @@ } } - CleanupData(false, &data, view); + CleanupData(false, &data); } void BoundsAnimator::AnimationProgressed(const gfx::Animation* animation) {
diff --git a/ui/views/animation/bounds_animator.h b/ui/views/animation/bounds_animator.h index 71fac2759..c0a6501f 100644 --- a/ui/views/animation/bounds_animator.h +++ b/ui/views/animation/bounds_animator.h
@@ -56,7 +56,7 @@ // Returns the target bounds for the specified view. If |view| is not // animating its current bounds is returned. - gfx::Rect GetTargetBounds(View* view); + gfx::Rect GetTargetBounds(const View* view) const; // Sets the animation for the specified view. void SetAnimationForView(View* view, @@ -127,7 +127,7 @@ ANIMATION_CANCELED }; - typedef std::map<View*, Data> ViewToDataMap; + typedef std::map<const View*, Data> ViewToDataMap; typedef std::map<const gfx::Animation*, View*> AnimationToViewMap; @@ -137,7 +137,7 @@ // Does the necessary cleanup for |data|. If |send_cancel| is true and a // delegate has been installed on |data| AnimationCanceled is invoked on it. - void CleanupData(bool send_cancel, Data* data, View* view); + void CleanupData(bool send_cancel, Data* data); // Used when changing the animation for a view. This resets the maps for // the animation used by view and returns the current animation. Ownership
diff --git a/ui/views/cocoa/bridged_native_widget.h b/ui/views/cocoa/bridged_native_widget.h index 83af13a..582dd406 100644 --- a/ui/views/cocoa/bridged_native_widget.h +++ b/ui/views/cocoa/bridged_native_widget.h
@@ -240,8 +240,7 @@ void InitCompositor(); void DestroyCompositor(); - // Installs the NSView for hosting the composited layer. It is later provided - // to |compositor_widget_| via AcceleratedWidgetGetNSView(). + // Installs the NSView for hosting the composited layer. void AddCompositorSuperview(); // Size the layer to match the client area bounds, taking into account display @@ -277,7 +276,6 @@ float new_device_scale_factor) override; // Overridden from ui::AcceleratedWidgetMac: - NSView* AcceleratedWidgetGetNSView() const override; void AcceleratedWidgetCALayerParamsUpdated() override; // Overridden from BridgedNativeWidgetOwner:
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index 230fd8f2..94bdab1 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -1069,10 +1069,6 @@ //////////////////////////////////////////////////////////////////////////////// // BridgedNativeWidget, AcceleratedWidgetMac: -NSView* BridgedNativeWidget::AcceleratedWidgetGetNSView() const { - return compositor_superview_; -} - void BridgedNativeWidget::AcceleratedWidgetCALayerParamsUpdated() { // Ignore frames arriving "late" for an old size. A frame at the new size // should arrive soon.
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.h b/ui/views/cocoa/native_widget_mac_nswindow.h index 0de886a..97b37b8 100644 --- a/ui/views/cocoa/native_widget_mac_nswindow.h +++ b/ui/views/cocoa/native_widget_mac_nswindow.h
@@ -12,6 +12,24 @@ @protocol WindowTouchBarDelegate; +// Weak lets Chrome launch even if a future macOS doesn't have the below classes + +WEAK_IMPORT_ATTRIBUTE +@interface NSNextStepFrame : NSView +@end + +WEAK_IMPORT_ATTRIBUTE +@interface NSThemeFrame : NSView +@end + +VIEWS_EXPORT +@interface NativeWidgetMacNSWindowBorderlessFrame : NSNextStepFrame +@end + +VIEWS_EXPORT +@interface NativeWidgetMacNSWindowTitledFrame : NSThemeFrame +@end + // The NSWindow used by BridgedNativeWidget. Provides hooks into AppKit that // can only be accomplished by overriding methods. VIEWS_EXPORT
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.mm b/ui/views/cocoa/native_widget_mac_nswindow.mm index 145bbbe0..bd4f06b2 100644 --- a/ui/views/cocoa/native_widget_mac_nswindow.mm +++ b/ui/views/cocoa/native_widget_mac_nswindow.mm
@@ -15,7 +15,12 @@ #include "ui/views/widget/widget_delegate.h" @interface NSWindow (Private) ++ (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle; - (BOOL)hasKeyAppearance; + +// Available in later point releases of 10.10. On 10.11+, use the public +// -performWindowDragWithEvent: instead. +- (void)beginWindowDragWithEvent:(NSEvent*)event; @end @interface NativeWidgetMacNSWindow () @@ -29,6 +34,38 @@ - (BOOL)_isTitleHidden; @end +// Use this category to implement mouseDown: on multiple frame view classes +// with different superclasses. +@interface NSView (CRFrameViewAdditions) +- (void)cr_mouseDownOnFrameView:(NSEvent*)event; +@end + +@implementation NSView (CRFrameViewAdditions) +// If a mouseDown: falls through to the frame view, turn it into a window drag. +- (void)cr_mouseDownOnFrameView:(NSEvent*)event { + if (@available(macOS 10.11, *)) + return [self.window performWindowDragWithEvent:event]; + else if ([self.window + respondsToSelector:@selector(beginWindowDragWithEvent:)]) + return [self.window beginWindowDragWithEvent:event]; + else + NOTREACHED(); + [super mouseDown:event]; +} +@end + +@implementation NativeWidgetMacNSWindowTitledFrame +- (void)mouseDown:(NSEvent*)event { + [self cr_mouseDownOnFrameView:event]; +} +@end + +@implementation NativeWidgetMacNSWindowBorderlessFrame +- (void)mouseDown:(NSEvent*)event { + [self cr_mouseDownOnFrameView:event]; +} +@end + @implementation NativeWidgetMacNSWindow { @private base::scoped_nsobject<CommandDispatcher> commandDispatcher_; @@ -99,6 +136,17 @@ // NSWindow overrides. ++ (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle { + if (windowStyle & NSWindowStyleMaskTitled) { + if (Class customFrame = [NativeWidgetMacNSWindowTitledFrame class]) + return customFrame; + } else if (Class customFrame = + [NativeWidgetMacNSWindowBorderlessFrame class]) { + return customFrame; + } + return [super frameViewClassForStyleMask:windowStyle]; +} + - (BOOL)_isTitleHidden { if (![self delegate]) return NO; @@ -106,6 +154,13 @@ return ![self viewsWidget]->widget_delegate()->ShouldShowWindowTitle(); } +// The base implementation returns YES if the window's frame view is a custom +// class, which causes undesirable changes in behavior. AppKit NSWindow +// subclasses are known to override it and return NO. +- (BOOL)_usesCustomDrawing { + return NO; +} + // Ignore [super canBecome{Key,Main}Window]. The default is NO for windows with // NSBorderlessWindowMask, which is not the desired behavior. // Note these can be called via -[NSWindow close] while the widget is being torn
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 1d22a51..8c3d787e 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1035,11 +1035,11 @@ return View::HandleAccessibleAction(action_data); if (action_data.action == ax::mojom::Action::kSetValue) { - SetText(action_data.value); + SetText(base::UTF8ToUTF16(action_data.value)); ClearSelection(); return true; } else if (action_data.action == ax::mojom::Action::kReplaceSelectedText) { - InsertOrReplaceText(action_data.value); + InsertOrReplaceText(base::UTF8ToUTF16(action_data.value)); ClearSelection(); return true; }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config_select.html b/ui/webui/resources/cr_components/chromeos/network/network_config_select.html index a103010..0fb698c7f 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config_select.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_config_select.html
@@ -1,4 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="network_shared_css.html"> @@ -6,7 +8,7 @@ <template> <style include="network-shared md-select"> .md-select { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); width: 100%; }
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html index 7c20b90..636bcc8 100644 --- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html +++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -5,7 +5,6 @@ <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/default-theme.html"> <dom-module id="cr-dialog"> <template> @@ -61,7 +60,7 @@ :host ::slotted([slot=body]) { -webkit-padding-end: 20px; -webkit-padding-start: 20px; - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); padding-bottom: 0; padding-top: 0; @apply --cr-dialog-body; @@ -78,7 +77,7 @@ :host ::slotted([slot=title]) { -webkit-padding-end: 20px; -webkit-padding-start: 20px; - color: var(--primary-text-color); + color: var(--cr-primary-text-color); flex: 1; font-size: calc(15 / 13 * 100%); line-height: 1; @@ -108,7 +107,7 @@ :host ::slotted([slot=footer]) { border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; - border-top: 1px solid var(--divider-color); + border-top: 1px solid #dbdbdb; margin: 0; padding: 16px 20px; }
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.js b/ui/webui/resources/cr_elements/cr_input/cr_input.js index bfd6110..7f4d8b3 100644 --- a/ui/webui/resources/cr_elements/cr_input/cr_input.js +++ b/ui/webui/resources/cr_elements/cr_input/cr_input.js
@@ -59,6 +59,17 @@ value: '', }, + /** + * This is strictly used internally for styling, do not attempt to use + * this to set focus. + * @private + */ + focused_: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + incremental: Boolean, invalid: { @@ -127,8 +138,8 @@ }, listeners: { - 'input.focus': 'onInputFocusChange_', - 'input.blur': 'onInputFocusChange_', + 'input.focus': 'onInputFocus_', + 'input.blur': 'onInputBlur_', 'input.change': 'onInputChange_', 'input.keydown': 'onInputKeydown_', 'focus': 'focusInput_', @@ -159,7 +170,7 @@ disabledChanged_: function(current, previous) { this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false'); // In case input was focused when disabled changes. - this.removeAttribute('focused_'); + this.focused_ = false; // Don't change tabindex until after finished attaching, since this.tabindex // might not be intialized yet. @@ -270,13 +281,14 @@ this.fire('change', {sourceEvent: e}); }, - // focused_ is used instead of :focus-within, so focus on elements within the - // suffix slot does not trigger a change in input styles. - onInputFocusChange_: function() { - if (this.shadowRoot.activeElement == this.inputElement) - this.setAttribute('focused_', ''); - else - this.removeAttribute('focused_'); + /** @private */ + onInputFocus_: function() { + this.focused_ = true; + }, + + /** @private */ + onInputBlur_: function() { + this.focused_ = false; }, /**
diff --git a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html index 4c43b0f6..1ecfead 100644 --- a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html +++ b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html
@@ -5,7 +5,6 @@ <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-behaviors/paper-ripple-behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/default-theme.html"> <dom-module id="cr-link-row"> <template strip-whitespace="">
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index 28bca01..13686d7 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -6,8 +6,8 @@ <custom-style> <style is="custom-style"> html { - --primary-text-color: var(--google-grey-900); - --secondary-text-color: var(--google-grey-refresh-700); + --cr-primary-text-color: var(--google-grey-900); + --cr-secondary-text-color: var(--google-grey-refresh-700); --cr-actionable: { cursor: pointer; @@ -37,7 +37,7 @@ /* Common properties for WebUI pages. */ --cr-page-host: { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); line-height: 154%; /* Apply 20px default line-height to all text. */ overflow: hidden; /* Prevent double scroll bar bugs. */ user-select: text; @@ -50,12 +50,12 @@ } --cr-primary-text: { - color: var(--primary-text-color); + color: var(--cr-primary-text-color); line-height: 154%; /* 20px. */ } --cr-secondary-text: { - color: var(--secondary-text-color); + color: var(--cr-secondary-text-color); font-weight: 400; }