diff --git a/AUTHORS b/AUTHORS index 397d7c96..4618223b 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -722,6 +722,7 @@ U. Artie Eoff <ullysses.a.eoff@intel.com> Umar Hansa <umar.hansa@gmail.com> Upendra Gowda <upendrag.gowda@gmail.com> +Uzair Jaleel <uzair.jaleel@samsung.com> Vaibhav Agrawal <vaibhav1.a@samsung.com> Valentin Ilie <valentin.ilie@intel.com> Vamshikrishna Yellenki <vamshi@motorola.com>
diff --git a/DEPS b/DEPS index d23886c7..5d0be82 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,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': 'a6ae1f7cda072ff814a838e2d9013a017552cc35', + 'skia_revision': 'dc3c336c84dbbf43c68337ebb1b640d5c948e2aa', # 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': '06d36330e481d098c19fe047809d45955837ee46', + 'v8_revision': 'f7036b132f6bcce9312b52a9ba386ae487280713', # 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. @@ -60,7 +60,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '2ddef8858e5015140f374d5c06d1a68b7c78af10', + 'swiftshader_revision': '38182314999cc26c6510fbb5d6372fda8847c1b8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -100,7 +100,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. - 'libfuzzer_revision': 'eebc6eb55995a29173f269baf071046fcd2e0f4b', + 'libfuzzer_revision': 'a746f0ef810637b40784e808bad49aa2ef1bde8b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-node-modules # and whatever else without interference from each other.
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index f6f6a1c..2df1e018 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -413,8 +413,6 @@ "common/system/tray/tray_popup_header_button.cc", "common/system/tray/tray_popup_header_button.h", "common/system/tray/tray_popup_ink_drop_style.h", - "common/system/tray/tray_popup_item_container.cc", - "common/system/tray/tray_popup_item_container.h", "common/system/tray/tray_popup_item_style.cc", "common/system/tray/tray_popup_item_style.h", "common/system/tray/tray_popup_utils.cc",
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index c132a7b..fa81be1 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -84,13 +84,12 @@ DISALLOW_COPY_AND_ASSIGN(TestTarget); }; -class ReleaseAccelerator : public ui::Accelerator { - public: - ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers) - : ui::Accelerator(keycode, modifiers) { - set_type(ui::ET_KEY_RELEASED); - } -}; +ui::Accelerator CreateReleaseAccelerator(ui::KeyboardCode key_code, + int modifiers) { + ui::Accelerator accelerator(key_code, modifiers); + accelerator.set_key_state(ui::Accelerator::KeyState::RELEASED); + return accelerator; +} class DummyBrightnessControlDelegate : public BrightnessControlDelegate { public: @@ -216,12 +215,12 @@ static AcceleratorController* GetController(); static bool ProcessInController(const ui::Accelerator& accelerator) { - if (accelerator.type() == ui::ET_KEY_RELEASED) { + if (accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) { // If the |accelerator| should trigger on release, then we store the // pressed version of it first in history then the released one to // simulate what happens in reality. ui::Accelerator pressed_accelerator = accelerator; - pressed_accelerator.set_type(ui::ET_KEY_PRESSED); + pressed_accelerator.set_key_state(ui::Accelerator::KeyState::PRESSED); GetController()->accelerator_history()->StoreCurrentAccelerator( pressed_accelerator); } @@ -286,7 +285,7 @@ TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) { ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); ui::Accelerator release(press); - release.set_type(ui::ET_KEY_RELEASED); + release.set_key_state(ui::Accelerator::KeyState::RELEASED); ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); ASSERT_TRUE(ewh); StubForTest(ewh); @@ -308,7 +307,7 @@ TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) { ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); ui::Accelerator release(press); - release.set_type(ui::ET_KEY_RELEASED); + release.set_key_state(ui::Accelerator::KeyState::RELEASED); ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); ASSERT_TRUE(ewh); StubForTest(ewh); @@ -747,11 +746,9 @@ TEST_F(AcceleratorControllerTest, AutoRepeat) { ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_CONTROL_DOWN); - accelerator_a.set_type(ui::ET_KEY_PRESSED); TestTarget target_a; GetController()->Register({accelerator_a}, &target_a); ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_CONTROL_DOWN); - accelerator_b.set_type(ui::ET_KEY_PRESSED); TestTarget target_b; GetController()->Register({accelerator_b}, &target_b); @@ -1032,8 +1029,8 @@ EXPECT_EQ(ui::VKEY_LWIN, GetCurrentAccelerator().key_code()); EXPECT_EQ(0u, test_app_list_presenter.toggle_count()); - EXPECT_TRUE( - ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); + EXPECT_TRUE(ProcessInController( + CreateReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); RunAllPendingInMessageLoop(); EXPECT_EQ(1u, test_app_list_presenter.toggle_count()); EXPECT_EQ(ui::VKEY_LWIN, GetPreviousAccelerator().key_code()); @@ -1042,8 +1039,8 @@ delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); EXPECT_FALSE( ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); - EXPECT_FALSE( - ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); + EXPECT_FALSE(ProcessInController( + CreateReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE); RunAllPendingInMessageLoop(); EXPECT_EQ(1u, test_app_list_presenter.toggle_count()); @@ -1051,8 +1048,8 @@ // Turning off spoken feedback should allow the AppList to toggle again. EXPECT_FALSE( ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE))); - EXPECT_TRUE( - ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); + EXPECT_TRUE(ProcessInController( + CreateReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE))); RunAllPendingInMessageLoop(); EXPECT_EQ(2u, test_app_list_presenter.toggle_count()); @@ -1062,7 +1059,7 @@ RunAllPendingInMessageLoop(); EXPECT_EQ(3u, test_app_list_presenter.toggle_count()); EXPECT_FALSE(ProcessInController( - ReleaseAccelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE))); + CreateReleaseAccelerator(ui::VKEY_BROWSER_SEARCH, ui::EF_NONE))); RunAllPendingInMessageLoop(); EXPECT_EQ(3u, test_app_list_presenter.toggle_count()); } @@ -1070,9 +1067,8 @@ TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) { // Test IME shortcuts. ui::Accelerator control_space_down(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); - control_space_down.set_type(ui::ET_KEY_PRESSED); ui::Accelerator control_space_up(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); - control_space_up.set_type(ui::ET_KEY_RELEASED); + control_space_up.set_key_state(ui::Accelerator::KeyState::RELEASED); const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE); const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE); const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE); @@ -1203,8 +1199,8 @@ EXPECT_FALSE(ProcessInController(press_alt_then_search)); // When you release Search before Alt, the key_code is still VKEY_LWIN and // Alt is still the modifier. - const ReleaseAccelerator release_search_before_alt(ui::VKEY_LWIN, - ui::EF_ALT_DOWN); + const ui::Accelerator release_search_before_alt( + CreateReleaseAccelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)); EXPECT_TRUE(ProcessInController(release_search_before_alt)); EXPECT_TRUE(input_method_manager->GetImeKeyboard()->CapsLockIsEnabled()); input_method_manager->GetImeKeyboard()->SetCapsLockEnabled(false); @@ -1219,8 +1215,8 @@ // 3. Press Alt, Press Search, Release Alt, Release Search. EXPECT_FALSE(ProcessInController(press_alt_then_search)); - const ReleaseAccelerator release_alt_before_search(ui::VKEY_MENU, - ui::EF_COMMAND_DOWN); + const ui::Accelerator release_alt_before_search( + CreateReleaseAccelerator(ui::VKEY_MENU, ui::EF_COMMAND_DOWN)); EXPECT_TRUE(ProcessInController(release_alt_before_search)); EXPECT_TRUE(input_method_manager->GetImeKeyboard()->CapsLockIsEnabled()); input_method_manager->GetImeKeyboard()->SetCapsLockEnabled(false); @@ -1487,8 +1483,9 @@ ui::Accelerator CreateAccelerator(const AcceleratorData& data) const { ui::Accelerator result(data.keycode, data.modifiers); - result.set_type(data.trigger_on_press ? ui::ET_KEY_PRESSED - : ui::ET_KEY_RELEASED); + result.set_key_state(data.trigger_on_press + ? ui::Accelerator::KeyState::PRESSED + : ui::Accelerator::KeyState::RELEASED); return result; }
diff --git a/ash/common/accelerators/accelerator_controller.cc b/ash/common/accelerators/accelerator_controller.cc index e4af731e..50fbb48 100644 --- a/ash/common/accelerators/accelerator_controller.cc +++ b/ash/common/accelerators/accelerator_controller.cc
@@ -157,8 +157,9 @@ int modifiers, bool trigger_on_press) { ui::Accelerator accelerator(keycode, modifiers); - accelerator.set_type(trigger_on_press ? ui::ET_KEY_PRESSED - : ui::ET_KEY_RELEASED); + accelerator.set_key_state(trigger_on_press + ? ui::Accelerator::KeyState::PRESSED + : ui::Accelerator::KeyState::RELEASED); return accelerator; } @@ -283,7 +284,7 @@ void HandlePreviousIme(ImeControlDelegate* ime_control_delegate, const ui::Accelerator& accelerator) { base::RecordAction(UserMetricsAction("Accel_Previous_Ime")); - if (accelerator.type() == ui::ET_KEY_PRESSED) + if (accelerator.key_state() == ui::Accelerator::KeyState::PRESSED) ime_control_delegate->HandlePreviousIme(); // Else: consume the Ctrl+Space ET_KEY_RELEASED event but do not do anything. } @@ -369,7 +370,8 @@ // If something else was pressed between the Search key (LWIN) // being pressed and released, then ignore the release of the // Search key. - if (previous_accelerator.type() != ui::ET_KEY_PRESSED || + if (previous_accelerator.key_state() != + ui::Accelerator::KeyState::PRESSED || previous_accelerator.key_code() != ui::VKEY_LWIN) { return false; } @@ -466,7 +468,7 @@ bool CanHandleDisableCapsLock(const ui::Accelerator& previous_accelerator) { ui::KeyboardCode previous_key_code = previous_accelerator.key_code(); - if (previous_accelerator.type() == ui::ET_KEY_RELEASED || + if (previous_accelerator.key_state() == ui::Accelerator::KeyState::RELEASED || (previous_key_code != ui::VKEY_LSHIFT && previous_key_code != ui::VKEY_SHIFT && previous_key_code != ui::VKEY_RSHIFT)) { @@ -554,11 +556,12 @@ // This shortcust is set to be trigger on release. Either the current // accelerator is a Search release or Alt release. if (accelerator.key_code() == ui::VKEY_LWIN && - accelerator.type() == ui::ET_KEY_RELEASED) { + accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) { // The previous must be either an Alt press or Search press: // 1. Press Alt, Press Search, Release Search, Release Alt. // 2. Press Search, Press Alt, Release Search, Release Alt. - if (previous_accelerator.type() == ui::ET_KEY_PRESSED && + if (previous_accelerator.key_state() == + ui::Accelerator::KeyState::PRESSED && (previous_accelerator.key_code() == ui::VKEY_LWIN || previous_accelerator.key_code() == ui::VKEY_MENU)) { return ime && ime->GetImeKeyboard(); @@ -567,11 +570,12 @@ // Alt release. if (accelerator.key_code() == ui::VKEY_MENU && - accelerator.type() == ui::ET_KEY_RELEASED) { + accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) { // The previous must be either an Alt press or Search press: // 3. Press Alt, Press Search, Release Alt, Release Search. // 4. Press Search, Press Alt, Release Alt, Release Search. - if (previous_accelerator.type() == ui::ET_KEY_PRESSED && + if (previous_accelerator.key_state() == + ui::Accelerator::KeyState::PRESSED && (previous_accelerator.key_code() == ui::VKEY_LWIN || previous_accelerator.key_code() == ui::VKEY_MENU)) { return ime && ime->GetImeKeyboard();
diff --git a/ash/common/system/chromeos/audio/volume_view.cc b/ash/common/system/chromeos/audio/volume_view.cc index 47cfabe..edd95b1 100644 --- a/ash/common/system/chromeos/audio/volume_view.cc +++ b/ash/common/system/chromeos/audio/volume_view.cc
@@ -11,7 +11,6 @@ #include "ash/common/system/tray/actionable_view.h" #include "ash/common/system/tray/system_tray_item.h" #include "ash/common/system/tray/tray_constants.h" -#include "ash/common/system/tray/tray_popup_item_container.h" #include "ash/common/system/tray/tray_popup_utils.h" #include "ash/common/system/tray/tri_view.h" #include "ash/common/wm_shell.h"
diff --git a/ash/common/system/tray/system_tray_bubble.cc b/ash/common/system/tray/system_tray_bubble.cc index 75e6b04a..97b78894 100644 --- a/ash/common/system/tray/system_tray_bubble.cc +++ b/ash/common/system/tray/system_tray_bubble.cc
@@ -7,13 +7,11 @@ #include <utility> #include <vector> -#include "ash/common/material_design/material_design_controller.h" #include "ash/common/system/tray/system_tray.h" #include "ash/common/system/tray/system_tray_delegate.h" #include "ash/common/system/tray/system_tray_item.h" #include "ash/common/system/tray/tray_bubble_wrapper.h" #include "ash/common/system/tray/tray_constants.h" -#include "ash/common/system/tray/tray_popup_item_container.h" #include "ash/common/wm_shell.h" #include "base/metrics/histogram_macros.h" #include "base/threading/thread_task_runner_handle.h" @@ -295,12 +293,10 @@ } void SystemTrayBubble::UpdateBottomPadding() { - if (bubble_type_ == BUBBLE_TYPE_DEFAULT && - MaterialDesignController::IsSystemTrayMenuMaterial()) { + if (bubble_type_ == BUBBLE_TYPE_DEFAULT) bubble_view_->SetBottomPadding(kDefaultViewBottomPadding); - } else { + else bubble_view_->SetBottomPadding(0); - } } void SystemTrayBubble::CreateItemViews(LoginStatus login_status) { @@ -313,9 +309,7 @@ login_status = LoginStatus::LOCKED; } - std::vector<TrayPopupItemContainer*> item_containers; views::View* focus_view = nullptr; - const bool is_default_bubble = bubble_type_ == BUBBLE_TYPE_DEFAULT; for (size_t i = 0; i < items_.size(); ++i) { views::View* item_view = nullptr; switch (bubble_type_) { @@ -329,27 +323,8 @@ break; } if (item_view) { - TrayPopupItemContainer* tray_popup_item_container = - new TrayPopupItemContainer( - item_view, - is_default_bubble && - !MaterialDesignController::IsSystemTrayMenuMaterial()); - bubble_view_->AddChildView(tray_popup_item_container); - item_containers.push_back(tray_popup_item_container); - tray_item_view_map_[items_[i]->uma_type()] = tray_popup_item_container; - } - } - - if (!MaterialDesignController::IsSystemTrayMenuMaterial()) { - // For default view, draw bottom border for each item, except the last - // 2 items, which are the bottom header row and the one just above it. - if (is_default_bubble) { - const int last_item_with_border = - static_cast<int>(item_containers.size()) - 2; - for (int i = 0; i < last_item_with_border; ++i) { - item_containers.at(i)->SetBorder( - views::CreateSolidSidedBorder(0, 0, 1, 0, kBorderLightColor)); - } + bubble_view_->AddChildView(item_view); + tray_item_view_map_[items_[i]->uma_type()] = item_view; } }
diff --git a/ash/common/system/tray/system_tray_unittest.cc b/ash/common/system/tray/system_tray_unittest.cc index 90b68324..42407b4b 100644 --- a/ash/common/system/tray/system_tray_unittest.cc +++ b/ash/common/system/tray/system_tray_unittest.cc
@@ -14,7 +14,6 @@ #include "ash/common/system/tray/system_tray_bubble.h" #include "ash/common/system/tray/system_tray_item.h" #include "ash/common/system/tray/tray_constants.h" -#include "ash/common/system/tray/tray_popup_item_container.h" #include "ash/common/system/web_notification/web_notification_tray.h" #include "ash/common/wm_shell.h" #include "ash/common/wm_window.h"
diff --git a/ash/common/system/tray/tray_popup_item_container.cc b/ash/common/system/tray/tray_popup_item_container.cc deleted file mode 100644 index 3a3d0d5..0000000 --- a/ash/common/system/tray/tray_popup_item_container.cc +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/common/system/tray/tray_popup_item_container.h" - -#include "ash/common/system/tray/tray_constants.h" -#include "ui/gfx/canvas.h" -#include "ui/views/layout/box_layout.h" - -namespace ash { - -TrayPopupItemContainer::TrayPopupItemContainer(views::View* view, - bool change_background) - : active_(false), change_background_(change_background) { - set_notify_enter_exit_on_child(true); - views::BoxLayout* layout = - new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); - layout->SetDefaultFlex(1); - SetLayoutManager(layout); - if (view->layer()) { - SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(view->layer()->fills_bounds_opaquely()); - } - AddChildView(view); - SetVisible(view->visible()); -} - -TrayPopupItemContainer::~TrayPopupItemContainer() {} - -void TrayPopupItemContainer::SetActive(bool active) { - if (!change_background_ || active_ == active) - return; - active_ = active; - SchedulePaint(); -} - -void TrayPopupItemContainer::ChildVisibilityChanged(View* child) { - if (visible() == child->visible()) - return; - SetVisible(child->visible()); - PreferredSizeChanged(); -} - -void TrayPopupItemContainer::ChildPreferredSizeChanged(View* child) { - PreferredSizeChanged(); -} - -void TrayPopupItemContainer::OnMouseEntered(const ui::MouseEvent& event) { - SetActive(true); -} - -void TrayPopupItemContainer::OnMouseExited(const ui::MouseEvent& event) { - SetActive(false); -} - -void TrayPopupItemContainer::OnGestureEvent(ui::GestureEvent* event) { - if (event->type() == ui::ET_GESTURE_TAP_DOWN) { - SetActive(true); - } else if (event->type() == ui::ET_GESTURE_TAP_CANCEL || - event->type() == ui::ET_GESTURE_TAP) { - SetActive(false); - } -} - -void TrayPopupItemContainer::OnPaintBackground(gfx::Canvas* canvas) { - if (child_count() == 0) - return; - - views::View* view = child_at(0); - if (!view->background()) { - canvas->FillRect(gfx::Rect(size()), - (active_) ? kHoverBackgroundColor : kBackgroundColor); - } -} - -} // namespace ash
diff --git a/ash/common/system/tray/tray_popup_item_container.h b/ash/common/system/tray/tray_popup_item_container.h deleted file mode 100644 index 2fdddb7f..0000000 --- a/ash/common/system/tray/tray_popup_item_container.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_COMMON_SYSTEM_TRAY_TRAY_POPUP_ITEM_CONTAINER_H_ -#define ASH_COMMON_SYSTEM_TRAY_TRAY_POPUP_ITEM_CONTAINER_H_ - -#include "base/macros.h" -#include "ui/views/view.h" - -namespace ash { - -// A view which can optionally change the background color when a mouse is -// hovering or a user is interacting via touch. -class TrayPopupItemContainer : public views::View { - public: - TrayPopupItemContainer(views::View* view, bool change_background); - - ~TrayPopupItemContainer() override; - - bool active() { return active_; } - - private: - // Sets whether the active background is to be used, and triggers a paint. - void SetActive(bool active); - - // views::View: - void ChildVisibilityChanged(views::View* child) override; - void ChildPreferredSizeChanged(views::View* child) override; - void OnMouseEntered(const ui::MouseEvent& event) override; - void OnMouseExited(const ui::MouseEvent& event) override; - void OnGestureEvent(ui::GestureEvent* event) override; - void OnPaintBackground(gfx::Canvas* canvas) override; - - // True if either a mouse is hovering over this view, or if a user has touched - // down. - bool active_; - - // True if mouse hover and touch feedback can alter the background color of - // the container. - bool change_background_; - - DISALLOW_COPY_AND_ASSIGN(TrayPopupItemContainer); -}; - -} // namespace ash - -#endif // ASH_COMMON_SYSTEM_TRAY_TRAY_POPUP_ITEM_CONTAINER_H_
diff --git a/ash/common/system/web_notification/web_notification_tray.cc b/ash/common/system/web_notification/web_notification_tray.cc index 440d8cb..28f6586 100644 --- a/ash/common/system/web_notification/web_notification_tray.cc +++ b/ash/common/system/web_notification/web_notification_tray.cc
@@ -4,7 +4,6 @@ #include "ash/common/system/web_notification/web_notification_tray.h" -#include "ash/common/material_design/material_design_controller.h" #include "ash/common/session/session_state_delegate.h" #include "ash/common/shelf/shelf_constants.h" #include "ash/common/shelf/wm_shelf.h" @@ -64,7 +63,6 @@ constexpr int kMaximumSmallIconCount = 3; constexpr gfx::Size kTrayItemInnerIconSize(16, 16); -constexpr gfx::Size kTrayItemInnerBellIconSizeNonMd(18, 18); constexpr gfx::Size kTrayItemOuterSize(26, 26); constexpr int kTrayMainAxisInset = 3; constexpr int kTrayCrossAxisInset = 0; @@ -75,14 +73,6 @@ // Flag to disable animation. Only for testing. bool disable_animations_for_test = false; -} - -namespace { - -const SkColor kWebNotificationColorNoUnread = - SkColorSetARGB(128, 255, 255, 255); -const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE; -const int kNoUnreadIconSize = 18; } // namespace @@ -232,13 +222,12 @@ class WebNotificationImage : public WebNotificationItem { public: WebNotificationImage(const gfx::ImageSkia& image, - const gfx::Size& size, gfx::AnimationContainer* container, WebNotificationTray* tray) : WebNotificationItem(container, tray) { view_ = new views::ImageView(); view_->SetImage(image); - view_->SetImageSize(size); + view_->SetImageSize(kTrayItemInnerIconSize); AddChildView(view_); } @@ -272,7 +261,6 @@ } view_->SetText(str); - view_->SetEnabledColor(kWebNotificationColorWithUnread); SchedulePaint(); } @@ -295,21 +283,11 @@ DCHECK(status_area_window_); DCHECK(system_tray_); - if (MaterialDesignController::IsShelfMaterial()) { - SetInkDropMode(InkDropMode::ON); - gfx::ImageSkia bell_image = - CreateVectorIcon(kShelfNotificationsIcon, kShelfIconColor); - const gfx::Size bell_icon_size = kTrayItemInnerIconSize; - bell_icon_.reset(new WebNotificationImage( - bell_image, bell_icon_size, animation_container_.get(), this)); - } else { - gfx::ImageSkia bell_image = - CreateVectorIcon(ui::kNotificationsIcon, kNoUnreadIconSize, - kWebNotificationColorNoUnread); - const gfx::Size bell_icon_size = kTrayItemInnerBellIconSizeNonMd; - bell_icon_.reset(new WebNotificationImage( - bell_image, bell_icon_size, animation_container_.get(), this)); - } + SetInkDropMode(InkDropMode::ON); + gfx::ImageSkia bell_image = + CreateVectorIcon(kShelfNotificationsIcon, kShelfIconColor); + bell_icon_.reset( + new WebNotificationImage(bell_image, animation_container_.get(), this)); tray_container()->AddChildView(bell_icon_.get()); counter_.reset(new WebNotificationLabel(animation_container_.get(), this)); @@ -583,9 +561,8 @@ if (visible_small_icons_.count(notification->id()) != 0) continue; - auto* item = - new WebNotificationImage(image.AsImageSkia(), kTrayItemInnerIconSize, - animation_container_.get(), this); + auto* item = new WebNotificationImage(image.AsImageSkia(), + animation_container_.get(), this); visible_small_icons_.insert(std::make_pair(notification->id(), item)); tray_container()->AddChildViewAt(item, 0);
diff --git a/ash/mus/accelerators/accelerator_controller_registrar.cc b/ash/mus/accelerators/accelerator_controller_registrar.cc index bac5387..bf4acc7 100644 --- a/ash/mus/accelerators/accelerator_controller_registrar.cc +++ b/ash/mus/accelerators/accelerator_controller_registrar.cc
@@ -142,10 +142,8 @@ accelerator.modifiers()); pre_event_matcher->accelerator_phase = ui::mojom::AcceleratorPhase::PRE_TARGET; - DCHECK(accelerator.type() == ui::ET_KEY_PRESSED || - accelerator.type() == ui::ET_KEY_RELEASED); pre_event_matcher->type_matcher->type = - accelerator.type() == ui::ET_KEY_PRESSED + accelerator.key_state() == ui::Accelerator::KeyState::PRESSED ? ui::mojom::EventType::KEY_PRESSED : ui::mojom::EventType::KEY_RELEASED;
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc index 40e9b95..444dc70 100644 --- a/base/debug/activity_tracker.cc +++ b/base/debug/activity_tracker.cc
@@ -23,6 +23,7 @@ #include "base/process/process_handle.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "base/threading/platform_thread.h" namespace base { @@ -30,18 +31,13 @@ namespace { -// A number that identifies the memory as having been initialized. It's -// arbitrary but happens to be the first 4 bytes of SHA1(ThreadActivityTracker). -// A version number is added on so that major structure changes won't try to -// read an older version (since the cookie won't match). -const uint32_t kHeaderCookie = 0xC0029B24UL + 2; // v2 - // The minimum depth a stack should support. const int kMinStackDepth = 2; // The amount of memory set aside for holding arbitrary user data (key/value // pairs) globally or associated with ActivityData entries. const size_t kUserDataSize = 1 << 10; // 1 KiB +const size_t kProcessDataSize = 4 << 10; // 4 KiB const size_t kGlobalDataSize = 16 << 10; // 16 KiB const size_t kMaxUserDataNameLength = static_cast<size_t>(std::numeric_limits<uint8_t>::max()); @@ -49,6 +45,13 @@ // A constant used to indicate that module information is changing. const uint32_t kModuleInformationChanging = 0x80000000; +// The key used to record process information. +const char kProcessPhaseDataKey[] = "process-phase"; + +// An atomically incrementing number, used to check for recreations of objects +// in the same memory space. +StaticAtomicSequenceNumber g_next_id; + union ThreadRef { int64_t as_id; #if defined(OS_WIN) @@ -64,6 +67,33 @@ #endif }; +// Get the next non-zero identifier. It is only unique within a process. +uint32_t GetNextDataId() { + uint32_t id; + while ((id = g_next_id.GetNext()) == 0) + ; + return id; +} + +// Finds and reuses a specific allocation or creates a new one. +PersistentMemoryAllocator::Reference AllocateFrom( + PersistentMemoryAllocator* allocator, + uint32_t from_type, + size_t size, + uint32_t to_type) { + PersistentMemoryAllocator::Iterator iter(allocator); + PersistentMemoryAllocator::Reference ref; + while ((ref = iter.GetNextOfType(from_type)) != 0) { + DCHECK_LE(size, allocator->GetAllocSize(ref)); + // This can fail if a another thread has just taken it. It is assumed that + // the memory is cleared during the "free" operation. + if (allocator->ChangeType(ref, to_type, from_type, /*clear=*/false)) + return ref; + } + + return allocator->Allocate(size, to_type); +} + // Determines the previous aligned index. size_t RoundDownToAlignment(size_t index, size_t alignment) { return index & (0 - alignment); @@ -76,6 +106,36 @@ } // namespace +OwningProcess::OwningProcess() {} +OwningProcess::~OwningProcess() {} + +void OwningProcess::Release_Initialize() { + uint32_t old_id = data_id.load(std::memory_order_acquire); + DCHECK_EQ(0U, old_id); + process_id = GetCurrentProcId(); + create_stamp = Time::Now().ToInternalValue(); + data_id.store(GetNextDataId(), std::memory_order_release); +} + +void OwningProcess::SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp) { + DCHECK_NE(0U, data_id); + process_id = pid; + create_stamp = stamp; +} + +// static +bool OwningProcess::GetOwningProcessId(const void* memory, + ProcessId* out_id, + int64_t* out_stamp) { + const OwningProcess* info = reinterpret_cast<const OwningProcess*>(memory); + uint32_t id = info->data_id.load(std::memory_order_acquire); + if (id == 0) + return false; + + *out_id = static_cast<ProcessId>(info->process_id); + *out_stamp = info->create_stamp; + return id == info->data_id.load(std::memory_order_seq_cst); +} // It doesn't matter what is contained in this (though it will be all zeros) // as only the address of it is important. @@ -246,32 +306,31 @@ return ref_value_; } +// These are required because std::atomic is (currently) not a POD type and +// thus clang requires explicit out-of-line constructors and destructors even +// when they do nothing. ActivityUserData::ValueInfo::ValueInfo() {} ActivityUserData::ValueInfo::ValueInfo(ValueInfo&&) = default; ActivityUserData::ValueInfo::~ValueInfo() {} - -StaticAtomicSequenceNumber ActivityUserData::next_id_; +ActivityUserData::MemoryHeader::MemoryHeader() {} +ActivityUserData::MemoryHeader::~MemoryHeader() {} +ActivityUserData::FieldHeader::FieldHeader() {} +ActivityUserData::FieldHeader::~FieldHeader() {} ActivityUserData::ActivityUserData(void* memory, size_t size) : memory_(reinterpret_cast<char*>(memory)), available_(RoundDownToAlignment(size, kMemoryAlignment)), - id_(reinterpret_cast<std::atomic<uint32_t>*>(memory)) { + header_(reinterpret_cast<MemoryHeader*>(memory)) { // It's possible that no user data is being stored. if (!memory_) return; - DCHECK_LT(kMemoryAlignment, available_); - if (id_->load(std::memory_order_relaxed) == 0) { - // Generate a new ID and store it in the first 32-bit word of memory_. - // |id_| must be non-zero for non-sink instances. - uint32_t id; - while ((id = next_id_.GetNext()) == 0) - ; - id_->store(id, std::memory_order_relaxed); - DCHECK_NE(0U, id_->load(std::memory_order_relaxed)); - } - memory_ += kMemoryAlignment; - available_ -= kMemoryAlignment; + static_assert(0 == sizeof(MemoryHeader) % kMemoryAlignment, "invalid header"); + DCHECK_LT(sizeof(MemoryHeader), available_); + if (header_->owner.data_id.load(std::memory_order_acquire) == 0) + header_->owner.Release_Initialize(); + memory_ += sizeof(MemoryHeader); + available_ -= sizeof(MemoryHeader); // If there is already data present, load that. This allows the same class // to be used for analysis through snapshots. @@ -280,148 +339,6 @@ ActivityUserData::~ActivityUserData() {} -void ActivityUserData::Set(StringPiece name, - ValueType type, - const void* memory, - size_t size) { - DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length()); - size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1), - size); - - // It's possible that no user data is being stored. - if (!memory_) - return; - - // The storage of a name is limited so use that limit during lookup. - if (name.length() > kMaxUserDataNameLength) - name.set(name.data(), kMaxUserDataNameLength); - - ValueInfo* info; - auto existing = values_.find(name); - if (existing != values_.end()) { - info = &existing->second; - } else { - // The name size is limited to what can be held in a single byte but - // because there are not alignment constraints on strings, it's set tight - // against the header. Its extent (the reserved space, even if it's not - // all used) is calculated so that, when pressed against the header, the - // following field will be aligned properly. - size_t name_size = name.length(); - size_t name_extent = - RoundUpToAlignment(sizeof(Header) + name_size, kMemoryAlignment) - - sizeof(Header); - size_t value_extent = RoundUpToAlignment(size, kMemoryAlignment); - - // The "base size" is the size of the header and (padded) string key. Stop - // now if there's not room enough for even this. - size_t base_size = sizeof(Header) + name_extent; - if (base_size > available_) - return; - - // The "full size" is the size for storing the entire value. - size_t full_size = std::min(base_size + value_extent, available_); - - // If the value is actually a single byte, see if it can be stuffed at the - // end of the name extent rather than wasting kMemoryAlignment bytes. - if (size == 1 && name_extent > name_size) { - full_size = base_size; - --name_extent; - --base_size; - } - - // Truncate the stored size to the amount of available memory. Stop now if - // there's not any room for even part of the value. - if (size != 0) { - size = std::min(full_size - base_size, size); - if (size == 0) - return; - } - - // Allocate a chunk of memory. - Header* header = reinterpret_cast<Header*>(memory_); - memory_ += full_size; - available_ -= full_size; - - // Datafill the header and name records. Memory must be zeroed. The |type| - // is written last, atomically, to release all the other values. - DCHECK_EQ(END_OF_VALUES, header->type.load(std::memory_order_relaxed)); - DCHECK_EQ(0, header->value_size.load(std::memory_order_relaxed)); - header->name_size = static_cast<uint8_t>(name_size); - header->record_size = full_size; - char* name_memory = reinterpret_cast<char*>(header) + sizeof(Header); - void* value_memory = - reinterpret_cast<char*>(header) + sizeof(Header) + name_extent; - memcpy(name_memory, name.data(), name_size); - header->type.store(type, std::memory_order_release); - - // Create an entry in |values_| so that this field can be found and changed - // later on without having to allocate new entries. - StringPiece persistent_name(name_memory, name_size); - auto inserted = - values_.insert(std::make_pair(persistent_name, ValueInfo())); - DCHECK(inserted.second); // True if inserted, false if existed. - info = &inserted.first->second; - info->name = persistent_name; - info->memory = value_memory; - info->size_ptr = &header->value_size; - info->extent = full_size - sizeof(Header) - name_extent; - info->type = type; - } - - // Copy the value data to storage. The |size| is written last, atomically, to - // release the copied data. Until then, a parallel reader will just ignore - // records with a zero size. - DCHECK_EQ(type, info->type); - size = std::min(size, info->extent); - info->size_ptr->store(0, std::memory_order_seq_cst); - memcpy(info->memory, memory, size); - info->size_ptr->store(size, std::memory_order_release); -} - -void ActivityUserData::SetReference(StringPiece name, - ValueType type, - const void* memory, - size_t size) { - ReferenceRecord rec; - rec.address = reinterpret_cast<uintptr_t>(memory); - rec.size = size; - Set(name, type, &rec, sizeof(rec)); -} - -void ActivityUserData::ImportExistingData() const { - while (available_ > sizeof(Header)) { - Header* header = reinterpret_cast<Header*>(memory_); - ValueType type = - static_cast<ValueType>(header->type.load(std::memory_order_acquire)); - if (type == END_OF_VALUES) - return; - if (header->record_size > available_) - return; - - size_t value_offset = RoundUpToAlignment(sizeof(Header) + header->name_size, - kMemoryAlignment); - if (header->record_size == value_offset && - header->value_size.load(std::memory_order_relaxed) == 1) { - value_offset -= 1; - } - if (value_offset + header->value_size > header->record_size) - return; - - ValueInfo info; - info.name = StringPiece(memory_ + sizeof(Header), header->name_size); - info.type = type; - info.memory = memory_ + value_offset; - info.size_ptr = &header->value_size; - info.extent = header->record_size - value_offset; - - StringPiece key(info.name); - values_.insert(std::make_pair(key, std::move(info))); - - memory_ += header->record_size; - available_ -= header->record_size; - } -} - bool ActivityUserData::CreateSnapshot(Snapshot* output_snapshot) const { DCHECK(output_snapshot); DCHECK(output_snapshot->empty()); @@ -470,10 +387,167 @@ return true; } -const void* ActivityUserData::GetBaseAddress() { - // The |memory_| pointer advances as elements are written but the |id_| +const void* ActivityUserData::GetBaseAddress() const { + // The |memory_| pointer advances as elements are written but the |header_| // value is always at the start of the block so just return that. - return id_; + return header_; +} + +void ActivityUserData::SetOwningProcessIdForTesting(ProcessId pid, + int64_t stamp) { + if (!header_) + return; + header_->owner.SetOwningProcessIdForTesting(pid, stamp); +} + +// static +bool ActivityUserData::GetOwningProcessId(const void* memory, + ProcessId* out_id, + int64_t* out_stamp) { + const MemoryHeader* header = reinterpret_cast<const MemoryHeader*>(memory); + return OwningProcess::GetOwningProcessId(&header->owner, out_id, out_stamp); +} + +void ActivityUserData::Set(StringPiece name, + ValueType type, + const void* memory, + size_t size) { + DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length()); + size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1), + size); + + // It's possible that no user data is being stored. + if (!memory_) + return; + + // The storage of a name is limited so use that limit during lookup. + if (name.length() > kMaxUserDataNameLength) + name.set(name.data(), kMaxUserDataNameLength); + + ValueInfo* info; + auto existing = values_.find(name); + if (existing != values_.end()) { + info = &existing->second; + } else { + // The name size is limited to what can be held in a single byte but + // because there are not alignment constraints on strings, it's set tight + // against the header. Its extent (the reserved space, even if it's not + // all used) is calculated so that, when pressed against the header, the + // following field will be aligned properly. + size_t name_size = name.length(); + size_t name_extent = + RoundUpToAlignment(sizeof(FieldHeader) + name_size, kMemoryAlignment) - + sizeof(FieldHeader); + size_t value_extent = RoundUpToAlignment(size, kMemoryAlignment); + + // The "base size" is the size of the header and (padded) string key. Stop + // now if there's not room enough for even this. + size_t base_size = sizeof(FieldHeader) + name_extent; + if (base_size > available_) + return; + + // The "full size" is the size for storing the entire value. + size_t full_size = std::min(base_size + value_extent, available_); + + // If the value is actually a single byte, see if it can be stuffed at the + // end of the name extent rather than wasting kMemoryAlignment bytes. + if (size == 1 && name_extent > name_size) { + full_size = base_size; + --name_extent; + --base_size; + } + + // Truncate the stored size to the amount of available memory. Stop now if + // there's not any room for even part of the value. + if (size != 0) { + size = std::min(full_size - base_size, size); + if (size == 0) + return; + } + + // Allocate a chunk of memory. + FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_); + memory_ += full_size; + available_ -= full_size; + + // Datafill the header and name records. Memory must be zeroed. The |type| + // is written last, atomically, to release all the other values. + DCHECK_EQ(END_OF_VALUES, header->type.load(std::memory_order_relaxed)); + DCHECK_EQ(0, header->value_size.load(std::memory_order_relaxed)); + header->name_size = static_cast<uint8_t>(name_size); + header->record_size = full_size; + char* name_memory = reinterpret_cast<char*>(header) + sizeof(FieldHeader); + void* value_memory = + reinterpret_cast<char*>(header) + sizeof(FieldHeader) + name_extent; + memcpy(name_memory, name.data(), name_size); + header->type.store(type, std::memory_order_release); + + // Create an entry in |values_| so that this field can be found and changed + // later on without having to allocate new entries. + StringPiece persistent_name(name_memory, name_size); + auto inserted = + values_.insert(std::make_pair(persistent_name, ValueInfo())); + DCHECK(inserted.second); // True if inserted, false if existed. + info = &inserted.first->second; + info->name = persistent_name; + info->memory = value_memory; + info->size_ptr = &header->value_size; + info->extent = full_size - sizeof(FieldHeader) - name_extent; + info->type = type; + } + + // Copy the value data to storage. The |size| is written last, atomically, to + // release the copied data. Until then, a parallel reader will just ignore + // records with a zero size. + DCHECK_EQ(type, info->type); + size = std::min(size, info->extent); + info->size_ptr->store(0, std::memory_order_seq_cst); + memcpy(info->memory, memory, size); + info->size_ptr->store(size, std::memory_order_release); +} + +void ActivityUserData::SetReference(StringPiece name, + ValueType type, + const void* memory, + size_t size) { + ReferenceRecord rec; + rec.address = reinterpret_cast<uintptr_t>(memory); + rec.size = size; + Set(name, type, &rec, sizeof(rec)); +} + +void ActivityUserData::ImportExistingData() const { + while (available_ > sizeof(FieldHeader)) { + FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_); + ValueType type = + static_cast<ValueType>(header->type.load(std::memory_order_acquire)); + if (type == END_OF_VALUES) + return; + if (header->record_size > available_) + return; + + size_t value_offset = RoundUpToAlignment( + sizeof(FieldHeader) + header->name_size, kMemoryAlignment); + if (header->record_size == value_offset && + header->value_size.load(std::memory_order_relaxed) == 1) { + value_offset -= 1; + } + if (value_offset + header->value_size > header->record_size) + return; + + ValueInfo info; + info.name = StringPiece(memory_ + sizeof(FieldHeader), header->name_size); + info.type = type; + info.memory = memory_ + value_offset; + info.size_ptr = &header->value_size; + info.extent = header->record_size - value_offset; + + StringPiece key(info.name); + values_.insert(std::make_pair(key, std::move(info))); + + memory_ += header->record_size; + available_ -= header->record_size; + } } // This information is kept for every thread that is tracked. It is filled @@ -485,27 +559,15 @@ GlobalActivityTracker::kTypeIdActivityTracker; // Expected size for 32/64-bit check. - static constexpr size_t kExpectedInstanceSize = 80; + static constexpr size_t kExpectedInstanceSize = + OwningProcess::kExpectedInstanceSize + 72; - // This unique number indicates a valid initialization of the memory. - std::atomic<uint32_t> cookie; + // This information uniquely identifies a process. + OwningProcess owner; - // The number of Activity slots (spaces that can hold an Activity) that - // immediately follow this structure in memory. - uint32_t stack_slots; - - // The process-id and thread-id (thread_ref.as_id) to which this data belongs. - // These identifiers are not guaranteed to mean anything but are unique, in - // combination, among all active trackers. It would be nice to always have - // the process_id be a 64-bit value but the necessity of having it atomic - // (for the memory barriers it provides) limits it to the natural word size - // of the machine. -#ifdef ARCH_CPU_64_BITS - std::atomic<int64_t> process_id; -#else - std::atomic<int32_t> process_id; - int32_t process_id_padding; -#endif + // The thread-id (thread_ref.as_id) to which this data belongs. This number + // is not guaranteed to mean anything but combined with the process-id from + // OwningProcess is unique among all active trackers. ThreadRef thread_ref; // The start-time and start-ticks when the data was created. Each activity @@ -514,6 +576,13 @@ int64_t start_time; int64_t start_ticks; + // The number of Activity slots (spaces that can hold an Activity) that + // immediately follow this structure in memory. + uint32_t stack_slots; + + // Some padding to keep everything 64-bit aligned. + uint32_t padding; + // The current depth of the stack. This may be greater than the number of // slots. If the depth exceeds the number of slots, the newest entries // won't be recorded. @@ -596,9 +665,10 @@ "ActivityData.data is not 64-bit aligned"); // Provided memory should either be completely initialized or all zeros. - if (header_->cookie.load(std::memory_order_relaxed) == 0) { + if (header_->owner.data_id.load(std::memory_order_relaxed) == 0) { // This is a new file. Double-check other fields and then initialize. - DCHECK_EQ(0, header_->process_id.load(std::memory_order_relaxed)); + DCHECK_EQ(0, header_->owner.process_id); + DCHECK_EQ(0, header_->owner.create_stamp); DCHECK_EQ(0, header_->thread_ref.as_id); DCHECK_EQ(0, header_->start_time); DCHECK_EQ(0, header_->start_ticks); @@ -616,7 +686,6 @@ header_->thread_ref.as_handle = PlatformThread::CurrentHandle().platform_handle(); #endif - header_->process_id.store(GetCurrentProcId(), std::memory_order_relaxed); header_->start_time = base::Time::Now().ToInternalValue(); header_->start_ticks = base::TimeTicks::Now().ToInternalValue(); @@ -626,7 +695,7 @@ // This is done last so as to guarantee that everything above is "released" // by the time this value gets written. - header_->cookie.store(kHeaderCookie, std::memory_order_release); + header_->owner.Release_Initialize(); valid_ = true; DCHECK(IsValid()); @@ -771,11 +840,9 @@ } bool ThreadActivityTracker::IsValid() const { - if (header_->cookie.load(std::memory_order_acquire) != kHeaderCookie || - header_->process_id.load(std::memory_order_relaxed) == 0 || - header_->thread_ref.as_id == 0 || - header_->start_time == 0 || - header_->start_ticks == 0 || + if (header_->owner.data_id.load(std::memory_order_acquire) == 0 || + header_->owner.process_id == 0 || header_->thread_ref.as_id == 0 || + header_->start_time == 0 || header_->start_ticks == 0 || header_->stack_slots != stack_slots_ || header_->thread_name[sizeof(header_->thread_name) - 1] != '\0') { return false; @@ -806,12 +873,12 @@ output_snapshot->activity_stack.reserve(stack_slots_); for (int attempt = 0; attempt < kMaxAttempts; ++attempt) { - // Remember the process and thread IDs to ensure they aren't replaced - // during the snapshot operation. Use "acquire" to ensure that all the - // non-atomic fields of the structure are valid (at least at the current - // moment in time). - const int64_t starting_process_id = - header_->process_id.load(std::memory_order_acquire); + // Remember the data IDs to ensure nothing is replaced during the snapshot + // operation. Use "acquire" so that all the non-atomic fields of the + // structure are valid (at least at the current moment in time). + const uint32_t starting_id = + header_->owner.data_id.load(std::memory_order_acquire); + const int64_t starting_process_id = header_->owner.process_id; const int64_t starting_thread_id = header_->thread_ref.as_id; // Write a non-zero value to |stack_unchanged| so it's possible to detect @@ -841,19 +908,11 @@ // TODO(bcwhite): Snapshot other things here. - // Get the general thread information. Loading of "process_id" is guaranteed - // to be last so that it's possible to detect below if any content has - // changed while reading it. It's technically possible for a thread to end, - // have its data cleared, a new thread get created with the same IDs, and - // it perform an action which starts tracking all in the time since the - // ID reads above but the chance is so unlikely that it's not worth the - // effort and complexity of protecting against it (perhaps with an - // "unchanged" field like is done for the stack). + // Get the general thread information. output_snapshot->thread_name = std::string(header_->thread_name, sizeof(header_->thread_name) - 1); output_snapshot->thread_id = header_->thread_ref.as_id; - output_snapshot->process_id = - header_->process_id.load(std::memory_order_seq_cst); + output_snapshot->process_id = header_->owner.process_id; // All characters of the thread-name buffer were copied so as to not break // if the trailing NUL were missing. Now limit the length if the actual @@ -861,9 +920,10 @@ output_snapshot->thread_name.resize( strlen(output_snapshot->thread_name.c_str())); - // If the process or thread ID has changed then the tracker has exited and - // the memory reused by a new one. Try again. - if (output_snapshot->process_id != starting_process_id || + // If the data ID has changed then the tracker has exited and the memory + // reused by a new one. Try again. + if (header_->owner.data_id.load(std::memory_order_seq_cst) != starting_id || + output_snapshot->process_id != starting_process_id || output_snapshot->thread_id != starting_thread_id) { continue; } @@ -892,6 +952,23 @@ return false; } +const void* ThreadActivityTracker::GetBaseAddress() { + return header_; +} + +void ThreadActivityTracker::SetOwningProcessIdForTesting(ProcessId pid, + int64_t stamp) { + header_->owner.SetOwningProcessIdForTesting(pid, stamp); +} + +// static +bool ThreadActivityTracker::GetOwningProcessId(const void* memory, + ProcessId* out_id, + int64_t* out_stamp) { + const Header* header = reinterpret_cast<const Header*>(memory); + return OwningProcess::GetOwningProcessId(&header->owner, out_id, out_stamp); +} + // static size_t ThreadActivityTracker::SizeForStackDepth(int stack_depth) { return static_cast<size_t>(stack_depth) * sizeof(Activity) + sizeof(Header); @@ -979,6 +1056,9 @@ pickle_size = pickler.size(); changes.store(0, std::memory_order_relaxed); + // Initialize the owner info. + owner.Release_Initialize(); + // Now set those fields that can change. return UpdateFrom(info); } @@ -1053,15 +1133,16 @@ return *user_data_; } -GlobalActivityTracker::GlobalUserData::GlobalUserData(void* memory, size_t size) +GlobalActivityTracker::ThreadSafeUserData::ThreadSafeUserData(void* memory, + size_t size) : ActivityUserData(memory, size) {} -GlobalActivityTracker::GlobalUserData::~GlobalUserData() {} +GlobalActivityTracker::ThreadSafeUserData::~ThreadSafeUserData() {} -void GlobalActivityTracker::GlobalUserData::Set(StringPiece name, - ValueType type, - const void* memory, - size_t size) { +void GlobalActivityTracker::ThreadSafeUserData::Set(StringPiece name, + ValueType type, + const void* memory, + size_t size) { AutoLock lock(data_lock_); ActivityUserData::Set(name, type, memory, size); } @@ -1186,6 +1267,174 @@ delete tracker; } +void GlobalActivityTracker::SetBackgroundTaskRunner( + const scoped_refptr<TaskRunner>& runner) { + AutoLock lock(global_tracker_lock_); + background_task_runner_ = runner; +} + +void GlobalActivityTracker::SetProcessExitCallback( + ProcessExitCallback callback) { + AutoLock lock(global_tracker_lock_); + process_exit_callback_ = callback; +} + +void GlobalActivityTracker::RecordProcessLaunch( + ProcessId process_id, + const FilePath::StringType& cmd) { + DCHECK_NE(GetCurrentProcId(), process_id); + + base::AutoLock lock(global_tracker_lock_); + if (base::ContainsKey(known_processes_, process_id)) { + // TODO(bcwhite): Measure this in UMA. + NOTREACHED() << "Process #" << process_id + << " was previously recorded as \"launched\"" + << " with no corresponding exit."; + known_processes_.erase(process_id); + } + +#if defined(OS_WIN) + known_processes_.insert(std::make_pair(process_id, UTF16ToUTF8(cmd))); +#else + known_processes_.insert(std::make_pair(process_id, cmd)); +#endif +} + +void GlobalActivityTracker::RecordProcessLaunch( + ProcessId process_id, + const FilePath::StringType& exe, + const FilePath::StringType& args) { + if (exe.find(FILE_PATH_LITERAL(" "))) { + RecordProcessLaunch(process_id, + FilePath::StringType(FILE_PATH_LITERAL("\"")) + exe + + FILE_PATH_LITERAL("\" ") + args); + } else { + RecordProcessLaunch(process_id, exe + FILE_PATH_LITERAL(' ') + args); + } +} + +void GlobalActivityTracker::RecordProcessExit(ProcessId process_id, + int exit_code) { + DCHECK_NE(GetCurrentProcId(), process_id); + + scoped_refptr<TaskRunner> task_runner; + std::string command_line; + { + base::AutoLock lock(global_tracker_lock_); + task_runner = background_task_runner_; + auto found = known_processes_.find(process_id); + if (found != known_processes_.end()) { + command_line = std::move(found->second); + known_processes_.erase(found); + } else { + DLOG(ERROR) << "Recording exit of unknown process #" << process_id; + } + } + + // Use the current time to differentiate the process that just exited + // from any that might be created in the future with the same ID. + int64_t now_stamp = Time::Now().ToInternalValue(); + + // The persistent allocator is thread-safe so run the iteration and + // adjustments on a worker thread if one was provided. + if (task_runner && !task_runner->RunsTasksOnCurrentThread()) { + task_runner->PostTask( + FROM_HERE, + Bind(&GlobalActivityTracker::CleanupAfterProcess, Unretained(this), + process_id, now_stamp, exit_code, Passed(&command_line))); + return; + } + + CleanupAfterProcess(process_id, now_stamp, exit_code, + std::move(command_line)); +} + +void GlobalActivityTracker::SetProcessPhase(ProcessPhase phase) { + process_data().SetInt(kProcessPhaseDataKey, phase); +} + +void GlobalActivityTracker::CleanupAfterProcess(ProcessId process_id, + int64_t exit_stamp, + int exit_code, + std::string&& command_line) { + // The process may not have exited cleanly so its necessary to go through + // all the data structures it may have allocated in the persistent memory + // segment and mark them as "released". This will allow them to be reused + // later on. + + PersistentMemoryAllocator::Iterator iter(allocator_.get()); + PersistentMemoryAllocator::Reference ref; + + ProcessExitCallback process_exit_callback; + { + AutoLock lock(global_tracker_lock_); + process_exit_callback = process_exit_callback_; + } + if (process_exit_callback) { + // Find the processes user-data record so the process phase can be passed + // to the callback. + ActivityUserData::Snapshot process_data_snapshot; + while ((ref = iter.GetNextOfType(kTypeIdProcessDataRecord)) != 0) { + const void* memory = allocator_->GetAsArray<char>( + ref, kTypeIdProcessDataRecord, PersistentMemoryAllocator::kSizeAny); + ProcessId found_id; + int64_t create_stamp; + if (ActivityUserData::GetOwningProcessId(memory, &found_id, + &create_stamp)) { + if (found_id == process_id && create_stamp < exit_stamp) { + const ActivityUserData process_data(const_cast<void*>(memory), + allocator_->GetAllocSize(ref)); + process_data.CreateSnapshot(&process_data_snapshot); + break; // No need to look for any others. + } + } + } + iter.Reset(); // So it starts anew when used below. + + // Record the process's phase at exit so callback doesn't need to go + // searching based on a private key value. + ProcessPhase exit_phase = PROCESS_PHASE_UNKNOWN; + auto phase = process_data_snapshot.find(kProcessPhaseDataKey); + if (phase != process_data_snapshot.end()) + exit_phase = static_cast<ProcessPhase>(phase->second.GetInt()); + + // Perform the callback. + process_exit_callback.Run(process_id, exit_stamp, exit_code, exit_phase, + std::move(command_line), + std::move(process_data_snapshot)); + } + + // Find all allocations associated with the exited process and free them. + uint32_t type; + while ((ref = iter.GetNext(&type)) != 0) { + switch (type) { + case kTypeIdActivityTracker: + case kTypeIdUserDataRecord: + case kTypeIdProcessDataRecord: + case ModuleInfoRecord::kPersistentTypeId: { + const void* memory = allocator_->GetAsArray<char>( + ref, type, PersistentMemoryAllocator::kSizeAny); + ProcessId found_id; + int64_t create_stamp; + + // By convention, the OwningProcess structure is always the first + // field of the structure so there's no need to handle all the + // cases separately. + if (OwningProcess::GetOwningProcessId(memory, &found_id, + &create_stamp)) { + // Only change the type to be "free" if the process ID matches and + // the creation time is before the exit time (so PID re-use doesn't + // cause the erasure of something that is in-use). Memory is cleared + // here, rather than when it's needed, so as to limit the impact at + // that critical time. + if (found_id == process_id && create_stamp < exit_stamp) + allocator_->ChangeType(ref, ~type, type, /*clear=*/true); + } + } break; + } + } +} + void GlobalActivityTracker::RecordLogMessage(StringPiece message) { // Allocate at least one extra byte so the string is NUL terminated. All // memory returned by the allocator is guaranteed to be zeroed. @@ -1249,12 +1498,20 @@ kTypeIdUserDataRecordFree, kUserDataSize, kCachedUserDataMemories, - /*make_iterable=*/false), + /*make_iterable=*/true), + process_data_(allocator_->GetAsArray<char>( + AllocateFrom(allocator_.get(), + kTypeIdProcessDataRecordFree, + kProcessDataSize, + kTypeIdProcessDataRecord), + kTypeIdProcessDataRecord, + kProcessDataSize), + kProcessDataSize), global_data_( allocator_->GetAsArray<char>( allocator_->Allocate(kGlobalDataSize, kTypeIdGlobalDataRecord), kTypeIdGlobalDataRecord, - PersistentMemoryAllocator::kSizeAny), + kGlobalDataSize), kGlobalDataSize) { // Ensure the passed memory is valid and empty (iterator finds nothing). uint32_t type; @@ -1264,10 +1521,15 @@ DCHECK(!g_tracker_); subtle::Release_Store(&g_tracker_, reinterpret_cast<uintptr_t>(this)); - // The global records must be iterable in order to be found by an analyzer. + // The data records must be iterable in order to be found by an analyzer. + allocator_->MakeIterable(allocator_->GetAsReference( + process_data_.GetBaseAddress(), kTypeIdProcessDataRecord)); allocator_->MakeIterable(allocator_->GetAsReference( global_data_.GetBaseAddress(), kTypeIdGlobalDataRecord)); + // Note that this process has launched. + SetProcessPhase(PROCESS_LAUNCHED); + // Fetch and record all activated field trials. FieldTrial::ActiveGroups active_groups; FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h index 719a318..922528f 100644 --- a/base/debug/activity_tracker.h +++ b/base/debug/activity_tracker.h
@@ -23,12 +23,15 @@ #include "base/atomicops.h" #include "base/base_export.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/location.h" #include "base/metrics/persistent_memory_allocator.h" +#include "base/process/process_handle.h" #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_runner.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_checker.h" #include "base/threading/thread_local_storage.h" @@ -41,7 +44,6 @@ class Lock; class PlatformThreadHandle; class Process; -class StaticAtomicSequenceNumber; class WaitableEvent; namespace debug { @@ -56,6 +58,39 @@ kActivityCallStackSize = 10, }; +// A class for keeping all information needed to verify that a structure is +// associated with a given process. +struct OwningProcess { + OwningProcess(); + ~OwningProcess(); + + // Initializes structure with the current process id and the current time. + // These can uniquely identify a process. A unique non-zero data_id will be + // set making it possible to tell using atomic reads if the data has changed. + void Release_Initialize(); + + // Explicitly sets the process ID. + void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); + + // Gets the associated process ID, in native form, and the creation timestamp + // from memory without loading the entire structure for analysis. This will + // return false if no valid process ID is available. + static bool GetOwningProcessId(const void* memory, + ProcessId* out_id, + int64_t* out_stamp); + + // SHA1(base::debug::OwningProcess): Increment this if structure changes! + static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1; + + // Expected size for 32/64-bit check by PersistentMemoryAllocator. + static constexpr size_t kExpectedInstanceSize = 24; + + std::atomic<uint32_t> data_id; + uint32_t padding; + int64_t process_id; + int64_t create_stamp; +}; + // The data associated with an activity is dependent upon the activity type. // This union defines all of the various fields. All fields must be explicitly // sized types to ensure no interoperability problems between 32-bit and @@ -293,7 +328,9 @@ // This class manages arbitrary user data that can be associated with activities // done by a thread by supporting key/value pairs of any type. This can provide // additional information during debugging. It is also used to store arbitrary -// global data. All updates must be done from the same thread. +// global data. All updates must be done from the same thread though other +// threads can read it concurrently if they create new objects using the same +// memory. class BASE_EXPORT ActivityUserData { public: // List of known value type. REFERENCE types must immediately follow the non- @@ -355,7 +392,7 @@ // contents have been overwritten by another thread. The return value is // always non-zero unless it's actually just a data "sink". uint32_t id() const { - return memory_ ? id_->load(std::memory_order_relaxed) : 0; + return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0; } // Writes a |value| (as part of a key/value pair) that will be included with @@ -409,7 +446,17 @@ bool CreateSnapshot(Snapshot* output_snapshot) const; // Gets the base memory address used for storing data. - const void* GetBaseAddress(); + const void* GetBaseAddress() const; + + // Explicitly sets the process ID. + void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); + + // Gets the associated process ID, in native form, and the creation timestamp + // from tracker memory without loading the entire structure for analysis. This + // will return false if no valid process ID is available. + static bool GetOwningProcessId(const void* memory, + ProcessId* out_id, + int64_t* out_stamp); protected: virtual void Set(StringPiece name, @@ -422,20 +469,31 @@ enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; - // A structure used to reference data held outside of persistent memory. - struct ReferenceRecord { - uint64_t address; - uint64_t size; + // A structure that defines the structure header in memory. + struct MemoryHeader { + MemoryHeader(); + ~MemoryHeader(); + + OwningProcess owner; // Information about the creating process. }; // Header to a key/value record held in persistent memory. - struct Header { + struct FieldHeader { + FieldHeader(); + ~FieldHeader(); + std::atomic<uint8_t> type; // Encoded ValueType uint8_t name_size; // Length of "name" key. std::atomic<uint16_t> value_size; // Actual size of of the stored value. uint16_t record_size; // Total storage of name, value, header. }; + // A structure used to reference data held outside of persistent memory. + struct ReferenceRecord { + uint64_t address; + uint64_t size; + }; + // This record is used to hold known value is a map so that they can be // found and overwritten later. struct ValueInfo { @@ -470,12 +528,8 @@ mutable char* memory_; mutable size_t available_; - // A pointer to the unique ID for this instance. - std::atomic<uint32_t>* const id_; - - // This ID is used to create unique indentifiers for user data so that it's - // possible to tell if the information has been overwritten. - static StaticAtomicSequenceNumber next_id_; + // A pointer to the memory header for this instance. + MemoryHeader* const header_; DISALLOW_COPY_AND_ASSIGN(ActivityUserData); }; @@ -618,6 +672,19 @@ // implementation does not support concurrent snapshot operations. bool CreateSnapshot(Snapshot* output_snapshot) const; + // Gets the base memory address used for storing data. + const void* GetBaseAddress(); + + // Explicitly sets the process ID. + void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); + + // Gets the associated process ID, in native form, and the creation timestamp + // from tracker memory without loading the entire structure for analysis. This + // will return false if no valid process ID is available. + static bool GetOwningProcessId(const void* memory, + ProcessId* out_id, + int64_t* out_stamp); + // Calculates the memory size required for a given stack depth, including // the internal header structure for the stack. static size_t SizeForStackDepth(int stack_depth); @@ -649,15 +716,45 @@ // will be safely ignored. These are public so that an external process // can recognize records of this type within an allocator. enum : uint32_t { - kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 - kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 + kTypeIdActivityTracker = 0x5D7381AF + 4, // SHA1(ActivityTracker) v4 + kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 - kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, + kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100, + kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 0x200, kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, + kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord, }; + // An enumeration of common process life stages. All entries are given an + // explicit number so they are known and remain constant; this allows for + // cross-version analysis either locally or on a server. + enum ProcessPhase : int { + // The phases are generic and may have meaning to the tracker. + PROCESS_PHASE_UNKNOWN = 0, + PROCESS_LAUNCHED = 1, + PROCESS_LAUNCH_FAILED = 2, + PROCESS_EXITED_CLEANLY = 10, + PROCESS_EXITED_WITH_CODE = 11, + + // Add here whatever is useful for analysis. + PROCESS_SHUTDOWN_STARTED = 100, + PROCESS_MAIN_LOOP_STARTED = 101, + }; + + // A callback made when a process exits to allow immediate analysis of its + // data. Note that the system may reuse the |process_id| so when fetching + // records it's important to ensure that what is returned was created before + // the |exit_stamp|. Movement of |process_data| information is allowed. + using ProcessExitCallback = + Callback<void(int64_t process_id, + int64_t exit_stamp, + int exit_code, + ProcessPhase exit_phase, + std::string&& command_line, + ActivityUserData::Snapshot&& process_data)>; + // This structure contains information about a loaded module, as shown to // users of the tracker. struct BASE_EXPORT ModuleInfo { @@ -789,6 +886,49 @@ // Releases the activity-tracker for the current thread (for testing only). void ReleaseTrackerForCurrentThreadForTesting(); + // Sets a task-runner that can be used for background work. + void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner); + + // Sets an optional callback to be called when a process exits. + void SetProcessExitCallback(ProcessExitCallback callback); + + // Manages process lifetimes. These are called by the process that launched + // and reaped the subprocess, not the subprocess itself. If it is expensive + // to generate the parameters, Get() the global tracker and call these + // conditionally rather than using the static versions. + void RecordProcessLaunch(ProcessId process_id, + const FilePath::StringType& cmd); + void RecordProcessLaunch(ProcessId process_id, + const FilePath::StringType& exe, + const FilePath::StringType& args); + void RecordProcessExit(ProcessId process_id, int exit_code); + static void RecordProcessLaunchIfEnabled(ProcessId process_id, + const FilePath::StringType& cmd) { + GlobalActivityTracker* tracker = Get(); + if (tracker) + tracker->RecordProcessLaunch(process_id, cmd); + } + static void RecordProcessLaunchIfEnabled(ProcessId process_id, + const FilePath::StringType& exe, + const FilePath::StringType& args) { + GlobalActivityTracker* tracker = Get(); + if (tracker) + tracker->RecordProcessLaunch(process_id, exe, args); + } + static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) { + GlobalActivityTracker* tracker = Get(); + if (tracker) + tracker->RecordProcessExit(process_id, exit_code); + } + // Sets the "phase" of the current process, useful for knowing what it was + // doing when it last reported. + void SetProcessPhase(ProcessPhase phase); + static void SetProcessPhaseIfEnabled(ProcessPhase phase) { + GlobalActivityTracker* tracker = Get(); + if (tracker) + tracker->SetProcessPhase(phase); + } + // Records a log message. The current implementation does NOT recycle these // only store critical messages such as FATAL ones. void RecordLogMessage(StringPiece message); @@ -818,7 +958,12 @@ tracker->RecordFieldTrial(trial_name, group_name); } + // Accesses the process data record for storing arbitrary key/value pairs. + // Updates to this are thread-safe. + ActivityUserData& process_data() { return process_data_; } + // Accesses the global data record for storing arbitrary key/value pairs. + // Updates to this are thread-safe. ActivityUserData& global_data() { return global_data_; } private: @@ -837,10 +982,10 @@ // A wrapper around ActivityUserData that is thread-safe and thus can be used // in the global scope without the requirement of being called from only one // thread. - class GlobalUserData : public ActivityUserData { + class ThreadSafeUserData : public ActivityUserData { public: - GlobalUserData(void* memory, size_t size); - ~GlobalUserData() override; + ThreadSafeUserData(void* memory, size_t size); + ~ThreadSafeUserData() override; private: void Set(StringPiece name, @@ -850,7 +995,7 @@ Lock data_lock_; - DISALLOW_COPY_AND_ASSIGN(GlobalUserData); + DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData); }; // State of a module as stored in persistent memory. This supports a single @@ -862,7 +1007,8 @@ static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; // Expected size for 32/64-bit check by PersistentMemoryAllocator. - static constexpr size_t kExpectedInstanceSize = 56; + static constexpr size_t kExpectedInstanceSize = + OwningProcess::kExpectedInstanceSize + 56; // The atomic unfortunately makes this a "complex" class on some compilers // and thus requires an out-of-line constructor & destructor even though @@ -870,6 +1016,7 @@ ModuleInfoRecord(); ~ModuleInfoRecord(); + OwningProcess owner; // The process that created this record. uint64_t address; // The base address of the module. uint64_t load_time; // Time of last load/unload. uint64_t size; // The size of the module in bytes. @@ -933,6 +1080,12 @@ // be tracked. |value| is a pointer to a ManagedActivityTracker. static void OnTLSDestroy(void* value); + // Does process-exit work. This can be run on any thread. + void CleanupAfterProcess(ProcessId process_id, + int64_t exit_stamp, + int exit_code, + std::string&& command_line); + // The persistent-memory allocator from which the memory for all trackers // is taken. std::unique_ptr<PersistentMemoryAllocator> allocator_; @@ -955,9 +1108,9 @@ ActivityTrackerMemoryAllocator user_data_allocator_; base::Lock user_data_allocator_lock_; - // An object for holding global arbitrary key value pairs. Values must always - // be written from the main UI thread. - GlobalUserData global_data_; + // An object for holding arbitrary key value pairs with thread-safe access. + ThreadSafeUserData process_data_; + ThreadSafeUserData global_data_; // A map of global module information, keyed by module path. std::map<const std::string, ModuleInfoRecord*> modules_; @@ -966,6 +1119,21 @@ // The active global activity tracker. static subtle::AtomicWord g_tracker_; + // A lock that is used to protect access to the following fields. + base::Lock global_tracker_lock_; + + // The collection of processes being tracked and their command-lines. + std::map<int64_t, std::string> known_processes_; + + // A task-runner that can be used for doing background processing. + scoped_refptr<TaskRunner> background_task_runner_; + + // A callback performed when a subprocess exits, including its exit-code + // and the phase it was in when that occurred. This will be called via + // the |background_task_runner_| if one is set or whatever thread reaped + // the process otherwise. + ProcessExitCallback process_exit_callback_; + DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); };
diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc index aced4fb3..e9934d1 100644 --- a/base/debug/activity_tracker_unittest.cc +++ b/base/debug/activity_tracker_unittest.cc
@@ -84,45 +84,73 @@ return GlobalActivityTracker::Get()->user_data_allocator_.cache_used(); } + void HandleProcessExit(int64_t id, + int64_t stamp, + int code, + GlobalActivityTracker::ProcessPhase phase, + std::string&& command, + ActivityUserData::Snapshot&& data) { + exit_id = id; + exit_stamp = stamp; + exit_code = code; + exit_phase = phase; + exit_command = std::move(command); + exit_data = std::move(data); + } + static void DoNothing() {} + + int64_t exit_id = 0; + int64_t exit_stamp; + int exit_code; + GlobalActivityTracker::ProcessPhase exit_phase; + std::string exit_command; + ActivityUserData::Snapshot exit_data; }; TEST_F(ActivityTrackerTest, UserDataTest) { char buffer[256]; memset(buffer, 0, sizeof(buffer)); ActivityUserData data(buffer, sizeof(buffer)); - const size_t space = sizeof(buffer) - 8; + size_t space = sizeof(buffer) - sizeof(ActivityUserData::MemoryHeader); ASSERT_EQ(space, data.available_); data.SetInt("foo", 1); - ASSERT_EQ(space - 24, data.available_); + space -= 24; + ASSERT_EQ(space, data.available_); data.SetUint("b", 1U); // Small names fit beside header in a word. - ASSERT_EQ(space - 24 - 16, data.available_); + space -= 16; + ASSERT_EQ(space, data.available_); data.Set("c", buffer, 10); - ASSERT_EQ(space - 24 - 16 - 24, data.available_); + space -= 24; + ASSERT_EQ(space, data.available_); data.SetString("dear john", "it's been fun"); - ASSERT_EQ(space - 24 - 16 - 24 - 32, data.available_); + space -= 32; + ASSERT_EQ(space, data.available_); data.Set("c", buffer, 20); - ASSERT_EQ(space - 24 - 16 - 24 - 32, data.available_); + ASSERT_EQ(space, data.available_); data.SetString("dear john", "but we're done together"); - ASSERT_EQ(space - 24 - 16 - 24 - 32, data.available_); + ASSERT_EQ(space, data.available_); data.SetString("dear john", "bye"); - ASSERT_EQ(space - 24 - 16 - 24 - 32, data.available_); + ASSERT_EQ(space, data.available_); data.SetChar("d", 'x'); - ASSERT_EQ(space - 24 - 16 - 24 - 32 - 8, data.available_); + space -= 8; + ASSERT_EQ(space, data.available_); data.SetBool("ee", true); - ASSERT_EQ(space - 24 - 16 - 24 - 32 - 8 - 16, data.available_); + space -= 16; + ASSERT_EQ(space, data.available_); data.SetString("f", ""); - ASSERT_EQ(space - 24 - 16 - 24 - 32 - 8 - 16 - 8, data.available_); + space -= 8; + ASSERT_EQ(space, data.available_); } TEST_F(ActivityTrackerTest, PushPopTest) { @@ -250,6 +278,16 @@ // GlobalActivityTracker tests below. +TEST_F(ActivityTrackerTest, BasicTest) { + GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); + GlobalActivityTracker* global = GlobalActivityTracker::Get(); + + // Ensure the data repositories have backing store, indicated by non-zero ID. + EXPECT_NE(0U, global->process_data().id()); + EXPECT_NE(0U, global->global_data().id()); + EXPECT_NE(global->process_data().id(), global->global_data().id()); +} + class SimpleActivityThread : public SimpleThread { public: SimpleActivityThread(const std::string& name, @@ -336,5 +374,107 @@ EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); } +TEST_F(ActivityTrackerTest, ProcessDeathTest) { + // This doesn't actually create and destroy a process. Instead, it uses for- + // testing interfaces to simulate data created by other processes. + const ProcessId other_process_id = GetCurrentProcId() + 1; + + GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); + GlobalActivityTracker* global = GlobalActivityTracker::Get(); + ThreadActivityTracker* thread = global->GetOrCreateTrackerForCurrentThread(); + + // Get callbacks for process exit. + global->SetProcessExitCallback( + Bind(&ActivityTrackerTest::HandleProcessExit, Unretained(this))); + + // Pretend than another process has started. + global->RecordProcessLaunch(other_process_id, FILE_PATH_LITERAL("foo --bar")); + + // Do some activities. + PendingTask task(FROM_HERE, base::Bind(&DoNothing)); + ScopedTaskRunActivity activity(task); + ActivityUserData& user_data = activity.user_data(); + ASSERT_NE(0U, user_data.id()); + + // Get the memory-allocator references to that data. + PersistentMemoryAllocator::Reference proc_data_ref = + global->allocator()->GetAsReference( + global->process_data().GetBaseAddress(), + GlobalActivityTracker::kTypeIdProcessDataRecord); + ASSERT_TRUE(proc_data_ref); + PersistentMemoryAllocator::Reference tracker_ref = + global->allocator()->GetAsReference( + thread->GetBaseAddress(), + GlobalActivityTracker::kTypeIdActivityTracker); + ASSERT_TRUE(tracker_ref); + PersistentMemoryAllocator::Reference user_data_ref = + global->allocator()->GetAsReference( + user_data.GetBaseAddress(), + GlobalActivityTracker::kTypeIdUserDataRecord); + ASSERT_TRUE(user_data_ref); + + // Make a copy of the thread-tracker state so it can be restored later. + const size_t tracker_size = global->allocator()->GetAllocSize(tracker_ref); + std::unique_ptr<char[]> tracker_copy(new char[tracker_size]); + memcpy(tracker_copy.get(), thread->GetBaseAddress(), tracker_size); + + // Change the objects to appear to be owned by another process. + ProcessId owning_id; + int64_t stamp; + ASSERT_TRUE(ActivityUserData::GetOwningProcessId( + global->process_data().GetBaseAddress(), &owning_id, &stamp)); + EXPECT_NE(other_process_id, owning_id); + ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId( + thread->GetBaseAddress(), &owning_id, &stamp)); + EXPECT_NE(other_process_id, owning_id); + ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(), + &owning_id, &stamp)); + EXPECT_NE(other_process_id, owning_id); + global->process_data().SetOwningProcessIdForTesting(other_process_id, stamp); + thread->SetOwningProcessIdForTesting(other_process_id, stamp); + user_data.SetOwningProcessIdForTesting(other_process_id, stamp); + ASSERT_TRUE(ActivityUserData::GetOwningProcessId( + global->process_data().GetBaseAddress(), &owning_id, &stamp)); + EXPECT_EQ(other_process_id, owning_id); + ASSERT_TRUE(ThreadActivityTracker::GetOwningProcessId( + thread->GetBaseAddress(), &owning_id, &stamp)); + EXPECT_EQ(other_process_id, owning_id); + ASSERT_TRUE(ActivityUserData::GetOwningProcessId(user_data.GetBaseAddress(), + &owning_id, &stamp)); + EXPECT_EQ(other_process_id, owning_id); + + // Check that process exit will perform callback and free the allocations. + ASSERT_EQ(0, exit_id); + ASSERT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecord, + global->allocator()->GetType(proc_data_ref)); + ASSERT_EQ(GlobalActivityTracker::kTypeIdActivityTracker, + global->allocator()->GetType(tracker_ref)); + ASSERT_EQ(GlobalActivityTracker::kTypeIdUserDataRecord, + global->allocator()->GetType(user_data_ref)); + global->RecordProcessExit(other_process_id, 0); + EXPECT_EQ(other_process_id, exit_id); + EXPECT_EQ("foo --bar", exit_command); + EXPECT_EQ(GlobalActivityTracker::kTypeIdProcessDataRecordFree, + global->allocator()->GetType(proc_data_ref)); + EXPECT_EQ(GlobalActivityTracker::kTypeIdActivityTrackerFree, + global->allocator()->GetType(tracker_ref)); + EXPECT_EQ(GlobalActivityTracker::kTypeIdUserDataRecordFree, + global->allocator()->GetType(user_data_ref)); + + // Restore memory contents and types so things don't crash when doing real + // process clean-up. + memcpy(const_cast<void*>(thread->GetBaseAddress()), tracker_copy.get(), + tracker_size); + global->allocator()->ChangeType( + proc_data_ref, GlobalActivityTracker::kTypeIdProcessDataRecord, + GlobalActivityTracker::kTypeIdUserDataRecordFree, false); + global->allocator()->ChangeType( + tracker_ref, GlobalActivityTracker::kTypeIdActivityTracker, + GlobalActivityTracker::kTypeIdActivityTrackerFree, false); + global->allocator()->ChangeType( + user_data_ref, GlobalActivityTracker::kTypeIdUserDataRecord, + GlobalActivityTracker::kTypeIdUserDataRecordFree, false); +} + } // namespace debug } // namespace base
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc index 939174e..a0e3871 100644 --- a/base/metrics/persistent_histogram_allocator.cc +++ b/base/metrics/persistent_histogram_allocator.cc
@@ -905,6 +905,8 @@ } void GlobalHistogramAllocator::DeletePersistentLocation() { + memory_allocator()->SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED); + #if defined(OS_NACL) NOTREACHED(); #else
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc index f70b3969..d381d87 100644 --- a/base/metrics/persistent_memory_allocator.cc +++ b/base/metrics/persistent_memory_allocator.cc
@@ -18,6 +18,7 @@ #include "base/memory/shared_memory.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" +#include "base/threading/thread_restrictions.h" namespace { @@ -32,7 +33,7 @@ // The current version of the metadata. If updates are made that change // the metadata, the version number can be queried to operate in a backward- // compatible manner until the memory segment is completely re-initalized. -const uint32_t kGlobalVersion = 1; +const uint32_t kGlobalVersion = 2; // Constant values placed in the block headers to indicate its state. const uint32_t kBlockCookieFree = 0; @@ -43,7 +44,7 @@ // TODO(bcwhite): When acceptable, consider moving flags to std::atomic<char> // types rather than combined bitfield. -// Flags stored in the flags_ field of the SharedMetaData structure below. +// Flags stored in the flags_ field of the SharedMetadata structure below. enum : int { kFlagCorrupt = 1 << 0, kFlagFull = 1 << 1 @@ -100,7 +101,9 @@ }; // The shared metadata exists once at the top of the memory segment to -// describe the state of the allocator to all processes. +// describe the state of the allocator to all processes. The size of this +// structure must be a multiple of 64-bits to ensure compatibility between +// architectures. struct PersistentMemoryAllocator::SharedMetadata { uint32_t cookie; // Some value that indicates complete initialization. uint32_t size; // Total size of memory segment. @@ -108,10 +111,15 @@ uint32_t version; // Version code so upgrades don't break. uint64_t id; // Arbitrary ID number given by creator. uint32_t name; // Reference to stored name string. + uint32_t padding1; // Pad-out read-only data to 64-bit alignment. // Above is read-only after first construction. Below may be changed and // so must be marked "volatile" to provide correct inter-process behavior. + // State of the memory, plus some padding to keep alignment. + volatile std::atomic<uint8_t> memory_state; // MemoryState enum values. + uint8_t padding2[3]; + // Bitfield of information flags. Access to this should be done through // the CheckFlag() and SetFlag() methods defined above. volatile std::atomic<uint32_t> flags; @@ -121,6 +129,7 @@ // The "iterable" queue is an M&S Queue as described here, append-only: // https://www.research.ibm.com/people/m/michael/podc-1996.pdf + // |queue| needs to be 64-bit aligned and is itself a multiple of 64 bits. volatile std::atomic<uint32_t> tailptr; // Last block of iteration queue. volatile BlockHeader queue; // Empty block for linked-list head/tail. }; @@ -312,7 +321,7 @@ // definitions and so cannot be moved to the global scope. static_assert(sizeof(PersistentMemoryAllocator::BlockHeader) == 16, "struct is not portable across different natural word widths"); - static_assert(sizeof(PersistentMemoryAllocator::SharedMetadata) == 56, + static_assert(sizeof(PersistentMemoryAllocator::SharedMetadata) == 64, "struct is not portable across different natural word widths"); static_assert(sizeof(BlockHeader) % kAllocAlignment == 0, @@ -384,12 +393,13 @@ if (name_cstr) memcpy(name_cstr, name.data(), name.length()); } + + shared_meta()->memory_state.store(MEMORY_INITIALIZED, + std::memory_order_release); } else { - if (shared_meta()->size == 0 || - shared_meta()->version == 0 || + if (shared_meta()->size == 0 || shared_meta()->version != kGlobalVersion || shared_meta()->freeptr.load(std::memory_order_relaxed) == 0 || - shared_meta()->tailptr == 0 || - shared_meta()->queue.cookie == 0 || + shared_meta()->tailptr == 0 || shared_meta()->queue.cookie == 0 || shared_meta()->queue.next.load(std::memory_order_relaxed) == 0) { SetCorrupt(); } @@ -470,6 +480,19 @@ HistogramBase::kUmaTargetedHistogramFlag); } +void PersistentMemoryAllocator::Flush(bool sync) { + FlushPartial(used(), sync); +} + +void PersistentMemoryAllocator::SetMemoryState(uint8_t memory_state) { + shared_meta()->memory_state.store(memory_state, std::memory_order_relaxed); + FlushPartial(sizeof(SharedMetadata), false); +} + +uint8_t PersistentMemoryAllocator::GetMemoryState() const { + return shared_meta()->memory_state.load(std::memory_order_relaxed); +} + size_t PersistentMemoryAllocator::used() const { return std::min(shared_meta()->freeptr.load(std::memory_order_relaxed), mem_size_); @@ -816,8 +839,12 @@ PersistentMemoryAllocator::GetBlock(Reference ref, uint32_t type_id, uint32_t size, bool queue_ok, bool free_ok) const { + // Handle special cases. + if (ref == kReferenceQueue && queue_ok) + return reinterpret_cast<const volatile BlockHeader*>(mem_base_ + ref); + // Validation of parameters. - if (ref < (queue_ok ? kReferenceQueue : sizeof(SharedMetadata))) + if (ref < sizeof(SharedMetadata)) return nullptr; if (ref % kAllocAlignment != 0) return nullptr; @@ -827,17 +854,13 @@ // Validation of referenced block-header. if (!free_ok) { - uint32_t freeptr = std::min( - shared_meta()->freeptr.load(std::memory_order_relaxed), mem_size_); - if (ref + size > freeptr) - return nullptr; const volatile BlockHeader* const block = reinterpret_cast<volatile BlockHeader*>(mem_base_ + ref); + if (block->cookie != kBlockCookieAllocated) + return nullptr; if (block->size < size) return nullptr; - if (ref + block->size > freeptr) - return nullptr; - if (ref != kReferenceQueue && block->cookie != kBlockCookieAllocated) + if (ref + block->size > mem_size_) return nullptr; if (type_id != 0 && block->type_id.load(std::memory_order_relaxed) != type_id) { @@ -849,6 +872,13 @@ return reinterpret_cast<const volatile BlockHeader*>(mem_base_ + ref); } +void PersistentMemoryAllocator::FlushPartial(size_t length, bool sync) { + // Generally there is nothing to do as every write is done through volatile + // memory with atomic instructions to guarantee consistency. This (virtual) + // method exists so that derivced classes can do special things, such as + // tell the OS to write changes to disk now rather than when convenient. +} + void PersistentMemoryAllocator::RecordError(int error) const { if (errors_histogram_) errors_histogram_->Add(error); @@ -989,7 +1019,12 @@ id, name, read_only), - mapped_file_(std::move(file)) {} + mapped_file_(std::move(file)) { + // Ensure the disk-copy of the data reflects the fully-initialized memory as + // there is no guarantee as to what order the pages might be auto-flushed by + // the OS in the future. + Flush(true); +} FilePersistentMemoryAllocator::~FilePersistentMemoryAllocator() {} @@ -999,6 +1034,33 @@ bool read_only) { return IsMemoryAcceptable(file.data(), file.length(), 0, read_only); } + +void FilePersistentMemoryAllocator::FlushPartial(size_t length, bool sync) { + if (sync) + ThreadRestrictions::AssertIOAllowed(); + if (IsReadonly()) + return; + +#if defined(OS_WIN) + // Windows doesn't support a synchronous flush. + BOOL success = ::FlushViewOfFile(data(), length); + DPCHECK(success); +#elif defined(OS_MACOSX) + // On OSX, "invalidate" removes all cached pages, forcing a re-read from + // disk. That's not applicable to "flush" so omit it. + int result = + ::msync(const_cast<void*>(data()), length, sync ? MS_SYNC : MS_ASYNC); + DCHECK_NE(EINVAL, result); +#elif defined(OS_POSIX) + // On POSIX, "invalidate" forces _other_ processes to recognize what has + // been written to disk and so is applicable to "flush". + int result = ::msync(const_cast<void*>(data()), length, + MS_INVALIDATE | (sync ? MS_SYNC : MS_ASYNC)); + DCHECK_NE(EINVAL, result); +#else +#error Unsupported OS. +#endif +} #endif // !defined(OS_NACL) } // namespace base
diff --git a/base/metrics/persistent_memory_allocator.h b/base/metrics/persistent_memory_allocator.h index b38f284..94a7744b 100644 --- a/base/metrics/persistent_memory_allocator.h +++ b/base/metrics/persistent_memory_allocator.h
@@ -96,6 +96,29 @@ public: typedef uint32_t Reference; + // These states are used to indicate the overall condition of the memory + // segment irrespective of what is stored within it. Because the data is + // often persistent and thus needs to be readable by different versions of + // a program, these values are fixed and can never change. + enum MemoryState : uint8_t { + // Persistent memory starts all zeros and so shows "uninitialized". + MEMORY_UNINITIALIZED = 0, + + // The header has been written and the memory is ready for use. + MEMORY_INITIALIZED = 1, + + // The data should be considered deleted. This would be set when the + // allocator is being cleaned up. If file-backed, the file is likely + // to be deleted but since deletion can fail for a variety of reasons, + // having this extra status means a future reader can realize what + // should have happened. + MEMORY_DELETED = 2, + + // Outside code can create states starting with this number; these too + // must also never change between code versions. + MEMORY_USER_DEFINED = 100, + }; + // Iterator for going through all iterable memory records in an allocator. // Like the allocator itself, iterators are lock-free and thread-secure. // That means that multiple threads can share an iterator and the same @@ -280,7 +303,11 @@ const char* Name() const; // Is this segment open only for read? - bool IsReadonly() { return readonly_; } + bool IsReadonly() const { return readonly_; } + + // Manage the saved state of the memory. + void SetMemoryState(uint8_t memory_state); + uint8_t GetMemoryState() const; // Create internal histograms for tracking memory use and allocation sizes // for allocator of |name| (which can simply be the result of Name()). This @@ -293,6 +320,17 @@ // UMA.PersistentAllocator.name.UsedPct void CreateTrackingHistograms(base::StringPiece name); + // Flushes the persistent memory to any backing store. This typically does + // nothing but is used by the FilePersistentMemoryAllocator to inform the + // OS that all the data should be sent to the disk immediately. This is + // useful in the rare case where something has just been stored that needs + // to survive a hard shutdown of the machine like from a power failure. + // The |sync| parameter indicates if this call should block until the flush + // is complete but is only advisory and may or may not have an effect + // depending on the capabilities of the OS. Synchronous flushes are allowed + // only from theads that are allowed to do I/O. + void Flush(bool sync); + // Direct access to underlying memory segment. If the segment is shared // across threads or processes, reading data through these values does // not guarantee consistency. Use with care. Do not write. @@ -580,6 +618,9 @@ uint64_t id, base::StringPiece name, bool readonly); + // Implementation of Flush that accepts how much to flush. + virtual void FlushPartial(size_t length, bool sync); + volatile char* const mem_base_; // Memory base. (char so sizeof guaranteed 1) const MemoryType mem_type_; // Type of memory allocation. const uint32_t mem_size_; // Size of entire memory segment. @@ -715,6 +756,10 @@ // the rest. static bool IsFileAcceptable(const MemoryMappedFile& file, bool read_only); + protected: + // PersistentMemoryAllocator: + void FlushPartial(size_t length, bool sync) override; + private: std::unique_ptr<MemoryMappedFile> mapped_file_;
diff --git a/base/metrics/persistent_memory_allocator_unittest.cc b/base/metrics/persistent_memory_allocator_unittest.cc index d12e00f..c3027ec 100644 --- a/base/metrics/persistent_memory_allocator_unittest.cc +++ b/base/metrics/persistent_memory_allocator_unittest.cc
@@ -100,6 +100,8 @@ EXPECT_TRUE(allocator_->used_histogram_); EXPECT_EQ("UMA.PersistentAllocator." + base_name + ".UsedPct", allocator_->used_histogram_->histogram_name()); + EXPECT_EQ(PersistentMemoryAllocator::MEMORY_INITIALIZED, + allocator_->GetMemoryState()); // Get base memory info for later comparison. PersistentMemoryAllocator::MemoryInfo meminfo0; @@ -254,6 +256,11 @@ allocator_->Delete(obj2); PersistentMemoryAllocator::Iterator iter1z(allocator_.get()); EXPECT_EQ(nullptr, iter1z.GetNextOfObject<TestObject2>()); + + // Ensure that the memory state can be set. + allocator_->SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED); + EXPECT_EQ(PersistentMemoryAllocator::MEMORY_DELETED, + allocator_->GetMemoryState()); } TEST_F(PersistentMemoryAllocatorTest, PageTest) { @@ -691,8 +698,8 @@ const size_t mmlength = mmfile->length(); EXPECT_GE(meminfo1.total, mmlength); - FilePersistentMemoryAllocator file(std::move(mmfile), 0, 0, "", true); - EXPECT_TRUE(file.IsReadonly()); + FilePersistentMemoryAllocator file(std::move(mmfile), 0, 0, "", false); + EXPECT_FALSE(file.IsReadonly()); EXPECT_EQ(TEST_ID, file.Id()); EXPECT_FALSE(file.IsFull()); EXPECT_FALSE(file.IsCorrupt()); @@ -713,6 +720,11 @@ EXPECT_GE(meminfo1.free, meminfo2.free); EXPECT_EQ(mmlength, meminfo2.total); EXPECT_EQ(0U, meminfo2.free); + + // There's no way of knowing if Flush actually does anything but at least + // verify that it runs without CHECK violations. + file.Flush(false); + file.Flush(true); } TEST(FilePersistentMemoryAllocatorTest, ExtendTest) {
diff --git a/base/process/launch_win.cc b/base/process/launch_win.cc index 1349b3e..bb51a69 100644 --- a/base/process/launch_win.cc +++ b/base/process/launch_win.cc
@@ -17,6 +17,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/debug/activity_tracker.h" #include "base/debug/stack_trace.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" @@ -94,7 +95,12 @@ NOTREACHED() << "Failed to start process"; return false; } + base::win::ScopedProcessInformation proc_info(temp_process_info); + base::debug::GlobalActivityTracker* tracker = + base::debug::GlobalActivityTracker::Get(); + if (tracker) + tracker->RecordProcessLaunch(proc_info.process_id(), cl.as_string()); // Close our writing end of pipe now. Otherwise later read would not be able // to detect end of child's output. @@ -119,6 +125,8 @@ int exit_code; base::TerminationStatus status = GetTerminationStatus( proc_info.process_handle(), &exit_code); + base::debug::GlobalActivityTracker::RecordProcessExitIfEnabled( + proc_info.process_id(), exit_code); return status != base::TERMINATION_STATUS_PROCESS_CRASHED && status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION; } @@ -317,6 +325,8 @@ if (options.wait) WaitForSingleObject(process_info.process_handle(), INFINITE); + base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled( + process_info.process_id(), cmdline); return Process(process_info.TakeProcessHandle()); } @@ -344,6 +354,8 @@ if (options.wait) WaitForSingleObject(shex_info.hProcess, INFINITE); + base::debug::GlobalActivityTracker::RecordProcessLaunchIfEnabled( + GetProcessId(shex_info.hProcess), file, arguments); return Process(shex_info.hProcess); }
diff --git a/base/process/process_win.cc b/base/process/process_win.cc index 62321265..9232c6d 100644 --- a/base/process/process_win.cc +++ b/base/process/process_win.cc
@@ -139,6 +139,10 @@ } else if (!result) { DPLOG(ERROR) << "Unable to terminate process"; } + if (result) { + base::debug::GlobalActivityTracker::RecordProcessExitIfEnabled(Pid(), + exit_code); + } return result; } @@ -162,6 +166,9 @@ if (exit_code) *exit_code = temp_code; + + base::debug::GlobalActivityTracker::RecordProcessExitIfEnabled( + Pid(), static_cast<int>(temp_code)); return true; }
diff --git a/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc b/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc index 0d9d55db..6a2676f 100644 --- a/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc +++ b/base/task_scheduler/scheduler_single_thread_task_runner_manager.cc
@@ -229,7 +229,7 @@ size_t workers_unregistered_during_join = subtle::NoBarrier_Load(&workers_unregistered_during_join_); DCHECK_EQ(workers_unregistered_during_join, workers_.size()) - << "There cannot be outstanding SingleThreadTaskRunners upon destruction" + << "There cannot be outstanding SingleThreadTaskRunners upon destruction " "of SchedulerSingleThreadTaskRunnerManager or the Task Scheduler"; #endif }
diff --git a/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc b/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc index ea9cb66a..1311ea8 100644 --- a/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc +++ b/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
@@ -280,6 +280,7 @@ private: SchedulerSingleThreadTaskRunnerManager* const manager_to_join_; WaitableEvent run_started_event_; + DISALLOW_COPY_AND_ASSIGN(CallJoinFromDifferentThread); }; @@ -302,6 +303,8 @@ } // namespace TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { + // Exercises the codepath where the workers are unavailable for unregistration + // because of a Join call. WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, @@ -328,6 +331,8 @@ TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoinExtraSkippedTask) { + // Tests to make sure that tasks are properly cleaned up at Join, allowing + // SingleThreadTaskRunners to unregister themselves. WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL,
diff --git a/build/OWNERS b/build/OWNERS index c57052cb..89f07f1d 100644 --- a/build/OWNERS +++ b/build/OWNERS
@@ -6,6 +6,7 @@ thakis@chromium.org brucedawson@chromium.org +per-file .gitignore=* per-file mac_toolchain.py=erikchen@chromium.org per-file mac_toolchain.py=justincohen@chromium.org per-file package_mac_toolchain.py=erikchen@chromium.org
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn index fddca1b..ea55411 100644 --- a/build/config/android/BUILD.gn +++ b/build/config/android/BUILD.gn
@@ -39,7 +39,6 @@ } ldflags = [ - "-Wl,--build-id=sha1", "-Wl,--no-undefined", # Don't allow visible symbols from libgcc or libc++ to be
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 1f89686..d60664b 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -277,6 +277,16 @@ } } + if (is_official_build) { + # Explicitly pass --build-id to ld. Compilers used to always pass this + # implicitly but don't any more (in particular clang when built without + # ENABLE_LINKER_BUILD_ID=ON). The crash infrastructure does need a build + # id, so explicitly enable it in official builds. It's not needed in + # unofficial builds and computing it does slow down the link, so go with + # faster links in unofficial builds. + ldflags += [ "-Wl,--build-id=sha1" ] + } + defines += [ "_FILE_OFFSET_BITS=64" ] if (!is_android) {
diff --git a/cc/playback/display_item_list.cc b/cc/playback/display_item_list.cc index 1d54ae7..f9a827de 100644 --- a/cc/playback/display_item_list.cc +++ b/cc/playback/display_item_list.cc
@@ -157,13 +157,9 @@ } // namespace -DisplayItemList::Inputs::Inputs() - : items(LargestDisplayItemSize(), - LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve) {} - -DisplayItemList::Inputs::~Inputs() = default; - -DisplayItemList::DisplayItemList() = default; +DisplayItemList::DisplayItemList() + : items_(LargestDisplayItemSize(), + LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve) {} DisplayItemList::~DisplayItemList() = default; @@ -194,7 +190,7 @@ std::vector<size_t> indices; rtree_.Search(canvas_playback_rect, &indices); for (size_t index : indices) { - RasterItem(inputs_.items[index], canvas, callback); + RasterItem(items_[index], canvas, callback); // We use a callback during solid color analysis on the compositor thread to // break out early. Since we're handling a sequence of pictures via rtree @@ -206,21 +202,21 @@ void DisplayItemList::GrowCurrentBeginItemVisualRect( const gfx::Rect& visual_rect) { - if (!inputs_.begin_item_indices.empty()) - inputs_.visual_rects[inputs_.begin_item_indices.back()].Union(visual_rect); + if (!begin_item_indices_.empty()) + visual_rects_[begin_item_indices_.back()].Union(visual_rect); } void DisplayItemList::Finalize() { TRACE_EVENT0("cc", "DisplayItemList::Finalize"); - DCHECK(inputs_.items.size() == inputs_.visual_rects.size()) - << "items.size() " << inputs_.items.size() << " visual_rects.size() " - << inputs_.visual_rects.size(); - rtree_.Build(inputs_.visual_rects); + DCHECK(items_.size() == visual_rects_.size()) + << "items.size() " << items_.size() << " visual_rects.size() " + << visual_rects_.size(); + rtree_.Build(visual_rects_); if (!retain_visual_rects_) // This clears both the vector and the vector's capacity, since // visual_rects won't be used anymore. - std::vector<gfx::Rect>().swap(inputs_.visual_rects); + std::vector<gfx::Rect>().swap(visual_rects_); } bool DisplayItemList::IsSuitableForGpuRasterization() const { @@ -228,7 +224,7 @@ // none of the items might individually trigger a veto even though they // collectively have enough "bad" operations that a corresponding Picture // would get vetoed. See crbug.com/513016. - return inputs_.all_items_are_suitable_for_gpu_rasterization; + return all_items_are_suitable_for_gpu_rasterization_; } int DisplayItemList::ApproximateOpCount() const { @@ -239,7 +235,7 @@ size_t memory_usage = sizeof(*this); size_t external_memory_usage = 0; - for (const auto& item : inputs_.items) { + for (const auto& item : items_) { size_t bytes = 0; switch (item.type) { case DisplayItem::CLIP: @@ -281,7 +277,7 @@ } // Memory outside this class due to |items_|. - memory_usage += inputs_.items.GetCapacityInBytes() + external_memory_usage; + memory_usage += items_.GetCapacityInBytes() + external_memory_usage; // TODO(jbroman): Does anything else owned by this class substantially // contribute to memory usage? @@ -313,10 +309,10 @@ if (include_items) { state->BeginArray("items"); - auto visual_rects_it = inputs_.visual_rects.begin(); - for (const DisplayItem& base_item : inputs_.items) { + auto visual_rects_it = visual_rects_.begin(); + for (const DisplayItem& base_item : items_) { gfx::Rect visual_rect; - if (visual_rects_it != inputs_.visual_rects.end()) { + if (visual_rects_it != visual_rects_.end()) { visual_rect = *visual_rects_it; ++visual_rects_it; } @@ -490,7 +486,7 @@ DiscardableImageMap::ScopedMetadataGenerator generator( &image_map_, gfx::Size(bounds.right(), bounds.bottom())); auto* canvas = generator.canvas(); - for (const auto& item : inputs_.items) + for (const auto& item : items_) RasterItem(item, canvas, nullptr); }
diff --git a/cc/playback/display_item_list.h b/cc/playback/display_item_list.h index 1b060825..1f78694 100644 --- a/cc/playback/display_item_list.h +++ b/cc/playback/display_item_list.h
@@ -68,18 +68,18 @@ const DisplayItemType& CreateAndAppendPairedBeginItemWithVisualRect( const gfx::Rect& visual_rect, Args&&... args) { - size_t item_index = inputs_.visual_rects.size(); - inputs_.visual_rects.push_back(visual_rect); - inputs_.begin_item_indices.push_back(item_index); + size_t item_index = visual_rects_.size(); + visual_rects_.push_back(visual_rect); + begin_item_indices_.push_back(item_index); return AllocateAndConstruct<DisplayItemType>(std::forward<Args>(args)...); } template <typename DisplayItemType, typename... Args> const DisplayItemType& CreateAndAppendPairedEndItem(Args&&... args) { - DCHECK(!inputs_.begin_item_indices.empty()); - size_t last_begin_index = inputs_.begin_item_indices.back(); - inputs_.begin_item_indices.pop_back(); + DCHECK(!begin_item_indices_.empty()); + size_t last_begin_index = begin_item_indices_.back(); + begin_item_indices_.pop_back(); // Note that we are doing two separate things below: // @@ -103,11 +103,11 @@ // overhead. // Ending bounds match the starting bounds. - inputs_.visual_rects.push_back(inputs_.visual_rects[last_begin_index]); + visual_rects_.push_back(visual_rects_[last_begin_index]); // The block that ended needs to be included in the bounds of the enclosing // block. - GrowCurrentBeginItemVisualRect(inputs_.visual_rects[last_begin_index]); + GrowCurrentBeginItemVisualRect(visual_rects_[last_begin_index]); return AllocateAndConstruct<DisplayItemType>(std::forward<Args>(args)...); } @@ -116,7 +116,7 @@ const DisplayItemType& CreateAndAppendDrawingItem( const gfx::Rect& visual_rect, Args&&... args) { - inputs_.visual_rects.push_back(visual_rect); + visual_rects_.push_back(visual_rect); GrowCurrentBeginItemVisualRect(visual_rect); return AllocateAndConstruct<DisplayItemType>(std::forward<Args>(args)...); @@ -127,7 +127,7 @@ void Finalize(); void SetIsSuitableForGpuRasterization(bool is_suitable) { - inputs_.all_items_are_suitable_for_gpu_rasterization = is_suitable; + all_items_are_suitable_for_gpu_rasterization_ = is_suitable; } bool IsSuitableForGpuRasterization() const; @@ -147,18 +147,16 @@ retain_visual_rects_ = retain; } - size_t size() const { return inputs_.items.size(); } + size_t size() const { return items_.size(); } - gfx::Rect VisualRectForTesting(int index) { - return inputs_.visual_rects[index]; - } + gfx::Rect VisualRectForTesting(int index) { return visual_rects_[index]; } ContiguousContainer<DisplayItem>::const_iterator begin() const { - return inputs_.items.begin(); + return items_.begin(); } ContiguousContainer<DisplayItem>::const_iterator end() const { - return inputs_.items.end(); + return items_.end(); } private: @@ -170,43 +168,35 @@ std::unique_ptr<base::trace_event::TracedValue> CreateTracedValue( bool include_items) const; - RTree rtree_; - // For testing purposes only. Whether to keep visual rects across calls to - // Finalize(). - bool retain_visual_rects_ = false; - // If we're currently within a paired display item block, unions the // given visual rect with the begin display item's visual rect. void GrowCurrentBeginItemVisualRect(const gfx::Rect& visual_rect); template <typename DisplayItemType, typename... Args> const DisplayItemType& AllocateAndConstruct(Args&&... args) { - auto* item = &inputs_.items.AllocateAndConstruct<DisplayItemType>( + auto* item = &items_.AllocateAndConstruct<DisplayItemType>( std::forward<Args>(args)...); approximate_op_count_ += item->ApproximateOpCount(); return *item; } - int approximate_op_count_ = 0; - + RTree rtree_; DiscardableImageMap image_map_; + ContiguousContainer<DisplayItem> items_; - struct Inputs { - Inputs(); - ~Inputs(); + // The visual rects associated with each of the display items in the + // display item list. There is one rect per display item, and the + // position in |visual_rects| matches the position of the item in + // |items| . These rects are intentionally kept separate + // because they are not needed while walking the |items| for raster. + std::vector<gfx::Rect> visual_rects_; + std::vector<size_t> begin_item_indices_; - ContiguousContainer<DisplayItem> items; - // The visual rects associated with each of the display items in the - // display item list. There is one rect per display item, and the - // position in |visual_rects| matches the position of the item in - // |items| . These rects are intentionally kept separate - // because they are not needed while walking the |items| for raster. - std::vector<gfx::Rect> visual_rects; - std::vector<size_t> begin_item_indices; - bool all_items_are_suitable_for_gpu_rasterization = true; - }; - - Inputs inputs_; + int approximate_op_count_ = 0; + bool all_items_are_suitable_for_gpu_rasterization_ = true; + // For testing purposes only. Whether to keep visual rects across calls to + // Finalize(). + bool retain_visual_rects_ = false; friend class base::RefCountedThreadSafe<DisplayItemList>; FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, ApproximateMemoryUsage);
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index 8c8637c..2ad91ae 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc
@@ -386,50 +386,7 @@ TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); const media::VideoPixelFormat input_frame_format = video_frame->format(); - // TODO(hubbe): Make this a video frame method. - int bits_per_channel = 0; - switch (input_frame_format) { - case media::PIXEL_FORMAT_UNKNOWN: - NOTREACHED(); - // Fall through! - case media::PIXEL_FORMAT_I420: - case media::PIXEL_FORMAT_YV12: - case media::PIXEL_FORMAT_YV16: - case media::PIXEL_FORMAT_YV12A: - case media::PIXEL_FORMAT_YV24: - case media::PIXEL_FORMAT_NV12: - case media::PIXEL_FORMAT_NV21: - case media::PIXEL_FORMAT_UYVY: - case media::PIXEL_FORMAT_YUY2: - case media::PIXEL_FORMAT_ARGB: - case media::PIXEL_FORMAT_XRGB: - case media::PIXEL_FORMAT_RGB24: - case media::PIXEL_FORMAT_RGB32: - case media::PIXEL_FORMAT_MJPEG: - case media::PIXEL_FORMAT_MT21: - case media::PIXEL_FORMAT_Y8: - case media::PIXEL_FORMAT_I422: - bits_per_channel = 8; - break; - case media::PIXEL_FORMAT_YUV420P9: - case media::PIXEL_FORMAT_YUV422P9: - case media::PIXEL_FORMAT_YUV444P9: - bits_per_channel = 9; - break; - case media::PIXEL_FORMAT_YUV420P10: - case media::PIXEL_FORMAT_YUV422P10: - case media::PIXEL_FORMAT_YUV444P10: - bits_per_channel = 10; - break; - case media::PIXEL_FORMAT_YUV420P12: - case media::PIXEL_FORMAT_YUV422P12: - case media::PIXEL_FORMAT_YUV444P12: - bits_per_channel = 12; - break; - case media::PIXEL_FORMAT_Y16: - bits_per_channel = 16; - break; - } + int bits_per_channel = video_frame->BitsPerChannel(input_frame_format); // Only YUV and Y16 software video frames are supported. DCHECK(media::IsYuvPlanar(input_frame_format) ||
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index c475793..880cb8c 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc
@@ -41,14 +41,6 @@ Destroy(std::move(current_surface_)); } -void SurfaceFactory::Reset() { - EvictSurface(); - // Disown Surfaces that are still alive so that they don't try to unref - // resources that we're not tracking any more. - weak_factory_.InvalidateWeakPtrs(); - holder_.Reset(); -} - void SurfaceFactory::SubmitCompositorFrame( const LocalSurfaceId& local_surface_id, CompositorFrame frame,
diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h index 911c044..39a45fd 100644 --- a/cc/surfaces/surface_factory.h +++ b/cc/surfaces/surface_factory.h
@@ -50,10 +50,6 @@ // the old surface will be dealt with). void EvictSurface(); - // Destroys and disowns the current surface, and resets all resource - // references. This is useful when resources are invalid (e.g. lost context). - void Reset(); - // Submits the frame to the current surface being managed by the factory if // the local frame ids match, or creates a new surface with the given local // frame id, destroys the old one, and submits the frame to this new surface.
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index 2ae43000..0e445dd 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc
@@ -584,86 +584,6 @@ EXPECT_FALSE(client_.returned_resources().empty()); } -// Tests that SurfaceFactory returns resources after Reset(). -TEST_F(SurfaceFactoryTest, Reset) { - LocalSurfaceId id(7, kArbitraryToken); - - TransferableResource resource; - resource.id = 1; - resource.mailbox_holder.texture_target = GL_TEXTURE_2D; - CompositorFrame frame; - frame.resource_list.push_back(resource); - factory_->SubmitCompositorFrame(id, std::move(frame), - SurfaceFactory::DrawCallback()); - EXPECT_EQ(last_created_surface_id().local_surface_id(), id); - - SurfaceId surface_id(kArbitraryFrameSinkId, id); - EXPECT_TRUE(manager_.GetSurfaceForId(surface_id)); - EXPECT_TRUE(client_.returned_resources().empty()); - factory_->Reset(); - EXPECT_FALSE(manager_.GetSurfaceForId(surface_id)); - EXPECT_FALSE(client_.returned_resources().empty()); - local_surface_id_ = LocalSurfaceId(); -} - -// Tests that SurfaceFactory returns resources after Reset() if dependency -// unregistered. -TEST_F(SurfaceFactoryTest, ResetDependenceUnRegistered) { - LocalSurfaceId id(7, kArbitraryToken); - - TransferableResource resource; - resource.id = 1; - resource.mailbox_holder.texture_target = GL_TEXTURE_2D; - CompositorFrame frame; - frame.resource_list.push_back(resource); - factory_->SubmitCompositorFrame(id, std::move(frame), - SurfaceFactory::DrawCallback()); - EXPECT_EQ(last_created_surface_id().local_surface_id(), id); - - SurfaceId surface_id(kArbitraryFrameSinkId, id); - Surface* surface = manager_.GetSurfaceForId(surface_id); - surface->AddDestructionDependency( - SurfaceSequence(kAnotherArbitraryFrameSinkId, 4)); - EXPECT_TRUE(manager_.GetSurfaceForId(surface_id)); - EXPECT_TRUE(client_.returned_resources().empty()); - factory_->Reset(); - EXPECT_FALSE(manager_.GetSurfaceForId(surface_id)); - EXPECT_FALSE(client_.returned_resources().empty()); - local_surface_id_ = LocalSurfaceId(); -} - -// Tests that SurfaceFactory doesn't return resources after Reset() if -// dependency registered. -TEST_F(SurfaceFactoryTest, ResetDependencyRegistered) { - LocalSurfaceId id(7, kArbitraryToken); - - TransferableResource resource; - resource.id = 1; - resource.mailbox_holder.texture_target = GL_TEXTURE_2D; - CompositorFrame frame; - frame.resource_list.push_back(resource); - factory_->SubmitCompositorFrame(id, std::move(frame), - SurfaceFactory::DrawCallback()); - EXPECT_EQ(last_created_surface_id().local_surface_id(), id); - - manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId); - - SurfaceId surface_id(kArbitraryFrameSinkId, id); - Surface* surface = manager_.GetSurfaceForId(surface_id); - surface->AddDestructionDependency( - SurfaceSequence(kAnotherArbitraryFrameSinkId, 4)); - EXPECT_TRUE(manager_.GetSurfaceForId(surface_id)); - EXPECT_TRUE(client_.returned_resources().empty()); - factory_->Reset(); - EXPECT_TRUE(manager_.GetSurfaceForId(surface_id)); - EXPECT_TRUE(client_.returned_resources().empty()); - - manager_.SatisfySequence(SurfaceSequence(kAnotherArbitraryFrameSinkId, 4)); - EXPECT_FALSE(manager_.GetSurfaceForId(surface_id)); - EXPECT_TRUE(client_.returned_resources().empty()); - local_surface_id_ = LocalSurfaceId(); -} - TEST_F(SurfaceFactoryTest, DestroySequence) { LocalSurfaceId local_surface_id2(5, kArbitraryToken); std::unique_ptr<SurfaceFactory> factory2(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index e79d47a..1643480 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -531,6 +531,7 @@ mIncognitoTabCreator = tabCreators.second; OfflinePageUtils.observeTabModelSelector(this, mTabModelSelector); + NewTabPageUma.monitorNTPCreation(mTabModelSelector); if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java index ce662d7..01c791d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -190,9 +190,15 @@ MediaNotificationManager manager = getManager(); if (manager == null || manager.mMediaNotificationInfo == null) return false; - manager.onServiceStarted(this); - - processAction(intent, manager); + if (intent.getAction() == null) { + // The intent comes from {@link startService()} or + // {@link startServiceWithNotification}. + manager.onServiceStarted(this); + } else { + // The intent comes from the notification. In this case, {@link onServiceStarted()} + // does need to be called. + processAction(intent, manager); + } return true; } @@ -616,6 +622,8 @@ * @param service the service that was started */ private void onServiceStarted(ListenerService service) { + if (mService == service) return; + mService = service; updateNotification(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java b/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java index 172ff86..5732a124 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.browser.shapedetection.TextDetectionImpl; import org.chromium.chrome.browser.webshare.ShareServiceImplementationFactory; import org.chromium.content_public.browser.InterfaceRegistrar; +import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; import org.chromium.payments.mojom.PaymentRequest; import org.chromium.services.service_manager.InterfaceRegistry; @@ -28,6 +29,8 @@ InterfaceRegistrar.Registry.addContextRegistrar(new ChromeContextInterfaceRegistrar()); InterfaceRegistrar.Registry.addWebContentsRegistrar( new ChromeWebContentsInterfaceRegistrar()); + InterfaceRegistrar.Registry.addRenderFrameHostRegistrar( + new ChromeRenderFrameHostInterfaceRegistrar()); } private static class ChromeContextInterfaceRegistrar implements InterfaceRegistrar<Context> { @@ -45,9 +48,18 @@ implements InterfaceRegistrar<WebContents> { @Override public void registerInterfaces(InterfaceRegistry registry, final WebContents webContents) { - registry.addInterface(PaymentRequest.MANAGER, new PaymentRequestFactory(webContents)); registry.addInterface( ShareService.MANAGER, new ShareServiceImplementationFactory(webContents)); } } + + private static class ChromeRenderFrameHostInterfaceRegistrar + implements InterfaceRegistrar<RenderFrameHost> { + @Override + public void registerInterfaces( + InterfaceRegistry registry, final RenderFrameHost renderFrameHost) { + registry.addInterface( + PaymentRequest.MANAGER, new PaymentRequestFactory(renderFrameHost)); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java index deb2e7d..d6c08f6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -16,6 +16,8 @@ import org.chromium.chrome.browser.rappor.RapporServiceBridge; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.PageTransition; @@ -266,6 +268,15 @@ } /** + * Records how often new tabs with a NewTabPage are created. This helps to determine how often + * users navigate back to already opened NTPs. + * @param tabModelSelector Model selector controlling the creation of new tabs. + */ + public static void monitorNTPCreation(TabModelSelector tabModelSelector) { + tabModelSelector.addObserver(new TabCreationRecorder()); + } + + /** * Records the type of load for the NTP, such as cold or warm start. */ public static void recordLoadType(ChromeActivity activity) { @@ -308,6 +319,18 @@ } /** + * Records the number of new NTPs opened in a new tab. Use through + * {@link NewTabPageUma#monitorNTPCreation(TabModelSelector)}. + */ + private static class TabCreationRecorder extends EmptyTabModelSelectorObserver { + @Override + public void onNewTabCreated(Tab tab) { + if (!NewTabPage.isNTPUrl(tab.getUrl())) return; + RecordUserAction.record("MobileNTPOpenedInNewTab"); + } + } + + /** * Records stats related to content suggestion visits, such as the time spent on the website, or * if the user comes back to the NTP. Use through * {@link NewTabPageUma#monitorContentSuggestionVisit(Tab, int)}.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java index 17f19df..dd84cca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestFactory.java
@@ -5,7 +5,7 @@ package org.chromium.chrome.browser.payments; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.mojo.system.MojoException; import org.chromium.payments.mojom.CanMakePaymentQueryResult; import org.chromium.payments.mojom.PaymentDetails; @@ -20,7 +20,7 @@ * Creates instances of PaymentRequest. */ public class PaymentRequestFactory implements InterfaceFactory<PaymentRequest> { - private final WebContents mWebContents; + private final RenderFrameHost mRenderFrameHost; /** * An implementation of PaymentRequest that immediately rejects all connections. @@ -71,8 +71,8 @@ * * @param webContents The web contents that may invoke the PaymentRequest API. */ - public PaymentRequestFactory(WebContents webContents) { - mWebContents = webContents; + public PaymentRequestFactory(RenderFrameHost renderFrameHost) { + mRenderFrameHost = renderFrameHost; } @Override @@ -81,8 +81,8 @@ return new InvalidPaymentRequest(); } - if (mWebContents == null) return new InvalidPaymentRequest(); + if (mRenderFrameHost == null) return new InvalidPaymentRequest(); - return new PaymentRequestImpl(mWebContents); + return new PaymentRequestImpl(mRenderFrameHost); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 3c06b63d..644351f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -47,7 +47,9 @@ import org.chromium.components.payments.CurrencyFormatter; import org.chromium.components.payments.PaymentValidator; import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.WebContentsStatics; import org.chromium.mojo.system.MojoException; import org.chromium.payments.mojom.CanMakePaymentQueryResult; import org.chromium.payments.mojom.PaymentComplete; @@ -246,6 +248,7 @@ }; private final Handler mHandler = new Handler(); + private final RenderFrameHost mRenderFrameHost; private final WebContents mWebContents; private final String mSchemelessOriginForPaymentApp; private final String mOriginForDisplay; @@ -348,10 +351,11 @@ * * @param webContents The web contents that have invoked the PaymentRequest API. */ - public PaymentRequestImpl(WebContents webContents) { - assert webContents != null; + public PaymentRequestImpl(RenderFrameHost renderFrameHost) { + assert renderFrameHost != null; - mWebContents = webContents; + mRenderFrameHost = renderFrameHost; + mWebContents = WebContentsStatics.fromRenderFrameHost(renderFrameHost); mSchemelessOriginForPaymentApp = UrlFormatter.formatUrlForSecurityDisplay( mWebContents.getLastCommittedUrl(), false /* omit scheme for payment apps. */); @@ -359,7 +363,8 @@ mOriginForDisplay = UrlFormatter.formatUrlForSecurityDisplay( mWebContents.getLastCommittedUrl(), true /* include scheme in display */); - mMerchantName = webContents.getTitle(); + mMerchantName = mWebContents.getTitle(); + mCertificateChain = CertificateChainHelper.getCertificateChain(mWebContents); mApps = new ArrayList<>();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java index e161cdf..a667832f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
@@ -233,12 +233,12 @@ /** * Tests that scanning the Daydream View NFC tag on supported devices - * fires the onvrdisplayactivate event. + * fires the vrdisplayactivate event. */ @SmallTest @Restriction(RESTRICTION_TYPE_DAYDREAM_VIEW) - public void testNfcFiresOnvrdisplayactivate() throws InterruptedException { - String testName = "test_nfc_fires_onvrdisplayactivate"; + public void testNfcFiresVrdisplayactivate() throws InterruptedException { + String testName = "test_nfc_fires_vrdisplayactivate"; loadUrl(getHtmlTestFile(testName), 10); simNfcScanAndWait(mWebContents); endTest(mWebContents);
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 4c7ab12..d1c92e8 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1216,6 +1216,8 @@ "signin/signin_status_metrics_provider_chromeos.h", "signin/signin_tracker_factory.cc", "signin/signin_tracker_factory.h", + "signin/signin_util.cc", + "signin/signin_util.h", "site_details.cc", "site_details.h", "speech/chrome_speech_recognition_manager_delegate.cc",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index ccb6bc0..ad12f6f8 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3168,13 +3168,13 @@ render_frame_host)); #if defined(OS_ANDROID) + registry->AddInterface( + render_frame_host->GetJavaInterfaces() + ->CreateInterfaceFactory<payments::mojom::PaymentRequest>()); content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(render_frame_host); if (web_contents) { registry->AddInterface( - web_contents->GetJavaInterfaces() - ->CreateInterfaceFactory<payments::mojom::PaymentRequest>()); - registry->AddInterface( base::Bind(&ForwardShareServiceRequest, web_contents->GetJavaInterfaces()->GetWeakPtr())); }
diff --git a/chrome/browser/chrome_site_per_process_browsertest.cc b/chrome/browser/chrome_site_per_process_browsertest.cc index de4374a4..6c45c0a 100644 --- a/chrome/browser/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/chrome_site_per_process_browsertest.cc
@@ -100,8 +100,16 @@ return device_scale_factor; } +// Flaky on Windows 10. http://crbug.com/700150 +#if defined(OS_WIN) +#define MAYBE_InterstitialLoadsWithCorrectDeviceScaleFactor \ + DISABLED_InterstitialLoadsWithCorrectDeviceScaleFactor +#else +#define MAYBE_InterstitialLoadsWithCorrectDeviceScaleFactor \ + InterstitialLoadsWithCorrectDeviceScaleFactor +#endif IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIExpiredCertBrowserTest, - InterstitialLoadsWithCorrectDeviceScaleFactor) { + MAYBE_InterstitialLoadsWithCorrectDeviceScaleFactor) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b)")); ui_test_utils::NavigateToURL(browser(), main_url);
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc index 47ff0add..d59ec468 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -258,7 +258,7 @@ AreArcAllOptInPreferencesManagedForProfile(profile_)); if (!suppress_play_store_app) { playstore_launcher_.reset( - new ArcAppLauncher(profile_, kPlayStoreAppId, true)); + new ArcAppLauncher(profile_, kPlayStoreAppId, true, false)); } for (auto& observer : observer_list_)
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 6ba3c6d..1705418 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -967,6 +967,10 @@ "api/log_private/syslog_parser.cc", "api/log_private/syslog_parser.h", "api/messaging/native_message_host_chromeos.cc", + "api/networking_cast_private/chrome_networking_cast_private_delegate.cc", + "api/networking_cast_private/chrome_networking_cast_private_delegate.h", + "api/networking_cast_private/networking_cast_private_api.cc", + "api/networking_cast_private/networking_cast_private_api.h", "api/networking_private/crypto_verify_impl.cc", "api/networking_private/crypto_verify_impl.h", "api/platform_keys/platform_keys_api.cc", @@ -1071,6 +1075,10 @@ if (is_win || is_mac) { sources += [ + "api/networking_cast_private/chrome_networking_cast_private_delegate.cc", + "api/networking_cast_private/chrome_networking_cast_private_delegate.h", + "api/networking_cast_private/networking_cast_private_api.cc", + "api/networking_cast_private/networking_cast_private_api.h", "api/networking_private/crypto_verify_impl.cc", "api/networking_private/crypto_verify_impl.h", "api/networking_private/networking_private_credentials_getter.h",
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc index 9aa074a..0ffe5d98 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/extensions/api/declarative_content/default_content_predicate_evaluators.h" #include "chrome/browser/extensions/api/management/chrome_management_api_delegate.h" #include "chrome/browser/extensions/api/metrics_private/chrome_metrics_private_delegate.h" +#include "chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h" #include "chrome/browser/extensions/api/storage/managed_value_store_cache.h" #include "chrome/browser/extensions/api/storage/sync_value_store_cache.h" #include "chrome/browser/extensions/api/web_request/chrome_extension_web_request_event_router_delegate.h" @@ -168,6 +169,16 @@ return metrics_private_delegate_.get(); } +NetworkingCastPrivateDelegate* +ChromeExtensionsAPIClient::GetNetworkingCastPrivateDelegate() { +#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) + if (!networking_cast_private_delegate_) + networking_cast_private_delegate_ = + ChromeNetworkingCastPrivateDelegate::Create(); +#endif + return networking_cast_private_delegate_.get(); +} + #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* ChromeExtensionsAPIClient::GetNonNativeFileSystemDelegate() {
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chrome/browser/extensions/api/chrome_extensions_api_client.h index 55611b7..bd5c116 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.h +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.h
@@ -54,6 +54,7 @@ const override; ManagementAPIDelegate* CreateManagementAPIDelegate() const override; MetricsPrivateDelegate* GetMetricsPrivateDelegate() override; + NetworkingCastPrivateDelegate* GetNetworkingCastPrivateDelegate() override; #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* GetNonNativeFileSystemDelegate() override; @@ -67,6 +68,8 @@ private: std::unique_ptr<ChromeMetricsPrivateDelegate> metrics_private_delegate_; + std::unique_ptr<NetworkingCastPrivateDelegate> + networking_cast_private_delegate_; #if defined(OS_CHROMEOS) std::unique_ptr<NonNativeFileSystemDelegate> non_native_file_system_delegate_;
diff --git a/chrome/browser/extensions/api/networking_cast_private/OWNERS b/chrome/browser/extensions/api/networking_cast_private/OWNERS new file mode 100644 index 0000000..b321c2f --- /dev/null +++ b/chrome/browser/extensions/api/networking_cast_private/OWNERS
@@ -0,0 +1,2 @@ +stevenjb@chromium.org +tbarzic@chromium.org
diff --git a/chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.cc b/chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.cc new file mode 100644 index 0000000..f6fb067 --- /dev/null +++ b/chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.cc
@@ -0,0 +1,66 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h" + +#include "base/callback.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_verify_delegate_factory_impl.h" +#include "extensions/common/api/networking_private.h" + +namespace extensions { + +namespace { + +ChromeNetworkingCastPrivateDelegate::FactoryCallback* g_factory_callback = + nullptr; + +} // namespace + +std::unique_ptr<ChromeNetworkingCastPrivateDelegate> +ChromeNetworkingCastPrivateDelegate::Create() { + if (g_factory_callback) + return g_factory_callback->Run(); + return std::unique_ptr<ChromeNetworkingCastPrivateDelegate>( + new ChromeNetworkingCastPrivateDelegate( + NetworkingPrivateVerifyDelegateFactoryImpl().CreateDelegate())); +} + +void ChromeNetworkingCastPrivateDelegate::SetFactoryCallbackForTest( + FactoryCallback* factory_callback) { + g_factory_callback = factory_callback; +} + +ChromeNetworkingCastPrivateDelegate::ChromeNetworkingCastPrivateDelegate( + std::unique_ptr<NetworkingPrivateDelegate::VerifyDelegate> crypto_verify) + : crypto_verify_(std::move(crypto_verify)) {} + +ChromeNetworkingCastPrivateDelegate::~ChromeNetworkingCastPrivateDelegate() {} + +void ChromeNetworkingCastPrivateDelegate::VerifyDestination( + const api::networking_private::VerificationProperties& properties, + const VerifiedCallback& success_callback, + const FailureCallback& failure_callback) { + crypto_verify_->VerifyDestination(properties, success_callback, + failure_callback); +} + +void ChromeNetworkingCastPrivateDelegate::VerifyAndEncryptCredentials( + const std::string& guid, + const api::networking_private::VerificationProperties& properties, + const DataCallback& success_callback, + const FailureCallback& failure_callback) { + crypto_verify_->VerifyAndEncryptCredentials( + guid, properties, success_callback, failure_callback); +} + +void ChromeNetworkingCastPrivateDelegate::VerifyAndEncryptData( + const std::string& data, + const api::networking_private::VerificationProperties& properties, + const DataCallback& success_callback, + const FailureCallback& failure_callback) { + crypto_verify_->VerifyAndEncryptData(properties, data, success_callback, + failure_callback); +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h b/chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h new file mode 100644 index 0000000..618e4ca --- /dev/null +++ b/chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h
@@ -0,0 +1,66 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_NETWORKING_CAST_PRIVATE_CHROME_NETWORKING_CAST_PRIVATE_DELEGATE_H_ +#define CHROME_BROWSER_EXTENSIONS_API_NETWORKING_CAST_PRIVATE_CHROME_NETWORKING_CAST_PRIVATE_DELEGATE_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "extensions/browser/api/networking_private/networking_cast_private_delegate.h" +#include "extensions/browser/api/networking_private/networking_private_delegate.h" + +namespace extensions { + +// Chrome implementation of extensions::NetworkingCastPrivateDelegate. +class ChromeNetworkingCastPrivateDelegate + : public NetworkingCastPrivateDelegate { + public: + using FactoryCallback = + base::Callback<std::unique_ptr<ChromeNetworkingCastPrivateDelegate>()>; + static void SetFactoryCallbackForTest(FactoryCallback* factory_callback); + + static std::unique_ptr<ChromeNetworkingCastPrivateDelegate> Create(); + + ~ChromeNetworkingCastPrivateDelegate() override; + + // NetworkingCastPrivateDelegate overrides: + void VerifyDestination( + const api::networking_private::VerificationProperties& properties, + const VerifiedCallback& success_callback, + const FailureCallback& failure_callback) override; + void VerifyAndEncryptCredentials( + const std::string& guid, + const api::networking_private::VerificationProperties& properties, + const DataCallback& success_callback, + const FailureCallback& failure_callback) override; + void VerifyAndEncryptData( + const std::string& data, + const api::networking_private::VerificationProperties& properties, + const DataCallback& success_callback, + const FailureCallback& failure_callback) override; + + private: + // Friend the test so it can inject stub VerifyDelegate implementation. + // TODO(tbarzic): Remove this when NetworkingCastPrivateDelegate stops + // depending on + // NetworkingPrivateDelegate::VerifyDelegate. + friend class NetworkingCastPrivateApiTest; + + explicit ChromeNetworkingCastPrivateDelegate( + std::unique_ptr<NetworkingPrivateDelegate::VerifyDelegate> + verify_delegate); + + // NetworkingPrivates API's crypto utility to which verification requests + // will be routed. + std::unique_ptr<NetworkingPrivateDelegate::VerifyDelegate> crypto_verify_; + + DISALLOW_COPY_AND_ASSIGN(ChromeNetworkingCastPrivateDelegate); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_NETWORKING_CAST_PRIVATE_CHROME_NETWORKING_CAST_PRIVATE_DELEGATE_H_
diff --git a/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.cc b/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.cc new file mode 100644 index 0000000..cd81046 --- /dev/null +++ b/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.cc
@@ -0,0 +1,239 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.h" + +#include <utility> + +#include "base/bind.h" +#include "chrome/common/extensions/api/networking_cast_private.h" +#include "extensions/browser/api/extensions_api_client.h" +#include "extensions/browser/api/networking_private/networking_cast_private_delegate.h" + +#if defined(OS_CHROMEOS) +#include "chromeos/network/network_device_handler.h" +#include "chromeos/network/network_handler.h" +#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" +#endif + +namespace private_api = extensions::api::networking_private; +namespace cast_api = extensions::api::networking_cast_private; + +namespace extensions { + +namespace { + +#if defined(OS_CHROMEOS) +// Parses TDLS status returned by network handler to networking_cast_private +// TDLS status type. +cast_api::TDLSStatus ParseTDLSStatus(const std::string& status) { + if (status == shill::kTDLSConnectedState) + return cast_api::TDLS_STATUS_CONNECTED; + if (status == shill::kTDLSNonexistentState) + return cast_api::TDLS_STATUS_NONEXISTENT; + if (status == shill::kTDLSDisabledState) + return cast_api::TDLS_STATUS_DISABLED; + if (status == shill::kTDLSDisconnectedState) + return cast_api::TDLS_STATUS_DISCONNECTED; + if (status == shill::kTDLSUnknownState) + return cast_api::TDLS_STATUS_UNKNOWN; + + NOTREACHED() << "Unknown TDLS status " << status; + return cast_api::TDLS_STATUS_UNKNOWN; +} +#endif + +std::unique_ptr<private_api::VerificationProperties> +AsPrivateApiVerificaitonProperties( + const cast_api::VerificationProperties& properties) { + std::unique_ptr<base::DictionaryValue> cast_properties_dict = + properties.ToValue(); + CHECK(cast_properties_dict); + return private_api::VerificationProperties::FromValue(*cast_properties_dict); +} + +} // namespace + +NetworkingCastPrivateVerifyDestinationFunction:: + ~NetworkingCastPrivateVerifyDestinationFunction() {} + +ExtensionFunction::ResponseAction +NetworkingCastPrivateVerifyDestinationFunction::Run() { + std::unique_ptr<cast_api::VerifyDestination::Params> params = + cast_api::VerifyDestination::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + NetworkingCastPrivateDelegate* delegate = + ExtensionsAPIClient::Get()->GetNetworkingCastPrivateDelegate(); + std::unique_ptr<private_api::VerificationProperties> private_api_properties = + AsPrivateApiVerificaitonProperties(params->properties); + delegate->VerifyDestination( + *private_api_properties, + base::Bind(&NetworkingCastPrivateVerifyDestinationFunction::Success, + this), + base::Bind(&NetworkingCastPrivateVerifyDestinationFunction::Failure, + this)); + + // VerifyDestination might respond synchronously, e.g. in tests. + return did_respond() ? AlreadyResponded() : RespondLater(); +} + +void NetworkingCastPrivateVerifyDestinationFunction::Success(bool result) { + Respond(ArgumentList(cast_api::VerifyDestination::Results::Create(result))); +} + +void NetworkingCastPrivateVerifyDestinationFunction::Failure( + const std::string& error) { + Respond(Error(error)); +} + +NetworkingCastPrivateVerifyAndEncryptCredentialsFunction:: + ~NetworkingCastPrivateVerifyAndEncryptCredentialsFunction() {} + +ExtensionFunction::ResponseAction +NetworkingCastPrivateVerifyAndEncryptCredentialsFunction::Run() { + std::unique_ptr<cast_api::VerifyAndEncryptCredentials::Params> params = + cast_api::VerifyAndEncryptCredentials::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + NetworkingCastPrivateDelegate* delegate = + ExtensionsAPIClient::Get()->GetNetworkingCastPrivateDelegate(); + std::unique_ptr<private_api::VerificationProperties> private_api_properties = + AsPrivateApiVerificaitonProperties(params->properties); + delegate->VerifyAndEncryptCredentials( + params->network_guid, *private_api_properties, + base::Bind( + &NetworkingCastPrivateVerifyAndEncryptCredentialsFunction::Success, + this), + base::Bind( + &NetworkingCastPrivateVerifyAndEncryptCredentialsFunction::Failure, + this)); + + // VerifyAndEncryptCredentials might respond synchronously, e.g. in tests. + return did_respond() ? AlreadyResponded() : RespondLater(); +} + +void NetworkingCastPrivateVerifyAndEncryptCredentialsFunction::Success( + const std::string& result) { + Respond(ArgumentList( + cast_api::VerifyAndEncryptCredentials::Results::Create(result))); +} + +void NetworkingCastPrivateVerifyAndEncryptCredentialsFunction::Failure( + const std::string& error) { + Respond(Error(error)); +} + +NetworkingCastPrivateVerifyAndEncryptDataFunction:: + ~NetworkingCastPrivateVerifyAndEncryptDataFunction() {} + +ExtensionFunction::ResponseAction +NetworkingCastPrivateVerifyAndEncryptDataFunction::Run() { + std::unique_ptr<cast_api::VerifyAndEncryptData::Params> params = + cast_api::VerifyAndEncryptData::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + NetworkingCastPrivateDelegate* delegate = + ExtensionsAPIClient::Get()->GetNetworkingCastPrivateDelegate(); + std::unique_ptr<private_api::VerificationProperties> private_api_properties = + AsPrivateApiVerificaitonProperties(params->properties); + delegate->VerifyAndEncryptData( + params->data, *private_api_properties, + base::Bind(&NetworkingCastPrivateVerifyAndEncryptDataFunction::Success, + this), + base::Bind(&NetworkingCastPrivateVerifyAndEncryptDataFunction::Failure, + this)); + + // VerifyAndEncryptData might respond synchronously, e.g. in tests. + return did_respond() ? AlreadyResponded() : RespondLater(); +} + +void NetworkingCastPrivateVerifyAndEncryptDataFunction::Success( + const std::string& result) { + Respond( + ArgumentList(cast_api::VerifyAndEncryptData::Results::Create(result))); +} + +void NetworkingCastPrivateVerifyAndEncryptDataFunction::Failure( + const std::string& error) { + Respond(Error(error)); +} + +NetworkingCastPrivateSetWifiTDLSEnabledStateFunction:: + ~NetworkingCastPrivateSetWifiTDLSEnabledStateFunction() {} + +ExtensionFunction::ResponseAction +NetworkingCastPrivateSetWifiTDLSEnabledStateFunction::Run() { + std::unique_ptr<cast_api::SetWifiTDLSEnabledState::Params> params = + cast_api::SetWifiTDLSEnabledState::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + +#if defined(OS_CHROMEOS) + chromeos::NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled( + params->ip_or_mac_address, params->enabled, + base::Bind(&NetworkingCastPrivateSetWifiTDLSEnabledStateFunction::Success, + this), + base::Bind(&NetworkingCastPrivateSetWifiTDLSEnabledStateFunction::Failure, + this)); + + // SetWifiTDLSEnabled might respond synchronously, e.g. in tests. + return did_respond() ? AlreadyResponded() : RespondLater(); +#else + return RespondNow(Error("Not supported")); +#endif +} + +#if defined(OS_CHROMEOS) +void NetworkingCastPrivateSetWifiTDLSEnabledStateFunction::Success( + const std::string& result) { + Respond(ArgumentList(cast_api::SetWifiTDLSEnabledState::Results::Create( + ParseTDLSStatus(result)))); +} + +void NetworkingCastPrivateSetWifiTDLSEnabledStateFunction::Failure( + const std::string& error, + std::unique_ptr<base::DictionaryValue> error_data) { + Respond(Error(error)); +} +#endif + +NetworkingCastPrivateGetWifiTDLSStatusFunction:: + ~NetworkingCastPrivateGetWifiTDLSStatusFunction() {} + +ExtensionFunction::ResponseAction +NetworkingCastPrivateGetWifiTDLSStatusFunction::Run() { + std::unique_ptr<cast_api::GetWifiTDLSStatus::Params> params = + cast_api::GetWifiTDLSStatus::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + +#if defined(OS_CHROMEOS) + chromeos::NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus( + params->ip_or_mac_address, + base::Bind(&NetworkingCastPrivateGetWifiTDLSStatusFunction::Success, + this), + base::Bind(&NetworkingCastPrivateGetWifiTDLSStatusFunction::Failure, + this)); + + // GetWifiTDLSStatus might respond synchronously, e.g. in tests. + return did_respond() ? AlreadyResponded() : RespondLater(); +#else + return RespondNow(Error("Not supported")); +#endif +} + +#if defined(OS_CHROMEOS) +void NetworkingCastPrivateGetWifiTDLSStatusFunction::Success( + const std::string& result) { + Respond(ArgumentList( + cast_api::GetWifiTDLSStatus::Results::Create(ParseTDLSStatus(result)))); +} + +void NetworkingCastPrivateGetWifiTDLSStatusFunction::Failure( + const std::string& error, + std::unique_ptr<base::DictionaryValue> error_data) { + Respond(Error(error)); +} +#endif + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.h b/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.h new file mode 100644 index 0000000..749e8588 --- /dev/null +++ b/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_api.h
@@ -0,0 +1,131 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_NETWORKING_CAST_PRIVATE_NETWORKING_CAST_PRIVATE_API_H_ +#define CHROME_BROWSER_EXTENSIONS_API_NETWORKING_CAST_PRIVATE_NETWORKING_CAST_PRIVATE_API_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "extensions/browser/extension_function.h" + +namespace base { +class DictionaryValue; +} + +namespace extensions { + +class NetworkingCastPrivateVerifyDestinationFunction + : public UIThreadExtensionFunction { + public: + NetworkingCastPrivateVerifyDestinationFunction() {} + DECLARE_EXTENSION_FUNCTION("networking.castPrivate.verifyDestination", + NETWORKINGCASTPRIVATE_VERIFYDESTINATION); + + protected: + ~NetworkingCastPrivateVerifyDestinationFunction() override; + + // ExtensionFunction: + ResponseAction Run() override; + + void Success(bool result); + void Failure(const std::string& error); + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkingCastPrivateVerifyDestinationFunction); +}; + +class NetworkingCastPrivateVerifyAndEncryptCredentialsFunction + : public UIThreadExtensionFunction { + public: + NetworkingCastPrivateVerifyAndEncryptCredentialsFunction() {} + DECLARE_EXTENSION_FUNCTION( + "networking.castPrivate.verifyAndEncryptCredentials", + NETWORKINGCASTPRIVATE_VERIFYANDENCRYPTCREDENTIALS); + + protected: + ~NetworkingCastPrivateVerifyAndEncryptCredentialsFunction() override; + + // ExtensionFunction: + ResponseAction Run() override; + + void Success(const std::string& result); + void Failure(const std::string& error); + + private: + DISALLOW_COPY_AND_ASSIGN( + NetworkingCastPrivateVerifyAndEncryptCredentialsFunction); +}; + +class NetworkingCastPrivateVerifyAndEncryptDataFunction + : public UIThreadExtensionFunction { + public: + NetworkingCastPrivateVerifyAndEncryptDataFunction() {} + DECLARE_EXTENSION_FUNCTION("networking.castPrivate.verifyAndEncryptData", + NETWORKINGCASTPRIVATE_VERIFYANDENCRYPTDATA); + + protected: + ~NetworkingCastPrivateVerifyAndEncryptDataFunction() override; + + // ExtensionFunction: + ResponseAction Run() override; + + void Success(const std::string& result); + void Failure(const std::string& error); + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkingCastPrivateVerifyAndEncryptDataFunction); +}; + +class NetworkingCastPrivateSetWifiTDLSEnabledStateFunction + : public UIThreadExtensionFunction { + public: + NetworkingCastPrivateSetWifiTDLSEnabledStateFunction() {} + DECLARE_EXTENSION_FUNCTION("networking.castPrivate.setWifiTDLSEnabledState", + NETWORKINGCASTPRIVATE_SETWIFITDLSENABLEDSTATE); + + protected: + ~NetworkingCastPrivateSetWifiTDLSEnabledStateFunction() override; + + // ExtensionFunction: + ResponseAction Run() override; + +#if defined(OS_CHROMEOS) + void Success(const std::string& result); + void Failure(const std::string& error, + std::unique_ptr<base::DictionaryValue> error_data); +#endif + + private: + DISALLOW_COPY_AND_ASSIGN( + NetworkingCastPrivateSetWifiTDLSEnabledStateFunction); +}; + +class NetworkingCastPrivateGetWifiTDLSStatusFunction + : public UIThreadExtensionFunction { + public: + NetworkingCastPrivateGetWifiTDLSStatusFunction() {} + DECLARE_EXTENSION_FUNCTION("networking.castPrivate.getWifiTDLSStatus", + NETWORKINGCASTPRIVATE_GETWIFITDLSSTATUS); + + protected: + ~NetworkingCastPrivateGetWifiTDLSStatusFunction() override; + + // ExtensionFunction: + ResponseAction Run() override; + +#if defined(OS_CHROMEOS) + void Success(const std::string& result); + void Failure(const std::string& error, + std::unique_ptr<base::DictionaryValue> error_data); +#endif + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkingCastPrivateGetWifiTDLSStatusFunction); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_NETWORKING_CAST_PRIVATE_NETWORKING_CAST_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_apitest.cc b/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_apitest.cc new file mode 100644 index 0000000..bdfc502 --- /dev/null +++ b/chrome/browser/extensions/api/networking_cast_private/networking_cast_private_apitest.cc
@@ -0,0 +1,144 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/command_line.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/api/networking_cast_private/chrome_networking_cast_private_delegate.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "extensions/browser/api/networking_private/networking_private_delegate.h" +#include "extensions/common/api/networking_private.h" +#include "extensions/common/switches.h" + +#if defined(OS_CHROMEOS) +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/shill_device_client.h" +#include "chromeos/dbus/shill_service_client.h" +#include "third_party/cros_system_api/dbus/service_constants.h" +#endif + +namespace extensions { + +namespace { + +class TestVerifyDelegate : public NetworkingPrivateDelegate::VerifyDelegate { + public: + TestVerifyDelegate() = default; + ~TestVerifyDelegate() override = default; + + void VerifyDestination(const VerificationProperties& properties, + const BoolCallback& success_callback, + const FailureCallback& failure_callback) override { + success_callback.Run(true); + } + + void VerifyAndEncryptCredentials( + const std::string& guid, + const VerificationProperties& properties, + const StringCallback& success_callback, + const FailureCallback& failure_callback) override { + success_callback.Run("encrypted_credentials"); + } + + void VerifyAndEncryptData(const VerificationProperties& properties, + const std::string& data, + const StringCallback& success_callback, + const FailureCallback& failure_callback) override { + success_callback.Run("encrypted_data"); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestVerifyDelegate); +}; + +} // namespace + +class NetworkingCastPrivateApiTest : public ExtensionApiTest { + public: + NetworkingCastPrivateApiTest() = default; + ~NetworkingCastPrivateApiTest() override = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + ExtensionApiTest::SetUpCommandLine(command_line); + // Whitelist the extension ID of the test extension. + command_line->AppendSwitchASCII( + extensions::switches::kWhitelistedExtensionID, + "epcifkihnkjgphfkloaaleeakhpmgdmn"); + } + + void SetUp() override { + networking_cast_private_delegate_factory_ = base::Bind( + &NetworkingCastPrivateApiTest::CreateNetworkingCastPrivateDelegate, + base::Unretained(this)); + ChromeNetworkingCastPrivateDelegate::SetFactoryCallbackForTest( + &networking_cast_private_delegate_factory_); + + ExtensionApiTest::SetUp(); + } + + void SetUpOnMainThread() override { + ExtensionApiTest::SetUpOnMainThread(); + +#if defined(OS_CHROMEOS) + chromeos::DBusThreadManager* dbus_manager = + chromeos::DBusThreadManager::Get(); + chromeos::ShillDeviceClient::TestInterface* device_test = + dbus_manager->GetShillDeviceClient()->GetTestInterface(); + device_test->ClearDevices(); + device_test->AddDevice("/device/stub_wifi_device1", shill::kTypeWifi, + "stub_wifi_device"); + device_test->SetTDLSState(shill::kTDLSConnectedState); + + chromeos::ShillServiceClient::TestInterface* service_test = + dbus_manager->GetShillServiceClient()->GetTestInterface(); + service_test->ClearServices(); + service_test->AddService("stub_wifi", "stub_wifi_guid", "wifi", + shill::kTypeWifi, shill::kStateOnline, + true /* add_to_visible */); +#endif // defined(OS_CHROMEOS) + } + + void TearDown() override { + ExtensionApiTest::TearDown(); + ChromeNetworkingCastPrivateDelegate::SetFactoryCallbackForTest(nullptr); + } + + bool TdlsSupported() { +#if defined(OS_CHROMEOS) + return true; +#else + return false; +#endif + } + + private: + std::unique_ptr<ChromeNetworkingCastPrivateDelegate> + CreateNetworkingCastPrivateDelegate() { + return std::unique_ptr<ChromeNetworkingCastPrivateDelegate>( + new ChromeNetworkingCastPrivateDelegate( + base::MakeUnique<TestVerifyDelegate>())); + } + + ChromeNetworkingCastPrivateDelegate::FactoryCallback + networking_cast_private_delegate_factory_; + + DISALLOW_COPY_AND_ASSIGN(NetworkingCastPrivateApiTest); +}; + +IN_PROC_BROWSER_TEST_F(NetworkingCastPrivateApiTest, Basic) { + const std::string arg = + base::StringPrintf("{\"tdlsSupported\": %d}", TdlsSupported()); + EXPECT_TRUE(RunPlatformAppTestWithArg("networking_cast_private", arg.c_str())) + << message_; +} + +} // namespace extensions
diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc index 0d6afba..193f85ce 100644 --- a/chrome/browser/profiles/profile_attributes_entry.cc +++ b/chrome/browser/profiles/profile_attributes_entry.cc
@@ -1,19 +1,10 @@ // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// -#include "chrome/browser/browser_process.h" + #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_info_cache.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" - -namespace { -bool IsForceSigninEnabled() { - PrefService* prefs = g_browser_process->local_state(); - return prefs && prefs->GetBoolean(prefs::kForceBrowserSignin); -} -} // namespace +#include "chrome/browser/signin/signin_util.h" ProfileAttributesEntry::ProfileAttributesEntry() : profile_info_cache_(nullptr), profile_path_(base::FilePath()) {} @@ -26,7 +17,7 @@ DCHECK(profile_path_.empty()); DCHECK(!path.empty()); profile_path_ = path; - is_force_signin_enabled_ = IsForceSigninEnabled(); + is_force_signin_enabled_ = signin_util::IsForceSigninEnabled(); if (!IsAuthenticated() && is_force_signin_enabled_) is_force_signin_profile_locked_ = true; } @@ -242,7 +233,10 @@ void ProfileAttributesEntry::LockForceSigninProfile(bool is_lock) { DCHECK(is_force_signin_enabled_); + if (is_force_signin_profile_locked_ == is_lock) + return; is_force_signin_profile_locked_ = is_lock; + profile_info_cache_->NotifyIsSigninRequiredChanged(profile_path_); } void ProfileAttributesEntry::SetIsEphemeral(bool value) {
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc index b789da4..fc1ef5d 100644 --- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc +++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -12,12 +12,17 @@ #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::Mock; +using ::testing::_; + namespace { // The ProfileMetadataEntry accessors aren't just plain old accessors to local // members so they'll be tested. The following helpers will make the testing @@ -132,6 +137,13 @@ content::TestBrowserThreadBundle thread_bundle_; }; +class ProfileAttributesTestObserver + : public ProfileAttributesStorage::Observer { + public: + MOCK_METHOD1(OnProfileSigninRequiredChanged, + void(const base::FilePath& profile_path)); +}; + TEST_F(ProfileAttributesStorageTest, ProfileNotFound) { EXPECT_EQ(0U, storage()->GetNumberOfProfiles()); @@ -436,3 +448,30 @@ storage()->ChooseAvatarIconIndexForNewProfile()); } } + +TEST_F(ProfileAttributesStorageTest, ProfileForceSigninLock) { + signin_util::SetForceSigninForTesting(true); + ProfileAttributesTestObserver observer; + ProfileAttributesEntry* entry; + + AddTestingProfile(); + ASSERT_TRUE(storage()->GetProfileAttributesWithPath( + GetProfilePath("testing_profile_path0"), &entry)); + storage()->AddObserver(&observer); + ASSERT_FALSE(entry->IsSigninRequired()); + + EXPECT_CALL(observer, OnProfileSigninRequiredChanged(_)).Times(0); + entry->LockForceSigninProfile(false); + ASSERT_FALSE(entry->IsSigninRequired()); + Mock::VerifyAndClear(&observer); + + EXPECT_CALL(observer, OnProfileSigninRequiredChanged(_)).Times(1); + entry->LockForceSigninProfile(true); + ASSERT_TRUE(entry->IsSigninRequired()); + Mock::VerifyAndClear(&observer); + + EXPECT_CALL(observer, OnProfileSigninRequiredChanged(_)).Times(1); + entry->SetIsSigninRequired(false); + ASSERT_FALSE(entry->IsSigninRequired()); + Mock::VerifyAndClear(&observer); +}
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc index 7249a7d..7707f2b 100644 --- a/chrome/browser/profiles/profile_info_cache.cc +++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -792,10 +792,7 @@ info->SetBoolean(kSigninRequiredKey, value); // This takes ownership of |info|. SetInfoForProfileAtIndex(index, info.release()); - - base::FilePath profile_path = GetPathOfProfileAtIndex(index); - for (auto& observer : observer_list_) - observer.OnProfileSigninRequiredChanged(profile_path); + NotifyIsSigninRequiredChanged(GetPathOfProfileAtIndex(index)); } void ProfileInfoCache::SetProfileIsEphemeralAtIndex(size_t index, bool value) { @@ -890,6 +887,12 @@ SetInfoForProfileAtIndex(index, info.release()); } +void ProfileInfoCache::NotifyIsSigninRequiredChanged( + const base::FilePath& profile_path) { + for (auto& observer : observer_list_) + observer.OnProfileSigninRequiredChanged(profile_path); +} + const base::FilePath& ProfileInfoCache::GetUserDataDir() const { return user_data_dir_; }
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h index bd700a7..08ae3ed 100644 --- a/chrome/browser/profiles/profile_info_cache.h +++ b/chrome/browser/profiles/profile_info_cache.h
@@ -152,6 +152,9 @@ void SetStatsBookmarksOfProfileAtIndex(size_t index, int value); void SetStatsSettingsOfProfileAtIndex(size_t index, int value); + // Notify IsSignedInRequired to all observer + void NotifyIsSigninRequiredChanged(const base::FilePath& profile_path); + const base::FilePath& GetUserDataDir() const; // Register cache related preferences in Local State.
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 014877c..0c4229c8 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -51,6 +51,7 @@ #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -336,6 +337,14 @@ } #endif +#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) +void SignOut(SigninManager* signin_manager) { + signin_manager->SignOut( + signin_metrics::AUTHENTICATION_FAILED_WITH_FORCE_SIGNIN, + signin_metrics::SignoutDelete::IGNORE_METRIC); +} +#endif + } // namespace ProfileManager::ProfileManager(const base::FilePath& user_data_dir) @@ -1564,8 +1573,21 @@ bool has_entry = storage.GetProfileAttributesWithPath(profile->GetPath(), &entry); if (has_entry) { +#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) + bool was_authenticated_status = entry->IsAuthenticated(); +#endif // The ProfileAttributesStorage's info must match the Signin Manager. entry->SetAuthInfo(account_info.gaia, username); +#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) + // Sign out if force-sign-in policy is enabled and profile is not signed + // in. + if (signin_util::IsForceSigninEnabled() && was_authenticated_status && + !entry->IsAuthenticated()) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SignOut, static_cast<SigninManager*>(signin_manager))); + } +#endif return; } }
diff --git a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp index af8851a..37bc620 100644 --- a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp
@@ -186,10 +186,11 @@ 'dependencies': [ '../compiled_resources2.gyp:route', '../settings_page/compiled_resources2.gyp:settings_animated_pages', - 'sync_browser_proxy', + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', + 'sync_browser_proxy', ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], },
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index b7bd67fb..f08e94f 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -32,6 +32,12 @@ margin-top: 20px; } + #existingPassphrase { + /* This particular list frame is not indented. */ + -webkit-padding-start: var(--settings-box-row-padding); + border-bottom: var(--settings-separator-line); + } + #existingPassphraseContainer, #passphraseRecoverHint { align-items: center; @@ -62,6 +68,37 @@ </div> <div id="[[pages.CONFIGURE]]" hidden$="[[!isStatus_(pages.CONFIGURE, pageStatus_)]]"> + <template is="dom-if" if="[[syncPrefs.passphraseRequired]]"> + <div id="existingPassphrase" class="list-frame"> + <div class="list-item"> + <span> + [[enterPassphrasePrompt_(syncPrefs.passphraseTypeIsCustom)]] + <a href="$i18nRaw{syncErrorHelpUrl}" target="_blank"> + $i18n{learnMore} + </a> + </span> + </div> + <div id="existingPassphraseContainer" class="list-item"> + <paper-input id="existingPassphraseInput" type="password" + value="{{existingPassphrase_}}" + placeholder="$i18n{passphrasePlaceholder}" + error-message="$i18n{incorrectPassphraseError}"> + <iron-a11y-keys id="keys" keys="enter" + on-keys-pressed="onSubmitExistingPassphraseTap_"> + </iron-a11y-keys> + </paper-input> + <paper-button id="submitExistingPassphrase" + on-tap="onSubmitExistingPassphraseTap_" class="action-button" + disabled="[[!existingPassphrase_]]"> + $i18n{submitPassphraseButton} + </paper-button> + </div> + <div id="passphraseRecoverHint" class="list-item"> + <span>$i18nRaw{passphraseRecover}</span> + </div> + </div> + </template> + <div class="settings-box first"> <div id="syncEverythingCheckboxLabel" class="start"> $i18n{syncEverythingCheckboxLabel} @@ -225,7 +262,8 @@ aria-describedby="manageSyncedDataSecondary"></button> </div> - <div class="settings-box two-line single-column"> + <div id="encryptionDescription" hidden="[[syncPrefs.passphraseRequired]]" + class="settings-box two-line single-column"> <div>$i18n{encryptionOptionsTitle}</div> <div class="secondary">$i18n{syncDataEncryptedText}</div> </div> @@ -286,37 +324,6 @@ </div> </div> </template> - - <template is="dom-if" if="[[syncPrefs.passphraseRequired]]"> - <div class="list-frame"> - <div class="list-item"> - <span> - [[enterPassphrasePrompt_(syncPrefs.passphraseTypeIsCustom)]] - <a href="$i18nRaw{syncErrorHelpUrl}" target="_blank"> - $i18n{learnMore} - </a> - </span> - </div> - <div id="existingPassphraseContainer" class="list-item"> - <paper-input id="existingPassphraseInput" type="password" - value="{{existingPassphrase_}}" - placeholder="$i18n{passphrasePlaceholder}" - error-message="$i18n{incorrectPassphraseError}"> - <iron-a11y-keys id="keys" keys="enter" - on-keys-pressed="onSubmitExistingPassphraseTap_"> - </iron-a11y-keys> - </paper-input> - <paper-button id="submitExistingPassphrase" - on-tap="onSubmitExistingPassphraseTap_" class="action-button" - disabled="[[!existingPassphrase_]]"> - $i18n{submitPassphraseButton} - </paper-button> - </div> - <div id="passphraseRecoverHint" class="list-item"> - <span>$i18nRaw{passphraseRecover}</span> - </div> - </div> - </template> </div> </template> <script src="sync_page.js"></script>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index b22155de..37d603b 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -225,6 +225,16 @@ // Hide the new passphrase box if the sync data has been encrypted. if (this.syncPrefs.encryptAllData) this.creatingNewPassphrase_ = false; + + // Focus the password input box if password is needed to start sync. + if (this.syncPrefs.passphraseRequired) { + // Async to allow the dom-if templates to render first. + this.async(function() { + var input = /** @type {!PaperInputElement} */ ( + this.$$('#existingPassphraseInput')); + input.inputElement.focus(); + }.bind(this)); + } }, /**
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chrome/browser/resources/settings/settings_menu/settings_menu.html index afc0aa9..cc6fb7c 100644 --- a/chrome/browser/resources/settings/settings_menu/settings_menu.html +++ b/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -133,8 +133,7 @@ </iron-icon></paper-button> <iron-collapse id="advancedSubmenu" opened="[[advancedOpened]]" hidden="[[!pageVisibility.advancedSettings]]"> - <iron-selector id="subMenu" selectable="a" attr-for-selected="href" - on-iron-activate="onSelectorActivate_"> + <iron-selector id="subMenu" selectable="a" attr-for-selected="href"> <if expr="chromeos"> <a href="/dateTime"> <iron-icon icon="settings:access-time"></iron-icon>
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index 3a30291d3..584775e 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -275,14 +275,20 @@ #endif } -void ChromeSigninClient::PreSignOut(const base::Callback<void()>& sign_out) { +void ChromeSigninClient::PreSignOut( + const base::Callback<void()>& sign_out, + signin_metrics::ProfileSignout signout_source_metric) { #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) if (is_force_signin_enabled_ && !profile_->IsSystemProfile() && !profile_->IsGuestSession() && !profile_->IsSupervised()) { + // TODO(zmin): force window closing based on the reason of sign-out. + // This will be updated after force window closing CL is commited. + + // User can't abort the window closing unless user sign out manually. BrowserList::CloseAllBrowsersWithProfile( profile_, base::Bind(&ChromeSigninClient::OnCloseBrowsersSuccess, - base::Unretained(this), sign_out), + base::Unretained(this), sign_out, signout_source_metric), base::Bind(&ChromeSigninClient::OnCloseBrowsersAborted, base::Unretained(this)), false); @@ -290,7 +296,7 @@ #else { #endif - SigninClient::PreSignOut(sign_out); + SigninClient::PreSignOut(sign_out, signout_source_metric); } } @@ -431,8 +437,9 @@ void ChromeSigninClient::OnCloseBrowsersSuccess( const base::Callback<void()>& sign_out, + const signin_metrics::ProfileSignout signout_source_metric, const base::FilePath& profile_path) { - SigninClient::PreSignOut(sign_out); + SigninClient::PreSignOut(sign_out, signout_source_metric); LockForceSigninProfile(profile_path); // After sign out, lock the profile and show UserManager if necessary.
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h index da0b0a22..10866bb 100644 --- a/chrome/browser/signin/chrome_signin_client.h +++ b/chrome/browser/signin/chrome_signin_client.h
@@ -73,7 +73,9 @@ void PostSignedIn(const std::string& account_id, const std::string& username, const std::string& password) override; - void PreSignOut(const base::Callback<void()>& sign_out) override; + void PreSignOut( + const base::Callback<void()>& sign_out, + signin_metrics::ProfileSignout signout_source_metric) override; // SigninErrorController::Observer implementation. void OnErrorChanged() override; @@ -105,8 +107,10 @@ private: void MaybeFetchSigninTokenHandle(); - void OnCloseBrowsersSuccess(const base::Callback<void()>& sign_out, - const base::FilePath& profile_path); + void OnCloseBrowsersSuccess( + const base::Callback<void()>& sign_out, + const signin_metrics::ProfileSignout signout_source_metric, + const base::FilePath& profile_path); void OnCloseBrowsersAborted(const base::FilePath& profile_path); Profile* profile_;
diff --git a/chrome/browser/signin/signin_util.cc b/chrome/browser/signin/signin_util.cc new file mode 100644 index 0000000..e5f50790 --- /dev/null +++ b/chrome/browser/signin/signin_util.cc
@@ -0,0 +1,41 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/signin/signin_util.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" + +namespace signin_util { +namespace { + +enum ForceSigninPolicyCache { + NOT_CACHED = 0, + ENABLE, + DISABLE +} g_is_force_signin_enabled_cache = NOT_CACHED; + +void SetForceSigninPolicy(bool enable) { + g_is_force_signin_enabled_cache = enable ? ENABLE : DISABLE; +} + +} // namespace + +bool IsForceSigninEnabled() { + if (g_is_force_signin_enabled_cache == NOT_CACHED) { + PrefService* prefs = g_browser_process->local_state(); + if (prefs) + SetForceSigninPolicy(prefs->GetBoolean(prefs::kForceBrowserSignin)); + else + return false; + } + return (g_is_force_signin_enabled_cache == ENABLE); +} + +void SetForceSigninForTesting(bool enable) { + SetForceSigninPolicy(enable); +} + +} // namespace signin_util
diff --git a/chrome/browser/signin/signin_util.h b/chrome/browser/signin/signin_util.h new file mode 100644 index 0000000..315fc63 --- /dev/null +++ b/chrome/browser/signin/signin_util.h
@@ -0,0 +1,19 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_ +#define CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_ + +namespace signin_util { + +// Return whether the force sign in policy is enabled or not. +// The state of this policy will not be changed without relaunch Chrome. +bool IsForceSigninEnabled(); + +// Enable or disable force sign in for testing. +void SetForceSigninForTesting(bool enable); + +} // namespace signin_util + +#endif // CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_
diff --git a/chrome/browser/signin/signin_util_unittest.cc b/chrome/browser/signin/signin_util_unittest.cc new file mode 100644 index 0000000..d436f78 --- /dev/null +++ b/chrome/browser/signin/signin_util_unittest.cc
@@ -0,0 +1,41 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/signin/signin_util.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/prefs/browser_prefs.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "chrome/test/base/testing_browser_process.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/testing_pref_service.h" + +class SigninUtilTest : public BrowserWithTestWindowTest { + public: + void SetUp() override { + BrowserWithTestWindowTest::SetUp(); + + prefs_.reset(new TestingPrefServiceSimple()); + } + + void TearDown() override { BrowserWithTestWindowTest::TearDown(); } + + std::unique_ptr<TestingPrefServiceSimple> prefs_; +}; + +TEST_F(SigninUtilTest, GetForceSigninPolicy) { + ASSERT_FALSE(signin_util::IsForceSigninEnabled()); + chrome::RegisterLocalState(prefs_->registry()); + TestingBrowserProcess::GetGlobal()->SetLocalState(prefs_.get()); + + g_browser_process->local_state()->SetBoolean(prefs::kForceBrowserSignin, + true); + ASSERT_TRUE(signin_util::IsForceSigninEnabled()); + g_browser_process->local_state()->SetBoolean(prefs::kForceBrowserSignin, + false); + ASSERT_TRUE(signin_util::IsForceSigninEnabled()); + + TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); +}
diff --git a/chrome/browser/signin/token_revoker_test_utils.cc b/chrome/browser/signin/token_revoker_test_utils.cc index 25add2de..a5b1967 100644 --- a/chrome/browser/signin/token_revoker_test_utils.cc +++ b/chrome/browser/signin/token_revoker_test_utils.cc
@@ -1,4 +1,4 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
diff --git a/chrome/browser/signin/token_revoker_test_utils.h b/chrome/browser/signin/token_revoker_test_utils.h index b8705c7..e60624a 100644 --- a/chrome/browser/signin/token_revoker_test_utils.h +++ b/chrome/browser/signin/token_revoker_test_utils.h
@@ -1,4 +1,4 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. +// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
diff --git a/chrome/browser/ui/app_list/arc/arc_app_launcher.cc b/chrome/browser/ui/app_list/arc/arc_app_launcher.cc index 878e244..8509703 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_launcher.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_launcher.cc
@@ -7,16 +7,21 @@ #include <memory> #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" +#include "ui/events/event_constants.h" ArcAppLauncher::ArcAppLauncher(content::BrowserContext* context, const std::string& app_id, - bool landscape_layout) - : context_(context), app_id_(app_id), landscape_layout_(landscape_layout) { + bool landscape_layout, + bool deferred_launch_allowed) + : context_(context), + app_id_(app_id), + landscape_layout_(landscape_layout), + deferred_launch_allowed_(deferred_launch_allowed) { ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context_); DCHECK(prefs); std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(app_id_); - if (app_info && app_info->ready) + if (app_info && (app_info->ready || deferred_launch_allowed_)) LaunchApp(); else prefs->AddObserver(this); @@ -34,12 +39,12 @@ void ArcAppLauncher::OnAppRegistered( const std::string& app_id, const ArcAppListPrefs::AppInfo& app_info) { - if (app_id == app_id_ && app_info.ready) + if (app_id == app_id_ && (app_info.ready || deferred_launch_allowed_)) LaunchApp(); } void ArcAppLauncher::OnAppReadyChanged(const std::string& app_id, bool ready) { - if (app_id == app_id_ && ready) + if (app_id == app_id_ && (ready || deferred_launch_allowed_)) LaunchApp(); } @@ -50,7 +55,7 @@ DCHECK(prefs && prefs->GetApp(app_id_)); prefs->RemoveObserver(this); - if (!arc::LaunchApp(context_, app_id_, landscape_layout_)) + if (!arc::LaunchApp(context_, app_id_, landscape_layout_, ui::EF_NONE)) VLOG(2) << "Failed to launch app: " + app_id_ + "."; app_launched_ = true;
diff --git a/chrome/browser/ui/app_list/arc/arc_app_launcher.h b/chrome/browser/ui/app_list/arc/arc_app_launcher.h index 613ad2bd..3043ff0c 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_launcher.h +++ b/chrome/browser/ui/app_list/arc/arc_app_launcher.h
@@ -20,7 +20,8 @@ public: ArcAppLauncher(content::BrowserContext* context, const std::string& app_id, - bool landscape_layout); + bool landscape_layout, + bool deferred_launch_allowed); ~ArcAppLauncher() override; bool app_launched() const { return app_launched_; } @@ -38,7 +39,11 @@ // ARC app id and requested layout. const std::string app_id_; const bool landscape_layout_; - // Flag idicating that ARC app was launched. + // If it is set to true that means app is allowed to launch in deferred mode + // once it is registered, regardless it is ready or not. Otherwise app is + // launched when it becomes ready. + const bool deferred_launch_allowed_; + // Flag indicating that ARC app was launched. bool app_launched_ = false; DISALLOW_COPY_AND_ASSIGN(ArcAppLauncher);
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index 294e5ed..7f0bb0b 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -854,7 +854,7 @@ } else { AppInfo app_info(updated_name, package_name, activity, intent_uri, icon_resource_id, base::Time(), GetInstallTime(app_id), - sticky, notifications_enabled, true, + sticky, notifications_enabled, app_ready, launchable && arc::ShouldShowInLauncher(app_id), shortcut, launchable, orientation_lock); for (auto& observer : observer_list_)
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc index 94ad8c2..8fb88d3a 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_test.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -97,9 +97,8 @@ arc_app_list_pref_ = ArcAppListPrefs::Get(profile_); DCHECK(arc_app_list_pref_); - base::RunLoop run_loop; - arc_app_list_pref_->SetDefaltAppsReadyCallback(run_loop.QuitClosure()); - run_loop.Run(); + if (wait_default_apps_) + WaitForDefaultApps(); // Check initial conditions. if (arc::ShouldArcAlwaysStart()) { @@ -115,6 +114,13 @@ app_instance_.get()); } +void ArcAppTest::WaitForDefaultApps() { + DCHECK(arc_app_list_pref_); + base::RunLoop run_loop; + arc_app_list_pref_->SetDefaltAppsReadyCallback(run_loop.QuitClosure()); + run_loop.Run(); +} + void ArcAppTest::CreateFakeAppsAndPackages() { arc::mojom::AppInfo app; // Make sure we have enough data for test.
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.h b/chrome/browser/ui/app_list/arc/arc_app_test.h index 8163acd..db1fa73 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_test.h +++ b/chrome/browser/ui/app_list/arc/arc_app_test.h
@@ -59,6 +59,8 @@ void RemovePackage(const arc::mojom::ArcPackageInfo& package); + void WaitForDefaultApps(); + // The 0th item is sticky but not the followings. const std::vector<arc::mojom::AppInfo>& fake_apps() const { return fake_apps_; @@ -85,6 +87,10 @@ return arc_service_manager_.get(); } + void set_wait_default_apps(bool wait_default_apps) { + wait_default_apps_ = wait_default_apps; + } + private: const user_manager::User* CreateUserAndLogin(); bool FindPackage(const arc::mojom::ArcPackageInfo& package); @@ -95,6 +101,8 @@ ArcAppListPrefs* arc_app_list_pref_ = nullptr; + bool wait_default_apps_ = true; + std::unique_ptr<arc::ArcServiceManager> arc_service_manager_; std::unique_ptr<arc::ArcSessionManager> arc_session_manager_; std::unique_ptr<arc::ArcPlayStoreEnabledPreferenceHandler>
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc index 4b35b2d..86d4af1 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -433,14 +433,31 @@ // ArcAppModelBuilderTest: void OnBeforeArcTestSetup() override { ArcDefaultAppList::UseTestAppsDirectory(); + arc_test()->set_wait_default_apps(IsWaitDefaultAppsNeeded()); arc::ArcPackageSyncableServiceFactory::GetInstance()->SetTestingFactory( profile_.get(), nullptr); } + // Returns true if test needs to wait for default apps on setup. + virtual bool IsWaitDefaultAppsNeeded() const { return true; } + private: DISALLOW_COPY_AND_ASSIGN(ArcDefaulAppTest); }; +class ArcAppLauncherForDefaulAppTest : public ArcDefaulAppTest { + public: + ArcAppLauncherForDefaulAppTest() = default; + ~ArcAppLauncherForDefaulAppTest() override = default; + + protected: + // ArcDefaulAppTest: + bool IsWaitDefaultAppsNeeded() const override { return false; } + + private: + DISALLOW_COPY_AND_ASSIGN(ArcAppLauncherForDefaulAppTest); +}; + class ArcPlayStoreAppTest : public ArcDefaulAppTest { public: ArcPlayStoreAppTest() = default; @@ -1271,11 +1288,11 @@ const std::string id2 = ArcAppTest::GetAppId(app2); const std::string id3 = ArcAppTest::GetAppId(app3); - ArcAppLauncher launcher1(profile(), id1, true); + ArcAppLauncher launcher1(profile(), id1, true, false); EXPECT_FALSE(launcher1.app_launched()); EXPECT_TRUE(prefs->HasObserver(&launcher1)); - ArcAppLauncher launcher3(profile(), id3, true); + ArcAppLauncher launcher3(profile(), id3, true, false); EXPECT_FALSE(launcher1.app_launched()); EXPECT_TRUE(prefs->HasObserver(&launcher1)); EXPECT_FALSE(launcher3.app_launched()); @@ -1294,7 +1311,7 @@ EXPECT_FALSE(prefs->HasObserver(&launcher1)); EXPECT_TRUE(prefs->HasObserver(&launcher3)); - ArcAppLauncher launcher2(profile(), id2, true); + ArcAppLauncher launcher2(profile(), id2, true, false); EXPECT_TRUE(launcher2.app_launched()); EXPECT_FALSE(prefs->HasObserver(&launcher2)); ASSERT_EQ(2u, app_instance()->launch_requests().size()); @@ -1439,6 +1456,37 @@ } } +TEST_P(ArcAppLauncherForDefaulAppTest, AppLauncherForDefaultApps) { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); + ASSERT_NE(nullptr, prefs); + + ASSERT_GE(fake_default_apps().size(), 2U); + const arc::mojom::AppInfo& app1 = fake_default_apps()[0]; + const arc::mojom::AppInfo& app2 = fake_default_apps()[1]; + const std::string id1 = ArcAppTest::GetAppId(app1); + const std::string id2 = ArcAppTest::GetAppId(app2); + + // Launch when app is registered and ready. + ArcAppLauncher launcher1(profile(), id1, true, false); + // Launch when app is registered. + ArcAppLauncher launcher2(profile(), id2, true, true); + + EXPECT_FALSE(launcher1.app_launched()); + EXPECT_FALSE(launcher2.app_launched()); + + arc_test()->WaitForDefaultApps(); + + // Only second app is expected to be launched. + EXPECT_FALSE(launcher1.app_launched()); + EXPECT_TRUE(launcher2.app_launched()); + + app_instance()->RefreshAppList(); + app_instance()->SendRefreshAppList(fake_default_apps()); + // Default apps are ready now and it is expected that first app was launched + // now. + EXPECT_TRUE(launcher1.app_launched()); +} + TEST_P(ArcDefaulAppTest, DefaultAppsNotAvailable) { ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); ASSERT_NE(nullptr, prefs); @@ -1528,6 +1576,9 @@ ArcDefaulAppTest, ::testing::ValuesIn(kUnmanagedArcStates)); INSTANTIATE_TEST_CASE_P(, + ArcAppLauncherForDefaulAppTest, + ::testing::ValuesIn(kUnmanagedArcStates)); +INSTANTIATE_TEST_CASE_P(, ArcDefaulAppForManagedUserTest, ::testing::ValuesIn(kManagedArcStates)); INSTANTIATE_TEST_CASE_P(,
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.h b/chrome/browser/ui/app_list/arc/arc_app_utils.h index e091173..8c75cb96 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_utils.h +++ b/chrome/browser/ui/app_list/arc/arc_app_utils.h
@@ -43,6 +43,8 @@ // Launch an app with given layout and let the system decides how big and where // to place it. +// TODO (khmel) replace bool for |landscape_layout| with enum class in order +// to prevent using another LaunchApp with different signature mistakenly. bool LaunchApp(content::BrowserContext* context, const std::string& app_id, bool landscape_layout,
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc b/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc index 465c770..45a009f 100644 --- a/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc +++ b/chrome/browser/ui/ash/chrome_screenshot_grabber_unittest.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" -#include "ash/common/accelerators/accelerator_controller.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/bind.h"
diff --git a/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.cc index 9f445f5..cfc048a 100644 --- a/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.cc
@@ -6,11 +6,11 @@ #include "base/memory/ptr_util.h" #include "chrome/browser/chromeos/arc/arc_support_host.h" -#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ui/app_list/arc/arc_app_launcher.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "ui/events/event_constants.h" ArcPlaystoreShortcutLauncherItemController:: ArcPlaystoreShortcutLauncherItemController( @@ -27,15 +27,8 @@ int64_t display_id, ash::ShelfLaunchSource source, const ItemSelectedCallback& callback) { - Profile* profile = controller()->profile(); - ArcAppListPrefs* arc_app_prefs = ArcAppListPrefs::Get(profile); - DCHECK(arc_app_prefs); - - // Play Store should always be registered and arc::LaunchApp can handle all - // cases. - DCHECK(arc_app_prefs->IsRegistered(arc::kPlayStoreAppId)); - arc::LaunchApp(profile, arc::kPlayStoreAppId, true); - + playstore_launcher_ = base::MakeUnique<ArcAppLauncher>( + controller()->profile(), arc::kPlayStoreAppId, true, true); callback.Run(ash::SHELF_ACTION_NONE, GetAppMenuItems(event ? event->flags() : ui::EF_NONE)); }
diff --git a/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.h b/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.h index ce1ad68a..84322f0 100644 --- a/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.h +++ b/chrome/browser/ui/ash/launcher/arc_playstore_shortcut_launcher_item_controller.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h" +class ArcAppLauncher; class ChromeLauncherController; class ArcPlaystoreShortcutLauncherItemController @@ -26,6 +27,8 @@ const ItemSelectedCallback& callback) override; private: + std::unique_ptr<ArcAppLauncher> playstore_launcher_; + DISALLOW_COPY_AND_ASSIGN(ArcPlaystoreShortcutLauncherItemController); };
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index 647ac32..525b426 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -129,8 +129,10 @@ const std::string autofill_card_type = autofill::data_util::GetCardTypeForBasicCardPaymentType( supported_network); - std::unique_ptr<views::ImageView> card_icon_view = - CreateCardIconView(autofill_card_type); + std::unique_ptr<views::ImageView> card_icon_view = CreateInstrumentIconView( + autofill::data_util::GetPaymentRequestData(autofill_card_type) + .icon_resource_id, + base::UTF8ToUTF16(supported_network)); card_icon_view->SetImageSize(kCardIconSize); icons_row->AddChildView(card_icon_view.release());
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.cc b/chrome/browser/ui/views/payments/payment_method_view_controller.cc index 1cf6cc90..b8a73452 100644 --- a/chrome/browser/ui/views/payments/payment_method_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
@@ -14,9 +14,8 @@ #include "chrome/browser/ui/views/payments/payment_request_row_view.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" -#include "components/autofill/core/browser/autofill_type.h" -#include "components/autofill/core/browser/credit_card.h" #include "components/payments/content/payment_request_state.h" +#include "components/payments/core/payment_instrument.h" #include "components/strings/grit/components_strings.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" @@ -42,16 +41,16 @@ class PaymentMethodListItem : public payments::PaymentRequestItemList::Item { public: - // Does not take ownership of |card|, which should not be null and should - // outlive this object. |list| is the PaymentRequestItemList object that will - // own this. - PaymentMethodListItem(autofill::CreditCard* card, + // Does not take ownership of |instrument|, which should not be null and + // should outlive this object. |list| is the PaymentRequestItemList object + // that will own this. + PaymentMethodListItem(PaymentInstrument* instrument, PaymentRequestSpec* spec, PaymentRequestState* state, PaymentRequestItemList* list, bool selected) : payments::PaymentRequestItemList::Item(spec, state, list, selected), - card_(card) {} + instrument_(instrument) {} ~PaymentMethodListItem() override {} private: @@ -100,11 +99,9 @@ views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); card_info_container->SetLayoutManager(box_layout.release()); + card_info_container->AddChildView(new views::Label(instrument_->label())); card_info_container->AddChildView( - new views::Label(card_->TypeAndLastFourDigits())); - card_info_container->AddChildView(new views::Label( - card_->GetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), - g_browser_process->GetApplicationLocale()))); + new views::Label(instrument_->sublabel())); // TODO(anthonyvd): Add the "card is incomplete" label once the // completedness logic is implemented. layout->AddView(card_info_container.release()); @@ -112,8 +109,8 @@ checkmark_ = CreateCheckmark(selected()); layout->AddView(checkmark_.get()); - std::unique_ptr<views::ImageView> card_icon_view = - CreateCardIconView(card_->type()); + std::unique_ptr<views::ImageView> card_icon_view = CreateInstrumentIconView( + instrument_->icon_resource_id(), instrument_->label()); card_icon_view->SetImageSize(gfx::Size(32, 20)); layout->AddView(card_icon_view.release()); @@ -126,7 +123,7 @@ if (checkmark_) checkmark_->SetVisible(selected()); - state()->SetSelectedCreditCard(card_); + state()->SetSelectedInstrument(instrument_); } // views::ButtonListener: @@ -145,7 +142,7 @@ return true; } - autofill::CreditCard* card_; + PaymentInstrument* instrument_; std::unique_ptr<views::ImageView> checkmark_; DISALLOW_COPY_AND_ASSIGN(PaymentMethodListItem); @@ -158,14 +155,15 @@ PaymentRequestState* state, PaymentRequestDialogView* dialog) : PaymentRequestSheetController(spec, state, dialog) { - const std::vector<autofill::CreditCard*>& available_cards = - state->credit_cards(); + const std::vector<std::unique_ptr<PaymentInstrument>>& available_instruments = + state->available_instruments(); - for (autofill::CreditCard* card : available_cards) { + for (const std::unique_ptr<PaymentInstrument>& instrument : + available_instruments) { std::unique_ptr<PaymentMethodListItem> item = base::MakeUnique<PaymentMethodListItem>( - card, spec, state, &payment_method_list_, - card == state->selected_credit_card()); + instrument.get(), spec, state, &payment_method_list_, + instrument.get() == state->selected_instrument()); payment_method_list_.AddItem(std::move(item)); } }
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc index 4cd3feb..d1beb30 100644 --- a/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "components/autofill/core/browser/autofill_test_utils.h" @@ -39,15 +40,16 @@ InvokePaymentRequestUI(); OpenPaymentMethodScreen(); - PaymentRequest* request = GetPaymentRequests(GetActiveWebContents())[0]; - EXPECT_EQ(1U, request->state()->credit_cards().size()); + PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); + EXPECT_EQ(1U, request->state()->available_instruments().size()); views::View* list_view = dialog_view()->GetViewByID( static_cast<int>(DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW)); EXPECT_TRUE(list_view); EXPECT_EQ(1, list_view->child_count()); - EXPECT_EQ(card, *request->state()->selected_credit_card()); + EXPECT_EQ(request->state()->available_instruments().front().get(), + request->state()->selected_instrument()); views::View* checkmark_view = list_view->child_at(0)->GetViewByID( static_cast<int>(DialogViewID::CHECKMARK_VIEW)); EXPECT_TRUE(checkmark_view->visible()); @@ -60,23 +62,27 @@ card1.set_use_count(5U); AddCreditCard(card1); - autofill::CreditCard card2 = autofill::test::GetCreditCard2(); + // Slightly different visa. + autofill::CreditCard card2 = autofill::test::GetCreditCard(); + card2.SetNumber(base::ASCIIToUTF16("4111111111111112")); card2.set_use_count(1U); AddCreditCard(card2); InvokePaymentRequestUI(); OpenPaymentMethodScreen(); - PaymentRequest* request = GetPaymentRequests(GetActiveWebContents())[0]; - EXPECT_EQ(2U, request->state()->credit_cards().size()); - EXPECT_EQ(card1, *request->state()->selected_credit_card()); + PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); + EXPECT_EQ(2U, request->state()->available_instruments().size()); + EXPECT_EQ(request->state()->available_instruments().front().get(), + request->state()->selected_instrument()); views::View* list_view = dialog_view()->GetViewByID( static_cast<int>(DialogViewID::PAYMENT_METHOD_SHEET_LIST_VIEW)); EXPECT_TRUE(list_view); EXPECT_EQ(2, list_view->child_count()); - EXPECT_EQ(card1, *request->state()->selected_credit_card()); + EXPECT_EQ(request->state()->available_instruments().front().get(), + request->state()->selected_instrument()); views::View* checkmark_view = list_view->child_at(0)->GetViewByID( static_cast<int>(DialogViewID::CHECKMARK_VIEW)); EXPECT_TRUE(checkmark_view->visible()); @@ -88,14 +94,16 @@ // Simulate selecting the second card. ClickOnDialogViewAndWait(list_view->child_at(1)); - EXPECT_EQ(card2, *request->state()->selected_credit_card()); + EXPECT_EQ(request->state()->available_instruments().back().get(), + request->state()->selected_instrument()); EXPECT_FALSE(checkmark_view->visible()); EXPECT_TRUE(checkmark_view2->visible()); // Clicking on the second card again should not modify any state. ClickOnDialogViewAndWait(list_view->child_at(1)); - EXPECT_EQ(card2, *request->state()->selected_credit_card()); + EXPECT_EQ(request->state()->available_instruments().back().get(), + request->state()->selected_instrument()); EXPECT_FALSE(checkmark_view->visible()); EXPECT_TRUE(checkmark_view2->visible()); }
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 4e3a9b4..1b8cb04 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -170,18 +170,16 @@ return container; } -std::unique_ptr<views::ImageView> CreateCardIconView( - const std::string& card_type) { +std::unique_ptr<views::ImageView> CreateInstrumentIconView( + int icon_resource_id, + const base::string16& tooltip_text) { std::unique_ptr<views::ImageView> card_icon_view = base::MakeUnique<views::ImageView>(); card_icon_view->set_can_process_events_within_subtree(false); - card_icon_view->SetImage( - ResourceBundle::GetSharedInstance() - .GetImageNamed(autofill::data_util::GetPaymentRequestData(card_type) - .icon_resource_id) - .AsImageSkia()); - card_icon_view->SetTooltipText( - autofill::CreditCard::TypeForDisplay(card_type)); + card_icon_view->SetImage(ResourceBundle::GetSharedInstance() + .GetImageNamed(icon_resource_id) + .AsImageSkia()); + card_icon_view->SetTooltipText(tooltip_text); card_icon_view->SetBorder(views::CreateRoundedRectBorder( 1, 3, card_icon_view->GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_UnfocusedBorderColor)));
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h index 69aad15..be1882b 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.h +++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -55,10 +55,12 @@ const base::string16& title, views::VectorIconButtonDelegate* delegate); -// Returns a card image view for the given |card_type|. Includes a rounded rect -// border. Callers need to set the size of the resulting ImageView. -std::unique_ptr<views::ImageView> CreateCardIconView( - const std::string& card_type); +// Returns an instrument image view for the given |icon_resource_id|. Includes +// a rounded rect border. Callers need to set the size of the resulting +// ImageView. Callers should set a |tooltip_text|. +std::unique_ptr<views::ImageView> CreateInstrumentIconView( + int icon_resource_id, + const base::string16& tooltip_text); // Represents formatting options for each of the different contexts in which an // Address label may be displayed.
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index fbb6a8d..a2cf94c 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -23,13 +23,12 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" -#include "components/autofill/core/browser/autofill_type.h" -#include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/payments/content/payment_request_spec.h" #include "components/payments/content/payment_request_state.h" #include "components/payments/core/currency_formatter.h" +#include "components/payments/core/payment_instrument.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" @@ -438,11 +437,11 @@ // +----------------------------------------------+ std::unique_ptr<views::Button> PaymentSheetViewController::CreatePaymentMethodRow() { - autofill::CreditCard* selected_card = state()->selected_credit_card(); + PaymentInstrument* selected_instrument = state()->selected_instrument(); std::unique_ptr<views::View> content_view; std::unique_ptr<views::ImageView> card_icon_view; - if (selected_card) { + if (selected_instrument) { content_view = base::MakeUnique<views::View>(); views::GridLayout* layout = new views::GridLayout(content_view.get()); @@ -452,14 +451,12 @@ 1, views::GridLayout::USE_PREF, 0, 0); layout->StartRow(0, 0); - layout->AddView(new views::Label(selected_card->TypeAndLastFourDigits())); + layout->AddView(new views::Label(selected_instrument->label())); layout->StartRow(0, 0); - layout->AddView(new views::Label( - selected_card->GetInfo( - autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), - g_browser_process->GetApplicationLocale()))); + layout->AddView(new views::Label(selected_instrument->sublabel())); - card_icon_view = CreateCardIconView(selected_card->type()); + card_icon_view = CreateInstrumentIconView( + selected_instrument->icon_resource_id(), selected_instrument->label()); card_icon_view->SetImageSize(gfx::Size(32, 20)); }
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 539491f..bc057b4 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -181,15 +181,13 @@ BackgroundColorHoverButton(ProfileChooserView* profile_chooser_view, const base::string16& text) : views::LabelButton(profile_chooser_view, text), -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - profile_chooser_view_(profile_chooser_view), -#endif title_(nullptr), subtitle_(nullptr) { DCHECK(profile_chooser_view); SetImageLabelSpacing(kMenuEdgeMargin - 2); SetBorder(views::CreateEmptyBorder(0, kMenuEdgeMargin, 0, kMenuEdgeMargin)); SetFocusForPlatform(); + SetFocusPainter(nullptr); label()->SetHandlesTooltips(false); } @@ -217,73 +215,64 @@ private: // views::View: - void OnNativeThemeChanged(const ui::NativeTheme* theme) override { - // The first time the theme changes, the state will not be hovered - // or pressed and the colors will be initialized. It's okay to - // reset the colors when the theme changes and the button is NOT - // hovered or pressed because the labels will be in a normal state. - if (state() == STATE_HOVERED || state() == STATE_PRESSED) - return; + void OnFocus() override { + LabelButton::OnFocus(); + UpdateColors(); + } + void OnBlur() override { + LabelButton::OnBlur(); + UpdateColors(); + } + + void OnNativeThemeChanged(const ui::NativeTheme* theme) override { LabelButton::OnNativeThemeChanged(theme); - views::Label* title = title_ ? title_ : label(); - normal_title_color_ = title->enabled_color(); - if (subtitle_) - normal_subtitle_color_ = subtitle_->disabled_color(); + UpdateColors(); } // views::CustomButton: void StateChanged(ButtonState old_state) override { LabelButton::StateChanged(old_state); - auto set_title_color = [&](SkColor color) { - if (title_) - title_->SetEnabledColor(color); - else - SetEnabledTextColors(color); - }; + // As in a menu, focus follows the mouse (including blurring when the mouse + // leaves the button). If we don't do this, the focused view and the hovered + // view might both have the selection highlight. + if (state() == STATE_HOVERED || state() == STATE_PRESSED) + RequestFocus(); + else if (state() == STATE_NORMAL && HasFocus()) + GetFocusManager()->SetFocusedView(nullptr); - bool was_prelight = - old_state == STATE_HOVERED || old_state == STATE_PRESSED; - bool is_prelight = state() == STATE_HOVERED || state() == STATE_PRESSED; - if (was_prelight && !is_prelight) { - // The pointer is no longer over this button. Set the - // background and text colors back to their normal states. - set_background(nullptr); - set_title_color(normal_title_color_); - if (subtitle_) - subtitle_->SetDisabledColor(normal_subtitle_color_); - } else if (!was_prelight && is_prelight) { - // The pointer moved over this button. Set the background and - // text colors back to their hovered states. - SkColor bg_color = profiles::kHoverColor; -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - if (ThemeServiceFactory::GetForProfile( - profile_chooser_view_->browser()->profile()) - ->UsingSystemTheme()) { - // When using the system (GTK) theme, use the selected menuitem colors. - bg_color = GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor); - SkColor text_color = GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor); - set_title_color(text_color); - if (subtitle_) - subtitle_->SetDisabledColor(text_color); - } -#endif - set_background(views::Background::CreateSolidBackground(bg_color)); + UpdateColors(); + } + + void UpdateColors() { + bool is_selected = HasFocus(); + + set_background( + is_selected + ? views::Background::CreateSolidBackground( + GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor)) + : nullptr); + + SkColor text_color = GetNativeTheme()->GetSystemColor( + is_selected ? ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor + : ui::NativeTheme::kColorId_LabelEnabledColor); + SetEnabledTextColors(text_color); + if (title_) + title_->SetEnabledColor(text_color); + + if (subtitle_) { + DCHECK(!subtitle_->enabled()); + subtitle_->SetDisabledColor(GetNativeTheme()->GetSystemColor( + is_selected + ? ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor + : ui::NativeTheme::kColorId_LabelDisabledColor)); } } -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - ProfileChooserView* profile_chooser_view_; -#endif - views::Label* title_; - SkColor normal_title_color_; - views::Label* subtitle_; - SkColor normal_subtitle_color_; DISALLOW_COPY_AND_ASSIGN(BackgroundColorHoverButton); };
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc index 142e598..6698269 100644 --- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc +++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/signin/local_auth.h" +#include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/app_list/app_list_service.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" @@ -1010,12 +1011,16 @@ // Unlock the profile after browser opens so startup can read the lock bit. // Any necessary authentication must have been successful to reach this point. + ProfileAttributesEntry* entry = nullptr; if (!browser->profile()->IsGuestSession()) { - ProfileAttributesEntry* entry = nullptr; bool has_entry = g_browser_process->profile_manager()-> GetProfileAttributesStorage(). GetProfileAttributesWithPath(browser->profile()->GetPath(), &entry); DCHECK(has_entry); + // If force sign in is enabled and profile is not signed in, do not close + // UserManager and unlock profile. + if (signin_util::IsForceSigninEnabled() && !entry->IsAuthenticated()) + return; entry->SetIsSigninRequired(false); }
diff --git a/chrome/common/extensions/api/BUILD.gn b/chrome/common/extensions/api/BUILD.gn index 031fea79..fb51030 100644 --- a/chrome/common/extensions/api/BUILD.gn +++ b/chrome/common/extensions/api/BUILD.gn
@@ -89,6 +89,11 @@ if (!is_android) { schema_sources += [ "processes.idl" ] } + +if (is_chromeos || is_mac || is_win) { + schema_sources += [ "networking_cast_private.idl" ] +} + if (is_chromeos) { schema_sources += [ "certificate_provider.idl",
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 1b53499c..858a45d 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -612,6 +612,11 @@ "dependencies": ["permission:musicManagerPrivate"], "contexts": ["blessed_extension"] }, + "networking.castPrivate": { + "channel": "stable", + "contexts": ["blessed_extension"], + "dependencies": ["permission:networking.castPrivate"] + }, "notifications": { "dependencies": ["permission:notifications"], "contexts": ["blessed_extension"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index d2eca346..86d2d69 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -507,6 +507,19 @@ "channel": "stable", "extension_types": ["extension", "platform_app"] }, + "networking.castPrivate": { + "channel": "stable", + "extension_types": ["extension", "platform_app"], + "platforms": ["chromeos", "mac", "win"], + "whitelist": [ + "63ED55E43214C211F82122ED56407FF1A807F2A3", // http://crbug.com/588179 + "FA01E0B81978950F2BC5A50512FD769725F57510", // http://crbug.com/588179 + "B11A93E7E5B541F8010245EBDE2C74647D6C14B9", // http://crbug.com/588179 + "F155646B5D1CA545F7E1E4E20D573DFDD44C2540", // http://crbug.com/588179 + "16CA7A47AAE4BE49B1E75A6B960C3875E945B264", // http://crbug.com/588179 + "226CF815E39A363090A1E547D53063472B8279FA" // http://crbug.com/588179 + ] + }, "management": [ { "channel": "stable",
diff --git a/chrome/common/extensions/api/networking_cast_private.idl b/chrome/common/extensions/api/networking_cast_private.idl new file mode 100644 index 0000000..cc4335cd --- /dev/null +++ b/chrome/common/extensions/api/networking_cast_private.idl
@@ -0,0 +1,109 @@ +// 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. + +// The networking.castPrivate API is a private API that exposes networking +// utilities needed by cast extension and setup app. +[nodoc] namespace networking.castPrivate { + enum TDLSStatus { + // TDLS is connected. + CONNECTED, + // TDLS is not supported. + NONEXISTENT, + // TDLS is supported, but disabled. + DISABLED, + // TDLS is enabled, but not connected + DISCONNECTED, + // TDLS status is not yet determined. + UNKNOWN + }; + + dictionary VerificationProperties { + // A string containing a PEM-encoded (including the 'BEGIN CERTIFICATE' + // header and 'END CERTIFICATE' footer) X.509 certificate for use in + // verifying the signed data. + DOMString certificate; + + // An array of PEM-encoded X.509 intermediate certificate authority + // certificates. Each PEM-encoded certificate is expected to have the + // 'BEGIN CERTIFICATE' header and 'END CERTIFICATE' footer. + DOMString[]? intermediateCertificates; + + // A string containing a base64-encoded RSAPublicKey ASN.1 structure, + // representing the public key to be used by + // $(ref:verifyAndEncryptCredentials) and $(ref:verifyAndEncryptData) + // methods. + DOMString publicKey; + + // A string containing a base64-encoded random binary data for use in + // verifying the signed data. + DOMString nonce; + + // A string containing the identifying data string signed by the device. + DOMString signedData; + + // A string containing the serial number of the device. + DOMString deviceSerial; + + // A string containing the SSID of the device. Should be empty for new + // configurations. + DOMString deviceSsid; + + // A string containing the BSSID of the device. Should be empty for new + // configurations. + DOMString deviceBssid; + }; + + callback BooleanCallback = void(boolean result); + callback StringCallback = void(DOMString result); + callback TDLSStatusCallback = void(TDLSStatus status); + + interface Functions { + // Verifies that the device is a trusted device. + // |properties|: Properties of the destination to use in verifying that it + // is a trusted device. + // |callback|: A callback function that indicates whether or not the device + // is a trusted device. + static void verifyDestination(VerificationProperties properties, + BooleanCallback callback); + + // Verifies that the device is a trusted device and retrieves encrypted + // network credentials. + // |properties|: Properties of the destination to use in verifying that it + // is a trusted device. + // |networkGuid|: The GUID of the Cellular network to activate. + // |callback|: A callback function that receives base64-encoded encrypted + // credential data to send to a trusted device. + static void verifyAndEncryptCredentials(VerificationProperties properties, + DOMString networkGuid, + StringCallback callback); + + // Verifies that the device is a trusted device and encrypts supplied + // data with device public key. + // |properties|: Properties of the destination to use in verifying that it + // is a trusted device. + // |data|: A string containing the base64-encoded data to encrypt. + // |callback|: A callback function that receives base64-encoded encrypted + // data to send to a trusted device. + static void verifyAndEncryptData(VerificationProperties properties, + DOMString data, + StringCallback callback); + + // Enables TDLS for WiFi traffic with a specified peer if available. + // |ip_or_mac_address|: The IP or MAC address of the peer with which to + // enable a TDLS connection. + // |enabled|: If true, enable TDLS, otherwise disable TDLS. + // |callback|: A callback function that receives a string with an error or + // the current TDLS status. + static void setWifiTDLSEnabledState(DOMString ip_or_mac_address, + boolean enabled, + optional TDLSStatusCallback callback); + + // Returns the current TDLS status for the specified peer. + // |ip_or_mac_address|: The IP or MAC address of the peer. + // |callback|: A callback function that receives a string with the current + // TDLS status. + static void getWifiTDLSStatus(DOMString ip_or_mac_address, + TDLSStatusCallback callback); + }; +};
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index fa08cada..3d361a7 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -139,6 +139,7 @@ APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kMusicManagerPrivate, "musicManagerPrivate", APIPermissionInfo::kFlagCannotBeOptional}, + {APIPermission::kNetworkingCastPrivate, "networking.castPrivate"}, {APIPermission::kPreferencesPrivate, "preferencesPrivate", APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kSystemPrivate, "systemPrivate",
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc index 7e3d40d..fcba6a74 100644 --- a/chrome/common/extensions/permissions/permission_set_unittest.cc +++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -838,6 +838,7 @@ skip.insert(APIPermission::kMediaPlayerPrivate); skip.insert(APIPermission::kMediaRouterPrivate); skip.insert(APIPermission::kMetricsPrivate); + skip.insert(APIPermission::kNetworkingCastPrivate); skip.insert(APIPermission::kPreferencesPrivate); skip.insert(APIPermission::kImageWriterPrivate); skip.insert(APIPermission::kResourcesPrivate);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9719d1d3..ff00205 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2603,6 +2603,9 @@ "../browser/profiles/profile_statistics_browsertest.cc", ] } + if (is_mac || is_win || is_chromeos) { + sources += [ "../browser/extensions/api/networking_cast_private/networking_cast_private_apitest.cc" ] + } if (enable_app_list) { sources += [ "../browser/apps/drive/drive_app_converter_browsertest.cc", @@ -4792,6 +4795,7 @@ "../browser/media/webrtc/native_desktop_media_list_unittest.cc", "../browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc", "../browser/signin/signin_global_error_unittest.cc", + "../browser/signin/signin_util_unittest.cc", "../browser/ui/webui/signin/signin_create_profile_handler_unittest.cc", "../browser/ui/webui/signin/sync_confirmation_handler_unittest.cc", "../browser/upgrade_detector_impl_unittest.cc",
diff --git a/chrome/test/chromedriver/performance_logger.cc b/chrome/test/chromedriver/performance_logger.cc index 5887650e..d7f61c54 100644 --- a/chrome/test/chromedriver/performance_logger.cc +++ b/chrome/test/chromedriver/performance_logger.cc
@@ -199,7 +199,7 @@ // 'value' will be between 0-1 and represents how full the DevTools trace // buffer is. If the buffer is full, warn the user. double buffer_usage = 0; - if (!params.GetDouble("value", &buffer_usage)) { + if (!params.GetDouble("percentFull", &buffer_usage)) { // Tracing.bufferUsage event will occur once per second, and it really // only serves as a warning, so if we can't reliably tell whether the // buffer is full, just fail silently instead of spamming the logs.
diff --git a/chrome/test/chromedriver/performance_logger_unittest.cc b/chrome/test/chromedriver/performance_logger_unittest.cc index 0c906ec9..68168622 100644 --- a/chrome/test/chromedriver/performance_logger_unittest.cc +++ b/chrome/test/chromedriver/performance_logger_unittest.cc
@@ -380,7 +380,7 @@ client.AddListener(&logger); logger.OnConnected(&client); base::DictionaryValue params; - params.SetDouble("value", 1.0); + params.SetDouble("percentFull", 1.0); ASSERT_EQ(kOk, client.TriggerEvent("Tracing.bufferUsage", params).code()); ASSERT_EQ(1u, log.GetEntries().size());
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index cd41f3e..4d4b5ea7 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -94,6 +94,8 @@ _OS_SPECIFIC_FILTER['win'] = [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=299 'ChromeLogPathCapabilityTest.testChromeLogPath', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1712 + 'ChromeDownloadDirTest.*', ] _OS_SPECIFIC_FILTER['linux'] = [ # Xvfb doesn't support maximization.
diff --git a/chrome/test/data/android/webvr_instrumentation/html/test_nfc_fires_onvrdisplayactivate.html b/chrome/test/data/android/webvr_instrumentation/html/test_nfc_fires_vrdisplayactivate.html similarity index 96% rename from chrome/test/data/android/webvr_instrumentation/html/test_nfc_fires_onvrdisplayactivate.html rename to chrome/test/data/android/webvr_instrumentation/html/test_nfc_fires_vrdisplayactivate.html index 4afac65..9a9f21a 100644 --- a/chrome/test/data/android/webvr_instrumentation/html/test_nfc_fires_onvrdisplayactivate.html +++ b/chrome/test/data/android/webvr_instrumentation/html/test_nfc_fires_vrdisplayactivate.html
@@ -1,7 +1,7 @@ <!doctype html> <!-- Tests that scanning the Daydream View NFC tag on supported devices fires the -ondisplayactivate event +vrdisplayactivate event --> <html> <head>
diff --git a/chrome/test/data/android/webvr_instrumentation/html/test_requestPresent_enters_vr.html b/chrome/test/data/android/webvr_instrumentation/html/test_requestPresent_enters_vr.html index 059ff72..c37f791 100644 --- a/chrome/test/data/android/webvr_instrumentation/html/test_requestPresent_enters_vr.html +++ b/chrome/test/data/android/webvr_instrumentation/html/test_requestPresent_enters_vr.html
@@ -13,7 +13,7 @@ <script src="../resources/webvr_boilerplate.js"></script> <script> var t = async_test("A successful requestPresent call actually enters VR"); - window.addEventListener("onvrdisplaypresentchange", () => {t.done();}, false); + window.addEventListener("vrdisplaypresentchange", () => {t.done();}, false); </script> </body> </html>
diff --git a/chrome/test/data/extensions/api_test/networking_cast_private/manifest.json b/chrome/test/data/extensions/api_test/networking_cast_private/manifest.json new file mode 100644 index 0000000..965e147f --- /dev/null +++ b/chrome/test/data/extensions/api_test/networking_cast_private/manifest.json
@@ -0,0 +1,15 @@ +{ + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC74Vbx3EbhPc/FOvn6+HxCjMSml0HdPMiuRjj5a3b+MnRML1iJ9OAgbKUYJ/u3s25/cGq8pNB0NbyupHGEqvqAE7TcNr1mdgs0PWxh2IOI1GKrxlzxpqzQuFmxq5WHKr5RrwZ4/Xq0t/+e8JkvhZdW0jarz/28Jom0gkM5lorsewIDAQAB", + "name": "networking cast extension API interface test", + "version": "0.1", + "manifest_version": 2, + "description": "Test of chrome.networking.castPrivate methods", + "app": { + "background": { + "scripts": ["test.js"] + } + }, + "permissions": [ + "networking.castPrivate" + ] +}
diff --git a/chrome/test/data/extensions/api_test/networking_cast_private/test.js b/chrome/test/data/extensions/api_test/networking_cast_private/test.js new file mode 100644 index 0000000..f70b961 --- /dev/null +++ b/chrome/test/data/extensions/api_test/networking_cast_private/test.js
@@ -0,0 +1,73 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var callbackPass = chrome.test.callbackPass; +var callbackFail = chrome.test.callbackFail; +var assertTrue = chrome.test.assertTrue; +var assertEq = chrome.test.assertEq; + +// Test properties for the verification API. +var verificationProperties = { + certificate: 'certificate', + intermediateCertificates: ['ica1', 'ica2', 'ica3'], + publicKey: 'cHVibGljX2tleQ==', // Base64('public_key') + nonce: 'nonce', + signedData: 'c2lnbmVkX2RhdGE=', // Base64('signed_data') + deviceSerial: 'device_serial', + deviceSsid: 'Device 0123', + deviceBssid: '00:01:02:03:04:05' +}; + +chrome.test.getConfig(function(config) { + var args = JSON.parse(config.customArg); + + chrome.test.runTests([ + function verifyDestination() { + chrome.networking.castPrivate.verifyDestination( + verificationProperties, + callbackPass(function(isValid) { + assertTrue(isValid); + })); + }, + function verifyAndEncryptCredentials() { + var networkGuid = 'wifi_guid'; + chrome.networking.castPrivate.verifyAndEncryptCredentials( + verificationProperties, + networkGuid, + callbackPass(function(result) { + assertEq('encrypted_credentials', result); + })); + }, + function verifyAndEncryptData() { + chrome.networking.castPrivate.verifyAndEncryptData( + verificationProperties, + 'data', + callbackPass(function(result) { + assertEq('encrypted_data', result); + })); + }, + function setWifiTDLSEnabledState() { + if (args.tdlsSupported) { + chrome.networking.castPrivate.setWifiTDLSEnabledState( + 'aa:bb:cc:dd:ee:ff', true, callbackPass(function(result) { + assertEq('CONNECTED', result); + })); + } else { + chrome.networking.castPrivate.setWifiTDLSEnabledState( + 'aa:bb:cc:dd:ee:ff', true, callbackFail('Not supported')); + } + }, + function getWifiTDLSStatus() { + if (args.tdlsSupported) { + chrome.networking.castPrivate.getWifiTDLSStatus( + 'aa:bb:cc:dd:ee:ff', callbackPass(function(result) { + assertEq('CONNECTED', result); + })); + } else { + chrome.networking.castPrivate.getWifiTDLSStatus( + 'aa:bb:cc:dd:ee:ff', callbackFail('Not supported')); + } + }, + ]); +});
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index ff1d784..d222865b 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -372,6 +372,7 @@ Polymer.dom.flush(); + assertTrue(syncPage.$.encryptionDescription.hidden); assertTrue(syncPage.$.encryptionRadioGroupContainer.hidden); });
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index e8c7376..6b671fb2 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -1159,8 +1159,9 @@ TEST_PPAPI_NACL_SUBTESTS(MAYBE_Compositor0, RUN_COMPOSITOR_SUBTESTS_0) TEST_PPAPI_NACL_SUBTESTS(MAYBE_Compositor1, RUN_COMPOSITOR_SUBTESTS_1) -#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS) -// Flaky on ChromeOS, Linux and Windows (crbug.com/438729) +#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ + defined(OS_MACOSX) +// Flaky on ChromeOS, Linux, Windows, and Mac (crbug.com/438729) #define MAYBE_MediaStreamAudioTrack DISABLED_MediaStreamAudioTrack #else #define MAYBE_MediaStreamAudioTrack MediaStreamAudioTrack
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index d88ee0a..681c2cb 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -447,7 +447,10 @@ buildflag_header("chromecast_features") { header = "chromecast_features.h" - flags = [ "IS_CAST_AUDIO_ONLY=$is_cast_audio_only" ] + flags = [ + "IS_CAST_AUDIO_ONLY=$is_cast_audio_only", + "IS_CAST_USING_CMA_BACKEND=$is_cast_using_cma_backend", + ] } if (is_android) {
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 81bf1e9..b33af270 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -284,13 +284,13 @@ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); AddDefaultCommandLineSwitches(command_line); -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media_resource_tracker_ = nullptr; -#endif // !defined(OS_ANDROID) +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) } CastBrowserMainParts::~CastBrowserMainParts() { -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) if (media_thread_ && media_pipeline_backend_manager_) { // Make sure that media_pipeline_backend_manager_ is destroyed after any // pending media thread tasks. The CastAudioOutputStream implementation @@ -306,14 +306,12 @@ media_thread_->task_runner()->DeleteSoon( FROM_HERE, media_pipeline_backend_manager_.release()); } -#endif // !defined(OS_ANDROID) +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) } scoped_refptr<base::SingleThreadTaskRunner> CastBrowserMainParts::GetMediaTaskRunner() { -#if defined(OS_ANDROID) - return nullptr; -#else +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) if (!media_thread_) { media_thread_.reset(new base::Thread("CastMediaThread")); base::Thread::Options options; @@ -321,10 +319,12 @@ CHECK(media_thread_->StartWithOptions(options)); } return media_thread_->task_runner(); -#endif +#else + return nullptr; +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) } -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::MediaResourceTracker* CastBrowserMainParts::media_resource_tracker() { if (!media_resource_tracker_) { media_resource_tracker_ = new media::MediaResourceTracker( @@ -341,7 +341,7 @@ } return media_pipeline_backend_manager_.get(); } -#endif +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::MediaCapsImpl* CastBrowserMainParts::media_caps() { return media_caps_.get(); @@ -495,7 +495,7 @@ video_plane_controller_.get(), window_manager_.get())); cast_browser_process_->cast_service()->Initialize(); -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media_resource_tracker()->InitializeMediaLib(); #endif ::media::InitializeMediaLibrary();
diff --git a/chromecast/browser/cast_browser_main_parts.h b/chromecast/browser/cast_browser_main_parts.h index 51defab..822e930 100644 --- a/chromecast/browser/cast_browser_main_parts.h +++ b/chromecast/browser/cast_browser_main_parts.h
@@ -9,6 +9,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "build/buildflag.h" +#include "chromecast/chromecast_features.h" #include "content/public/browser/browser_main_parts.h" #include "content/public/common/main_function_params.h" @@ -45,7 +47,7 @@ scoped_refptr<base::SingleThreadTaskRunner> GetMediaTaskRunner(); -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::MediaResourceTracker* media_resource_tracker(); media::MediaPipelineBackendManager* media_pipeline_backend_manager(); #endif @@ -70,7 +72,7 @@ std::unique_ptr<media::MediaCapsImpl> media_caps_; std::unique_ptr<CastWindowManager> window_manager_; -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) // CMA thread used by AudioManager, MojoRenderer, and MediaPipelineBackend. std::unique_ptr<base::Thread> media_thread_;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 978db0e..eac81d927 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -71,10 +71,12 @@ #if defined(OS_ANDROID) #include "components/cdm/browser/cdm_message_filter_android.h" #include "components/crash/content/browser/crash_dump_manager_android.h" -#else -#include "chromecast/media/cdm/cast_cdm_factory.h" #endif // defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) +#include "chromecast/media/cdm/cast_cdm_factory.h" +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) + namespace chromecast { namespace shell { @@ -146,7 +148,7 @@ return nullptr; } -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::VideoResolutionPolicy* CastContentBrowserClient::GetVideoResolutionPolicy() { return nullptr; @@ -195,7 +197,7 @@ #endif // defined(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) return nullptr; } -#endif // !defined(OS_ANDROID) +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::MediaCapsImpl* CastContentBrowserClient::media_caps() { DCHECK(cast_browser_main_parts_);
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 879dc35..200ad6d7 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -13,6 +13,8 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "build/build_config.h" +#include "build/buildflag.h" +#include "chromecast/chromecast_features.h" #include "content/public/browser/certificate_request_result_type.h" #include "content/public/browser/content_browser_client.h" @@ -84,7 +86,7 @@ virtual media::VideoModeSwitcher* GetVideoModeSwitcher(); -#if !defined(OS_ANDROID) +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) // Gets object for enforcing video resolution policy restrictions. virtual media::VideoResolutionPolicy* GetVideoResolutionPolicy(); @@ -101,7 +103,7 @@ ::media::ScopedAudioManagerPtr CreateAudioManager( ::media::AudioLogFactory* audio_log_factory) override; std::unique_ptr<::media::CdmFactory> CreateCdmFactory() override; -#endif +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::MediaCapsImpl* media_caps(); // Invoked when the metrics client ID changes.
diff --git a/chromecast/media/cdm/BUILD.gn b/chromecast/media/cdm/BUILD.gn index 2cf3f96f..d6fb2ea 100644 --- a/chromecast/media/cdm/BUILD.gn +++ b/chromecast/media/cdm/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//chromecast/chromecast.gni") +import("//media/media_options.gni") source_set("cdm") { sources = [ @@ -15,7 +16,7 @@ "//media", ] - if (!is_android) { + if (is_cast_using_cma_backend) { sources += [ "cast_cdm.cc", "cast_cdm.h", @@ -29,14 +30,14 @@ "//chromecast/media/base", "//url:url", ] - } else { - if (use_playready) { - sources += [ - "playready_drm_delegate_android.cc", - "playready_drm_delegate_android.h", - ] + } - deps += [ "//media/base/android" ] - } + if (is_android && use_playready) { + sources += [ + "playready_drm_delegate_android.cc", + "playready_drm_delegate_android.h", + ] + + deps += [ "//media/base/android" ] } }
diff --git a/chromecast/media/cma/backend/BUILD.gn b/chromecast/media/cma/backend/BUILD.gn index e24eee2..4d096ddd 100644 --- a/chromecast/media/cma/backend/BUILD.gn +++ b/chromecast/media/cma/backend/BUILD.gn
@@ -4,6 +4,7 @@ import("//build/config/chromecast_build.gni") import("//chromecast/chromecast.gni") +import("//media/media_options.gni") source_set("backend") { sources = [ @@ -26,7 +27,12 @@ ] if (is_android) { - deps += [ ":cast_media_android" ] + if (is_cast_using_cma_backend) { + # TODO(tsunghung): use the real implementation when it's done. + deps += [ ":default" ] + } else { + deps += [ ":cast_media_android" ] + } } else { deps += [ ":libcast_media_1.0" ] }
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc index 65a1bae7..d5c8769f 100644 --- a/components/metrics/file_metrics_provider.cc +++ b/components/metrics/file_metrics_provider.cc
@@ -337,10 +337,18 @@ return ACCESS_RESULT_INVALID_CONTENTS; } - // Create an allocator for the mapped file. Ownership passes to the allocator. - source->allocator.reset(new base::PersistentHistogramAllocator( + // Map the file and validate it. + std::unique_ptr<base::PersistentMemoryAllocator> memory_allocator = base::MakeUnique<base::FilePersistentMemoryAllocator>( - std::move(mapped), 0, 0, base::StringPiece(), read_only))); + std::move(mapped), 0, 0, base::StringPiece(), read_only); + if (memory_allocator->GetMemoryState() == + base::PersistentMemoryAllocator::MEMORY_DELETED) { + return ACCESS_RESULT_MEMORY_DELETED; + } + + // Create an allocator for the mapped file. Ownership passes to the allocator. + source->allocator = base::MakeUnique<base::PersistentHistogramAllocator>( + std::move(memory_allocator)); return ACCESS_RESULT_SUCCESS; }
diff --git a/components/metrics/file_metrics_provider.h b/components/metrics/file_metrics_provider.h index 001fe83..43d4d30 100644 --- a/components/metrics/file_metrics_provider.h +++ b/components/metrics/file_metrics_provider.h
@@ -130,6 +130,9 @@ // File could not be opened. ACCESS_RESULT_NO_OPEN, + // File contents were internally deleted. + ACCESS_RESULT_MEMORY_DELETED, + ACCESS_RESULT_MAX };
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc index 4ba32f4..a869f2b 100644 --- a/components/password_manager/core/browser/form_fetcher_impl.cc +++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -91,10 +91,10 @@ void FormFetcherImpl::OnGetPasswordStoreResults( std::vector<std::unique_ptr<PasswordForm>> results) { DCHECK_EQ(State::WAITING, state_); - state_ = State::NOT_WAITING; if (need_to_refetch_) { // The received results are no longer up to date, need to re-request. + state_ = State::NOT_WAITING; Fetch(); need_to_refetch_ = false; return; @@ -167,6 +167,8 @@ void FormFetcherImpl::ProcessPasswordStoreResults( std::vector<std::unique_ptr<autofill::PasswordForm>> results) { + DCHECK_EQ(State::WAITING, state_); + state_ = State::NOT_WAITING; federated_ = SplitFederatedMatches(&results); non_federated_ = std::move(results);
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc index 864a2b6..219e7e59 100644 --- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc +++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -500,4 +500,57 @@ UnorderedElementsAre(Pointee(federated_form))); } +// When the FormFetcher delegates to the HttpPasswordMigrator, its state should +// be WAITING until the migrator passes the results. +TEST_F(FormFetcherImplTest, StateIsWaitingDuringMigration) { + GURL::Replacements https_rep; + https_rep.SetSchemeStr(url::kHttpsScheme); + const GURL https_origin = form_digest_.origin.ReplaceComponents(https_rep); + form_digest_ = PasswordStore::FormDigest( + PasswordForm::SCHEME_HTML, https_origin.GetOrigin().spec(), https_origin); + + // A new form fetcher is created to be able to set the form digest and + // migration flag. + form_fetcher_ = base::MakeUnique<FormFetcherImpl>( + form_digest_, &client_, /* should_migrate_http_passwords */ true); + + PasswordForm https_form = CreateNonFederated(); + + // Create HTTP form for the same orgin (except scheme), which will be passed + // to the migrator. + GURL::Replacements http_rep; + http_rep.SetSchemeStr(url::kHttpScheme); + PasswordForm http_form = https_form; + http_form.origin = https_form.origin.ReplaceComponents(http_rep); + http_form.signon_realm = http_form.origin.GetOrigin().spec(); + + std::vector<PasswordForm> empty_forms; + + // Ensure there is an attempt to migrate credentials on HTTPS origins and + // extract the migrator. + const GURL form_digest_http_origin = + form_digest_.origin.ReplaceComponents(http_rep); + PasswordStore::FormDigest http_form_digest( + PasswordForm::SCHEME_HTML, form_digest_http_origin.GetOrigin().spec(), + form_digest_http_origin); + Fetch(); + // First the FormFetcher is waiting for the initial response from + // PasswordStore. + EXPECT_EQ(FormFetcher::State::WAITING, form_fetcher_->GetState()); + base::WeakPtr<PasswordStoreConsumer> migrator_ptr; + EXPECT_CALL(*mock_store_, GetLogins(http_form_digest, _)) + .WillOnce(WithArg<1>(GetAndAssignWeakPtr(&migrator_ptr))); + form_fetcher_->OnGetPasswordStoreResults(MakeResults(empty_forms)); + ASSERT_TRUE(migrator_ptr); + // While the initial results from PasswordStore arrived to the FormFetcher, it + // should be still waiting for the migrator. + EXPECT_EQ(FormFetcher::State::WAITING, form_fetcher_->GetState()); + + // Now perform the actual migration. + EXPECT_CALL(*mock_store_, AddLogin(https_form)); + static_cast<HttpPasswordMigrator*>(migrator_ptr.get()) + ->OnGetPasswordStoreResults(MakeResults({http_form})); + EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState()); +} + } // namespace password_manager
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index 310cc5ac..77f03bf 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -125,8 +125,6 @@ } void PaymentRequest::Pay() { - DCHECK(state_->is_ready_to_pay()); - state_->GeneratePaymentResponse(); }
diff --git a/components/payments/content/payment_request_spec.cc b/components/payments/content/payment_request_spec.cc index 3d321120..5a92e86 100644 --- a/components/payments/content/payment_request_spec.cc +++ b/components/payments/content/payment_request_spec.cc
@@ -124,6 +124,9 @@ } } } + + supported_card_networks_set_.insert(supported_card_networks_.begin(), + supported_card_networks_.end()); } void PaymentRequestSpec::NotifyOnInvalidSpecProvided() {
diff --git a/components/payments/content/payment_request_spec.h b/components/payments/content/payment_request_spec.h index d205a1b..729d7ca 100644 --- a/components/payments/content/payment_request_spec.h +++ b/components/payments/content/payment_request_spec.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_SPEC_H_ #define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_SPEC_H_ +#include <set> #include <string> #include <vector> @@ -46,9 +47,12 @@ bool request_payer_phone() const { return options_->request_payer_phone; } bool request_payer_email() const { return options_->request_payer_email; } - const std::vector<std::string>& supported_card_networks() { + const std::vector<std::string>& supported_card_networks() const { return supported_card_networks_; } + const std::set<std::string>& supported_card_networks_set() const { + return supported_card_networks_set_; + } // Uses CurrencyFormatter to format |amount| with the currency symbol for this // request's currency. Will use currency of the "total" display item, because @@ -85,9 +89,11 @@ const std::string app_locale_; std::unique_ptr<CurrencyFormatter> currency_formatter_; - // A list of supported basic card networks, in order that they were specified - // by the merchant. + // A list/set of supported basic card networks. The list is used to keep the + // order in which they were specified by the merchant. The set is used for + // fast lookup of supported methods. std::vector<std::string> supported_card_networks_; + std::set<std::string> supported_card_networks_set_; base::ObserverList<Observer> observers_;
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index e37422a..01b95a3 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -13,11 +13,6 @@ namespace payments { -namespace { -// Identifier for the basic card payment method in the PaymentMethodData. -static const char* const kBasicCardMethodName = "basic-card"; -} // namespace - PaymentRequestState::PaymentRequestState( PaymentRequestSpec* spec, Delegate* delegate, @@ -30,7 +25,7 @@ personal_data_manager_(personal_data_manager), selected_shipping_profile_(nullptr), selected_contact_profile_(nullptr), - selected_credit_card_(nullptr), + selected_instrument_(nullptr), selected_shipping_option_(nullptr) { PopulateProfileCache(); UpdateSelectedShippingOption(); @@ -59,16 +54,10 @@ } void PaymentRequestState::GeneratePaymentResponse() { - // TODO(mathp): PaymentRequest should know about the currently selected - // instrument, and not |selected_credit_card_| which is too specific. - // TODO(mathp): The method_name should reflect what the merchant asked, and - // not necessarily basic-card. - selected_payment_instrument_.reset(new AutofillPaymentInstrument( - kBasicCardMethodName, *selected_credit_card_, shipping_profiles_, - app_locale_)); + DCHECK(is_ready_to_pay()); // Fetch the instrument details, will call back into // PaymentRequest::OnInstrumentsDetailsReady. - selected_payment_instrument_->InvokePaymentApp(this); + selected_instrument_->InvokePaymentApp(this); } void PaymentRequestState::SetSelectedShippingProfile( @@ -83,8 +72,8 @@ UpdateIsReadyToPayAndNotifyObservers(); } -void PaymentRequestState::SetSelectedCreditCard(autofill::CreditCard* card) { - selected_credit_card_ = card; +void PaymentRequestState::SetSelectedInstrument(PaymentInstrument* instrument) { + selected_instrument_ = instrument; UpdateIsReadyToPayAndNotifyObservers(); } @@ -113,11 +102,27 @@ contact_profiles_.push_back(profile_cache_[i].get()); } + // Create the list of available instruments. const std::vector<autofill::CreditCard*>& cards = personal_data_manager_->GetCreditCardsToSuggest(); + const std::set<std::string>& supported_card_networks = + spec_->supported_card_networks_set(); for (autofill::CreditCard* card : cards) { - card_cache_.push_back(base::MakeUnique<autofill::CreditCard>(*card)); - credit_cards_.push_back(card_cache_.back().get()); + std::string basic_card_network = + autofill::data_util::GetPaymentRequestData(card->type()) + .basic_card_payment_type; + if (!supported_card_networks.count(basic_card_network)) + continue; + + // TODO(crbug.com/701952): Should use the method name preferred by the + // merchant (either "basic-card" or the basic card network e.g. "visa"). + + // Copy the credit cards as part of AutofillPaymentInstrument so they are + // indirectly owned by this object. + std::unique_ptr<PaymentInstrument> instrument = + base::MakeUnique<AutofillPaymentInstrument>( + basic_card_network, *card, shipping_profiles_, app_locale_); + available_instruments_.push_back(std::move(instrument)); } } @@ -128,15 +133,20 @@ if (!contact_profiles().empty()) selected_contact_profile_ = contact_profiles()[0]; - // TODO(anthonyvd): Change this code to prioritize server cards and implement - // a way to modify this function's return value. - const std::vector<autofill::CreditCard*> cards = credit_cards(); - auto first_complete_card = - std::find_if(cards.begin(), cards.end(), - [](autofill::CreditCard* card) { return card->IsValid(); }); + // TODO(crbug.com/702063): Change this code to prioritize instruments by use + // count and other means, and implement a way to modify this function's return + // value. + const std::vector<std::unique_ptr<PaymentInstrument>>& instruments = + available_instruments(); + auto first_complete_instrument = + std::find_if(instruments.begin(), instruments.end(), + [](const std::unique_ptr<PaymentInstrument>& instrument) { + return instrument->IsValid(); + }); - selected_credit_card_ = - first_complete_card == cards.end() ? nullptr : *first_complete_card; + selected_instrument_ = first_complete_instrument == instruments.end() + ? nullptr + : first_complete_instrument->get(); UpdateIsReadyToPayAndNotifyObservers(); } @@ -153,18 +163,10 @@ } bool PaymentRequestState::ArePaymentDetailsSatisfied() { - // TODO(mathp): A masked card may not satisfy IsValid(). - if (selected_credit_card_ == nullptr || !selected_credit_card_->IsValid()) - return false; - - const std::string basic_card_payment_type = - autofill::data_util::GetPaymentRequestData(selected_credit_card_->type()) - .basic_card_payment_type; - return !spec_->supported_card_networks().empty() && - std::find(spec_->supported_card_networks().begin(), - spec_->supported_card_networks().end(), - basic_card_payment_type) != - spec_->supported_card_networks().end(); + // There is no need to check for supported networks, because only supported + // instruments are listed/created in the flow. + // TODO(crbug.com/702063): A masked card may not satisfy IsValid(). + return selected_instrument_ != nullptr && selected_instrument_->IsValid(); } bool PaymentRequestState::ArePaymentOptionsSatisfied() {
diff --git a/components/payments/content/payment_request_state.h b/components/payments/content/payment_request_state.h index 1363690..edae5e8 100644 --- a/components/payments/content/payment_request_state.h +++ b/components/payments/content/payment_request_state.h
@@ -12,7 +12,6 @@ namespace autofill { class AutofillProfile; -class CreditCard; class PersonalDataManager; } // namespace autofill @@ -76,11 +75,11 @@ autofill::AutofillProfile* selected_contact_profile() const { return selected_contact_profile_; } - // Returns the currently selected credit card for this PaymentRequest flow. + // Returns the currently selected instrument for this PaymentRequest flow. // It's not guaranteed to be complete. Returns nullptr if there is no selected - // card. - autofill::CreditCard* selected_credit_card() const { - return selected_credit_card_; + // instrument. + PaymentInstrument* selected_instrument() const { + return selected_instrument_; } mojom::PaymentShippingOption* selected_shipping_option() { return selected_shipping_option_; @@ -94,15 +93,16 @@ const std::vector<autofill::AutofillProfile*>& contact_profiles() { return contact_profiles_; } - const std::vector<autofill::CreditCard*>& credit_cards() { - return credit_cards_; + const std::vector<std::unique_ptr<PaymentInstrument>>& + available_instruments() { + return available_instruments_; } // Setters to change the selected information. Will have the side effect of // recomputing "is ready to pay" and notify observers. void SetSelectedShippingProfile(autofill::AutofillProfile* profile); void SetSelectedContactProfile(autofill::AutofillProfile* profile); - void SetSelectedCreditCard(autofill::CreditCard* card); + void SetSelectedInstrument(PaymentInstrument* instrument); bool is_ready_to_pay() { return is_ready_to_pay_; } @@ -115,7 +115,7 @@ // profile_cache_. void PopulateProfileCache(); - // Sets the initial selections for credit card and profiles, and notifies + // Sets the initial selections for instruments and profiles, and notifies // observers. void SetDefaultProfileSelections(); @@ -150,21 +150,19 @@ autofill::AutofillProfile* selected_shipping_profile_; autofill::AutofillProfile* selected_contact_profile_; - autofill::CreditCard* selected_credit_card_; + PaymentInstrument* selected_instrument_; // The shipping options (and thus this pointer) are owned by |spec_| which // outlives this object. mojom::PaymentShippingOption* selected_shipping_option_; - std::unique_ptr<PaymentInstrument> selected_payment_instrument_; - // Profiles may change due to (e.g.) sync events, so profiles are cached after // loading and owned here. They are populated once only, and ordered by // frecency. std::vector<std::unique_ptr<autofill::AutofillProfile>> profile_cache_; std::vector<autofill::AutofillProfile*> shipping_profiles_; std::vector<autofill::AutofillProfile*> contact_profiles_; - std::vector<std::unique_ptr<autofill::CreditCard>> card_cache_; - std::vector<autofill::CreditCard*> credit_cards_; + // Credit cards are directly owned by the instruments in this list. + std::vector<std::unique_ptr<PaymentInstrument>> available_instruments_; base::ObserverList<Observer> observers_;
diff --git a/components/payments/content/payment_request_state_unittest.cc b/components/payments/content/payment_request_state_unittest.cc index be56d1f..c9455875 100644 --- a/components/payments/content/payment_request_state_unittest.cc +++ b/components/payments/content/payment_request_state_unittest.cc
@@ -24,10 +24,15 @@ PaymentRequestStateTest() : num_on_selected_information_changed_called_(0), address_(autofill::test::GetFullProfile()), - credit_card_(autofill::test::GetCreditCard()) { + credit_card_visa_(autofill::test::GetCreditCard()), + credit_card_amex_(autofill::test::GetCreditCard2()) { test_personal_data_manager_.AddTestingProfile(&address_); - credit_card_.set_billing_address_id(address_.guid()); - test_personal_data_manager_.AddTestingCreditCard(&credit_card_); + credit_card_visa_.set_billing_address_id(address_.guid()); + credit_card_visa_.set_use_count(5u); + test_personal_data_manager_.AddTestingCreditCard(&credit_card_visa_); + credit_card_amex_.set_billing_address_id(address_.guid()); + credit_card_amex_.set_use_count(1u); + test_personal_data_manager_.AddTestingCreditCard(&credit_card_amex_); } ~PaymentRequestStateTest() override {} @@ -86,7 +91,6 @@ } autofill::AutofillProfile* test_address() { return &address_; } - autofill::CreditCard* test_credit_card() { return &credit_card_; } private: std::unique_ptr<PaymentRequestState> state_; @@ -97,7 +101,8 @@ // Test data. autofill::AutofillProfile address_; - autofill::CreditCard credit_card_; + autofill::CreditCard credit_card_visa_; + autofill::CreditCard credit_card_amex_; }; // Test that the last shipping option is selected. @@ -133,28 +138,18 @@ EXPECT_TRUE(state()->is_ready_to_pay()); } -// Testing that the card is supported when determining "is ready to pay". In -// this test the merchant only supports Visa. -TEST_F(PaymentRequestStateTest, ReadyToPay_SelectUnsupportedCard) { +// Testing that only supported intruments are shown. In this test the merchant +// only supports Visa. +TEST_F(PaymentRequestStateTest, UnsupportedCardAreNotAvailable) { // Default options. RecreateStateWithOptions(mojom::PaymentOptions::New()); - // Ready to pay because the default card is selected and supported. + // Ready to pay because the default instrument is selected and supported. EXPECT_TRUE(state()->is_ready_to_pay()); - autofill::CreditCard amex_card = autofill::test::GetCreditCard2(); // Amex. - state()->SetSelectedCreditCard(&amex_card); - EXPECT_EQ(1, num_on_selected_information_changed_called()); - - // Not ready to pay because the card is not supported. - EXPECT_FALSE(state()->is_ready_to_pay()); - - // Go back to the Visa card. - state()->SetSelectedCreditCard(test_credit_card()); // Visa card. - EXPECT_EQ(2, num_on_selected_information_changed_called()); - - // Visa card is supported by the merchant. - EXPECT_TRUE(state()->is_ready_to_pay()); + // There's only one instrument available, even though there's an Amex in + // PersonalDataManager. + EXPECT_EQ(1u, state()->available_instruments().size()); } // Test selecting a contact info profile will make the user ready to pay. @@ -185,13 +180,13 @@ TEST_F(PaymentRequestStateTest, GeneratePaymentResponse) { // Default options (no shipping, no contact info). RecreateStateWithOptions(mojom::PaymentOptions::New()); - state()->SetSelectedCreditCard(test_credit_card()); + state()->SetSelectedInstrument(state()->available_instruments()[0].get()); EXPECT_EQ(1, num_on_selected_information_changed_called()); EXPECT_TRUE(state()->is_ready_to_pay()); // TODO(mathp): Currently synchronous, when async will need a RunLoop. state()->GeneratePaymentResponse(); - EXPECT_EQ("basic-card", response()->method_name); + EXPECT_EQ("visa", response()->method_name); EXPECT_EQ( "{\"billingAddress\":" "{\"addressLine\":[\"666 Erebus St.\",\"Apt 8\"],"
diff --git a/components/payments/core/BUILD.gn b/components/payments/core/BUILD.gn index 892c2c8..b0b5e5b 100644 --- a/components/payments/core/BUILD.gn +++ b/components/payments/core/BUILD.gn
@@ -14,6 +14,7 @@ "currency_formatter.h", "payment_address.cc", "payment_address.h", + "payment_instrument.cc", "payment_instrument.h", "payment_request_data_util.cc", "payment_request_data_util.h",
diff --git a/components/payments/core/autofill_payment_instrument.cc b/components/payments/core/autofill_payment_instrument.cc index 3f55efd..00c59b6 100644 --- a/components/payments/core/autofill_payment_instrument.cc +++ b/components/payments/core/autofill_payment_instrument.cc
@@ -15,11 +15,18 @@ AutofillPaymentInstrument::AutofillPaymentInstrument( const std::string& method_name, - const autofill::CreditCard& credit_card, + const autofill::CreditCard& card, const std::vector<autofill::AutofillProfile*>& billing_profiles, const std::string& app_locale) - : PaymentInstrument(method_name), - credit_card_(credit_card), + : PaymentInstrument( + method_name, + /* label= */ card.TypeAndLastFourDigits(), + /* sublabel= */ + card.GetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), + app_locale), + autofill::data_util::GetPaymentRequestData(card.type()) + .icon_resource_id), + credit_card_(card), billing_profiles_(billing_profiles), app_locale_(app_locale) {} AutofillPaymentInstrument::~AutofillPaymentInstrument() {} @@ -39,4 +46,8 @@ delegate->OnInstrumentDetailsReady(method_name(), stringified_details); } +bool AutofillPaymentInstrument::IsValid() { + return credit_card_.IsValid(); +} + } // namespace payments
diff --git a/components/payments/core/autofill_payment_instrument.h b/components/payments/core/autofill_payment_instrument.h index d6d9ec6c..ca0e125 100644 --- a/components/payments/core/autofill_payment_instrument.h +++ b/components/payments/core/autofill_payment_instrument.h
@@ -26,17 +26,21 @@ // |billing_profiles| is owned by the caller and should outlive this object. AutofillPaymentInstrument( const std::string& method_name, - const autofill::CreditCard& credit_card, + const autofill::CreditCard& card, const std::vector<autofill::AutofillProfile*>& billing_profiles, const std::string& app_locale); ~AutofillPaymentInstrument() override; // PaymentInstrument: void InvokePaymentApp(PaymentInstrument::Delegate* delegate) override; + bool IsValid() override; private: + // A copy of the card is owned by this object. const autofill::CreditCard credit_card_; + // Not owned by this object, should outlive this. const std::vector<autofill::AutofillProfile*>& billing_profiles_; + const std::string app_locale_; DISALLOW_COPY_AND_ASSIGN(AutofillPaymentInstrument);
diff --git a/components/payments/core/payment_instrument.cc b/components/payments/core/payment_instrument.cc new file mode 100644 index 0000000..324c47a9 --- /dev/null +++ b/components/payments/core/payment_instrument.cc
@@ -0,0 +1,20 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/payments/core/payment_instrument.h" + +namespace payments { + +PaymentInstrument::PaymentInstrument(const std::string& method_name, + const base::string16& label, + const base::string16& sublabel, + int icon_resource_id) + : method_name_(method_name), + label_(label), + sublabel_(sublabel), + icon_resource_id_(icon_resource_id) {} + +PaymentInstrument::~PaymentInstrument() {} + +} // namespace payments
diff --git a/components/payments/core/payment_instrument.h b/components/payments/core/payment_instrument.h index a9348d5..7b3d0e0 100644 --- a/components/payments/core/payment_instrument.h +++ b/components/payments/core/payment_instrument.h
@@ -9,6 +9,7 @@ #include <string> #include "base/macros.h" +#include "base/strings/string16.h" namespace payments { @@ -28,19 +29,29 @@ virtual void OnInstrumentDetailsError() = 0; }; - virtual ~PaymentInstrument() {} + virtual ~PaymentInstrument(); // Will call into the |delegate| (can't be null) on success or error. virtual void InvokePaymentApp(Delegate* delegate) = 0; + // Returns true if the card is valid to be used as a payment method. + virtual bool IsValid() = 0; - const std::string& method_name() { return method_name_; } + const std::string& method_name() const { return method_name_; } + const base::string16& label() const { return label_; } + const base::string16& sublabel() const { return sublabel_; } + int icon_resource_id() const { return icon_resource_id_; } protected: - explicit PaymentInstrument(const std::string& method_name) - : method_name_(method_name) {} + PaymentInstrument(const std::string& method_name, + const base::string16& label, + const base::string16& sublabel, + int icon_resource_id); private: const std::string method_name_; + const base::string16 label_; + const base::string16 sublabel_; + int icon_resource_id_; DISALLOW_COPY_AND_ASSIGN(PaymentInstrument); };
diff --git a/components/signin/core/browser/signin_client.cc b/components/signin/core/browser/signin_client.cc index 9473e0b..6ca52420 100644 --- a/components/signin/core/browser/signin_client.cc +++ b/components/signin/core/browser/signin_client.cc
@@ -32,7 +32,9 @@ return signin_scoped_device_id; } -void SigninClient::PreSignOut(const base::Callback<void()>& sign_out) { +void SigninClient::PreSignOut( + const base::Callback<void()>& sign_out, + signin_metrics::ProfileSignout signout_source_metric) { sign_out.Run(); }
diff --git a/components/signin/core/browser/signin_client.h b/components/signin/core/browser/signin_client.h index a4910c15..8281810 100644 --- a/components/signin/core/browser/signin_client.h +++ b/components/signin/core/browser/signin_client.h
@@ -10,6 +10,7 @@ #include "base/time/time.h" #include "components/keyed_service/core/keyed_service.h" #include "components/signin/core/browser/account_info.h" +#include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/webdata/token_web_data.h" #include "google_apis/gaia/gaia_auth_fetcher.h" #include "net/cookies/cookie_store.h" @@ -98,7 +99,8 @@ // Called before Google signout started, call |sign_out| to start the sign out // process. - virtual void PreSignOut(const base::Callback<void()>& sign_out); + virtual void PreSignOut(const base::Callback<void()>& sign_out, + signin_metrics::ProfileSignout signout_source_metric); virtual bool IsFirstRun() const = 0; virtual base::Time GetInstallDate() = 0;
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index 27fce04..d27931d 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -149,9 +149,10 @@ void SigninManager::SignOut( signin_metrics::ProfileSignout signout_source_metric, signin_metrics::SignoutDelete signout_delete_metric) { - client_->PreSignOut(base::Bind(&SigninManager::DoSignOut, - base::Unretained(this), signout_source_metric, - signout_delete_metric)); + client_->PreSignOut( + base::Bind(&SigninManager::DoSignOut, base::Unretained(this), + signout_source_metric, signout_delete_metric), + signout_source_metric); } void SigninManager::DoSignOut(
diff --git a/components/signin/core/browser/signin_metrics.h b/components/signin/core/browser/signin_metrics.h index 0ba0eb04..061a414 100644 --- a/components/signin/core/browser/signin_metrics.h +++ b/components/signin/core/browser/signin_metrics.h
@@ -46,7 +46,8 @@ // The credentials are being transfered to a new profile, so the old one is // signed out. TRANSFER_CREDENTIALS, - + // Signed out because credentials are invalid and force-sign-in is enabled. + AUTHENTICATION_FAILED_WITH_FORCE_SIGNIN, // Keep this as the last enum. NUM_PROFILE_SIGNOUT_METRICS, };
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index cd10a75..ea1a1f9e 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -224,10 +224,7 @@ InitTranslateEvent(language_code, target_lang, *translate_prefs); // Don't translate similar languages (ex: en-US to en). - // Also do not offer to translate between Simplified and Traditional Chinese. - if (language_code == target_lang || - (language_code == "zh-CN" && target_lang == "zh-TW") || - (language_code == "zh-TW" && target_lang == "zh-CN")) { + if (language_code == target_lang) { TranslateBrowserMetrics::ReportInitiationStatus( TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES); return;
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc index dfe0696..fda38d7 100644 --- a/components/translate/core/browser/translate_manager_unittest.cc +++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -307,64 +307,6 @@ 1); } -// The test measures that Translate is not triggered for a zh-TW page for a -// zh-CN user. -TEST_F(TranslateManagerTest, - DontTranslateZhTraditionalPageForZhSimplifiedLocale) { - TranslateManager::SetIgnoreMissingKeyForTesting(true); - translate_manager_.reset(new translate::TranslateManager( - &mock_translate_client_, kAcceptLanguages)); - - const char kMetricName[] = "Translate.InitiationStatus.v2"; - base::HistogramTester histogram_tester; - - const std::string locale = "zh-TW"; - const std::string page_lang = "zh-CN"; - - network_notifier_.SimulateOnline(); - manager_->set_application_locale(locale); - ON_CALL(mock_translate_client_, IsTranslatableURL(_)) - .WillByDefault(Return(true)); - - EXPECT_EQ("zh-TW", translate_manager_->GetTargetLanguage(&translate_prefs_)); - translate_manager_->GetLanguageState().LanguageDetermined(page_lang, true); - translate_manager_->InitiateTranslation(page_lang); - - histogram_tester.ExpectUniqueSample( - kMetricName, - translate::TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES, - 1); -} - -// The test measures that Translate is not triggered for a zh-CN page for a -// zh-TW user. -TEST_F(TranslateManagerTest, - DontTranslateZhSimplifiedPageForZhTraditionalLocale) { - TranslateManager::SetIgnoreMissingKeyForTesting(true); - translate_manager_.reset(new translate::TranslateManager( - &mock_translate_client_, kAcceptLanguages)); - - const char kMetricName[] = "Translate.InitiationStatus.v2"; - base::HistogramTester histogram_tester; - - const std::string locale = "zh-CN"; - const std::string page_lang = "zh-TW"; - - network_notifier_.SimulateOnline(); - manager_->set_application_locale(locale); - ON_CALL(mock_translate_client_, IsTranslatableURL(_)) - .WillByDefault(Return(true)); - - EXPECT_EQ("zh-CN", translate_manager_->GetTargetLanguage(&translate_prefs_)); - translate_manager_->GetLanguageState().LanguageDetermined(page_lang, true); - translate_manager_->InitiateTranslation(page_lang); - - histogram_tester.ExpectUniqueSample( - kMetricName, - translate::TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES, - 1); -} - // Utility function to set the threshold params void ChangeThresholdInParams( const char* initiate_translation_confidence_threshold,
diff --git a/content/app/content_main.cc b/content/app/content_main.cc index b983bf8..c5086ad 100644 --- a/content/app/content_main.cc +++ b/content/app/content_main.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/debug/activity_tracker.h" #include "content/public/app/content_main_runner.h" namespace content { @@ -14,13 +15,34 @@ std::unique_ptr<ContentMainRunner> main_runner(ContentMainRunner::Create()); int exit_code = main_runner->Initialize(params); - if (exit_code >= 0) + if (exit_code >= 0) { + base::debug::GlobalActivityTracker* tracker = + base::debug::GlobalActivityTracker::Get(); + if (tracker) { + tracker->SetProcessPhase( + base::debug::GlobalActivityTracker::PROCESS_LAUNCH_FAILED); + tracker->process_data().SetInt("exit-code", exit_code); + } return exit_code; + } exit_code = main_runner->Run(); main_runner->Shutdown(); + base::debug::GlobalActivityTracker* tracker = + base::debug::GlobalActivityTracker::Get(); + if (tracker) { + if (exit_code == 0) { + tracker->SetProcessPhaseIfEnabled( + base::debug::GlobalActivityTracker::PROCESS_EXITED_CLEANLY); + } else { + tracker->SetProcessPhaseIfEnabled( + base::debug::GlobalActivityTracker::PROCESS_EXITED_WITH_CODE); + tracker->process_data().SetInt("exit-code", exit_code); + } + } + return exit_code; }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 673a49c2..7fe0901 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -334,6 +334,8 @@ "background_fetch/background_fetch_job_info.h", "background_fetch/background_fetch_request_info.cc", "background_fetch/background_fetch_request_info.h", + "background_fetch/background_fetch_service_impl.cc", + "background_fetch/background_fetch_service_impl.h", "background_sync/background_sync_context.cc", "background_sync/background_sync_context.h", "background_sync/background_sync_manager.cc",
diff --git a/content/browser/android/java_interfaces_impl.cc b/content/browser/android/java_interfaces_impl.cc index 4169654..64ac665 100644 --- a/content/browser/android/java_interfaces_impl.cc +++ b/content/browser/android/java_interfaces_impl.cc
@@ -11,6 +11,7 @@ #include "base/android/context_utils.h" #include "base/android/jni_android.h" #include "base/memory/singleton.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "jni/InterfaceRegistrarImpl_jni.h" @@ -60,4 +61,13 @@ web_contents->GetJavaWebContents().obj()); } +void BindInterfaceRegistryForRenderFrameHost( + service_manager::mojom::InterfaceProviderRequest request, + RenderFrameHostImpl* render_frame_host) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_InterfaceRegistrarImpl_createInterfaceRegistryForRenderFrameHost( + env, request.PassMessagePipe().release().value(), + render_frame_host->GetJavaRenderFrameHost().obj()); +} + } // namespace content
diff --git a/content/browser/android/java_interfaces_impl.h b/content/browser/android/java_interfaces_impl.h index f78c063d..fd5cb80 100644 --- a/content/browser/android/java_interfaces_impl.h +++ b/content/browser/android/java_interfaces_impl.h
@@ -9,12 +9,17 @@ #include "services/service_manager/public/interfaces/interface_provider.mojom.h" namespace content { +class RenderFrameHostImpl; class WebContents; void BindInterfaceRegistryForWebContents( service_manager::mojom::InterfaceProviderRequest request, WebContents* web_contents); +void BindInterfaceRegistryForRenderFrameHost( + service_manager::mojom::InterfaceProviderRequest request, + RenderFrameHostImpl* render_frame_host); + } // namespace content #endif // CONTENT_BROWSER_ANDROID_JAVA_INTERFACES_IMPL_H_
diff --git a/content/browser/background_fetch/DEPS b/content/browser/background_fetch/DEPS new file mode 100644 index 0000000..c0c3af0 --- /dev/null +++ b/content/browser/background_fetch/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h", +]
diff --git a/content/browser/background_fetch/background_fetch_service_impl.cc b/content/browser/background_fetch/background_fetch_service_impl.cc new file mode 100644 index 0000000..cb81edc --- /dev/null +++ b/content/browser/background_fetch/background_fetch_service_impl.cc
@@ -0,0 +1,84 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/background_fetch/background_fetch_service_impl.h" + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "content/browser/background_fetch/background_fetch_context.h" +#include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/public/browser/browser_thread.h" +#include "mojo/public/cpp/bindings/strong_binding.h" + +namespace content { + +// static +void BackgroundFetchServiceImpl::Create( + scoped_refptr<BackgroundFetchContext> background_fetch_context, + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, + blink::mojom::BackgroundFetchServiceRequest request) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + mojo::MakeStrongBinding(base::MakeUnique<BackgroundFetchServiceImpl>( + std::move(background_fetch_context), + std::move(service_worker_context)), + std::move(request)); +} + +BackgroundFetchServiceImpl::BackgroundFetchServiceImpl( + scoped_refptr<BackgroundFetchContext> background_fetch_context, + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) + : background_fetch_context_(std::move(background_fetch_context)), + service_worker_context_(std::move(service_worker_context)) { + DCHECK(background_fetch_context_); + DCHECK(service_worker_context_); +} + +BackgroundFetchServiceImpl::~BackgroundFetchServiceImpl() = default; + +void BackgroundFetchServiceImpl::UpdateUI( + int64_t service_worker_registration_id, + const std::string& tag, + const std::string& title, + const UpdateUICallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + // TODO(peter): Get the BackgroundFetchJobController for the + // {service_worker_registration_id, tag} pair and call UpdateUI() on it. + + callback.Run(blink::mojom::BackgroundFetchError::NONE); +} + +void BackgroundFetchServiceImpl::Abort(int64_t service_worker_registration_id, + const std::string& tag) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + // TODO(peter): Get the BackgroundFetchJobController for the + // {service_worker_registration_id, tag} pair and call Abort() on it. +} + +void BackgroundFetchServiceImpl::GetRegistration( + int64_t service_worker_registration_id, + const std::string& tag, + const GetRegistrationCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + // TODO(peter): Get the registration for {service_worker_registration_id, tag} + // and construct a BackgroundFetchRegistrationPtr for it. + + callback.Run(blink::mojom::BackgroundFetchError::NONE, + nullptr /* registration */); +} + +void BackgroundFetchServiceImpl::GetTags(int64_t service_worker_registration_id, + const GetTagsCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + // TODO(peter): Get the list of active Background Fetches associated with + // service_worker_registration_id and share their tags. + + callback.Run(blink::mojom::BackgroundFetchError::NONE, + std::vector<std::string>()); +} + +} // namespace content
diff --git a/content/browser/background_fetch/background_fetch_service_impl.h b/content/browser/background_fetch/background_fetch_service_impl.h new file mode 100644 index 0000000..ffc2986 --- /dev/null +++ b/content/browser/background_fetch/background_fetch_service_impl.h
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SERVICE_IMPL_H_ +#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SERVICE_IMPL_H_ + +#include <string> +#include <utility> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h" + +namespace content { + +class BackgroundFetchContext; +class ServiceWorkerContextWrapper; + +class BackgroundFetchServiceImpl : public blink::mojom::BackgroundFetchService { + public: + BackgroundFetchServiceImpl( + scoped_refptr<BackgroundFetchContext> background_fetch_context, + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context); + ~BackgroundFetchServiceImpl() override; + + static void Create( + scoped_refptr<BackgroundFetchContext> background_fetch_context, + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, + blink::mojom::BackgroundFetchServiceRequest request); + + // blink::mojom::BackgroundFetchService implementation. + void UpdateUI(int64_t service_worker_registration_id, + const std::string& tag, + const std::string& title, + const UpdateUICallback& callback) override; + void Abort(int64_t service_worker_registration_id, + const std::string& tag) override; + void GetRegistration(int64_t service_worker_registration_id, + const std::string& tag, + const GetRegistrationCallback& callback) override; + void GetTags(int64_t service_worker_registration_id, + const GetTagsCallback& callback) override; + + private: + scoped_refptr<BackgroundFetchContext> background_fetch_context_; + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; + + DISALLOW_COPY_AND_ASSIGN(BackgroundFetchServiceImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SERVICE_IMPL_H_
diff --git a/content/browser/device_sensors/device_sensor_browsertest.cc b/content/browser/device_sensors/device_sensor_browsertest.cc index df8fbc7..f3d65a6 100644 --- a/content/browser/device_sensors/device_sensor_browsertest.cc +++ b/content/browser/device_sensors/device_sensor_browsertest.cc
@@ -57,6 +57,18 @@ orientation_stopped_callback_ = orientation_stopped_callback; } + void SetOrientationAbsoluteStartedCallback( + base::Closure orientation_absolute_started_callback) { + orientation_absolute_started_callback_ = + orientation_absolute_started_callback; + } + + void SetOrientationAbsoluteStoppedCallback( + base::Closure orientation_absolute_stopped_callback) { + orientation_absolute_stopped_callback_ = + orientation_absolute_stopped_callback; + } + bool Start(device::ConsumerType consumer_type, void* buffer) override { EXPECT_TRUE(buffer); @@ -79,6 +91,15 @@ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, orientation_started_callback_); } break; + case device::CONSUMER_TYPE_ORIENTATION_ABSOLUTE: { + device::DeviceOrientationHardwareBuffer* orientation_buffer = + static_cast<device::DeviceOrientationHardwareBuffer*>(buffer); + if (sensor_data_available_) + UpdateOrientationAbsolute(orientation_buffer); + SetOrientationBufferReady(orientation_buffer); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + orientation_absolute_started_callback_); + } break; case device::CONSUMER_TYPE_LIGHT: { device::DeviceLightHardwareBuffer* light_buffer = static_cast<device::DeviceLightHardwareBuffer*>(buffer); @@ -105,6 +126,10 @@ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, orientation_stopped_callback_); break; + case device::CONSUMER_TYPE_ORIENTATION_ABSOLUTE: + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + orientation_absolute_stopped_callback_); + break; case device::CONSUMER_TYPE_LIGHT: BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, light_stopped_callback_); @@ -178,6 +203,20 @@ buffer->seqlock.WriteEnd(); } + void UpdateOrientationAbsolute( + device::DeviceOrientationHardwareBuffer* buffer) { + buffer->seqlock.WriteBegin(); + buffer->data.alpha = 4; + buffer->data.hasAlpha = true; + buffer->data.beta = 5; + buffer->data.hasBeta = true; + buffer->data.gamma = 6; + buffer->data.hasGamma = true; + buffer->data.absolute = true; + buffer->data.allAvailableSensorsAreActive = true; + buffer->seqlock.WriteEnd(); + } + void UpdateLight(device::DeviceLightHardwareBuffer* buffer, double lux) { buffer->seqlock.WriteBegin(); buffer->data.value = lux; @@ -187,9 +226,11 @@ // The below callbacks should be run on the UI thread. base::Closure motion_started_callback_; base::Closure orientation_started_callback_; + base::Closure orientation_absolute_started_callback_; base::Closure light_started_callback_; base::Closure motion_stopped_callback_; base::Closure orientation_stopped_callback_; + base::Closure orientation_absolute_stopped_callback_; base::Closure light_stopped_callback_; bool sensor_data_available_; @@ -213,6 +254,8 @@ motion_stopped_runloop_.reset(new base::RunLoop()); orientation_started_runloop_.reset(new base::RunLoop()); orientation_stopped_runloop_.reset(new base::RunLoop()); + orientation_absolute_started_runloop_.reset(new base::RunLoop()); + orientation_absolute_stopped_runloop_.reset(new base::RunLoop()); #if defined(OS_ANDROID) // On Android, the DeviceSensorService lives on the UI thread. SetUpFetcher(); @@ -236,6 +279,10 @@ orientation_started_runloop_->QuitClosure()); fetcher_->SetOrientationStoppedCallback( orientation_stopped_runloop_->QuitClosure()); + fetcher_->SetOrientationAbsoluteStartedCallback( + orientation_absolute_started_runloop_->QuitClosure()); + fetcher_->SetOrientationAbsoluteStoppedCallback( + orientation_absolute_stopped_runloop_->QuitClosure()); device::DeviceSensorService::GetInstance()->SetDataFetcherForTesting( fetcher_); } @@ -279,6 +326,8 @@ std::unique_ptr<base::RunLoop> motion_stopped_runloop_; std::unique_ptr<base::RunLoop> orientation_started_runloop_; std::unique_ptr<base::RunLoop> orientation_stopped_runloop_; + std::unique_ptr<base::RunLoop> orientation_absolute_started_runloop_; + std::unique_ptr<base::RunLoop> orientation_absolute_stopped_runloop_; private: base::WaitableEvent io_loop_finished_event_; @@ -296,6 +345,19 @@ orientation_stopped_runloop_->Run(); } +IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationAbsoluteTest) { + // The test page will register an event handler for absolute orientation + // events, expects to get an event with fake values, then removes the event + // handler and navigates to #pass. + GURL test_url = + GetTestUrl("device_sensors", "device_orientation_absolute_test.html"); + NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); + + EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + orientation_absolute_started_runloop_->Run(); + orientation_absolute_stopped_runloop_->Run(); +} + IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, LightTest) { // The test page will register an event handler for light events, // expects to get an event with fake values, then removes the event @@ -350,6 +412,20 @@ orientation_stopped_runloop_->Run(); } +IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationAbsoluteNullTest) { + // The test page registers an event handler for absolute orientation events + // and expects to get an event with null values, because no sensor data can be + // provided. + fetcher_->SetSensorDataAvailable(false); + GURL test_url = GetTestUrl("device_sensors", + "device_orientation_absolute_null_test.html"); + NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); + + EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); + orientation_absolute_started_runloop_->Run(); + orientation_absolute_stopped_runloop_->Run(); +} + IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, MotionNullTest) { // The test page registers an event handler for motion events and // expects to get an event with null values, because no sensor data can be
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 77fdcb7b..70c236e6 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -114,6 +114,7 @@ #include "url/gurl.h" #if defined(OS_ANDROID) +#include "content/browser/android/java_interfaces_impl.h" #include "content/browser/frame_host/render_frame_host_android.h" #include "content/browser/media/android/media_player_renderer.h" #include "content/public/browser/android/java_interfaces.h" @@ -3507,6 +3508,16 @@ } return render_frame_host_android->GetJavaObject(); } + +service_manager::InterfaceProvider* RenderFrameHostImpl::GetJavaInterfaces() { + if (!java_interfaces_) { + service_manager::mojom::InterfaceProviderPtr provider; + BindInterfaceRegistryForRenderFrameHost(mojo::MakeRequest(&provider), this); + java_interfaces_.reset(new service_manager::InterfaceProvider); + java_interfaces_->Bind(std::move(provider)); + } + return java_interfaces_.get(); +} #endif } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index b5c7fe6..8bed9932 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -619,6 +619,7 @@ #if defined(OS_ANDROID) base::android::ScopedJavaLocalRef<jobject> GetJavaRenderFrameHost(); + service_manager::InterfaceProvider* GetJavaInterfaces() override; #endif protected: @@ -1144,6 +1145,10 @@ // Tracks the feature policy which has been set on this frame. std::unique_ptr<FeaturePolicy> feature_policy_; +#if defined(OS_ANDROID) + std::unique_ptr<service_manager::InterfaceProvider> java_interfaces_; +#endif + // NOTE: This must be the last member. base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 9086cd30..c65dad2 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -55,6 +55,7 @@ #include "components/tracing/common/tracing_switches.h" #include "content/browser/appcache/appcache_dispatcher_host.h" #include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/background_fetch/background_fetch_service_impl.h" #include "content/browser/background_sync/background_sync_service_impl.h" #include "content/browser/bad_message.h" #include "content/browser/blob_storage/blob_dispatcher_host.h" @@ -1315,6 +1316,11 @@ base::Bind(&PushMessagingManager::BindRequest, base::Unretained(push_messaging_manager_.get()))); + registry->AddInterface(base::Bind( + &BackgroundFetchServiceImpl::Create, + make_scoped_refptr(storage_partition_impl_->GetBackgroundFetchContext()), + make_scoped_refptr(storage_partition_impl_->GetServiceWorkerContext()))); + registry->AddInterface(base::Bind(&RenderProcessHostImpl::CreateMusGpuRequest, base::Unretained(this)));
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 95b3a95..b84229d 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -398,6 +398,9 @@ if (GetPlatformNotificationContext()) GetPlatformNotificationContext()->Shutdown(); + if (GetBackgroundFetchContext()) + GetBackgroundFetchContext()->Shutdown(); + if (GetBackgroundSyncContext()) GetBackgroundSyncContext()->Shutdown(); @@ -489,6 +492,9 @@ partition->service_worker_context_); partition->platform_notification_context_->Initialize(); + partition->background_fetch_context_ = new BackgroundFetchContext( + context, partition.get(), partition->service_worker_context_); + partition->background_sync_context_ = new BackgroundSyncContext(); partition->background_sync_context_->Init(partition->service_worker_context_); @@ -566,6 +572,10 @@ return platform_notification_context_.get(); } +BackgroundFetchContext* StoragePartitionImpl::GetBackgroundFetchContext() { + return background_fetch_context_.get(); +} + BackgroundSyncContext* StoragePartitionImpl::GetBackgroundSyncContext() { return background_sync_context_.get(); }
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 92b46dd0..9157d5b 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -16,6 +16,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/background_fetch/background_fetch_context.h" #include "content/browser/background_sync/background_sync_context.h" #include "content/browser/bluetooth/bluetooth_allowed_devices_map.h" #include "content/browser/broadcast_channel/broadcast_channel_provider.h" @@ -78,6 +79,7 @@ PlatformNotificationContextImpl* GetPlatformNotificationContext() override; void ClearBluetoothAllowedDevicesMapForTesting() override; + BackgroundFetchContext* GetBackgroundFetchContext(); BackgroundSyncContext* GetBackgroundSyncContext(); PaymentAppContextImpl* GetPaymentAppContext(); BroadcastChannelProvider* GetBroadcastChannelProvider(); @@ -220,6 +222,7 @@ scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; scoped_refptr<HostZoomLevelContext> host_zoom_level_context_; scoped_refptr<PlatformNotificationContextImpl> platform_notification_context_; + scoped_refptr<BackgroundFetchContext> background_fetch_context_; scoped_refptr<BackgroundSyncContext> background_sync_context_; scoped_refptr<PaymentAppContextImpl> payment_app_context_; scoped_refptr<BroadcastChannelProvider> broadcast_channel_provider_;
diff --git a/content/common/message_port.cc b/content/common/message_port.cc index 428162e..a57236a 100644 --- a/content/common/message_port.cc +++ b/content/common/message_port.cc
@@ -153,15 +153,14 @@ MojoResult rv = CreateWatcher(&State::CallOnHandleReady, &watcher_handle_); DCHECK_EQ(MOJO_RESULT_OK, rv); - // We use a scoped_refptr<State> instance as the watch context. This is owned - // by the watch and deleted upon receiving a cancellation notification. - scoped_refptr<State>* state_ref = new scoped_refptr<State>(this); - context_ = reinterpret_cast<uintptr_t>(state_ref); + // Balanced in CallOnHandleReady when MOJO_RESULT_CANCELLED is received. + AddRef(); // NOTE: An HTML MessagePort does not receive an event to tell it when the // peer has gone away, so we only watch for readability here. - rv = MojoWatch(watcher_handle_.get().value(), handle_.get().value(), - MOJO_HANDLE_SIGNAL_READABLE, context_); + rv = + MojoWatch(watcher_handle_.get().value(), handle_.get().value(), + MOJO_HANDLE_SIGNAL_READABLE, reinterpret_cast<uintptr_t>(this)); DCHECK_EQ(MOJO_RESULT_OK, rv); ArmWatcher(); @@ -169,7 +168,6 @@ void MessagePort::State::CancelWatch() { watcher_handle_.reset(); - context_ = 0; } MessagePort::State::~State() = default; @@ -191,7 +189,7 @@ // The watcher could not be armed because it would notify immediately. DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv); DCHECK_EQ(1u, num_ready_contexts); - DCHECK_EQ(context_, ready_context); + DCHECK_EQ(reinterpret_cast<uintptr_t>(this), ready_context); if (ready_result == MOJO_RESULT_OK) { // The handle is already signaled, so we trigger a callback now. @@ -222,12 +220,13 @@ MojoResult result, MojoHandleSignalsState signals_state, MojoWatcherNotificationFlags flags) { - auto* state_ref = reinterpret_cast<scoped_refptr<State>*>(context); + auto* state = reinterpret_cast<State*>(context); if (result == MOJO_RESULT_CANCELLED) { - // Last notification. Delete the watch's owned State ref. - delete state_ref; + // Last notification. Release the watch context's owned State ref. This is + // balanced in MessagePort::State::AddWatch. + state->Release(); } else { - (*state_ref)->OnHandleReady(result); + state->OnHandleReady(result); } }
diff --git a/content/common/message_port.h b/content/common/message_port.h index fbd7280a..d3d198c 100644 --- a/content/common/message_port.h +++ b/content/common/message_port.h
@@ -100,8 +100,6 @@ MojoResult result, MojoHandleSignalsState signals_state, MojoWatcherNotificationFlags flags); - - uintptr_t context_; }; mutable scoped_refptr<State> state_; };
diff --git a/content/common/sandbox_win.cc b/content/common/sandbox_win.cc index 789a7a8..b8474b6 100644 --- a/content/common/sandbox_win.cc +++ b/content/common/sandbox_win.cc
@@ -10,6 +10,7 @@ #include "base/base_switches.h" #include "base/command_line.h" +#include "base/debug/activity_tracker.h" #include "base/debug/profiler.h" #include "base/files/file_util.h" #include "base/hash.h" @@ -836,6 +837,13 @@ TRACE_EVENT_END0("startup", "StartProcessWithAccess::LAUNCHPROCESS"); + base::debug::GlobalActivityTracker* tracker = + base::debug::GlobalActivityTracker::Get(); + if (tracker) { + tracker->RecordProcessLaunch(target.process_id(), + cmd_line->GetCommandLineString()); + } + if (sandbox::SBOX_ALL_OK != result) { UMA_HISTOGRAM_SPARSE_SLOWLY("Process.Sandbox.Launch.Error", last_error); if (result == sandbox::SBOX_ERROR_GENERIC)
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 77d840f8..6a31d09f 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -233,6 +233,7 @@ "java/src/org/chromium/content_public/browser/SmartClipCallback.java", "java/src/org/chromium/content_public/browser/WebContents.java", "java/src/org/chromium/content_public/browser/WebContentsObserver.java", + "java/src/org/chromium/content_public/browser/WebContentsStatics.java", "java/src/org/chromium/content_public/common/MediaMetadata.java", "java/src/org/chromium/content_public/common/Referrer.java", "java/src/org/chromium/content_public/common/ResourceRequestBody.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java index ec7a125..081410e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
@@ -10,6 +10,7 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.content.browser.shapedetection.FaceDetectionProviderImpl; import org.chromium.content_public.browser.InterfaceRegistrar; +import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; import org.chromium.device.BatteryMonitor; import org.chromium.device.battery.BatteryMonitorFactory; @@ -43,6 +44,16 @@ InterfaceRegistrar.Registry.applyWebContentsRegistrars(registry, webContents); } + @CalledByNative + static void createInterfaceRegistryForRenderFrameHost( + int nativeHandle, RenderFrameHost renderFrameHost) { + ensureContentRegistrarsAreRegistered(); + + InterfaceRegistry registry = InterfaceRegistry.create( + CoreImpl.getInstance().acquireNativeHandle(nativeHandle).toMessagePipeHandle()); + InterfaceRegistrar.Registry.applyRenderFrameHostRegistrars(registry, renderFrameHost); + } + private static void ensureContentRegistrarsAreRegistered() { if (sHasRegisteredRegistrars) return; sHasRegisteredRegistrars = true;
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java index 90b9740..8a4526a9 100644 --- a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java
@@ -35,6 +35,11 @@ mNativeRenderFrameHostAndroid = 0; } + /** + * Get the delegate associated with this RenderFrameHost. + * + * @return The delegate associated with this RenderFrameHost. + */ public RenderFrameHostDelegate getRenderFrameHostDelegate() { return mDelegate; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 0f8738e..b942f907 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -21,7 +21,6 @@ import org.chromium.content.browser.AppWebMessagePort; import org.chromium.content.browser.MediaSessionImpl; import org.chromium.content.browser.framehost.RenderFrameHostDelegate; -import org.chromium.content.browser.framehost.RenderFrameHostImpl; import org.chromium.content_public.browser.AccessibilitySnapshotCallback; import org.chromium.content_public.browser.AccessibilitySnapshotNode; import org.chromium.content_public.browser.ContentBitmapCallback; @@ -96,14 +95,6 @@ } }; - public static WebContents fromRenderFrameHost(RenderFrameHost rfh) { - RenderFrameHostDelegate delegate = ((RenderFrameHostImpl) rfh).getRenderFrameHostDelegate(); - if (delegate == null || !(delegate instanceof WebContents)) { - return null; - } - return (WebContents) delegate; - } - private long mNativeWebContentsAndroid; private NavigationController mNavigationController; private RenderFrameHost mMainFrame;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java b/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java index 45b3ffe0..131260b 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java
@@ -25,6 +25,7 @@ public static class Registry<ParamType> { private static Registry<Context> sContextRegistry; private static Registry<WebContents> sWebContentsRegistry; + private static Registry<RenderFrameHost> sRenderFrameHostRegistry; private List<InterfaceRegistrar<ParamType>> mRegistrars = new ArrayList<InterfaceRegistrar<ParamType>>(); @@ -45,6 +46,14 @@ sWebContentsRegistry.applyRegistrars(interfaceRegistry, webContents); } + public static void applyRenderFrameHostRegistrars( + InterfaceRegistry interfaceRegistry, RenderFrameHost renderFrameHost) { + if (sRenderFrameHostRegistry == null) { + return; + } + sRenderFrameHostRegistry.applyRegistrars(interfaceRegistry, renderFrameHost); + } + public static void addContextRegistrar(InterfaceRegistrar<Context> registrar) { if (sContextRegistry == null) { sContextRegistry = new Registry<Context>(); @@ -59,6 +68,14 @@ sWebContentsRegistry.addRegistrar(registrar); } + public static void addRenderFrameHostRegistrar( + InterfaceRegistrar<RenderFrameHost> registrar) { + if (sRenderFrameHostRegistry == null) { + sRenderFrameHostRegistry = new Registry<RenderFrameHost>(); + } + sRenderFrameHostRegistry.addRegistrar(registrar); + } + private Registry() {} private void addRegistrar(InterfaceRegistrar<ParamType> registrar) {
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java new file mode 100644 index 0000000..ef580b17 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java
@@ -0,0 +1,24 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content_public.browser; + +import org.chromium.content.browser.framehost.RenderFrameHostDelegate; +import org.chromium.content.browser.framehost.RenderFrameHostImpl; + +/** + * Static public methods for WebContents. + */ +public class WebContentsStatics { + /** + * @return The WebContens associated witht the RenderFrameHost. This can be null. + */ + public static WebContents fromRenderFrameHost(RenderFrameHost rfh) { + RenderFrameHostDelegate delegate = ((RenderFrameHostImpl) rfh).getRenderFrameHostDelegate(); + if (delegate == null || !(delegate instanceof WebContents)) { + return null; + } + return (WebContents) delegate; + } +}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java index 508a224..6b01ef2 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java
@@ -20,6 +20,7 @@ import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.WebContentsStatics; import org.chromium.content_shell.Shell; import org.chromium.content_shell_apk.ContentShellActivity; import org.chromium.content_shell_apk.ContentShellActivityTestRule; @@ -355,7 +356,8 @@ Assert.assertEquals("RenderFrameHost has incorrect last committed URL", TEST_URL_2, frameHost.getLastCommittedURL()); - WebContents associatedWebContents = WebContentsImpl.fromRenderFrameHost(frameHost); + WebContents associatedWebContents = + WebContentsStatics.fromRenderFrameHost(frameHost); Assert.assertEquals("RenderFrameHost associated with different WebContents", webContents, associatedWebContents); }
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 78a5d95..0b21bea8 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -9,6 +9,7 @@ "ui::mojom::Gpu" ], "renderer": [ + "blink::mojom::BackgroundFetchService", "blink::mojom::BackgroundSyncService", "blink::mojom::BroadcastChannelProvider", "blink::mojom::BudgetService",
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index 4bb87a6..8e0425ad 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -224,6 +224,14 @@ // RenderFrame. See BindingsPolicy for details. virtual int GetEnabledBindings() const = 0; +#if defined(OS_ANDROID) + // Returns an InterfaceProvider for Java-implemented interfaces that are + // scoped to this RenderFrameHost. This provides access to interfaces + // implemented in Java in the browser process to C++ code in the browser + // process. + virtual service_manager::InterfaceProvider* GetJavaInterfaces() = 0; +#endif // OS_ANDROID + private: // This interface should only be implemented inside content. friend class RenderFrameHostImpl;
diff --git a/content/test/data/device_sensors/device_orientation_absolute_null_test.html b/content/test/data/device_sensors/device_orientation_absolute_null_test.html new file mode 100644 index 0000000..266ef00d --- /dev/null +++ b/content/test/data/device_sensors/device_orientation_absolute_null_test.html
@@ -0,0 +1,31 @@ +<html> + <head> + <title>DeviceOrientationAbsolute all-null event test</title> + </head> + <body> + <div id="status">FAIL</div> + </body> + <script type="text/javascript"> + function checkOrientationAbsoluteEvent(event) { + return event.alpha == null && + event.beta == null && + event.gamma == null; + } + + function onOrientationAbsolute(event) { + window.removeEventListener('deviceorientationabsolute', onOrientationAbsolute); + checkOrientationAbsoluteEvent(event) ? pass() : fail(); + } + + function pass() { + document.getElementById('status').innerHTML = 'PASS'; + document.location = '#pass'; + } + + function fail() { + document.location = '#fail'; + } + + window.addEventListener('deviceorientationabsolute', onOrientationAbsolute); + </script> +</html>
diff --git a/content/test/data/device_sensors/device_orientation_absolute_test.html b/content/test/data/device_sensors/device_orientation_absolute_test.html new file mode 100644 index 0000000..d35f18f --- /dev/null +++ b/content/test/data/device_sensors/device_orientation_absolute_test.html
@@ -0,0 +1,35 @@ +<html> + <head> + <title>DeviceOrientationAbsolute test</title> + <script type="text/javascript"> + function checkOrientationAbsoluteEvent(event) { + // Return true iff the orientation is close enough to (4, 5, 6). + return Math.abs(event.alpha - 4) < 0.01 && + Math.abs(event.beta - 5) < 0.01 && + Math.abs(event.gamma - 6) < 0.01 && + event.absolute == true; + } + + function onOrientationAbsolute(event) { + if (checkOrientationAbsoluteEvent(event)) { + window.removeEventListener('deviceorientationabsolute', onOrientationAbsolute); + pass(); + } else { + fail(); + } + } + + function pass() { + document.getElementById('status').innerHTML = 'PASS'; + document.location = '#pass'; + } + + function fail() { + document.location = '#fail'; + } + </script> + </head> + <body onLoad="window.addEventListener('deviceorientationabsolute', onOrientationAbsolute)"> + <div id="status">FAIL</div> + </body> +</html>
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index b2f53d0..015debfd 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -1619,6 +1619,15 @@ 'disabled_instrumentation_types': ['tsan'], } ], + 'disabled_tester_configs': [ + { + # The Mac ASAN swarming runs on two different GPU types so we can't + # have one expected vendor ID / device ID + 'names': [ + 'Mac GPU ASAN Release', + ], + }, + ], }, 'maps_pixel_test': { 'target_name': 'maps', @@ -1728,6 +1737,7 @@ # Run this on the FYI waterfall and optional tryservers. 'predicate': Predicates.FYI_AND_OPTIONAL, 'os_types': ['win'], + 'disabled_instrumentation_types': ['tsan'], } ], 'disabled_tester_configs': [ @@ -1749,6 +1759,7 @@ # Run this on the FYI waterfall and optional tryservers. 'predicate': Predicates.FYI_AND_OPTIONAL, 'os_types': ['win'], + 'disabled_instrumentation_types': ['tsan'], } ], 'disabled_tester_configs': [ @@ -1818,6 +1829,7 @@ # Run this on the FYI waterfall and optional tryservers. 'predicate': Predicates.FYI_AND_OPTIONAL, 'os_types': ['win'], + 'disabled_instrumentation_types': ['tsan'], } ], 'disabled_tester_configs': [ @@ -1846,6 +1858,7 @@ # Run this on the FYI waterfall and optional tryservers. 'predicate': Predicates.FYI_AND_OPTIONAL, 'os_types': ['linux'], + 'disabled_instrumentation_types': ['tsan'], } ], 'disabled_tester_configs': [ @@ -1967,6 +1980,7 @@ 'os': 'Windows-2008ServerR2-SP1' }, ], + 'disabled_instrumentation_types': ['tsan'], }, ], 'disabled_tester_configs': [
diff --git a/device/bluetooth/README.md b/device/bluetooth/README.md index 7ccda1f..f3c0ed89 100644 --- a/device/bluetooth/README.md +++ b/device/bluetooth/README.md
@@ -1,5 +1,4 @@ -Bluetooth -========= +# Bluetooth `device/bluetooth` abstracts [Bluetooth Classic](https://en.wikipedia.org/wiki/Bluetooth) and @@ -20,9 +19,12 @@ Chrome OS and Linux are supported via BlueZ, see `*_bluez` files. +[Mojo](https://www.chromium.org/developers/design-documents/mojo) +interfaces in [public/interfaces](public/interfaces) have been started +but are *not* ready for production use. -Maintainer History --------------------------------------------------------------------------------- + +## Maintainer History Initial implementation OWNERS were youngki@chromium.org, keybuk@chromium.org, armansito@chromium.org, and rpaquay@chromium.org. They no longer contribute to @@ -42,8 +44,7 @@ [Refactoring meta issue](https://crbug.com/580406). -Testing --------------------------------------------------------------------------------- +## Testing Implementation of the Bluetooth component is tested via unittests. Client code uses Mock Bluetooth objects: @@ -93,8 +94,7 @@ https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/client/cros/bluetooth/ -Android --------------------------------------------------------------------------------- +## Android The android implementation requires crossing from C++ to Java using [__JNI__](https://www.chromium.org/developers/design-documents/android-jni). @@ -130,8 +130,8 @@ [Class]: https://sites.google.com/a/chromium.org/dev/developers/design-documents/bluetooth-design-docs/web-bluetooth-through-bluetooth-android-class-diagram -Design Documents --------------------------------------------------------------------------------- + +## Design Documents * [Bluetooth Notifications](https://docs.google.com/document/d/1guBtAnQUP8ZoZre4VQGrjR5uX0ZYxfK-lwKNeqY0-z4/edit?usp=sharing) 2016-08-26 * Web Bluetooth through Android implementation details, class diagram and
diff --git a/device/bluetooth/public/interfaces/README.md b/device/bluetooth/public/interfaces/README.md new file mode 100644 index 0000000..cd9758c --- /dev/null +++ b/device/bluetooth/public/interfaces/README.md
@@ -0,0 +1,15 @@ +# Bluetooth + +Interfaces providing cross platform abstraction of [Bluetooth](../..). + +## Note + +These interfaces are NOT yet ready for production use by +other components. They are a start at a large task of producing +a service for device/bluetooth. Work was scoped to the miniumum +required to enable +[chrome://bluetooth-internals page][InternalsDesignDoc], and +long term design and testing were minimized to accomplish that. + +[InternalsDesignDoc]: https://docs.google.com/document/d/1wa96bCrB2Iw7tTI-fWsKmhLB7_ffF12frGIjRvhaj9E/edit#heading=h.2j0b11w2a292 +
diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index b9cb075..1d183bd 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc
@@ -103,6 +103,11 @@ return nullptr; } +NetworkingCastPrivateDelegate* +ExtensionsAPIClient::GetNetworkingCastPrivateDelegate() { + return nullptr; +} + #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* ExtensionsAPIClient::GetNonNativeFileSystemDelegate() {
diff --git a/extensions/browser/api/extensions_api_client.h b/extensions/browser/api/extensions_api_client.h index be47c88..e61cc0c 100644 --- a/extensions/browser/api/extensions_api_client.h +++ b/extensions/browser/api/extensions_api_client.h
@@ -38,6 +38,7 @@ class MetricsPrivateDelegate; class MimeHandlerViewGuest; class MimeHandlerViewGuestDelegate; +class NetworkingCastPrivateDelegate; class NonNativeFileSystemDelegate; class RulesCacheDelegate; class SettingsObserver; @@ -132,6 +133,9 @@ // MetricsPrivateAPI behavior. virtual MetricsPrivateDelegate* GetMetricsPrivateDelegate(); + // Creates a delegate for networking.castPrivate's API behavior. + virtual NetworkingCastPrivateDelegate* GetNetworkingCastPrivateDelegate(); + #if defined(OS_CHROMEOS) // If supported by the embedder, returns a delegate for querying non-native // file systems.
diff --git a/extensions/browser/api/networking_private/BUILD.gn b/extensions/browser/api/networking_private/BUILD.gn index b2b5f73..a362879 100644 --- a/extensions/browser/api/networking_private/BUILD.gn +++ b/extensions/browser/api/networking_private/BUILD.gn
@@ -6,6 +6,7 @@ source_set("networking_private") { sources = [ + "networking_cast_delegate.h", "networking_private_api.cc", "networking_private_api.h", "networking_private_chromeos.cc",
diff --git a/extensions/browser/api/networking_private/networking_cast_private_delegate.h b/extensions/browser/api/networking_private/networking_cast_private_delegate.h new file mode 100644 index 0000000..a7704ac --- /dev/null +++ b/extensions/browser/api/networking_private/networking_cast_private_delegate.h
@@ -0,0 +1,59 @@ +// 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 EXTENSIONS_BROWSER_API_NETWORKING_PRIVATE_NETWORKING_CAST_PRIVATE_DELEGATE_H_ +#define EXTENSIONS_BROWSER_API_NETWORKING_PRIVATE_NETWORKING_CAST_PRIVATE_DELEGATE_H_ + +#include <string> + +#include "base/callback.h" +#include "extensions/common/api/networking_private.h" + +namespace extensions { + +// Delegate interface that provides crypto methods needed to verify cast +// certificates and encrypt data using public key derived from the verified +// certificate. +// TODO(tbarzic): This is to be used during migration of +// networkingPrivate.verify* methods to networking.castPrivate API to share +// verification logic shared between networkingPrivate and +// networking.castPrivate API. When the deprecated networkingPrivate methods +// are removed, this interface should be removed, too. +class NetworkingCastPrivateDelegate { + public: + virtual ~NetworkingCastPrivateDelegate() {} + + using FailureCallback = base::Callback<void(const std::string& error)>; + using VerifiedCallback = base::Callback<void(bool is_valid)>; + using DataCallback = base::Callback<void(const std::string& encrypted_data)>; + + // Verifies that data provided in |properties| authenticates a cast device. + virtual void VerifyDestination( + const api::networking_private::VerificationProperties& properties, + const VerifiedCallback& success_callback, + const FailureCallback& failure_callback) = 0; + + // Verifies that data provided in |properties| authenticates a cast device. + // If the device is verified as a cast device, it fetches credentials of the + // network identified with |network_guid| and returns the network credentials + // encrypted with a public key derived from |properties|. + virtual void VerifyAndEncryptCredentials( + const std::string& network_guid, + const api::networking_private::VerificationProperties& properties, + const DataCallback& encrypted_credetials_callback, + const FailureCallback& failure_callback) = 0; + + // Verifies that data provided in |properties| authenticates a cast device. + // If the device is verified as a cast device, it returns |data| encrypted + // with a public key derived from |properties|. + virtual void VerifyAndEncryptData( + const std::string& data, + const api::networking_private::VerificationProperties& properties, + const DataCallback& enrypted_data_callback, + const FailureCallback& failure_callback) = 0; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_NETWORKING_PRIVATE_NETWORKING_CAST_PRIVATE_DELEGATE_H_
diff --git a/extensions/browser/api/networking_private/networking_private_delegate.h b/extensions/browser/api/networking_private/networking_private_delegate.h index a682742..66b1f12 100644 --- a/extensions/browser/api/networking_private/networking_private_delegate.h +++ b/extensions/browser/api/networking_private/networking_private_delegate.h
@@ -19,13 +19,6 @@ class NetworkingPrivateDelegateObserver; -namespace api { -namespace networking_private { -struct DeviceStateProperties; -struct VerificationProperties; -} // networking_private -} // api - // Base class for platform dependent networkingPrivate API implementations. // All inputs and results for this class use ONC values. See // networking_private.idl for descriptions of the expected inputs and results.
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index fd51439..3d5bc42 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1222,6 +1222,11 @@ AUDIO_SETMUTE, AUDIO_GETDEVICES, VIRTUALKEYBOARD_RESTRICTFEATURES, + NETWORKINGCASTPRIVATE_VERIFYDESTINATION, + NETWORKINGCASTPRIVATE_VERIFYANDENCRYPTCREDENTIALS, + NETWORKINGCASTPRIVATE_VERIFYANDENCRYPTDATA, + NETWORKINGCASTPRIVATE_SETWIFITDLSENABLEDSTATE, + NETWORKINGCASTPRIVATE_GETWIFITDLSSTATUS, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/common/api/networking_private.idl b/extensions/common/api/networking_private.idl index 6bbe086..3cd81883 100644 --- a/extensions/common/api/networking_private.idl +++ b/extensions/common/api/networking_private.idl
@@ -961,6 +961,7 @@ // is a trusted device. // |callback|: A callback function that indicates whether or not the device // is a trusted device. + [nodoc, deprecated = "Use networking.castPrivate API."] static void verifyDestination(VerificationProperties properties, BooleanCallback callback); @@ -971,6 +972,7 @@ // |networkGuid|: The GUID of the Cellular network to activate. // |callback|: A callback function that receives base64-encoded encrypted // credential data to send to a trusted device. + [nodoc, deprecated = "Use networking.castPrivate API."] static void verifyAndEncryptCredentials(VerificationProperties properties, DOMString networkGuid, StringCallback callback); @@ -982,6 +984,7 @@ // |data|: A string containing the base64-encoded data to encrypt. // |callback|: A callback function that receives base64-encoded encrypted // data to send to a trusted device. + [nodoc, deprecated = "Use networking.castPrivate API."] static void verifyAndEncryptData(VerificationProperties properties, DOMString data, StringCallback callback); @@ -995,6 +998,7 @@ // (e.g. MAC address lookup failed). 'Timeout' indicates that the lookup // timed out. Otherwise a valid status is returned (see // $(ref:getWifiTDLSStatus)). + [nodoc, deprecated = "Use networking.castPrivate API."] static void setWifiTDLSEnabledState(DOMString ip_or_mac_address, boolean enabled, optional StringCallback callback); @@ -1004,6 +1008,7 @@ // |callback|: A callback function that receives a string with the current // TDLS status which can be 'Connected', 'Disabled', 'Disconnected', // 'Nonexistent', or 'Unknown'. + [nodoc, deprecated = "Use networking.castPrivate API."] static void getWifiTDLSStatus(DOMString ip_or_mac_address, StringCallback callback);
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index 5c6f069..267ad25 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h
@@ -243,6 +243,7 @@ kClipboard, kNetworkingOnc, kVirtualKeyboard, + kNetworkingCastPrivate, // Last entry: Add new entries above and ensure to update the // "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml // (by running update_extension_permission.py).
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm index 02577800..ae1102c 100644 --- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm +++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
@@ -18,8 +18,8 @@ #import "ios/chrome/browser/passwords/password_generation_utils.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/web/public/url_scheme_util.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #include "ios/web/public/web_state/url_verification_constants.h" #include "ios/web/public/web_state/web_state.h" #include "url/gurl.h"
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller.mm b/ios/chrome/browser/autofill/form_suggestion_controller.mm index 343c368..3e96631 100644 --- a/ios/chrome/browser/autofill/form_suggestion_controller.mm +++ b/ios/chrome/browser/autofill/form_suggestion_controller.mm
@@ -21,8 +21,8 @@ #import "ios/chrome/browser/passwords/password_generation_utils.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/web/public/url_scheme_util.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #import "ios/web/public/web_state/web_state.h" namespace {
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm index 3d09d21..e65903e 100644 --- a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm +++ b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
@@ -16,7 +16,7 @@ #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/web/chrome_web_test.h" #include "ios/chrome/test/base/scoped_block_swizzler.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #import "ios/web/web_state/ui/crw_web_controller.h" #import "testing/gtest_mac.h" #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm index 3e021534..3d29a73b1 100644 --- a/ios/chrome/browser/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -189,9 +189,7 @@ // Tests "Open in New Tab" on context menu on a link that requires scrolling // on the page to verify that context menu can be properly triggered in the // current screen view. -// TODO(crbug.com/701104): This test is flaky because sometimes it doesn't -// scroll down far enough for the link to be visible. -- (void)FLAKY_testContextMenuOpenInNewTabFromTallPage { +- (void)testContextMenuOpenInNewTabFromTallPage { // Set up test simple http server. std::map<GURL, std::string> responses; GURL initialURL = @@ -211,10 +209,20 @@ chrome_test_util::AssertMainTabCount(1U); // Scroll down on the web view to make the link visible. + // grey_swipeFastInDirecton will quickly scroll towards the bottom, and then + // grey_scrollToContentEdge guarantees the content edge is reached. Two + // methods are used because the first one is much faster, but doesn't + // guarantee the link becomes visible. + // TODO(crbug.com/702272): Try to replace this with one EarlGrey method call. [[EarlGrey selectElementWithMatcher:WebViewScrollView( chrome_test_util::GetCurrentWebState())] performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; + [[EarlGrey + selectElementWithMatcher:WebViewScrollView( + chrome_test_util::GetCurrentWebState())] + performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( kDestinationLinkID)] assertWithMatcher:grey_notNil()];
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index 5b019f4..b3b4af4d8 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -76,9 +76,6 @@ // Whether the Payment Request API is enabled or not. bool IsPaymentRequestEnabled(); -// Whether the back-forward navigation uses pending index. -bool IsPendingIndexNavigationEnabled(); - // Whether the Physical Web feature is enabled. bool IsPhysicalWebEnabled();
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index 83cd531..6d6ef708 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -41,8 +41,6 @@ @"HeuristicsForPasswordGeneration"; NSString* const kMDMIntegrationDisabled = @"MDMIntegrationDisabled"; NSString* const kOriginServerHost = @"AlternateOriginServerHost"; -NSString* const kPendingIndexNavigationDisabled = - @"PendingIndexNavigationDisabled"; NSString* const kSafariVCSignInDisabled = @"SafariVCSignInDisabled"; NSString* const kWhatsNewPromoStatus = @"WhatsNewPromoStatus"; @@ -201,11 +199,6 @@ base::CompareCase::INSENSITIVE_ASCII); } -bool IsPendingIndexNavigationEnabled() { - return ![[NSUserDefaults standardUserDefaults] - boolForKey:kPendingIndexNavigationDisabled]; -} - bool IsPhysicalWebEnabled() { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kEnableIOSPhysicalWeb)) {
diff --git a/ios/chrome/browser/find_in_page/find_in_page_controller.mm b/ios/chrome/browser/find_in_page/find_in_page_controller.mm index 692d7f6e..18ac00f4 100644 --- a/ios/chrome/browser/find_in_page/find_in_page_controller.mm +++ b/ios/chrome/browser/find_in_page/find_in_page_controller.mm
@@ -14,9 +14,9 @@ #import "ios/chrome/browser/find_in_page/find_in_page_model.h" #import "ios/chrome/browser/find_in_page/js_findinpage_manager.h" #import "ios/chrome/browser/web/dom_altering_lock.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state_observer_bridge.h"
diff --git a/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm b/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm index 38cd267..06398da8 100644 --- a/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm +++ b/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm
@@ -10,8 +10,8 @@ #import "ios/chrome/browser/find_in_page/find_in_page_model.h" #import "ios/chrome/browser/find_in_page/js_findinpage_manager.h" #import "ios/chrome/browser/web/chrome_web_test.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #import "ios/web/public/web_state/web_state.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h index bfcec31..1ab57eb 100644 --- a/ios/chrome/browser/payments/payment_request.h +++ b/ios/chrome/browser/payments/payment_request.h
@@ -94,6 +94,13 @@ return shipping_profiles_; } + const std::vector<std::string>& supported_card_networks() const { + return supported_card_networks_; + } + + // Adds |credit_card| to the list of cached credit cards. + void AddCreditCard(std::unique_ptr<autofill::CreditCard> credit_card); + // Returns the available autofill credit cards for this user that match a // supported type specified in |web_payment_request_|. const std::vector<autofill::CreditCard*>& credit_cards() const { @@ -167,6 +174,9 @@ std::vector<autofill::CreditCard*> credit_cards_; autofill::CreditCard* selected_credit_card_; + // A vector of supported basic card networks. + std::vector<std::string> supported_card_networks_; + // A vector of pointers to the shipping options in |web_payment_request_|. std::vector<web::PaymentShippingOption*> shipping_options_; web::PaymentShippingOption* selected_shipping_option_;
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm index 68e0830..9d2109b 100644 --- a/ios/chrome/browser/payments/payment_request.mm +++ b/ios/chrome/browser/payments/payment_request.mm
@@ -4,8 +4,7 @@ #include "ios/chrome/browser/payments/payment_request.h" -#include <unordered_set> - +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_profile.h" @@ -53,6 +52,12 @@ return currency_formatter_.get(); } +void PaymentRequest::AddCreditCard( + std::unique_ptr<autofill::CreditCard> credit_card) { + credit_card_cache_.insert(credit_card_cache_.begin(), std::move(credit_card)); + credit_cards_.insert(credit_cards_.begin(), credit_card_cache_.front().get()); +} + void PaymentRequest::PopulateProfileCache() { for (const auto* profile : personal_data_manager_->GetProfilesToSuggest()) { profile_cache_.push_back( @@ -73,10 +78,14 @@ void PaymentRequest::PopulateCreditCardCache() { DCHECK(web_payment_request_); - std::unordered_set<base::string16> supported_method_types; for (const auto& method_data : web_payment_request_->method_data) { - for (const auto& supported_method : method_data.supported_methods) - supported_method_types.insert(supported_method); + for (const auto& supported_method : method_data.supported_methods) { + // Reject non-ASCII supported methods. + if (base::IsStringASCII(supported_method)) { + supported_card_networks_.push_back( + base::UTF16ToASCII(supported_method)); + } + } } std::vector<autofill::CreditCard*> credit_cards = @@ -91,8 +100,9 @@ std::string spec_card_type = autofill::data_util::GetPaymentRequestData(credit_card->type()) .basic_card_payment_type; - if (supported_method_types.find(base::ASCIIToUTF16(spec_card_type)) != - supported_method_types.end()) { + if (std::find(supported_card_networks_.begin(), + supported_card_networks_.end(), + spec_card_type) != supported_card_networks_.end()) { credit_card_cache_.push_back( base::MakeUnique<autofill::CreditCard>(*credit_card)); credit_cards_.push_back(credit_card_cache_.back().get());
diff --git a/ios/chrome/browser/payments/payment_request_manager.mm b/ios/chrome/browser/payments/payment_request_manager.mm index 95359fd..2b5f6c2 100644 --- a/ios/chrome/browser/payments/payment_request_manager.mm +++ b/ios/chrome/browser/payments/payment_request_manager.mm
@@ -27,8 +27,8 @@ #include "ios/web/public/payments/payment_request.h" #include "ios/web/public/ssl_status.h" #import "ios/web/public/url_scheme_util.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #include "ios/web/public/web_state/url_verification_constants.h" #include "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state_observer_bridge.h"
diff --git a/ios/chrome/browser/payments/payment_request_unittest.mm b/ios/chrome/browser/payments/payment_request_unittest.mm index 3e3470f..651404b 100644 --- a/ios/chrome/browser/payments/payment_request_unittest.mm +++ b/ios/chrome/browser/payments/payment_request_unittest.mm
@@ -8,6 +8,7 @@ #include "components/autofill/core/browser/test_personal_data_manager.h" #include "components/payments/core/currency_formatter.h" #include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/payments/payment_request_test_util.h" #include "ios/web/public/payments/payment_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,36 +21,71 @@ TEST(PaymentRequestTest, CreatesCurrencyFormatterCorrectly) { ASSERT_EQ("en", GetApplicationContext()->GetApplicationLocale()); + web::PaymentRequest web_payment_request; autofill::TestPersonalDataManager personal_data_manager; - std::unique_ptr<web::PaymentRequest> web_payment_request = - base::MakeUnique<web::PaymentRequest>(); - web_payment_request->details.total.amount.currency = - base::ASCIIToUTF16("USD"); - PaymentRequest payment_request1(std::move(web_payment_request), - &personal_data_manager); + web_payment_request.details.total.amount.currency = base::ASCIIToUTF16("USD"); + PaymentRequest payment_request1( + base::MakeUnique<web::PaymentRequest>(web_payment_request), + &personal_data_manager); payments::CurrencyFormatter* currency_formatter = payment_request1.GetOrCreateCurrencyFormatter(); - ASSERT_EQ(base::UTF8ToUTF16("$55.00"), currency_formatter->Format("55.00")); - ASSERT_EQ("USD", currency_formatter->formatted_currency_code()); + EXPECT_EQ(base::UTF8ToUTF16("$55.00"), currency_formatter->Format("55.00")); + EXPECT_EQ("USD", currency_formatter->formatted_currency_code()); - web_payment_request = base::MakeUnique<web::PaymentRequest>(); - web_payment_request->details.total.amount.currency = - base::ASCIIToUTF16("JPY"); - PaymentRequest payment_request2(std::move(web_payment_request), - &personal_data_manager); + web_payment_request.details.total.amount.currency = base::ASCIIToUTF16("JPY"); + PaymentRequest payment_request2( + base::MakeUnique<web::PaymentRequest>(web_payment_request), + &personal_data_manager); currency_formatter = payment_request2.GetOrCreateCurrencyFormatter(); - ASSERT_EQ(base::UTF8ToUTF16("¥55"), currency_formatter->Format("55.00")); - ASSERT_EQ("JPY", currency_formatter->formatted_currency_code()); + EXPECT_EQ(base::UTF8ToUTF16("¥55"), currency_formatter->Format("55.00")); + EXPECT_EQ("JPY", currency_formatter->formatted_currency_code()); - web_payment_request = base::MakeUnique<web::PaymentRequest>(); - web_payment_request->details.total.amount.currency_system = + web_payment_request.details.total.amount.currency_system = base::ASCIIToUTF16("NOT_ISO4217"); - web_payment_request->details.total.amount.currency = - base::ASCIIToUTF16("USD"); - PaymentRequest payment_request3(std::move(web_payment_request), - &personal_data_manager); + web_payment_request.details.total.amount.currency = base::ASCIIToUTF16("USD"); + PaymentRequest payment_request3( + base::MakeUnique<web::PaymentRequest>(web_payment_request), + &personal_data_manager); currency_formatter = payment_request3.GetOrCreateCurrencyFormatter(); - ASSERT_EQ(base::UTF8ToUTF16("55.00"), currency_formatter->Format("55.00")); - ASSERT_EQ("USD", currency_formatter->formatted_currency_code()); + EXPECT_EQ(base::UTF8ToUTF16("55.00"), currency_formatter->Format("55.00")); + EXPECT_EQ("USD", currency_formatter->formatted_currency_code()); +} + +// Tests that the accepted card networks are identified correctly. +TEST(PaymentRequestTest, AcceptedPaymentNetworks) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + web::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back(base::ASCIIToUTF16("visa")); + web_payment_request.method_data.push_back(method_datum1); + web::PaymentMethodData method_datum2; + method_datum2.supported_methods.push_back(base::ASCIIToUTF16("mastercard")); + web_payment_request.method_data.push_back(method_datum2); + + PaymentRequest payment_request( + base::MakeUnique<web::PaymentRequest>(web_payment_request), + &personal_data_manager); + ASSERT_EQ(2U, payment_request.supported_card_networks().size()); + EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); + EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); +} + +// Tests that credit cards can be added to the list of cached credit cards. +TEST(PaymentRequestTest, AddCreditCard) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + PaymentRequest payment_request( + base::MakeUnique<web::PaymentRequest>(web_payment_request), + &personal_data_manager); + EXPECT_EQ(0U, payment_request.credit_cards().size()); + + std::unique_ptr<autofill::CreditCard> credit_card = + payment_request_test_util::CreateTestCreditCard(); + const autofill::CreditCard* added_credit_card = credit_card.get(); + payment_request.AddCreditCard(std::move(credit_card)); + ASSERT_EQ(1U, payment_request.credit_cards().size()); + EXPECT_EQ(added_credit_card, payment_request.credit_cards()[0]); }
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist index 21aaa2e..6207de6 100644 --- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist +++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -6,16 +6,6 @@ <array> <dict> <key>Type</key> - <string>PSToggleSwitchSpecifier</string> - <key>Title</key> - <string>Disable pending index navigation</string> - <key>Key</key> - <string>PendingIndexNavigationDisabled</string> - <key>DefaultValue</key> - <false/> - </dict> - <dict> - <key>Type</key> <string>PSMultiValueSpecifier</string> <key>Title</key> <string>Enable SnapshotLRUCache</string>
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 7cbcff3..ee076d83 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -1319,10 +1319,6 @@ return NO; } -- (void)webWillFinishHistoryNavigation { - [parentTabModel_ notifyTabChanged:self]; -} - - (void)webState:(web::WebState*)webState didFinishNavigation:(web::NavigationContext*)navigation { if (navigation->IsSameDocument()) {
diff --git a/ios/chrome/browser/ui/DEPS b/ios/chrome/browser/ui/DEPS index 0a1586ac..1362209 100644 --- a/ios/chrome/browser/ui/DEPS +++ b/ios/chrome/browser/ui/DEPS
@@ -24,13 +24,13 @@ # TODO(crbug.com/620143): Remove these exceptions. "^fullscreen_controller_unittest\.mm$": [ - "+ios/web/web_state/crw_web_view_proxy_impl.h", + "+ios/web/web_state/ui/crw_web_view_proxy_impl.h", "+ios/web/web_state/ui/crw_web_controller.h", ], # TODO(crbug.com/620139): Remove these exceptions. "^fullscreen_controller_unittest\.mm$": [ - "+ios/web/web_state/crw_web_view_proxy_impl.h", + "+ios/web/web_state/ui/crw_web_view_proxy_impl.h", "+ios/web/web_state/ui/crw_web_controller.h", ],
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 976ed05..7bb68675 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -183,8 +183,8 @@ #include "ios/web/public/user_agent.h" #include "ios/web/public/web_client.h" #import "ios/web/public/web_state/context_menu_params.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" #import "ios/web/public/web_state/ui/crw_native_content_provider.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #include "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state_delegate_bridge.h" #include "ios/web/public/web_thread.h"
diff --git a/ios/chrome/browser/ui/contextual_search/contextual_search_controller.mm b/ios/chrome/browser/ui/contextual_search/contextual_search_controller.mm index 39bc9d8..cc6aacd 100644 --- a/ios/chrome/browser/ui/contextual_search/contextual_search_controller.mm +++ b/ios/chrome/browser/ui/contextual_search/contextual_search_controller.mm
@@ -50,9 +50,9 @@ #include "ios/web/public/browser_state.h" #include "ios/web/public/load_committed_details.h" #include "ios/web/public/referrer.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #include "ios/web/public/web_state/web_state.h" #include "ios/web/public/web_state/web_state_observer.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ios/chrome/browser/ui/contextual_search/contextual_search_results_view.mm b/ios/chrome/browser/ui/contextual_search/contextual_search_results_view.mm index f9145f5..f669e27 100644 --- a/ios/chrome/browser/ui/contextual_search/contextual_search_results_view.mm +++ b/ios/chrome/browser/ui/contextual_search/contextual_search_results_view.mm
@@ -14,9 +14,9 @@ #import "ios/chrome/browser/ui/contextual_search/contextual_search_web_state_observer.h" #import "ios/chrome/common/material_timing.h" #include "ios/web/public/load_committed_details.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/ui/crw_native_content_provider.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/web_state/ui/crw_web_controller.h" namespace {
diff --git a/ios/chrome/browser/ui/fullscreen_controller.h b/ios/chrome/browser/ui/fullscreen_controller.h index 14dbd25c..33c65bce 100644 --- a/ios/chrome/browser/ui/fullscreen_controller.h +++ b/ios/chrome/browser/ui/fullscreen_controller.h
@@ -8,7 +8,7 @@ #import <UIKit/UIKit.h> #import "ios/web/public/web_state/crw_web_controller_observer.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" namespace ios_internal { // Duration of the toolbar animation.
diff --git a/ios/chrome/browser/ui/fullscreen_controller.mm b/ios/chrome/browser/ui/fullscreen_controller.mm index cf4902f..2d37826 100644 --- a/ios/chrome/browser/ui/fullscreen_controller.mm +++ b/ios/chrome/browser/ui/fullscreen_controller.mm
@@ -17,7 +17,7 @@ #include "ios/web/public/navigation_item.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/ssl_status.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" #import "ios/web/web_state/ui/crw_web_controller.h" NSString* const kSetupForTestingWillCloseAllTabsNotification =
diff --git a/ios/chrome/browser/ui/fullscreen_controller_unittest.mm b/ios/chrome/browser/ui/fullscreen_controller_unittest.mm index 0e3aec6..854a15bd 100644 --- a/ios/chrome/browser/ui/fullscreen_controller_unittest.mm +++ b/ios/chrome/browser/ui/fullscreen_controller_unittest.mm
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/mac/scoped_nsobject.h" #import "ios/chrome/browser/ui/fullscreen_controller.h" + +#include "base/mac/scoped_nsobject.h" #import "ios/web/public/test/fakes/test_web_view_content_view.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/ui/crw_web_view_content_view.h" -#import "ios/web/web_state/crw_web_view_proxy_impl.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/web_state/ui/crw_web_controller.h" +#import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/ocmock_extensions.h"
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h index 1715bd3..825d261 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h
@@ -10,7 +10,7 @@ #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" #import "ios/chrome/browser/ui/util/relaxed_bounds_constraints_hittest.h" #import "ios/web/public/web_state/crw_web_controller_observer.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" @class OverscrollActionsController;
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm index 2016efe8..fbec30a 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
@@ -18,7 +18,7 @@ #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" #include "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h" -#import "ios/web/public/web_state/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" namespace { // This enum is used to record the overscroll actions performed by the user on
diff --git a/ios/chrome/browser/web/visible_url_egtest.mm b/ios/chrome/browser/web/visible_url_egtest.mm index f14423f..364fb65 100644 --- a/ios/chrome/browser/web/visible_url_egtest.mm +++ b/ios/chrome/browser/web/visible_url_egtest.mm
@@ -7,14 +7,12 @@ #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" -#include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" -#import "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/web/public/test/http_server.h" #include "ios/web/public/test/http_server_util.h" #include "ios/web/public/test/response_providers/html_response_provider.h" @@ -175,10 +173,6 @@ // Tests that visible URL is always the same as last committed URL during // pending back and forward navigations. - (void)testBackForwardNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -225,10 +219,6 @@ // Tests that visible URL is always the same as last committed URL during // pending navigations initialted from back history popover. - (void)testHistoryNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -258,10 +248,6 @@ // Tests that stopping a pending Back navigation and reloading reloads committed // URL, not pending URL. - (void)testStoppingPendingBackNavigationAndReload { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -295,10 +281,6 @@ // Tests that visible URL is always the same as last committed URL during // back forward navigations initiated with JS. - (void)testJSBackForwardNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -344,10 +326,6 @@ // Tests that visible URL is always the same as last committed URL during go // navigations initiated with JS. - (void)testJSGoNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -394,10 +372,6 @@ // Tests that visible URL is always the same as last committed URL during go // back navigation started with pending reload in progress. - (void)testBackNavigationWithPendingReload { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -436,10 +410,6 @@ // back navigation initiated with pending renderer-initiated navigation in // progress. - (void)testBackNavigationWithPendingRendererInitiatedNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -470,10 +440,6 @@ // renderer-initiated navigation started with pending back navigation in // progress. - (void)testRendererInitiatedNavigationWithPendingBackNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Purge web view caches and pause the server to make sure that tests can // verify omnibox state before server starts responding. PurgeCachedWebViewPages(); @@ -504,10 +470,6 @@ // Tests that visible URL is always the same as last committed URL if user // issues 2 go back commands. - (void)testDoubleBackNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Create 3rd entry in the history, to be able to go back twice. [ChromeEarlGrey loadURL:_testURL3]; @@ -539,10 +501,6 @@ // Tests that visible URL is always the same as last committed URL if page calls // window.history.back() twice. - (void)testDoubleBackJSNavigation { - if (!experimental_flags::IsPendingIndexNavigationEnabled()) { - EARL_GREY_TEST_SKIPPED(@"Pending Index Navigation experiment is disabled"); - } - // Create 3rd entry in the history, to be able to go back twice. [ChromeEarlGrey loadURL:_testURL3];
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 2c904e9..58b9936 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -144,8 +144,6 @@ "public/web_state/context_menu_params.h", "public/web_state/credential.h", "public/web_state/crw_web_controller_observer.h", - "public/web_state/crw_web_view_proxy.h", - "public/web_state/crw_web_view_scroll_view_proxy.h", "public/web_state/global_web_state_observer.h", "public/web_state/js/credential_util.h", "public/web_state/js/crw_js_injection_evaluator.h", @@ -161,6 +159,8 @@ "public/web_state/ui/crw_native_content_provider.h", "public/web_state/ui/crw_web_delegate.h", "public/web_state/ui/crw_web_view_content_view.h", + "public/web_state/ui/crw_web_view_proxy.h", + "public/web_state/ui/crw_web_view_scroll_view_proxy.h", "public/web_state/url_verification_constants.h", "public/web_state/web_state.h", "public/web_state/web_state_delegate.h", @@ -188,9 +188,6 @@ "web_state/credential.cc", "web_state/crw_pass_kit_downloader.h", "web_state/crw_pass_kit_downloader.mm", - "web_state/crw_web_view_proxy_impl.h", - "web_state/crw_web_view_proxy_impl.mm", - "web_state/crw_web_view_scroll_view_proxy.mm", "web_state/error_translation_util.h", "web_state/error_translation_util.mm", "web_state/global_web_state_event_tracker.h", @@ -217,6 +214,9 @@ "web_state/ui/crw_swipe_recognizer_provider.h", "web_state/ui/crw_touch_tracking_recognizer.h", "web_state/ui/crw_touch_tracking_recognizer.mm", + "web_state/ui/crw_web_view_proxy_impl.h", + "web_state/ui/crw_web_view_proxy_impl.mm", + "web_state/ui/crw_web_view_scroll_view_proxy.mm", "web_state/ui/crw_wk_navigation_states.h", "web_state/ui/crw_wk_navigation_states.mm", "web_thread_impl.cc", @@ -566,7 +566,6 @@ "url_util_unittest.cc", "web_state/context_menu_params_utils_unittest.mm", "web_state/crw_pass_kit_downloader_unittest.mm", - "web_state/crw_web_view_scroll_view_proxy_unittest.mm", "web_state/error_translation_util_unittest.mm", "web_state/js/common_js_unittest.mm", "web_state/js/core_js_unittest.mm", @@ -580,6 +579,7 @@ "web_state/ui/crw_web_controller_container_view_unittest.mm", "web_state/ui/crw_web_controller_observer_unittest.mm", "web_state/ui/crw_web_controller_unittest.mm", + "web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm", "web_state/ui/crw_wk_navigation_states_unittest.mm", "web_state/ui/crw_wk_script_message_router_unittest.mm", "web_state/ui/web_view_js_utils_unittest.mm",
diff --git a/ios/web/interstitials/web_interstitial_impl.mm b/ios/web/interstitials/web_interstitial_impl.mm index 30698e6..1a9febb4 100644 --- a/ios/web/interstitials/web_interstitial_impl.mm +++ b/ios/web/interstitials/web_interstitial_impl.mm
@@ -84,19 +84,12 @@ // Clear the pending entry, since that's the page that's not being // proceeded to. - NavigationManager* nav_manager = GetWebStateImpl()->GetNavigationManager(); - nav_manager->DiscardNonCommittedItems(); + GetWebStateImpl()->GetNavigationManager()->DiscardNonCommittedItems(); Hide(); GetDelegate()->OnDontProceed(); - NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; - if (![user_defaults boolForKey:@"PendingIndexNavigationDisabled"]) { - // Reload last committed entry. - nav_manager->Reload(ReloadType::NORMAL, true /* check_for_repost */); - } - delete this; }
diff --git a/ios/web/public/test/web_view_interaction_test_util.mm b/ios/web/public/test/web_view_interaction_test_util.mm index aa1baf60..f29ee56 100644 --- a/ios/web/public/test/web_view_interaction_test_util.mm +++ b/ios/web/public/test/web_view_interaction_test_util.mm
@@ -9,9 +9,9 @@ #include "base/strings/utf_string_conversions.h" #import "base/test/ios/wait_util.h" #import "ios/testing/wait_util.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" -#import "ios/web/web_state/crw_web_view_proxy_impl.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/web_state/ui/crw_web_controller.h" +#import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #import "ios/web/web_state/web_state_impl.h" using web::NavigationManager;
diff --git a/ios/web/public/web_state/ui/crw_web_delegate.h b/ios/web/public/web_state/ui/crw_web_delegate.h index 2be85fc96..9fe0df2b 100644 --- a/ios/web/public/web_state/ui/crw_web_delegate.h +++ b/ios/web/public/web_state/ui/crw_web_delegate.h
@@ -58,9 +58,6 @@ - (void)webDidUpdateSessionForLoadWithParams: (const web::NavigationManager::WebLoadParams&)params wasInitialNavigation:(BOOL)initialNavigation; -// Called from finishHistoryNavigationFromEntry. -// TODO(crbug.com/692331): Remove this method and use |DidFinishNavigation|. -- (void)webWillFinishHistoryNavigation; @optional
diff --git a/ios/web/public/web_state/crw_web_view_proxy.h b/ios/web/public/web_state/ui/crw_web_view_proxy.h similarity index 93% rename from ios/web/public/web_state/crw_web_view_proxy.h rename to ios/web/public/web_state/ui/crw_web_view_proxy.h index 81125e7..7a5768c7 100644 --- a/ios/web/public/web_state/crw_web_view_proxy.h +++ b/ios/web/public/web_state/ui/crw_web_view_proxy.h
@@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_WEB_STATE_CRW_WEB_VIEW_PROXY_H_ -#define IOS_WEB_PUBLIC_WEB_STATE_CRW_WEB_VIEW_PROXY_H_ +#ifndef IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_WEB_VIEW_PROXY_H_ +#define IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_WEB_VIEW_PROXY_H_ #import <UIKit/UIKit.h> - @class CRWWebViewScrollViewProxy; // Provides an interface for embedders to access the WebState's web view in a @@ -74,4 +73,4 @@ @end -#endif // IOS_WEB_PUBLIC_WEB_STATE_CRW_WEB_VIEW_PROXY_H_ +#endif // IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_WEB_VIEW_PROXY_H_
diff --git a/ios/web/public/web_state/crw_web_view_scroll_view_proxy.h b/ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h similarity index 85% rename from ios/web/public/web_state/crw_web_view_scroll_view_proxy.h rename to ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h index 89f432f..93032cc 100644 --- a/ios/web/public/web_state/crw_web_view_scroll_view_proxy.h +++ b/ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.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_WEB_PUBLIC_WEB_STATE_CRW_WEB_VIEW_SCROLL_VIEW_PROXY_H_ -#define IOS_WEB_PUBLIC_WEB_STATE_CRW_WEB_VIEW_SCROLL_VIEW_PROXY_H_ +#ifndef IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_WEB_VIEW_SCROLL_VIEW_PROXY_H_ +#define IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_WEB_VIEW_SCROLL_VIEW_PROXY_H_ #import <UIKit/UIKit.h> @@ -58,9 +58,9 @@ @protocol CRWWebViewScrollViewObserver<NSObject> @optional - (void)webViewScrollViewDidScroll: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewWillBeginDragging: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewWillEndDragging: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy withVelocity:(CGPoint)velocity @@ -69,13 +69,13 @@ (CRWWebViewScrollViewProxy*)webViewScrollViewProxy willDecelerate:(BOOL)decelerate; - (void)webViewScrollViewDidEndScrollingAnimation: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewDidEndDecelerating: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (BOOL)webViewScrollViewShouldScrollToTop: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewDidZoom: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; - (void)webViewScrollViewDidResetContentSize: (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; @end @@ -88,7 +88,7 @@ @optional // Called when the underlying scrollview of the proxy is set. - (void)webViewScrollViewProxyDidSetScrollView: - (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; + (CRWWebViewScrollViewProxy*)webViewScrollViewProxy; @end -#endif // IOS_WEB_PUBLIC_WEB_STATE_CRW_WEB_VIEW_SCROLL_VIEW_PROXY_H_ +#endif // IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_WEB_VIEW_SCROLL_VIEW_PROXY_H_
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 199b341..4d638b3 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -64,7 +64,6 @@ #import "ios/web/public/web_state/context_menu_params.h" #include "ios/web/public/web_state/credential.h" #import "ios/web/public/web_state/crw_web_controller_observer.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" #include "ios/web/public/web_state/js/credential_util.h" #import "ios/web/public/web_state/js/crw_js_injection_manager.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" @@ -74,11 +73,11 @@ #import "ios/web/public/web_state/ui/crw_native_content.h" #import "ios/web/public/web_state/ui/crw_native_content_provider.h" #import "ios/web/public/web_state/ui/crw_web_view_content_view.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #include "ios/web/public/web_state/url_verification_constants.h" #import "ios/web/public/web_state/web_state.h" #include "ios/web/public/webui/web_ui_ios.h" #import "ios/web/web_state/crw_pass_kit_downloader.h" -#import "ios/web/web_state/crw_web_view_proxy_impl.h" #import "ios/web/web_state/error_translation_util.h" #import "ios/web/web_state/js/crw_js_plugin_placeholder_manager.h" #import "ios/web/web_state/js/crw_js_post_request_loader.h" @@ -88,6 +87,7 @@ #import "ios/web/web_state/ui/crw_swipe_recognizer_provider.h" #import "ios/web/web_state/ui/crw_web_controller.h" #import "ios/web/web_state/ui/crw_web_controller_container_view.h" +#import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #import "ios/web/web_state/ui/crw_wk_navigation_states.h" #import "ios/web/web_state/ui/crw_wk_script_message_router.h" #import "ios/web/web_state/ui/wk_back_forward_list_item_holder.h" @@ -476,11 +476,6 @@ // unless the request was a POST. @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; -// TODO(crbug.com/684098): Remove these methods and inline their content. -// Called before finishing a history navigation from a page with the given -// UserAgentType. -- (void)webWillFinishHistoryNavigationWithPreviousUserAgentType: - (web::UserAgentType)userAgentType; // Requires page reconstruction if |item| has a non-NONE UserAgentType and it // differs from that of |fromItem|. - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item @@ -603,13 +598,6 @@ // bounds. Reloads if delta is 0. // TODO(crbug.com/661316): Move this method to NavigationManager. - (void)goDelta:(int)delta; -// Loads a new URL if the current entry is not from a pushState() navigation. -// |fromURL| is the URL of the previous NavigationItem, |fromUserAgentType| is -// that item's UserAgentType, and |sameDocument| is YES if the navigation is -// between two pages with the same document. -- (void)finishHistoryNavigationFromURL:(const GURL&)fromURL - userAgentType:(web::UserAgentType)fromUserAgentType - sameDocument:(BOOL)sameDocument; // Informs the native controller if web usage is allowed or not. - (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; // Called when web controller receives a new message from the web page. @@ -718,11 +706,6 @@ // Returns YES if the given WKBackForwardListItem is valid to use for // navigation. - (BOOL)isBackForwardListItemValid:(WKBackForwardListItem*)item; -// Compares the two URLs being navigated between during a history navigation to -// determine if a # needs to be appended to the URL of |toItem| to trigger a -// hashchange event. If so, also saves the modified URL into |toItem|. -- (GURL)URLForHistoryNavigationToItem:(web::NavigationItem*)toItem - previousURL:(const GURL&)previousURL; // Finds all the scrollviews in the view hierarchy and makes sure they do not // interfere with scroll to top when tapping the statusbar. - (void)optOutScrollsToTopForSubviews; @@ -1407,40 +1390,6 @@ [list.backList indexOfObject:item] != NSNotFound; } -- (GURL)URLForHistoryNavigationToItem:(web::NavigationItem*)toItem - previousURL:(const GURL&)previousURL { - // If navigating with native API, i.e. using a back forward list item, - // hashchange events will be triggered automatically, so no URL tampering is - // required. - web::WKBackForwardListItemHolder* holder = - web::WKBackForwardListItemHolder::FromNavigationItem(toItem); - if (holder->back_forward_list_item()) { - return toItem->GetURL(); - } - - const GURL& URL = toItem->GetURL(); - - // Check the state of the fragments on both URLs (aka, is there a '#' in the - // url or not). - if (!previousURL.has_ref() || URL.has_ref()) { - return URL; - } - - // startURL contains a fragment and endURL doesn't. Remove the fragment from - // startURL and compare the resulting string to endURL. If they are equal, add - // # to endURL to cause a hashchange event. - GURL hashless = web::GURLByRemovingRefFromGURL(previousURL); - - if (hashless != URL) - return URL; - - url::StringPieceReplacements<std::string> emptyRef; - emptyRef.SetRefStr(""); - GURL newEndURL = URL.ReplaceComponents(emptyRef); - toItem->SetURL(newEndURL); - return newEndURL; -} - - (void)injectWindowID { // Default value for shouldSuppressDialogs is NO, so updating them only // when necessary is a good optimization. @@ -1846,56 +1795,42 @@ NavigationManager::WebLoadParams params(originalParams); // Initiating a navigation from the UI, record the current page state before - // the new page loads. Don't record for back/forward, as the current entry - // has already been moved to the next entry in the history. Do, however, - // record it for general reload. - // TODO(jimblackler): consider a single unified call to record state whenever - // the page is about to be changed. This cannot currently be done after - // addPendingItem is called. + // the new page loads. [_delegate webWillInitiateLoadWithParams:params]; GURL navUrl = params.url; ui::PageTransition transition = params.transition_type; + DCHECK(!(transition & ui::PAGE_TRANSITION_FORWARD_BACK)); + DCHECK(!(transition & ui::PAGE_TRANSITION_RELOAD)); BOOL initialNavigation = NO; - BOOL forwardBack = - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) && - (transition & ui::PAGE_TRANSITION_FORWARD_BACK); - if (forwardBack) { - // Setting these for back/forward is not supported. - DCHECK(!params.extra_headers); - DCHECK(!params.post_data); - } else { - // Clear transient view before making any changes to history and navigation - // manager. TODO(stuartmorgan): Drive Transient Item clearing from - // navigation system, rather than from WebController. - [self clearTransientContentView]; + // Clear transient view before making any changes to history and navigation + // manager. TODO(stuartmorgan): Drive Transient Item clearing from + // navigation system, rather than from WebController. + [self clearTransientContentView]; - // TODO(stuartmorgan): Why doesn't recordStateInHistory get called for - // forward/back transitions? - [self recordStateInHistory]; + [self recordStateInHistory]; - if (!self.currentNavItem) - initialNavigation = YES; + if (!self.currentNavItem) + initialNavigation = YES; - web::NavigationInitiationType navigationInitiationType = - params.is_renderer_initiated - ? web::NavigationInitiationType::RENDERER_INITIATED - : web::NavigationInitiationType::USER_INITIATED; - self.navigationManagerImpl->AddPendingItem( - navUrl, params.referrer, transition, navigationInitiationType); + web::NavigationInitiationType navigationInitiationType = + params.is_renderer_initiated + ? web::NavigationInitiationType::RENDERER_INITIATED + : web::NavigationInitiationType::USER_INITIATED; + self.navigationManagerImpl->AddPendingItem( + navUrl, params.referrer, transition, navigationInitiationType); - web::NavigationItemImpl* addedItem = self.currentNavItem; - DCHECK(addedItem); - if (params.extra_headers) - addedItem->AddHttpRequestHeaders(params.extra_headers); - if (params.post_data) { - DCHECK([addedItem->GetHttpRequestHeaders() objectForKey:@"Content-Type"]) - << "Post data should have an associated content type"; - addedItem->SetPostData(params.post_data); - addedItem->SetShouldSkipRepostFormConfirmation(true); - } + web::NavigationItemImpl* addedItem = self.currentNavItem; + DCHECK(addedItem); + if (params.extra_headers) + addedItem->AddHttpRequestHeaders(params.extra_headers); + if (params.post_data) { + DCHECK([addedItem->GetHttpRequestHeaders() objectForKey:@"Content-Type"]) + << "Post data should have an associated content type"; + addedItem->SetPostData(params.post_data); + addedItem->SetShouldSkipRepostFormConfirmation(true); } [_delegate webDidUpdateSessionForLoadWithParams:params @@ -2099,44 +2034,32 @@ if (!_webStateImpl->IsShowingWebInterstitial()) [self recordStateInHistory]; + [self clearTransientContentView]; + + // Update the user agent before attempting the navigation. + web::NavigationItem* toItem = items[index].get(); web::NavigationItem* previousItem = sessionController.currentItem; - GURL previousURL = previousItem ? previousItem->GetURL() : GURL::EmptyGURL(); web::UserAgentType previousUserAgentType = previousItem ? previousItem->GetUserAgentType() : web::UserAgentType::NONE; - web::NavigationItem* toItem = items[index].get(); + [self updateDesktopUserAgentForItem:toItem + previousUserAgentType:previousUserAgentType]; + BOOL sameDocumentNavigation = [sessionController isSameDocumentNavigationBetweenItem:previousItem andItem:toItem]; - - NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; - if (![userDefaults boolForKey:@"PendingIndexNavigationDisabled"]) { - [self clearTransientContentView]; - - // Update the user agent before attempting the navigation. - [self updateDesktopUserAgentForItem:toItem - previousUserAgentType:previousUserAgentType]; - - if (sameDocumentNavigation) { - [sessionController goToItemAtIndex:index]; - [self updateHTML5HistoryState]; - } else { - [sessionController discardNonCommittedItems]; - [sessionController setPendingItemIndex:index]; - - web::NavigationItemImpl* pendingItem = sessionController.pendingItem; - pendingItem->SetTransitionType(ui::PageTransitionFromInt( - pendingItem->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK)); - - [self loadCurrentURL]; - } - } else { + if (sameDocumentNavigation) { [sessionController goToItemAtIndex:index]; - if (previousURL.is_valid()) { - [self finishHistoryNavigationFromURL:previousURL - userAgentType:previousUserAgentType - sameDocument:sameDocumentNavigation]; - } + [self updateHTML5HistoryState]; + } else { + [sessionController discardNonCommittedItems]; + [sessionController setPendingItemIndex:index]; + + web::NavigationItemImpl* pendingItem = sessionController.pendingItem; + pendingItem->SetTransitionType(ui::PageTransitionFromInt( + pendingItem->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK)); + + [self loadCurrentURL]; } } @@ -2230,38 +2153,6 @@ } } -- (void)finishHistoryNavigationFromURL:(const GURL&)fromURL - userAgentType:(web::UserAgentType)fromUserAgentType - sameDocument:(BOOL)sameDocument { - [self webWillFinishHistoryNavigationWithPreviousUserAgentType: - fromUserAgentType]; - - // Only load the new URL if it has a different document than |fromEntry| to - // prevent extra page loads from NavigationItems created by hash changes or - // calls to window.history.pushState(). - web::NavigationItem* currentItem = self.currentNavItem; - GURL endURL = - [self URLForHistoryNavigationToItem:currentItem previousURL:fromURL]; - if (!sameDocument) { - ui::PageTransition transition = ui::PageTransitionFromInt( - ui::PAGE_TRANSITION_RELOAD | ui::PAGE_TRANSITION_FORWARD_BACK); - - NavigationManager::WebLoadParams params(endURL); - if (currentItem) { - params.referrer = currentItem->GetReferrer(); - } - params.transition_type = transition; - [self loadWithParams:params]; - } - // If this is a same-document navigation, update the HTML5 history state - // immediately. For cross-document navigations, the history state will be - // updated after the navigation is committed, as attempting to replace the URL - // here will result in a JavaScript SecurityError due to the URLs having - // different origins. - if (sameDocument) - [self updateHTML5HistoryState]; -} - - (void)addGestureRecognizerToWebView:(UIGestureRecognizer*)recognizer { if ([_gestureRecognizers containsObject:recognizer]) return; @@ -2351,13 +2242,6 @@ return _passKitDownloader.get(); } -- (void)webWillFinishHistoryNavigationWithPreviousUserAgentType: - (web::UserAgentType)userAgentType { - [self updateDesktopUserAgentForItem:self.currentNavItem - previousUserAgentType:userAgentType]; - [_delegate webWillFinishHistoryNavigation]; -} - - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item previousUserAgentType:(web::UserAgentType)userAgentType { if (!item)
diff --git a/ios/web/web_state/ui/crw_web_controller_container_view.mm b/ios/web/web_state/ui/crw_web_controller_container_view.mm index 6db54ac..9c7ae37 100644 --- a/ios/web/web_state/ui/crw_web_controller_container_view.mm +++ b/ios/web/web_state/ui/crw_web_controller_container_view.mm
@@ -10,7 +10,7 @@ #import "ios/web/public/web_state/ui/crw_content_view.h" #import "ios/web/public/web_state/ui/crw_native_content.h" #import "ios/web/public/web_state/ui/crw_web_view_content_view.h" -#import "ios/web/web_state/crw_web_view_proxy_impl.h" +#import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #pragma mark - CRWToolbarContainerView
diff --git a/ios/web/web_state/ui/crw_web_controller_container_view_unittest.mm b/ios/web/web_state/ui/crw_web_controller_container_view_unittest.mm index fa4f0af..207b0ba 100644 --- a/ios/web/web_state/ui/crw_web_controller_container_view_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_container_view_unittest.mm
@@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "base/mac/scoped_nsobject.h" -#import "ios/web/web_state/crw_web_view_proxy_impl.h" #import "ios/web/web_state/ui/crw_web_controller_container_view.h" + +#import "base/mac/scoped_nsobject.h" +#import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" #include "testing/platform_test.h" -#include "third_party/ocmock/gtest_support.h" #import "third_party/ocmock/OCMock/OCMock.h" +#include "third_party/ocmock/gtest_support.h" namespace { // The frame of CRWWebControllerContainerViewTest's |container_view_|.
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index 8e78518..41998a4 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -50,8 +50,6 @@ @interface CRWWebController (PrivateAPI) @property(nonatomic, readwrite) web::PageDisplayState pageDisplayState; -- (GURL)URLForHistoryNavigationToItem:(web::NavigationItem*)toItem - previousURL:(const GURL&)previousURL; @end @interface CountingObserver : NSObject<CRWWebControllerObserver> @@ -170,72 +168,6 @@ base::scoped_nsobject<id> mock_web_view_; }; -#define MAKE_URL(url_string) GURL([url_string UTF8String]) - -TEST_F(CRWWebControllerTest, UrlForHistoryNavigation) { - NSArray* urls_without_fragments = @[ - @"http://one.com", @"http://two.com/", @"http://three.com/bar", - @"http://four.com/bar/", @"five", @"/six", @"/seven/", @"" - ]; - - NSArray* fragments = @[ @"#", @"#bar" ]; - NSMutableArray* urls_with_fragments = [NSMutableArray array]; - for (NSString* url in urls_without_fragments) { - for (NSString* fragment in fragments) { - [urls_with_fragments addObject:[url stringByAppendingString:fragment]]; - } - } - - GURL previous_url; - web::NavigationItemImpl to_item; - - // No start fragment: the end url is never changed. - for (NSString* start in urls_without_fragments) { - for (NSString* end in urls_with_fragments) { - previous_url = MAKE_URL(start); - to_item.SetURL(MAKE_URL(end)); - EXPECT_EQ(MAKE_URL(end), - [web_controller() URLForHistoryNavigationToItem:&to_item - previousURL:previous_url]); - } - } - // Both contain fragments: the end url is never changed. - for (NSString* start in urls_with_fragments) { - for (NSString* end in urls_with_fragments) { - previous_url = MAKE_URL(start); - to_item.SetURL(MAKE_URL(end)); - EXPECT_EQ(MAKE_URL(end), - [web_controller() URLForHistoryNavigationToItem:&to_item - previousURL:previous_url]); - } - } - for (unsigned start_index = 0; start_index < urls_with_fragments.count; - ++start_index) { - NSString* start = urls_with_fragments[start_index]; - for (unsigned end_index = 0; end_index < urls_without_fragments.count; - ++end_index) { - NSString* end = urls_without_fragments[end_index]; - previous_url = MAKE_URL(start); - if (start_index / 2 != end_index) { - // The URLs have nothing in common, they are left untouched. - to_item.SetURL(MAKE_URL(end)); - EXPECT_EQ( - MAKE_URL(end), - [web_controller() URLForHistoryNavigationToItem:&to_item - previousURL:previous_url]); - } else { - // Start contains a fragment and matches end: An empty fragment is - // added. - to_item.SetURL(MAKE_URL(end)); - EXPECT_EQ( - MAKE_URL([end stringByAppendingString:@"#"]), - [web_controller() URLForHistoryNavigationToItem:&to_item - previousURL:previous_url]); - } - } - } -} - // Tests that AllowCertificateError is called with correct arguments if // WKWebView fails to load a page with bad SSL cert. TEST_F(CRWWebControllerTest, SslCertError) {
diff --git a/ios/web/web_state/crw_web_view_proxy_impl.h b/ios/web/web_state/ui/crw_web_view_proxy_impl.h similarity index 77% rename from ios/web/web_state/crw_web_view_proxy_impl.h rename to ios/web/web_state/ui/crw_web_view_proxy_impl.h index 53074406..98fe0ee 100644 --- a/ios/web/web_state/crw_web_view_proxy_impl.h +++ b/ios/web/web_state/ui/crw_web_view_proxy_impl.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_WEB_STATE_CRW_WEB_VIEW_PROXY_IMPL_H_ -#define IOS_WEB_WEB_STATE_CRW_WEB_VIEW_PROXY_IMPL_H_ +#ifndef IOS_WEB_WEB_STATE_UI_CRW_WEB_VIEW_PROXY_IMPL_H_ +#define IOS_WEB_WEB_STATE_UI_CRW_WEB_VIEW_PROXY_IMPL_H_ #import <UIKit/UIKit.h> -#import "ios/web/public/web_state/crw_web_view_proxy.h" #import "ios/web/public/web_state/ui/crw_content_view.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" @class CRWWebController; @@ -25,4 +25,4 @@ @end -#endif // IOS_WEB_WEB_STATE_CRW_WEB_VIEW_PROXY_IMPL_H_ +#endif // IOS_WEB_WEB_STATE_UI_CRW_WEB_VIEW_PROXY_IMPL_H_
diff --git a/ios/web/web_state/crw_web_view_proxy_impl.mm b/ios/web/web_state/ui/crw_web_view_proxy_impl.mm similarity index 97% rename from ios/web/web_state/crw_web_view_proxy_impl.mm rename to ios/web/web_state/ui/crw_web_view_proxy_impl.mm index 357ed97..bc81d69 100644 --- a/ios/web/web_state/crw_web_view_proxy_impl.mm +++ b/ios/web/web_state/ui/crw_web_view_proxy_impl.mm
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/web/web_state/crw_web_view_proxy_impl.h" +#import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" #import "base/mac/scoped_nsobject.h" -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" #import "ios/web/public/web_state/ui/crw_content_view.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import "ios/web/web_state/ui/crw_web_controller.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/web_state/crw_web_view_scroll_view_proxy.mm b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy.mm similarity index 95% rename from ios/web/web_state/crw_web_view_scroll_view_proxy.mm rename to ios/web/web_state/ui/crw_web_view_scroll_view_proxy.mm index 291f409..3c5b54e 100644 --- a/ios/web/web_state/crw_web_view_scroll_view_proxy.mm +++ b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy.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/web/public/web_state/crw_web_view_scroll_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import <objc/runtime.h> @@ -191,11 +191,11 @@ DCHECK_EQ(_scrollView, scrollView); __block BOOL shouldScrollToTop = YES; [_observers executeOnObservers:^(id observer) { - if ([observer respondsToSelector:@selector( - webViewScrollViewShouldScrollToTop:)]) { - shouldScrollToTop = shouldScrollToTop && - [observer webViewScrollViewShouldScrollToTop:self]; - } + if ([observer respondsToSelector:@selector + (webViewScrollViewShouldScrollToTop:)]) { + shouldScrollToTop = shouldScrollToTop && + [observer webViewScrollViewShouldScrollToTop:self]; + } }]; return shouldScrollToTop; }
diff --git a/ios/web/web_state/crw_web_view_scroll_view_proxy_unittest.mm b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm similarity index 74% rename from ios/web/web_state/crw_web_view_scroll_view_proxy_unittest.mm rename to ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm index 04a0428..2f3581b8 100644 --- a/ios/web/web_state/crw_web_view_scroll_view_proxy_unittest.mm +++ b/ios/web/web_state/ui/crw_web_view_scroll_view_proxy_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" #import <UIKit/UIKit.h> @@ -68,38 +68,39 @@ // Arbitrary point. const CGPoint point = CGPointMake(10, 10); - [[[mockScrollView_ stub] - andReturnValue:[NSValue valueWithCGPoint:point]] contentOffset]; - EXPECT_TRUE(CGPointEqualToPoint(point, - [webViewScrollViewProxy_ contentOffset])); + [[[mockScrollView_ stub] andReturnValue:[NSValue valueWithCGPoint:point]] + contentOffset]; + EXPECT_TRUE( + CGPointEqualToPoint(point, [webViewScrollViewProxy_ contentOffset])); // Arbitrary inset. const UIEdgeInsets contentInset = UIEdgeInsetsMake(10, 10, 10, 10); - [[[mockScrollView_ stub] andReturnValue: - [NSValue valueWithUIEdgeInsets:contentInset]] contentInset]; - EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(contentInset, - [webViewScrollViewProxy_ contentInset])); + [[[mockScrollView_ stub] + andReturnValue:[NSValue valueWithUIEdgeInsets:contentInset]] + contentInset]; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets( + contentInset, [webViewScrollViewProxy_ contentInset])); // Arbitrary inset. const UIEdgeInsets scrollIndicatorInsets = UIEdgeInsetsMake(20, 20, 20, 20); - [[[mockScrollView_ stub] andReturnValue:[NSValue - valueWithUIEdgeInsets:scrollIndicatorInsets]] scrollIndicatorInsets]; - EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(scrollIndicatorInsets, - [webViewScrollViewProxy_ scrollIndicatorInsets])); + [[[mockScrollView_ stub] + andReturnValue:[NSValue valueWithUIEdgeInsets:scrollIndicatorInsets]] + scrollIndicatorInsets]; + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets( + scrollIndicatorInsets, [webViewScrollViewProxy_ scrollIndicatorInsets])); // Arbitrary size. const CGSize contentSize = CGSizeMake(19, 19); - [[[mockScrollView_ stub] andReturnValue: - [NSValue valueWithCGSize:contentSize]] contentSize]; - EXPECT_TRUE(CGSizeEqualToSize(contentSize, - [webViewScrollViewProxy_ contentSize])); + [[[mockScrollView_ stub] andReturnValue:[NSValue valueWithCGSize:contentSize]] + contentSize]; + EXPECT_TRUE( + CGSizeEqualToSize(contentSize, [webViewScrollViewProxy_ contentSize])); // Arbitrary rect. const CGRect frame = CGRectMake(2, 4, 5, 1); - [[[mockScrollView_ stub] andReturnValue: - [NSValue valueWithCGRect:frame]] frame]; - EXPECT_TRUE(CGRectEqualToRect(frame, - [webViewScrollViewProxy_ frame])); + [[[mockScrollView_ stub] andReturnValue:[NSValue valueWithCGRect:frame]] + frame]; + EXPECT_TRUE(CGRectEqualToRect(frame, [webViewScrollViewProxy_ frame])); } // Tests that CRWWebViewScrollViewProxy returns the correct property values when @@ -113,10 +114,9 @@ UIEdgeInsetsZero, [webViewScrollViewProxy_ contentInset])); EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets( UIEdgeInsetsZero, [webViewScrollViewProxy_ scrollIndicatorInsets])); - EXPECT_TRUE(CGSizeEqualToSize(CGSizeZero, - [webViewScrollViewProxy_ contentSize])); - EXPECT_TRUE(CGRectEqualToRect(CGRectZero, - [webViewScrollViewProxy_ frame])); + EXPECT_TRUE( + CGSizeEqualToSize(CGSizeZero, [webViewScrollViewProxy_ contentSize])); + EXPECT_TRUE(CGRectEqualToRect(CGRectZero, [webViewScrollViewProxy_ frame])); // Make sure setting the properties is fine too. // Arbitrary point. @@ -152,15 +152,14 @@ // Arbitrary point. const CGPoint point = CGPointMake(10, 10); - [[[mockScrollView_ stub] - andReturnValue:[NSValue valueWithCGPoint:point]] contentOffset]; - EXPECT_TRUE(CGPointEqualToPoint(point, - [webViewScrollViewProxy_ contentOffset])); - EXPECT_TRUE(CGPointEqualToPoint(point, - [webViewScrollViewProxy1 contentOffset])); - EXPECT_TRUE(CGPointEqualToPoint(point, - [webViewScrollViewProxy2 contentOffset])); + [[[mockScrollView_ stub] andReturnValue:[NSValue valueWithCGPoint:point]] + contentOffset]; + EXPECT_TRUE( + CGPointEqualToPoint(point, [webViewScrollViewProxy_ contentOffset])); + EXPECT_TRUE( + CGPointEqualToPoint(point, [webViewScrollViewProxy1 contentOffset])); + EXPECT_TRUE( + CGPointEqualToPoint(point, [webViewScrollViewProxy2 contentOffset])); } } // namespace -
diff --git a/ios/web_view/internal/web_view_web_main_delegate.mm b/ios/web_view/internal/web_view_web_main_delegate.mm index 47983b4..83188ce8 100644 --- a/ios/web_view/internal/web_view_web_main_delegate.mm +++ b/ios/web_view/internal/web_view_web_main_delegate.mm
@@ -4,9 +4,11 @@ #import "ios/web_view/internal/web_view_web_main_delegate.h" +#import "base/mac/bundle_locations.h" #include "base/memory/ptr_util.h" #import "ios/web_view/internal/web_view_web_client.h" #import "ios/web_view/public/cwv_delegate.h" +#import "ios/web_view/public/cwv_web_view.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -20,6 +22,8 @@ WebViewWebMainDelegate::~WebViewWebMainDelegate() = default; void WebViewWebMainDelegate::BasicStartupComplete() { + base::mac::SetOverrideFrameworkBundle( + [NSBundle bundleForClass:[CWVWebView class]]); web_client_ = base::MakeUnique<WebViewWebClient>(delegate_); web::SetWebClient(web_client_.get()); }
diff --git a/ios/web_view/internal/web_view_web_main_parts.mm b/ios/web_view/internal/web_view_web_main_parts.mm index 651d357..7cb74eb 100644 --- a/ios/web_view/internal/web_view_web_main_parts.mm +++ b/ios/web_view/internal/web_view_web_main_parts.mm
@@ -7,13 +7,11 @@ #import <Foundation/Foundation.h> #include "base/base_paths.h" -#import "base/mac/bundle_locations.h" #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "components/translate/core/browser/translate_download_manager.h" #include "ios/web_view/internal/web_view_browser_state.h" #import "ios/web_view/public/cwv_delegate.h" -#import "ios/web_view/public/cwv_web_view.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/resource/resource_bundle.h" @@ -30,9 +28,6 @@ WebViewWebMainParts::~WebViewWebMainParts() = default; void WebViewWebMainParts::PreMainMessageLoopRun() { - base::mac::SetOverrideFrameworkBundle( - [NSBundle bundleForClass:[CWVWebView class]]); - // Initialize resources. l10n_util::OverrideLocaleWithCocoaLocale(); ui::ResourceBundle::InitSharedInstanceWithLocale(
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 6e719b3..ea11b54a 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -802,6 +802,53 @@ return s.str(); } +int VideoFrame::BitsPerChannel(VideoPixelFormat format) { + int bits_per_channel = 0; + switch (format) { + case media::PIXEL_FORMAT_UNKNOWN: + NOTREACHED(); + // Fall through! + case media::PIXEL_FORMAT_I420: + case media::PIXEL_FORMAT_YV12: + case media::PIXEL_FORMAT_YV16: + case media::PIXEL_FORMAT_YV12A: + case media::PIXEL_FORMAT_YV24: + case media::PIXEL_FORMAT_NV12: + case media::PIXEL_FORMAT_NV21: + case media::PIXEL_FORMAT_UYVY: + case media::PIXEL_FORMAT_YUY2: + case media::PIXEL_FORMAT_ARGB: + case media::PIXEL_FORMAT_XRGB: + case media::PIXEL_FORMAT_RGB24: + case media::PIXEL_FORMAT_RGB32: + case media::PIXEL_FORMAT_MJPEG: + case media::PIXEL_FORMAT_MT21: + case media::PIXEL_FORMAT_Y8: + case media::PIXEL_FORMAT_I422: + bits_per_channel = 8; + break; + case media::PIXEL_FORMAT_YUV420P9: + case media::PIXEL_FORMAT_YUV422P9: + case media::PIXEL_FORMAT_YUV444P9: + bits_per_channel = 9; + break; + case media::PIXEL_FORMAT_YUV420P10: + case media::PIXEL_FORMAT_YUV422P10: + case media::PIXEL_FORMAT_YUV444P10: + bits_per_channel = 10; + break; + case media::PIXEL_FORMAT_YUV420P12: + case media::PIXEL_FORMAT_YUV422P12: + case media::PIXEL_FORMAT_YUV444P12: + bits_per_channel = 12; + break; + case media::PIXEL_FORMAT_Y16: + bits_per_channel = 16; + break; + } + return bits_per_channel; +} + // static scoped_refptr<VideoFrame> VideoFrame::WrapExternalStorage( VideoPixelFormat format,
diff --git a/media/base/video_frame.h b/media/base/video_frame.h index 3139f7a..0ae2d70 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h
@@ -402,6 +402,9 @@ // guaranteed to be unique within a single process. int unique_id() const { return unique_id_; } + // Returns the number of bits per channel for given |format|. + int BitsPerChannel(VideoPixelFormat format); + protected: friend class base::RefCountedThreadSafe<VideoFrame>;
diff --git a/media/media_options.gni b/media/media_options.gni index 2f757021..00709d3 100644 --- a/media/media_options.gni +++ b/media/media_options.gni
@@ -60,6 +60,9 @@ # Enabled by default on the cast desktop implementation to allow unit tests of # MP2TS parsing support. enable_hls_sample_aes = proprietary_codecs && is_cast_desktop_build + + # If true, use cast CMA backend instead of default chromium media pipeline. + is_cast_using_cma_backend = is_cast_audio_only || !is_android } # enable_hls_sample_aes can only be true if enable_mse_mpeg2ts_stream_parser is. @@ -149,18 +152,19 @@ # Can be overridden by gn build arguments from the --args command line flag # for local testing. if (enable_mojo_media) { - if (is_android) { - mojo_media_services = [ - "cdm", - "audio_decoder", - ] - mojo_media_host = "gpu" - } else if (is_chromecast) { + if (is_chromecast && is_cast_using_cma_backend) { mojo_media_services = [ "cdm", "renderer", ] mojo_media_host = "browser" + } else if (is_android) { + # Both chrome for Android and cast for ATV belongs to this case + mojo_media_services = [ + "cdm", + "audio_decoder", + ] + mojo_media_host = "gpu" } else { mojo_media_services = [ "video_decoder" ] mojo_media_host = "gpu"
diff --git a/media/mojo/interfaces/media_types.typemap b/media/mojo/interfaces/media_types.typemap index db421145..a10cdf6 100644 --- a/media/mojo/interfaces/media_types.typemap +++ b/media/mojo/interfaces/media_types.typemap
@@ -19,8 +19,11 @@ traits_headers = [ "//media/base/ipc/media_param_traits_macros.h" ] -deps = [ +public_deps = [ "//media", +] + +deps = [ "//media/base/ipc", ]
diff --git a/mojo/public/cpp/system/simple_watcher.cc b/mojo/public/cpp/system/simple_watcher.cc index 218a350f..ae96faa 100644 --- a/mojo/public/cpp/system/simple_watcher.cc +++ b/mojo/public/cpp/system/simple_watcher.cc
@@ -26,8 +26,10 @@ WatcherHandle watcher_handle, Handle handle, MojoHandleSignals signals, + int watch_id, MojoResult* watch_result) { - scoped_refptr<Context> context = new Context(watcher, task_runner); + scoped_refptr<Context> context = + new Context(watcher, task_runner, watch_id); // If MojoWatch succeeds, it assumes ownership of a reference to |context|. // In that case, this reference is balanced in CallNotify() when |result| is @@ -69,8 +71,11 @@ friend class base::RefCountedThreadSafe<Context>; Context(base::WeakPtr<SimpleWatcher> weak_watcher, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : weak_watcher_(weak_watcher), task_runner_(task_runner) {} + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + int watch_id) + : weak_watcher_(weak_watcher), + task_runner_(task_runner), + watch_id_(watch_id) {} ~Context() {} void Notify(MojoResult result, @@ -95,16 +100,17 @@ // System notifications will trigger from the task runner passed to // mojo::edk::InitIPCSupport(). In Chrome this happens to always be the // default task runner for the IO thread. - weak_watcher_->OnHandleReady(make_scoped_refptr(this), result); + weak_watcher_->OnHandleReady(watch_id_, result); } else { task_runner_->PostTask( FROM_HERE, base::Bind(&SimpleWatcher::OnHandleReady, weak_watcher_, - make_scoped_refptr(this), result)); + watch_id_, result)); } } const base::WeakPtr<SimpleWatcher> weak_watcher_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const int watch_id_; base::Lock lock_; bool enable_cancellation_notifications_ = true; @@ -145,11 +151,12 @@ callback_ = callback; handle_ = handle; + watch_id_ += 1; MojoResult watch_result = MOJO_RESULT_UNKNOWN; - context_ = - Context::Create(weak_factory_.GetWeakPtr(), task_runner_, - watcher_handle_.get(), handle_, signals, &watch_result); + context_ = Context::Create(weak_factory_.GetWeakPtr(), task_runner_, + watcher_handle_.get(), handle_, signals, watch_id_, + &watch_result); if (!context_) { handle_.set_value(kInvalidHandleValue); callback_.Reset(); @@ -227,16 +234,15 @@ DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv); task_runner_->PostTask(FROM_HERE, base::Bind(&SimpleWatcher::OnHandleReady, weak_factory_.GetWeakPtr(), - context_, ready_result)); + watch_id_, ready_result)); } -void SimpleWatcher::OnHandleReady(scoped_refptr<const Context> context, - MojoResult result) { +void SimpleWatcher::OnHandleReady(int watch_id, MojoResult result) { DCHECK(thread_checker_.CalledOnValidThread()); // This notification may be for a previously watched context, in which case // we just ignore it. - if (context != context_) + if (watch_id != watch_id_) return; ReadyCallback callback = callback_;
diff --git a/mojo/public/cpp/system/simple_watcher.h b/mojo/public/cpp/system/simple_watcher.h index 5e5a7ea3..9001884 100644 --- a/mojo/public/cpp/system/simple_watcher.h +++ b/mojo/public/cpp/system/simple_watcher.h
@@ -164,7 +164,7 @@ private: class Context; - void OnHandleReady(scoped_refptr<const Context> context, MojoResult result); + void OnHandleReady(int watch_id, MojoResult result); base::ThreadChecker thread_checker_; @@ -190,6 +190,10 @@ // The handle currently under watch. Not owned. Handle handle_; + // A simple counter to disambiguate notifications from multiple watch contexts + // in the event that this SimpleWatcher cancels and watches multiple times. + int watch_id_ = 0; + // The callback to call when the handle is signaled. ReadyCallback callback_;
diff --git a/net/BUILD.gn b/net/BUILD.gn index 2cf5735b..4ff5d00b 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1470,8 +1470,6 @@ "spdy/hpack/hpack_constants.h", "spdy/hpack/hpack_decoder.cc", "spdy/hpack/hpack_decoder.h", - "spdy/hpack/hpack_decoder2.cc", - "spdy/hpack/hpack_decoder2.h", "spdy/hpack/hpack_decoder3.cc", "spdy/hpack/hpack_decoder3.h", "spdy/hpack/hpack_decoder_interface.h", @@ -4611,7 +4609,6 @@ "spdy/buffered_spdy_framer_unittest.cc", "spdy/fuzzing/hpack_fuzz_util_test.cc", "spdy/header_coalescer_test.cc", - "spdy/hpack/hpack_decoder2_test.cc", "spdy/hpack/hpack_decoder3_test.cc", "spdy/hpack/hpack_decoder_test.cc", "spdy/hpack/hpack_encoder_test.cc",
diff --git a/net/quic/core/quic_headers_stream_test.cc b/net/quic/core/quic_headers_stream_test.cc index 8a784bf..056f34b 100644 --- a/net/quic/core/quic_headers_stream_test.cc +++ b/net/quic/core/quic_headers_stream_test.cc
@@ -150,13 +150,11 @@ return os; } -enum HpackDecoderChoice { HPACK_DECODER_SPDY, HPACK_DECODER2, HPACK_DECODER3 }; +enum HpackDecoderChoice { HPACK_DECODER_SPDY, HPACK_DECODER3 }; std::ostream& operator<<(std::ostream& os, HpackDecoderChoice v) { switch (v) { case HPACK_DECODER_SPDY: return os << "SPDY"; - case HPACK_DECODER2: - return os << "HPACK_DECODER2"; case HPACK_DECODER3: return os << "HPACK_DECODER3"; } @@ -191,15 +189,9 @@ } switch (hpack_decoder) { case HPACK_DECODER_SPDY: - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; - break; - case HPACK_DECODER2: - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = true; FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; break; case HPACK_DECODER3: - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = true; break; } @@ -407,13 +399,13 @@ INSTANTIATE_TEST_CASE_P( Tests, QuicHeadersStreamTest, - ::testing::Combine( - ::testing::ValuesIn(AllSupportedVersions()), - ::testing::Values(Perspective::IS_CLIENT, Perspective::IS_SERVER), - ::testing::Values(HTTP2_DECODER_SPDY, - HTTP2_DECODER_NESTED_SPDY, - HTTP2_DECODER_NEW), - ::testing::Values(HPACK_DECODER_SPDY, HPACK_DECODER2, HPACK_DECODER3))); + ::testing::Combine(::testing::ValuesIn(AllSupportedVersions()), + ::testing::Values(Perspective::IS_CLIENT, + Perspective::IS_SERVER), + ::testing::Values(HTTP2_DECODER_SPDY, + HTTP2_DECODER_NESTED_SPDY, + HTTP2_DECODER_NEW), + ::testing::Values(HPACK_DECODER_SPDY, HPACK_DECODER3))); TEST_P(QuicHeadersStreamTest, StreamId) { EXPECT_EQ(3u, headers_stream_->id()); @@ -755,9 +747,8 @@ stream_frame_.data_buffer = frame.data(); stream_frame_.data_length = frame.size(); headers_stream_->OnStreamFrame(stream_frame_); - EXPECT_EQ(kTestHeaderTableSize, - QuicSpdySessionPeer::GetSpdyFramer(&session_) - .header_encoder_table_size()); + EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_) + .header_encoder_table_size()); } TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
diff --git a/net/spdy/hpack/hpack_decoder2.cc b/net/spdy/hpack/hpack_decoder2.cc deleted file mode 100644 index 14ff94e990f..0000000 --- a/net/spdy/hpack/hpack_decoder2.cc +++ /dev/null
@@ -1,337 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/hpack/hpack_decoder2.h" - -#include <list> -#include <utility> - -#include "base/logging.h" -#include "base/strings/string_piece.h" -#include "net/http2/decoder/decode_buffer.h" -#include "net/http2/decoder/decode_status.h" -#include "net/spdy/hpack/hpack_entry.h" -#include "net/spdy/platform/api/spdy_estimate_memory_usage.h" - -using base::StringPiece; - -namespace net { - -HpackDecoder2::HpackDecoder2() : hpack_block_decoder_(this) { - Reset(); -} - -HpackDecoder2::~HpackDecoder2() {} - -void HpackDecoder2::Reset() { - DVLOG(2) << "HpackDecoder2::Reset"; - handler_ = nullptr; - - hpack_block_decoder_.Reset(); - hpack_block_decoder_.set_listener(this); - - total_hpack_bytes_ = 0; - total_header_bytes_ = 0; - size_update_count_ = 0; - header_seen_ = false; - in_progress_ = false; - error_detected_ = false; - header_block_started_ = false; - - name_.Reset(); - value_.Reset(); -} - -void HpackDecoder2::SetErrorDetected() { - if (!error_detected_) { - DVLOG(2) << "HpackDecoder2::SetErrorDetected"; - hpack_block_decoder_.set_listener(&no_op_listener_); - error_detected_ = true; - } -} - -void HpackDecoder2::ApplyHeaderTableSizeSetting(size_t size_setting) { - DVLOG(2) << "HpackDecoder2::ApplyHeaderTableSizeSetting"; - header_table_.SetSettingsHeaderTableSize(size_setting); -} - -// If a SpdyHeadersHandlerInterface is provided, the decoder will emit -// headers to it rather than accumulating them in a SpdyHeaderBlock. -void HpackDecoder2::HandleControlFrameHeadersStart( - SpdyHeadersHandlerInterface* handler) { - DVLOG(2) << "HpackDecoder2::HandleControlFrameHeadersStart"; - DCHECK(!header_block_started_); - handler_ = handler; -} - -// Called as HPACK block fragments arrive. Returns false -// if an error occurred while decoding the block. -bool HpackDecoder2::HandleControlFrameHeadersData(const char* headers_data, - size_t headers_data_length) { - DVLOG(2) << "HpackDecoder2::HandleControlFrameHeadersData: len=" - << headers_data_length; - if (!header_block_started_) { - DCHECK_EQ(total_hpack_bytes_, 0u); - // Clear the SpdyHeaderBlock here rather than in Reset so that it is NOT - // cleared in HandleControlFrameHeadersComplete, which would be before it - // could be used. - decoded_block_.clear(); - header_block_started_ = true; - if (handler_ != nullptr) { - handler_->OnHeaderBlockStart(); - } - } - - // Sometimes we get a call with headers_data==nullptr and - // headers_data_length==0, in which case we need to avoid creating - // a DecodeBuffer, which would otherwise complain. - if (headers_data_length > 0) { - DCHECK_NE(headers_data, nullptr); - total_hpack_bytes_ += headers_data_length; - DecodeBuffer db(headers_data, headers_data_length); - DecodeStatus status = hpack_block_decoder_.Decode(&db); - switch (status) { - case DecodeStatus::kDecodeDone: - // We've completed the decoding of headers_data, and it ended at the - // boundary between two HPACK block entries, so name_ and value_ are - // currently reset. - DCHECK_EQ(0u, db.Remaining()); - in_progress_ = false; - break; - - case DecodeStatus::kDecodeInProgress: - DCHECK_EQ(0u, db.Remaining()); - in_progress_ = true; - if (!error_detected_) { - name_.BufferStringIfUnbuffered(); - value_.BufferStringIfUnbuffered(); - EnforceMaxDecodeBufferSize(); - } - break; - - case DecodeStatus::kDecodeError: - SetErrorDetected(); - break; - } - } - return !error_detected_; -} - -// Called after a HPACK block has been completely delivered via -// HandleControlFrameHeadersData(). Returns false if an error occurred. -// |compressed_len| if non-null will be set to the size of the encoded -// buffered block that was accumulated in HandleControlFrameHeadersData(), -// to support subsequent calculation of compression percentage. -// Discards the handler supplied at the start of decoding the block. -// TODO(jamessynge): Determine if compressed_len is needed; it is used to -// produce UUMA stat Net.SpdyHpackDecompressionPercentage, but only for -// SPDY3, not HTTP2. -bool HpackDecoder2::HandleControlFrameHeadersComplete(size_t* compressed_len) { - DVLOG(2) << "HpackDecoder2::HandleControlFrameHeadersComplete"; - if (error_detected_ || in_progress_) { - DVLOG(2) << "error_detected_=" << error_detected_ - << ", in_progress_=" << in_progress_; - return false; - } - if (compressed_len != nullptr) { - *compressed_len = total_hpack_bytes_; - } - if (handler_ != nullptr) { - handler_->OnHeaderBlockEnd(total_header_bytes_); - } - Reset(); - return true; -} - -const SpdyHeaderBlock& HpackDecoder2::decoded_block() const { - return decoded_block_; -} - -void HpackDecoder2::SetHeaderTableDebugVisitor( - std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { - DVLOG(2) << "HpackDecoder2::SetHeaderTableDebugVisitor"; - header_table_.set_debug_visitor(std::move(visitor)); -} - -void HpackDecoder2::set_max_decode_buffer_size_bytes( - size_t max_decode_buffer_size_bytes) { - DVLOG(2) << "HpackDecoder2::set_max_decode_buffer_size_bytes"; - max_decode_buffer_size_bytes_ = max_decode_buffer_size_bytes; -} - -size_t HpackDecoder2::EstimateMemoryUsage() const { - return SpdyEstimateMemoryUsage(header_table_) + - SpdyEstimateMemoryUsage(decoded_block_) + - SpdyEstimateMemoryUsage(name_) + SpdyEstimateMemoryUsage(value_); -} - -void HpackDecoder2::OnIndexedHeader(size_t index) { - DVLOG(2) << "HpackDecoder2::OnIndexedHeader: index=" << index; - DCHECK(!error_detected_); - const HpackEntry* entry = header_table_.GetByIndex(index); - if (entry == nullptr) { - SetErrorDetected(); - return; - } - HandleHeaderRepresentation(entry->name(), entry->value()); -} - -void HpackDecoder2::OnStartLiteralHeader(HpackEntryType entry_type, - size_t maybe_name_index) { - DVLOG(2) << "HpackDecoder2::OnStartLiteralHeader: entry_type=" << entry_type - << ", maybe_name_index=" << maybe_name_index; - DCHECK(!error_detected_); - entry_type_ = entry_type; - if (maybe_name_index > 0) { - const HpackEntry* entry = header_table_.GetByIndex(maybe_name_index); - if (entry == nullptr) { - SetErrorDetected(); - return; - } else { - // Non-static entries could be evicted, leaving us with a dangling - // pointer, so we preemptively copy. This could be avoided if - // TryAddEntry would copy the strings prior to performing eviction. - name_.Set(entry->name(), entry->IsStatic()); - name_.BufferStringIfUnbuffered(); - } - } -} - -void HpackDecoder2::OnNameStart(bool huffman_encoded, size_t len) { - DVLOG(2) << "HpackDecoder2::OnNameStart: huffman_encoded=" - << (huffman_encoded ? "true" : "false") << ", len=" << len; - if (len > max_decode_buffer_size_bytes_) { - DVLOG(1) << "Name length (" << len << ") is longer than permitted (" - << max_decode_buffer_size_bytes_ << ")"; - SetErrorDetected(); - return; - } - name_.OnStart(huffman_encoded, len); -} - -void HpackDecoder2::OnNameData(const char* data, size_t len) { - DVLOG(2) << "HpackDecoder2::OnNameData: len=" << len - << "\n data: " << StringPiece(data, len); - if (error_detected_) { - return; - } - if (!name_.OnData(data, len)) { - SetErrorDetected(); - } -} - -void HpackDecoder2::OnNameEnd() { - DVLOG(2) << "HpackDecoder2::OnNameEnd"; - if (error_detected_) { - return; - } - if (!name_.OnEnd()) { - SetErrorDetected(); - } -} - -void HpackDecoder2::OnValueStart(bool huffman_encoded, size_t len) { - DVLOG(2) << "HpackDecoder2::OnValueStart: huffman_encoded=" - << (huffman_encoded ? "true" : "false") << ", len=" << len; - if (len > max_decode_buffer_size_bytes_) { - DVLOG(1) << "Value length (" << len << ") is longer than permitted (" - << max_decode_buffer_size_bytes_ << ")"; - SetErrorDetected(); - return; - } - value_.OnStart(huffman_encoded, len); -} - -void HpackDecoder2::OnValueData(const char* data, size_t len) { - DVLOG(2) << "HpackDecoder2::OnValueData: len=" << len - << "\n data: " << StringPiece(data, len); - if (error_detected_) { - return; - } - if (!value_.OnData(data, len)) { - SetErrorDetected(); - } -} - -void HpackDecoder2::OnValueEnd() { - DVLOG(2) << "HpackDecoder2::OnValueEnd"; - if (error_detected_) { - return; - } - if (!value_.OnEnd()) { - SetErrorDetected(); - return; - } - if (EnforceMaxDecodeBufferSize()) { - // All is well. - HandleHeaderRepresentation(name_.str(), value_.str()); - if (entry_type_ == HpackEntryType::kIndexedLiteralHeader) { - header_table_.TryAddEntry(name_.str(), value_.str()); - } - name_.Reset(); - value_.Reset(); - } -} - -void HpackDecoder2::OnDynamicTableSizeUpdate(size_t size) { - DVLOG(2) << "HpackDecoder2::OnDynamicTableSizeUpdate: size=" << size; - if (error_detected_) { - return; - } - if (size > header_table_.settings_size_bound()) { - DVLOG(1) << "Dynamic Table Size Update with too large a size: " << size - << " > " << header_table_.settings_size_bound(); - SetErrorDetected(); - return; - } - if (header_seen_) { - DVLOG(1) << "Dynamic Table Size Update seen after a Header"; - SetErrorDetected(); - return; - } - ++size_update_count_; - if (size_update_count_ > 2) { - DVLOG(1) << "Too many (" << size_update_count_ - << ") Dynamic Table Size Updates"; - SetErrorDetected(); - return; - } - header_table_.SetMaxSize(size); - return; -} - -bool HpackDecoder2::EnforceMaxDecodeBufferSize() { - if (!error_detected_) { - size_t buffered_length = name_.BufferedLength() + value_.BufferedLength(); - DVLOG(2) << "buffered_length=" << buffered_length - << "; max=" << max_decode_buffer_size_bytes_; - if (buffered_length > max_decode_buffer_size_bytes_) { - DVLOG(1) << "Header length (" << buffered_length - << ") is longer than permitted (" - << max_decode_buffer_size_bytes_ << ")"; - SetErrorDetected(); - } - } - return !error_detected_; -} - -void HpackDecoder2::HandleHeaderRepresentation(StringPiece name, - StringPiece value) { - DVLOG(2) << "HpackDecoder2::HandleHeaderRepresentation:\n name: " << name - << "\n value: " << value; - total_header_bytes_ += name.size() + value.size(); - header_seen_ = true; - if (handler_ == nullptr) { - DVLOG(3) << "HpackDecoder2::HandleHeaderRepresentation " - << "adding to decoded_block"; - decoded_block_.AppendValueOrAddHeader(name, value); - } else { - DVLOG(3) << "HpackDecoder2::HandleHeaderRepresentation " - << "passing to handler"; - DCHECK(decoded_block_.empty()); - handler_->OnHeader(name, value); - } -} - -} // namespace net
diff --git a/net/spdy/hpack/hpack_decoder2.h b/net/spdy/hpack/hpack_decoder2.h deleted file mode 100644 index 614ac01..0000000 --- a/net/spdy/hpack/hpack_decoder2.h +++ /dev/null
@@ -1,147 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SPDY_HPACK_HPACK_DECODER2_H_ -#define NET_SPDY_HPACK_HPACK_DECODER2_H_ - -// HpackDecoder2 - -// An HpackDecoder decodes header sets as outlined in -// http://tools.ietf.org/html/rfc7541. This implementation uses the -// new HpackBlockDecoder in //net/http2/hpack/ - -#include <stddef.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/strings/string_piece.h" -#include "net/base/net_export.h" -#include "net/http2/hpack/decoder/hpack_block_decoder.h" -#include "net/http2/hpack/decoder/hpack_decoder_string_buffer.h" -#include "net/http2/hpack/decoder/hpack_entry_decoder_listener.h" -#include "net/http2/hpack/http2_hpack_constants.h" -#include "net/http2/hpack/huffman/http2_hpack_huffman_decoder.h" -#include "net/spdy/hpack/hpack_constants.h" -#include "net/spdy/hpack/hpack_decoder_interface.h" -#include "net/spdy/hpack/hpack_header_table.h" -#include "net/spdy/spdy_header_block.h" -#include "net/spdy/spdy_headers_handler_interface.h" - -namespace net { -namespace test { -class HpackDecoder2Peer; -} // namespace test - -class NET_EXPORT_PRIVATE HpackDecoder2 : public HpackDecoderInterface, - HpackEntryDecoderListener { - public: - friend test::HpackDecoder2Peer; - HpackDecoder2(); - ~HpackDecoder2() override; - - // Override the interface methods: - - void ApplyHeaderTableSizeSetting(size_t size_setting) override; - void HandleControlFrameHeadersStart( - SpdyHeadersHandlerInterface* handler) override; - bool HandleControlFrameHeadersData(const char* headers_data, - size_t headers_data_length) override; - bool HandleControlFrameHeadersComplete(size_t* compressed_len) override; - const SpdyHeaderBlock& decoded_block() const override; - void SetHeaderTableDebugVisitor( - std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) - override; - void set_max_decode_buffer_size_bytes( - size_t max_decode_buffer_size_bytes) override; - size_t EstimateMemoryUsage() const override; - - protected: - // Override the HpackEntryDecoderListener methods: - - void OnIndexedHeader(size_t index) override; - void OnStartLiteralHeader(HpackEntryType entry_type, - size_t maybe_name_index) override; - void OnNameStart(bool huffman_encoded, size_t len) override; - void OnNameData(const char* data, size_t len) override; - void OnNameEnd() override; - void OnValueStart(bool huffman_encoded, size_t len) override; - void OnValueData(const char* data, size_t len) override; - void OnValueEnd() override; - void OnDynamicTableSizeUpdate(size_t size) override; - - private: - // Called when a complete header entry has been decoded, with the name and - // value of the entry. If check_header_order_ is true, confirms that - // pseudo-headers don't appear after normal headers, else it treats the - // headers as malformed, as per sections 8.1.2.3. of the HTTP2 specification. - // Calls handler_->OnHeader() if there is a handler, else adds the header - // to decoded_block_. - void HandleHeaderRepresentation(base::StringPiece name, - base::StringPiece value); - - // Reset state in preparation for decoding a new HPACK block. Does not reset - // the dynamic table. - void Reset(); - - // Called when an error is detected while decoding. Replaces the listener - // in the HpackBlockDecoder with the no-op listener. - void SetErrorDetected(); - - // Enforce the limit on the maximum size of strings that can be buffered. - // It happens that this test is made after the strings have been buffered, - // but that isn't a problem because we don't pass enormous buffers into - // HandleControlFrameHeadersData. - bool EnforceMaxDecodeBufferSize(); - - HpackHeaderTable header_table_; - SpdyHeaderBlock decoded_block_; - - // Scratch space for storing decoded literals. - HpackDecoderStringBuffer name_, value_; - - // If non-NULL, handles decoded headers. - SpdyHeadersHandlerInterface* handler_; - - HpackEntryDecoderNoOpListener no_op_listener_; - - // Total bytes that have been received as input (i.e. HPACK encoded). - size_t total_hpack_bytes_; - - // Total bytes of the name and value strings in the current HPACK block. - size_t total_header_bytes_; - - // How much encoded data this decoder is willing to buffer. - size_t max_decode_buffer_size_bytes_ = 32 * 1024; // 32 KB - - HpackBlockDecoder hpack_block_decoder_; - - // Count of Dynamic Table Size Updates seen in the current HPACK block. - uint32_t size_update_count_; - - // The type of the current header entry (with literals) that is being decoded. - HpackEntryType entry_type_; - - // Has a header been seen in the current HPACK block? - bool header_seen_; - - // Did the HpackBlockDecoder stop in the middle of an entry? - bool in_progress_; - - // Has an error been detected while decoding the HPACK block? - bool error_detected_; - - // Flag to keep track of having seen the header block start. Needed at the - // moment because HandleControlFrameHeadersStart won't be called if a handler - // is not being provided by the caller. - // TODO(jamessynge): Consider collapsing several of these bools into a single - // enum representing the state of the decoding process. - bool header_block_started_; - - DISALLOW_COPY_AND_ASSIGN(HpackDecoder2); -}; - -} // namespace net -#endif // NET_SPDY_HPACK_HPACK_DECODER2_H_
diff --git a/net/spdy/hpack/hpack_decoder2_test.cc b/net/spdy/hpack/hpack_decoder2_test.cc deleted file mode 100644 index 8c70051..0000000 --- a/net/spdy/hpack/hpack_decoder2_test.cc +++ /dev/null
@@ -1,959 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/hpack/hpack_decoder2.h" - -// Tests of HpackDecoder2. - -#include <string> -#include <tuple> -#include <utility> -#include <vector> - -#include "base/logging.h" -#include "base/strings/string_piece.h" -#include "net/http2/hpack/tools/hpack_block_builder.h" -#include "net/http2/tools/http2_random.h" -#include "net/spdy/hpack/hpack_encoder.h" -#include "net/spdy/hpack/hpack_entry.h" -#include "net/spdy/hpack/hpack_huffman_table.h" -#include "net/spdy/hpack/hpack_output_stream.h" -#include "net/spdy/spdy_test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::StringPiece; -using std::string; - -namespace net { -namespace test { - -class HpackDecoder2Peer { - public: - explicit HpackDecoder2Peer(HpackDecoder2* decoder) : decoder_(decoder) {} - - void HandleHeaderRepresentation(StringPiece name, StringPiece value) { - decoder_->HandleHeaderRepresentation(name, value); - } - HpackHeaderTable* header_table() { return &decoder_->header_table_; } - - private: - HpackDecoder2* decoder_; -}; - -namespace { - -using testing::ElementsAre; -using testing::Pair; - -// Is HandleControlFrameHeadersStart to be called, and with what value? -enum StartChoice { START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START }; - -class HpackDecoder2Test - : public ::testing::TestWithParam<std::tuple<StartChoice, bool>> { - protected: - HpackDecoder2Test() : decoder_(), decoder_peer_(&decoder_) {} - - void SetUp() override { - std::tie(start_choice_, randomly_split_input_buffer_) = GetParam(); - } - - void HandleControlFrameHeadersStart() { - switch (start_choice_) { - case START_WITH_HANDLER: - decoder_.HandleControlFrameHeadersStart(&handler_); - break; - case START_WITHOUT_HANDLER: - decoder_.HandleControlFrameHeadersStart(nullptr); - break; - case NO_START: - break; - } - } - - bool HandleControlFrameHeadersData(StringPiece str) { - return decoder_.HandleControlFrameHeadersData(str.data(), str.size()); - } - - bool HandleControlFrameHeadersComplete(size_t* size) { - return decoder_.HandleControlFrameHeadersComplete(size); - } - - bool DecodeHeaderBlock(StringPiece str) { - // Don't call this again if HandleControlFrameHeadersData failed previously. - EXPECT_FALSE(decode_has_failed_); - HandleControlFrameHeadersStart(); - if (randomly_split_input_buffer_) { - do { - // Decode some fragment of the remaining bytes. - size_t bytes = str.length(); - if (!str.empty()) { - bytes = (random_.Rand8() % str.length()) + 1; - } - EXPECT_LE(bytes, str.length()); - if (!HandleControlFrameHeadersData(str.substr(0, bytes))) { - decode_has_failed_ = true; - return false; - } - str.remove_prefix(bytes); - } while (!str.empty()); - } else if (!HandleControlFrameHeadersData(str)) { - decode_has_failed_ = true; - return false; - } - if (!HandleControlFrameHeadersComplete(nullptr)) { - decode_has_failed_ = true; - return false; - } - return true; - } - - const SpdyHeaderBlock& decoded_block() const { - if (start_choice_ == START_WITH_HANDLER) { - return handler_.decoded_block(); - } else { - return decoder_.decoded_block(); - } - } - - const SpdyHeaderBlock& DecodeBlockExpectingSuccess(StringPiece str) { - EXPECT_TRUE(DecodeHeaderBlock(str)); - return decoded_block(); - } - - void expectEntry(size_t index, - size_t size, - const string& name, - const string& value) { - const HpackEntry* entry = decoder_peer_.header_table()->GetByIndex(index); - EXPECT_EQ(name, entry->name()) << "index " << index; - EXPECT_EQ(value, entry->value()); - EXPECT_EQ(size, entry->Size()); - EXPECT_EQ(index, decoder_peer_.header_table()->IndexOf(entry)); - } - - SpdyHeaderBlock MakeHeaderBlock( - const std::vector<std::pair<string, string>>& headers) { - SpdyHeaderBlock result; - for (const auto& kv : headers) { - result.AppendValueOrAddHeader(kv.first, kv.second); - } - return result; - } - - Http2Random random_; - HpackDecoder2 decoder_; - test::HpackDecoder2Peer decoder_peer_; - TestHeadersHandler handler_; - StartChoice start_choice_; - bool randomly_split_input_buffer_; - bool decode_has_failed_ = false; -}; - -INSTANTIATE_TEST_CASE_P( - StartChoiceAndRandomlySplitChoice, - HpackDecoder2Test, - ::testing::Combine( - ::testing::Values(START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START), - ::testing::Bool())); - -TEST_P(HpackDecoder2Test, AddHeaderDataWithHandleControlFrameHeadersData) { - // The hpack decode buffer size is limited in size. This test verifies that - // adding encoded data under that limit is accepted, and data that exceeds the - // limit is rejected. - HandleControlFrameHeadersStart(); - const size_t kMaxBufferSizeBytes = 50; - const string a_value = string(49, 'x'); - decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); - { - HpackBlockBuilder hbb; - hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, - false, "a", false, a_value); - const auto& s = hbb.buffer(); - EXPECT_TRUE(decoder_.HandleControlFrameHeadersData(s.data(), s.size())); - } - { - HpackBlockBuilder hbb; - hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, - false, "b", false, string(51, 'x')); - const auto& s = hbb.buffer(); - EXPECT_FALSE(decoder_.HandleControlFrameHeadersData(s.data(), s.size())); - } - - SpdyHeaderBlock expected_block = MakeHeaderBlock({{"a", a_value}}); - EXPECT_EQ(expected_block, decoded_block()); -} - -TEST_P(HpackDecoder2Test, NameTooLong) { - // Verify that a name longer than the allowed size generates an error. - const size_t kMaxBufferSizeBytes = 50; - const string name = string(2 * kMaxBufferSizeBytes, 'x'); - const string value = "abc"; - - decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); - - HpackBlockBuilder hbb; - hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, - false, name, false, value); - - const size_t fragment_size = (3 * kMaxBufferSizeBytes) / 2; - const string fragment = hbb.buffer().substr(0, fragment_size); - - HandleControlFrameHeadersStart(); - EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); -} - -TEST_P(HpackDecoder2Test, HeaderTooLongToBuffer) { - // Verify that a header longer than the allowed size generates an error if - // it isn't all in one input buffer. - const string name = "some-key"; - const string value = "some-value"; - const size_t kMaxBufferSizeBytes = name.size() + value.size() - 2; - decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes); - - HpackBlockBuilder hbb; - hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader, - false, name, false, value); - const size_t fragment_size = hbb.size() - 1; - const string fragment = hbb.buffer().substr(0, fragment_size); - - HandleControlFrameHeadersStart(); - EXPECT_FALSE(HandleControlFrameHeadersData(fragment)); -} - -// Decode with incomplete data in buffer. -TEST_P(HpackDecoder2Test, DecodeWithIncompleteData) { - HandleControlFrameHeadersStart(); - - // No need to wait for more data. - EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82")); - std::vector<std::pair<string, string>> expected_headers = { - {":method", "GET"}, {":path", "/index.html"}, {":method", "GET"}}; - - SpdyHeaderBlock expected_block1 = MakeHeaderBlock(expected_headers); - EXPECT_EQ(expected_block1, decoded_block()); - - // Full and partial headers, won't add partial to the headers. - EXPECT_TRUE( - HandleControlFrameHeadersData("\x40\x03goo" - "\x03gar\xbe\x40\x04spam")); - expected_headers.push_back({"goo", "gar"}); - expected_headers.push_back({"goo", "gar"}); - - SpdyHeaderBlock expected_block2 = MakeHeaderBlock(expected_headers); - EXPECT_EQ(expected_block2, decoded_block()); - - // Add the needed data. - EXPECT_TRUE(HandleControlFrameHeadersData("\x04gggs")); - - size_t size = 0; - EXPECT_TRUE(HandleControlFrameHeadersComplete(&size)); - EXPECT_EQ(24u, size); - - expected_headers.push_back({"spam", "gggs"}); - - SpdyHeaderBlock expected_block3 = MakeHeaderBlock(expected_headers); - EXPECT_EQ(expected_block3, decoded_block()); -} - -TEST_P(HpackDecoder2Test, HandleHeaderRepresentation) { - // Make sure the decoder is properly initialized. - HandleControlFrameHeadersStart(); - HandleControlFrameHeadersData(""); - - // All cookie crumbs are joined. - decoder_peer_.HandleHeaderRepresentation("cookie", " part 1"); - decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 "); - decoder_peer_.HandleHeaderRepresentation("cookie", "part3"); - - // Already-delimited headers are passed through. - decoder_peer_.HandleHeaderRepresentation("passed-through", - string("foo\0baz", 7)); - - // Other headers are joined on \0. Case matters. - decoder_peer_.HandleHeaderRepresentation("joined", "not joined"); - decoder_peer_.HandleHeaderRepresentation("joineD", "value 1"); - decoder_peer_.HandleHeaderRepresentation("joineD", "value 2"); - - // Empty headers remain empty. - decoder_peer_.HandleHeaderRepresentation("empty", ""); - - // Joined empty headers work as expected. - decoder_peer_.HandleHeaderRepresentation("empty-joined", ""); - decoder_peer_.HandleHeaderRepresentation("empty-joined", "foo"); - decoder_peer_.HandleHeaderRepresentation("empty-joined", ""); - decoder_peer_.HandleHeaderRepresentation("empty-joined", ""); - - // Non-contiguous cookie crumb. - decoder_peer_.HandleHeaderRepresentation("cookie", " fin!"); - - // Finish and emit all headers. - decoder_.HandleControlFrameHeadersComplete(nullptr); - - // Resulting decoded headers are in the same order as the inputs. - EXPECT_THAT(decoded_block(), - ElementsAre(Pair("cookie", " part 1; part 2 ; part3; fin!"), - Pair("passed-through", StringPiece("foo\0baz", 7)), - Pair("joined", "not joined"), - Pair("joineD", StringPiece("value 1\0value 2", 15)), - Pair("empty", ""), - Pair("empty-joined", StringPiece("\0foo\0\0", 6)))); -} - -// Decoding indexed static table field should work. -TEST_P(HpackDecoder2Test, IndexedHeaderStatic) { - // Reference static table entries #2 and #5. - const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess("\x82\x85"); - SpdyHeaderBlock expected_header_set1; - expected_header_set1[":method"] = "GET"; - expected_header_set1[":path"] = "/index.html"; - EXPECT_EQ(expected_header_set1, header_set1); - - // Reference static table entry #2. - const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess("\x82"); - SpdyHeaderBlock expected_header_set2; - expected_header_set2[":method"] = "GET"; - EXPECT_EQ(expected_header_set2, header_set2); -} - -TEST_P(HpackDecoder2Test, IndexedHeaderDynamic) { - // First header block: add an entry to header table. - const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess( - "\x40\x03" - "foo" - "\x03" - "bar"); - SpdyHeaderBlock expected_header_set1; - expected_header_set1["foo"] = "bar"; - EXPECT_EQ(expected_header_set1, header_set1); - - // Second header block: add another entry to header table. - const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess( - "\xbe\x40\x04" - "spam" - "\x04" - "eggs"); - SpdyHeaderBlock expected_header_set2; - expected_header_set2["foo"] = "bar"; - expected_header_set2["spam"] = "eggs"; - EXPECT_EQ(expected_header_set2, header_set2); - - // Third header block: refer to most recently added entry. - const SpdyHeaderBlock& header_set3 = DecodeBlockExpectingSuccess("\xbe"); - SpdyHeaderBlock expected_header_set3; - expected_header_set3["spam"] = "eggs"; - EXPECT_EQ(expected_header_set3, header_set3); -} - -// Test a too-large indexed header. -TEST_P(HpackDecoder2Test, InvalidIndexedHeader) { - // High-bit set, and a prefix of one more than the number of static entries. - EXPECT_FALSE(DecodeHeaderBlock("\xbe")); -} - -TEST_P(HpackDecoder2Test, ContextUpdateMaximumSize) { - EXPECT_EQ(kDefaultHeaderTableSizeSetting, - decoder_peer_.header_table()->max_size()); - string input; - { - // Maximum-size update with size 126. Succeeds. - HpackOutputStream output_stream; - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(126); - - output_stream.TakeString(&input); - EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(126u, decoder_peer_.header_table()->max_size()); - } - { - // Maximum-size update with kDefaultHeaderTableSizeSetting. Succeeds. - HpackOutputStream output_stream; - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(kDefaultHeaderTableSizeSetting); - - output_stream.TakeString(&input); - EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(kDefaultHeaderTableSizeSetting, - decoder_peer_.header_table()->max_size()); - } - { - // Maximum-size update with kDefaultHeaderTableSizeSetting + 1. Fails. - HpackOutputStream output_stream; - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1); - - output_stream.TakeString(&input); - EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(kDefaultHeaderTableSizeSetting, - decoder_peer_.header_table()->max_size()); - } -} - -// Two HeaderTableSizeUpdates may appear at the beginning of the block -TEST_P(HpackDecoder2Test, TwoTableSizeUpdates) { - string input; - { - // Should accept two table size updates, update to second one - HpackOutputStream output_stream; - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(0); - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(122); - - output_stream.TakeString(&input); - EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(122u, decoder_peer_.header_table()->max_size()); - } -} - -// Three HeaderTableSizeUpdates should result in an error -TEST_P(HpackDecoder2Test, ThreeTableSizeUpdatesError) { - string input; - { - // Should reject three table size updates, update to second one - HpackOutputStream output_stream; - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(5); - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(10); - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(15); - - output_stream.TakeString(&input); - - EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(10u, decoder_peer_.header_table()->max_size()); - } -} - -// HeaderTableSizeUpdates may only appear at the beginning of the block -// Any other updates should result in an error -TEST_P(HpackDecoder2Test, TableSizeUpdateSecondError) { - string input; - { - // Should reject a table size update appearing after a different entry - // The table size should remain as the default - HpackOutputStream output_stream; - output_stream.AppendBytes("\x82\x85"); - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(123); - - output_stream.TakeString(&input); - - EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(kDefaultHeaderTableSizeSetting, - decoder_peer_.header_table()->max_size()); - } -} - -// HeaderTableSizeUpdates may only appear at the beginning of the block -// Any other updates should result in an error -TEST_P(HpackDecoder2Test, TableSizeUpdateFirstThirdError) { - string input; - { - // Should reject the second table size update - // if a different entry appears after the first update - // The table size should update to the first but not the second - HpackOutputStream output_stream; - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(60); - output_stream.AppendBytes("\x82\x85"); - output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); - output_stream.AppendUint32(125); - - output_stream.TakeString(&input); - - EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); - EXPECT_EQ(60u, decoder_peer_.header_table()->max_size()); - } -} - -// Decoding two valid encoded literal headers with no indexing should -// work. -TEST_P(HpackDecoder2Test, LiteralHeaderNoIndexing) { - // First header with indexed name, second header with string literal - // name. - const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2"; - const SpdyHeaderBlock& header_set = - DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); - - SpdyHeaderBlock expected_header_set; - expected_header_set[":path"] = "/sample/path"; - expected_header_set[":path2"] = "/sample/path/2"; - EXPECT_EQ(expected_header_set, header_set); -} - -// Decoding two valid encoded literal headers with incremental -// indexing and string literal names should work. -TEST_P(HpackDecoder2Test, LiteralHeaderIncrementalIndexing) { - const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2"; - const SpdyHeaderBlock& header_set = - DecodeBlockExpectingSuccess(StringPiece(input, arraysize(input) - 1)); - - SpdyHeaderBlock expected_header_set; - expected_header_set[":path"] = "/sample/path"; - expected_header_set[":path2"] = "/sample/path/2"; - EXPECT_EQ(expected_header_set, header_set); -} - -TEST_P(HpackDecoder2Test, LiteralHeaderWithIndexingInvalidNameIndex) { - decoder_.ApplyHeaderTableSizeSetting(0); - - // Name is the last static index. Works. - EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x7d\x03ooo"))); - // Name is one beyond the last static index. Fails. - EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x7e\x03ooo"))); -} - -TEST_P(HpackDecoder2Test, LiteralHeaderNoIndexingInvalidNameIndex) { - // Name is the last static index. Works. - EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x0f\x2e\x03ooo"))); - // Name is one beyond the last static index. Fails. - EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x0f\x2f\x03ooo"))); -} - -TEST_P(HpackDecoder2Test, LiteralHeaderNeverIndexedInvalidNameIndex) { - // Name is the last static index. Works. - EXPECT_TRUE(DecodeHeaderBlock(StringPiece("\x1f\x2e\x03ooo"))); - // Name is one beyond the last static index. Fails. - EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x1f\x2f\x03ooo"))); -} - -TEST_P(HpackDecoder2Test, TruncatedIndex) { - // Indexed Header, varint for index requires multiple bytes, - // but only one provided. - EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\xff", 1))); -} - -TEST_P(HpackDecoder2Test, TruncatedHuffmanLiteral) { - // Literal value, Huffman encoded, but with the last byte missing (i.e. - // drop the final ff shown below). - // - // 41 | == Literal indexed == - // | Indexed name (idx = 1) - // | :authority - // 8c | Literal value (len = 12) - // | Huffman encoded: - // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... - // | Decoded: - // | www.example.com - // | -> :authority: www.example.com - - string first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); - EXPECT_TRUE(DecodeHeaderBlock(first)); - first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4"); - EXPECT_FALSE(DecodeHeaderBlock(first)); -} - -TEST_P(HpackDecoder2Test, HuffmanEOSError) { - // Literal value, Huffman encoded, but with an additional ff byte at the end - // of the string, i.e. an EOS that is longer than permitted. - // - // 41 | == Literal indexed == - // | Indexed name (idx = 1) - // | :authority - // 8d | Literal value (len = 13) - // | Huffman encoded: - // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... - // | Decoded: - // | www.example.com - // | -> :authority: www.example.com - - string first = a2b_hex("418cf1e3c2e5f23a6ba0ab90f4ff"); - EXPECT_TRUE(DecodeHeaderBlock(first)); - first = a2b_hex("418df1e3c2e5f23a6ba0ab90f4ffff"); - EXPECT_FALSE(DecodeHeaderBlock(first)); -} - -// Round-tripping the header set from RFC 7541 C.3.1 should work. -// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 -TEST_P(HpackDecoder2Test, BasicC31) { - HpackEncoder encoder(ObtainHpackHuffmanTable()); - - SpdyHeaderBlock expected_header_set; - expected_header_set[":method"] = "GET"; - expected_header_set[":scheme"] = "http"; - expected_header_set[":path"] = "/"; - expected_header_set[":authority"] = "www.example.com"; - - string encoded_header_set; - EXPECT_TRUE( - encoder.EncodeHeaderSet(expected_header_set, &encoded_header_set)); - - EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set)); - EXPECT_EQ(expected_header_set, decoded_block()); -} - -// RFC 7541, Section C.4: Request Examples with Huffman Coding -// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4 -TEST_P(HpackDecoder2Test, SectionC4RequestHuffmanExamples) { - // TODO(jamessynge): Use net/http2/hpack/tools/hpack_example.h to parse the - // example directly, instead of having it as a comment. - // 82 | == Indexed - Add == - // | idx = 2 - // | -> :method: GET - // 86 | == Indexed - Add == - // | idx = 6 - // | -> :scheme: http - // 84 | == Indexed - Add == - // | idx = 4 - // | -> :path: / - // 41 | == Literal indexed == - // | Indexed name (idx = 1) - // | :authority - // 8c | Literal value (len = 12) - // | Huffman encoded: - // f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... - // | Decoded: - // | www.example.com - // | -> :authority: www.example.com - string first = a2b_hex("828684418cf1e3c2e5f23a6ba0ab90f4ff"); - const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); - - EXPECT_THAT(first_header_set, - ElementsAre( - // clang-format off - Pair(":method", "GET"), - Pair(":scheme", "http"), - Pair(":path", "/"), - Pair(":authority", "www.example.com"))); - // clang-format on - - expectEntry(62, 57, ":authority", "www.example.com"); - EXPECT_EQ(57u, decoder_peer_.header_table()->size()); - - // 82 | == Indexed - Add == - // | idx = 2 - // | -> :method: GET - // 86 | == Indexed - Add == - // | idx = 6 - // | -> :scheme: http - // 84 | == Indexed - Add == - // | idx = 4 - // | -> :path: / - // be | == Indexed - Add == - // | idx = 62 - // | -> :authority: www.example.com - // 58 | == Literal indexed == - // | Indexed name (idx = 24) - // | cache-control - // 86 | Literal value (len = 8) - // | Huffman encoded: - // a8eb 1064 9cbf | ...d.. - // | Decoded: - // | no-cache - // | -> cache-control: no-cache - - string second = a2b_hex("828684be5886a8eb10649cbf"); - const SpdyHeaderBlock& second_header_set = - DecodeBlockExpectingSuccess(second); - - EXPECT_THAT(second_header_set, - ElementsAre( - // clang-format off - Pair(":method", "GET"), - Pair(":scheme", "http"), - Pair(":path", "/"), - Pair(":authority", "www.example.com"), - Pair("cache-control", "no-cache"))); - // clang-format on - - expectEntry(62, 53, "cache-control", "no-cache"); - expectEntry(63, 57, ":authority", "www.example.com"); - EXPECT_EQ(110u, decoder_peer_.header_table()->size()); - - // 82 | == Indexed - Add == - // | idx = 2 - // | -> :method: GET - // 87 | == Indexed - Add == - // | idx = 7 - // | -> :scheme: https - // 85 | == Indexed - Add == - // | idx = 5 - // | -> :path: /index.html - // bf | == Indexed - Add == - // | idx = 63 - // | -> :authority: www.example.com - // 40 | == Literal indexed == - // 88 | Literal name (len = 10) - // | Huffman encoded: - // 25a8 49e9 5ba9 7d7f | %.I.[.}. - // | Decoded: - // | custom-key - // 89 | Literal value (len = 12) - // | Huffman encoded: - // 25a8 49e9 5bb8 e8b4 bf | %.I.[.... - // | Decoded: - // | custom-value - // | -> custom-key: custom-value - string third = a2b_hex("828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf"); - const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); - - EXPECT_THAT( - third_header_set, - ElementsAre( - // clang-format off - Pair(":method", "GET"), - Pair(":scheme", "https"), - Pair(":path", "/index.html"), - Pair(":authority", "www.example.com"), - Pair("custom-key", "custom-value"))); - // clang-format on - - expectEntry(62, 54, "custom-key", "custom-value"); - expectEntry(63, 53, "cache-control", "no-cache"); - expectEntry(64, 57, ":authority", "www.example.com"); - EXPECT_EQ(164u, decoder_peer_.header_table()->size()); -} - -// RFC 7541, Section C.6: Response Examples with Huffman Coding -// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6 -TEST_P(HpackDecoder2Test, SectionC6ResponseHuffmanExamples) { - decoder_.ApplyHeaderTableSizeSetting(256); - - // 48 | == Literal indexed == - // | Indexed name (idx = 8) - // | :status - // 82 | Literal value (len = 3) - // | Huffman encoded: - // 6402 | d. - // | Decoded: - // | 302 - // | -> :status: 302 - // 58 | == Literal indexed == - // | Indexed name (idx = 24) - // | cache-control - // 85 | Literal value (len = 7) - // | Huffman encoded: - // aec3 771a 4b | ..w.K - // | Decoded: - // | private - // | -> cache-control: private - // 61 | == Literal indexed == - // | Indexed name (idx = 33) - // | date - // 96 | Literal value (len = 29) - // | Huffman encoded: - // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f - // e082 a62d 1bff | ...-.. - // | Decoded: - // | Mon, 21 Oct 2013 20:13:21 - // | GMT - // | -> date: Mon, 21 Oct 2013 - // | 20:13:21 GMT - // 6e | == Literal indexed == - // | Indexed name (idx = 46) - // | location - // 91 | Literal value (len = 23) - // | Huffman encoded: - // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C - // d3 | . - // | Decoded: - // | https://www.example.com - // | -> location: https://www.e - // | xample.com - - string first = a2b_hex( - "488264025885aec3771a4b6196d07abe" - "941054d444a8200595040b8166e082a6" - "2d1bff6e919d29ad171863c78f0b97c8" - "e9ae82ae43d3"); - const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first); - - EXPECT_THAT(first_header_set, - ElementsAre( - // clang-format off - Pair(":status", "302"), - Pair("cache-control", "private"), - Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), - Pair("location", "https://www.example.com"))); - // clang-format on - - expectEntry(62, 63, "location", "https://www.example.com"); - expectEntry(63, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); - expectEntry(64, 52, "cache-control", "private"); - expectEntry(65, 42, ":status", "302"); - EXPECT_EQ(222u, decoder_peer_.header_table()->size()); - - // 48 | == Literal indexed == - // | Indexed name (idx = 8) - // | :status - // 83 | Literal value (len = 3) - // | Huffman encoded: - // 640e ff | d.. - // | Decoded: - // | 307 - // | - evict: :status: 302 - // | -> :status: 307 - // c1 | == Indexed - Add == - // | idx = 65 - // | -> cache-control: private - // c0 | == Indexed - Add == - // | idx = 64 - // | -> date: Mon, 21 Oct 2013 - // | 20:13:21 GMT - // bf | == Indexed - Add == - // | idx = 63 - // | -> location: - // | https://www.example.com - string second = a2b_hex("4883640effc1c0bf"); - const SpdyHeaderBlock& second_header_set = - DecodeBlockExpectingSuccess(second); - - EXPECT_THAT(second_header_set, - ElementsAre( - // clang-format off - Pair(":status", "307"), - Pair("cache-control", "private"), - Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), - Pair("location", "https://www.example.com"))); - // clang-format on - - expectEntry(62, 42, ":status", "307"); - expectEntry(63, 63, "location", "https://www.example.com"); - expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT"); - expectEntry(65, 52, "cache-control", "private"); - EXPECT_EQ(222u, decoder_peer_.header_table()->size()); - - // 88 | == Indexed - Add == - // | idx = 8 - // | -> :status: 200 - // c1 | == Indexed - Add == - // | idx = 65 - // | -> cache-control: private - // 61 | == Literal indexed == - // | Indexed name (idx = 33) - // | date - // 96 | Literal value (len = 22) - // | Huffman encoded: - // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f - // e084 a62d 1bff | ...-.. - // | Decoded: - // | Mon, 21 Oct 2013 20:13:22 - // | GMT - // | - evict: cache-control: - // | private - // | -> date: Mon, 21 Oct 2013 - // | 20:13:22 GMT - // c0 | == Indexed - Add == - // | idx = 64 - // | -> location: - // | https://www.example.com - // 5a | == Literal indexed == - // | Indexed name (idx = 26) - // | content-encoding - // 83 | Literal value (len = 3) - // | Huffman encoded: - // 9bd9 ab | ... - // | Decoded: - // | gzip - // | - evict: date: Mon, 21 Oct - // | 2013 20:13:21 GMT - // | -> content-encoding: gzip - // 77 | == Literal indexed == - // | Indexed name (idx = 55) - // | set-cookie - // ad | Literal value (len = 45) - // | Huffman encoded: - // 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9` - // d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)... - // 3160 65c0 03ed 4ee5 b106 3d50 07 | 1`e...N...=P. - // | Decoded: - // | foo=ASDJKHQKBZXOQWEOPIUAXQ - // | WEOIU; max-age=3600; versi - // | on=1 - // | - evict: location: - // | https://www.example.com - // | - evict: :status: 307 - // | -> set-cookie: foo=ASDJKHQ - // | KBZXOQWEOPIUAXQWEOIU; - // | max-age=3600; version=1 - string third = a2b_hex( - "88c16196d07abe941054d444a8200595" - "040b8166e084a62d1bffc05a839bd9ab" - "77ad94e7821dd7f2e6c7b335dfdfcd5b" - "3960d5af27087f3672c1ab270fb5291f" - "9587316065c003ed4ee5b1063d5007"); - const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third); - - EXPECT_THAT(third_header_set, - ElementsAre( - // clang-format off - Pair(":status", "200"), - Pair("cache-control", "private"), - Pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), - Pair("location", "https://www.example.com"), - Pair("content-encoding", "gzip"), - Pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" - " max-age=3600; version=1"))); - // clang-format on - - expectEntry(62, 98, "set-cookie", - "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;" - " max-age=3600; version=1"); - expectEntry(63, 52, "content-encoding", "gzip"); - expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT"); - EXPECT_EQ(215u, decoder_peer_.header_table()->size()); -} - -// Regression test: Found that entries with dynamic indexed names and literal -// values caused "use after free" MSAN failures if the name was evicted as it -// was being re-used. -TEST_P(HpackDecoder2Test, ReuseNameOfEvictedEntry) { - // Each entry is measured as 32 bytes plus the sum of the lengths of the name - // and the value. Set the size big enough for at most one entry, and a fairly - // small one at that (31 ASCII characters). - decoder_.ApplyHeaderTableSizeSetting(63); - - HpackBlockBuilder hbb; - - const StringPiece name("some-name"); - const StringPiece value1("some-value"); - const StringPiece value2("another-value"); - const StringPiece value3("yet-another-value"); - - // Add an entry that will become the first in the dynamic table, entry 62. - hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false, - name, false, value1); - - // Confirm that entry has been added by re-using it. - hbb.AppendIndexedHeader(62); - - // Add another entry referring to the name of the first. This will evict the - // first. - hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62, - false, value2); - - // Confirm that entry has been added by re-using it. - hbb.AppendIndexedHeader(62); - - // Add another entry referring to the name of the second. This will evict the - // second. - hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62, - false, value3); - - // Confirm that entry has been added by re-using it. - hbb.AppendIndexedHeader(62); - - EXPECT_TRUE(DecodeHeaderBlock(hbb.buffer())); - - SpdyHeaderBlock expected_header_set; - expected_header_set.AppendValueOrAddHeader(name, value1); - expected_header_set.AppendValueOrAddHeader(name, value1); - expected_header_set.AppendValueOrAddHeader(name, value2); - expected_header_set.AppendValueOrAddHeader(name, value2); - expected_header_set.AppendValueOrAddHeader(name, value3); - expected_header_set.AppendValueOrAddHeader(name, value3); - - // SpdyHeaderBlock stores these 6 strings as '\0' separated values. - // Make sure that is what happened. - string joined_values = expected_header_set[name].as_string(); - EXPECT_EQ(joined_values.size(), - 2 * value1.size() + 2 * value2.size() + 2 * value3.size() + 5); - - EXPECT_EQ(expected_header_set, decoded_block()); -} - -} // namespace -} // namespace test -} // namespace net
diff --git a/net/spdy/spdy_flags.cc b/net/spdy/spdy_flags.cc index e074527..23956d6 100644 --- a/net/spdy/spdy_flags.cc +++ b/net/spdy/spdy_flags.cc
@@ -12,9 +12,6 @@ // If true, remove use of SpdyFrameBuilder::OverwriteLength(). bool FLAGS_chromium_http2_flag_remove_rewritelength = true; -// Use //net/http2/hpack/decoder as HPACK entry decoder. -bool FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; - // Use //net/http2/hpack/decoder as complete HPACK decoder. bool FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = true;
diff --git a/net/spdy/spdy_flags.h b/net/spdy/spdy_flags.h index a660235b..de706f2e 100644 --- a/net/spdy/spdy_flags.h +++ b/net/spdy/spdy_flags.h
@@ -12,8 +12,6 @@ NET_EXPORT_PRIVATE extern bool FLAGS_chromium_http2_flag_log_compressed_size; NET_EXPORT_PRIVATE extern bool FLAGS_chromium_http2_flag_remove_rewritelength; NET_EXPORT_PRIVATE extern bool - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2; -NET_EXPORT_PRIVATE extern bool FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3; NET_EXPORT_PRIVATE extern bool FLAGS_use_http2_frame_decoder_adapter; NET_EXPORT_PRIVATE extern bool FLAGS_use_nested_spdy_framer_decoder;
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index c8471bf59..1483962 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc
@@ -25,7 +25,6 @@ #include "net/quic/core/quic_flags.h" #include "net/spdy/hpack/hpack_constants.h" #include "net/spdy/hpack/hpack_decoder.h" -#include "net/spdy/hpack/hpack_decoder2.h" #include "net/spdy/hpack/hpack_decoder3.h" #include "net/spdy/http2_frame_decoder_adapter.h" #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" @@ -2403,11 +2402,7 @@ HpackDecoderInterface* SpdyFramer::GetHpackDecoder() { if (hpack_decoder_.get() == nullptr) { if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3) { - SPDY_BUG_IF(FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2) - << "Both alternate decoders are enabled."; hpack_decoder_.reset(new HpackDecoder3()); - } else if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2) { - hpack_decoder_.reset(new HpackDecoder2()); } else { hpack_decoder_.reset(new HpackDecoder()); }
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index 5072e92..0552ba8 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc
@@ -636,7 +636,7 @@ } enum DecoderChoice { DECODER_SELF, DECODER_NESTED, DECODER_HTTP2 }; -enum HpackChoice { HPACK_DECODER_1, HPACK_DECODER_2, HPACK_DECODER_3 }; +enum HpackChoice { HPACK_DECODER_1, HPACK_DECODER_3 }; class SpdyFramerTest : public ::testing::TestWithParam<std::tuple<DecoderChoice, HpackChoice>> { @@ -659,15 +659,9 @@ } switch (std::get<1>(param)) { case HPACK_DECODER_1: - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; - break; - case HPACK_DECODER_2: - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = true; FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = false; break; case HPACK_DECODER_3: - FLAGS_chromium_http2_flag_spdy_use_hpack_decoder2 = false; FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3 = true; break; } @@ -695,12 +689,13 @@ } }; -INSTANTIATE_TEST_CASE_P( - SpdyFramerTests, - SpdyFramerTest, - ::testing::Combine( - ::testing::Values(DECODER_SELF, DECODER_NESTED, DECODER_HTTP2), - ::testing::Values(HPACK_DECODER_1, HPACK_DECODER_2, HPACK_DECODER_3))); +INSTANTIATE_TEST_CASE_P(SpdyFramerTests, + SpdyFramerTest, + ::testing::Combine(::testing::Values(DECODER_SELF, + DECODER_NESTED, + DECODER_HTTP2), + ::testing::Values(HPACK_DECODER_1, + HPACK_DECODER_3))); // Test that we can encode and decode a SpdyHeaderBlock in serialized form. TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 906ddb2..4376bd9 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -3717,29 +3717,6 @@ } ] } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-passthrough-cmd-decoder" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_gl_passthrough_tests", - "override_compile_targets": [ - "telemetry_gpu_integration_test_run" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Ubuntu" - } - ] - } } ] }, @@ -8135,38 +8112,6 @@ }, { "args": [ - "info_collection", - "--show-stdout", - "--browser=release", - "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", - "--expected-vendor-id", - "8086", - "--expected-device-id", - "0a2e" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "info_collection_tests", - "override_compile_targets": [ - "telemetry_gpu_integration_test_run" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.12" - }, - { - "gpu": "1002:6821", - "hidpi": "1", - "os": "Mac" - } - ] - } - }, - { - "args": [ "maps", "--show-stdout", "--browser=release",
diff --git a/third_party/OWNERS b/third_party/OWNERS index c79ad1b..65d14c4a 100644 --- a/third_party/OWNERS +++ b/third_party/OWNERS
@@ -19,3 +19,5 @@ klobag@chromium.org sky@chromium.org thakis@chromium.org + +per-file .gitignore=*
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 4a689f97..bae83cf 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -158,9 +158,6 @@ # ====== Paint team owned tests to here ====== -crbug.com/702148 http/tests/images/gif-animated-partial-load.html [ NeedsRebaseline ] -crbug.com/702148 virtual/mojo-loading/http/tests/images/gif-animated-partial-load.html [ NeedsRebaseline ] - # ====== LayoutNG-only failures from here ====== # LayoutNG - is a new layout system for Blink. @@ -2828,7 +2825,7 @@ crbug.com/698521 external/wpt/preload/preload-with-type.html [ Failure Pass ] # Sheriff failures 2017-03-10 -crbug.com/402805 [ Mac10.10 Mac10.11 Mac10.12 ] inspector-protocol/input/emulateTouchFromMouseEvent.html [ Timeout ] +crbug.com/402805 [ Mac10.10 Mac10.11 Mac10.12 Win10 ] inspector-protocol/input/emulateTouchFromMouseEvent.html [ Timeout ] crbug.com/700374 [ Win ] virtual/mojo-loading/http/tests/inspector/workers-on-navigation.html [ Failure Pass ] crbug.com/700374 [ Win ] http/tests/inspector/workers-on-navigation.html [ Failure Pass ] crbug.com/700387 [ Win7 ] external/wpt/fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/gif-animated-partial-load-expected.png b/third_party/WebKit/LayoutTests/http/tests/images/gif-animated-partial-load-expected.png new file mode 100644 index 0000000..23d531b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/images/gif-animated-partial-load-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/gif-animated-partial-load-expected.txt b/third_party/WebKit/LayoutTests/http/tests/images/gif-animated-partial-load-expected.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/images/gif-animated-partial-load-expected.txt
@@ -0,0 +1 @@ +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-navigation.html b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-navigation.html index 4052d5b..167da48 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-navigation.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-navigation.html
@@ -24,7 +24,7 @@ function test() { - for (var message of SDK.consoleModel.messages()) { + for (var message of ConsoleModel.consoleModel.messages()) { var args = (message.parameters || []).map((arg) => arg.type); InspectorTest.addResult("Message: \"" + message.messageText + "\", arguments: [" + args.join(", ") + "]"); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-remove.html b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-remove.html index fb74a8a..3129a56 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-remove.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/console-clear-arguments-on-frame-remove.html
@@ -31,7 +31,7 @@ function test() { - for (var message of SDK.consoleModel.messages()) { + for (var message of ConsoleModel.consoleModel.messages()) { var args = (message.parameters || []).map((arg) => arg.type); InspectorTest.addResult("Message: \"" + message.messageText + "\", arguments: [" + args.join(", ") + "]"); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js index 40efec2..11e3d1f9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-test.js
@@ -93,7 +93,7 @@ InspectorTest.dumpConsoleMessagesIntoArray = function(printOriginatingCommand, dumpClassNames, formatter) { - Common.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose); + Common.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Verbose); formatter = formatter || InspectorTest.prepareConsoleMessageText; var result = []; InspectorTest.disableConsoleViewport();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console/console-links-on-messages-before-inspection.html b/third_party/WebKit/LayoutTests/http/tests/inspector/console/console-links-on-messages-before-inspection.html index 390ee4d0..336c5fc1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/console/console-links-on-messages-before-inspection.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console/console-links-on-messages-before-inspection.html
@@ -15,8 +15,8 @@ { var mainTarget = SDK.targetManager.mainTarget(); var debuggerModel = SDK.DebuggerModel.fromTarget(mainTarget); - var message = new SDK.ConsoleMessage(mainTarget, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, "hello?", null, "http://127.0.0.1:8000/inspector/resources/source2.js"); - SDK.consoleModel.addMessage(message); + var message = new ConsoleModel.ConsoleMessage(mainTarget, ConsoleModel.ConsoleMessage.MessageSource.JS, ConsoleModel.ConsoleMessage.MessageLevel.Info, "hello?", null, "http://127.0.0.1:8000/inspector/resources/source2.js"); + ConsoleModel.consoleModel.addMessage(message); debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, onScriptAdded); InspectorTest.dumpConsoleMessages();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js index b7a4b9c..49dae01 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -668,7 +668,7 @@ InspectorTest.addConsoleSniffer = function(override, opt_sticky) { - InspectorTest.addSniffer(SDK.ConsoleModel.prototype, "addMessage", override, opt_sticky); + InspectorTest.addSniffer(ConsoleModel.ConsoleModel.prototype, "addMessage", override, opt_sticky); } InspectorTest.override = function(receiver, methodName, override, opt_sticky) @@ -987,7 +987,7 @@ InspectorTest.serviceWorkerManager = target.model(SDK.ServiceWorkerManager); InspectorTest.tracingManager = target.model(SDK.TracingManager); InspectorTest.mainTarget = target; - InspectorTest.consoleModel = SDK.consoleModel; + InspectorTest.consoleModel = ConsoleModel.consoleModel; }, targetRemoved: function(target) { }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html index 61d0ab08..c1908f82 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/user-agent-override.html
@@ -30,13 +30,13 @@ function waitForConsoleMessage(regex) { return new Promise(function(resolve) { - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, sniff); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, sniff); function sniff(e) { if (e.data && regex.test(e.data.messageText)) { resolve(e.data); - SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, sniff); + ConsoleModel.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, sniff); } } });
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-eval-throw.html b/third_party/WebKit/LayoutTests/inspector/console/console-eval-throw.html index fa8af2be..5f717e0 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-eval-throw.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-eval-throw.html
@@ -9,12 +9,12 @@ { InspectorTest.dumpConsoleMessagesIgnoreErrorStackFrames(); - InspectorTest.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, afterCleared); + InspectorTest.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.ConsoleCleared, afterCleared); Console.ConsoleView.clearConsole(); function afterCleared() { - InspectorTest.consoleModel.removeEventListener(SDK.ConsoleModel.Events.ConsoleCleared, afterCleared); + InspectorTest.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.ConsoleCleared, afterCleared); next(); } }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html b/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html index 1069b1c9b..4226eb51 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html
@@ -45,35 +45,35 @@ function verbose(next) { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Verbose); dumpVisibleMessages(); next(); }, function info(next) { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Info); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Info); dumpVisibleMessages(); next(); }, function warning(next) { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Warning); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Warning); dumpVisibleMessages(); next(); }, function error(next) { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Error); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Error); dumpVisibleMessages(); next(); }, function abcMessagePlain(next) { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Verbose); Console.ConsoleView.instance()._filter._textFilterUI.setValue("abc"); Console.ConsoleView.instance()._filter._textFilterChanged(); dumpVisibleMessages(); @@ -90,7 +90,7 @@ function abcMessageRegexWarning(next) { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Warning); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Warning); dumpVisibleMessages(); next(); }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-preserve-log.html b/third_party/WebKit/LayoutTests/inspector/console/console-preserve-log.html index 5e9cb3d..8d6bf217 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-preserve-log.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-preserve-log.html
@@ -5,7 +5,7 @@ <script> function test() { - InspectorTest.consoleModel.addMessage(new SDK.ConsoleMessage(InspectorTest.mainTarget, SDK.ConsoleMessage.MessageSource.Other, SDK.ConsoleMessage.MessageLevel.Info, "PASS")); + InspectorTest.consoleModel.addMessage(new ConsoleModel.ConsoleMessage(InspectorTest.mainTarget, ConsoleModel.ConsoleMessage.MessageSource.Other, ConsoleModel.ConsoleMessage.MessageLevel.Info, "PASS")); Common.settingForTest("preserveConsoleLog").set(true); InspectorTest.reloadPage(function() { InspectorTest.dumpConsoleMessages();
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error-in-worker.html b/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error-in-worker.html index 341c25c..afed3d41 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error-in-worker.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error-in-worker.html
@@ -18,8 +18,8 @@ function test() { - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, InspectorTest.wrapListener(messageAdded)); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageUpdated, InspectorTest.wrapListener(messageUpdated)); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, InspectorTest.wrapListener(messageAdded)); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageUpdated, InspectorTest.wrapListener(messageUpdated)); InspectorTest.addResult("Creating worker with promise"); InspectorTest.evaluateInPageWithTimeout("createPromise()"); @@ -29,7 +29,7 @@ InspectorTest.addResult(""); InspectorTest.addResult("Message added: " + event.data.level + " " + event.data.type); - if (event.data.level === SDK.ConsoleMessage.MessageLevel.Error) { + if (event.data.level === ConsoleModel.ConsoleMessage.MessageLevel.Error) { InspectorTest.dumpConsoleCounters(); InspectorTest.addResult(""); InspectorTest.addResult("Handling promise");
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error.html b/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error.html index a212edd..b437f7f 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-revoke-error.html
@@ -21,7 +21,7 @@ function test() { var messageAddedListener = InspectorTest.wrapListener(messageAdded); - InspectorTest.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, messageAddedListener); + InspectorTest.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, messageAddedListener); InspectorTest.addResult("Creating promise"); InspectorTest.evaluateInPageWithTimeout("createPromises()"); @@ -34,11 +34,11 @@ return; messageNumber = 0; - InspectorTest.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, messageAddedListener); + InspectorTest.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, messageAddedListener); InspectorTest.addResult(""); // Process array as a batch. - InspectorTest.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageUpdated, InspectorTest.wrapListener(messageUpdated)); + InspectorTest.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageUpdated, InspectorTest.wrapListener(messageUpdated)); InspectorTest.dumpConsoleCounters(); InspectorTest.addResult(""); InspectorTest.addResult("Handling promise");
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-tests.html b/third_party/WebKit/LayoutTests/inspector/console/console-tests.html index d4b1600..41f307f 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-tests.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-tests.html
@@ -42,7 +42,7 @@ function test() { - Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose); + Common.settings.settingForTest('messageLevelFilters2').set(ConsoleModel.ConsoleMessage.MessageLevel.Verbose); InspectorTest.dumpConsoleMessagesWithClasses(); InspectorTest.completeTest(); }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-timestamp.html b/third_party/WebKit/LayoutTests/inspector/console/console-timestamp.html index 1bc866e5..9d605a8d 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-timestamp.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-timestamp.html
@@ -13,10 +13,10 @@ function addMessageWithFixedTimestamp(messageText, timestamp) { - var message = new SDK.ConsoleMessage( + var message = new ConsoleModel.ConsoleMessage( InspectorTest.mainTarget, - SDK.ConsoleMessage.MessageSource.Other, // source - SDK.ConsoleMessage.MessageLevel.Info, // level + ConsoleModel.ConsoleMessage.MessageSource.Other, // source + ConsoleModel.ConsoleMessage.MessageLevel.Info, // level messageText, undefined, // type undefined, // url
diff --git a/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html b/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html index 4945678..cbcbb1a 100644 --- a/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html +++ b/third_party/WebKit/LayoutTests/inspector/extensions/extensions-panel.html
@@ -64,11 +64,11 @@ InspectorTest.disableConsoleViewport(); InspectorTest.evaluateInPage("logMessage()"); var wrappedConsoleMessageAdded = InspectorTest.safeWrap(consoleMessageAdded); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded); function consoleMessageAdded() { - SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded); + ConsoleModel.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded); Console.ConsoleView.instance()._viewportThrottler.flush(); InspectorTest.deprecatedRunAfterPendingDispatches(clickOnMessage) }
diff --git a/third_party/WebKit/LayoutTests/inspector/initial-modules-load-expected.txt b/third_party/WebKit/LayoutTests/inspector/initial-modules-load-expected.txt index f8f32be0..2ab6cfd 100644 --- a/third_party/WebKit/LayoutTests/inspector/initial-modules-load-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/initial-modules-load-expected.txt
@@ -6,6 +6,7 @@ bindings common components + console_model dom_extension emulation extensions @@ -28,6 +29,7 @@ color_picker common components + console_model dom_extension elements emulation @@ -55,6 +57,7 @@ color_picker common components + console_model cookie_table data_grid diff @@ -90,6 +93,7 @@ color_picker common components + console_model cookie_table data_grid diff @@ -128,6 +132,7 @@ color_picker common components + console_model cookie_table data_grid diff
diff --git a/third_party/WebKit/LayoutTests/inspector/input-event-warning.html b/third_party/WebKit/LayoutTests/inspector/input-event-warning.html index 0822b324..c4b5531ef 100644 --- a/third_party/WebKit/LayoutTests/inspector/input-event-warning.html +++ b/third_party/WebKit/LayoutTests/inspector/input-event-warning.html
@@ -62,7 +62,7 @@ function test() { - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, InspectorTest.safeWrap(onConsoleMessage)); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, InspectorTest.safeWrap(onConsoleMessage)); step1(); function step1()
diff --git a/third_party/WebKit/LayoutTests/inspector/open-with-rendering-option-enabled-expected.txt b/third_party/WebKit/LayoutTests/inspector/open-with-rendering-option-enabled-expected.txt index 94c946b..30b0d9df 100644 --- a/third_party/WebKit/LayoutTests/inspector/open-with-rendering-option-enabled-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/open-with-rendering-option-enabled-expected.txt
@@ -4,6 +4,7 @@ bindings common components + console_model dom_extension emulation extensions
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/monitor-console-command.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/monitor-console-command.html index bc73877..47f2eae2 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/monitor-console-command.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/monitor-console-command.html
@@ -68,7 +68,7 @@ function didReceive(message) { - if (message.type === SDK.ConsoleMessage.MessageType.Result) { + if (message.type === ConsoleModel.ConsoleMessage.MessageType.Result) { InspectorTest.waitUntilMessageReceived(didReceive); return; }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html index 59e642c..fd0645c 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html
@@ -40,7 +40,7 @@ function testDumpFunctionDefinition(next) { InspectorTest.addSniffer(ObjectUI.ObjectPropertiesSection, "formatObjectAsFunction", onConsoleMessagesReceived); - SDK.consoleModel.evaluateCommandInConsole(UI.context.flavor(SDK.ExecutionContext), "jumpToMe"); + ConsoleModel.consoleModel.evaluateCommandInConsole(UI.context.flavor(SDK.ExecutionContext), "jumpToMe"); function onConsoleMessagesReceived() {
diff --git a/third_party/WebKit/LayoutTests/platform/linux/http/tests/images/gif-animated-partial-load-expected.png b/third_party/WebKit/LayoutTests/platform/linux/http/tests/images/gif-animated-partial-load-expected.png new file mode 100644 index 0000000..92dcd244 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/http/tests/images/gif-animated-partial-load-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/images/gif-animated-partial-load-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/images/gif-animated-partial-load-expected.png new file mode 100644 index 0000000..92dcd244 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/images/gif-animated-partial-load-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/mojo-loading/http/tests/images/gif-animated-partial-load-expected.png b/third_party/WebKit/LayoutTests/virtual/mojo-loading/http/tests/images/gif-animated-partial-load-expected.png new file mode 100644 index 0000000..23d531b --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/mojo-loading/http/tests/images/gif-animated-partial-load-expected.png Binary files differ
diff --git a/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/third_party/WebKit/Source/bindings/modules/v8/generated.gni index d8eb286..b7536970 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/generated.gni +++ b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -50,6 +50,8 @@ "$bindings_modules_v8_output_dir/RenderingContext.h", "$bindings_modules_v8_output_dir/RequestOrUSVString.cpp", "$bindings_modules_v8_output_dir/RequestOrUSVString.h", + "$bindings_modules_v8_output_dir/RequestOrUSVStringOrRequestOrUSVStringSequence.cpp", + "$bindings_modules_v8_output_dir/RequestOrUSVStringOrRequestOrUSVStringSequence.h", "$bindings_modules_v8_output_dir/StringOrArrayBufferOrNFCMessage.cpp", "$bindings_modules_v8_output_dir/StringOrArrayBufferOrNFCMessage.h", "$bindings_modules_v8_output_dir/StringOrCanvasGradientOrCanvasPattern.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp index 7887781..1ea5625 100644 --- a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
@@ -124,6 +124,26 @@ GradientStop() : offset(0), specified(false) {} }; +struct CSSGradientValue::GradientDesc { + STACK_ALLOCATED(); + + GradientDesc(const FloatPoint& p0, + const FloatPoint& p1, + GradientSpreadMethod spreadMethod) + : p0(p0), p1(p1), spreadMethod(spreadMethod) {} + GradientDesc(const FloatPoint& p0, + const FloatPoint& p1, + float r0, + float r1, + GradientSpreadMethod spreadMethod) + : p0(p0), p1(p1), r0(r0), r1(r1), spreadMethod(spreadMethod) {} + + Vector<Gradient::ColorStop> stops; + FloatPoint p0, p1; + float r0 = 0, r1 = 0; + GradientSpreadMethod spreadMethod = SpreadMethodPad; +}; + static void replaceColorHintsWithColorStops( Vector<GradientStop>& stops, const HeapVector<CSSGradientColorStop, 2>& cssGradientStops) { @@ -223,7 +243,7 @@ stopColor, object.resolveColor(CSSPropertyColor)); } -void CSSGradientValue::addDeprecatedStops(Gradient* gradient, +void CSSGradientValue::addDeprecatedStops(GradientDesc& desc, const LayoutObject& object) { ASSERT(m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient); @@ -241,19 +261,19 @@ else offset = stop.m_position->getFloatValue(); - gradient->addColorStop(offset, resolveStopColor(*stop.m_color, object)); + desc.stops.emplace_back(offset, resolveStopColor(*stop.m_color, object)); } } static bool requiresStopsNormalization(const Vector<GradientStop>& stops, - const Gradient* gradient) { + CSSGradientValue::GradientDesc& desc) { // We need at least two stops to normalize if (stops.size() < 2) return false; // Repeating gradients are implemented using a normalized stop offset range // with the point/radius pairs aligned on the interval endpoints. - if (gradient->spreadMethod() == SpreadMethodRepeat) + if (desc.spreadMethod == SpreadMethodRepeat) return true; // Degenerate stops @@ -266,7 +286,7 @@ // Redistribute the stops such that they fully cover [0 , 1] and add them to the // gradient. static bool normalizeAndAddStops(const Vector<GradientStop>& stops, - Gradient* gradient) { + CSSGradientValue::GradientDesc& desc) { ASSERT(stops.size() > 1); const float firstOffset = stops.front().offset; @@ -281,9 +301,9 @@ // image with the color of the last color-stop in the rule. // For non-repeating gradients, both the first color and the last color can // be significant (padding on both sides of the offset). - if (gradient->spreadMethod() != SpreadMethodRepeat) - gradient->addColorStop(clampedOffset, stops.front().color); - gradient->addColorStop(clampedOffset, stops.back().color); + if (desc.spreadMethod != SpreadMethodRepeat) + desc.stops.emplace_back(clampedOffset, stops.front().color); + desc.stops.emplace_back(clampedOffset, stops.back().color); return false; } @@ -298,7 +318,7 @@ ASSERT(i == 0 || normalizedOffset >= (stops[i - 1].offset - firstOffset) / span); - gradient->addColorStop(normalizedOffset, stops[i].color); + desc.stops.emplace_back(normalizedOffset, stops[i].color); } return true; @@ -332,31 +352,31 @@ } // Update the linear gradient points to align with the given offset range. -static void adjustGradientPointsForOffsetRange(Gradient* gradient, - float firstOffset, - float lastOffset) { - ASSERT(!gradient->isRadial()); +static void adjustGradientPointsForOffsetRange( + CSSGradientValue::GradientDesc& desc, + float firstOffset, + float lastOffset) { ASSERT(firstOffset <= lastOffset); - const FloatPoint p0 = gradient->p0(); - const FloatPoint p1 = gradient->p1(); + const FloatPoint p0 = desc.p0; + const FloatPoint p1 = desc.p1; const FloatSize d(p1 - p0); // Linear offsets are relative to the [p0 , p1] segment. - gradient->setP0(p0 + d * firstOffset); - gradient->setP1(p0 + d * lastOffset); + desc.p0 = p0 + d * firstOffset; + desc.p1 = p0 + d * lastOffset; } // Update the radial gradient radii to align with the given offset range. -static void adjustGradientRadiiForOffsetRange(Gradient* gradient, - float firstOffset, - float lastOffset) { - ASSERT(gradient->isRadial()); +static void adjustGradientRadiiForOffsetRange( + CSSGradientValue::GradientDesc& desc, + float firstOffset, + float lastOffset) { ASSERT(firstOffset <= lastOffset); // Radial offsets are relative to the [0 , endRadius] segment. - float adjustedR0 = gradient->endRadius() * firstOffset; - float adjustedR1 = gradient->endRadius() * lastOffset; + float adjustedR0 = desc.r1 * firstOffset; + float adjustedR1 = desc.r1 * lastOffset; ASSERT(adjustedR0 <= adjustedR1); // Unlike linear gradients (where we can adjust the points arbitrarily), @@ -364,7 +384,7 @@ if (adjustedR0 < 0) { // For the non-repeat case, this can never happen: clampNegativeOffsets() // ensures we don't have to deal with negative offsets at this point. - ASSERT(gradient->spreadMethod() == SpreadMethodRepeat); + DCHECK_EQ(desc.spreadMethod, SpreadMethodRepeat); // When in repeat mode, we deal with it by repositioning both radii in the // positive domain - shifting them by a multiple of the radius span (which @@ -378,16 +398,16 @@ ASSERT(adjustedR0 >= 0); ASSERT(adjustedR1 >= adjustedR0); - gradient->setStartRadius(adjustedR0); - gradient->setEndRadius(adjustedR1); + desc.r0 = adjustedR0; + desc.r1 = adjustedR1; } -void CSSGradientValue::addStops(Gradient* gradient, +void CSSGradientValue::addStops(CSSGradientValue::GradientDesc& desc, const CSSToLengthConversionData& conversionData, const LayoutObject& object) { if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient) { - addDeprecatedStops(gradient, object); + addDeprecatedStops(desc, object); return; } @@ -397,12 +417,12 @@ bool hasHints = false; - FloatPoint gradientStart = gradient->p0(); + FloatPoint gradientStart = desc.p0; FloatPoint gradientEnd; if (isLinearGradientValue()) - gradientEnd = gradient->p1(); + gradientEnd = desc.p1; else if (isRadialGradientValue()) - gradientEnd = gradientStart + FloatSize(gradient->endRadius(), 0); + gradientEnd = gradientStart + FloatSize(desc.r1, 0); float gradientLength = FloatSize(gradientStart - gradientEnd).diagonalLength(); @@ -501,19 +521,19 @@ // At this point we have a fully resolved set of stops. Time to perform // adjustments for repeat gradients and degenerate values if needed. - if (requiresStopsNormalization(stops, gradient)) { + if (requiresStopsNormalization(stops, desc)) { // Negative offsets are only an issue for non-repeating radial gradients: // linear gradient points can be repositioned arbitrarily, and for repeating // radial gradients we shift the radii into equivalent positive values. if (isRadialGradientValue() && !m_repeating) clampNegativeOffsets(stops); - if (normalizeAndAddStops(stops, gradient)) { + if (normalizeAndAddStops(stops, desc)) { if (isLinearGradientValue()) { - adjustGradientPointsForOffsetRange(gradient, stops.front().offset, + adjustGradientPointsForOffsetRange(desc, stops.front().offset, stops.back().offset); } else { - adjustGradientRadiiForOffsetRange(gradient, stops.front().offset, + adjustGradientRadiiForOffsetRange(desc, stops.front().offset, stops.back().offset); } } else { @@ -522,7 +542,7 @@ } else { // No normalization required, just add the current stops. for (const auto& stop : stops) - gradient->addColorStop(stop.offset, stop.color); + desc.stops.emplace_back(stop.offset, stop.color); } } @@ -878,13 +898,16 @@ } } - RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint); + GradientDesc desc(firstPoint, secondPoint, + m_repeating ? SpreadMethodRepeat : SpreadMethodPad); + addStops(desc, conversionData, object); - gradient->setSpreadMethod(m_repeating ? SpreadMethodRepeat : SpreadMethodPad); - gradient->setDrawsInPMColorSpace(true); + RefPtr<Gradient> gradient = + Gradient::create(desc.p0, desc.p1, desc.spreadMethod, + Gradient::ColorInterpolation::Premultiplied); // Now add the stops. - addStops(gradient.get(), conversionData, object); + gradient->addColorStops(desc.stops); return gradient.release(); } @@ -1244,16 +1267,18 @@ DCHECK(std::isfinite(secondRadius.height())); bool isDegenerate = !secondRadius.width() || !secondRadius.height(); - RefPtr<Gradient> gradient = - Gradient::create(firstPoint, firstRadius, secondPoint, - isDegenerate ? 0 : secondRadius.width(), - isDegenerate ? 1 : secondRadius.aspectRatio()); + GradientDesc desc(firstPoint, secondPoint, firstRadius, + isDegenerate ? 0 : secondRadius.width(), + m_repeating ? SpreadMethodRepeat : SpreadMethodPad); + addStops(desc, conversionData, object); - gradient->setSpreadMethod(m_repeating ? SpreadMethodRepeat : SpreadMethodPad); - gradient->setDrawsInPMColorSpace(true); + RefPtr<Gradient> gradient = Gradient::create( + desc.p0, desc.r0, desc.p1, desc.r1, + isDegenerate ? 1 : secondRadius.aspectRatio(), desc.spreadMethod, + Gradient::ColorInterpolation::Premultiplied); // Now add the stops. - addStops(gradient.get(), conversionData, object); + gradient->addColorStops(desc.stops); return gradient.release(); }
diff --git a/third_party/WebKit/Source/core/css/CSSGradientValue.h b/third_party/WebKit/Source/core/css/CSSGradientValue.h index 0fcead9..19967def 100644 --- a/third_party/WebKit/Source/core/css/CSSGradientValue.h +++ b/third_party/WebKit/Source/core/css/CSSGradientValue.h
@@ -114,6 +114,8 @@ DECLARE_TRACE_AFTER_DISPATCH(); + struct GradientDesc; + protected: CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, @@ -123,10 +125,10 @@ m_gradientType(gradientType), m_repeating(repeat == Repeating) {} - void addStops(Gradient*, + void addStops(GradientDesc&, const CSSToLengthConversionData&, const LayoutObject&); - void addDeprecatedStops(Gradient*, const LayoutObject&); + void addDeprecatedStops(GradientDesc&, const LayoutObject&); // Resolve points/radii to front end values. FloatPoint computeEndPoint(CSSValue*,
diff --git a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp index b6574da..f8618151 100644 --- a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp +++ b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp
@@ -368,10 +368,10 @@ } TEST_F(EventHandlerTest, ClearHandleAfterTap) { - setHtmlInnerHTML("<textarea cols=50 rows=50>Enter text</textarea>"); + setHtmlInnerHTML("<textarea cols=50 rows=10>Enter text</textarea>"); // Show handle - LongPressEventBuilder longPressEvent(IntPoint(200, 200)); + LongPressEventBuilder longPressEvent(IntPoint(200, 10)); document().frame()->eventHandler().handleGestureEvent(longPressEvent); ASSERT_TRUE( @@ -379,11 +379,9 @@ ASSERT_TRUE(selection().isHandleVisible()); // Tap away from text area should clear handle - TapEventBuilder singleTapEvent(IntPoint(700, 700), 1); + TapEventBuilder singleTapEvent(IntPoint(200, 350), 1); document().frame()->eventHandler().handleGestureEvent(singleTapEvent); - ASSERT_TRUE( - selection().computeVisibleSelectionInDOMTreeDeprecated().isNone()); ASSERT_FALSE(selection().isHandleVisible()); }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceLinearGradient.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceLinearGradient.cpp index d79ca19..3c525aa 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceLinearGradient.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceLinearGradient.cpp
@@ -52,10 +52,10 @@ PassRefPtr<Gradient> LayoutSVGResourceLinearGradient::buildGradient() const { const LinearGradientAttributes& attributes = this->attributes(); - RefPtr<Gradient> gradient = - Gradient::create(startPoint(attributes), endPoint(attributes)); - gradient->setSpreadMethod( - platformSpreadMethodFromSVGType(attributes.spreadMethod())); + RefPtr<Gradient> gradient = Gradient::create( + startPoint(attributes), endPoint(attributes), + platformSpreadMethodFromSVGType(attributes.spreadMethod()), + Gradient::ColorInterpolation::Unpremultiplied); gradient->addColorStops(attributes.stops()); return gradient.release(); }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceRadialGradient.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceRadialGradient.cpp index b6408d7..c673fe5 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceRadialGradient.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceRadialGradient.cpp
@@ -65,11 +65,11 @@ PassRefPtr<Gradient> LayoutSVGResourceRadialGradient::buildGradient() const { const RadialGradientAttributes& attributes = this->attributes(); - RefPtr<Gradient> gradient = - Gradient::create(focalPoint(attributes), focalRadius(attributes), - centerPoint(attributes), radius(attributes)); - gradient->setSpreadMethod( - platformSpreadMethodFromSVGType(attributes.spreadMethod())); + RefPtr<Gradient> gradient = Gradient::create( + focalPoint(attributes), focalRadius(attributes), centerPoint(attributes), + radius(attributes), 1, + platformSpreadMethodFromSVGType(attributes.spreadMethod()), + Gradient::ColorInterpolation::Unpremultiplied); gradient->addColorStops(attributes.stops()); return gradient.release(); }
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index ea25b99..665b1d7 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -134,6 +134,8 @@ "front_end/console/ConsoleViewMessage.js", "front_end/console/ConsoleViewport.js", "front_end/console/module.json", + "front_end/console_model/ConsoleModel.js", + "front_end/console_model/module.json", "front_end/cookie_table/CookiesTable.js", "front_end/cookie_table/module.json", "front_end/coverage/coverageListView.css", @@ -436,7 +438,6 @@ "front_end/screencast/screencastView.css", "front_end/screencast/ScreencastView.js", "front_end/sdk/Connections.js", - "front_end/sdk/ConsoleModel.js", "front_end/sdk/ContentProviders.js", "front_end/sdk/CookieModel.js", "front_end/sdk/CookieParser.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/Tests.js b/third_party/WebKit/Source/devtools/front_end/Tests.js index e1c8f01..7d10d989 100644 --- a/third_party/WebKit/Source/devtools/front_end/Tests.js +++ b/third_party/WebKit/Source/devtools/front_end/Tests.js
@@ -514,19 +514,23 @@ TestSuite.prototype.testConsoleOnNavigateBack = function() { function filteredMessages() { - return SDK.consoleModel.messages().filter(a => a.source !== SDK.ConsoleMessage.MessageSource.Violation); + return ConsoleModel.consoleModel.messages().filter( + a => a.source !== ConsoleModel.ConsoleMessage.MessageSource.Violation); } - if (filteredMessages().length === 1) + if (filteredMessages().length === 1) { firstConsoleMessageReceived.call(this, null); - else - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this); + } else { + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this); + } function firstConsoleMessageReceived(event) { - if (event && event.data.source === SDK.ConsoleMessage.MessageSource.Violation) + if (event && event.data.source === ConsoleModel.ConsoleMessage.MessageSource.Violation) return; - SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this); + ConsoleModel.consoleModel.removeEventListener( + ConsoleModel.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this); this.evaluateInConsole_('clickLink();', didClickLink.bind(this)); } @@ -682,12 +686,13 @@ messages.splice(index, 1); if (!messages.length) { - SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); + ConsoleModel.consoleModel.removeEventListener( + ConsoleModel.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); next(); } } - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); SDK.multitargetNetworkManager.setNetworkConditions(preset); } @@ -832,7 +837,7 @@ }; TestSuite.prototype.testWindowInitializedOnNavigateBack = function() { - var messages = SDK.consoleModel.messages(); + var messages = ConsoleModel.consoleModel.messages(); this.assertEquals(1, messages.length); var text = messages[0].messageText; if (text.indexOf('Uncaught') !== -1) @@ -867,7 +872,7 @@ }; TestSuite.prototype.waitForTestResultsInConsole = function() { - var messages = SDK.consoleModel.messages(); + var messages = ConsoleModel.consoleModel.messages(); for (var i = 0; i < messages.length; ++i) { var text = messages[i].messageText; if (text === 'PASS') @@ -884,7 +889,7 @@ this.fail(text); } - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, onConsoleMessage, this); this.takeControl(); }; @@ -928,12 +933,12 @@ Array.prototype.slice.call(arguments, 1, -1).map(arg => JSON.stringify(arg)).join(',') + ','; this.evaluateInConsole_( `${functionName}(${argsString} function() { console.log('${doneMessage}'); });`, function() {}); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, onConsoleMessage); function onConsoleMessage(event) { var text = event.data.messageText; if (text === doneMessage) { - SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage); + ConsoleModel.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, onConsoleMessage); callback(); } }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/PresentationConsoleMessageHelper.js b/third_party/WebKit/Source/devtools/front_end/bindings/PresentationConsoleMessageHelper.js index cb1e587..bc208e5 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/PresentationConsoleMessageHelper.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/PresentationConsoleMessageHelper.js
@@ -38,15 +38,17 @@ constructor(workspace) { this._workspace = workspace; - /** @type {!Object.<string, !Array.<!SDK.ConsoleMessage>>} */ + /** @type {!Object.<string, !Array.<!ConsoleModel.ConsoleMessage>>} */ this._pendingConsoleMessages = {}; /** @type {!Array.<!Bindings.PresentationConsoleMessage>} */ this._presentationConsoleMessages = []; - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this); - SDK.consoleModel.messages().forEach(this._consoleMessageAdded, this); + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this); + ConsoleModel.consoleModel.messages().forEach(this._consoleMessageAdded, this); // TODO(dgozman): setImmediate because we race with DebuggerWorkspaceBinding on ParsedScriptSource event delivery. SDK.targetManager.addModelListener( SDK.DebuggerModel, SDK.DebuggerModel.Events.ParsedScriptSource, @@ -64,12 +66,12 @@ * @param {!Common.Event} event */ _onConsoleMessageAdded(event) { - var message = /** @type {!SDK.ConsoleMessage} */ (event.data); + var message = /** @type {!ConsoleModel.ConsoleMessage} */ (event.data); this._consoleMessageAdded(message); } /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message */ _consoleMessageAdded(message) { if (!message.isErrorOrWarning()) @@ -83,7 +85,7 @@ } /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message * @return {?SDK.DebuggerModel.Location} */ _rawLocation(message) { @@ -103,18 +105,18 @@ } /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message * @param {!SDK.DebuggerModel.Location} rawLocation */ _addConsoleMessageToScript(message, rawLocation) { - if (message.source === SDK.ConsoleMessage.MessageSource.Violation) + if (message.source === ConsoleModel.ConsoleMessage.MessageSource.Violation) return; this._presentationConsoleMessages.push( new Bindings.PresentationConsoleMessage(message, rawLocation, this._locationPool)); } /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message */ _addPendingConsoleMessage(message) { if (!message.url) @@ -170,13 +172,13 @@ */ Bindings.PresentationConsoleMessage = class { /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message * @param {!SDK.DebuggerModel.Location} rawLocation * @param {!Bindings.LiveLocationPool} locationPool */ constructor(message, rawLocation, locationPool) { this._text = message.messageText; - this._level = message.level === SDK.ConsoleMessage.MessageLevel.Error ? + this._level = message.level === ConsoleModel.ConsoleMessage.MessageLevel.Error ? Workspace.UISourceCode.Message.Level.Error : Workspace.UISourceCode.Message.Level.Warning; Bindings.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateLocation.bind(this), locationPool);
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/module.json b/third_party/WebKit/Source/devtools/front_end/bindings/module.json index 9cba604..577bb33d 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/module.json +++ b/third_party/WebKit/Source/devtools/front_end/bindings/module.json
@@ -3,7 +3,8 @@ "sdk", "platform", "services", - "workspace" + "workspace", + "console_model" ], "scripts": [ "LiveLocation.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js b/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js index 0704bbc..f0c2ff7 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js
@@ -191,7 +191,7 @@ this.setText(''); var currentExecutionContext = UI.context.flavor(SDK.ExecutionContext); if (currentExecutionContext) { - SDK.consoleModel.evaluateCommandInConsole(currentExecutionContext, text, useCommandLineAPI); + ConsoleModel.consoleModel.evaluateCommandInConsole(currentExecutionContext, text, useCommandLineAPI); if (Console.ConsolePanel.instance().isShowing()) Host.userMetrics.actionTaken(Host.UserMetrics.Action.CommandEvaluatedInConsolePanel); }
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js index 12af176..921bec5 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -182,7 +182,7 @@ } static clearConsole() { - SDK.consoleModel.requestClearMessages(); + ConsoleModel.consoleModel.requestClearMessages(); } /** @@ -225,11 +225,15 @@ } _fetchMultitargetMessages() { - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageUpdated, this._onConsoleMessageUpdated, this); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this); - SDK.consoleModel.messages().forEach(this._addConsoleMessage, this); + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this); + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this); + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.MessageUpdated, this._onConsoleMessageUpdated, this); + ConsoleModel.consoleModel.addEventListener( + ConsoleModel.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this); + ConsoleModel.consoleModel.messages().forEach(this._addConsoleMessage, this); this._viewport.invalidate(); } @@ -301,22 +305,22 @@ * @param {!Common.Console.Message} message */ _addSinkMessage(message) { - var level = SDK.ConsoleMessage.MessageLevel.Verbose; + var level = ConsoleModel.ConsoleMessage.MessageLevel.Verbose; switch (message.level) { case Common.Console.MessageLevel.Info: - level = SDK.ConsoleMessage.MessageLevel.Info; + level = ConsoleModel.ConsoleMessage.MessageLevel.Info; break; case Common.Console.MessageLevel.Error: - level = SDK.ConsoleMessage.MessageLevel.Error; + level = ConsoleModel.ConsoleMessage.MessageLevel.Error; break; case Common.Console.MessageLevel.Warning: - level = SDK.ConsoleMessage.MessageLevel.Warning; + level = ConsoleModel.ConsoleMessage.MessageLevel.Warning; break; } - var consoleMessage = new SDK.ConsoleMessage( - null, SDK.ConsoleMessage.MessageSource.Other, level, message.text, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, message.timestamp); + var consoleMessage = new ConsoleModel.ConsoleMessage( + null, ConsoleModel.ConsoleMessage.MessageSource.Other, level, message.text, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, message.timestamp); this._addConsoleMessage(consoleMessage); } @@ -435,12 +439,12 @@ * @param {!Common.Event} event */ _onConsoleMessageAdded(event) { - var message = /** @type {!SDK.ConsoleMessage} */ (event.data); + var message = /** @type {!ConsoleModel.ConsoleMessage} */ (event.data); this._addConsoleMessage(message); } /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message */ _addConsoleMessage(message) { /** @@ -449,11 +453,12 @@ * @return {number} */ function compareTimestamps(viewMessage1, viewMessage2) { - return SDK.ConsoleMessage.timestampComparator(viewMessage1.consoleMessage(), viewMessage2.consoleMessage()); + return ConsoleModel.ConsoleMessage.timestampComparator( + viewMessage1.consoleMessage(), viewMessage2.consoleMessage()); } - if (message.type === SDK.ConsoleMessage.MessageType.Command || - message.type === SDK.ConsoleMessage.MessageType.Result) { + if (message.type === ConsoleModel.ConsoleMessage.MessageType.Command || + message.type === ConsoleModel.ConsoleMessage.MessageType.Result) { message.timestamp = this._consoleMessages.length ? this._consoleMessages.peekLast().consoleMessage().timestamp : 0; } @@ -484,7 +489,7 @@ * @param {!Common.Event} event */ _onConsoleMessageUpdated(event) { - var message = /** @type {!SDK.ConsoleMessage} */ (event.data); + var message = /** @type {!ConsoleModel.ConsoleMessage} */ (event.data); var viewMessage = message[this._viewMessageSymbol]; if (viewMessage) { viewMessage.updateMessageElement(); @@ -511,7 +516,7 @@ return; var lastMessage = this._visibleViewMessages.peekLast(); - if (viewMessage.consoleMessage().type === SDK.ConsoleMessage.MessageType.EndGroup) { + if (viewMessage.consoleMessage().type === ConsoleModel.ConsoleMessage.MessageType.EndGroup) { if (lastMessage && !this._currentGroup.messagesHidden()) lastMessage.incrementCloseGroupDecorationCount(); this._currentGroup = this._currentGroup.parentGroup(); @@ -537,18 +542,18 @@ } /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message * @return {!Console.ConsoleViewMessage} */ _createViewMessage(message) { var nestingLevel = this._currentGroup.nestingLevel(); switch (message.type) { - case SDK.ConsoleMessage.MessageType.Command: + case ConsoleModel.ConsoleMessage.MessageType.Command: return new Console.ConsoleCommand(message, this._linkifier, nestingLevel); - case SDK.ConsoleMessage.MessageType.Result: + case ConsoleModel.ConsoleMessage.MessageType.Result: return new Console.ConsoleCommandResult(message, this._linkifier, nestingLevel); - case SDK.ConsoleMessage.MessageType.StartGroupCollapsed: - case SDK.ConsoleMessage.MessageType.StartGroup: + case ConsoleModel.ConsoleMessage.MessageType.StartGroupCollapsed: + case ConsoleModel.ConsoleMessage.MessageType.StartGroup: return new Console.ConsoleGroupViewMessage(message, this._linkifier, nestingLevel); default: return new Console.ConsoleViewMessage(message, this._linkifier, nestingLevel); @@ -784,25 +789,26 @@ /** * @param {?SDK.RemoteObject} result - * @param {!SDK.ConsoleMessage} originatingConsoleMessage + * @param {!ConsoleModel.ConsoleMessage} originatingConsoleMessage * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails */ _printResult(result, originatingConsoleMessage, exceptionDetails) { if (!result) return; - var level = !!exceptionDetails ? SDK.ConsoleMessage.MessageLevel.Error : SDK.ConsoleMessage.MessageLevel.Info; + var level = !!exceptionDetails ? ConsoleModel.ConsoleMessage.MessageLevel.Error : + ConsoleModel.ConsoleMessage.MessageLevel.Info; var message; if (!exceptionDetails) { - message = new SDK.ConsoleMessage( - result.target(), SDK.ConsoleMessage.MessageSource.JS, level, '', SDK.ConsoleMessage.MessageType.Result, - undefined, undefined, undefined, undefined, [result]); + message = new ConsoleModel.ConsoleMessage( + result.target(), ConsoleModel.ConsoleMessage.MessageSource.JS, level, '', + ConsoleModel.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, undefined, [result]); } else { - message = SDK.ConsoleMessage.fromException( - result.target(), exceptionDetails, SDK.ConsoleMessage.MessageType.Result, undefined, undefined); + message = ConsoleModel.ConsoleMessage.fromException( + result.target(), exceptionDetails, ConsoleModel.ConsoleMessage.MessageType.Result, undefined, undefined); } message.setOriginatingMessage(originatingConsoleMessage); - SDK.consoleModel.addMessage(message); + ConsoleModel.consoleModel.addMessage(message); } /** @@ -810,7 +816,7 @@ */ _commandEvaluated(event) { var data = - /** @type {{result: ?SDK.RemoteObject, text: string, commandMessage: !SDK.ConsoleMessage, exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined)}} */ + /** @type {{result: ?SDK.RemoteObject, text: string, commandMessage: !ConsoleModel.ConsoleMessage, exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined)}} */ (event.data); this._prompt.history().pushHistoryItem(data.text); this._consoleHistorySetting.set( @@ -1045,7 +1051,7 @@ this._messageURLFiltersSetting = Common.settings.createSetting('messageURLFilters', {}); this._messageLevelFiltersSetting = - Common.settings.createSetting('messageLevelFilters2', SDK.ConsoleMessage.MessageLevel.Info); + Common.settings.createSetting('messageLevelFilters2', ConsoleModel.ConsoleMessage.MessageLevel.Info); this._hideNetworkMessagesSetting = Common.moduleSetting('hideNetworkMessages'); this._messageURLFiltersSetting.addChangeListener(this._filterChanged); @@ -1056,10 +1062,10 @@ this._textFilterUI.addEventListener(UI.ToolbarInput.Event.TextChanged, this._textFilterChanged, this); var levels = [ - {value: SDK.ConsoleMessage.MessageLevel.Verbose, label: Common.UIString('Verbose')}, - {value: SDK.ConsoleMessage.MessageLevel.Info, label: Common.UIString('Info'), default: true}, - {value: SDK.ConsoleMessage.MessageLevel.Warning, label: Common.UIString('Warnings')}, - {value: SDK.ConsoleMessage.MessageLevel.Error, label: Common.UIString('Errors')} + {value: ConsoleModel.ConsoleMessage.MessageLevel.Verbose, label: Common.UIString('Verbose')}, + {value: ConsoleModel.ConsoleMessage.MessageLevel.Info, label: Common.UIString('Info'), default: true}, + {value: ConsoleModel.ConsoleMessage.MessageLevel.Warning, label: Common.UIString('Warnings')}, + {value: ConsoleModel.ConsoleMessage.MessageLevel.Error, label: Common.UIString('Errors')} ]; this._levelComboBox = @@ -1124,22 +1130,22 @@ } if (this._hideNetworkMessagesSetting.get() && - viewMessage.consoleMessage().source === SDK.ConsoleMessage.MessageSource.Network) + viewMessage.consoleMessage().source === ConsoleModel.ConsoleMessage.MessageSource.Network) return false; if (viewMessage.consoleMessage().isGroupMessage()) return true; - if (message.type === SDK.ConsoleMessage.MessageType.Result || - message.type === SDK.ConsoleMessage.MessageType.Command) + if (message.type === ConsoleModel.ConsoleMessage.MessageType.Result || + message.type === ConsoleModel.ConsoleMessage.MessageType.Command) return true; if (message.url && this._messageURLFiltersSetting.get()[message.url]) return false; - var filterOrdinal = SDK.ConsoleMessage.MessageLevel.ordinal( - /** @type {!SDK.ConsoleMessage.MessageLevel} */ (this._messageLevelFiltersSetting.get())); - if (message.level && SDK.ConsoleMessage.MessageLevel.ordinal(message.level) < filterOrdinal) + var filterOrdinal = ConsoleModel.ConsoleMessage.MessageLevel.ordinal( + /** @type {!ConsoleModel.ConsoleMessage.MessageLevel} */ (this._messageLevelFiltersSetting.get())); + if (message.level && ConsoleModel.ConsoleMessage.MessageLevel.ordinal(message.level) < filterOrdinal) return false; if (this._filterRegex) { @@ -1155,7 +1161,7 @@ reset() { this._messageURLFiltersSetting.set({}); - this._messageLevelFiltersSetting.set(SDK.ConsoleMessage.MessageLevel.Info); + this._messageLevelFiltersSetting.set(ConsoleModel.ConsoleMessage.MessageLevel.Info); this._showTargetMessagesCheckbox.inputElement.checked = false; this._hideNetworkMessagesSetting.set(false); this._textFilterUI.setValue(''); @@ -1168,7 +1174,7 @@ */ Console.ConsoleCommand = class extends Console.ConsoleViewMessage { /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message * @param {!Components.Linkifier} linkifier * @param {number} nestingLevel */ @@ -1221,7 +1227,7 @@ */ Console.ConsoleCommandResult = class extends Console.ConsoleViewMessage { /** - * @param {!SDK.ConsoleMessage} message + * @param {!ConsoleModel.ConsoleMessage} message * @param {!Components.Linkifier} linkifier * @param {number} nestingLevel */ @@ -1237,7 +1243,7 @@ var element = super.contentElement(); if (!element.classList.contains('console-user-command-result')) { element.classList.add('console-user-command-result'); - if (this.consoleMessage().level === SDK.ConsoleMessage.MessageLevel.Info) { + if (this.consoleMessage().level === ConsoleModel.ConsoleMessage.MessageLevel.Info) { var icon = UI.Icon.create('smallicon-command-result', 'command-result-icon'); element.insertBefore(icon, element.firstChild); }
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js index 6d3a809..4f470bf 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -33,7 +33,7 @@ */ Console.ConsoleViewMessage = class { /** - * @param {!SDK.ConsoleMessage} consoleMessage + * @param {!ConsoleModel.ConsoleMessage} consoleMessage * @param {!Components.Linkifier} linkifier * @param {number} nestingLevel */ @@ -100,7 +100,7 @@ // This value reflects the 18px min-height of .console-message, plus the // 1px border of .console-message-wrapper. Keep in sync with consoleView.css. const defaultConsoleRowHeight = 19; - if (this._message.type === SDK.ConsoleMessage.MessageType.Table) { + if (this._message.type === ConsoleModel.ConsoleMessage.MessageType.Table) { var table = this._message.parameters[0]; if (table && table.preview) return defaultConsoleRowHeight * table.preview.properties.length; @@ -109,14 +109,14 @@ } /** - * @return {!SDK.ConsoleMessage} + * @return {!ConsoleModel.ConsoleMessage} */ consoleMessage() { return this._message; } /** - * @param {!SDK.ConsoleMessage} consoleMessage + * @param {!ConsoleModel.ConsoleMessage} consoleMessage * @return {!Element} */ _buildTableMessage(consoleMessage) { @@ -188,34 +188,34 @@ } /** - * @param {!SDK.ConsoleMessage} consoleMessage + * @param {!ConsoleModel.ConsoleMessage} consoleMessage * @return {!Element} */ _buildMessage(consoleMessage) { var messageElement; var messageText = consoleMessage.messageText; - if (consoleMessage.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI) { + if (consoleMessage.source === ConsoleModel.ConsoleMessage.MessageSource.ConsoleAPI) { switch (consoleMessage.type) { - case SDK.ConsoleMessage.MessageType.Trace: + case ConsoleModel.ConsoleMessage.MessageType.Trace: messageElement = this._format(consoleMessage.parameters || ['console.trace']); break; - case SDK.ConsoleMessage.MessageType.Clear: + case ConsoleModel.ConsoleMessage.MessageType.Clear: messageElement = createElementWithClass('span', 'console-info'); messageElement.textContent = Common.UIString('Console was cleared'); break; - case SDK.ConsoleMessage.MessageType.Assert: + case ConsoleModel.ConsoleMessage.MessageType.Assert: var args = [Common.UIString('Assertion failed:')]; if (consoleMessage.parameters) args = args.concat(consoleMessage.parameters); messageElement = this._format(args); break; - case SDK.ConsoleMessage.MessageType.Dir: + case ConsoleModel.ConsoleMessage.MessageType.Dir: var obj = consoleMessage.parameters ? consoleMessage.parameters[0] : undefined; var args = ['%O', obj]; messageElement = this._format(args); break; - case SDK.ConsoleMessage.MessageType.Profile: - case SDK.ConsoleMessage.MessageType.ProfileEnd: + case ConsoleModel.ConsoleMessage.MessageType.Profile: + case ConsoleModel.ConsoleMessage.MessageType.ProfileEnd: messageElement = this._format([messageText]); break; default: @@ -225,10 +225,10 @@ var args = consoleMessage.parameters || [messageText]; messageElement = messageElement || this._format(args); } - } else if (consoleMessage.source === SDK.ConsoleMessage.MessageSource.Network) { + } else if (consoleMessage.source === ConsoleModel.ConsoleMessage.MessageSource.Network) { if (consoleMessage.request) { messageElement = createElement('span'); - if (consoleMessage.level === SDK.ConsoleMessage.MessageLevel.Error) { + if (consoleMessage.level === ConsoleModel.ConsoleMessage.MessageLevel.Error) { messageElement.createTextChild(consoleMessage.request.requestMethod + ' '); messageElement.appendChild(Components.Linkifier.linkifyRevealable( consoleMessage.request, consoleMessage.request.url(), consoleMessage.request.url())); @@ -247,11 +247,11 @@ messageElement = this._format([messageText]); } } else { - if (consoleMessage.source === SDK.ConsoleMessage.MessageSource.Violation) + if (consoleMessage.source === ConsoleModel.ConsoleMessage.MessageSource.Violation) messageText = Common.UIString('[Violation] %s', messageText); - else if (consoleMessage.source === SDK.ConsoleMessage.MessageSource.Intervention) + else if (consoleMessage.source === ConsoleModel.ConsoleMessage.MessageSource.Intervention) messageText = Common.UIString('[Intervention] %s', messageText); - if (consoleMessage.source === SDK.ConsoleMessage.MessageSource.Deprecation) + if (consoleMessage.source === ConsoleModel.ConsoleMessage.MessageSource.Deprecation) messageText = Common.UIString('[Deprecation] %s', messageText); var args = consoleMessage.parameters || [messageText]; messageElement = this._format(args); @@ -271,7 +271,7 @@ /** * @param {string} title * @return {!Element} - * @this {SDK.ConsoleMessage} + * @this {ConsoleModel.ConsoleMessage} */ function linkifyRequest(title) { return Components.Linkifier.linkifyRevealable( @@ -280,12 +280,12 @@ } /** - * @param {!SDK.ConsoleMessage} consoleMessage + * @param {!ConsoleModel.ConsoleMessage} consoleMessage * @return {?Element} */ _buildMessageAnchor(consoleMessage) { var anchorElement = null; - if (consoleMessage.source !== SDK.ConsoleMessage.MessageSource.Network || consoleMessage.request) { + if (consoleMessage.source !== ConsoleModel.ConsoleMessage.MessageSource.Network || consoleMessage.request) { if (consoleMessage.scriptId) { anchorElement = this._linkifyScriptId( consoleMessage.scriptId, consoleMessage.url || '', consoleMessage.line, consoleMessage.column); @@ -309,7 +309,7 @@ } /** - * @param {!SDK.ConsoleMessage} consoleMessage + * @param {!ConsoleModel.ConsoleMessage} consoleMessage * @param {!SDK.Target} target * @param {!Components.Linkifier} linkifier * @return {!Element} @@ -349,7 +349,7 @@ } clickableElement.addEventListener('click', toggleStackTrace, false); - if (consoleMessage.type === SDK.ConsoleMessage.MessageType.Trace) + if (consoleMessage.type === ConsoleModel.ConsoleMessage.MessageType.Trace) expandStackTrace(true); toggleElement._expandStackTraceForTest = expandStackTrace.bind(null, true); @@ -428,8 +428,8 @@ // There can be string log and string eval result. We distinguish between them based on message type. var shouldFormatMessage = SDK.RemoteObject.type((/** @type {!Array.<!SDK.RemoteObject>} **/ (parameters))[0]) === 'string' && - (this._message.type !== SDK.ConsoleMessage.MessageType.Result || - this._message.level === SDK.ConsoleMessage.MessageLevel.Error); + (this._message.type !== ConsoleModel.ConsoleMessage.MessageType.Result || + this._message.level === ConsoleModel.ConsoleMessage.MessageLevel.Error); // Multiple parameters with the first being a format string. Save unused substitutions. if (shouldFormatMessage) { @@ -909,21 +909,21 @@ if (this._messageLevelIcon) contentElement.appendChild(this._messageLevelIcon); this._contentElement = contentElement; - if (this._message.type === SDK.ConsoleMessage.MessageType.StartGroup || - this._message.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed) + if (this._message.type === ConsoleModel.ConsoleMessage.MessageType.StartGroup || + this._message.type === ConsoleModel.ConsoleMessage.MessageType.StartGroupCollapsed) contentElement.classList.add('console-group-title'); var formattedMessage; var consoleMessage = this._message; var target = consoleMessage.target(); - var shouldIncludeTrace = - !!consoleMessage.stackTrace && (consoleMessage.source === SDK.ConsoleMessage.MessageSource.Network || - consoleMessage.level === SDK.ConsoleMessage.MessageLevel.Error || - consoleMessage.type === SDK.ConsoleMessage.MessageType.Trace || - consoleMessage.level === SDK.ConsoleMessage.MessageLevel.Warning); + var shouldIncludeTrace = !!consoleMessage.stackTrace && + (consoleMessage.source === ConsoleModel.ConsoleMessage.MessageSource.Network || + consoleMessage.level === ConsoleModel.ConsoleMessage.MessageLevel.Error || + consoleMessage.type === ConsoleModel.ConsoleMessage.MessageType.Trace || + consoleMessage.level === ConsoleModel.ConsoleMessage.MessageLevel.Warning); if (target && shouldIncludeTrace) formattedMessage = this._buildMessageWithStackTrace(consoleMessage, target, this._linkifier); - else if (this._message.type === SDK.ConsoleMessage.MessageType.Table) + else if (this._message.type === ConsoleModel.ConsoleMessage.MessageType.Table) formattedMessage = this._buildTableMessage(this._message); else formattedMessage = this._buildMessage(consoleMessage); @@ -959,30 +959,30 @@ this._element.message = this; switch (this._message.level) { - case SDK.ConsoleMessage.MessageLevel.Verbose: + case ConsoleModel.ConsoleMessage.MessageLevel.Verbose: this._element.classList.add('console-verbose-level'); this._updateMessageLevelIcon(''); break; - case SDK.ConsoleMessage.MessageLevel.Info: + case ConsoleModel.ConsoleMessage.MessageLevel.Info: this._element.classList.add('console-info-level'); break; - case SDK.ConsoleMessage.MessageLevel.Warning: + case ConsoleModel.ConsoleMessage.MessageLevel.Warning: this._element.classList.add('console-warning-level'); this._updateMessageLevelIcon('smallicon-warning'); break; - case SDK.ConsoleMessage.MessageLevel.Error: + case ConsoleModel.ConsoleMessage.MessageLevel.Error: this._element.classList.add('console-error-level'); this._updateMessageLevelIcon('smallicon-error'); break; } // Render verbose and info deprecations, interventions and violations with warning background. - if (this._message.level === SDK.ConsoleMessage.MessageLevel.Verbose || - this._message.level === SDK.ConsoleMessage.MessageLevel.Info) { + if (this._message.level === ConsoleModel.ConsoleMessage.MessageLevel.Verbose || + this._message.level === ConsoleModel.ConsoleMessage.MessageLevel.Info) { switch (this._message.source) { - case SDK.ConsoleMessage.MessageSource.Violation: - case SDK.ConsoleMessage.MessageSource.Deprecation: - case SDK.ConsoleMessage.MessageSource.Intervention: + case ConsoleModel.ConsoleMessage.MessageSource.Violation: + case ConsoleModel.ConsoleMessage.MessageSource.Deprecation: + case ConsoleModel.ConsoleMessage.MessageSource.Intervention: this._element.classList.add('console-warning-level'); break; } @@ -1037,13 +1037,13 @@ if (!this._repeatCountElement) { this._repeatCountElement = createElementWithClass('label', 'console-message-repeat-count', 'dt-small-bubble'); switch (this._message.level) { - case SDK.ConsoleMessage.MessageLevel.Warning: + case ConsoleModel.ConsoleMessage.MessageLevel.Warning: this._repeatCountElement.type = 'warning'; break; - case SDK.ConsoleMessage.MessageLevel.Error: + case ConsoleModel.ConsoleMessage.MessageLevel.Error: this._repeatCountElement.type = 'error'; break; - case SDK.ConsoleMessage.MessageLevel.Verbose: + case ConsoleModel.ConsoleMessage.MessageLevel.Verbose: this._repeatCountElement.type = 'verbose'; break; default: @@ -1212,14 +1212,14 @@ */ Console.ConsoleGroupViewMessage = class extends Console.ConsoleViewMessage { /** - * @param {!SDK.ConsoleMessage} consoleMessage + * @param {!ConsoleModel.ConsoleMessage} consoleMessage * @param {!Components.Linkifier} linkifier * @param {number} nestingLevel */ constructor(consoleMessage, linkifier, nestingLevel) { console.assert(consoleMessage.isGroupStartMessage()); super(consoleMessage, linkifier, nestingLevel); - this._collapsed = consoleMessage.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed; + this._collapsed = consoleMessage.type === ConsoleModel.ConsoleMessage.MessageType.StartGroupCollapsed; /** @type {?UI.Icon} */ this._expandGroupIcon = null; }
diff --git a/third_party/WebKit/Source/devtools/front_end/console/module.json b/third_party/WebKit/Source/devtools/front_end/console/module.json index 0cf6c076..c94885e 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/module.json +++ b/third_party/WebKit/Source/devtools/front_end/console/module.json
@@ -125,7 +125,8 @@ "dependencies": [ "components", "data_grid", - "object_ui" + "object_ui", + "console_model" ], "scripts": [ "ConsoleContextSelector.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js similarity index 76% rename from third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js rename to third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js index f9e5681..fe95a26 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js +++ b/third_party/WebKit/Source/devtools/front_end/console_model/ConsoleModel.js
@@ -31,13 +31,13 @@ /** * @implements {SDK.TargetManager.Observer} */ -SDK.ConsoleModel = class extends Common.Object { +ConsoleModel.ConsoleModel = class extends Common.Object { constructor() { super(); - /** @type {!Array.<!SDK.ConsoleMessage>} */ + /** @type {!Array.<!ConsoleModel.ConsoleMessage>} */ this._messages = []; - /** @type {!Map<!SDK.Target, !Map<number, !SDK.ConsoleMessage>>} */ + /** @type {!Map<!SDK.Target, !Map<number, !ConsoleModel.ConsoleMessage>>} */ this._messageByExceptionId = new Map(); this._warnings = 0; this._errors = 0; @@ -89,7 +89,7 @@ SDK.NetworkManager.Events.WarningGenerated, this._networkWarningGenerated.bind(this, networkManager))); } - target[SDK.ConsoleModel._events] = eventListeners; + target[ConsoleModel.ConsoleModel._events] = eventListeners; } /** @@ -98,7 +98,7 @@ */ targetRemoved(target) { this._messageByExceptionId.delete(target); - Common.EventTarget.removeEventListeners(target[SDK.ConsoleModel._events]); + Common.EventTarget.removeEventListeners(target[ConsoleModel.ConsoleModel._events]); } /** @@ -110,15 +110,16 @@ var target = executionContext.target(); var requestedText = text; - var commandMessage = new SDK.ConsoleMessage( - target, SDK.ConsoleMessage.MessageSource.JS, null, text, SDK.ConsoleMessage.MessageType.Command); + var commandMessage = new ConsoleModel.ConsoleMessage( + target, ConsoleModel.ConsoleMessage.MessageSource.JS, null, text, + ConsoleModel.ConsoleMessage.MessageType.Command); commandMessage.setExecutionContextId(executionContext.id); this.addMessage(commandMessage); /** * @param {?SDK.RemoteObject} result * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails - * @this {SDK.ConsoleModel} + * @this {ConsoleModel.ConsoleModel} */ function printResult(result, exceptionDetails) { if (!result) @@ -126,7 +127,7 @@ Common.console.showPromise().then(() => { this.dispatchEventToListeners( - SDK.ConsoleModel.Events.CommandEvaluated, + ConsoleModel.ConsoleModel.Events.CommandEvaluated, {result: result, text: requestedText, commandMessage: commandMessage, exceptionDetails: exceptionDetails}); }); } @@ -162,13 +163,14 @@ } /** - * @param {!SDK.ConsoleMessage} msg + * @param {!ConsoleModel.ConsoleMessage} msg */ addMessage(msg) { - if (msg.source === SDK.ConsoleMessage.MessageSource.Worker && SDK.targetManager.targetById(msg.workerId)) + if (msg.source === ConsoleModel.ConsoleMessage.MessageSource.Worker && SDK.targetManager.targetById(msg.workerId)) return; - if (msg.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI && msg.type === SDK.ConsoleMessage.MessageType.Clear) + if (msg.source === ConsoleModel.ConsoleMessage.MessageSource.ConsoleAPI && + msg.type === ConsoleModel.ConsoleMessage.MessageType.Clear) this._clear(); this._messages.push(msg); @@ -184,14 +186,14 @@ targetMap.set(msg._exceptionId, msg); } this._incrementErrorWarningCount(msg); - this.dispatchEventToListeners(SDK.ConsoleModel.Events.MessageAdded, msg); + this.dispatchEventToListeners(ConsoleModel.ConsoleModel.Events.MessageAdded, msg); } /** * @param {!SDK.LogModel.EntryAddedEvent} event */ _logEntryAdded(event) { - var consoleMessage = new SDK.ConsoleMessage( + var consoleMessage = new ConsoleModel.ConsoleMessage( event.logModel.target(), event.entry.source, event.entry.level, event.entry.text, undefined, event.entry.url, event.entry.lineNumber, undefined, event.entry.networkRequestId, undefined, event.entry.stackTrace, event.entry.timestamp, undefined, undefined, event.entry.workerId); @@ -204,7 +206,7 @@ */ _exceptionThrown(runtimeModel, event) { var exceptionWithTimestamp = /** @type {!SDK.RuntimeModel.ExceptionWithTimestamp} */ (event.data); - var consoleMessage = SDK.ConsoleMessage.fromException( + var consoleMessage = ConsoleModel.ConsoleMessage.fromException( runtimeModel.target(), exceptionWithTimestamp.details, undefined, exceptionWithTimestamp.timestamp, undefined); consoleMessage.setExceptionId(exceptionWithTimestamp.details.exceptionId); this.addMessage(consoleMessage); @@ -221,8 +223,8 @@ if (!exceptionMessage) return; this._errors--; - exceptionMessage.level = SDK.ConsoleMessage.MessageLevel.Info; - this.dispatchEventToListeners(SDK.ConsoleModel.Events.MessageUpdated, exceptionMessage); + exceptionMessage.level = ConsoleModel.ConsoleMessage.MessageLevel.Info; + this.dispatchEventToListeners(ConsoleModel.ConsoleModel.Events.MessageUpdated, exceptionMessage); } /** @@ -231,23 +233,27 @@ */ _consoleAPICalled(runtimeModel, event) { var call = /** @type {!SDK.RuntimeModel.ConsoleAPICall} */ (event.data); - var level = SDK.ConsoleMessage.MessageLevel.Info; - if (call.type === SDK.ConsoleMessage.MessageType.Debug) - level = SDK.ConsoleMessage.MessageLevel.Verbose; - else if (call.type === SDK.ConsoleMessage.MessageType.Error || call.type === SDK.ConsoleMessage.MessageType.Assert) - level = SDK.ConsoleMessage.MessageLevel.Error; - else if (call.type === SDK.ConsoleMessage.MessageType.Warning) - level = SDK.ConsoleMessage.MessageLevel.Warning; - else if (call.type === SDK.ConsoleMessage.MessageType.Info || call.type === SDK.ConsoleMessage.MessageType.Log) - level = SDK.ConsoleMessage.MessageLevel.Info; + var level = ConsoleModel.ConsoleMessage.MessageLevel.Info; + if (call.type === ConsoleModel.ConsoleMessage.MessageType.Debug) + level = ConsoleModel.ConsoleMessage.MessageLevel.Verbose; + else if ( + call.type === ConsoleModel.ConsoleMessage.MessageType.Error || + call.type === ConsoleModel.ConsoleMessage.MessageType.Assert) + level = ConsoleModel.ConsoleMessage.MessageLevel.Error; + else if (call.type === ConsoleModel.ConsoleMessage.MessageType.Warning) + level = ConsoleModel.ConsoleMessage.MessageLevel.Warning; + else if ( + call.type === ConsoleModel.ConsoleMessage.MessageType.Info || + call.type === ConsoleModel.ConsoleMessage.MessageType.Log) + level = ConsoleModel.ConsoleMessage.MessageLevel.Info; var message = ''; if (call.args.length && typeof call.args[0].value === 'string') message = call.args[0].value; else if (call.args.length && call.args[0].description) message = call.args[0].description; var callFrame = call.stackTrace && call.stackTrace.callFrames.length ? call.stackTrace.callFrames[0] : null; - var consoleMessage = new SDK.ConsoleMessage( - runtimeModel.target(), SDK.ConsoleMessage.MessageSource.ConsoleAPI, level, + var consoleMessage = new ConsoleModel.ConsoleMessage( + runtimeModel.target(), ConsoleModel.ConsoleMessage.MessageSource.ConsoleAPI, level, /** @type {string} */ (message), call.type, callFrame ? callFrame.url : undefined, callFrame ? callFrame.lineNumber : undefined, callFrame ? callFrame.columnNumber : undefined, undefined, call.args, call.stackTrace, call.timestamp, call.executionContextId, undefined); @@ -277,7 +283,7 @@ _consoleProfileStarted(cpuProfilerModel, event) { var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data); this._addConsoleProfileMessage( - cpuProfilerModel, SDK.ConsoleMessage.MessageType.Profile, data.scriptLocation, + cpuProfilerModel, ConsoleModel.ConsoleMessage.MessageType.Profile, data.scriptLocation, Common.UIString('Profile \'%s\' started.', data.title)); } @@ -288,7 +294,7 @@ _consoleProfileFinished(cpuProfilerModel, event) { var data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data); this._addConsoleProfileMessage( - cpuProfilerModel, SDK.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation, + cpuProfilerModel, ConsoleModel.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation, Common.UIString('Profile \'%s\' finished.', data.title)); } @@ -306,9 +312,10 @@ lineNumber: scriptLocation.lineNumber, columnNumber: scriptLocation.columnNumber || 0 }]; - this.addMessage(new SDK.ConsoleMessage( - cpuProfilerModel.target(), SDK.ConsoleMessage.MessageSource.ConsoleAPI, SDK.ConsoleMessage.MessageLevel.Info, - messageText, type, undefined, undefined, undefined, undefined, stackTrace)); + this.addMessage(new ConsoleModel.ConsoleMessage( + cpuProfilerModel.target(), ConsoleModel.ConsoleMessage.MessageSource.ConsoleAPI, + ConsoleModel.ConsoleMessage.MessageLevel.Info, messageText, type, undefined, undefined, undefined, undefined, + stackTrace)); } /** @@ -317,29 +324,30 @@ */ _networkWarningGenerated(networkManager, event) { var warning = /** @type {!SDK.NetworkManager.Warning} */ (event.data); - this.addMessage(new SDK.ConsoleMessage( - networkManager.target(), SDK.ConsoleMessage.MessageSource.Network, SDK.ConsoleMessage.MessageLevel.Warning, - warning.message, undefined, undefined, undefined, undefined, warning.requestId)); + this.addMessage(new ConsoleModel.ConsoleMessage( + networkManager.target(), ConsoleModel.ConsoleMessage.MessageSource.Network, + ConsoleModel.ConsoleMessage.MessageLevel.Warning, warning.message, undefined, undefined, undefined, undefined, + warning.requestId)); } /** - * @param {!SDK.ConsoleMessage} msg + * @param {!ConsoleModel.ConsoleMessage} msg */ _incrementErrorWarningCount(msg) { - if (msg.source === SDK.ConsoleMessage.MessageSource.Violation) + if (msg.source === ConsoleModel.ConsoleMessage.MessageSource.Violation) return; switch (msg.level) { - case SDK.ConsoleMessage.MessageLevel.Warning: + case ConsoleModel.ConsoleMessage.MessageLevel.Warning: this._warnings++; break; - case SDK.ConsoleMessage.MessageLevel.Error: + case ConsoleModel.ConsoleMessage.MessageLevel.Error: this._errors++; break; } } /** - * @return {!Array.<!SDK.ConsoleMessage>} + * @return {!Array.<!ConsoleModel.ConsoleMessage>} */ messages() { return this._messages; @@ -358,7 +366,7 @@ this._messageByExceptionId.clear(); this._errors = 0; this._warnings = 0; - this.dispatchEventToListeners(SDK.ConsoleModel.Events.ConsoleCleared); + this.dispatchEventToListeners(ConsoleModel.ConsoleModel.Events.ConsoleCleared); } /** @@ -377,7 +385,7 @@ }; /** @enum {symbol} */ -SDK.ConsoleModel.Events = { +ConsoleModel.ConsoleModel.Events = { ConsoleCleared: Symbol('ConsoleCleared'), MessageAdded: Symbol('MessageAdded'), MessageUpdated: Symbol('MessageUpdated'), @@ -388,7 +396,7 @@ /** * @unrestricted */ -SDK.ConsoleMessage = class { +ConsoleModel.ConsoleMessage = class { /** * @param {?SDK.Target} target * @param {string} source @@ -407,26 +415,13 @@ * @param {?string=} workerId */ constructor( - target, - source, - level, - messageText, - type, - url, - line, - column, - requestId, - parameters, - stackTrace, - timestamp, - executionContextId, - scriptId, - workerId) { + target, source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, timestamp, + executionContextId, scriptId, workerId) { this._target = target; this.source = source; - this.level = /** @type {?SDK.ConsoleMessage.MessageLevel} */ (level); + this.level = /** @type {?ConsoleModel.ConsoleMessage.MessageLevel} */ (level); this.messageText = messageText; - this.type = type || SDK.ConsoleMessage.MessageType.Log; + this.type = type || ConsoleModel.ConsoleMessage.MessageType.Log; /** @type {string|undefined} */ this.url = url || undefined; /** @type {number} */ @@ -457,8 +452,8 @@ } /** - * @param {!SDK.ConsoleMessage} a - * @param {!SDK.ConsoleMessage} b + * @param {!ConsoleModel.ConsoleMessage} a + * @param {!ConsoleModel.ConsoleMessage} b * @return {number} */ static timestampComparator(a, b) { @@ -471,11 +466,11 @@ * @param {string=} messageType * @param {number=} timestamp * @param {string=} forceUrl - * @return {!SDK.ConsoleMessage} + * @return {!ConsoleModel.ConsoleMessage} */ static fromException(target, exceptionDetails, messageType, timestamp, forceUrl) { - return new SDK.ConsoleMessage( - target, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Error, + return new ConsoleModel.ConsoleMessage( + target, ConsoleModel.ConsoleMessage.MessageSource.JS, ConsoleModel.ConsoleMessage.MessageLevel.Error, SDK.RuntimeModel.simpleTextFromException(exceptionDetails), messageType, forceUrl || exceptionDetails.url, exceptionDetails.lineNumber, exceptionDetails.columnNumber, undefined, exceptionDetails.exception ? @@ -492,7 +487,7 @@ } /** - * @param {!SDK.ConsoleMessage} originatingMessage + * @param {!ConsoleModel.ConsoleMessage} originatingMessage */ setOriginatingMessage(originatingMessage) { this._originatingConsoleMessage = originatingMessage; @@ -514,7 +509,7 @@ } /** - * @return {?SDK.ConsoleMessage} + * @return {?ConsoleModel.ConsoleMessage} */ originatingMessage() { return this._originatingConsoleMessage; @@ -524,17 +519,17 @@ * @return {boolean} */ isGroupMessage() { - return this.type === SDK.ConsoleMessage.MessageType.StartGroup || - this.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed || - this.type === SDK.ConsoleMessage.MessageType.EndGroup; + return this.type === ConsoleModel.ConsoleMessage.MessageType.StartGroup || + this.type === ConsoleModel.ConsoleMessage.MessageType.StartGroupCollapsed || + this.type === ConsoleModel.ConsoleMessage.MessageType.EndGroup; } /** * @return {boolean} */ isGroupStartMessage() { - return this.type === SDK.ConsoleMessage.MessageType.StartGroup || - this.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed; + return this.type === ConsoleModel.ConsoleMessage.MessageType.StartGroup || + this.type === ConsoleModel.ConsoleMessage.MessageType.StartGroupCollapsed; } /** @@ -542,11 +537,12 @@ */ isErrorOrWarning() { return ( - this.level === SDK.ConsoleMessage.MessageLevel.Warning || this.level === SDK.ConsoleMessage.MessageLevel.Error); + this.level === ConsoleModel.ConsoleMessage.MessageLevel.Warning || + this.level === ConsoleModel.ConsoleMessage.MessageLevel.Error); } /** - * @param {?SDK.ConsoleMessage} msg + * @param {?ConsoleModel.ConsoleMessage} msg * @return {boolean} */ isEqual(msg) { @@ -605,7 +601,7 @@ /** * @enum {string} */ -SDK.ConsoleMessage.MessageSource = { +ConsoleModel.ConsoleMessage.MessageSource = { XML: 'xml', JS: 'javascript', Network: 'network', @@ -625,7 +621,7 @@ /** * @enum {string} */ -SDK.ConsoleMessage.MessageType = { +ConsoleModel.ConsoleMessage.MessageType = { Log: 'log', Debug: 'debug', Info: 'info', @@ -649,7 +645,7 @@ /** * @enum {string} */ -SDK.ConsoleMessage.MessageLevel = { +ConsoleModel.ConsoleMessage.MessageLevel = { Verbose: 'verbose', Info: 'info', Warning: 'warning', @@ -657,22 +653,22 @@ }; /** - * @param {!SDK.ConsoleMessage.MessageLevel} level + * @param {!ConsoleModel.ConsoleMessage.MessageLevel} level * @return {number} */ -SDK.ConsoleMessage.MessageLevel.ordinal = function(level) { - if (level === SDK.ConsoleMessage.MessageLevel.Verbose) +ConsoleModel.ConsoleMessage.MessageLevel.ordinal = function(level) { + if (level === ConsoleModel.ConsoleMessage.MessageLevel.Verbose) return 0; - if (level === SDK.ConsoleMessage.MessageLevel.Info) + if (level === ConsoleModel.ConsoleMessage.MessageLevel.Info) return 1; - if (level === SDK.ConsoleMessage.MessageLevel.Warning) + if (level === ConsoleModel.ConsoleMessage.MessageLevel.Warning) return 2; return 3; }; -SDK.ConsoleModel._events = Symbol('SDK.ConsoleModel.events'); +ConsoleModel.ConsoleModel._events = Symbol('ConsoleModel.ConsoleModel.events'); /** - * @type {!SDK.ConsoleModel} + * @type {!ConsoleModel.ConsoleModel} */ -SDK.consoleModel; +ConsoleModel.consoleModel;
diff --git a/third_party/WebKit/Source/devtools/front_end/console_model/module.json b/third_party/WebKit/Source/devtools/front_end/console_model/module.json new file mode 100644 index 0000000..441f9fa3 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/console_model/module.json
@@ -0,0 +1,8 @@ +{ + "dependencies": [ + "sdk" + ], + "scripts": [ + "ConsoleModel.js" + ] +}
diff --git a/third_party/WebKit/Source/devtools/front_end/inspector.json b/third_party/WebKit/Source/devtools/front_end/inspector.json index efcabc79..a331425 100644 --- a/third_party/WebKit/Source/devtools/front_end/inspector.json +++ b/third_party/WebKit/Source/devtools/front_end/inspector.json
@@ -56,7 +56,8 @@ { "name": "event_listeners" }, { "name": "object_ui", "type": "autostart"}, { "name": "help", "type": "autostart"}, - { "name": "workspace_diff" } + { "name": "workspace_diff" }, + { "name": "console_model", "type": "autostart"} ], "has_html": true
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js index bfa3748..677d0e1 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Main.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -165,7 +165,7 @@ UI.ContextMenu.installHandler(document); UI.Tooltip.installHandler(document); Components.dockController = new Components.DockController(canDock); - SDK.consoleModel = new SDK.ConsoleModel(); + ConsoleModel.consoleModel = new ConsoleModel.ConsoleModel(); SDK.multitargetNetworkManager = new SDK.MultitargetNetworkManager(); SDK.targetManager.addEventListener( SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged.bind(this)); @@ -602,9 +602,9 @@ this._warnings = this._createItem(shadowRoot, 'smallicon-warning'); this._titles = []; - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, this._update, this); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, this._update, this); - SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageUpdated, this._update, this); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.ConsoleCleared, this._update, this); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, this._update, this); + ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageUpdated, this._update, this); this._update(); } @@ -637,8 +637,8 @@ } _update() { - var errors = SDK.consoleModel.errors(); - var warnings = SDK.consoleModel.warnings(); + var errors = ConsoleModel.consoleModel.errors(); + var warnings = ConsoleModel.consoleModel.warnings(); this._titles = []; this._toolbarItem.setVisible(!!(errors || warnings));
diff --git a/third_party/WebKit/Source/devtools/front_end/main/module.json b/third_party/WebKit/Source/devtools/front_end/main/module.json index c1480768..52a3d5a 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/module.json +++ b/third_party/WebKit/Source/devtools/front_end/main/module.json
@@ -436,7 +436,8 @@ "platform", "sdk", "persistence", - "help" + "help", + "console_model" ], "scripts": [ "RenderingOptions.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/module.json b/third_party/WebKit/Source/devtools/front_end/sdk/module.json index 8c1721dd..4b612215 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/module.json +++ b/third_party/WebKit/Source/devtools/front_end/sdk/module.json
@@ -120,7 +120,6 @@ "Target.js", "TargetManager.js", "Connections.js", - "ConsoleModel.js", "ContentProviders.js", "CookieModel.js", "CookieParser.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js index c25cf7c..e8929d1 100644 --- a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js +++ b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
@@ -275,10 +275,10 @@ * @param {?string=} sourceURL */ _printRunScriptResult(target, result, scriptId, sourceURL) { - var consoleMessage = new SDK.ConsoleMessage( - target, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '', undefined, sourceURL, - undefined, undefined, undefined, [result], undefined, undefined, undefined, scriptId); - SDK.consoleModel.addMessage(consoleMessage); + var consoleMessage = new ConsoleModel.ConsoleMessage( + target, ConsoleModel.ConsoleMessage.MessageSource.JS, ConsoleModel.ConsoleMessage.MessageLevel.Info, '', + undefined, sourceURL, undefined, undefined, undefined, [result], undefined, undefined, undefined, scriptId); + ConsoleModel.consoleModel.addMessage(consoleMessage); } /** @@ -287,8 +287,8 @@ * @param {?string=} sourceURL */ _printRunOrCompileScriptResultFailure(target, exceptionDetails, sourceURL) { - SDK.consoleModel.addMessage( - SDK.ConsoleMessage.fromException(target, exceptionDetails, undefined, undefined, sourceURL || undefined)); + ConsoleModel.consoleModel.addMessage(ConsoleModel.ConsoleMessage.fromException( + target, exceptionDetails, undefined, undefined, sourceURL || undefined)); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js index 695c0a1..4fd9a0c 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -956,7 +956,7 @@ if (wasThrown || !result || result.type !== 'string') { failedToSave(result); } else { - SDK.consoleModel.evaluateCommandInConsole( + ConsoleModel.consoleModel.evaluateCommandInConsole( /** @type {!SDK.ExecutionContext} */ (currentExecutionContext), result.value, /* useCommandLineAPI */ false); } @@ -1268,7 +1268,7 @@ var text = frame.textEditor.text(frame.textEditor.selection()); var executionContext = UI.context.flavor(SDK.ExecutionContext); if (executionContext) - SDK.consoleModel.evaluateCommandInConsole(executionContext, text, /* useCommandLineAPI */ true); + ConsoleModel.consoleModel.evaluateCommandInConsole(executionContext, text, /* useCommandLineAPI */ true); } return true; }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js index 06d7a9c6..922a5aa9 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
@@ -61,6 +61,8 @@ this._rowHeight = 17; this._userInteracted = false; this._userEnteredText = ''; + this._defaultSelectionIsDimmed = false; + /** @type {?string} */ this._onlyCompletion = null; @@ -81,6 +83,7 @@ * @param {boolean} value */ setDefaultSelectionIsDimmed(value) { + this._defaultSelectionIsDimmed = value; this._element.classList.toggle('default-selection-is-dimmed', value); } @@ -259,8 +262,11 @@ selectedItemChanged(from, to, fromElement, toElement) { if (fromElement) fromElement.classList.remove('selected', 'force-white-icons'); - if (toElement) - toElement.classList.add('selected', 'force-white-icons'); + if (toElement) { + toElement.classList.add('selected'); + if (fromElement || this._userInteracted || !this._defaultSelectionIsDimmed) + toElement.classList.add('force-white-icons'); + } if (!to) return; this._applySuggestion(true);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css b/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css index 0a0ec31..70ab416 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css
@@ -94,7 +94,7 @@ } .default-selection-is-dimmed .suggest-box-content-item.selected { - background-color: whitesmoke; + background-color: #E0E0E0; } .default-selection-is-dimmed .suggest-box-content-item.selected > span {
diff --git a/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js b/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js index 307f117..c07c5f7 100644 --- a/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js +++ b/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js
@@ -24,17 +24,13 @@ const MODULES_TO_REMOVE = []; const JS_FILES_MAPPING = [ - {file: 'components/CustomPreviewComponent.js', new: 'object_ui'}, - {file: 'components/ObjectPopoverHelper.js', new: 'object_ui'}, - {file: 'components/ObjectPropertiesSection.js', new: 'object_ui'}, - {file: 'components/JavaScriptAutocomplete.js', new: 'object_ui'}, - {file: 'components/RemoteObjectPreviewFormatter.js', new: 'object_ui'}, + {file: 'sdk/ConsoleModel.js', new: 'console_model'}, ]; const MODULE_MAPPING = { - object_ui: { - dependencies: ['ui', 'sdk', 'components'], - dependents: ['console', 'sources', 'extensions', 'event_listeners', 'resources', 'profiler', 'network'], + console_model: { + dependencies: ['sdk'], + dependents: ['bindings', 'console', 'main'], applications: ['inspector.json'], autostart: true, // set to autostart because of extensions },
diff --git a/third_party/WebKit/Source/modules/background_fetch/BUILD.gn b/third_party/WebKit/Source/modules/background_fetch/BUILD.gn index c2036e6..4ba3957 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BUILD.gn +++ b/third_party/WebKit/Source/modules/background_fetch/BUILD.gn
@@ -6,6 +6,8 @@ blink_modules_sources("background_fetch") { sources = [ + "BackgroundFetchBridge.cpp", + "BackgroundFetchBridge.h", "BackgroundFetchClickEvent.cpp", "BackgroundFetchClickEvent.h", "BackgroundFetchEvent.cpp",
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp new file mode 100644 index 0000000..ef89640 --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp
@@ -0,0 +1,123 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "modules/background_fetch/BackgroundFetchBridge.h" + +#include <utility> +#include "modules/background_fetch/BackgroundFetchOptions.h" +#include "modules/background_fetch/BackgroundFetchRegistration.h" +#include "modules/background_fetch/IconDefinition.h" +#include "public/platform/InterfaceProvider.h" +#include "public/platform/Platform.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" + +namespace blink { + +namespace { + +// Creates a new BackgroundFetchRegistration instance given a Service Worker +// Registration and a Mojo BackgroundFetchRegistrationPtr instance. +BackgroundFetchRegistration* CreateBackgroundFetchRegistration( + ServiceWorkerRegistration* serviceWorkerRegistration, + mojom::blink::BackgroundFetchRegistrationPtr registrationPtr) { + HeapVector<IconDefinition> icons; + + for (const auto& iconPtr : registrationPtr->icons) { + IconDefinition icon; + icon.setSrc(iconPtr->src); + icon.setSizes(iconPtr->sizes); + icon.setType(iconPtr->type); + + icons.push_back(icon); + } + + return new BackgroundFetchRegistration( + serviceWorkerRegistration, registrationPtr->tag, std::move(icons), + registrationPtr->total_download_size, registrationPtr->title); +} + +} // namespace + +// static +BackgroundFetchBridge* BackgroundFetchBridge::from( + ServiceWorkerRegistration* serviceWorkerRegistration) { + DCHECK(serviceWorkerRegistration); + + BackgroundFetchBridge* bridge = static_cast<BackgroundFetchBridge*>( + Supplement<ServiceWorkerRegistration>::from(serviceWorkerRegistration, + supplementName())); + + if (!bridge) { + bridge = new BackgroundFetchBridge(*serviceWorkerRegistration); + Supplement<ServiceWorkerRegistration>::provideTo(*serviceWorkerRegistration, + supplementName(), bridge); + } + + return bridge; +} + +// static +const char* BackgroundFetchBridge::supplementName() { + return "BackgroundFetchBridge"; +} + +BackgroundFetchBridge::BackgroundFetchBridge( + ServiceWorkerRegistration& registration) + : Supplement<ServiceWorkerRegistration>(registration) {} + +BackgroundFetchBridge::~BackgroundFetchBridge() = default; + +void BackgroundFetchBridge::abort(const String& tag) { + getService()->Abort(supplementable()->webRegistration()->registrationId(), + tag); +} + +void BackgroundFetchBridge::updateUI( + const String& tag, + const String& title, + std::unique_ptr<UpdateUICallback> callback) { + getService()->UpdateUI(supplementable()->webRegistration()->registrationId(), + tag, title, + convertToBaseCallback(std::move(callback))); +} + +void BackgroundFetchBridge::getRegistration( + const String& tag, + std::unique_ptr<GetRegistrationCallback> callback) { + getService()->GetRegistration( + supplementable()->webRegistration()->registrationId(), tag, + convertToBaseCallback( + WTF::bind(&BackgroundFetchBridge::didGetRegistration, + wrapPersistent(this), WTF::passed(std::move(callback))))); +} + +void BackgroundFetchBridge::didGetRegistration( + std::unique_ptr<GetRegistrationCallback> callback, + mojom::blink::BackgroundFetchError error, + mojom::blink::BackgroundFetchRegistrationPtr registrationPtr) { + BackgroundFetchRegistration* registration = nullptr; + + if (registrationPtr) { + DCHECK_EQ(error, mojom::blink::BackgroundFetchError::NONE); + registration = CreateBackgroundFetchRegistration( + supplementable(), std::move(registrationPtr)); + } + + (*callback)(error, registration); +} + +void BackgroundFetchBridge::getTags(std::unique_ptr<GetTagsCallback> callback) { + getService()->GetTags(supplementable()->webRegistration()->registrationId(), + convertToBaseCallback(std::move(callback))); +} + +mojom::blink::BackgroundFetchServicePtr& BackgroundFetchBridge::getService() { + if (!m_backgroundFetchService) { + Platform::current()->interfaceProvider()->getInterface( + mojo::MakeRequest(&m_backgroundFetchService)); + } + return m_backgroundFetchService; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h new file mode 100644 index 0000000..837237d --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h
@@ -0,0 +1,81 @@ +// 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 BackgroundFetchBridge_h +#define BackgroundFetchBridge_h + +#include <memory> +#include "modules/serviceworkers/ServiceWorkerRegistration.h" +#include "platform/Supplementable.h" +#include "platform/heap/Handle.h" +#include "public/platform/modules/background_fetch/background_fetch.mojom-blink.h" +#include "wtf/Functional.h" +#include "wtf/Vector.h" +#include "wtf/text/WTFString.h" + +namespace blink { + +class BackgroundFetchRegistration; + +// The bridge is responsible for establishing and maintaining the Mojo +// connection to the BackgroundFetchService. It's keyed on an active Service +// Worker Registration. +class BackgroundFetchBridge final + : public GarbageCollectedFinalized<BackgroundFetchBridge>, + public Supplement<ServiceWorkerRegistration> { + USING_GARBAGE_COLLECTED_MIXIN(BackgroundFetchBridge); + WTF_MAKE_NONCOPYABLE(BackgroundFetchBridge); + + public: + using UpdateUICallback = Function<void(mojom::blink::BackgroundFetchError)>; + using GetRegistrationCallback = + Function<void(mojom::blink::BackgroundFetchError, + BackgroundFetchRegistration*)>; + using GetTagsCallback = + Function<void(mojom::blink::BackgroundFetchError, const Vector<String>&)>; + + static BackgroundFetchBridge* from(ServiceWorkerRegistration*); + static const char* supplementName(); + + virtual ~BackgroundFetchBridge(); + + // TODO(peter): Implement support for the `fetch()` function in the bridge. + + // Updates the user interface for the Background Fetch identified by |tag| + // with the updated |title|. Will invoke the |callback| when the interface + // has been requested to update. + void updateUI(const String& tag, + const String& title, + std::unique_ptr<UpdateUICallback>); + + // Aborts the active Background Fetch for |tag|. Does not respond. + void abort(const String& tag); + + // Gets the Background Fetch registration for the given |tag|. Will invoke the + // |callback| with the Background Fetch registration, which may be a nullptr + // if the |tag| does not exist, when the Mojo call has completed. + void getRegistration(const String& tag, + std::unique_ptr<GetRegistrationCallback>); + + // Gets the sequence of tags for active Background Fetch registrations. Will + // invoke the |callback| with the tags when the Mojo call has completed. + void getTags(std::unique_ptr<GetTagsCallback>); + + private: + explicit BackgroundFetchBridge(ServiceWorkerRegistration&); + + // Returns an initialized BackgroundFetchServicePtr. A connection will be + // established after the first call to this method. + mojom::blink::BackgroundFetchServicePtr& getService(); + + void didGetRegistration(std::unique_ptr<GetRegistrationCallback>, + mojom::blink::BackgroundFetchError, + mojom::blink::BackgroundFetchRegistrationPtr); + + mojom::blink::BackgroundFetchServicePtr m_backgroundFetchService; +}; + +} // namespace blink + +#endif // BackgroundFetchBridge_h
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp index a1339f5..14dd263 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp
@@ -7,6 +7,7 @@ #include "bindings/core/v8/ScriptPromiseResolver.h" #include "bindings/core/v8/ScriptState.h" #include "bindings/core/v8/V8ThrowException.h" +#include "modules/background_fetch/BackgroundFetchBridge.h" #include "modules/background_fetch/BackgroundFetchOptions.h" #include "modules/background_fetch/BackgroundFetchRegistration.h" #include "modules/serviceworkers/ServiceWorkerRegistration.h" @@ -17,12 +18,13 @@ ServiceWorkerRegistration* registration) : m_registration(registration) { DCHECK(registration); + m_bridge = BackgroundFetchBridge::from(m_registration); } ScriptPromise BackgroundFetchManager::fetch( ScriptState* scriptState, - String tag, - HeapVector<RequestOrUSVString> requests, + const String& tag, + const RequestOrUSVStringOrRequestOrUSVStringSequence& requests, const BackgroundFetchOptions& options) { if (!m_registration->active()) { return ScriptPromise::reject( @@ -48,7 +50,7 @@ } ScriptPromise BackgroundFetchManager::get(ScriptState* scriptState, - String tag) { + const String& tag) { if (!m_registration->active()) { return ScriptPromise::reject( scriptState, @@ -60,13 +62,29 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); - // TODO(peter): Get the background fetch registration for `tag` from the - // browser process. There may not be one. - resolver->resolve(v8::Null(scriptState->isolate())); + m_bridge->getRegistration( + tag, WTF::bind(&BackgroundFetchManager::didGetRegistration, + wrapPersistent(this), wrapPersistent(resolver))); return promise; } +void BackgroundFetchManager::didGetRegistration( + ScriptPromiseResolver* resolver, + mojom::blink::BackgroundFetchError error, + BackgroundFetchRegistration* registration) { + switch (error) { + case mojom::blink::BackgroundFetchError::NONE: + resolver->resolve(registration); + return; + case mojom::blink::BackgroundFetchError::DUPLICATED_TAG: + // Not applicable for this callback. + break; + } + + NOTREACHED(); +} + ScriptPromise BackgroundFetchManager::getTags(ScriptState* scriptState) { if (!m_registration->active()) { return ScriptPromise::reject( @@ -79,14 +97,31 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); - // TODO(peter): Get a list of tags from the browser process. - resolver->resolve(Vector<String>()); + m_bridge->getTags(WTF::bind(&BackgroundFetchManager::didGetTags, + wrapPersistent(this), wrapPersistent(resolver))); return promise; } +void BackgroundFetchManager::didGetTags( + ScriptPromiseResolver* resolver, + mojom::blink::BackgroundFetchError error, + const Vector<String>& tags) { + switch (error) { + case mojom::blink::BackgroundFetchError::NONE: + resolver->resolve(tags); + return; + case mojom::blink::BackgroundFetchError::DUPLICATED_TAG: + // Not applicable for this callback. + break; + } + + NOTREACHED(); +} + DEFINE_TRACE(BackgroundFetchManager) { visitor->trace(m_registration); + visitor->trace(m_bridge); } } // namespace blink
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h index e52725e..03cd38f8 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h
@@ -9,11 +9,15 @@ #include "bindings/core/v8/ScriptWrappable.h" #include "platform/heap/GarbageCollected.h" #include "platform/heap/Handle.h" +#include "public/platform/modules/background_fetch/background_fetch.mojom-blink.h" namespace blink { +class BackgroundFetchBridge; class BackgroundFetchOptions; -class RequestOrUSVString; +class BackgroundFetchRegistration; +class RequestOrUSVStringOrRequestOrUSVStringSequence; +class ScriptPromiseResolver; class ScriptState; class ServiceWorkerRegistration; @@ -31,11 +35,12 @@ } // Web Exposed methods defined in the IDL file. - ScriptPromise fetch(ScriptState*, - String tag, - HeapVector<RequestOrUSVString> requests, - const BackgroundFetchOptions&); - ScriptPromise get(ScriptState*, String tag); + ScriptPromise fetch( + ScriptState*, + const String& tag, + const RequestOrUSVStringOrRequestOrUSVStringSequence& requests, + const BackgroundFetchOptions&); + ScriptPromise get(ScriptState*, const String& tag); ScriptPromise getTags(ScriptState*); DECLARE_TRACE(); @@ -43,7 +48,15 @@ private: explicit BackgroundFetchManager(ServiceWorkerRegistration*); + void didGetRegistration(ScriptPromiseResolver*, + mojom::blink::BackgroundFetchError, + BackgroundFetchRegistration*); + void didGetTags(ScriptPromiseResolver*, + mojom::blink::BackgroundFetchError, + const Vector<String>& tags); + Member<ServiceWorkerRegistration> m_registration; + Member<BackgroundFetchBridge> m_bridge; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl index 085096f3..a30ad00 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl
@@ -8,10 +8,7 @@ Exposed=(Window,Worker), RuntimeEnabled=BackgroundFetch ] interface BackgroundFetchManager { - // TODO(peter): The `requests` argument of `fetch()` should accept either an - // individual RequestInfo, or a sequence of them. - [CallWith=ScriptState] Promise<BackgroundFetchRegistration> fetch(DOMString tag, sequence<RequestInfo> requests, optional BackgroundFetchOptions options); - + [CallWith=ScriptState] Promise<BackgroundFetchRegistration> fetch(DOMString tag, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options); [CallWith=ScriptState] Promise<BackgroundFetchRegistration?> get(DOMString tag); [CallWith=ScriptState] Promise<FrozenArray<DOMString>> getTags(); };
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchRegistration.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchRegistration.cpp index 0a7aefe..b5ed2d0 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchRegistration.cpp +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchRegistration.cpp
@@ -4,6 +4,7 @@ #include "modules/background_fetch/BackgroundFetchRegistration.h" +#include "modules/background_fetch/BackgroundFetchBridge.h" #include "modules/background_fetch/IconDefinition.h" #include "modules/serviceworkers/ServiceWorkerRegistration.h" @@ -40,8 +41,7 @@ } void BackgroundFetchRegistration::abort() { - // TODO(peter): Implement the ability to abort the active background fetch - // for the |m_registration| identified by the |m_tag|. + BackgroundFetchBridge::from(m_registration)->abort(m_tag); } DEFINE_TRACE(BackgroundFetchRegistration) {
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.cpp index d5cc50d..3551dbe 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.cpp +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.cpp
@@ -4,9 +4,11 @@ #include "modules/background_fetch/BackgroundFetchedEvent.h" +#include "bindings/core/v8/ScriptPromiseResolver.h" #include "bindings/core/v8/ScriptState.h" #include "core/dom/DOMException.h" #include "modules/EventModulesNames.h" +#include "modules/background_fetch/BackgroundFetchBridge.h" #include "modules/background_fetch/BackgroundFetchSettledRequest.h" #include "modules/background_fetch/BackgroundFetchedEventInit.h" @@ -14,9 +16,11 @@ BackgroundFetchedEvent::BackgroundFetchedEvent( const AtomicString& type, - const BackgroundFetchedEventInit& init) + const BackgroundFetchedEventInit& init, + ServiceWorkerRegistration* registration) : BackgroundFetchEvent(type, init), - m_completedFetches(init.completedFetches()) {} + m_completedFetches(init.completedFetches()), + m_registration(registration) {} BackgroundFetchedEvent::~BackgroundFetchedEvent() = default; @@ -26,10 +30,37 @@ } ScriptPromise BackgroundFetchedEvent::updateUI(ScriptState* scriptState, - String title) { - return ScriptPromise::rejectWithDOMException( - scriptState, - DOMException::create(NotSupportedError, "Not implemented yet.")); + const String& title) { + if (!m_registration) { + // Return a Promise that will never settle when a developer calls this + // method on a BackgroundFetchedEvent instance they created themselves. + return ScriptPromise(); + } + + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); + ScriptPromise promise = resolver->promise(); + + BackgroundFetchBridge::from(m_registration) + ->updateUI(tag(), title, + WTF::bind(&BackgroundFetchedEvent::didUpdateUI, + wrapPersistent(this), wrapPersistent(resolver))); + + return promise; +} + +void BackgroundFetchedEvent::didUpdateUI( + ScriptPromiseResolver* resolver, + mojom::blink::BackgroundFetchError error) { + switch (error) { + case mojom::blink::BackgroundFetchError::NONE: + resolver->resolve(); + return; + case mojom::blink::BackgroundFetchError::DUPLICATED_TAG: + // Not applicable for this callback. + break; + } + + NOTREACHED(); } const AtomicString& BackgroundFetchedEvent::interfaceName() const { @@ -38,6 +69,7 @@ DEFINE_TRACE(BackgroundFetchedEvent) { visitor->trace(m_completedFetches); + visitor->trace(m_registration); BackgroundFetchEvent::trace(visitor); }
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.h b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.h index aaee6f61..1e63594 100644 --- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.h +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchedEvent.h
@@ -8,12 +8,14 @@ #include "bindings/core/v8/ScriptPromise.h" #include "modules/background_fetch/BackgroundFetchEvent.h" #include "platform/heap/Handle.h" +#include "public/platform/modules/background_fetch/background_fetch.mojom-blink.h" #include "wtf/text/AtomicString.h" namespace blink { class BackgroundFetchSettledRequest; class BackgroundFetchedEventInit; +class ServiceWorkerRegistration; class BackgroundFetchedEvent final : public BackgroundFetchEvent { DEFINE_WRAPPERTYPEINFO(); @@ -22,7 +24,15 @@ static BackgroundFetchedEvent* create( const AtomicString& type, const BackgroundFetchedEventInit& initializer) { - return new BackgroundFetchedEvent(type, initializer); + return new BackgroundFetchedEvent(type, initializer, + nullptr /* registration */); + } + + static BackgroundFetchedEvent* create( + const AtomicString& type, + const BackgroundFetchedEventInit& initializer, + ServiceWorkerRegistration* registration) { + return new BackgroundFetchedEvent(type, initializer, registration); } ~BackgroundFetchedEvent() override; @@ -31,7 +41,7 @@ HeapVector<Member<BackgroundFetchSettledRequest>> completedFetches() const; // Web Exposed method defined in the IDL file. - ScriptPromise updateUI(ScriptState*, String title); + ScriptPromise updateUI(ScriptState*, const String& title); // ExtendableEvent interface. const AtomicString& interfaceName() const override; @@ -40,9 +50,13 @@ private: BackgroundFetchedEvent(const AtomicString& type, - const BackgroundFetchedEventInit&); + const BackgroundFetchedEventInit&, + ServiceWorkerRegistration*); + + void didUpdateUI(ScriptPromiseResolver*, mojom::blink::BackgroundFetchError); HeapVector<Member<BackgroundFetchSettledRequest>> m_completedFetches; + Member<ServiceWorkerRegistration> m_registration; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp index 381cc394..2a667a2 100644 --- a/third_party/WebKit/Source/modules/webusb/USB.cpp +++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -53,12 +53,7 @@ } // namespace USB::USB(LocalFrame& frame) - : ContextLifecycleObserver(frame.document()), m_clientBinding(this) { - frame.interfaceProvider()->getInterface(mojo::MakeRequest(&m_deviceManager)); - m_deviceManager.set_connection_error_handler(convertToBaseCallback(WTF::bind( - &USB::onDeviceManagerConnectionError, wrapWeakPersistent(this)))); - m_deviceManager->SetClient(m_clientBinding.CreateInterfacePtrAndBind()); -} + : ContextLifecycleObserver(frame.document()), m_clientBinding(this) {} USB::~USB() { // |m_deviceManager| and |m_chooserService| may still be valid but there @@ -77,6 +72,7 @@ ScriptPromise USB::getDevices(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); + ensureDeviceManagerConnection(); if (!m_deviceManager) { resolver->reject(DOMException::create(NotSupportedError)); } else { @@ -91,20 +87,15 @@ ScriptPromise USB::requestDevice(ScriptState* scriptState, const USBDeviceRequestOptions& options) { - ExecutionContext* executionContext = scriptState->getExecutionContext(); - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); if (!m_chooserService) { - LocalFrame* frame = executionContext->isDocument() - ? toDocument(executionContext)->frame() - : nullptr; - if (!frame) { + if (!frame()) { resolver->reject(DOMException::create(NotSupportedError)); return promise; } - frame->interfaceProvider()->getInterface( + frame()->interfaceProvider()->getInterface( mojo::MakeRequest(&m_chooserService)); m_chooserService.set_connection_error_handler( convertToBaseCallback(WTF::bind(&USB::onChooserServiceConnectionError, @@ -180,16 +171,18 @@ return; m_chooserServiceRequests.erase(requestEntry); + ensureDeviceManagerConnection(); if (!m_deviceManager) { resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); return; } - if (deviceInfo) + if (deviceInfo) { resolver->resolve(getOrCreateDevice(std::move(deviceInfo))); - else + } else { resolver->reject( DOMException::create(NotFoundError, "No device selected.")); + } } void USB::OnDeviceAdded(usb::DeviceInfoPtr deviceInfo) { @@ -203,15 +196,17 @@ void USB::OnDeviceRemoved(usb::DeviceInfoPtr deviceInfo) { String guid = deviceInfo->guid; USBDevice* device = m_deviceCache.at(guid); - if (!device) + if (!device) { device = USBDevice::create(std::move(deviceInfo), nullptr, getExecutionContext()); + } dispatchEvent(USBConnectionEvent::create(EventTypeNames::disconnect, device)); m_deviceCache.erase(guid); } void USB::onDeviceManagerConnectionError() { m_deviceManager.reset(); + m_clientBinding.Close(); for (ScriptPromiseResolver* resolver : m_deviceManagerRequests) resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); m_deviceManagerRequests.clear(); @@ -224,6 +219,28 @@ m_chooserServiceRequests.clear(); } +void USB::addedEventListener(const AtomicString& eventType, + RegisteredEventListener& listener) { + EventTargetWithInlineData::addedEventListener(eventType, listener); + if (eventType == EventTypeNames::connect || + eventType == EventTypeNames::disconnect) { + ensureDeviceManagerConnection(); + } +} + +void USB::ensureDeviceManagerConnection() { + if (m_deviceManager || !frame()) + return; + + frame()->interfaceProvider()->getInterface( + mojo::MakeRequest(&m_deviceManager)); + m_deviceManager.set_connection_error_handler(convertToBaseCallback(WTF::bind( + &USB::onDeviceManagerConnectionError, wrapWeakPersistent(this)))); + + DCHECK(!m_clientBinding.is_bound()); + m_deviceManager->SetClient(m_clientBinding.CreateInterfacePtrAndBind()); +} + DEFINE_TRACE(USB) { visitor->trace(m_deviceManagerRequests); visitor->trace(m_chooserServiceRequests);
diff --git a/third_party/WebKit/Source/modules/webusb/USB.h b/third_party/WebKit/Source/modules/webusb/USB.h index 92ad0d9..5d73165c 100644 --- a/third_party/WebKit/Source/modules/webusb/USB.h +++ b/third_party/WebKit/Source/modules/webusb/USB.h
@@ -69,9 +69,16 @@ DECLARE_VIRTUAL_TRACE(); + protected: + // EventTarget protected overrides. + void addedEventListener(const AtomicString& eventType, + RegisteredEventListener&) override; + private: explicit USB(LocalFrame& frame); + void ensureDeviceManagerConnection(); + device::usb::blink::DeviceManagerPtr m_deviceManager; HeapHashSet<Member<ScriptPromiseResolver>> m_deviceManagerRequests; device::usb::blink::ChooserServicePtr m_chooserService;
diff --git a/third_party/WebKit/Source/platform/graphics/Gradient.cpp b/third_party/WebKit/Source/platform/graphics/Gradient.cpp index e6d5452..0ef2a039 100644 --- a/third_party/WebKit/Source/platform/graphics/Gradient.cpp +++ b/third_party/WebKit/Source/platform/graphics/Gradient.cpp
@@ -42,7 +42,10 @@ namespace blink { -Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1) +Gradient::Gradient(const FloatPoint& p0, + const FloatPoint& p1, + GradientSpreadMethod spreadMethod, + ColorInterpolation interpolation) : m_p0(p0), m_p1(p1), m_r0(0), @@ -50,14 +53,16 @@ m_aspectRatio(1), m_radial(false), m_stopsSorted(false), - m_drawInPMColorSpace(false), - m_spreadMethod(SpreadMethodPad) {} + m_spreadMethod(spreadMethod), + m_colorInterpolation(interpolation) {} Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, - float aspectRatio) + float aspectRatio, + GradientSpreadMethod spreadMethod, + ColorInterpolation interpolation) : m_p0(p0), m_p1(p1), m_r0(r0), @@ -65,8 +70,8 @@ m_aspectRatio(aspectRatio), m_radial(true), m_stopsSorted(false), - m_drawInPMColorSpace(false), - m_spreadMethod(SpreadMethodPad) {} + m_spreadMethod(spreadMethod), + m_colorInterpolation(interpolation) {} Gradient::~Gradient() {} @@ -103,25 +108,6 @@ std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); } -void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod) { - // FIXME: Should it become necessary, allow calls to this method after - // |m_gradient| has been set. - DCHECK(!m_cachedShader); - - if (m_spreadMethod == spreadMethod) - return; - - m_spreadMethod = spreadMethod; -} - -void Gradient::setDrawsInPMColorSpace(bool drawInPMColorSpace) { - if (drawInPMColorSpace == m_drawInPMColorSpace) - return; - - m_drawInPMColorSpace = drawInPMColorSpace; - m_cachedShader.reset(); -} - // Determine the total number of stops needed, including pseudo-stops at the // ends as necessary. static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, @@ -208,9 +194,9 @@ } sk_sp<SkShader> shader; - uint32_t shouldDrawInPMColorSpace = - m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag - : 0; + uint32_t flags = m_colorInterpolation == ColorInterpolation::Premultiplied + ? SkGradientShader::kInterpolateColorsInPremul_Flag + : 0; if (m_radial) { SkMatrix adjustedLocalMatrix = localMatrix; @@ -228,8 +214,7 @@ if (m_p0 == m_p1 && m_r0 <= 0.0f) { shader = SkGradientShader::MakeRadial( m_p1.data(), m_r1, colors.data(), pos.data(), - static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, - &adjustedLocalMatrix); + static_cast<int>(countUsed), tile, flags, &adjustedLocalMatrix); } else { // The radii we give to Skia must be positive. If we're given a // negative radius, ask for zero instead. @@ -237,14 +222,13 @@ SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; shader = SkGradientShader::MakeTwoPointConical( m_p0.data(), radius0, m_p1.data(), radius1, colors.data(), pos.data(), - static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, - &adjustedLocalMatrix); + static_cast<int>(countUsed), tile, flags, &adjustedLocalMatrix); } } else { SkPoint pts[2] = {m_p0.data(), m_p1.data()}; - shader = SkGradientShader::MakeLinear( - pts, colors.data(), pos.data(), static_cast<int>(countUsed), tile, - shouldDrawInPMColorSpace, &localMatrix); + shader = SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), + static_cast<int>(countUsed), tile, + flags, &localMatrix); } if (!shader) {
diff --git a/third_party/WebKit/Source/platform/graphics/Gradient.h b/third_party/WebKit/Source/platform/graphics/Gradient.h index 273c1fed..bb4832b 100644 --- a/third_party/WebKit/Source/platform/graphics/Gradient.h +++ b/third_party/WebKit/Source/platform/graphics/Gradient.h
@@ -49,16 +49,28 @@ WTF_MAKE_NONCOPYABLE(Gradient); public: - static PassRefPtr<Gradient> create(const FloatPoint& p0, - const FloatPoint& p1) { - return adoptRef(new Gradient(p0, p1)); + enum class ColorInterpolation { + Premultiplied, + Unpremultiplied, + }; + + static PassRefPtr<Gradient> create( + const FloatPoint& p0, + const FloatPoint& p1, + GradientSpreadMethod spreadMethod = SpreadMethodPad, + ColorInterpolation interpolation = ColorInterpolation::Unpremultiplied) { + return adoptRef(new Gradient(p0, p1, spreadMethod, interpolation)); } - static PassRefPtr<Gradient> create(const FloatPoint& p0, - float r0, - const FloatPoint& p1, - float r1, - float aspectRatio = 1) { - return adoptRef(new Gradient(p0, r0, p1, r1, aspectRatio)); + static PassRefPtr<Gradient> create( + const FloatPoint& p0, + float r0, + const FloatPoint& p1, + float r1, + float aspectRatio = 1, + GradientSpreadMethod spreadMethod = SpreadMethodPad, + ColorInterpolation interpolation = ColorInterpolation::Unpremultiplied) { + return adoptRef( + new Gradient(p0, r0, p1, r1, aspectRatio, spreadMethod, interpolation)); } ~Gradient(); @@ -84,51 +96,25 @@ const FloatPoint& p0() const { return m_p0; } const FloatPoint& p1() const { return m_p1; } - void setP0(const FloatPoint& p) { - if (m_p0 == p) - return; - - m_p0 = p; - } - - void setP1(const FloatPoint& p) { - if (m_p1 == p) - return; - - m_p1 = p; - } - float startRadius() const { return m_r0; } float endRadius() const { return m_r1; } - void setStartRadius(float r) { - if (m_r0 == r) - return; - - m_r0 = r; - } - - void setEndRadius(float r) { - if (m_r1 == r) - return; - - m_r1 = r; - } - void applyToFlags(PaintFlags&, const SkMatrix& localMatrix); - void setDrawsInPMColorSpace(bool drawInPMColorSpace); - - void setSpreadMethod(GradientSpreadMethod); GradientSpreadMethod spreadMethod() const { return m_spreadMethod; } private: - Gradient(const FloatPoint& p0, const FloatPoint& p1); + Gradient(const FloatPoint& p0, + const FloatPoint& p1, + GradientSpreadMethod, + ColorInterpolation); Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, - float aspectRatio); + float aspectRatio, + GradientSpreadMethod, + ColorInterpolation); sk_sp<PaintShader> createShader(const SkMatrix& localMatrix); @@ -142,8 +128,8 @@ Vector<ColorStop, 2> m_stops; bool m_radial; bool m_stopsSorted; - bool m_drawInPMColorSpace; GradientSpreadMethod m_spreadMethod; + ColorInterpolation m_colorInterpolation; mutable sk_sp<PaintShader> m_cachedShader; };
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index 9459ec1..a1ae793 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -653,6 +653,7 @@ sources = [ "platform/mime_registry.mojom", "platform/modules/app_banner/app_banner.mojom", + "platform/modules/background_fetch/background_fetch.mojom", "platform/modules/background_sync/background_sync.mojom", "platform/modules/bluetooth/web_bluetooth.mojom", "platform/modules/broadcastchannel/broadcast_channel.mojom",
diff --git a/third_party/WebKit/public/platform/modules/background_fetch/OWNERS b/third_party/WebKit/public/platform/modules/background_fetch/OWNERS new file mode 100644 index 0000000..f239b900 --- /dev/null +++ b/third_party/WebKit/public/platform/modules/background_fetch/OWNERS
@@ -0,0 +1,7 @@ +peter@chromium.org + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS + +# TEAM: platform-capabilities@chromium.org +# COMPONENT: Blink>BackgroundFetch
diff --git a/third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom b/third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom new file mode 100644 index 0000000..9092281 --- /dev/null +++ b/third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom
@@ -0,0 +1,48 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +enum BackgroundFetchError { + NONE, + DUPLICATED_TAG +}; + +struct IconDefinition { + string src; + string sizes; + string type; +}; + +struct BackgroundFetchRegistration { + string tag; + array<IconDefinition> icons; + int64 total_download_size = 0; + string title = ""; +}; + +interface BackgroundFetchService { + // TODO(peter): Implement support for the `fetch()` function in Mojo. + + // Updates the user interface for the Background Fetch identified by the + // |service_worker_registration_id| and the |tag|. + UpdateUI(int64 service_worker_registration_id, string tag, string title) + => (BackgroundFetchError error); + + // Aborts the Background Fetch registration identified by the + // |service_worker_registration_id| and the |tag|. + Abort(int64 service_worker_registration_id, string tag); + + // Gets the Background Fetch registration identified by the + // |service_worker_registration_id| and the |tag|. + GetRegistration(int64 service_worker_registration_id, string tag) + => (BackgroundFetchError error, + BackgroundFetchRegistration? registration); + + // Gets the sequence of tags for active Background Fetch registrations given + // the |service_worker_registration_id|. + GetTags(int64 service_worker_registration_id) + => (BackgroundFetchError error, + array<string> tags); +};
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 9239e75..8eca868 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -9985,6 +9985,14 @@ <description>Please enter the description of this user action.</description> </action> +<action name="MobileNTPOpenedInNewTab"> + <owner>fhorschig@chromium.org</owner> + <description> + The user manually created a New Tab Page (NTP) in a new tab that has not + been shown before. This includes the initial tab (when starting Chrome). + </description> +</action> + <action name="MobileNTPRecentlyClosed"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9dab252..a6c7ce90 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -90950,6 +90950,11 @@ <int value="1161" label="AUDIO_SETMUTE"/> <int value="1162" label="AUDIO_GETDEVICES"/> <int value="1163" label="VIRTUALKEYBOARD_RESTRICTFEATURES"/> + <int value="1164" label="NETWORKINGCASTPRIVATE_VERIFYDESTINATION"/> + <int value="1165" label="NETWORKINGCASTPRIVATE_VERIFYANDENCRYPTCREDENTIALS"/> + <int value="1166" label="NETWORKINGCASTPRIVATE_VERIFYANDENCRYPTDATA"/> + <int value="1167" label="NETWORKINGCASTPRIVATE_SETWIFITDLSENABLEDSTATE"/> + <int value="1168" label="NETWORKINGCASTPRIVATE_GETWIFITDLSSTATUS"/> </enum> <enum name="ExtensionIconState" type="int"> @@ -91375,6 +91380,7 @@ <int value="200" label="kClipboard"/> <int value="201" label="kNetworkingOnc"/> <int value="202" label="kVirtualKeyboard"/> + <int value="203" label="kNetworkingCastPrivate"/> </enum> <enum name="ExtensionServiceVerifyAllSuccess" type="int"> @@ -94304,6 +94310,7 @@ <int value="4" label="File could not be memory-mapped by system."/> <int value="5" label="File has invalid contents."/> <int value="6" label="File could not be exclusively opened."/> + <int value="7" label="File contents internally deleted."/> </enum> <enum name="FileReaderSyncWorkerType" type="int"> @@ -109504,6 +109511,9 @@ The credentials are being transfered to a new profile, so the old one is signed out. </int> + <int value="7" label="Authentication failed with force signin"> + Signed out because credentials are invalid and force-sign-in is enabled. + </int> </enum> <enum name="SigninSource" type="int">
diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc index f338a950..340e1263 100644 --- a/ui/base/accelerators/accelerator.cc +++ b/ui/base/accelerators/accelerator.cc
@@ -27,33 +27,33 @@ namespace { -const int kModifierMask = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | - ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN; +const int kModifierMask = + EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN | EF_COMMAND_DOWN; const int kInterestingFlagsMask = - kModifierMask | ui::EF_IS_SYNTHESIZED | ui::EF_IS_REPEAT; + kModifierMask | EF_IS_SYNTHESIZED | EF_IS_REPEAT; } // namespace -Accelerator::Accelerator() - : key_code_(ui::VKEY_UNKNOWN), type_(ui::ET_KEY_PRESSED), modifiers_(0) {} +Accelerator::Accelerator() : Accelerator(VKEY_UNKNOWN, EF_NONE) {} -Accelerator::Accelerator(KeyboardCode keycode, int modifiers) - : key_code_(keycode), - type_(ui::ET_KEY_PRESSED), +Accelerator::Accelerator(KeyboardCode key_code, int modifiers) + : key_code_(key_code), + key_state_(KeyState::PRESSED), modifiers_(modifiers & kInterestingFlagsMask) {} Accelerator::Accelerator(const KeyEvent& key_event) : key_code_(key_event.key_code()), - type_(key_event.type()), + key_state_(key_event.type() == ET_KEY_PRESSED ? KeyState::PRESSED + : KeyState::RELEASED), // |modifiers_| may include the repeat flag. modifiers_(key_event.flags() & kInterestingFlagsMask) {} Accelerator::Accelerator(const Accelerator& accelerator) { key_code_ = accelerator.key_code_; - type_ = accelerator.type_; + key_state_ = accelerator.key_state_; modifiers_ = accelerator.modifiers_; - if (accelerator.platform_accelerator_.get()) + if (accelerator.platform_accelerator_) platform_accelerator_ = accelerator.platform_accelerator_->CreateCopy(); } @@ -68,9 +68,9 @@ Accelerator& Accelerator::operator=(const Accelerator& accelerator) { if (this != &accelerator) { key_code_ = accelerator.key_code_; - type_ = accelerator.type_; + key_state_ = accelerator.key_state_; modifiers_ = accelerator.modifiers_; - if (accelerator.platform_accelerator_.get()) + if (accelerator.platform_accelerator_) platform_accelerator_ = accelerator.platform_accelerator_->CreateCopy(); else platform_accelerator_.reset(); @@ -81,14 +81,16 @@ bool Accelerator::operator <(const Accelerator& rhs) const { if (key_code_ != rhs.key_code_) return key_code_ < rhs.key_code_; - if (type_ != rhs.type_) - return type_ < rhs.type_; + if (key_state_ != rhs.key_state_) { + return static_cast<int32_t>(key_state_) < + static_cast<int32_t>(rhs.key_state_); + } return MaskOutKeyEventFlags(modifiers_) < MaskOutKeyEventFlags(rhs.modifiers_); } bool Accelerator::operator ==(const Accelerator& rhs) const { - if ((key_code_ == rhs.key_code_) && (type_ == rhs.type_) && + if ((key_code_ == rhs.key_code_) && (key_state_ == rhs.key_state_) && (MaskOutKeyEventFlags(modifiers_) == MaskOutKeyEventFlags(rhs.modifiers_))) return true; @@ -127,73 +129,73 @@ base::string16 Accelerator::GetShortcutText() const { int string_id = 0; switch (key_code_) { - case ui::VKEY_TAB: + case VKEY_TAB: string_id = IDS_APP_TAB_KEY; break; - case ui::VKEY_RETURN: + case VKEY_RETURN: string_id = IDS_APP_ENTER_KEY; break; - case ui::VKEY_ESCAPE: + case VKEY_ESCAPE: string_id = IDS_APP_ESC_KEY; break; - case ui::VKEY_SPACE: + case VKEY_SPACE: string_id = IDS_APP_SPACE_KEY; break; - case ui::VKEY_PRIOR: + case VKEY_PRIOR: string_id = IDS_APP_PAGEUP_KEY; break; - case ui::VKEY_NEXT: + case VKEY_NEXT: string_id = IDS_APP_PAGEDOWN_KEY; break; - case ui::VKEY_END: + case VKEY_END: string_id = IDS_APP_END_KEY; break; - case ui::VKEY_HOME: + case VKEY_HOME: string_id = IDS_APP_HOME_KEY; break; - case ui::VKEY_INSERT: + case VKEY_INSERT: string_id = IDS_APP_INSERT_KEY; break; - case ui::VKEY_DELETE: + case VKEY_DELETE: string_id = IDS_APP_DELETE_KEY; break; - case ui::VKEY_LEFT: + case VKEY_LEFT: string_id = IDS_APP_LEFT_ARROW_KEY; break; - case ui::VKEY_RIGHT: + case VKEY_RIGHT: string_id = IDS_APP_RIGHT_ARROW_KEY; break; - case ui::VKEY_UP: + case VKEY_UP: string_id = IDS_APP_UP_ARROW_KEY; break; - case ui::VKEY_DOWN: + case VKEY_DOWN: string_id = IDS_APP_DOWN_ARROW_KEY; break; - case ui::VKEY_BACK: + case VKEY_BACK: string_id = IDS_APP_BACKSPACE_KEY; break; - case ui::VKEY_F1: + case VKEY_F1: string_id = IDS_APP_F1_KEY; break; - case ui::VKEY_F11: + case VKEY_F11: string_id = IDS_APP_F11_KEY; break; - case ui::VKEY_OEM_COMMA: + case VKEY_OEM_COMMA: string_id = IDS_APP_COMMA_KEY; break; - case ui::VKEY_OEM_PERIOD: + case VKEY_OEM_PERIOD: string_id = IDS_APP_PERIOD_KEY; break; - case ui::VKEY_MEDIA_NEXT_TRACK: + case VKEY_MEDIA_NEXT_TRACK: string_id = IDS_APP_MEDIA_NEXT_TRACK_KEY; break; - case ui::VKEY_MEDIA_PLAY_PAUSE: + case VKEY_MEDIA_PLAY_PAUSE: string_id = IDS_APP_MEDIA_PLAY_PAUSE_KEY; break; - case ui::VKEY_MEDIA_PREV_TRACK: + case VKEY_MEDIA_PREV_TRACK: string_id = IDS_APP_MEDIA_PREV_TRACK_KEY; break; - case ui::VKEY_MEDIA_STOP: + case VKEY_MEDIA_STOP: string_id = IDS_APP_MEDIA_STOP_KEY; break; default:
diff --git a/ui/base/accelerators/accelerator.h b/ui/base/accelerators/accelerator.h index 7941f33..4363198a 100644 --- a/ui/base/accelerators/accelerator.h +++ b/ui/base/accelerators/accelerator.h
@@ -35,9 +35,14 @@ // repeat flag in its comparison. class UI_BASE_EXPORT Accelerator { public: + enum class KeyState { + PRESSED, + RELEASED, + }; + Accelerator(); // NOTE: this constructor strips out non key related flags. - Accelerator(ui::KeyboardCode keycode, int modifiers); + Accelerator(KeyboardCode key_code, int modifiers); explicit Accelerator(const KeyEvent& key_event); Accelerator(const Accelerator& accelerator); ~Accelerator(); @@ -56,12 +61,11 @@ bool operator !=(const Accelerator& rhs) const; - ui::KeyboardCode key_code() const { return key_code_; } + KeyboardCode key_code() const { return key_code_; } - // Sets the event type if the accelerator should be processed on an event - // other than ui::ET_KEY_PRESSED. - void set_type(ui::EventType type) { type_ = type; } - ui::EventType type() const { return type_; } + // Sets the key state that triggers the accelerator. Default is PRESSED. + void set_key_state(KeyState state) { key_state_ = state; } + KeyState key_state() const { return key_state_; } int modifiers() const { return modifiers_; } @@ -87,8 +91,7 @@ // The keycode (VK_...). KeyboardCode key_code_; - // The event type (usually ui::ET_KEY_PRESSED). - EventType type_; + KeyState key_state_; // The state of the Shift/Ctrl/Alt keys. This corresponds to Event::flags(). int modifiers_; @@ -120,9 +123,8 @@ public: // Gets the accelerator for the specified command id. Returns true if the // command id has a valid accelerator, false otherwise. - virtual bool GetAcceleratorForCommandId( - int command_id, - ui::Accelerator* accelerator) const = 0; + virtual bool GetAcceleratorForCommandId(int command_id, + Accelerator* accelerator) const = 0; protected: virtual ~AcceleratorProvider() {}
diff --git a/ui/base/accelerators/accelerator_manager_unittest.cc b/ui/base/accelerators/accelerator_manager_unittest.cc index 50e8841..3cca7da 100644 --- a/ui/base/accelerators/accelerator_manager_unittest.cc +++ b/ui/base/accelerators/accelerator_manager_unittest.cc
@@ -247,9 +247,7 @@ EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << i; // The non-registered accelerators are not processed. - accelerator.set_type(ET_UNKNOWN); - EXPECT_FALSE(manager_.Process(accelerator)) << i; // different type - accelerator.set_type(ET_KEY_RELEASED); + accelerator.set_key_state(Accelerator::KeyState::RELEASED); EXPECT_FALSE(manager_.Process(accelerator)) << i; // different type EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_UNKNOWN, modifiers)))
diff --git a/ui/content_accelerators/accelerator_util.cc b/ui/content_accelerators/accelerator_util.cc index 4e9d0b4..b2924a26 100644 --- a/ui/content_accelerators/accelerator_util.cc +++ b/ui/content_accelerators/accelerator_util.cc
@@ -41,7 +41,7 @@ static_cast<ui::KeyboardCode>(event.windowsKeyCode), GetModifiersFromNativeWebKeyboardEvent(event)); if (event.type() == blink::WebInputEvent::KeyUp) - accelerator.set_type(ui::ET_KEY_RELEASED); + accelerator.set_key_state(Accelerator::KeyState::RELEASED); return accelerator; }
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp index 2ff25d7..15c5727 100644 --- a/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp +++ b/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp
@@ -5,10 +5,24 @@ 'targets': [ # { # 'target_name': 'actions_controller', +# 'dependencies': [ +# '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', +# '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', +# '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui', +# '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:context_menu_handler', +# 'actions_model', +# ], # 'includes': ['../../../compile_js2.gypi'], # }, # { # 'target_name': 'actions_model', +# 'dependencies': [ +# '../../background/js/compiled_resources2.gyp:drive_sync_handler', +# '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', +# '<(EXTERNS_GYP):file_manager_private', +# 'folder_shortcuts_data_model', +# 'metadata/compiled_resources2.gyp:metadata_model', +# ], # 'includes': ['../../../compile_js2.gypi'], # }, # { @@ -61,6 +75,12 @@ # }, # { # 'target_name': 'file_selection', +# 'dependencies': [ +# '../../common/js/compiled_resources2.gyp:util', +# '../../common/js/compiled_resources2.gyp:volume_manager_common', +# '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', +# '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', +# ], # 'includes': ['../../../compile_js2.gypi'], # }, # { @@ -75,10 +95,18 @@ # 'target_name': 'file_watcher', # 'includes': ['../../../compile_js2.gypi'], # }, -# { -# 'target_name': 'folder_shortcuts_data_model', -# 'includes': ['../../../compile_js2.gypi'], -# }, + { + 'target_name': 'folder_shortcuts_data_model', + 'dependencies': [ + '../../common/js/compiled_resources2.gyp:async_util', + '../../common/js/compiled_resources2.gyp:metrics', + '../../common/js/compiled_resources2.gyp:util', + '../../common/js/compiled_resources2.gyp:volume_manager_common', + '<(EXTERNS_GYP):chrome_extensions', + 'volume_manager_wrapper', + ], + 'includes': ['../../../compile_js2.gypi'], + }, # { # 'target_name': 'gear_menu_controller', # 'includes': ['../../../compile_js2.gypi'], @@ -206,6 +234,12 @@ }, # { # 'target_name': 'toolbar_controller', +# 'dependencies': [ +# '../../common/js/compiled_resources2.gyp:util', +# 'file_selection', +# 'ui/compiled_resources2.gyp:list_container', +# 'ui/compiled_resources2.gyp:location_line', +# ], # 'includes': ['../../../compile_js2.gypi'], # }, {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp b/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp index 12aee82..f42d42d 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp +++ b/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
@@ -101,14 +101,21 @@ # 'target_name': 'gear_menu', # 'includes': ['../../../../compile_js2.gypi'], # }, -# { -# 'target_name': 'list_container', -# 'includes': ['../../../../compile_js2.gypi'], -# }, -# { -# 'target_name': 'location_line', -# 'includes': ['../../../../compile_js2.gypi'], -# }, + { + 'target_name': 'list_container', + 'includes': ['../../../../compile_js2.gypi'], + }, + { + 'target_name': 'location_line', + 'dependencies': [ + '../../../../externs/compiled_resources2.gyp:platform', + '../../../../externs/compiled_resources2.gyp:volume_manager', + '../../../common/js/compiled_resources2.gyp:util', + '../../../common/js/compiled_resources2.gyp:volume_manager_common', + '../compiled_resources2.gyp:volume_manager_wrapper', + ], + 'includes': ['../../../../compile_js2.gypi'], + }, # { # 'target_name': 'multi_profile_share_dialog', # 'includes': ['../../../../compile_js2.gypi'],
diff --git a/ui/gfx/render_text_mac.mm b/ui/gfx/render_text_mac.mm index 6075a0d7..eafd25a 100644 --- a/ui/gfx/render_text_mac.mm +++ b/ui/gfx/render_text_mac.mm
@@ -428,14 +428,6 @@ run->width = run_width; run->glyphs.resize(glyph_count); CTRunGetGlyphs(ct_run, empty_cf_range, &run->glyphs[0]); - // CTRunGetGlyphs() sometimes returns glyphs with value 65535 and zero - // width (this has been observed at the beginning of a string containing - // Arabic content). Passing these to Skia will trigger an assertion; - // instead set their values to 0. - for (size_t glyph = 0; glyph < glyph_count; glyph++) { - if (run->glyphs[glyph] == 65535) - run->glyphs[glyph] = 0; - } run->glyph_positions.resize(glyph_count); const CGPoint* positions_ptr = CTRunGetPositionsPtr(ct_run);
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc index 9d41e98ad..d4c7487b3 100644 --- a/ui/ozone/platform/drm/common/drm_util.cc +++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -421,8 +421,10 @@ } } -int GetFourCCFormatForFramebuffer(gfx::BufferFormat format) { - // Currently, drm supports 24 bitcolordepth for hardware overlay. +int GetFourCCFormatForOpaqueFramebuffer(gfx::BufferFormat format) { + // DRM atomic interface doesn't currently support specifying an alpha + // blending. We can simulate disabling alpha bleding creating an fb + // with a format without the alpha channel. switch (format) { case gfx::BufferFormat::RGBA_8888: case gfx::BufferFormat::RGBX_8888:
diff --git a/ui/ozone/platform/drm/common/drm_util.h b/ui/ozone/platform/drm/common/drm_util.h index 52e90fe..57f9d217 100644 --- a/ui/ozone/platform/drm/common/drm_util.h +++ b/ui/ozone/platform/drm/common/drm_util.h
@@ -66,7 +66,7 @@ int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format); gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format); -int GetFourCCFormatForFramebuffer(gfx::BufferFormat format); +int GetFourCCFormatForOpaqueFramebuffer(gfx::BufferFormat format); gfx::Size GetMaximumCursorSize(int fd);
diff --git a/ui/ozone/platform/drm/gpu/drm_buffer.cc b/ui/ozone/platform/drm/gpu/drm_buffer.cc index 17bc5d3..d511661b 100644 --- a/ui/ozone/platform/drm/gpu/drm_buffer.cc +++ b/ui/ozone/platform/drm/gpu/drm_buffer.cc
@@ -99,6 +99,14 @@ return fb_pixel_format_; } +uint32_t DrmBuffer::GetOpaqueFramebufferId() const { + return framebuffer_; +} + +uint32_t DrmBuffer::GetOpaqueFramebufferPixelFormat() const { + return fb_pixel_format_; +} + uint32_t DrmBuffer::GetHandle() const { return handle_; }
diff --git a/ui/ozone/platform/drm/gpu/drm_buffer.h b/ui/ozone/platform/drm/gpu/drm_buffer.h index a9460b49..dd162198 100644 --- a/ui/ozone/platform/drm/gpu/drm_buffer.h +++ b/ui/ozone/platform/drm/gpu/drm_buffer.h
@@ -38,6 +38,8 @@ // ScanoutBuffer: uint32_t GetFramebufferId() const override; uint32_t GetFramebufferPixelFormat() const override; + uint32_t GetOpaqueFramebufferId() const override; + uint32_t GetOpaqueFramebufferPixelFormat() const override; uint32_t GetHandle() const override; gfx::Size GetSize() const override; const DrmDevice* GetDrmDevice() const override;
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc index af00fe3..bfe65bbb 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -131,7 +131,10 @@ gfx::Size scaled_buffer_size = GetScaledSize( overlay.buffer_size, overlay.display_rect, overlay.crop_rect); - uint32_t original_format = GetFourCCFormatForFramebuffer(overlay.format); + uint32_t original_format = + overlay.plane_z_order + ? GetFourCCFormatFromBufferFormat(overlay.format) + : GetFourCCFormatForOpaqueFramebuffer(overlay.format); scoped_refptr<ScanoutBuffer> buffer = GetBufferForPageFlipTest(drm, overlay.buffer_size, original_format, buffer_generator_, &reusable_buffers);
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc index f0a69e73..3bffad6 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
@@ -122,19 +122,21 @@ ui::OverlayCheck_Params primary_candidate; primary_candidate.buffer_size = primary_rect_.size(); primary_candidate.display_rect = primary_rect_; + primary_candidate.format = gfx::BufferFormat::BGRX_8888; overlay_params_.push_back(primary_candidate); ui::OverlayCheck_Params overlay_candidate; overlay_candidate.buffer_size = overlay_rect_.size(); overlay_candidate.display_rect = overlay_rect_; overlay_candidate.plane_z_order = 1; + overlay_candidate.format = gfx::BufferFormat::BGRX_8888; overlay_params_.push_back(overlay_candidate); scoped_refptr<ui::DrmDevice> drm = window_->GetController()->GetAllocationDrmDevice(); for (const auto& param : overlay_params_) { scoped_refptr<ui::ScanoutBuffer> scanout_buffer = buffer_generator_->Create( - drm, ui::GetFourCCFormatForFramebuffer(param.format), + drm, ui::GetFourCCFormatFromBufferFormat(param.format), param.buffer_size); ui::OverlayPlane plane(std::move(scanout_buffer), param.plane_z_order, param.transform, param.display_rect, param.crop_rect,
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer_base.cc b/ui/ozone/platform/drm/gpu/gbm_buffer_base.cc index eb0b900..d36ec22 100644 --- a/ui/ozone/platform/drm/gpu/gbm_buffer_base.cc +++ b/ui/ozone/platform/drm/gpu/gbm_buffer_base.cc
@@ -21,11 +21,9 @@ : drm_(drm), bo_(bo) { if (flags & GBM_BO_USE_SCANOUT) { DCHECK(bo_); - // The framebuffer format might be different than the format: - // drm supports 24 bit color depth and formats with alpha will - // be converted to one without it. - framebuffer_pixel_format_ = - GetFourCCFormatForFramebuffer(GetBufferFormatFromFourCCFormat(format)); + framebuffer_pixel_format_ = format; + opaque_framebuffer_pixel_format_ = GetFourCCFormatForOpaqueFramebuffer( + GetBufferFormatFromFourCCFormat(format)); // TODO(dcastagna): Add multi-planar support. uint32_t handles[4] = {0}; @@ -43,6 +41,12 @@ drm_->AddFramebuffer2(gbm_bo_get_width(bo), gbm_bo_get_height(bo), framebuffer_pixel_format_, handles, strides, offsets, modifiers, &framebuffer_, addfb_flags); + if (opaque_framebuffer_pixel_format_ != framebuffer_pixel_format_) { + drm_->AddFramebuffer2(gbm_bo_get_width(bo), gbm_bo_get_height(bo), + opaque_framebuffer_pixel_format_, handles, strides, + offsets, modifiers, &opaque_framebuffer_, + addfb_flags); + } } } @@ -55,6 +59,10 @@ return framebuffer_; } +uint32_t GbmBufferBase::GetOpaqueFramebufferId() const { + return opaque_framebuffer_ ? opaque_framebuffer_ : framebuffer_; +} + uint32_t GbmBufferBase::GetHandle() const { return gbm_bo_get_handle(bo_).u32; } @@ -68,6 +76,11 @@ return framebuffer_pixel_format_; } +uint32_t GbmBufferBase::GetOpaqueFramebufferPixelFormat() const { + DCHECK(framebuffer_); + return opaque_framebuffer_pixel_format_; +} + const DrmDevice* GbmBufferBase::GetDrmDevice() const { return drm_.get(); }
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer_base.h b/ui/ozone/platform/drm/gpu/gbm_buffer_base.h index a4732c7..1aca1bb 100644 --- a/ui/ozone/platform/drm/gpu/gbm_buffer_base.h +++ b/ui/ozone/platform/drm/gpu/gbm_buffer_base.h
@@ -27,9 +27,11 @@ // ScanoutBuffer: uint32_t GetFramebufferId() const override; + uint32_t GetOpaqueFramebufferId() const override; uint32_t GetHandle() const override; gfx::Size GetSize() const override; uint32_t GetFramebufferPixelFormat() const override; + uint32_t GetOpaqueFramebufferPixelFormat() const override; const DrmDevice* GetDrmDevice() const override; bool RequiresGlFinish() const override; @@ -47,6 +49,11 @@ gbm_bo* bo_; uint32_t framebuffer_ = 0; uint32_t framebuffer_pixel_format_ = 0; + // If |opaque_framebuffer_pixel_format_| differs from + // |framebuffer_pixel_format_| the following member is set to a valid fb, + // otherwise it is set to 0. + uint32_t opaque_framebuffer_ = 0; + uint32_t opaque_framebuffer_pixel_format_ = 0; DISALLOW_COPY_AND_ASSIGN(GbmBufferBase); };
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc index e3a2b28..17bdd2a 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -95,8 +95,11 @@ CrtcController* crtc) { HardwareDisplayPlaneAtomic* atomic_plane = static_cast<HardwareDisplayPlaneAtomic*>(hw_plane); + uint32_t framebuffer_id = overlay.z_order + ? overlay.buffer->GetFramebufferId() + : overlay.buffer->GetOpaqueFramebufferId(); if (!atomic_plane->SetPlaneData(plane_list->atomic_property_set.get(), - crtc_id, overlay.buffer->GetFramebufferId(), + crtc_id, framebuffer_id, overlay.display_bounds, src_rect)) { LOG(ERROR) << "Failed to set plane properties"; return false;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc index 0c92d4aa..e412076 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -110,7 +110,7 @@ plane_list->legacy_page_flips.back().crtc_id != crtc_id) { plane_list->legacy_page_flips.push_back( HardwareDisplayPlaneList::PageFlipInfo( - crtc_id, overlay.buffer->GetFramebufferId(), crtc)); + crtc_id, overlay.buffer->GetOpaqueFramebufferId(), crtc)); } else { plane_list->legacy_page_flips.back().planes.push_back( HardwareDisplayPlaneList::PageFlipInfo::Plane(
diff --git a/ui/ozone/platform/drm/gpu/mock_scanout_buffer.cc b/ui/ozone/platform/drm/gpu/mock_scanout_buffer.cc index d372f8e..91c0082d 100644 --- a/ui/ozone/platform/drm/gpu/mock_scanout_buffer.cc +++ b/ui/ozone/platform/drm/gpu/mock_scanout_buffer.cc
@@ -15,6 +15,10 @@ return 1; } +uint32_t MockScanoutBuffer::GetOpaqueFramebufferId() const { + return 2; +} + uint32_t MockScanoutBuffer::GetHandle() const { return 0; } @@ -27,6 +31,10 @@ return format_; } +uint32_t MockScanoutBuffer::GetOpaqueFramebufferPixelFormat() const { + return format_; +} + const DrmDevice* MockScanoutBuffer::GetDrmDevice() const { return nullptr; }
diff --git a/ui/ozone/platform/drm/gpu/mock_scanout_buffer.h b/ui/ozone/platform/drm/gpu/mock_scanout_buffer.h index 71411f3..e2e9046 100644 --- a/ui/ozone/platform/drm/gpu/mock_scanout_buffer.h +++ b/ui/ozone/platform/drm/gpu/mock_scanout_buffer.h
@@ -20,9 +20,11 @@ // ScanoutBuffer: uint32_t GetFramebufferId() const override; + uint32_t GetOpaqueFramebufferId() const override; uint32_t GetHandle() const override; gfx::Size GetSize() const override; uint32_t GetFramebufferPixelFormat() const override; + uint32_t GetOpaqueFramebufferPixelFormat() const override; const DrmDevice* GetDrmDevice() const override; bool RequiresGlFinish() const override;
diff --git a/ui/ozone/platform/drm/gpu/scanout_buffer.h b/ui/ozone/platform/drm/gpu/scanout_buffer.h index 529490a..8a5cd13c 100644 --- a/ui/ozone/platform/drm/gpu/scanout_buffer.h +++ b/ui/ozone/platform/drm/gpu/scanout_buffer.h
@@ -21,11 +21,19 @@ // ID allocated by the KMS API when the buffer is registered (via the handle). virtual uint32_t GetFramebufferId() const = 0; + // ID allocated if the buffer is also registered with a different pixel format + // so that it can be scheduled as an opaque buffer. + virtual uint32_t GetOpaqueFramebufferId() const = 0; + // Returns FourCC format representing the way pixel data has been encoded in // memory for the registered framebuffer. This can be used to check if frame // buffer is compatible with a given hardware plane. virtual uint32_t GetFramebufferPixelFormat() const = 0; + // Returns FourCC format that should be used to schedule this buffer for + // scanout when used as an opaque buffer. + virtual uint32_t GetOpaqueFramebufferPixelFormat() const = 0; + // Handle for the buffer. This is received when allocating the buffer. virtual uint32_t GetHandle() const = 0;
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.cc b/ui/ozone/platform/drm/gpu/screen_manager.cc index 09e9b4257..881188e 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager.cc +++ b/ui/ozone/platform/drm/gpu/screen_manager.cc
@@ -345,7 +345,7 @@ gfx::BufferFormat format = display::DisplaySnapshot::PrimaryFormat(); scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice(); - uint32_t fourcc_format = ui::GetFourCCFormatForFramebuffer(format); + uint32_t fourcc_format = ui::GetFourCCFormatForOpaqueFramebuffer(format); scoped_refptr<ScanoutBuffer> buffer = buffer_generator_->Create(drm, fourcc_format, bounds.size()); if (!buffer) {
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 8414521..2530685 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -771,8 +771,11 @@ // This function is called by BrowserView to execute clipboard commands. bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) { - ui::KeyEvent event(accelerator.type(), accelerator.key_code(), - accelerator.modifiers()); + ui::KeyEvent event( + accelerator.key_state() == ui::Accelerator::KeyState::PRESSED + ? ui::ET_KEY_PRESSED + : ui::ET_KEY_RELEASED, + accelerator.key_code(), accelerator.modifiers()); ExecuteTextEditCommand(GetCommandForKeyEvent(event)); return true; }