diff --git a/DEPS b/DEPS index 003680d3..0998f50 100644 --- a/DEPS +++ b/DEPS
@@ -129,11 +129,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': '1208002548e8ce4b0f4f61ddebd200562ce64470', + 'skia_revision': '99d792276740293109edb22a26fea50490e7eeaf', # 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': '790137c150aceab523179662ca3534b5050ef81b', + 'v8_revision': '0ec288d449bc14033c44dd5d0bbcd3f6d64ec9f1', # 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. @@ -141,7 +141,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '76a9a97fb2a19a325ef90c10900718bfbdb4b1d3', + 'angle_revision': 'e6b23e45b380bee1a2dfda06e4728d24d4d4ad8b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -149,7 +149,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '44034bca7d3eda87b7e7f38d9cf695fde9a312dd', + 'pdfium_revision': '9cf260b9d7f4491833bd5fd997a286ce6926678e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -196,7 +196,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'f8d4d2df537739c5f101da3d702b0a8ff6537909', + 'catapult_revision': 'dc0c991440dbeb33c04e4ad9f52e22c173817abd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -268,7 +268,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'b4b3ea05ebde1a1bb6372f8506cd762d040d7978', + 'dawn_revision': 'f4c3f4562eeeaeab99a19d4a293d062936c5a2ee', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -475,7 +475,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '2cacdff921fb067d93cf476a10f7decb1a9fb766', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '82cfc2ceebd3d1bfbaf6b5129d08f2b1f4054508', 'condition': 'checkout_ios', }, @@ -490,7 +490,7 @@ }, 'src/ios/third_party/material_roboto_font_loader_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-roboto-font-loader-ios.git' + '@' + '4aa51e906e5671c71d24e991f1f10d782a58409f', + 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-roboto-font-loader-ios.git' + '@' + 'bc63eabbbd1e14cee0779b05827e08db2e413553', 'condition': 'checkout_ios', }, @@ -805,7 +805,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c62d4b70f2c79cd0a5720d81570bcb0324070cd2', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f21ce663029c3172c162dae0a199f5be5a0c9991', 'condition': 'checkout_linux', }, @@ -830,7 +830,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '77b3499b880955840580bffbb167124c9ff83b6b', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6379cd39a3336ab8716c77b1c68ab37ff406d060', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1172,7 +1172,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '73904e05a2db53359bff5514130a9e16ac886bfe', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '911b1a37708e3ded201d9664602f9670a0acb572', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index dcba1f5..e8bf5f2 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -66,6 +66,7 @@ "system/unified/unified_system_tray.h", "touch/touch_observer_hud.h", "wm/client_controlled_state.h", + "wm/desks/desks_util.h", "wm/drag_window_resizer.h", "wm/mru_window_tracker.h", "wm/overview/overview_controller.h",
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index e3abe52..4c60aa9 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -1089,9 +1089,11 @@ return deprecated_accelerators_.count(accelerator) != 0; } -bool AcceleratorController::PerformActionIfEnabled(AcceleratorAction action) { - if (CanPerformAction(action, ui::Accelerator())) { - PerformAction(action, ui::Accelerator()); +bool AcceleratorController::PerformActionIfEnabled( + AcceleratorAction action, + const ui::Accelerator& accelerator) { + if (CanPerformAction(action, accelerator)) { + PerformAction(action, accelerator); return true; } return false; @@ -1407,6 +1409,12 @@ if (restriction != RESTRICTION_NONE) return; + // TODO(minch): For VOLUME_DOWN and VOLUME_UP. Do the calculation based on + // accelerator.source_device_id() and + // ui::InputDeviceManager::GetInstance()->GetOtherInputDevices() to see + // whether we need to flip its action on current screen orientation for side + // volume button. http://crbug.com/937907. + // If your accelerator invokes more than one line of code, please either // implement it in your module's controller code or pull it into a HandleFoo() // function above.
diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h index 7b74911..40ea43a1 100644 --- a/ash/accelerators/accelerator_controller.h +++ b/ash/accelerators/accelerator_controller.h
@@ -105,7 +105,9 @@ // Performs the specified action if it is enabled. Returns whether the action // was performed successfully. - bool PerformActionIfEnabled(AcceleratorAction action); + bool PerformActionIfEnabled( + AcceleratorAction action, + const ui::Accelerator& accelerator = ui::Accelerator()); // Returns the restriction for the current context. AcceleratorProcessingRestriction GetCurrentAcceleratorRestriction();
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 40bfb7a..8bbf6044 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -760,6 +760,11 @@ return app_list::AppListViewState::CLOSED; } +void AppListControllerImpl::SetStateTransitionAnimationCallback( + StateTransitionAnimationCallback callback) { + state_transition_animation_callback_ = std::move(callback); +} + void AppListControllerImpl::SetAppListModelForTest( std::unique_ptr<app_list::AppListModel> model) { model_->RemoveObserver(this); @@ -1025,6 +1030,12 @@ mojom::VoiceInteractionState::NOT_READY; } +void AppListControllerImpl::OnStateTransitionAnimationCompleted( + app_list::AppListViewState state) { + if (!state_transition_animation_callback_.is_null()) + state_transition_animation_callback_.Run(state); +} + void AppListControllerImpl::AddObserver(AppListControllerObserver* observer) { observers_.AddObserver(observer); }
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index 5d8dd12..c60cb726 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -200,6 +200,8 @@ void OnSearchResultVisibilityChanged(const std::string& id, bool visibility) override; bool IsAssistantAllowedAndEnabled() const override; + void OnStateTransitionAnimationCompleted( + app_list::AppListViewState state) override; void AddObserver(AppListControllerObserver* observer); void RemoveObserver(AppListControllerObserver* obsever); @@ -286,6 +288,12 @@ void SetAppListModelForTest(std::unique_ptr<app_list::AppListModel> model); + using StateTransitionAnimationCallback = + base::RepeatingCallback<void(app_list::AppListViewState)>; + + void SetStateTransitionAnimationCallback( + StateTransitionAnimationCallback callback); + private: syncer::StringOrdinal GetOemFolderPos(); std::unique_ptr<app_list::AppListItem> CreateAppListItem( @@ -336,6 +344,8 @@ // each profile has its own AppListModelUpdater to manipulate app list items. int profile_id_ = kAppListInvalidProfileID; + StateTransitionAnimationCallback state_transition_animation_callback_; + base::ObserverList<AppListControllerObserver> observers_; DISALLOW_COPY_AND_ASSIGN(AppListControllerImpl);
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index 0ac383a..ac9f3cf0 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -9,6 +9,7 @@ #include <vector> #include "ash/app_list/app_list_metrics.h" +#include "ash/app_list/model/app_list_view_state.h" #include "ash/assistant/ui/assistant_view_delegate.h" #include "ash/public/cpp/ash_public_export.h" #include "ash/public/interfaces/app_list.mojom.h" @@ -167,6 +168,9 @@ // Returns if the Assistant feature is allowed and enabled. virtual bool IsAssistantAllowedAndEnabled() const = 0; + + // Called when the app list view animation is completed. + virtual void OnStateTransitionAnimationCompleted(AppListViewState state) = 0; }; } // namespace app_list
diff --git a/ash/app_list/test/app_list_test_view_delegate.cc b/ash/app_list/test/app_list_test_view_delegate.cc index 7539368..d4bb588 100644 --- a/ash/app_list/test/app_list_test_view_delegate.cc +++ b/ash/app_list/test/app_list_test_view_delegate.cc
@@ -137,6 +137,9 @@ return false; } +void AppListTestViewDelegate::OnStateTransitionAnimationCompleted( + AppListViewState state) {} + bool AppListTestViewDelegate::IsCommandIdChecked(int command_id) const { return true; }
diff --git a/ash/app_list/test/app_list_test_view_delegate.h b/ash/app_list/test/app_list_test_view_delegate.h index 597fe5f..c11ed62e 100644 --- a/ash/app_list/test/app_list_test_view_delegate.h +++ b/ash/app_list/test/app_list_test_view_delegate.h
@@ -101,6 +101,7 @@ void OnSearchResultVisibilityChanged(const std::string& id, bool visibility) override; bool IsAssistantAllowedAndEnabled() const override; + void OnStateTransitionAnimationCompleted(AppListViewState state) override; // Do a bulk replacement of the items in the model. void ReplaceTestModel(int item_count);
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index a7aac57..59836967 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -188,7 +188,8 @@ class AppListView::StateAnimationMetricsReporter : public ui::AnimationMetricsReporter { public: - StateAnimationMetricsReporter() = default; + explicit StateAnimationMetricsReporter(AppListView* view) : view_(view) {} + ~StateAnimationMetricsReporter() override = default; void Start(bool is_in_tablet_mode) { @@ -209,6 +210,7 @@ UMA_HISTOGRAM_PERCENTAGE( "Apps.StateTransition.AnimationSmoothness.ClamshellMode", value); } + view_->OnStateTransitionAnimationCompleted(); #if defined(DCHECK) started_ = false; #endif @@ -219,6 +221,7 @@ bool started_ = false; #endif bool is_in_tablet_mode_ = false; + AppListView* view_; DISALLOW_COPY_AND_ASSIGN(StateAnimationMetricsReporter); }; @@ -323,7 +326,9 @@ //////////////////////////////////////////////////////////////////////////////// // AppListView::TestApi -AppListView::TestApi::TestApi(AppListView* view) : view_(view) {} +AppListView::TestApi::TestApi(AppListView* view) : view_(view) { + DCHECK(view_); +} AppListView::TestApi::~TestApi() = default; @@ -344,7 +349,7 @@ transition_animation_observer_( std::make_unique<TransitionAnimationObserver>(this)), state_animation_metrics_reporter_( - std::make_unique<StateAnimationMetricsReporter>()), + std::make_unique<StateAnimationMetricsReporter>(this)), weak_ptr_factory_(this) { CHECK(delegate); } @@ -1842,4 +1847,8 @@ app_list_background_shield_->SetTransform(transform); } +void AppListView::OnStateTransitionAnimationCompleted() { + delegate_->OnStateTransitionAnimationCompleted(app_list_state_); +} + } // namespace app_list
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index 05151e1f..d93b9e6 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -255,6 +255,9 @@ const gfx::Rect& new_bounds, ui::PropertyChangeReason reason) override; + // Called when state transition animation is completed. + void OnStateTransitionAnimationCompleted(); + views::Widget* get_fullscreen_widget_for_test() const { return fullscreen_widget_; }
diff --git a/ash/assistant/assistant_screen_context_controller_unittest.cc b/ash/assistant/assistant_screen_context_controller_unittest.cc index 41d62b17..4f05369 100644 --- a/ash/assistant/assistant_screen_context_controller_unittest.cc +++ b/ash/assistant/assistant_screen_context_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "base/bind.h" #include "base/macros.h" #include "base/test/scoped_feature_list.h" @@ -69,9 +70,9 @@ // Verify that incognito windows are blocked in screenshot. TEST_F(AssistantScreenContextControllerTest, Screenshot) { std::unique_ptr<aura::Window> window1 = CreateToplevelTestWindow( - gfx::Rect(0, 0, 200, 200), kShellWindowId_DefaultContainer); + gfx::Rect(0, 0, 200, 200), desks_util::GetActiveDeskContainerId()); std::unique_ptr<aura::Window> window2 = CreateToplevelTestWindow( - gfx::Rect(30, 30, 100, 100), kShellWindowId_DefaultContainer); + gfx::Rect(30, 30, 100, 100), desks_util::GetActiveDeskContainerId()); ui::Layer* window1_layer = window1->layer(); ui::Layer* window2_layer = window2->layer();
diff --git a/ash/custom_tab/arc_custom_tab_view.cc b/ash/custom_tab/arc_custom_tab_view.cc index c22934b7..6b066c2 100644 --- a/ash/custom_tab/arc_custom_tab_view.cc +++ b/ash/custom_tab/arc_custom_tab_view.cc
@@ -72,7 +72,7 @@ return nullptr; } auto* parent = widget->widget_delegate()->GetContentsView(); - auto* view = new ArcCustomTabView(surface_id, top_margin); + auto* view = new ArcCustomTabView(arc_app_window, surface_id, top_margin); parent->AddChildView(view); parent->SetLayoutManager(std::make_unique<views::FillLayout>()); parent->Layout(); @@ -118,17 +118,32 @@ window->parent()->StackChildAtTop(window); } -ArcCustomTabView::ArcCustomTabView(int32_t surface_id, int32_t top_margin) +void ArcCustomTabView::OnWindowHierarchyChanged( + const HierarchyChangeParams& params) { + auto* surface = exo::Surface::AsSurface(params.target); + if (surface && surface->GetClientSurfaceId() == surface_id_ && + params.new_parent != nullptr) { + Layout(); + } +} + +ArcCustomTabView::ArcCustomTabView(aura::Window* arc_app_window, + int32_t surface_id, + int32_t top_margin) : binding_(this), remote_view_host_(new ws::ServerRemoteViewHost( ash::Shell::Get()->window_service_owner()->window_service())), + arc_app_window_(arc_app_window), surface_id_(surface_id), top_margin_(top_margin), weak_ptr_factory_(this) { AddChildView(remote_view_host_); + arc_app_window_->AddObserver(this); } -ArcCustomTabView::~ArcCustomTabView() = default; +ArcCustomTabView::~ArcCustomTabView() { + arc_app_window_->RemoveObserver(this); +} void ArcCustomTabView::Bind(mojom::ArcCustomTabViewPtr* ptr) { binding_.Bind(mojo::MakeRequest(ptr));
diff --git a/ash/custom_tab/arc_custom_tab_view.h b/ash/custom_tab/arc_custom_tab_view.h index 84d2b7f..f43fcff 100644 --- a/ash/custom_tab/arc_custom_tab_view.h +++ b/ash/custom_tab/arc_custom_tab_view.h
@@ -11,12 +11,15 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/ws/remote_view_host/server_remote_view_host.h" +#include "ui/aura/window_observer.h" #include "ui/views/view.h" namespace ash { // Implementation of ArcCustomTabView interface. -class ArcCustomTabView : public views::View, public mojom::ArcCustomTabView { +class ArcCustomTabView : public views::View, + public mojom::ArcCustomTabView, + public aura::WindowObserver { public: // Creates a new ArcCustomTabView instance. The instance will be deleted when // the pointer is closed. Returns null when the arguments are invalid. @@ -30,8 +33,13 @@ // views::View: void Layout() override; + // aura::WindowObserver: + void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override; + private: - ArcCustomTabView(int32_t surface_id, int32_t top_margin); + ArcCustomTabView(aura::Window* arc_app_window, + int32_t surface_id, + int32_t top_margin); ~ArcCustomTabView() override; // Binds this instance to the pointer. @@ -45,6 +53,7 @@ mojo::Binding<mojom::ArcCustomTabView> binding_; ws::ServerRemoteViewHost* remote_view_host_; + aura::Window* arc_app_window_; int32_t surface_id_, top_margin_; base::WeakPtrFactory<ArcCustomTabView> weak_ptr_factory_;
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc index db6a80a..be43f19 100644 --- a/ash/extended_desktop_unittest.cc +++ b/ash/extended_desktop_unittest.cc
@@ -10,6 +10,7 @@ #include "ash/system/unified/unified_system_tray.h" #include "ash/test/ash_test_base.h" #include "ash/window_factory.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/root_window_finder.h" #include "ash/wm/window_properties.h" #include "ash/wm/window_util.h" @@ -603,19 +604,21 @@ wm::ActivateWindow(w1); // |w1_t1| is a transient child window of |w1|. std::unique_ptr<aura::Window> w1_t1 = CreateChildWindow( - w1, gfx::Rect(50, 50, 50, 50), kShellWindowId_DefaultContainer); + w1, gfx::Rect(50, 50, 50, 50), desks_util::GetActiveDeskContainerId()); ::wm::AddTransientChild(w1, w1_t1.get()); // |w1_t11| is a transient child window of transient child window |w1_t1|. - std::unique_ptr<aura::Window> w1_t11 = CreateChildWindow( - w1_t1.get(), gfx::Rect(2, 7, 35, 35), kShellWindowId_DefaultContainer); + std::unique_ptr<aura::Window> w1_t11 = + CreateChildWindow(w1_t1.get(), gfx::Rect(2, 7, 35, 35), + desks_util::GetActiveDeskContainerId()); ::wm::AddTransientChild(w1_t1.get(), w1_t11.get()); // |w11| is a non-transient child window of |w1|. std::unique_ptr<aura::Window> w11 = CreateChildWindow( - w1, gfx::Rect(10, 10, 40, 40), kShellWindowId_DefaultContainer); + w1, gfx::Rect(10, 10, 40, 40), desks_util::GetActiveDeskContainerId()); // |w11_t1| is a transient child window of |w11|. - std::unique_ptr<aura::Window> w11_t1 = CreateChildWindow( - w11.get(), gfx::Rect(30, 10, 80, 80), kShellWindowId_DefaultContainer); + std::unique_ptr<aura::Window> w11_t1 = + CreateChildWindow(w11.get(), gfx::Rect(30, 10, 80, 80), + desks_util::GetActiveDeskContainerId()); ::wm::AddTransientChild(w11.get(), w11_t1.get()); EXPECT_EQ(root_windows[0], w1->GetRootWindow());
diff --git a/ash/first_run/desktop_cleaner.cc b/ash/first_run/desktop_cleaner.cc index 0d54d33..cec78c9 100644 --- a/ash/first_run/desktop_cleaner.cc +++ b/ash/first_run/desktop_cleaner.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "base/stl_util.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" @@ -19,12 +20,20 @@ namespace ash { namespace { -const int kContainerIdsToHide[] = { - kShellWindowId_DefaultContainer, kShellWindowId_AlwaysOnTopContainer, - // TODO(dzhioev): uncomment this when issue with BrowserView::CanActivate - // will be fixed. - // kShellWindowId_SystemModalContainer -}; +std::vector<int> GetContainerIdsToHide() { + return std::vector<int>{ + // Hide the active desk container. The inactive ones are already hidden. + // TODO(afakhry): Define the behavior of Virtual Desks during the first + // run tutorial whether it should be disabled or locked to the currently + // active desk. + desks_util::GetActiveDeskContainerId(), + + kShellWindowId_AlwaysOnTopContainer, + // TODO(dzhioev): uncomment this when issue with BrowserView::CanActivate + // will be fixed. + // kShellWindowId_SystemModalContainer + }; +} } // namespace @@ -94,9 +103,8 @@ DesktopCleaner::DesktopCleaner() { // TODO(dzhioev): Add support for secondary displays. aura::Window* root_window = Shell::Get()->GetPrimaryRootWindow(); - for (size_t i = 0; i < base::size(kContainerIdsToHide); ++i) { - aura::Window* container = - Shell::GetContainer(root_window, kContainerIdsToHide[i]); + for (int id : GetContainerIdsToHide()) { + aura::Window* container = Shell::GetContainer(root_window, id); container_hiders_.push_back(std::make_unique<ContainerHider>(container)); } notification_blocker_.reset(new NotificationBlocker()); @@ -106,9 +114,7 @@ // static std::vector<int> DesktopCleaner::GetContainersToHideForTest() { - return std::vector<int>( - kContainerIdsToHide, - kContainerIdsToHide + base::size(kContainerIdsToHide)); + return GetContainerIdsToHide(); } } // namespace ash
diff --git a/ash/frame/default_frame_header_unittest.cc b/ash/frame/default_frame_header_unittest.cc index ef9b652..6a374906f 100644 --- a/ash/frame/default_frame_header_unittest.cc +++ b/ash/frame/default_frame_header_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "base/i18n/rtl.h" #include "base/test/icu_test_util.h" #include "ui/aura/window.h" @@ -30,7 +31,7 @@ // Ensure the title text is vertically aligned with the window icon. TEST_F(DefaultFrameHeaderTest, TitleIconAlignment) { std::unique_ptr<Widget> widget = CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(1, 2, 3, 4)); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(1, 2, 3, 4)); FrameCaptionButtonContainerView container(widget.get(), nullptr); views::StaticSizedView window_icon(gfx::Size(16, 16)); window_icon.SetBounds(0, 0, 16, 16); @@ -48,7 +49,7 @@ TEST_F(DefaultFrameHeaderTest, BackButtonAlignment) { std::unique_ptr<Widget> widget = CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(1, 2, 3, 4)); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(1, 2, 3, 4)); FrameCaptionButtonContainerView container(widget.get(), nullptr); FrameBackButton back; @@ -66,7 +67,7 @@ TEST_F(DefaultFrameHeaderTest, MinimumHeaderWidthRTL) { base::test::ScopedRestoreICUDefaultLocale restore_locale; std::unique_ptr<Widget> widget = CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(1, 2, 3, 4)); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(1, 2, 3, 4)); FrameCaptionButtonContainerView container(widget.get(), nullptr); DefaultFrameHeader frame_header( @@ -82,7 +83,7 @@ // Ensure the right frame colors are used. TEST_F(DefaultFrameHeaderTest, FrameColors) { std::unique_ptr<Widget> widget = CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(1, 2, 3, 4)); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(1, 2, 3, 4)); FrameCaptionButtonContainerView container(widget.get(), nullptr); views::StaticSizedView window_icon(gfx::Size(16, 16)); window_icon.SetBounds(0, 0, 16, 16);
diff --git a/ash/frame/non_client_frame_view_ash_unittest.cc b/ash/frame/non_client_frame_view_ash_unittest.cc index 7315a6b..070d315 100644 --- a/ash/frame/non_client_frame_view_ash_unittest.cc +++ b/ash/frame/non_client_frame_view_ash_unittest.cc
@@ -19,6 +19,7 @@ #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" @@ -404,8 +405,9 @@ TEST_F(NonClientFrameViewAshTest, HeaderVisibilityInOverviewMode) { auto* delegate = new NonClientFrameViewAshTestWidgetDelegate(); - std::unique_ptr<views::Widget> widget = CreateTestWidget( - delegate, kShellWindowId_DefaultContainer, gfx::Rect(0, 0, 400, 500)); + std::unique_ptr<views::Widget> widget = + CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(), + gfx::Rect(0, 0, 400, 500)); // Verify the header is not painted in overview mode and painted when not in // overview mode. @@ -513,8 +515,9 @@ TestButtonModel* model_ptr = model.get(); auto* delegate = new NonClientFrameViewAshTestWidgetDelegate(); - std::unique_ptr<views::Widget> widget = CreateTestWidget( - delegate, kShellWindowId_DefaultContainer, gfx::Rect(0, 0, 400, 500)); + std::unique_ptr<views::Widget> widget = + CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(), + gfx::Rect(0, 0, 400, 500)); ui::Accelerator accelerator_back_press(ui::VKEY_BROWSER_BACK, ui::EF_NONE); accelerator_back_press.set_key_state(ui::Accelerator::KeyState::PRESSED); @@ -572,7 +575,7 @@ new NonClientFrameViewAshTestWidgetDelegate; gfx::Rect window_bounds(10, 10, 200, 100); std::unique_ptr<views::Widget> widget = CreateTestWidget( - delegate, kShellWindowId_DefaultContainer, window_bounds); + delegate, desks_util::GetActiveDeskContainerId(), window_bounds); // The height is smaller by the top border height. gfx::Size client_bounds(200, 68); @@ -677,8 +680,9 @@ TEST_F(NonClientFrameViewAshTest, WideFrame) { auto* delegate = new NonClientFrameViewAshTestWidgetDelegate(); - std::unique_ptr<views::Widget> widget = CreateTestWidget( - delegate, kShellWindowId_DefaultContainer, gfx::Rect(100, 0, 400, 500)); + std::unique_ptr<views::Widget> widget = + CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(), + gfx::Rect(100, 0, 400, 500)); NonClientFrameViewAsh* non_client_frame_view = delegate->non_client_frame_view(); @@ -758,8 +762,9 @@ TEST_F(NonClientFrameViewAshTest, WideFrameButton) { auto* delegate = new NonClientFrameViewAshTestWidgetDelegate(); - std::unique_ptr<views::Widget> widget = CreateTestWidget( - delegate, kShellWindowId_DefaultContainer, gfx::Rect(100, 0, 400, 500)); + std::unique_ptr<views::Widget> widget = + CreateTestWidget(delegate, desks_util::GetActiveDeskContainerId(), + gfx::Rect(100, 0, 400, 500)); std::unique_ptr<WideFrameView> wide_frame_view = std::make_unique<WideFrameView>(widget.get());
diff --git a/ash/media/media_notification_view.cc b/ash/media/media_notification_view.cc index a4ca85b..ace6fe0 100644 --- a/ash/media/media_notification_view.cc +++ b/ash/media/media_notification_view.cc
@@ -279,6 +279,7 @@ title_label_->SetText(metadata.title); artist_label_->SetText(metadata.artist); + header_row_->SetSummaryText(metadata.album); if (!metadata.title.empty()) RecordMetadataHistogram(Metadata::kTitle);
diff --git a/ash/media/media_notification_view_unittest.cc b/ash/media/media_notification_view_unittest.cc index 8a2bd5b..f0785b0 100644 --- a/ash/media/media_notification_view_unittest.cc +++ b/ash/media/media_notification_view_unittest.cc
@@ -535,6 +535,8 @@ ExpectHistogramMetadataRecorded(MediaNotificationView::Metadata::kAlbum, 0); ExpectHistogramMetadataRecorded(MediaNotificationView::Metadata::kCount, 1); + EXPECT_FALSE(header_row()->summary_text_for_testing()->visible()); + media_session::MediaMetadata metadata; metadata.title = base::ASCIIToUTF16("title2"); metadata.artist = base::ASCIIToUTF16("artist2"); @@ -545,9 +547,11 @@ EXPECT_TRUE(title_artist_row()->visible()); EXPECT_TRUE(title_label()->visible()); EXPECT_TRUE(artist_label()->visible()); + EXPECT_TRUE(header_row()->summary_text_for_testing()->visible()); EXPECT_EQ(metadata.title, title_label()->text()); EXPECT_EQ(metadata.artist, artist_label()->text()); + EXPECT_EQ(metadata.album, header_row()->summary_text_for_testing()->text()); EXPECT_EQ(kMediaTitleArtistRowExpectedHeight, title_artist_row()->height());
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc index 2a9dd68..99f1c6a 100644 --- a/ash/metrics/user_metrics_recorder.cc +++ b/ash/metrics/user_metrics_recorder.cc
@@ -5,6 +5,7 @@ #include "ash/metrics/user_metrics_recorder.h" #include <memory> +#include <vector> #include "ash/login/ui/lock_screen.h" #include "ash/metrics/demo_session_metrics_recorder.h" @@ -19,6 +20,7 @@ #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_view.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_state.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -99,13 +101,17 @@ return session->IsActiveUserSessionStarted() && !session->IsScreenLocked(); } -// Array of window container ids that contain visible windows to be counted for -// UMA statistics. Note the containers are ordered from top most visible -// container to the lowest to allow the |GetNumVisibleWindows| method to short -// circuit when processing a maximized or fullscreen window. -int kVisibleWindowContainerIds[] = {kShellWindowId_PipContainer, - kShellWindowId_AlwaysOnTopContainer, - kShellWindowId_DefaultContainer}; +// Returns a list of window container ids that contain visible windows to be +// counted for UMA statistics. Note the containers are ordered from top most +// visible container to the lowest to allow the |GetNumVisibleWindows| method to +// short circuit when processing a maximized or fullscreen window. +std::vector<int> GetVisibleWindowContainerIds() { + std::vector<int> ids{kShellWindowId_PipContainer, + kShellWindowId_AlwaysOnTopContainer}; + // TODO(afakhry): Add metrics for the inactive desks. + ids.emplace_back(desks_util::GetActiveDeskContainerId()); + return ids; +} // Returns an approximate count of how many windows are currently visible in the // primary root window. @@ -113,7 +119,7 @@ int visible_window_count = 0; bool maximized_or_fullscreen_window_present = false; - for (const int& current_container_id : kVisibleWindowContainerIds) { + for (const int& current_container_id : GetVisibleWindowContainerIds()) { if (maximized_or_fullscreen_window_present) break; @@ -140,7 +146,7 @@ ++visible_window_count; // Stop counting windows that will be hidden by maximized or fullscreen - // windows. Only windows in the kShellWindowId_DefaultContainer and + // windows. Only windows in the active desk container and // kShellWindowId_AlwaysOnTopContainer can be maximized or fullscreened // and completely obscure windows beneath them. if (child_window_state->IsMaximizedOrFullscreenOrPinned()) {
diff --git a/ash/public/cpp/frame_header.cc b/ash/public/cpp/frame_header.cc index 2c9e7d1..0c45170e 100644 --- a/ash/public/cpp/frame_header.cc +++ b/ash/public/cpp/frame_header.cc
@@ -62,11 +62,10 @@ // widget's activation changes. Returns false if the header should switch to // new visuals instantaneously. bool CanAnimateActivation(views::Widget* widget) { - // Do not animate the header if the parent (e.g. - // kShellWindowId_DefaultContainer) is already animating. All of the - // implementers of FrameHeader animate activation by continuously painting - // during the animation. This gives the parent's animation a slower frame - // rate. + // Do not animate the header if the parent (e.g. the active desk container) is + // already animating. All of the implementers of FrameHeader animate + // activation by continuously painting during the animation. This gives the + // parent's animation a slower frame rate. // TODO(sky): Expose a better way to determine this rather than assuming the // parent is a toplevel container. aura::Window* window = widget->GetNativeWindow();
diff --git a/ash/public/cpp/shell_window_ids.cc b/ash/public/cpp/shell_window_ids.cc index e969b41..ce4306e4 100644 --- a/ash/public/cpp/shell_window_ids.cc +++ b/ash/public/cpp/shell_window_ids.cc
@@ -22,7 +22,7 @@ kShellWindowId_SystemModalContainer, kShellWindowId_AlwaysOnTopContainer, kShellWindowId_AppListContainer, - kShellWindowId_DefaultContainer, + kShellWindowId_DefaultContainerDeprecated, kShellWindowId_HomeScreenContainer, // Launcher and status are intentionally checked after other containers
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h index f7a1977..aae3e5b7 100644 --- a/ash/public/cpp/shell_window_ids.h +++ b/ash/public/cpp/shell_window_ids.h
@@ -48,8 +48,12 @@ // The wallpaper (desktop background) window. kShellWindowId_WallpaperContainer, - // The container for standard top-level windows. - kShellWindowId_DefaultContainer, + // The containers for standard top-level windows per active desks. + // Note: Do not use this container directly. Use + // `desks_util::GetActiveDeskContainerId()` instead. + // TODO(afakhry): Rename this container, unexpose it, and add the rest of the + // containers. + kShellWindowId_DefaultContainerDeprecated, // The container for top-level windows with the 'always-on-top' flag set. kShellWindowId_AlwaysOnTopContainer, @@ -174,7 +178,7 @@ kShellWindowId_UnparentedControlContainer, kShellWindowId_WallpaperContainer, kShellWindowId_VirtualKeyboardContainer, - kShellWindowId_DefaultContainer, + kShellWindowId_DefaultContainerDeprecated, kShellWindowId_AlwaysOnTopContainer, kShellWindowId_AppListContainer, kShellWindowId_HomeScreenContainer,
diff --git a/ash/public/interfaces/shell_test_api.test-mojom b/ash/public/interfaces/shell_test_api.test-mojom index 718c0f4..f0239f01 100644 --- a/ash/public/interfaces/shell_test_api.test-mojom +++ b/ash/public/interfaces/shell_test_api.test-mojom
@@ -9,6 +9,14 @@ kExitAnimationComplete, }; +enum LauncherAnimationState { + kClosed, + kPeeking, + kHalf, + kFullscreenAllApps, + kFullscreenSearch +}; + interface ShellTestApi { // Returns true if a system modal window is open (e.g. the Wi-Fi network // password dialog). @@ -53,4 +61,8 @@ // Runs the callback when the overview state becomes |state|. WaitForOverviewAnimationState(OverviewAnimationState state) => (); + + // Runs the callback when the launcher state becomes |state| after + // state transition animation. + WaitForLauncherAnimationState(LauncherAnimationState state) => (); };
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 772063c..941da6f7 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -212,7 +212,8 @@ void ReparentAllWindows(aura::Window* src, aura::Window* dst) { // Set of windows to move. const int kContainerIdsToMove[] = { - kShellWindowId_DefaultContainer, + // TODO(afakhry): Add rest of desks containers. + kShellWindowId_DefaultContainerDeprecated, kShellWindowId_AlwaysOnTopContainer, kShellWindowId_PipContainer, kShellWindowId_SystemModalContainer,
diff --git a/ash/screen_util.cc b/ash/screen_util.cc index 5bc44ad..d8ad15c 100644 --- a/ash/screen_util.cc +++ b/ash/screen_util.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/work_area_insets.h" #include "base/logging.h" #include "ui/aura/client/screen_position_client.h" @@ -62,17 +63,17 @@ return bounds; } -gfx::Rect GetDisplayWorkAreaBoundsInParentForDefaultContainer( +gfx::Rect GetDisplayWorkAreaBoundsInParentForActiveDeskContainer( aura::Window* window) { aura::Window* root_window = window->GetRootWindow(); return GetDisplayWorkAreaBoundsInParent( - root_window->GetChildById(kShellWindowId_DefaultContainer)); + desks_util::GetActiveDeskContainerForRoot(root_window)); } -gfx::Rect GetDisplayWorkAreaBoundsInScreenForDefaultContainer( +gfx::Rect GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( aura::Window* window) { gfx::Rect bounds = - GetDisplayWorkAreaBoundsInParentForDefaultContainer(window); + GetDisplayWorkAreaBoundsInParentForActiveDeskContainer(window); ::wm::ConvertRectToScreen(window->GetRootWindow(), &bounds); return bounds; }
diff --git a/ash/screen_util.h b/ash/screen_util.h index 119f04e..dd39770 100644 --- a/ash/screen_util.h +++ b/ash/screen_util.h
@@ -45,10 +45,10 @@ ASH_EXPORT gfx::Rect GetDisplayWorkAreaBoundsInParentForLockScreen( aura::Window* window); -// Returns the display's work area bounds on the default container. -ASH_EXPORT gfx::Rect GetDisplayWorkAreaBoundsInParentForDefaultContainer( +// Returns the display's work area bounds on the active desk container. +ASH_EXPORT gfx::Rect GetDisplayWorkAreaBoundsInParentForActiveDeskContainer( aura::Window* window); -ASH_EXPORT gfx::Rect GetDisplayWorkAreaBoundsInScreenForDefaultContainer( +ASH_EXPORT gfx::Rect GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( aura::Window* window); // Returns the bounds of the physical display containing the shelf for
diff --git a/ash/screen_util_unittest.cc b/ash/screen_util_unittest.cc index bbc931bb..84a4514d 100644 --- a/ash/screen_util_unittest.cc +++ b/ash/screen_util_unittest.cc
@@ -12,6 +12,7 @@ #include "ash/shelf/shelf_constants.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "ui/aura/env.h" @@ -231,7 +232,7 @@ UpdateDisplay("1366x768"); std::unique_ptr<aura::Window> window = CreateToplevelTestWindow( - gfx::Rect(300, 300, 200, 150), kShellWindowId_DefaultContainer); + gfx::Rect(300, 300, 200, 150), desks_util::GetActiveDeskContainerId()); auto* docked_magnifier_controller = Shell::Get()->docked_magnifier_controller();
diff --git a/ash/shelf/shelf_window_watcher.cc b/ash/shelf/shelf_window_watcher.cc index b4a15f1..a55a015f 100644 --- a/ash/shelf/shelf_window_watcher.cc +++ b/ash/shelf/shelf_window_watcher.cc
@@ -13,6 +13,7 @@ #include "ash/shelf/shelf_constants.h" #include "ash/shelf/shelf_window_watcher_item_delegate.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_util.h" #include "base/strings/string_util.h" #include "ui/aura/client/aura_constants.h" @@ -93,8 +94,9 @@ void ShelfWindowWatcher::ContainerWindowObserver::OnWindowHierarchyChanged( const HierarchyChangeParams& params) { if (!params.old_parent && params.new_parent && - (params.new_parent->id() == kShellWindowId_DefaultContainer)) { - // A new window was created in the default container. + desks_util::IsDeskContainerId(params.new_parent->id())) { + // A new window was created in one of the desks' containers. Note that the + // shelf is globally showing all apps from all active and inactive desks. window_watcher_->OnUserWindowAdded(params.target); } } @@ -263,11 +265,11 @@ } void ShelfWindowWatcher::OnRootWindowAdded(aura::Window* root_window) { - aura::Window* container = - root_window->GetChildById(kShellWindowId_DefaultContainer); - for (aura::Window* window : container->children()) - OnUserWindowAdded(window); - observed_container_windows_.Add(container); + for (aura::Window* container : desks_util::GetDesksContainers(root_window)) { + for (aura::Window* window : container->children()) + OnUserWindowAdded(window); + observed_container_windows_.Add(container); + } } } // namespace ash
diff --git a/ash/shelf/shelf_window_watcher_unittest.cc b/ash/shelf/shelf_window_watcher_unittest.cc index c4c5768..f83bc90 100644 --- a/ash/shelf/shelf_window_watcher_unittest.cc +++ b/ash/shelf/shelf_window_watcher_unittest.cc
@@ -15,6 +15,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/window_factory.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -74,12 +75,12 @@ // Ensure shelf items are added and removed as windows are opened and closed. TEST_F(ShelfWindowWatcherTest, OpenAndClose) { // Windows with valid ShelfItemType and ShelfID properties get shelf items. - std::unique_ptr<views::Widget> widget1 = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget1 = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); CreateShelfItem(widget1->GetNativeWindow()); EXPECT_EQ(3, model_->item_count()); - std::unique_ptr<views::Widget> widget2 = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget2 = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); CreateShelfItem(widget2->GetNativeWindow()); EXPECT_EQ(4, model_->item_count()); @@ -96,11 +97,11 @@ return; // Windows with no valid ShelfItemType and ShelfID properties get shelf items. - std::unique_ptr<views::Widget> widget1 = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget1 = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); EXPECT_EQ(3, model_->item_count()); - std::unique_ptr<views::Widget> widget2 = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget2 = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); EXPECT_EQ(4, model_->item_count()); // Each ShelfItem is removed when the associated window is destroyed. @@ -121,7 +122,7 @@ window_factory::NewWindow(nullptr, type); window->Init(ui::LAYER_NOT_DRAWN); Shell::GetPrimaryRootWindow() - ->GetChildById(kShellWindowId_DefaultContainer) + ->GetChildById(desks_util::GetActiveDeskContainerId()) ->AddChild(window.get()); window->Show(); EXPECT_EQ(type == aura::client::WINDOW_TYPE_NORMAL ? 3 : 2, @@ -131,10 +132,10 @@ TEST_F(ShelfWindowWatcherTest, CreateAndRemoveShelfItemProperties) { // Creating windows without a valid ShelfItemType only adds items in mash. - std::unique_ptr<views::Widget> widget1 = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); - std::unique_ptr<views::Widget> widget2 = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget1 = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); + std::unique_ptr<views::Widget> widget2 = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); const bool is_mash = ::features::IsMultiProcessMash(); EXPECT_EQ(is_mash ? 4 : 2, model_->item_count()); @@ -173,8 +174,8 @@ TEST_F(ShelfWindowWatcherTest, UpdateWindowProperty) { // Create a ShelfItem for a new window. - std::unique_ptr<views::Widget> widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); ShelfID id = CreateShelfItem(widget->GetNativeWindow()); EXPECT_EQ(3, model_->item_count()); @@ -190,8 +191,8 @@ TEST_F(ShelfWindowWatcherTest, MaximizeAndRestoreWindow) { // Create a ShelfItem for a new window. - std::unique_ptr<views::Widget> widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); ShelfID id = CreateShelfItem(widget->GetNativeWindow()); EXPECT_EQ(3, model_->item_count()); @@ -223,8 +224,8 @@ // TODO(simonhong): Add a test for removing a Window during the dragging. TEST_F(ShelfWindowWatcherTest, DragWindow) { // Create a ShelfItem for a new window. - std::unique_ptr<views::Widget> widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); ShelfID id = CreateShelfItem(widget->GetNativeWindow()); EXPECT_EQ(3, model_->item_count()); @@ -247,16 +248,16 @@ // Ensure dialogs get shelf items. TEST_F(ShelfWindowWatcherTest, DialogWindows) { // An item is created for a dialog window. - std::unique_ptr<views::Widget> dialog_widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> dialog_widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); aura::Window* dialog = dialog_widget->GetNativeWindow(); dialog->SetProperty(kShelfIDKey, new std::string(ShelfID("a").Serialize())); dialog->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG)); EXPECT_EQ(3, model_->item_count()); // An item is not created for an app window. - std::unique_ptr<views::Widget> app_widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> app_widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); aura::Window* app = app_widget->GetNativeWindow(); app->SetProperty(kShelfIDKey, new std::string(ShelfID("c").Serialize())); app->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_APP)); @@ -271,8 +272,8 @@ // Ensure items use the app icon and window icon aura::Window properties. TEST_F(ShelfWindowWatcherTest, ItemIcon) { // Create a ShelfItem for a window; it should have a default icon. - std::unique_ptr<views::Widget> widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); aura::Window* window = widget->GetNativeWindow(); ShelfID id = CreateShelfItem(window); EXPECT_EQ(3, model_->item_count()); @@ -303,7 +304,7 @@ window->SetProperty(kShelfIDKey, new std::string(ShelfID("a").Serialize())); window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG)); Shell::GetPrimaryRootWindow() - ->GetChildById(kShellWindowId_DefaultContainer) + ->GetChildById(desks_util::GetActiveDeskContainerId()) ->AddChild(window.get()); window->Show(); EXPECT_EQ(3, model_->item_count()); @@ -331,7 +332,7 @@ window->SetProperty(kShelfIDKey, new std::string(ShelfID("a").Serialize())); window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG)); Shell::GetPrimaryRootWindow() - ->GetChildById(kShellWindowId_DefaultContainer) + ->GetChildById(desks_util::GetActiveDeskContainerId()) ->AddChild(window.get()); window->Show(); EXPECT_EQ(3, model_->item_count()); @@ -343,7 +344,7 @@ new std::string(ShelfID("b").Serialize())); transient->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_DIALOG)); Shell::GetPrimaryRootWindow() - ->GetChildById(kShellWindowId_DefaultContainer) + ->GetChildById(desks_util::GetActiveDeskContainerId()) ->AddChild(transient.get()); ::wm::TransientWindowController::Get()->AddTransientChild(window.get(), transient.get()); @@ -368,8 +369,8 @@ EXPECT_EQ(2, model->item_count()); // Construct a window that should get a shelf item once the session starts. - std::unique_ptr<views::Widget> widget = - CreateTestWidget(nullptr, kShellWindowId_DefaultContainer, gfx::Rect()); + std::unique_ptr<views::Widget> widget = CreateTestWidget( + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect()); ShelfWindowWatcherTest::CreateShelfItem(widget->GetNativeWindow()); EXPECT_EQ(2, model->item_count());
diff --git a/ash/shell/window_watcher.cc b/ash/shell/window_watcher.cc index 01a4c78..6ac7220 100644 --- a/ash/shell/window_watcher.cc +++ b/ash/shell/window_watcher.cc
@@ -14,6 +14,7 @@ #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/shell/window_watcher_shelf_item_delegate.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_util.h" #include "base/strings/string_number_conversions.h" #include "third_party/skia/include/core/SkColor.h" @@ -42,19 +43,20 @@ } void RootWindowAdded(aura::Window* root) { - aura::Window* container = - root->GetChildById(kShellWindowId_DefaultContainer); - container->AddObserver(watcher_); - for (aura::Window* window : container->children()) - watcher_->OnWindowAdded(window); + // The shelf is globally observing all active and inactive desks containers. + for (aura::Window* container : desks_util::GetDesksContainers(root)) { + container->AddObserver(watcher_); + for (aura::Window* window : container->children()) + watcher_->OnWindowAdded(window); + } } void RootWindowRemoved(aura::Window* root) { - aura::Window* container = - root->GetChildById(kShellWindowId_DefaultContainer); - container->RemoveObserver(watcher_); - for (aura::Window* window : container->children()) - watcher_->OnWillRemoveWindow(window); + for (aura::Window* container : desks_util::GetDesksContainers(root)) { + container->RemoveObserver(watcher_); + for (aura::Window* window : container->children()) + watcher_->OnWillRemoveWindow(window); + } } private:
diff --git a/ash/shell_test_api.cc b/ash/shell_test_api.cc index 177f4eb..6d83764 100644 --- a/ash/shell_test_api.cc +++ b/ash/shell_test_api.cc
@@ -105,6 +105,54 @@ DISALLOW_COPY_AND_ASSIGN(OverviewAnimationStateWaiter); }; +// A waiter that waits until the animation ended with the target state, and +// execute the callback. This self destruction upon completion. +class LauncherStateWaiter { + public: + LauncherStateWaiter( + mojom::LauncherAnimationState state, + ShellTestApi::WaitForLauncherAnimationStateCallback callback) + : callback_(std::move(callback)) { + switch (state) { + case mojom::LauncherAnimationState::kClosed: + target_state_ = app_list::AppListViewState::CLOSED; + break; + case mojom::LauncherAnimationState::kPeeking: + target_state_ = app_list::AppListViewState::PEEKING; + break; + case mojom::LauncherAnimationState::kHalf: + target_state_ = app_list::AppListViewState::HALF; + break; + case mojom::LauncherAnimationState::kFullscreenAllApps: + target_state_ = app_list::AppListViewState::FULLSCREEN_ALL_APPS; + break; + case mojom::LauncherAnimationState::kFullscreenSearch: + target_state_ = app_list::AppListViewState::FULLSCREEN_SEARCH; + break; + }; + Shell::Get()->app_list_controller()->SetStateTransitionAnimationCallback( + base::BindRepeating(&LauncherStateWaiter::OnStateChanged, + base::Unretained(this))); + } + ~LauncherStateWaiter() { + Shell::Get()->app_list_controller()->SetStateTransitionAnimationCallback( + base::NullCallback()); + } + + void OnStateChanged(app_list::AppListViewState state) { + if (target_state_ == state) { + std::move(callback_).Run(); + delete this; + } + } + + private: + app_list::AppListViewState target_state_; + ShellTestApi::WaitForLauncherAnimationStateCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(LauncherStateWaiter); +}; + } // namespace ShellTestApi::ShellTestApi() : ShellTestApi(Shell::Get()) {} @@ -261,4 +309,10 @@ new OverviewAnimationStateWaiter(state, std::move(callback)); } +void ShellTestApi::WaitForLauncherAnimationState( + mojom::LauncherAnimationState target_state, + WaitForLauncherAnimationStateCallback callback) { + new LauncherStateWaiter(target_state, std::move(callback)); +} + } // namespace ash
diff --git a/ash/shell_test_api.h b/ash/shell_test_api.h index 040747a..ee9e6fef 100644 --- a/ash/shell_test_api.h +++ b/ash/shell_test_api.h
@@ -70,6 +70,9 @@ void WaitForOverviewAnimationState( mojom::OverviewAnimationState state, WaitForOverviewAnimationStateCallback callback) override; + void WaitForLauncherAnimationState( + mojom::LauncherAnimationState state, + WaitForLauncherAnimationStateCallback callback) override; private: Shell* shell_; // not owned
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index a68fd576..4b79e80 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -25,6 +25,7 @@ #include "ash/test_shell_delegate.h" #include "ash/wallpaper/wallpaper_widget_controller.h" #include "ash/window_factory.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_util.h" #include "base/command_line.h" #include "base/stl_util.h" @@ -59,9 +60,9 @@ namespace { -aura::Window* GetDefaultContainer() { +aura::Window* GetActiveDeskContainer() { return Shell::GetContainer(Shell::GetPrimaryRootWindow(), - kShellWindowId_DefaultContainer); + desks_util::GetActiveDeskContainerId()); } aura::Window* GetAlwaysOnTopContainer() { @@ -80,8 +81,9 @@ aura::Window* root_window = Shell::GetPrimaryRootWindow(); EXPECT_TRUE( Shell::GetContainer(root_window, kShellWindowId_WallpaperContainer)); - EXPECT_TRUE( - Shell::GetContainer(root_window, kShellWindowId_DefaultContainer)); + // TODO(afakhry): Test rest of desks containers. + EXPECT_TRUE(Shell::GetContainer(root_window, + kShellWindowId_DefaultContainerDeprecated)); EXPECT_TRUE( Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer)); EXPECT_TRUE(Shell::GetContainer(root_window, kShellWindowId_ShelfContainer)); @@ -238,10 +240,10 @@ // Normal window should be created in default container. TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW, false, // always_on_top - GetDefaultContainer()); + GetActiveDeskContainer()); TestCreateWindow(views::Widget::InitParams::TYPE_POPUP, false, // always_on_top - GetDefaultContainer()); + GetActiveDeskContainer()); // Always-on-top window and popup are created in always-on-top container. TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW, @@ -283,9 +285,9 @@ views::Widget* widget = CreateTestWindow(widget_params); widget->Show(); - // It should be in default container. + // It should be in the active desk container. EXPECT_TRUE( - GetDefaultContainer()->Contains(widget->GetNativeWindow()->parent())); + GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); // Flip always-on-top flag. widget->SetAlwaysOnTop(true); @@ -294,15 +296,15 @@ // Flip always-on-top flag. widget->SetAlwaysOnTop(false); - // It should go back to default container. + // It should go back to the active desk container. EXPECT_TRUE( - GetDefaultContainer()->Contains(widget->GetNativeWindow()->parent())); + GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); // Set the same always-on-top flag again. widget->SetAlwaysOnTop(false); - // Should have no effect and we are still in the default container. + // Should have no effect and we are still in the the active desk container. EXPECT_TRUE( - GetDefaultContainer()->Contains(widget->GetNativeWindow()->parent())); + GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); widget->Close(); } @@ -315,9 +317,9 @@ views::Widget* widget = CreateTestWindow(widget_params); widget->Show(); - // It should be in default container. + // It should be in the active desk container. EXPECT_TRUE( - GetDefaultContainer()->Contains(widget->GetNativeWindow()->parent())); + GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); // Create a modal window. views::Widget* modal_widget = views::Widget::CreateWindowWithParent( @@ -350,9 +352,9 @@ widget->Show(); EXPECT_TRUE(widget->GetNativeView()->HasFocus()); - // It should be in default container. + // It should be in the active desk container. EXPECT_TRUE( - GetDefaultContainer()->Contains(widget->GetNativeWindow()->parent())); + GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent())); Shell::Get()->session_controller()->LockScreenAndFlushForTest(); // Create a LockScreen window.
diff --git a/ash/system/message_center/arc/arc_notification_view_unittest.cc b/ash/system/message_center/arc/arc_notification_view_unittest.cc index f51978ea..780ee977 100644 --- a/ash/system/message_center/arc/arc_notification_view_unittest.cc +++ b/ash/system/message_center/arc/arc_notification_view_unittest.cc
@@ -13,6 +13,7 @@ #include "ash/system/message_center/arc/mock_arc_notification_item.h" #include "ash/system/message_center/arc/mock_arc_notification_surface.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "base/bind.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -90,7 +91,7 @@ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); init_params.context = CurrentContext(); init_params.parent = Shell::GetPrimaryRootWindow()->GetChildById( - kShellWindowId_DefaultContainer); + desks_util::GetActiveDeskContainerId()); init_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; views::Widget* widget = new views::Widget();
diff --git a/ash/system/message_center/ash_popup_alignment_delegate_unittest.cc b/ash/system/message_center/ash_popup_alignment_delegate_unittest.cc index 23be4b98..5c3a42b 100644 --- a/ash/system/message_center/ash_popup_alignment_delegate_unittest.cc +++ b/ash/system/message_center/ash_popup_alignment_delegate_unittest.cc
@@ -14,6 +14,7 @@ #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "base/command_line.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" @@ -143,7 +144,7 @@ // Create a window, otherwise autohide doesn't work. std::unique_ptr<views::Widget> widget = CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(0, 0, 50, 50)); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(0, 0, 50, 50)); Shelf* shelf = GetPrimaryShelf(); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); EXPECT_EQ(origin_x, alignment_delegate()->GetToastOriginX(toast_size));
diff --git a/ash/system/power/power_button_screenshot_controller.cc b/ash/system/power/power_button_screenshot_controller.cc index 8359015..509eebc1 100644 --- a/ash/system/power/power_button_screenshot_controller.cc +++ b/ash/system/power/power_button_screenshot_controller.cc
@@ -108,8 +108,10 @@ if (!volume_down_timer_.IsRunning()) { volume_down_timer_.Start( - FROM_HERE, kScreenshotChordDelay, this, - &PowerButtonScreenshotController::OnVolumeDownTimeout); + FROM_HERE, kScreenshotChordDelay, + base::BindOnce( + &PowerButtonScreenshotController::OnVolumeDownTimeout, + base::Unretained(this), ui::Accelerator(*event))); } } } @@ -140,8 +142,10 @@ return false; } -void PowerButtonScreenshotController::OnVolumeDownTimeout() { - Shell::Get()->accelerator_controller()->PerformActionIfEnabled(VOLUME_DOWN); +void PowerButtonScreenshotController::OnVolumeDownTimeout( + const ui::Accelerator& accelerator) { + Shell::Get()->accelerator_controller()->PerformActionIfEnabled(VOLUME_DOWN, + accelerator); } } // namespace ash
diff --git a/ash/system/power/power_button_screenshot_controller.h b/ash/system/power/power_button_screenshot_controller.h index 156ed27a..36ed8e3 100644 --- a/ash/system/power/power_button_screenshot_controller.h +++ b/ash/system/power/power_button_screenshot_controller.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "ui/base/accelerators/accelerator.h" #include "ui/events/event_handler.h" namespace base { @@ -47,7 +48,7 @@ bool InterceptScreenshotChord(); // Called by |volume_down_timer_| to perform volume down accelerator. - void OnVolumeDownTimeout(); + void OnVolumeDownTimeout(const ui::Accelerator& accelerator); // True if volume down key is pressed. bool volume_down_key_pressed_ = false;
diff --git a/ash/system/session/logout_confirmation_controller.cc b/ash/system/session/logout_confirmation_controller.cc index 1644bb4..cd63a96 100644 --- a/ash/system/session/logout_confirmation_controller.cc +++ b/ash/system/session/logout_confirmation_controller.cc
@@ -6,6 +6,7 @@ #include <memory> #include <utility> +#include <vector> #include "ash/login_status.h" #include "ash/public/cpp/shell_window_ids.h" @@ -13,6 +14,7 @@ #include "ash/shell.h" #include "ash/shell_observer.h" #include "ash/system/session/logout_confirmation_dialog.h" +#include "ash/wm/desks/desks_util.h" #include "base/bind.h" #include "base/callback.h" #include "base/location.h" @@ -27,10 +29,13 @@ namespace { const int kLogoutConfirmationDelayInSeconds = 20; -// Shell window containers monitored for when the last window closes. -const int kLastWindowClosedContainerIds[] = { - kShellWindowId_DefaultContainer, kShellWindowId_AlwaysOnTopContainer, - kShellWindowId_PipContainer}; +std::vector<int> GetLastWindowClosedContainerIds() { + const auto& desks_ids = desks_util::GetDesksContainersIds(); + std::vector<int> ids{desks_ids.begin(), desks_ids.end()}; + ids.emplace_back(kShellWindowId_AlwaysOnTopContainer); + ids.emplace_back(kShellWindowId_PipContainer); + return ids; +} void SignOut(LogoutConfirmationController::Source source) { if (Shell::Get()->session_controller()->IsDemoSession() && @@ -62,7 +67,7 @@ ~LastWindowClosedObserver() override { // Stop observing all displays. for (aura::Window* root : Shell::GetAllRootWindows()) { - for (int id : kLastWindowClosedContainerIds) + for (int id : GetLastWindowClosedContainerIds()) root->GetChildById(id)->RemoveObserver(this); } Shell::Get()->RemoveShellObserver(this); @@ -72,7 +77,7 @@ // Observes containers in the |root| window for the last browser and/or app // window being closed. The observers are removed automatically. void ObserveForLastWindowClosed(aura::Window* root) { - for (int id : kLastWindowClosedContainerIds) + for (int id : GetLastWindowClosedContainerIds()) root->GetChildById(id)->AddObserver(this); } @@ -87,7 +92,7 @@ // Enumerate all root windows. for (aura::Window* root : Shell::GetAllRootWindows()) { // For each root window enumerate tracked containers. - for (int id : kLastWindowClosedContainerIds) { + for (int id : GetLastWindowClosedContainerIds()) { // In each container try to find child window that is not equal to // |closing_window| which would indicate that we have other top-level // window and logout time does not apply.
diff --git a/ash/system/session/logout_confirmation_controller_unittest.cc b/ash/system/session/logout_confirmation_controller_unittest.cc index fe2bd540..c74750c 100644 --- a/ash/system/session/logout_confirmation_controller_unittest.cc +++ b/ash/system/session/logout_confirmation_controller_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/memory/ref_counted.h" @@ -319,10 +320,10 @@ UpdateDisplay("1024x768,800x600"); std::unique_ptr<aura::Window> window1 = CreateChildWindow(Shell::GetAllRootWindows()[0]->GetChildById( - kShellWindowId_DefaultContainer)); + desks_util::GetActiveDeskContainerId())); std::unique_ptr<aura::Window> window2 = CreateChildWindow(Shell::GetAllRootWindows()[1]->GetChildById( - kShellWindowId_DefaultContainer)); + desks_util::GetActiveDeskContainerId())); // Closing the last window shows the dialog. window1.reset();
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h index cbe1cca..4c1f7a4 100644 --- a/ash/system/tray/tray_constants.h +++ b/ash/system/tray/tray_constants.h
@@ -183,10 +183,11 @@ constexpr int kUnifiedTrayContentPadding = 8; constexpr int kUnifiedTopShortcutSpacing = 16; constexpr int kUnifiedNotificationHiddenLineHeight = 20; +constexpr int kUnifiedTopShortcutContainerTopPadding = 12; constexpr int kUnifiedNotificationMinimumHeight = 40; constexpr gfx::Insets kUnifiedTopShortcutPadding(0, 16); constexpr gfx::Insets kUnifiedNotificationHiddenPadding(6, 16); - +constexpr gfx::Insets kUnifiedCircularButtonFocusPadding(4); constexpr int kStackingNotificationCounterMax = 8; constexpr int kStackingNotificationCounterRadius = 2; constexpr int kStackingNotificationCounterStartX = 18; @@ -220,6 +221,8 @@ constexpr int kUnifiedFeaturePodSpacing = 6; constexpr int kUnifiedFeaturePodHoverRadius = 4; constexpr int kUnifiedFeaturePodVerticalPadding = 28; +constexpr int kUnifiedFeaturePodTopPadding = 24; +constexpr int kUnifiedFeaturePodBottomPadding = 24; constexpr int kUnifiedFeaturePodHorizontalSidePadding = 12; constexpr int kUnifiedFeaturePodHorizontalMiddlePadding = 0; constexpr int kUnifiedFeaturePodCollapsedVerticalPadding = 16;
diff --git a/ash/system/unified/feature_pods_container_view.cc b/ash/system/unified/feature_pods_container_view.cc index dea9f00..5b06311 100644 --- a/ash/system/unified/feature_pods_container_view.cc +++ b/ash/system/unified/feature_pods_container_view.cc
@@ -39,7 +39,7 @@ // floor(visible_count / kUnifiedFeaturePodItemsInRow) int number_of_lines = (visible_count + kUnifiedFeaturePodItemsInRow - 1) / kUnifiedFeaturePodItemsInRow; - return kUnifiedFeaturePodVerticalPadding + + return kUnifiedFeaturePodBottomPadding + (kUnifiedFeaturePodVerticalPadding + kUnifiedFeaturePodSize.height()) * number_of_lines; } @@ -145,10 +145,9 @@ (kUnifiedFeaturePodSize.width() + kUnifiedFeaturePodHorizontalMiddlePadding) * column; - int y = - kUnifiedFeaturePodVerticalPadding + - (kUnifiedFeaturePodSize.height() + kUnifiedFeaturePodVerticalPadding) * - row; + int y = kUnifiedFeaturePodTopPadding + (kUnifiedFeaturePodSize.height() + + kUnifiedFeaturePodVerticalPadding) * + row; // When fully expanded, or below the second row, always return the same // position.
diff --git a/ash/system/unified/top_shortcuts_view.cc b/ash/system/unified/top_shortcuts_view.cc index 6d9b5ba..eba1261 100644 --- a/ash/system/unified/top_shortcuts_view.cc +++ b/ash/system/unified/top_shortcuts_view.cc
@@ -21,7 +21,7 @@ #include "ui/gfx/paint_vector_icon.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" - +#include "ui/views/view_class_properties.h" namespace ash { namespace { @@ -38,11 +38,19 @@ UserAvatarButton::UserAvatarButton(views::ButtonListener* listener) : Button(listener) { SetLayoutManager(std::make_unique<views::FillLayout>()); + SetBorder(views::CreateEmptyBorder(kUnifiedCircularButtonFocusPadding)); AddChildView(CreateUserAvatarView(0 /* user_index */)); SetTooltipText(GetUserItemAccessibleString(0 /* user_index */)); - SetFocusPainter(TrayPopupUtils::CreateFocusPainter()); + SetInstallFocusRingOnFocus(true); SetFocusForPlatform(); + + int focus_ring_radius = + kTrayItemSize + kUnifiedCircularButtonFocusPadding.width(); + auto path = std::make_unique<SkPath>(); + path->addOval(gfx::RectToSkRect( + gfx::Rect(gfx::Size(focus_ring_radius, focus_ring_radius)))); + SetProperty(views::kHighlightPathKey, path.release()); } } // namespace @@ -89,15 +97,36 @@ } int horizontal_position = child_area.x(); - for (int i = 0; i < child_count(); i++) { + + if (user_avatar_button_ && user_avatar_button_->visible()) { + int vertical_position = + child_area.y() + kUnifiedTopShortcutContainerTopPadding; + horizontal_position -= kUnifiedCircularButtonFocusPadding.left(); + + gfx::Size size = user_avatar_button_->GetPreferredSize(); + gfx::Rect user_avatar_bounds(horizontal_position, vertical_position, + size.width(), size.height()); + user_avatar_button_->SetBoundsRect(user_avatar_bounds); + + horizontal_position += user_avatar_bounds.size().width() + spacing - + kUnifiedCircularButtonFocusPadding.right(); + } + + int vertical_position = child_area.y() + + kUnifiedTopShortcutContainerTopPadding + + kUnifiedCircularButtonFocusPadding.bottom(); + for (int i = 1; i < child_count(); i++) { views::View* child = child_at(i); if (!child->visible()) continue; gfx::Rect bounds(child_area); bounds.set_x(horizontal_position); + bounds.set_y(vertical_position); + int width = (child == sign_out_button_) ? sign_out_button_width : child->GetPreferredSize().width(); bounds.set_width(width); + bounds.set_height(child->GetHeightForWidth(width)); child->SetBoundsRect(bounds); horizontal_position += width + spacing; } @@ -105,7 +134,6 @@ gfx::Size TopShortcutButtonContainer::CalculatePreferredSize() const { int total_horizontal_size = 0; - int max_height = 0; int num_visible = 0; for (int i = 0; i < child_count(); i++) { const views::View* child = child_at(i); @@ -116,14 +144,21 @@ continue; total_horizontal_size += child_horizontal_size; num_visible++; - max_height = std::max(child->GetPreferredSize().height(), max_height); } int width = (num_visible == 0) ? 0 : total_horizontal_size + (num_visible - 1) * kUnifiedTopShortcutButtonDefaultSpacing; - return gfx::Size(width, max_height); + int height = kTrayItemSize + kUnifiedCircularButtonFocusPadding.height() + + kUnifiedTopShortcutContainerTopPadding; + return gfx::Size(width, height); +} + +void TopShortcutButtonContainer::AddUserAvatarButton( + views::View* user_avatar_button) { + AddChildView(user_avatar_button); + user_avatar_button_ = user_avatar_button; } void TopShortcutButtonContainer::AddSignOutButton( @@ -139,7 +174,8 @@ auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kHorizontal, kUnifiedTopShortcutPadding, kUnifiedTopShortcutSpacing)); - layout->set_cross_axis_alignment(views::BoxLayout::CROSS_AXIS_ALIGNMENT_END); + layout->set_cross_axis_alignment( + views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); container_ = new TopShortcutButtonContainer(); AddChildView(container_); @@ -147,7 +183,7 @@ LoginStatus::NOT_LOGGED_IN) { user_avatar_button_ = new UserAvatarButton(this); user_avatar_button_->SetEnabled(controller->IsUserChooserEnabled()); - container_->AddChildView(user_avatar_button_); + container_->AddUserAvatarButton(user_avatar_button_); } // Show the buttons in this row as disabled if the user is at the login
diff --git a/ash/system/unified/top_shortcuts_view.h b/ash/system/unified/top_shortcuts_view.h index 8856183..d06f867 100644 --- a/ash/system/unified/top_shortcuts_view.h +++ b/ash/system/unified/top_shortcuts_view.h
@@ -30,10 +30,12 @@ void Layout() override; gfx::Size CalculatePreferredSize() const override; + void AddUserAvatarButton(views::View* user_avatar_button); // Add the sign-out button, which can be resized upon layout. void AddSignOutButton(views::View* sign_out_button); private: + views::View* user_avatar_button_ = nullptr; views::View* sign_out_button_ = nullptr; DISALLOW_COPY_AND_ASSIGN(TopShortcutButtonContainer);
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc index e535c91..e7096a8 100644 --- a/ash/system/unified/unified_system_tray_bubble.cc +++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -5,6 +5,7 @@ #include "ash/system/unified/unified_system_tray_bubble.h" #include "ash/public/cpp/app_list/app_list_features.h" +#include "ash/public/cpp/ash_features.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/system/status_area_widget.h" @@ -317,8 +318,18 @@ bubble_widget_->client_view()->layer()->SetBackgroundBlur(0); - blur_layer_ = views::Painter::CreatePaintedLayer( - views::Painter::CreateSolidRoundRectPainter(SK_ColorTRANSPARENT, 0)); + if (features::ShouldUseShaderRoundedCorner()) { + blur_layer_ = std::make_unique<ui::LayerOwner>( + std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR)); + blur_layer_->layer()->SetColor(SK_ColorTRANSPARENT); + blur_layer_->layer()->SetRoundedCornerRadius( + {kUnifiedTrayCornerRadius, kUnifiedTrayCornerRadius, + kUnifiedTrayCornerRadius, kUnifiedTrayCornerRadius}); + } else { + blur_layer_ = views::Painter::CreatePaintedLayer( + views::Painter::CreateSolidRoundRectPainter(SK_ColorTRANSPARENT, 0)); + } + blur_layer_->layer()->SetFillsBoundsOpaquely(false); bubble_widget_->GetLayer()->Add(blur_layer_->layer());
diff --git a/ash/system/unified/user_chooser_view.cc b/ash/system/unified/user_chooser_view.cc index 2297264..a1110bc 100644 --- a/ash/system/unified/user_chooser_view.cc +++ b/ash/system/unified/user_chooser_view.cc
@@ -149,6 +149,9 @@ gfx::ImageSkia icon = gfx::CreateVectorIcon(kSystemMenuGuestIcon, kMenuIconColor); image_view->SetImage(icon, icon.size()); + // make sure icon height stays same for guest icon + image_view->SetBorder(views::CreateEmptyBorder( + gfx::Insets((kTrayItemSize - icon.size().height()) / 2, 0))); } else { image_view->SetImage(user_session->user_info->avatar->image, gfx::Size(kTrayItemSize, kTrayItemSize));
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index f067845b..79fa96e7 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h
@@ -13,6 +13,7 @@ #include <vector> #include "ash/public/cpp/shell_window_ids.h" +#include "ash/wm/desks/desks_util.h" #include "base/macros.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread.h" @@ -115,7 +116,7 @@ // values for |container_id|. static std::unique_ptr<views::Widget> CreateTestWidget( views::WidgetDelegate* delegate = nullptr, - int container_id = kShellWindowId_DefaultContainer, + int container_id = desks_util::GetActiveDeskContainerId(), const gfx::Rect& bounds = gfx::Rect(), bool show = true);
diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc index 3e1b9c60..9c6c0b5 100644 --- a/ash/tooltips/tooltip_controller_unittest.cc +++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "ui/aura/env.h" @@ -39,8 +40,9 @@ params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; params.accept_events = true; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.parent = Shell::Get()->GetContainer( - Shell::GetAllRootWindows().at(display), kShellWindowId_DefaultContainer); + params.parent = + Shell::Get()->GetContainer(Shell::GetAllRootWindows().at(display), + desks_util::GetActiveDeskContainerId()); params.bounds = bounds; widget->Init(params); widget->Show();
diff --git a/ash/wm/always_on_top_controller.cc b/ash/wm/always_on_top_controller.cc index 1b3e823..3d7f1a1 100644 --- a/ash/wm/always_on_top_controller.cc +++ b/ash/wm/always_on_top_controller.cc
@@ -6,6 +6,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_state.h" #include "ash/wm/workspace/workspace_layout_manager.h" #include "ui/aura/client/aura_constants.h" @@ -20,8 +21,8 @@ aura::Window* pip_container) : always_on_top_container_(always_on_top_container), pip_container_(pip_container) { - DCHECK_NE(kShellWindowId_DefaultContainer, always_on_top_container_->id()); - DCHECK_NE(kShellWindowId_DefaultContainer, pip_container_->id()); + DCHECK(!desks_util::IsDeskContainer(always_on_top_container_)); + DCHECK(!desks_util::IsDeskContainer(pip_container_)); always_on_top_container_->SetLayoutManager( new WorkspaceLayoutManager(always_on_top_container_)); pip_container_->SetLayoutManager(new WorkspaceLayoutManager(pip_container_)); @@ -44,8 +45,12 @@ DCHECK(pip_container_); if (!window->GetProperty(aura::client::kAlwaysOnTopKey)) { - return always_on_top_container_->GetRootWindow()->GetChildById( - kShellWindowId_DefaultContainer); + aura::Window* root = always_on_top_container_->GetRootWindow(); + + // TODO(afakhry): Do we need to worry about the context of |window| here? Or + // is it safe to assume that |window| should always be parented to the + // active desks' container. + return desks_util::GetActiveDeskContainerForRoot(root); } if (window->parent() && wm::GetWindowState(window)->IsPip()) return pip_container_;
diff --git a/ash/wm/always_on_top_controller_unittest.cc b/ash/wm/always_on_top_controller_unittest.cc index 9d562e4..1427110 100644 --- a/ash/wm/always_on_top_controller_unittest.cc +++ b/ash/wm/always_on_top_controller_unittest.cc
@@ -9,6 +9,7 @@ #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" #include "ash/wm/workspace/workspace_layout_manager.h" @@ -130,7 +131,7 @@ aura::Window* container = always_on_top_controller->GetContainer(window.get()); ASSERT_TRUE(container); - EXPECT_EQ(kShellWindowId_DefaultContainer, container->id()); + EXPECT_EQ(desks_util::GetActiveDeskContainerId(), container->id()); } TEST_F(AlwaysOnTopControllerTest,
diff --git a/ash/wm/ash_focus_rules.cc b/ash/wm/ash_focus_rules.cc index db3773c7..5b372c8e 100644 --- a/ash/wm/ash_focus_rules.cc +++ b/ash/wm/ash_focus_rules.cc
@@ -9,6 +9,7 @@ #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/wm/container_finder.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/window_state.h" #include "ui/aura/client/aura_constants.h" @@ -81,9 +82,11 @@ if (!window->TargetVisibility()) return false; - const int parent_shell_window_id = window->parent()->id(); - return parent_shell_window_id == kShellWindowId_DefaultContainer || - parent_shell_window_id == kShellWindowId_LockScreenContainer; + const aura::Window* parent = window->parent(); + if (desks_util::IsActiveDeskContainer(parent)) + return true; + + return parent->id() == kShellWindowId_LockScreenContainer; } bool AshFocusRules::CanActivateWindow(const aura::Window* window) const {
diff --git a/ash/wm/ash_focus_rules_unittest.cc b/ash/wm/ash_focus_rules_unittest.cc index fea4a3ec..0291078 100644 --- a/ash/wm/ash_focus_rules_unittest.cc +++ b/ash/wm/ash_focus_rules_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" #include "ash/window_factory.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/lock_state_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -97,8 +98,8 @@ Shell::Get()->session_controller())); } - aura::Window* CreateWindowInDefaultContainer() { - return CreateWindowInContainer(kShellWindowId_DefaultContainer); + aura::Window* CreateWindowInActiveDesk() { + return CreateWindowInContainer(desks_util::GetActiveDeskContainerId()); } aura::Window* CreateWindowInAlwaysOnTopContainer() { @@ -157,7 +158,7 @@ // Verifies focus is returned (after unlocking the screen) to the most recent // window that had it before locking the screen. TEST_F(LockScreenAshFocusRulesTest, RegainFocusAfterUnlock) { - std::unique_ptr<aura::Window> normal_window(CreateWindowInDefaultContainer()); + std::unique_ptr<aura::Window> normal_window(CreateWindowInActiveDesk()); std::unique_ptr<aura::Window> always_on_top_window( CreateWindowInAlwaysOnTopContainer());
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc index 43c52297..4cbaa0d 100644 --- a/ash/wm/client_controlled_state_unittest.cc +++ b/ash/wm/client_controlled_state_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/screen_pinning_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -106,7 +107,7 @@ views::Widget::InitParams params; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.parent = Shell::GetPrimaryRootWindow()->GetChildById( - kShellWindowId_DefaultContainer); + desks_util::GetActiveDeskContainerId()); params.bounds = kInitialBounds; params.delegate = widget_delegate_;
diff --git a/ash/wm/container_finder_unittest.cc b/ash/wm/container_finder_unittest.cc index d00db8a..166d905 100644 --- a/ash/wm/container_finder_unittest.cc +++ b/ash/wm/container_finder_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ui/aura/window.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/widget/widget.h" @@ -19,7 +20,7 @@ TEST_F(ContainerFinderTest, GetContainerForWindow) { // Create a normal widget in the default container. std::unique_ptr<views::Widget> widget = CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(1, 2, 3, 4)); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(1, 2, 3, 4)); aura::Window* window = widget->GetNativeWindow(); // The window itself is not a container. @@ -28,7 +29,7 @@ // Container lookup finds the default container. aura::Window* container = wm::GetContainerForWindow(window); ASSERT_TRUE(container); - EXPECT_EQ(kShellWindowId_DefaultContainer, container->id()); + EXPECT_EQ(desks_util::GetActiveDeskContainerId(), container->id()); } } // namespace ash
diff --git a/ash/wm/desks/desks_util.cc b/ash/wm/desks/desks_util.cc index 6ce77254..844d77b0 100644 --- a/ash/wm/desks/desks_util.cc +++ b/ash/wm/desks/desks_util.cc
@@ -15,7 +15,7 @@ constexpr std::array<int, kMaxNumberOfDesks> kDesksContainersIds = { // TODO(afakhry): Fill this. - kShellWindowId_DefaultContainer, + kShellWindowId_DefaultContainerDeprecated, }; } // namespace @@ -26,7 +26,7 @@ const char* GetDeskContainerName(int container_id) { switch (container_id) { - case kShellWindowId_DefaultContainer: + case kShellWindowId_DefaultContainerDeprecated: return "Desk_Container_A"; // TODO(afakhry): Fill this. @@ -51,19 +51,24 @@ return containers; } -bool IsDeskContainer(aura::Window* container) { +bool IsDeskContainer(const aura::Window* container) { DCHECK(container); // TODO(afakhry): Add the rest of the desks containers. - return container->id() == kShellWindowId_DefaultContainer; + return container->id() == kShellWindowId_DefaultContainerDeprecated; +} + +bool IsDeskContainerId(int id) { + // TODO(afakhry): Add the rest of the desks containers. + return id == kShellWindowId_DefaultContainerDeprecated; } int GetActiveDeskContainerId() { // TODO(afakhry): Do proper checking when the other desks containers are // added. - return kShellWindowId_DefaultContainer; + return kShellWindowId_DefaultContainerDeprecated; } -ASH_EXPORT bool IsActiveDeskContainer(aura::Window* container) { +ASH_EXPORT bool IsActiveDeskContainer(const aura::Window* container) { DCHECK(container); return container->id() == GetActiveDeskContainerId(); }
diff --git a/ash/wm/desks/desks_util.h b/ash/wm/desks/desks_util.h index fff0deb..af8c04b 100644 --- a/ash/wm/desks/desks_util.h +++ b/ash/wm/desks/desks_util.h
@@ -28,11 +28,13 @@ ASH_EXPORT const char* GetDeskContainerName(int container_id); -ASH_EXPORT bool IsDeskContainer(aura::Window* container); +ASH_EXPORT bool IsDeskContainer(const aura::Window* container); + +ASH_EXPORT bool IsDeskContainerId(int id); ASH_EXPORT int GetActiveDeskContainerId(); -ASH_EXPORT bool IsActiveDeskContainer(aura::Window* container); +ASH_EXPORT bool IsActiveDeskContainer(const aura::Window* container); ASH_EXPORT aura::Window* GetActiveDeskContainerForRoot(aura::Window* root);
diff --git a/ash/wm/drag_window_resizer_unittest.cc b/ash/wm/drag_window_resizer_unittest.cc index 56d86de..c3ad7b4 100644 --- a/ash/wm/drag_window_resizer_unittest.cc +++ b/ash/wm/drag_window_resizer_unittest.cc
@@ -13,6 +13,7 @@ #include "ash/test/ash_test_base.h" #include "ash/window_factory.h" #include "ash/wm/cursor_manager_test_api.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/drag_window_controller.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_util.h" @@ -608,11 +609,10 @@ // Move window from the root window with 2.0 device scale factor to the root // window with 1.0 device scale factor. { - // Make sure the window is on the default container first. - aura::Window* default_container = - RootWindowController::ForWindow(root_windows[1]) - ->GetContainer(kShellWindowId_DefaultContainer); - default_container->AddChild(window_.get()); + // Make sure the window is on the active desk container first. + aura::Window* active_desk_container = + desks_util::GetActiveDeskContainerForRoot(root_windows[1]); + active_desk_container->AddChild(window_.get()); window_->SetBoundsInScreen( gfx::Rect(600, 0, 50, 60), display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index f254cb8f..facf810 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -219,8 +219,9 @@ return split_view_controller->GetSnappedWindowBoundsInScreen( dragged_window, SplitViewController::LEFT); default: - return screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( - dragged_window); + return screen_util:: + GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + dragged_window); } } @@ -244,8 +245,9 @@ return split_view_controller->GetSnappedWindowBoundsInScreen( dragged_window, SplitViewController::LEFT); default: - return screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( - dragged_window); + return screen_util:: + GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + dragged_window); } }
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 4630bfc..4fa195b 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -66,7 +66,7 @@ gfx::Rect GetGridBoundsInScreen(aura::Window* root_window, bool divider_changed) { gfx::Rect work_area = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( root_window); // If the shelf is in auto hide, overview will force it to be in auto hide
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index efe7449..e85936fc 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -24,6 +24,7 @@ #include "ash/shelf/shelf_view_test_api.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/overview/caption_container_view.h" #include "ash/wm/overview/overview_constants.h" #include "ash/wm/overview/overview_controller.h" @@ -608,7 +609,7 @@ TEST_F(OverviewSessionTest, ActiveWindowChangedUserActionWindowClose) { base::UserActionTester user_action_tester; std::unique_ptr<views::Widget> widget(CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(400, 400))); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(400, 400))); ToggleOverview(); aura::Window* window = widget->GetNativeWindow(); @@ -2759,7 +2760,7 @@ TEST_F(OverviewSessionTest, DraggingFromTopAnimation) { EnterTabletMode(); std::unique_ptr<views::Widget> widget(CreateTestWidget( - nullptr, kShellWindowId_DefaultContainer, gfx::Rect(200, 200))); + nullptr, desks_util::GetActiveDeskContainerId(), gfx::Rect(200, 200))); widget->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, 20); // Drag from the the top of the app to enter overview. @@ -2901,7 +2902,7 @@ } gfx::Rect GetWorkAreaInScreen(aura::Window* window) { - return screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + return screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window); } @@ -4071,7 +4072,7 @@ OverviewItem* overview_item2 = GetWindowItemForWindow(grid_index, window2.get()); const gfx::Rect work_area_rect = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window2.get()); const gfx::PointF end_location2(work_area_rect.width(), 0); DragWindowTo(overview_item2, end_location2);
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index 7cbbf68..3bd0c6f8 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -453,7 +453,7 @@ switch (snap_position) { case SplitViewController::NONE: return gfx::Rect( - screen_util::GetDisplayWorkAreaBoundsInParentForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInParentForActiveDeskContainer( pending_snapped_window)); case SplitViewController::LEFT: return split_view_controller_->GetSnappedWindowBoundsInScreen(
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 6e266a5..fd252d81 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -441,7 +441,8 @@ aura::Window* window, SnapPosition snap_position) { const gfx::Rect work_area_bounds_in_screen = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer(window); + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + window); if (snap_position == NONE) return work_area_bounds_in_screen; @@ -463,7 +464,8 @@ aura::Window* window, SnapPosition snap_position) { const gfx::Rect work_area_bounds_in_screen = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer(window); + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + window); if (snap_position == NONE) return work_area_bounds_in_screen; @@ -479,7 +481,8 @@ int SplitViewController::GetDefaultDividerPosition(aura::Window* window) const { const gfx::Rect work_area_bounds_in_screen = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer(window); + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + window); const gfx::Size divider_size = SplitViewDivider::GetDividerSize( work_area_bounds_in_screen, GetCurrentScreenOrientation(), false /* is_dragging */); @@ -547,7 +550,7 @@ return; presentation_time_recorder_->RequestNext(); const gfx::Rect work_area_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( GetDefaultSnappedWindow()); gfx::Point modified_location_in_screen = GetBoundedPosition(location_in_screen, work_area_bounds); @@ -578,7 +581,7 @@ is_resizing_ = false; const gfx::Rect work_area_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( GetDefaultSnappedWindow()); gfx::Point modified_location_in_screen = GetBoundedPosition(location_in_screen, work_area_bounds); @@ -1042,7 +1045,7 @@ ? location_in_screen.x() : location_in_screen.y(); gfx::Rect work_area_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( GetDefaultSnappedWindow()); if (!IsCurrentScreenOrientationLandscape()) work_area_bounds.Transpose(); @@ -1079,7 +1082,7 @@ SplitViewController::SnapPosition SplitViewController::GetBlackScrimPosition( const gfx::Point& location_in_screen) { const gfx::Rect work_area_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( GetDefaultSnappedWindow()); if (!work_area_bounds.Contains(location_in_screen)) return NONE; @@ -1143,7 +1146,8 @@ gfx::Rect* left_or_top_rect, gfx::Rect* right_or_bottom_rect) { const gfx::Rect work_area_bounds_in_screen = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer(window); + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + window); // |divide_position_| might not be properly initialized yet. divider_position_ = (divider_position_ < 0) @@ -1187,7 +1191,7 @@ DCHECK(IsSplitViewModeActive()); const gfx::Rect work_area_bounds_in_screen = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( GetDefaultSnappedWindow()); const gfx::Size divider_size = SplitViewDivider::GetDividerSize( work_area_bounds_in_screen, GetCurrentScreenOrientation(), @@ -1271,7 +1275,7 @@ int SplitViewController::GetDividerEndPosition() { const gfx::Rect work_area_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( GetDefaultSnappedWindow()); return IsCurrentScreenOrientationLandscape() ? work_area_bounds.width() : work_area_bounds.height();
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index f9ba055..2d952140 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -23,6 +23,7 @@ #include "ash/system/status_area_widget_test_helper.h" #include "ash/test/ash_test_base.h" #include "ash/wallpaper/wallpaper_controller.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/drag_window_resizer.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" @@ -1437,7 +1438,7 @@ EXPECT_TRUE(CanSnapInSplitview(window1.get())); const gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); aura::test::TestWindowDelegate* delegate = static_cast<aura::test::TestWindowDelegate*>(window1->delegate()); @@ -1472,7 +1473,7 @@ OrientationLockType::kLandscapePrimary); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); EXPECT_TRUE(CanSnapInSplitview(window1.get())); split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT); @@ -1516,7 +1517,7 @@ OrientationLockType::kPortraitPrimary); display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); delegate1->set_minimum_size( gfx::Size(display_bounds.width(), display_bounds.height() * 0.4f)); @@ -1546,7 +1547,7 @@ OrientationLockType::kLandscapeSecondary); display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); delegate1->set_minimum_size( gfx::Size(display_bounds.width() * 0.4f, display_bounds.height())); @@ -1578,7 +1579,7 @@ OrientationLockType::kPortraitSecondary); display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); delegate1->set_minimum_size( gfx::Size(display_bounds.width(), display_bounds.height() * 0.4f)); @@ -1616,7 +1617,7 @@ EXPECT_EQ(OrientationLockType::kLandscapePrimary, GetCurrentScreenOrientation()); gfx::Rect workarea_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); // Snap the divider to one third position when there is only left window with @@ -1702,7 +1703,7 @@ const gfx::Rect bounds(0, 0, 200, 300); std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); const gfx::Rect workarea_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); // Divider should be moved to the middle at the beginning. @@ -1845,7 +1846,7 @@ gfx::Rect divider_bounds = split_view_divider()->GetDividerBoundsInScreen(false /* is_dragging */); const int screen_width = - screen_util::GetDisplayWorkAreaBoundsInParentForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInParentForActiveDeskContainer( window1.get()) .width(); GetEventGenerator()->set_current_screen_location( @@ -2128,7 +2129,7 @@ gfx::Rect divider_bounds = split_view_divider()->GetDividerBoundsInScreen(false); gfx::Rect workarea_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window.get()); generator->set_current_screen_location(divider_bounds.CenterPoint()); // Drag the divider to one third position of the work area's width. @@ -2226,7 +2227,7 @@ display::Display::RotationSource::ACTIVE); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window.get()); split_view_controller()->SnapWindow(window.get(), SplitViewController::LEFT); delegate->set_minimum_size( @@ -2269,7 +2270,7 @@ std::unique_ptr<aura::Window> window2(CreateWindow(bounds)); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT); split_view_controller()->SnapWindow(window2.get(), @@ -2339,7 +2340,7 @@ display::Display::RotationSource::ACTIVE); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window.get()); split_view_controller()->SnapWindow(window.get(), SplitViewController::LEFT); delegate->set_minimum_size( @@ -3429,7 +3430,7 @@ window1->GetRootWindow()); EXPECT_TRUE(current_grid->GetDropTarget()); const gfx::Rect work_area_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window1.get()); EXPECT_EQ(current_grid->bounds(), work_area_bounds); // The drop target should be visible. @@ -4328,7 +4329,7 @@ InitializeWindow(false); EXPECT_TRUE(wm::GetWindowState(window())->IsMaximized()); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window()); const float long_scroll_delta = display_bounds.height() / 4 + 5; @@ -4354,7 +4355,7 @@ InitializeWindow(); EXPECT_TRUE(wm::GetWindowState(window())->IsMaximized()); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window()); // Move the window by a small amount of distance will maximize the window @@ -4407,7 +4408,7 @@ ShelfLayoutManager* shelf_layout_manager = AshTestBase::GetPrimaryShelf()->shelf_layout_manager(); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window()); // Shelf will be auto-hidden if the window requests to be fullscreened. @@ -4482,7 +4483,7 @@ InitializeWindow(); EXPECT_TRUE(wm::GetWindowState(window())->IsMaximized()); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window()); const float long_scroll_delta = display_bounds.height() / 4 + 5; @@ -4544,7 +4545,7 @@ SplitViewController::RIGHT); gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window()); const float long_scroll_y = display_bounds.bottom() - 10; float large_velocity = @@ -4662,24 +4663,24 @@ SplitViewController::RIGHT); EXPECT_EQ(window2.get(), wm::GetActiveWindow()); - const aura::Window* default_container = + const aura::Window* active_desk_container = Shell::GetPrimaryRootWindowController()->GetContainer( - kShellWindowId_DefaultContainer); + desks_util::GetActiveDeskContainerId()); // Backdrop window should below two snapped windows and its bounds should be // the same as the container bounds. - EXPECT_EQ(3U, default_container->children().size()); - EXPECT_EQ(window(), default_container->children()[1]); - EXPECT_EQ(window2.get(), default_container->children()[2]); - EXPECT_EQ(default_container->bounds(), - default_container->children()[0]->bounds()); + EXPECT_EQ(3U, active_desk_container->children().size()); + EXPECT_EQ(window(), active_desk_container->children()[1]); + EXPECT_EQ(window2.get(), active_desk_container->children()[2]); + EXPECT_EQ(active_desk_container->bounds(), + active_desk_container->children()[0]->bounds()); // Start window drag and activate the dragged window during drag. gfx::Point location(0, 10); SendScrollStartAndUpdate(location); wm::ActivateWindow(window()); - aura::Window::Windows windows = default_container->children(); + aura::Window::Windows windows = active_desk_container->children(); auto it = std::find(windows.begin(), windows.end(), window2.get()); // Backdrop window should be the window that just below the snapped |window2| // and its bounds should be the same as the snapped window during drag. @@ -4692,12 +4693,12 @@ // Backdrop should restore back to container bounds after drag. EndScrollSequence(); EXPECT_EQ(window(), wm::GetActiveWindow()); - windows = default_container->children(); + windows = active_desk_container->children(); it = std::find(windows.begin(), windows.end(), window2.get()); if (it != windows.begin()) backdrop_window = *(--it); DCHECK(backdrop_window); - EXPECT_EQ(backdrop_window->bounds(), default_container->bounds()); + EXPECT_EQ(backdrop_window->bounds(), active_desk_container->bounds()); } } // namespace ash
diff --git a/ash/wm/splitview/split_view_divider.cc b/ash/wm/splitview/split_view_divider.cc index 8b3587e3..9a5e9bb4 100644 --- a/ash/wm/splitview/split_view_divider.cc +++ b/ash/wm/splitview/split_view_divider.cc
@@ -376,7 +376,7 @@ aura::Window* root_window = divider_widget_->GetNativeWindow()->GetRootWindow(); const gfx::Rect work_area_bounds_in_screen = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( root_window); const int divider_position = controller_->divider_position(); const OrientationLockType screen_orientation = GetCurrentScreenOrientation();
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc index ac1ac926..7083610 100644 --- a/ash/wm/splitview/split_view_utils.cc +++ b/ash/wm/splitview/split_view_utils.cc
@@ -253,7 +253,7 @@ // area size, the window can't be snapped in this case. const gfx::Size min_size = window->delegate()->GetMinimumSize(); const gfx::Rect display_area = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( window); const bool is_landscape = (display_area.width() > display_area.height()); if ((is_landscape && min_size.width() > display_area.width() / 2) ||
diff --git a/ash/wm/switchable_windows.cc b/ash/wm/switchable_windows.cc index be269757..9476fa9 100644 --- a/ash/wm/switchable_windows.cc +++ b/ash/wm/switchable_windows.cc
@@ -12,7 +12,8 @@ namespace wm { const int kSwitchableWindowContainerIds[] = { - kShellWindowId_DefaultContainer, kShellWindowId_AlwaysOnTopContainer}; + kShellWindowId_DefaultContainerDeprecated, + kShellWindowId_AlwaysOnTopContainer}; const size_t kSwitchableWindowContainerIdsLength = base::size(kSwitchableWindowContainerIds);
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc index 1ebc131..59d418a8 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -1318,7 +1318,7 @@ std::unique_ptr<aura::Window> left_window(CreateTestWindowInShellWithDelegate( &left_window_delegate, /*id=*/-1, /*bounds=*/gfx::Rect(0, 0, 400, 400))); const gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( left_window.get()); left_window_delegate.set_minimum_size( gfx::Size(display_bounds.width() * 0.67f, display_bounds.height())); @@ -1350,7 +1350,7 @@ &right_window_delegate, /*id=*/-1, /*bounds=*/gfx::Rect(0, 0, 400, 400))); const gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( right_window.get()); right_window_delegate.set_minimum_size( gfx::Size(display_bounds.width() * 0.67f, display_bounds.height())); @@ -1381,7 +1381,7 @@ &right_window_delegate, /*id=*/-1, /*bounds=*/gfx::Rect(0, 0, 400, 400))); const gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( right_window.get()); right_window_delegate.set_minimum_size( gfx::Size(display_bounds.width() * 0.67f, display_bounds.height())); @@ -1410,7 +1410,7 @@ std::unique_ptr<aura::Window> left_window(CreateTestWindowInShellWithDelegate( &left_window_delegate, /*id=*/-1, /*bounds=*/gfx::Rect(0, 0, 400, 400))); const gfx::Rect display_bounds = - screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer( + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( left_window.get()); left_window_delegate.set_minimum_size( gfx::Size(display_bounds.width() * 0.67f, display_bounds.height()));
diff --git a/ash/wm/top_level_window_factory_unittest.cc b/ash/wm/top_level_window_factory_unittest.cc index cdd9ebfe..432b77b 100644 --- a/ash/wm/top_level_window_factory_unittest.cc +++ b/ash/wm/top_level_window_factory_unittest.cc
@@ -13,6 +13,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_properties.h" #include "mojo/public/cpp/bindings/map.h" #include "services/ws/public/cpp/property_type_converters.h" @@ -106,7 +107,7 @@ aura::Window* window = GetWindowTreeTestHelper()->NewTopLevelWindow( mojo::MapToFlatMap(std::move(properties))); ASSERT_TRUE(window->parent()); - EXPECT_EQ(kShellWindowId_DefaultContainer, window->parent()->id()); + EXPECT_EQ(desks_util::GetActiveDeskContainerId(), window->parent()->id()); EXPECT_EQ(bounds, window->bounds()); EXPECT_FALSE(window->IsVisible()); }
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index 6ba1b4f2..211ecc9 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -9,6 +9,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/window_factory.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/resize_shadow.h" #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/window_state.h" @@ -102,8 +103,8 @@ .release(); w1->set_id(1); w1->Init(ui::LAYER_TEXTURED); - aura::Window* parent = Shell::GetContainer(Shell::GetPrimaryRootWindow(), - kShellWindowId_DefaultContainer); + aura::Window* parent = Shell::GetContainer( + Shell::GetPrimaryRootWindow(), desks_util::GetActiveDeskContainerId()); parent->AddChild(w1); w1->SetBounds(gfx::Rect(0, 0, 100, 100)); w1->Show();
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index 6931263c..b71f0689 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -30,6 +30,7 @@ #include "ash/wallpaper/wallpaper_controller_test_api.h" #include "ash/window_factory.h" #include "ash/wm/always_on_top_controller.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/fullscreen_window_finder.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/splitview/split_view_controller.h" @@ -450,10 +451,10 @@ window_factory::NewWindow(nullptr, aura::client::WINDOW_TYPE_NORMAL); window->Init(ui::LAYER_TEXTURED); window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); - aura::Window* default_container = + aura::Window* active_desk_container = Shell::GetPrimaryRootWindowController()->GetContainer( - kShellWindowId_DefaultContainer); - default_container->AddChild(window.get()); + desks_util::GetActiveDeskContainerId()); + active_desk_container->AddChild(window.get()); window->Show(); gfx::Rect work_area(GetPrimaryDisplay().work_area()); EXPECT_EQ(work_area.ToString(), window->GetBoundsInScreen().ToString()); @@ -1130,7 +1131,7 @@ AshTestBase::SetUp(); UpdateDisplay("800x600"); default_container_ = Shell::GetPrimaryRootWindowController()->GetContainer( - kShellWindowId_DefaultContainer); + desks_util::GetActiveDeskContainerId()); } // Turn the top window back drop on / off. @@ -1649,10 +1650,10 @@ void SetUp() override { AshTestBase::SetUp(); UpdateDisplay("800x600"); - aura::Window* default_container = + aura::Window* active_desk_container = Shell::GetPrimaryRootWindowController()->GetContainer( - kShellWindowId_DefaultContainer); - layout_manager_ = GetWorkspaceLayoutManager(default_container); + desks_util::GetActiveDeskContainerId()); + layout_manager_ = GetWorkspaceLayoutManager(active_desk_container); } void ShowKeyboard() {
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index 84a9346..d2e5dc7b 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -16,6 +16,7 @@ #include "ash/screen_util.h" #include "ash/shell.h" #include "ash/wm/default_window_resizer.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/drag_window_resizer.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/pip/pip_window_resizer.h" @@ -182,7 +183,8 @@ const int parent_shell_window_id = window->parent() ? window->parent()->id() : -1; if (window->parent() && - (parent_shell_window_id == kShellWindowId_DefaultContainer || + // TODO(afakhry): Maybe use switchable containers? + (desks_util::IsDeskContainerId(parent_shell_window_id) || parent_shell_window_id == kShellWindowId_AlwaysOnTopContainer)) { window_resizer.reset(WorkspaceWindowResizer::Create( window_state, std::vector<aura::Window*>())); @@ -899,8 +901,10 @@ aura::Window* root_window = Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId( display.id()); - const std::vector<aura::Window*>& children = - root_window->GetChildById(kShellWindowId_DefaultContainer)->children(); + aura::Window* container = + desks_util::GetActiveDeskContainerForRoot(root_window); + DCHECK(container); + const std::vector<aura::Window*>& children = container->children(); for (auto i = children.rbegin(); i != children.rend() && !matcher.AreEdgesObscured(); ++i) { wm::WindowState* other_state = wm::GetWindowState(*i);
diff --git a/ash/wm/workspace_controller_unittest.cc b/ash/wm/workspace_controller_unittest.cc index 9db34819..67d62f5 100644 --- a/ash/wm/workspace_controller_unittest.cc +++ b/ash/wm/workspace_controller_unittest.cc
@@ -17,6 +17,7 @@ #include "ash/system/status_area_widget.h" #include "ash/test/ash_test_base.h" #include "ash/window_factory.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" @@ -114,7 +115,7 @@ aura::Window* GetDesktop() { return Shell::GetContainer(Shell::GetPrimaryRootWindow(), - kShellWindowId_DefaultContainer); + desks_util::GetActiveDeskContainerId()); } gfx::Rect GetFullscreenBounds(aura::Window* window) {
diff --git a/ash/ws/ax_ash_window_utils_unittest.cc b/ash/ws/ax_ash_window_utils_unittest.cc index 57bcfc1d..7185607 100644 --- a/ash/ws/ax_ash_window_utils_unittest.cc +++ b/ash/ws/ax_ash_window_utils_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" +#include "ash/wm/desks/desks_util.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_action_data.h" @@ -137,7 +138,7 @@ // Start with the widget's container. aura::Window* container = Shell::GetContainer( - Shell::GetPrimaryRootWindow(), kShellWindowId_DefaultContainer); + Shell::GetPrimaryRootWindow(), desks_util::GetActiveDeskContainerId()); EXPECT_EQ(aura::Env::Mode::LOCAL, container->env()->mode()); // Walking down "jumps the fence" into the client window.
diff --git a/ash/ws/window_service_delegate_impl_unittest.cc b/ash/ws/window_service_delegate_impl_unittest.cc index bfd32f8..84cc348 100644 --- a/ash/ws/window_service_delegate_impl_unittest.cc +++ b/ash/ws/window_service_delegate_impl_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/frame/non_client_frame_view_ash.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/resize_shadow.h" #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/toplevel_window_event_handler.h" @@ -400,9 +401,9 @@ TEST_F(WindowServiceDelegateImplTest, ObserveTopmostWindow) { std::unique_ptr<aura::Window> window2 = CreateTestWindow(gfx::Rect(150, 100, 100, 100)); - std::unique_ptr<aura::Window> window3( - CreateTestWindowInShell(SK_ColorRED, kShellWindowId_DefaultContainer, - gfx::Rect(100, 150, 100, 100))); + std::unique_ptr<aura::Window> window3(CreateTestWindowInShell( + SK_ColorRED, desks_util::GetActiveDeskContainerId(), + gfx::Rect(100, 150, 100, 100))); // Left button is pressed on SetUp() -- release it first. GetEventGenerator()->ReleaseLeftButton();
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 83ed4b1..6512667a 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8916548565018644928 \ No newline at end of file +8916518872782926384 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index fa67335..f39818f 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8916561048598159552 \ No newline at end of file +8916520934446696624 \ No newline at end of file
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index cef5e05..18d503a 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -441,8 +441,12 @@ "//components/module_installer/android:module_interface_processor", ] + proguard_configs = [] if (async_ar) { - proguard_configs = [ "//chrome/android/features/ar/proguard_async.flags" ] + proguard_configs += [ "//chrome/android/features/ar/proguard_async.flags" ] + } + if (async_vr) { + proguard_configs += [ "//chrome/android/features/vr/proguard_async.flags" ] } processor_args_javac = [ "dagger.fastInit=enabled" ] @@ -2158,6 +2162,7 @@ { name = "vr" module_target = ":${target_name}__vr_bundle_module" + proguard_async = async_vr }, ] } @@ -2443,6 +2448,7 @@ "java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java", "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfAndroidBridge.java", "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfEntry.java", + "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfInfoBar.java", "java/src/org/chromium/chrome/browser/sessions/SessionTabHelper.java", "java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java", "java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 55f82c9..aab9de73 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1411,6 +1411,7 @@ "java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java", "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfAndroidBridge.java", "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfEntry.java", + "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfInfoBar.java", "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfShareActivity.java", "java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java", "java/src/org/chromium/chrome/browser/services/AndroidEduAndChildAccountHelper.java",
diff --git a/chrome/android/features/vr/BUILD.gn b/chrome/android/features/vr/BUILD.gn index 3f76fb5..00038cff 100644 --- a/chrome/android/features/vr/BUILD.gn +++ b/chrome/android/features/vr/BUILD.gn
@@ -133,6 +133,10 @@ "//third_party/gvr-android-keyboard:kb_java", "//third_party/gvr-android-sdk:gvr_common_java", ] + + if (async_vr) { + proguard_configs = [ "//base/android/proguard/chromium_code.flags" ] + } } generate_jni("jni_headers") {
diff --git a/chrome/android/features/vr/proguard_async.flags b/chrome/android/features/vr/proguard_async.flags new file mode 100644 index 0000000..1b4893d --- /dev/null +++ b/chrome/android/features/vr/proguard_async.flags
@@ -0,0 +1,118 @@ +# Copyright 2019 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. + +# Contains flags necessary to keep the VR module compatible with base when VR +# is specified as an async DFM (when the VR module is proguarded separately). +# This flags file was generated from the dependencies of Java classes in +# src/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/ +# produced using the jdeps tool. It intentionally keeps all members from these +# dependencies to ensure compatibility between the async VR module and base. + +# TODO(cuianthony): Reduce the scope of these keep rules by parsing information +# from constant pools of relevant Java classes. + +-keep class org.chromium.base.ActivityState { *; } +-keep class org.chromium.base.ApiCompatibilityUtils { *; } +-keep class org.chromium.base.ApplicationStatus { *; } +-keep class org.chromium.base.ApplicationStatus$ActivityStateListener { *; } +-keep class org.chromium.base.Callback { *; } +-keep class org.chromium.base.ContextUtils { *; } +-keep class org.chromium.base.Log { *; } +-keep class org.chromium.base.PackageUtils { *; } +-keep class org.chromium.base.StrictModeContext { *; } +-keep class org.chromium.base.ThreadUtils { *; } +-keep class org.chromium.base.TraceEvent { *; } +-keep class org.chromium.base.annotations.JNINamespace { *; } +-keep class org.chromium.base.library_loader.LibraryLoader { *; } +-keep class org.chromium.base.metrics.CachedMetrics { *; } +-keep class org.chromium.base.metrics.CachedMetrics$BooleanHistogramSample { *; } +-keep class org.chromium.base.metrics.RecordUserAction { *; } +-keep class org.chromium.base.task.AsyncTask { *; } +-keep class org.chromium.base.task.PostTask { *; } +-keep class org.chromium.base.task.TaskTraits { *; } +-keep class org.chromium.chrome.R { *; } +-keep class org.chromium.chrome.R$anim { *; } +-keep class org.chromium.chrome.R$id { *; } +-keep class org.chromium.chrome.R$layout { *; } +-keep class org.chromium.chrome.R$string { *; } +-keep class org.chromium.chrome.R$style { *; } +-keep class org.chromium.chrome.browser.ApplicationLifetime { *; } +-keep class org.chromium.chrome.browser.ChromeActivity { *; } +-keep class org.chromium.chrome.browser.ChromeFeatureList { *; } +-keep class org.chromium.chrome.browser.ChromeTabbedActivity { *; } +-keep class org.chromium.chrome.browser.compositor.CompositorSurfaceManager { *; } +-keep class org.chromium.chrome.browser.compositor.CompositorSurfaceManager$SurfaceManagerCallbackTarget { *; } +-keep class org.chromium.chrome.browser.compositor.CompositorView { *; } +-keep class org.chromium.chrome.browser.compositor.CompositorViewHolder { *; } +-keep class org.chromium.chrome.browser.customtabs.CustomTabActivity { *; } +-keep class org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager { *; } +-keep class org.chromium.chrome.browser.help.HelpAndFeedback { *; } +-keep class org.chromium.chrome.browser.infobar.InfoBarIdentifier { *; } +-keep class org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder { *; } +-keep class org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder$Listener { *; } +-keep class org.chromium.chrome.browser.modaldialog.ModalDialogView { *; } +-keep class org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder { *; } +-keep class org.chromium.chrome.browser.page_info.PageInfoController { *; } +-keep class org.chromium.chrome.browser.page_info.PageInfoController$OpenedFromSource { *; } +-keep class org.chromium.chrome.browser.preferences.ChromePreferenceManager { *; } +-keep class org.chromium.chrome.browser.profiles.Profile { *; } +-keep class org.chromium.chrome.browser.tab.EmptyTabObserver { *; } +-keep class org.chromium.chrome.browser.tab.Tab { *; } +-keep class org.chromium.chrome.browser.tab.TabObserver { *; } +-keep class org.chromium.chrome.browser.tab.TabRedirectHandler { *; } +-keep class org.chromium.chrome.browser.tabmodel.ChromeTabCreator { *; } +-keep class org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabCreatorManager { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabCreatorManager$TabCreator { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabLaunchType { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabModel { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabModelSelector { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver { *; } +-keep class org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver { *; } +-keep class org.chromium.chrome.browser.toolbar.NewTabButton { *; } +-keep class org.chromium.chrome.browser.toolbar.ToolbarManager { *; } +-keep class org.chromium.chrome.browser.util.FeatureUtilities { *; } +-keep class org.chromium.chrome.browser.util.IntentUtils { *; } +-keep class org.chromium.chrome.browser.vr.OnExitVrRequestListener { *; } +-keep class org.chromium.chrome.browser.vr.VrDelegate { *; } +-keep class org.chromium.chrome.browser.vr.VrDelegateProvider { *; } +-keep class org.chromium.chrome.browser.vr.VrIntentDelegate { *; } +-keep class org.chromium.chrome.browser.vr.VrModuleProvider { *; } +-keep class org.chromium.chrome.browser.webapps.WebappActivity { *; } +-keep class org.chromium.chrome.browser.widget.findinpage.FindToolbarManager { *; } +-keep class org.chromium.content_public.browser.ImeAdapter { *; } +-keep class org.chromium.content_public.browser.InputMethodManagerWrapper { *; } +-keep class org.chromium.content_public.browser.LoadUrlParams { *; } +-keep class org.chromium.content_public.browser.MotionEventSynthesizer { *; } +-keep class org.chromium.content_public.browser.ScreenOrientationDelegate { *; } +-keep class org.chromium.content_public.browser.ScreenOrientationProvider { *; } +-keep class org.chromium.content_public.browser.UiThreadTaskTraits { *; } +-keep class org.chromium.content_public.browser.ViewEventSink { *; } +-keep class org.chromium.content_public.browser.WebContents { *; } +-keep class org.chromium.content_public.common.BrowserControlsState { *; } +-keep class org.chromium.ui.UiUtils { *; } +-keep class org.chromium.ui.base.ActivityWindowAndroid { *; } +-keep class org.chromium.ui.base.AndroidPermissionDelegate { *; } +-keep class org.chromium.ui.base.EventForwarder { *; } +-keep class org.chromium.ui.base.PermissionCallback { *; } +-keep class org.chromium.ui.base.WindowAndroid { *; } +-keep class org.chromium.ui.base.WindowAndroid$IntentCallback { *; } +-keep class org.chromium.ui.display.DisplayAndroid { *; } +-keep class org.chromium.ui.display.VirtualDisplayAndroid { *; } +-keep class org.chromium.ui.modaldialog.DialogDismissalCause { *; } +-keep class org.chromium.ui.modaldialog.ModalDialogManager { *; } +-keep class org.chromium.ui.modaldialog.ModalDialogManager$ModalDialogType { *; } +-keep class org.chromium.ui.modaldialog.ModalDialogManager$Presenter { *; } +-keep class org.chromium.ui.modaldialog.ModalDialogProperties { *; } +-keep class org.chromium.ui.modaldialog.ModalDialogProperties$ButtonType { *; } +-keep class org.chromium.ui.modaldialog.ModalDialogProperties$Controller { *; } +-keep class org.chromium.ui.modelutil.PropertyKey { *; } +-keep class org.chromium.ui.modelutil.PropertyModel { *; } +-keep class org.chromium.ui.modelutil.PropertyModel$Builder { *; } +-keep class org.chromium.ui.modelutil.PropertyModel$ReadableObjectPropertyKey { *; } +-keep class org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey { *; } +-keep class org.chromium.ui.modelutil.PropertyModelChangeProcessor { *; } +-keep class org.chromium.ui.modelutil.PropertyModelChangeProcessor$ViewBinder { *; } +-keep class org.chromium.ui.modelutil.PropertyObservable { *; } +-keep class org.chromium.ui.widget.UiWidgetFactory { *; } \ No newline at end of file
diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml index 3e1c382f..38bf90e 100644 --- a/chrome/android/java/res/xml/privacy_preferences.xml +++ b/chrome/android/java/res/xml/privacy_preferences.xml
@@ -34,7 +34,7 @@ android:key="can_make_payment" android:title="@string/can_make_payment_title" android:summary="@string/settings_can_make_payment_toggle_label" /> - <Preference + <org.chromium.chrome.browser.preferences.ChromeBasePreference android:key="usage_stats_reporting" android:title="@string/usage_stats_setting_title" android:persistent="false" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java index 501b675..bd1556d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java
@@ -19,6 +19,7 @@ import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.content.R; import org.chromium.content_public.browser.ActionModeCallbackHelper; @@ -112,7 +113,8 @@ private void search(String searchText) { RecordUserAction.record("MobileActionMode.WebSearch"); - if (mTab.getTabModelSelector() == null) return; + TabModelSelector selector = TabModelSelector.from(mTab); + if (selector == null) return; String query = ActionModeCallbackHelper.sanitizeQuery( searchText, ActionModeCallbackHelper.MAX_SEARCH_QUERY_LENGTH); @@ -120,7 +122,7 @@ TrackerFactory.getTrackerForProfile(mTab.getProfile()) .notifyEvent(EventConstants.WEB_SEARCH_PERFORMED); - mTab.getTabModelSelector().openNewTab(generateUrlParamsForSearch(query), + selector.openNewTab(generateUrlParamsForSearch(query), TabLaunchType.FROM_LONGPRESS_FOREGROUND, mTab, mTab.isIncognito()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabCreatorManager.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabCreatorManager.java index 6802bd9..27fb36e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabCreatorManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabCreatorManager.java
@@ -73,8 +73,8 @@ } @Override - public boolean createTabWithWebContents(Tab parent, WebContents webContents, int parentId, - @TabLaunchType int type, String url) { + public boolean createTabWithWebContents( + Tab parent, WebContents webContents, @TabLaunchType int type, String url) { throw new UnsupportedOperationException( "Browser Actions does not support createTabWithWebContents"); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java index 258d0995..fec0fcbd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java
@@ -93,9 +93,10 @@ IntentUtils.safeGetIntExtra(intent, IntentHandler.EXTRA_TAB_ID, Tab.INVALID_TAB_ID); int parentTabId = IntentUtils.safeGetIntExtra( intent, IntentHandler.EXTRA_PARENT_TAB_ID, Tab.INVALID_TAB_ID); + Tab parent = mTabModelSelector != null ? mTabModelSelector.getTabById(parentTabId) : null; return new TabBuilder() .setId(assignedTabId) - .setParentId(parentTabId) + .setParent(parent) .setIncognito(mIntentDataProvider.isIncognito()) .setWindow(mActivityWindowAndroid.get()) .setLaunchType(TabLaunchType.FROM_EXTERNAL_APP)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java index 91c7572..534d0e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java
@@ -280,7 +280,7 @@ || contents.getNavigationController().isInitialNavigation(); if (isInitialNavigation) { // Tab is created just for download, close it. - TabModelSelector selector = tab.getTabModelSelector(); + TabModelSelector selector = TabModelSelector.from(tab); if (selector == null) return true; if (selector.getModel(tab.isIncognito()).getCount() == 1) return false; boolean closed = selector.closeTab(tab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index 464519d7..4055e2a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -726,6 +726,8 @@ + intent.getData().getScheme(), ex); } catch (SecurityException ex) { Log.d(TAG, "cannot open intent: " + intent, ex); + } catch (Exception ex) { + Log.d(TAG, "cannot open intent: " + intent, ex); } return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCoordinator.java index 00c97d95..496d7fe7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCoordinator.java
@@ -42,6 +42,10 @@ .build(); mOnClickEventCallback = onClickCallback; mOnDismissEventCallback = dismissCallback; + + mRenameDialogCustomView.setEmptyInputObserver((result) -> { + mRenameDialogModel.set(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, result); + }); } public void destroy() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java index c7c7e339..7c1c946 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogCustomView.java
@@ -7,13 +7,16 @@ import static android.content.Context.INPUT_METHOD_SERVICE; import android.content.Context; +import android.text.Editable; import android.text.TextUtils; +import android.text.TextWatcher; import android.util.AttributeSet; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.ScrollView; import android.widget.TextView; +import org.chromium.base.Callback; import org.chromium.chrome.browser.widget.AlertDialogEditText; import org.chromium.chrome.download.R; import org.chromium.components.offline_items_collection.RenameResult; @@ -24,6 +27,7 @@ public class RenameDialogCustomView extends ScrollView { private TextView mSubtitleView; private AlertDialogEditText mFileName; + private Callback</*Empty*/ Boolean> mEmptyFileNameObserver; public RenameDialogCustomView(Context context, AttributeSet attrs) { super(context, attrs); @@ -35,6 +39,26 @@ super.onFinishInflate(); mSubtitleView = findViewById(R.id.subtitle); mFileName = findViewById(R.id.file_name); + mFileName.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + if (mEmptyFileNameObserver == null) return; + mEmptyFileNameObserver.onResult(getTargetName().isEmpty()); + } + }); + } + + /** + * @param callback Callback to run when edit text is empty. + */ + public void setEmptyInputObserver(Callback<Boolean> callback) { + mEmptyFileNameObserver = callback; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogManager.java index 7fccfbc..f6490574 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/rename/RenameDialogManager.java
@@ -158,9 +158,6 @@ if (isPositiveButton) { mLastAttemptedName = mRenameDialogCoordinator.getCurSuggestedName(); - // TODO(hesen): Have a TextWatcher on the input, and disable OK button if it's empty. - if (TextUtils.isEmpty(mLastAttemptedName)) return; - if (TextUtils.equals(mLastAttemptedName, mOriginalName)) { processDialogState(RenameDialogState.RENAME_DIALOG_CANCEL, DialogDismissalCause.POSITIVE_BUTTON_CLICKED);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java index ebc7d749..1503499 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.content_public.browser.WebContents; @@ -212,16 +213,17 @@ new DismissActivityOnTabModelSelectorEventObserver(activity); final WebContentsObserver webContentsObserver = new DismissActivityOnWebContentsObserver(activity); + final TabModelSelector tabModelSelector = TabModelSelector.from(activityTab); activityTab.addObserver(tabObserver); - activityTab.getTabModelSelector().addObserver(tabModelSelectorObserver); + tabModelSelector.addObserver(tabModelSelectorObserver); webContents.addObserver(webContentsObserver); mOnLeavePipCallbacks.add(new Callback<ChromeActivity>() { @Override public void onResult(ChromeActivity activity2) { activityTab.removeObserver(tabObserver); - activityTab.getTabModelSelector().removeObserver(tabModelSelectorObserver); + tabModelSelector.removeObserver(tabModelSelectorObserver); webContents.removeObserver(webContentsObserver); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java index 2394eff6..fc81539 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
@@ -133,20 +133,17 @@ * @param url The URL to be handled. * @param candidatePage A NativePage to be reused if it matches the url, or null. * @param tab The Tab that will show the page. - * @param tabModelSelector The TabModelSelector containing the tab. * @param activity The activity used to create the views for the page. * @return A NativePage showing the specified url or null. */ - public static NativePage createNativePageForURL(String url, NativePage candidatePage, - Tab tab, TabModelSelector tabModelSelector, ChromeActivity activity) { - return createNativePageForURL(url, candidatePage, tab, tabModelSelector, activity, - tab.isIncognito()); + public static NativePage createNativePageForURL( + String url, NativePage candidatePage, Tab tab, ChromeActivity activity) { + return createNativePageForURL(url, candidatePage, tab, activity, tab.isIncognito()); } @VisibleForTesting - static NativePage createNativePageForURL(String url, NativePage candidatePage, - Tab tab, TabModelSelector tabModelSelector, ChromeActivity activity, - boolean isIncognito) { + static NativePage createNativePageForURL(String url, NativePage candidatePage, Tab tab, + ChromeActivity activity, boolean isIncognito) { NativePage page; switch (nativePageType(url, candidatePage, isIncognito)) { @@ -156,7 +153,8 @@ page = candidatePage; break; case NativePageType.NTP: - page = sNativePageBuilder.buildNewTabPage(activity, tab, tabModelSelector); + page = sNativePageBuilder.buildNewTabPage( + activity, tab, TabModelSelector.from(tab)); break; case NativePageType.BOOKMARKS: page = sNativePageBuilder.buildBookmarksPage(activity, tab); @@ -209,7 +207,7 @@ @Override public int loadUrl(LoadUrlParams urlParams, boolean incognito) { if (incognito && !mTab.isIncognito()) { - mTab.getTabModelSelector().openNewTab(urlParams, + TabModelSelector.from(mTab).openNewTab(urlParams, TabLaunchType.FROM_LONGPRESS_FOREGROUND, mTab, /* incognito = */ true); return TabLoadStatus.DEFAULT_PAGE_LOAD; @@ -235,7 +233,7 @@ @Override public boolean isVisible() { - return mTab == mTab.getTabModelSelector().getCurrentTab(); + return mTab == TabModelSelector.from(mTab).getCurrentTab(); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfInfoBar.java new file mode 100644 index 0000000..2d5dee6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfInfoBar.java
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.send_tab_to_self; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.infobar.InfoBar; +import org.chromium.chrome.browser.infobar.InfoBarCompactLayout; + +/** + * This infobar is shown to let users know they have a shared tab from another + * device that can be opened on this one. + */ +public class SendTabToSelfInfoBar extends InfoBar { + public SendTabToSelfInfoBar() { + // TODO(crbug.com/949233): Update this to the right icon + super(R.drawable.infobar_chrome, null, null); + } + + @Override + protected boolean usesCompactLayout() { + return true; + } + + @Override + protected void createCompactLayoutContent(InfoBarCompactLayout layout) { + new InfoBarCompactLayout.MessageBuilder(layout) + .withText("Tab shared") + // TODO(crbug.com/949233): Add the link in + // .withLink(textResId, onTapCallback) + .buildAndInsert(); + } + + @CalledByNative + private static SendTabToSelfInfoBar create() { + return new SendTabToSelfInfoBar(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java index 518e0de..9e5421d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java
@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.OverrideUrlLoadingResult; import org.chromium.chrome.browser.externalnav.ExternalNavigationParams; import org.chromium.chrome.browser.tabmodel.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.components.navigation_interception.NavigationParams; import org.chromium.content_public.browser.NavigationController; @@ -312,7 +313,7 @@ PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { - mTab.getTabModelSelector().closeTab(mTab); + TabModelSelector.from(mTab).closeTab(mTab); } }); } else if (TabRedirectHandler.from(mTab).isOnNavigation()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index d1f53d15..795cb93 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -153,7 +153,12 @@ * caused it to be opened so that we can activate it when this tab gets * closed. */ - private int mParentId = INVALID_TAB_ID; + private final int mParentId; + + /** + * Tab id to be used as a source tab in SyncedTabDelegate. + */ + private final int mSourceTabId; /** * By default, this id inherits from the tab that caused it to be opened, or it equals to tab @@ -289,7 +294,7 @@ * Package-private. Use {@link TabBuilder} to create an instance. * * @param id The id this tab should be identified with. - * @param parentId The id id of the tab that caused this tab to be opened. + * @param parent The tab that caused this tab to be opened. * @param incognito Whether or not this tab is incognito. * @param window An instance of a {@link WindowAndroid}. * @param launchType Type indicating how this tab was launched. @@ -297,12 +302,20 @@ * @param loadUrlParams Parameters used for a lazily loaded Tab. */ @SuppressLint("HandlerLeak") - Tab(int id, int parentId, boolean incognito, WindowAndroid window, + Tab(int id, Tab parent, boolean incognito, WindowAndroid window, @Nullable @TabLaunchType Integer launchType, @Nullable @TabCreationState Integer creationState, LoadUrlParams loadUrlParams) { mId = TabIdManager.getInstance().generateValidId(id); - mParentId = parentId; mIncognito = incognito; + if (parent == null) { + mParentId = INVALID_TAB_ID; + mSourceTabId = INVALID_TAB_ID; + mRootId = mId; + } else { + mParentId = parent.getId(); + mSourceTabId = parent.isIncognito() == incognito ? mParentId : INVALID_TAB_ID; + mRootId = parent.getRootId(); + } // Override the configuration for night mode to always stay in light mode until all UIs in // Tab are inflated from activity context instead of application context. This is to avoid @@ -328,13 +341,6 @@ TabHelpers.initTabHelpers(this, creationState); - if (mParentId == INVALID_TAB_ID || getTabModelSelector() == null - || getTabModelSelector().getTabById(mParentId) == null) { - mRootId = mId; - } else { - mRootId = getTabModelSelector().getTabById(mParentId).getRootId(); - } - mAttachStateChangeListener = new OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View view) { @@ -570,15 +576,6 @@ return context == context.getApplicationContext() ? getThemedApplicationContext() : context; } - /** - * @return {@link TabModelSelector} that currently hosts the {@link TabModel} for this - * {@link Tab}. - */ - public TabModelSelector getTabModelSelector() { - if (getActivity() == null) return null; - return getActivity().getTabModelSelector(); - } - /** @return WebContentsState representing the state of the WebContents (navigations, etc.) */ WebContentsState getFrozenContentsState() { return mFrozenContentsState; @@ -995,11 +992,8 @@ WebContents webContents = getWebContents(); if (webContents != null) webContents.setTopLevelNativeWindow(null); - TabModelSelector tabModelSelector = getTabModelSelector(); - if (tabModelSelector != null) { - tabModelSelector.getModel(mIncognito).removeTab(this); - } - + // TabModelSelector of this Tab, if present, gets notified to remove the tab from + // the TabModel it belonged to. for (TabObserver observer : mObservers) { observer.onActivityAttachmentChanged(this, false); } @@ -1215,17 +1209,9 @@ mWebContentsDelegate = mDelegateFactory.createWebContentsDelegate(this); - int parentId = getParentId(); - if (parentId != INVALID_TAB_ID) { - Tab parentTab = getTabModelSelector().getTabById(parentId); - if (parentTab != null && parentTab.isIncognito() != isIncognito()) { - parentId = INVALID_TAB_ID; - } - } - assert mNativeTabAndroid != 0; nativeInitWebContents(mNativeTabAndroid, mIncognito, isDetached(), webContents, - parentId, mWebContentsDelegate, + mSourceTabId, mWebContentsDelegate, new TabContextMenuPopulator( mDelegateFactory.createContextMenuPopulator(this), this)); @@ -1253,8 +1239,8 @@ // completed. if (isDetached()) return false; NativePage candidateForReuse = forceReload ? null : getNativePage(); - NativePage nativePage = NativePageFactory.createNativePageForURL(url, candidateForReuse, - this, getTabModelSelector(), getActivity()); + NativePage nativePage = NativePageFactory.createNativePageForURL( + url, candidateForReuse, this, getActivity()); if (nativePage != null) { showNativePage(nativePage); notifyPageTitleChanged();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java index c8f18054..ba1785c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java
@@ -15,7 +15,7 @@ */ public class TabBuilder { private int mId = Tab.INVALID_TAB_ID; - private int mParentId = Tab.INVALID_TAB_ID; + private Tab mParent; private boolean mIncognito; private WindowAndroid mWindow; private Integer mLaunchType; @@ -34,12 +34,12 @@ } /** - * Sets the id of the tab from which the new one is opened. - * @param parentId The id of the parent Tab. + * Sets the tab from which the new one is opened. + * @param parent The parent Tab. * @return {@link TabBuilder} creating the Tab. */ - public TabBuilder setParentId(int parentId) { - mParentId = parentId; + public TabBuilder setParent(Tab parent) { + mParent = parent; return this; } @@ -87,7 +87,7 @@ } return new Tab( - mId, mParentId, mIncognito, mWindow, mLaunchType, mCreationType, mLoadUrlParams); + mId, mParent, mIncognito, mWindow, mLaunchType, mCreationType, mLoadUrlParams); } private TabBuilder setCreationType(@TabCreationState int type) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index b960310..c60f254 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -25,6 +25,7 @@ import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.tabmodel.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.UrlUtilities; @@ -173,7 +174,7 @@ RecordUserAction.record("LinkOpenedInNewTab"); LoadUrlParams loadUrlParams = new LoadUrlParams(url); loadUrlParams.setReferrer(referrer); - mTab.getTabModelSelector().openNewTab( + TabModelSelector.from(mTab).openNewTab( loadUrlParams, TabLaunchType.FROM_LONGPRESS_BACKGROUND, mTab, isIncognito()); } @@ -191,8 +192,8 @@ @Override public void onOpenInNewIncognitoTab(String url) { RecordUserAction.record("MobileNewTabOpened"); - mTab.getTabModelSelector().openNewTab(new LoadUrlParams(url), - TabLaunchType.FROM_LONGPRESS_FOREGROUND, mTab, true); + TabModelSelector.from(mTab).openNewTab( + new LoadUrlParams(url), TabLaunchType.FROM_LONGPRESS_FOREGROUND, mTab, true); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabParentIntent.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabParentIntent.java index 0d11c3d..c31f491d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabParentIntent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabParentIntent.java
@@ -8,6 +8,7 @@ import org.chromium.base.UserData; import org.chromium.base.UserDataHost; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; /** * A holder of {@link Intent} object to be used to bring back the parent {@link Activity} @@ -40,7 +41,7 @@ @Override public void onCloseContents(Tab tab) { - boolean isSelected = mTab.getTabModelSelector().getCurrentTab() == tab; + boolean isSelected = TabModelSelector.from(mTab).getCurrentTab() == tab; // If the parent Tab belongs to another Activity, fire the Intent to bring it back. if (isSelected && mParentIntent != null && tab.getActivity().getIntent() != mParentIntent) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java index 48302ee..d2f546c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java
@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabSelectionType; import org.chromium.net.NetError; @@ -242,7 +243,7 @@ @Override public void onShown(Tab tab, @TabSelectionType int selectionType) { - int rank = computeMRURank(tab, tab.getTabModelSelector().getModel(tab.isIncognito())); + int rank = computeMRURank(tab, TabModelSelector.from(tab).getModel(tab.isIncognito())); long previousTimestampMillis = tab.getTimestampMillis(); long now = SystemClock.elapsedRealtime(); @@ -323,7 +324,7 @@ } } }; - tab.getTabModelSelector().addObserver(mNewTabObserver); + TabModelSelector.from(tab).addObserver(mNewTabObserver); } // Record "tab age upon first display" metrics. previousTimestampMillis is persisted through @@ -371,7 +372,7 @@ } private void removeObservers(Tab tab) { - if (mNewTabObserver != null) tab.getTabModelSelector().removeObserver(mNewTabObserver); + if (mNewTabObserver != null) TabModelSelector.from(tab).removeObserver(mNewTabObserver); tab.removeObserver(this); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java index 98448f4..dcc7a15 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java
@@ -41,6 +41,7 @@ import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator; import org.chromium.chrome.browser.tabmodel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.tabmodel.TabWindowManager; import org.chromium.chrome.browser.util.IntentUtils; @@ -91,7 +92,7 @@ mHandler = new Handler(); mCloseContentsRunnable = () -> { // TODO(jinsukkim): Move |closeTab| to TabModelSelector by making it observe its tabs. - mTab.getTabModelSelector().closeTab(mTab); + TabModelSelector.from(mTab).closeTab(mTab); RewindableIterator<TabObserver> observers = mTab.getTabObservers(); while (observers.hasNext()) observers.next().onCloseContents(mTab); }; @@ -291,7 +292,7 @@ protected TabModel getTabModel() { // TODO(dfalcantara): Remove this when DocumentActivity.getTabModelSelector() // can return a TabModelSelector that activateContents() can use. - return mTab.getTabModelSelector().getModel(mTab.isIncognito()); + return TabModelSelector.from(mTab).getModel(mTab.isIncognito()); } @CalledByNative @@ -319,13 +320,13 @@ // Creating new Tabs asynchronously requires starting a new Activity to create the Tab, // so the Tab returned will always be null. There's no way to know synchronously // whether the Tab is created, so assume it's always successful. - boolean createdSuccessfully = tabCreator.createTabWithWebContents(mTab, - webContents, mTab.getId(), TabLaunchType.FROM_LONGPRESS_FOREGROUND, url); + boolean createdSuccessfully = tabCreator.createTabWithWebContents( + mTab, webContents, TabLaunchType.FROM_LONGPRESS_FOREGROUND, url); boolean success = tabCreator.createsTabsAsynchronously() || createdSuccessfully; if (success) { if (disposition == WindowOpenDisposition.NEW_FOREGROUND_TAB) { - if (mTab.getTabModelSelector() + if (TabModelSelector.from(mTab) .getTabModelFilterProvider() .getCurrentTabModelFilter() .getRelatedTabList(mTab.getId())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java index 1af4ded2..99ec101 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
@@ -126,12 +126,13 @@ intent, IntentHandler.EXTRA_PARENT_INTENT); parentId = IntentUtils.safeGetIntExtra( intent, IntentHandler.EXTRA_PARENT_TAB_ID, parentId); - + TabModelSelector selector = mActivity.getTabModelSelector(); + parent = selector != null ? selector.getTabById(parentId) : null; assert TabModelUtils.getTabIndexById(mTabModel, assignedTabId) == TabModel.INVALID_TAB_INDEX; tab = TabBuilder.createLiveTab(!openInForeground) .setId(assignedTabId) - .setParentId(parentId) + .setParent(parent) .setIncognito(mIncognito) .setWindow(mNativeWindow) .setLaunchType(type) @@ -144,7 +145,7 @@ // to preserve resources (cpu, memory, strong renderer binding) for the foreground // tab. tab = TabBuilder.createForLazyLoad(loadUrlParams) - .setParentId(parentId) + .setParent(parent) .setIncognito(mIncognito) .setWindow(mNativeWindow) .setLaunchType(type) @@ -152,7 +153,7 @@ tab.initialize(null, delegateFactory, !openInForeground, null, false); } else { tab = TabBuilder.createLiveTab(!openInForeground) - .setParentId(parentId) + .setParent(parent) .setIncognito(mIncognito) .setWindow(mNativeWindow) .setLaunchType(type) @@ -176,9 +177,10 @@ } @Override - public boolean createTabWithWebContents(Tab parent, WebContents webContents, int parentId, - @TabLaunchType int type, String url) { + public boolean createTabWithWebContents( + Tab parent, WebContents webContents, @TabLaunchType int type, String url) { // The parent tab was already closed. Do not open child tabs. + int parentId = parent != null ? parent.getId() : Tab.INVALID_TAB_ID; if (mTabModel.isClosurePending(parentId)) return false; // If parent is in the same tab model, place the new tab next to it. @@ -190,7 +192,7 @@ TabDelegateFactory delegateFactory = parent == null ? createDefaultTabDelegateFactory() : parent.getDelegateFactory(); Tab tab = TabBuilder.createLiveTab(!openInForeground) - .setParentId(parentId) + .setParent(parent) .setIncognito(mIncognito) .setWindow(mNativeWindow) .setLaunchType(type) @@ -291,9 +293,11 @@ @Override public Tab createFrozenTab(TabState state, int id, int index) { + TabModelSelector selector = mActivity.getTabModelSelector(); + Tab parent = selector != null ? selector.getTabById(state.parentId) : null; Tab tab = TabBuilder.createFromFrozenState() .setId(id) - .setParentId(state.parentId) + .setParent(parent) .setIncognito(state.isIncognito()) .setWindow(mNativeWindow) .build();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java index 9825ab5..3ae6f111 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java
@@ -65,26 +65,23 @@ * Creates a Tab to host the given WebContents. * @param parent The parent tab, if present. * @param webContents The web contents to create a tab around. - * @param parentId The id of the parent tab. * @param type The TabLaunchType describing how this tab was created. * @param url URL to show in the Tab. (Needed only for asynchronous tab creation.) * @return Whether a Tab was created successfully. */ - public abstract boolean createTabWithWebContents(Tab parent, WebContents webContents, - int parentId, @TabLaunchType int type, String url); + public abstract boolean createTabWithWebContents( + Tab parent, WebContents webContents, @TabLaunchType int type, String url); /** * Creates a tab around the native web contents pointer. * @param parent The parent tab, if present. * @param webContents The web contents to create a tab around. - * @param parentId The id of the parent tab. * @param type The TabLaunchType describing how this tab was created. * @return Whether a Tab was created successfully. */ public final boolean createTabWithWebContents( - Tab parent, WebContents webContents, int parentId, @TabLaunchType int type) { - return createTabWithWebContents( - parent, webContents, parentId, type, webContents.getVisibleUrl()); + Tab parent, WebContents webContents, @TabLaunchType int type) { + return createTabWithWebContents(parent, webContents, type, webContents.getVisibleUrl()); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java index b52f48e..f68e8cb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -760,10 +760,10 @@ } @Override - protected boolean createTabWithWebContents(Tab parent, boolean incognito, - WebContents webContents, int parentId) { - return getTabCreator(incognito).createTabWithWebContents(parent, webContents, parentId, - TabLaunchType.FROM_LONGPRESS_BACKGROUND); + protected boolean createTabWithWebContents( + Tab parent, boolean incognito, WebContents webContents) { + return getTabCreator(incognito).createTabWithWebContents( + parent, webContents, TabLaunchType.FROM_LONGPRESS_BACKGROUND); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java index 9e7153c..c9493fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -117,12 +117,11 @@ * @param parent The parent tab that creates the new tab. * @param incognito Whether or not the tab is incognito. * @param webContents A {@link WebContents} object. - * @param parentId ID of the parent. * @return Whether or not the Tab was successfully created. */ @CalledByNative - protected abstract boolean createTabWithWebContents(Tab parent, boolean incognito, - WebContents webContents, int parentId); + protected abstract boolean createTabWithWebContents( + Tab parent, boolean incognito, WebContents webContents); @CalledByNative protected abstract void openNewTab(Tab parent, String url, String initiatorOrigin,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelector.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelector.java index 0deb20e..2460777 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelector.java
@@ -20,6 +20,16 @@ */ public interface TabModelSelector { /** + * @param tab The Tab to get its {@link TabModelSelector} from. + * @return {@link TabModelSelector} that currently hosts the {@link TabModel} for this + * {@link Tab}. + */ + public static TabModelSelector from(Tab tab) { + if (tab == null || tab.getActivity() == null) return null; + return tab.getActivity().getTabModelSelector(); + } + + /** * A delegate interface to push close all tabs requests. */ public interface CloseAllTabsDelegate {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java index 16f3346..3435a2a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
@@ -193,6 +193,11 @@ public void onNavigationEntriesDeleted(Tab tab) { mTabSaver.addTabToSaveQueue(tab); } + + @Override + public void onActivityAttachmentChanged(Tab tab, boolean attached) { + if (!attached) getModel(tab.isIncognito()).removeTab(tab); + } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java index ce04bf4..c0d59c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/DocumentTabModelImpl.java
@@ -271,8 +271,8 @@ } @Override - protected boolean createTabWithWebContents(Tab parent, boolean isIncognito, - WebContents webContents, int parentTabId) { + protected boolean createTabWithWebContents( + Tab parent, boolean isIncognito, WebContents webContents) { return false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java index 1f228145..edeaeab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java
@@ -61,14 +61,14 @@ } @Override - public boolean createTabWithWebContents(Tab parent, WebContents webContents, int parentId, - @TabLaunchType int type, String url) { + public boolean createTabWithWebContents( + Tab parent, WebContents webContents, @TabLaunchType int type, String url) { if (url == null) url = ""; AsyncTabCreationParams asyncParams = new AsyncTabCreationParams( new LoadUrlParams(url, PageTransition.AUTO_TOPLEVEL), webContents); - createNewTab(asyncParams, type, parentId); + createNewTab(asyncParams, type, parent != null ? parent.getId() : Tab.INVALID_TAB_ID); return true; } @@ -80,8 +80,8 @@ * @param activity The current {@link Activity} * @param parentId The ID of the parent tab, or {@link Tab#INVALID_TAB_ID}. */ - public void createTabInOtherWindow(LoadUrlParams loadUrlParams, Activity activity, - int parentId) { + public void createTabInOtherWindow( + LoadUrlParams loadUrlParams, Activity activity, int parentId) { Intent intent = createNewTabIntent( new AsyncTabCreationParams(loadUrlParams), parentId, false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java index 47ed82c..43ceed1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
@@ -104,7 +104,7 @@ new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tab.getId())); // The tab should be foreground and so no snapshot should exist. - TabModelSelector tabModelSelector = tab.getTabModelSelector(); + TabModelSelector tabModelSelector = TabModelSelector.from(tab); Assert.assertEquals(tabModelSelector.getCurrentTab(), tab); Assert.assertFalse(tab.isHidden()); Assert.assertNull(OfflineTestUtil.getPageByClientId(firstTabClientId));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java index 62f4c76..62666bd1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
@@ -13,6 +13,6 @@ * these two fields only. */ public MockTab(int id, boolean incognito) { - super(id, Tab.INVALID_TAB_ID, incognito, null, null, null, null); + super(id, null, incognito, null, null, null, null); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java index 6b7b103..7b678692 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
@@ -114,7 +114,6 @@ public Tab createFrozenTab(TabState state, int id, int index) { Tab tab = TabBuilder.createFromFrozenState() .setId(id) - .setParentId(state.parentId) .setIncognito(state.isIncognito()) .build(); TabTestUtils.restoreFieldsFromState(tab, state); @@ -124,8 +123,8 @@ } @Override - public boolean createTabWithWebContents(Tab parent, WebContents webContents, int parentId, - @TabLaunchType int type, String url) { + public boolean createTabWithWebContents( + Tab parent, WebContents webContents, @TabLaunchType int type, String url) { return false; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java index bb34894..638d132 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNavigationTest.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.vr.rules.ChromeTabbedActivityVrTestRule; import org.chromium.chrome.browser.vr.util.NativeUiUtils; import org.chromium.chrome.browser.vr.util.RenderTestUtils; @@ -716,7 +717,7 @@ VrBrowserTransitionUtils.forceExitVr(); TestThreadUtils.runOnUiThreadBlocking(() -> { // Close the tab that's automatically open at test start. - mTestRule.getActivity().getActivityTab().getTabModelSelector().closeAllTabs(); + TabModelSelector.from(mTestRule.getActivity().getActivityTab()).closeAllTabs(); // Create an Incognito tab. Closing all tabs automatically goes to overview mode, but // appears to take some amount of time to do so. Instead of waiting until then and // creating through the menu item, just create an Incognito tab directly.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/native_page/NativePageFactoryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/native_page/NativePageFactoryTest.java index e6359ad..39bc2bd 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/native_page/NativePageFactoryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/native_page/NativePageFactoryTest.java
@@ -199,7 +199,7 @@ MockNativePage candidate = candidateType == NativePageType.NONE ? null : new MockNativePage(candidateType); MockNativePage page = (MockNativePage) NativePageFactory.createNativePageForURL( - urlCombo.url, candidate, null, null, null, isIncognito); + urlCombo.url, candidate, null, null, isIncognito); String debugMessage = String.format( "Failed test case: isIncognito=%s, urlCombo={%s,%s}, candidateType=%s", isIncognito, urlCombo.url, urlCombo.expectedType, candidateType); @@ -224,14 +224,16 @@ public void testCreateNativePageWithInvalidUrl() { for (UrlCombo urlCombo : VALID_URLS) { if (!isValidInIncognito(urlCombo)) { - Assert.assertNull(urlCombo.url, NativePageFactory.createNativePageForURL( - urlCombo.url, null, null, null, null, true)); + Assert.assertNull(urlCombo.url, + NativePageFactory.createNativePageForURL( + urlCombo.url, null, null, null, true)); } } for (boolean isIncognito : new boolean[] {true, false}) { for (String invalidUrl : INVALID_URLS) { - Assert.assertNull(invalidUrl, NativePageFactory.createNativePageForURL(invalidUrl, - null, null, null, null, isIncognito)); + Assert.assertNull(invalidUrl, + NativePageFactory.createNativePageForURL( + invalidUrl, null, null, null, isIncognito)); } } }
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 01d056a..be40d0f 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -552,6 +552,21 @@ Only Android devices are currently supported. </message> + <!-- Plugin VM Page --> + <!-- TODO(timloh): Remove transleatable flag after strings are finalized. --> + <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE" desc="The title of Plugin VM section." translateable="false"> + Plugin VM + </message> + <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL" desc="The text associated with the primary section setting for Plugin VM." translateable="false"> + Plugin VM + </message> + <message name="IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT" desc="Description for the section for enabling and managing Crostini." translateable="false"> + Run Plugin VM apps on your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> + </message> + <message name="IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS" desc="The text associated with the primary section setting for Plugin VM." translateable="false"> + Give access to printers + </message> + <!-- Android Apps Page --> <message name="IDS_SETTINGS_ANDROID_APPS_TITLE" desc="The title of Google Play Store (Arc++ / Android Apps) section."> Google Play Store
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index a12eaa94..7df20f2 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2488,6 +2488,8 @@ "android/send_tab_to_self/android_notification_handler.cc", "android/send_tab_to_self/android_notification_handler.h", "android/send_tab_to_self/send_tab_to_self_android_bridge.cc", + "android/send_tab_to_self/send_tab_to_self_infobar.cc", + "android/send_tab_to_self/send_tab_to_self_infobar.h", "android/service_tab_launcher.cc", "android/service_tab_launcher.h", "android/sessions/session_tab_helper_android.cc", @@ -2755,10 +2757,10 @@ "apps/app_service/app_icon_factory.h", "apps/app_service/app_icon_source.cc", "apps/app_service/app_icon_source.h", - "apps/app_service/app_service_proxy.cc", - "apps/app_service/app_service_proxy.h", "apps/app_service/app_service_proxy_factory.cc", "apps/app_service/app_service_proxy_factory.h", + "apps/app_service/app_service_proxy_impl.cc", + "apps/app_service/app_service_proxy_impl.h", "apps/app_service/dip_px_util.cc", "apps/app_service/dip_px_util.h", "apps/intent_helper/apps_navigation_throttle.cc", @@ -3317,6 +3319,7 @@ "//chrome/browser/search:generated", "//chrome/common/importer:interfaces", "//chrome/services/app_service:lib", + "//chrome/services/app_service/public/cpp:app_service_proxy", "//chrome/services/app_service/public/cpp:app_update", "//chrome/services/app_service/public/cpp:icon_loader", "//components/feedback",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 29dcef3a..0eb15c8 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1365,6 +1365,9 @@ {"single-process-mash", flag_descriptions::kSingleProcessMashName, flag_descriptions::kSingleProcessMashDescription, kOsCrOS, FEATURE_VALUE_TYPE(features::kSingleProcessMash)}, + {"mojo-imf", flag_descriptions::kMojoImfName, + flag_descriptions::kMojoImfDescription, kOsCrOS, + FEATURE_VALUE_TYPE(features::kMojoIMF)}, #endif // OS_CHROMEOS { "disable-accelerated-video-decode", @@ -1494,11 +1497,6 @@ {"enable-virtual-keyboard", flag_descriptions::kVirtualKeyboardName, flag_descriptions::kVirtualKeyboardDescription, kOsCrOS, SINGLE_VALUE_TYPE(keyboard::switches::kEnableVirtualKeyboard)}, - {"virtual-keyboard-overscroll", - flag_descriptions::kVirtualKeyboardOverscrollName, - flag_descriptions::kVirtualKeyboardOverscrollDescription, kOsCrOS, - SINGLE_DISABLE_VALUE_TYPE( - keyboard::switches::kDisableVirtualKeyboardOverscroll)}, {"enable-physical-keyboard-autocorrect", flag_descriptions::kPhysicalKeyboardAutocorrectName, flag_descriptions::kPhysicalKeyboardAutocorrectDescription, kOsCrOS,
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_infobar.cc b/chrome/browser/android/send_tab_to_self/send_tab_to_self_infobar.cc new file mode 100644 index 0000000..e833fd6f --- /dev/null +++ b/chrome/browser/android/send_tab_to_self/send_tab_to_self_infobar.cc
@@ -0,0 +1,51 @@ +// Copyright 2019 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/android/send_tab_to_self/send_tab_to_self_infobar.h" + +#include <memory> +#include <utility> + +#include "base/android/jni_string.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/android/tab_android.h" +#include "chrome/browser/infobars/infobar_service.h" +#include "chrome/browser/ui/android/infobars/infobar_android.h" +#include "components/infobars/core/infobar_delegate.h" +#include "content/public/browser/web_contents.h" +#include "jni/SendTabToSelfInfoBar_jni.h" + +namespace send_tab_to_self { + +SendTabToSelfInfoBar::SendTabToSelfInfoBar( + std::unique_ptr<SendTabToSelfInfoBarDelegate> delegate) + : InfoBarAndroid(std::move(delegate)) {} + +SendTabToSelfInfoBar::~SendTabToSelfInfoBar() = default; + +void SendTabToSelfInfoBar::ProcessButton(int action) { + NOTREACHED(); // No button on this infobar. +} + +base::android::ScopedJavaLocalRef<jobject> +SendTabToSelfInfoBar::CreateRenderInfoBar(JNIEnv* env) { + return Java_SendTabToSelfInfoBar_create(env); +} + +void SendTabToSelfInfoBar::OnLinkClicked( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj) { + // TODO(crbug.com/949233): Open the tab here via the delegate + NOTIMPLEMENTED(); +} + +// static +void SendTabToSelfInfoBar::ShowInfoBar(content::WebContents* web_contents, + SendTabToSelfInfoBarDelegate* delegate) { + NOTIMPLEMENTED(); +} + +} // namespace send_tab_to_self
diff --git a/chrome/browser/android/send_tab_to_self/send_tab_to_self_infobar.h b/chrome/browser/android/send_tab_to_self/send_tab_to_self_infobar.h new file mode 100644 index 0000000..ad815568 --- /dev/null +++ b/chrome/browser/android/send_tab_to_self/send_tab_to_self_infobar.h
@@ -0,0 +1,44 @@ +// Copyright 2019 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_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_H_ +#define CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_H_ + +#include "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" +#include "base/macros.h" +#include "chrome/browser/ui/android/infobars/infobar_android.h" +#include "components/send_tab_to_self/send_tab_to_self_infobar_delegate.h" + +namespace content { +class WebContents; +} + +namespace send_tab_to_self { +// Communicates to the user that a tab was shared from another device. See +// SendTabToSelfInfoBar.java for UI specifics, and SendTabToSelfInfobarDelegate +// for behavior specifics. +class SendTabToSelfInfoBar : public InfoBarAndroid { + public: + ~SendTabToSelfInfoBar() override; + // |delegate| must remain alive while showing this info bar. + static void ShowInfoBar(content::WebContents* web_contents, + SendTabToSelfInfoBarDelegate* delegate); + + private: + explicit SendTabToSelfInfoBar( + std::unique_ptr<SendTabToSelfInfoBarDelegate> delegate); + // InfoBarAndroid: + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + JNIEnv* env) override; + void OnLinkClicked(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj) override; + void ProcessButton(int action) override; + + DISALLOW_COPY_AND_ASSIGN(SendTabToSelfInfoBar); +}; + +} // namespace send_tab_to_self + +#endif // CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_H_
diff --git a/chrome/browser/apps/app_service/app_icon_source.cc b/chrome/browser/apps/app_service/app_icon_source.cc index 0a16d96..92b97cd 100644 --- a/chrome/browser/apps/app_service/app_icon_source.cc +++ b/chrome/browser/apps/app_service/app_icon_source.cc
@@ -11,10 +11,11 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/dip_px_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "extensions/grit/extensions_browser_resources.h" #include "ui/base/resource/resource_bundle.h" #include "url/gurl.h" @@ -80,7 +81,7 @@ int size_in_dip = apps_util::ConvertPxToDip(size); apps::AppServiceProxy* app_service_proxy = - apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxyFactory::GetForProfile(profile_); if (!app_service_proxy) { LoadDefaultImage(callback); return;
diff --git a/chrome/browser/apps/app_service/app_service_proxy_factory.cc b/chrome/browser/apps/app_service/app_service_proxy_factory.cc index b407a8b..b657fa7 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_factory.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_factory.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "base/feature_list.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -26,7 +26,7 @@ // is branched from (i.e. "inherit" the parent service), // - return a temporary service just for the incognito session (probably // the least sensible option). - return static_cast<AppServiceProxy*>( + return static_cast<AppServiceProxyImpl*>( AppServiceProxyFactory::GetInstance()->GetServiceForBrowserContext( profile, true /* create */)); } @@ -57,7 +57,7 @@ KeyedService* AppServiceProxyFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - return new AppServiceProxy(Profile::FromBrowserContext(context)); + return new AppServiceProxyImpl(Profile::FromBrowserContext(context)); } bool AppServiceProxyFactory::ServiceIsCreatedWithBrowserContext() const {
diff --git a/chrome/browser/apps/app_service/app_service_proxy.cc b/chrome/browser/apps/app_service/app_service_proxy_impl.cc similarity index 75% rename from chrome/browser/apps/app_service/app_service_proxy.cc rename to chrome/browser/apps/app_service/app_service_proxy_impl.cc index 6f61a5e4..12dae356 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_impl.h" #include <utility> @@ -16,10 +16,10 @@ namespace apps { -AppServiceProxy::InnerIconLoader::InnerIconLoader(AppServiceProxy* host) +AppServiceProxyImpl::InnerIconLoader::InnerIconLoader(AppServiceProxyImpl* host) : host_(host), overriding_icon_loader_for_testing_(nullptr) {} -apps::mojom::IconKeyPtr AppServiceProxy::InnerIconLoader::GetIconKey( +apps::mojom::IconKeyPtr AppServiceProxyImpl::InnerIconLoader::GetIconKey( const std::string& app_id) { if (overriding_icon_loader_for_testing_) { return overriding_icon_loader_for_testing_->GetIconKey(app_id); @@ -35,7 +35,7 @@ } std::unique_ptr<IconLoader::Releaser> -AppServiceProxy::InnerIconLoader::LoadIconFromIconKey( +AppServiceProxyImpl::InnerIconLoader::LoadIconFromIconKey( apps::mojom::AppType app_type, const std::string& app_id, apps::mojom::IconKeyPtr icon_key, @@ -69,11 +69,12 @@ } // static -AppServiceProxy* AppServiceProxy::Get(Profile* profile) { - return AppServiceProxyFactory::GetForProfile(profile); +AppServiceProxyImpl* AppServiceProxyImpl::GetImplForTesting(Profile* profile) { + return static_cast<AppServiceProxyImpl*>( + AppServiceProxyFactory::GetForProfile(profile)); } -AppServiceProxy::AppServiceProxy(Profile* profile) +AppServiceProxyImpl::AppServiceProxyImpl(Profile* profile) : inner_icon_loader_(this), outer_icon_loader_(&inner_icon_loader_, apps::IconCache::GarbageCollectionPolicy::kEager) { @@ -88,16 +89,16 @@ connector->BindInterface(apps::mojom::kServiceName, mojo::MakeRequest(&app_service_)); - // The AppServiceProxy is a subscriber: something that wants to be able to - // list all known apps. + // The AppServiceProxyImpl is a subscriber: something that wants to be able + // to list all known apps. apps::mojom::SubscriberPtr subscriber; bindings_.AddBinding(this, mojo::MakeRequest(&subscriber)); app_service_->RegisterSubscriber(std::move(subscriber), nullptr); #if defined(OS_CHROMEOS) - // The AppServiceProxy is also a publisher, of a variety of app types. That - // responsibility isn't intrinsically part of the AppServiceProxy, but doing - // that here, for each such app type, is as good a place as any. + // The AppServiceProxyImpl is also a publisher, of a variety of app types. + // That responsibility isn't intrinsically part of the AppServiceProxyImpl, + // but doing that here, for each such app type, is as good a place as any. built_in_chrome_os_apps_.Initialize(app_service_, profile); crostini_apps_.Initialize(app_service_, profile); extension_apps_.Initialize(app_service_, profile, @@ -107,22 +108,15 @@ #endif // OS_CHROMEOS } -AppServiceProxy::~AppServiceProxy() = default; +AppServiceProxyImpl::~AppServiceProxyImpl() = default; -apps::mojom::AppServicePtr& AppServiceProxy::AppService() { - return app_service_; -} - -apps::AppRegistryCache& AppServiceProxy::AppRegistryCache() { - return cache_; -} - -apps::mojom::IconKeyPtr AppServiceProxy::GetIconKey(const std::string& app_id) { +apps::mojom::IconKeyPtr AppServiceProxyImpl::GetIconKey( + const std::string& app_id) { return outer_icon_loader_.GetIconKey(app_id); } std::unique_ptr<apps::IconLoader::Releaser> -AppServiceProxy::LoadIconFromIconKey( +AppServiceProxyImpl::LoadIconFromIconKey( apps::mojom::AppType app_type, const std::string& app_id, apps::mojom::IconKeyPtr icon_key, @@ -135,10 +129,10 @@ allow_placeholder_icon, std::move(callback)); } -void AppServiceProxy::Launch(const std::string& app_id, - int32_t event_flags, - apps::mojom::LaunchSource launch_source, - int64_t display_id) { +void AppServiceProxyImpl::Launch(const std::string& app_id, + int32_t event_flags, + apps::mojom::LaunchSource launch_source, + int64_t display_id) { if (app_service_.is_bound()) { cache_.ForOneApp(app_id, [this, event_flags, launch_source, display_id](const apps::AppUpdate& update) { @@ -148,8 +142,8 @@ } } -void AppServiceProxy::SetPermission(const std::string& app_id, - apps::mojom::PermissionPtr permission) { +void AppServiceProxyImpl::SetPermission(const std::string& app_id, + apps::mojom::PermissionPtr permission) { if (app_service_.is_bound()) { cache_.ForOneApp( app_id, [this, &permission](const apps::AppUpdate& update) { @@ -159,7 +153,7 @@ } } -void AppServiceProxy::Uninstall(const std::string& app_id) { +void AppServiceProxyImpl::Uninstall(const std::string& app_id) { if (app_service_.is_bound()) { cache_.ForOneApp(app_id, [this](const apps::AppUpdate& update) { app_service_->Uninstall(update.AppType(), update.AppId()); @@ -167,7 +161,7 @@ } } -void AppServiceProxy::OpenNativeSettings(const std::string& app_id) { +void AppServiceProxyImpl::OpenNativeSettings(const std::string& app_id) { if (app_service_.is_bound()) { cache_.ForOneApp(app_id, [this](const apps::AppUpdate& update) { app_service_->OpenNativeSettings(update.AppType(), update.AppId()); @@ -175,7 +169,7 @@ } } -apps::IconLoader* AppServiceProxy::OverrideInnerIconLoaderForTesting( +apps::IconLoader* AppServiceProxyImpl::OverrideInnerIconLoaderForTesting( apps::IconLoader* icon_loader) { apps::IconLoader* old = inner_icon_loader_.overriding_icon_loader_for_testing_; @@ -183,7 +177,7 @@ return old; } -void AppServiceProxy::Shutdown() { +void AppServiceProxyImpl::Shutdown() { #if defined(OS_CHROMEOS) if (app_service_.is_bound()) { extension_apps_.Shutdown(); @@ -192,11 +186,11 @@ #endif // OS_CHROMEOS } -void AppServiceProxy::OnApps(std::vector<apps::mojom::AppPtr> deltas) { +void AppServiceProxyImpl::OnApps(std::vector<apps::mojom::AppPtr> deltas) { cache_.OnApps(std::move(deltas)); } -void AppServiceProxy::Clone(apps::mojom::SubscriberRequest request) { +void AppServiceProxyImpl::Clone(apps::mojom::SubscriberRequest request) { bindings_.AddBinding(this, std::move(request)); }
diff --git a/chrome/browser/apps/app_service/app_service_proxy.h b/chrome/browser/apps/app_service/app_service_proxy_impl.h similarity index 76% rename from chrome/browser/apps/app_service/app_service_proxy.h rename to chrome/browser/apps/app_service/app_service_proxy_impl.h index 4a75605..e142ef5b 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.h +++ b/chrome/browser/apps/app_service/app_service_proxy_impl.h
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_H_ -#define CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_H_ +#ifndef CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_IMPL_H_ +#define CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_IMPL_H_ #include <memory> #include "base/macros.h" -#include "chrome/services/app_service/public/cpp/app_registry_cache.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "chrome/services/app_service/public/cpp/icon_cache.h" -#include "chrome/services/app_service/public/mojom/app_service.mojom.h" -#include "chrome/services/app_service/public/mojom/types.mojom.h" #include "components/keyed_service/core/keyed_service.h" #include "mojo/public/cpp/bindings/binding_set.h" @@ -31,20 +29,23 @@ // proxy for a given Profile, and therefore share its caches. // // See chrome/services/app_service/README.md. -class AppServiceProxy : public KeyedService, - public apps::IconLoader, - public apps::mojom::Subscriber { +class AppServiceProxyImpl : public KeyedService, + public apps::AppServiceProxy, + public apps::mojom::Subscriber { public: - static AppServiceProxy* Get(Profile* profile); + // This method returns an AppServiceProxyImpl, not just an AppServiceProxy, so + // that callers (which are presumably in test code) can then call other + // XxxForTesting methods. + // + // For regular (non-test) code, use AppServiceProxyFactory::GetForProfile + // instead. + static AppServiceProxyImpl* GetImplForTesting(Profile* profile); - explicit AppServiceProxy(Profile* profile); + explicit AppServiceProxyImpl(Profile* profile); - ~AppServiceProxy() override; + ~AppServiceProxyImpl() override; - apps::mojom::AppServicePtr& AppService(); - apps::AppRegistryCache& AppRegistryCache(); - - // apps::IconLoader overrides. + // apps::AppServiceProxy (including apps::IconLoader) overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override; std::unique_ptr<IconLoader::Releaser> LoadIconFromIconKey( apps::mojom::AppType app_type, @@ -54,18 +55,14 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::mojom::Publisher::LoadIconCallback callback) override; - void Launch(const std::string& app_id, int32_t event_flags, apps::mojom::LaunchSource launch_source, - int64_t display_id); - + int64_t display_id) override; void SetPermission(const std::string& app_id, - apps::mojom::PermissionPtr permission); - - void Uninstall(const std::string& app_id); - - void OpenNativeSettings(const std::string& app_id); + apps::mojom::PermissionPtr permission) override; + void Uninstall(const std::string& app_id) override; + void OpenNativeSettings(const std::string& app_id) override; apps::IconLoader* OverrideInnerIconLoaderForTesting( apps::IconLoader* icon_loader); @@ -74,8 +71,8 @@ // An adapter, presenting an IconLoader interface based on the underlying // Mojo service (or on a fake implementation for testing). // - // Conceptually, the ASP (the AppServiceProxy) is itself such an adapter: UI - // clients call the IconLoader::LoadIconFromIconKey method (which the ASP + // Conceptually, the ASP (the AppServiceProxyImpl) is itself such an adapter: + // UI clients call the IconLoader::LoadIconFromIconKey method (which the ASP // implements) and the ASP translates (i.e. adapts) these to Mojo calls (or // C++ calls to the Fake). This diagram shows control flow going left to // right (with "=c=>" and "=m=>" denoting C++ and Mojo calls), and the @@ -104,7 +101,7 @@ // component: the one that ultimately talks to the Mojo service. // // The outer_icon_loader_ field (of type IconCache) is the "Outer" component: - // the entry point for calls into the AppServiceProxy. + // the entry point for calls into the AppServiceProxyImpl. // // Note that even if the ASP provides some icon caching, upstream UI clients // may want to introduce further icon caching. See the commentary where @@ -113,7 +110,7 @@ // IPC coalescing would be one of the "MoreDecorators". class InnerIconLoader : public apps::IconLoader { public: - explicit InnerIconLoader(AppServiceProxy* host); + explicit InnerIconLoader(AppServiceProxyImpl* host); // apps::IconLoader overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override; @@ -126,8 +123,9 @@ bool allow_placeholder_icon, apps::mojom::Publisher::LoadIconCallback callback) override; - // |host_| owns |this|, as the InnerIconLoader is an AppServiceProxy field. - AppServiceProxy* host_; + // |host_| owns |this|, as the InnerIconLoader is an AppServiceProxyImpl + // field. + AppServiceProxyImpl* host_; apps::IconLoader* overriding_icon_loader_for_testing_; }; @@ -139,9 +137,7 @@ void OnApps(std::vector<apps::mojom::AppPtr> deltas) override; void Clone(apps::mojom::SubscriberRequest request) override; - apps::mojom::AppServicePtr app_service_; mojo::BindingSet<apps::mojom::Subscriber> bindings_; - apps::AppRegistryCache cache_; // The LoadIconFromIconKey implementation sends a chained series of requests // through each icon loader, starting from the outer and working back to the @@ -158,9 +154,9 @@ ExtensionApps extension_web_apps_; #endif // OS_CHROMEOS - DISALLOW_COPY_AND_ASSIGN(AppServiceProxy); + DISALLOW_COPY_AND_ASSIGN(AppServiceProxyImpl); }; } // namespace apps -#endif // CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_H_ +#endif // CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_PROXY_IMPL_H_
diff --git a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc b/chrome/browser/apps/app_service/app_service_proxy_impl_unittest.cc similarity index 93% rename from chrome/browser/apps/app_service/app_service_proxy_unittest.cc rename to chrome/browser/apps/app_service/app_service_proxy_impl_unittest.cc index cfad9c2..a147ecd 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_impl_unittest.cc
@@ -6,12 +6,12 @@ #include <vector> #include "base/callback.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_impl.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia_rep.h" -class AppServiceProxyTest : public testing::Test { +class AppServiceProxyImplTest : public testing::Test { protected: using UniqueReleaser = std::unique_ptr<apps::IconLoader::Releaser>; @@ -66,11 +66,11 @@ return loader->LoadIcon(app_type, app_id, icon_compression, size_hint_in_dip, allow_placeholder_icon, - base::BindOnce(&AppServiceProxyTest::OnLoadIcon, + base::BindOnce(&AppServiceProxyImplTest::OnLoadIcon, base::Unretained(this))); } - void OverrideAppServiceProxyInnerIconLoader(apps::AppServiceProxy* proxy, + void OverrideAppServiceProxyInnerIconLoader(apps::AppServiceProxyImpl* proxy, apps::IconLoader* icon_loader) { proxy->OverrideInnerIconLoaderForTesting(icon_loader); } @@ -84,8 +84,8 @@ int num_outer_finished_callbacks_ = 0; }; -TEST_F(AppServiceProxyTest, IconCache) { - apps::AppServiceProxy proxy(nullptr); +TEST_F(AppServiceProxyImplTest, IconCache) { + apps::AppServiceProxyImpl proxy(nullptr); FakeIconLoader fake; OverrideAppServiceProxyInnerIconLoader(&proxy, &fake);
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc index a168a56..0899b24 100644 --- a/chrome/browser/apps/app_service/arc_apps.cc +++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/containers/flat_map.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/arc_apps_factory.h" #include "chrome/browser/apps/app_service/dip_px_util.h" #include "chrome/browser/chromeos/arc/arc_util.h" @@ -19,6 +19,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_icon_descriptor.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/grit/component_extension_resources.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "components/arc/app_permissions/arc_app_permissions_bridge.h" #include "components/arc/arc_service_manager.h" #include "components/arc/common/app.mojom.h" @@ -172,8 +173,9 @@ apps::mojom::PublisherPtr publisher; binding_.Bind(mojo::MakeRequest(&publisher)); - apps::AppServiceProxy::Get(profile)->AppService()->RegisterPublisher( - std::move(publisher), apps::mojom::AppType::kArc); + apps::AppServiceProxyFactory::GetForProfile(profile) + ->AppService() + ->RegisterPublisher(std::move(publisher), apps::mojom::AppType::kArc); } ArcApps::~ArcApps() {
diff --git a/chrome/browser/apps/app_service/crostini_apps.cc b/chrome/browser/apps/app_service/crostini_apps.cc index 9e189ff0..d555b47 100644 --- a/chrome/browser/apps/app_service/crostini_apps.cc +++ b/chrome/browser/apps/app_service/crostini_apps.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/dip_px_util.h" #include "chrome/browser/apps/app_service/launch_util.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
diff --git a/chrome/browser/apps/intent_helper/OWNERS b/chrome/browser/apps/intent_helper/OWNERS index 8db6e277..1e68db6 100644 --- a/chrome/browser/apps/intent_helper/OWNERS +++ b/chrome/browser/apps/intent_helper/OWNERS
@@ -1,3 +1,5 @@ +dominickn@chromium.org +mxcai@chromium.org # For ARC related code djacobo@chromium.org # For ARC related code, backup reviewers
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 8985978..675d8fa4 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -71,6 +71,7 @@ "//chrome/common", "//chrome/common/extensions/api", "//chrome/services/app_service:lib", + "//chrome/services/app_service/public/cpp:app_service_proxy", "//chrome/services/app_service/public/cpp:app_update", "//chrome/services/diagnosticsd/public/mojom", "//chrome/services/file_util/public/cpp",
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc index bdd5a0b..81399f0 100644 --- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc
@@ -12,6 +12,7 @@ #include "ash/shell.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" +#include "components/arc/arc_util.h" #include "components/arc/metrics/arc_metrics_constants.h" #include "ui/aura/env.h" #include "ui/base/ui_base_features.h" @@ -82,7 +83,7 @@ bool ArcKioskAppLauncher::CheckAndPinWindow(aura::Window* const window) { DCHECK_GE(task_id_, 0); - if (ArcAppWindowLauncherController::GetWindowTaskId(window) != task_id_) + if (arc::GetWindowTaskId(window) != task_id_) return false; // Stop observing as target window is already found. StopObserving();
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc index 1f03a38a2..f844390 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -18,6 +18,7 @@ #include "chromeos/constants/chromeos_features.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_service_manager.h" +#include "components/arc/arc_util.h" #include "components/arc/session/arc_bridge_service.h" #include "components/exo/input_method_surface.h" #include "components/exo/shell_surface.h" @@ -36,8 +37,6 @@ namespace { -constexpr int32_t kNoTaskId = -1; - exo::Surface* GetArcSurface(const aura::Window* window) { if (!window) return nullptr; @@ -48,18 +47,6 @@ return arc_surface; } -int32_t GetTaskId(aura::Window* window) { - const std::string* arc_app_id = exo::GetShellApplicationId(window); - if (!arc_app_id) - return kNoTaskId; - - int32_t task_id = kNoTaskId; - if (sscanf(arc_app_id->c_str(), "org.chromium.arc.%d", &task_id) != 1) - return kNoTaskId; - - return task_id; -} - void DispatchFocusChange(arc::mojom::AccessibilityNodeInfoData* node_data, Profile* profile) { chromeos::AccessibilityManager* accessibility_manager = @@ -168,7 +155,7 @@ aura::Window* window = GetActiveWindow(); if (!window) return; - int32_t task_id = GetTaskId(window); + int32_t task_id = arc::GetWindowTaskId(window); if (task_id == kNoTaskId) return; @@ -194,7 +181,7 @@ return; aura::Window* window = window_tracker->Pop(); - int32_t task_id = GetTaskId(window); + int32_t task_id = arc::GetWindowTaskId(window); DCHECK_NE(task_id, kNoTaskId); if (!enabled) { @@ -315,7 +302,7 @@ if (!active_window) return; - int32_t task_id = GetTaskId(active_window); + int32_t task_id = arc::GetWindowTaskId(active_window); if (task_id != event_data->task_id) return; @@ -678,7 +665,7 @@ // First, do a lookup for the task id associated with this app. There should // always be a valid entry. - int32_t task_id = GetTaskId(window); + int32_t task_id = arc::GetWindowTaskId(window); // Do a lookup for the tree source. A tree source may not exist because the // app isn't whitelisted Android side or no data has been received for the
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc index 58ea13f..4375f338 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/arc/tracing/arc_tracing_event.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_event_matcher.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_model.h" +#include "components/arc/arc_util.h" namespace arc { @@ -351,9 +352,8 @@ LOG(ERROR) << "Failed to get app id from event: " << event->ToString(); continue; } - int task_id = -1; - if (sscanf(app_id.c_str(), "org.chromium.arc.%d", &task_id) != 1 || - task_id < 0) { + int task_id = GetTaskIdFromWindowAppId(app_id); + if (task_id == kNoTaskId) { LOG(ERROR) << "Failed to parse app id from event: " << event->ToString(); continue;
diff --git a/chrome/browser/chromeos/assistant/assistant_util.cc b/chrome/browser/chromeos/assistant/assistant_util.cc index dda3c07..2b5934d6 100644 --- a/chrome/browser/chromeos/assistant/assistant_util.cc +++ b/chrome/browser/chromeos/assistant/assistant_util.cc
@@ -51,7 +51,7 @@ ULOC_US, "da_DK", "nl_NL", - "no_NO" + "no_NO", "sv_SE"}; const PrefService* prefs = profile->GetPrefs();
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.cc b/chrome/browser/chromeos/crostini/crostini_registry_service.cc index 47dd733..9c6f9ec 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service.cc +++ b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/crostini/crostini_pref_names.h" #include "chrome/browser/chromeos/crostini/crostini_util.h" -#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/grit/generated_resources.h" #include "chromeos/dbus/vm_applications/apps.pb.h" @@ -35,8 +34,7 @@ namespace { -// Prefixes of the ApplicationId set on exo windows. -constexpr char kArcWindowAppIdPrefix[] = "org.chromium.arc"; +// Prefix of the ApplicationId set on exo windows for X apps. constexpr char kCrostiniWindowAppIdPrefix[] = "org.chromium.termina."; // This comes after kCrostiniWindowAppIdPrefix constexpr char kWMClassPrefix[] = "wmclass."; @@ -487,8 +485,8 @@ } // The code follows these steps to identify apps and returns the first match: -// 1) Ignore windows if the App Id is prefixed by org.chromium.arc. -// 2) If the Startup Id is set, look for a matching desktop file id. +// 1) If the Startup Id is set, look for a matching desktop file id. +// 2) Ignore windows if the App Id is not set. // 3) If the App Id is not prefixed by org.chromium.termina., it's an app with // native Wayland support. Look for a matching desktop file id. // 4) If the App Id is prefixed by org.chromium.termina.wmclass.: @@ -516,13 +514,8 @@ // Try a lookup with the window app id. } - // TODO(timloh): Crostini shouldn't need to know about Arc and PluginVm. - if (!window_app_id || - base::StartsWith(*window_app_id, kArcWindowAppIdPrefix, - base::CompareCase::SENSITIVE) || - plugin_vm::IsPluginVmExoApplicationId(*window_app_id)) { + if (!window_app_id) return std::string(); - } // Wayland apps won't be prefixed with org.chromium.termina. if (!base::StartsWith(*window_app_id, kCrostiniWindowAppIdPrefix,
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.h b/chrome/browser/chromeos/crostini/crostini_registry_service.h index 0b7ec83d..ba24934 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service.h +++ b/chrome/browser/chromeos/crostini/crostini_registry_service.h
@@ -139,10 +139,9 @@ // // First try to return a desktop file id matching the |window_startup_id|. // - // If the given window app id is not for Crostini (i.e. Arc++), returns an - // empty string. If we can uniquely identify a registry entry, returns the - // crostini app id for that. Otherwise, returns the string pointed to by - // |window_app_id|, prefixed by "crostini:". + // If the app id is empty, returns empty string. If we can uniquely identify + // a registry entry, returns the crostini app id for that. Otherwise, returns + // the string pointed to by |window_app_id|, prefixed by "crostini:". // // As the window app id is derived from fields set by the app itself, it is // possible for an app to masquerade as a different app.
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc b/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc index a6b1cbb..dab07e7 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc +++ b/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc
@@ -357,10 +357,6 @@ window_app_id = "fancy.app"; EXPECT_EQ(service()->GetCrostiniShelfAppId(&window_app_id, nullptr), "crostini:fancy.app"); - - window_app_id = "org.chromium.arc.h"; - EXPECT_EQ(service()->GetCrostiniShelfAppId(&window_app_id, nullptr), - std::string()); } TEST_F(CrostiniRegistryServiceTest, GetCrostiniAppIdStartupWMClass) {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc index f084489..41f5434 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -72,8 +72,8 @@ ime::mojom::ImeEngineFactoryPtr factory_ptr; factory_binding_.Close(); factory_binding_.Bind(mojo::MakeRequest(&factory_ptr)); - factory_binding_.set_connection_error_handler( - base::BindOnce(&MojoHelper::OnConnectionLost, base::Unretained(this))); + factory_binding_.set_connection_error_handler(base::BindOnce( + &MojoHelper::OnFactoryConnectionLost, base::Unretained(this))); if (registry) { registry_ = std::move(registry); @@ -86,12 +86,16 @@ registry_->ActivateFactory(std::move(factory_ptr)); } + void set_allow_finish_input(bool allow) { allow_finish_input_ = allow; } + // ime::mojom::ImeEngineFactory overrides: void CreateEngine(ime::mojom::ImeEngineRequest engine_request, ime::mojom::ImeEngineClientPtr client) override { engine_binding_.Close(); engine_binding_.Bind(std::move(engine_request)); engine_client_ = std::move(client); + engine_client_.set_connection_error_handler(base::BindOnce( + &MojoHelper::OnClientConnectionLost, base::Unretained(this))); } // ime::mojom::ImeEngine overrides: @@ -100,8 +104,17 @@ info->type, info->mode, info->flags, info->focus_reason, info->should_do_learning); engine_->FocusIn(context); + allow_finish_input_ = true; } - void FinishInput() override { engine_->FocusOut(); } + void FinishInput() override { + // Only allows the call of FocusOut() when the FocusIn() was caused from a + // mojo-based client. Please see the comments for |allow_finish_input_| for + // the details. + if (allow_finish_input_) { + engine_->FocusOut(); + allow_finish_input_ = false; + } + } void CancelInput() override { engine_->Reset(); } void ProcessKeyEvent( std::unique_ptr<ui::Event> key_event, @@ -132,13 +145,15 @@ } private: - void OnConnectionLost() { + void OnFactoryConnectionLost() { // After the connection to |ImeEngineFactoryRegistry| is broken, notifies // the client to reconnect through Window Service. if (engine_client_) engine_client_->Reconnect(); } + void OnClientConnectionLost() { engine_client_.reset(); } + InputMethodEngine* engine_; mojo::Binding<ime::mojom::ImeEngineFactory> factory_binding_; mojo::Binding<ime::mojom::ImeEngine> engine_binding_; @@ -146,6 +161,14 @@ ime::mojom::ImeEngineClientPtr engine_client_; ime::mojom::ImeEngineFactoryRegistryPtr registry_; + // Whether mutes the call of FinishInput(). + // This is to guard the mis-ordered calls of FocusIn() & FocusOut() calls when + // switching between mojo-based and non-mojo-based clients. + // e.g. app_list window is non-mojo-based client, so need to guard the + // FocusOut() call from the mojo-based client because the app_list window's + // FocusIn() comes in first. + bool allow_finish_input_ = false; + DISALLOW_COPY_AND_ASSIGN(MojoHelper); }; @@ -185,6 +208,12 @@ return !active_component_id_.empty(); } +void InputMethodEngine::FocusIn( + const ui::IMEEngineHandlerInterface::InputContext& input_context) { + InputMethodEngineBase::FocusIn(input_context); + mojo_helper_->set_allow_finish_input(false); +} + void InputMethodEngine::PropertyActivate(const std::string& property_name) { observer_->OnMenuItemActivated(active_component_id_, property_name); }
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h index 710f8adc..5a8d0e2 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.h +++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -92,6 +92,8 @@ // InputMethodEngineBase overrides. void Enable(const std::string& component_id) override; bool IsActive() const override; + void FocusIn(const ui::IMEEngineHandlerInterface::InputContext& input_context) + override; // ui::IMEEngineHandlerInterface overrides. void PropertyActivate(const std::string& property_name) override;
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index 93088e8..66abd87 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -424,6 +424,22 @@ engine_->CommitText(context, "input", &error); engine_->FlushForTesting(); EXPECT_TRUE(client.commit_text_called()); + + engine_ptr->FinishInput(); + engine_ptr.FlushForTesting(); + EXPECT_EQ(ONBLUR, observer_->GetCallsBitmapAndReset()); + + // Switches from a mojo-based client to a non-mojo-based client. + engine_ptr->StartInput(ime::mojom::EditorInfo::New( + ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT, + ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_MOUSE, + false)); + engine_ptr.FlushForTesting(); + engine_ptr->FinishInput(); + FocusIn(ui::TEXT_INPUT_TYPE_TEXT); + engine_ptr.FlushForTesting(); + // Verifies no ONBLUR is called. + EXPECT_EQ(ONFOCUS, observer_->GetCallsBitmapAndReset()); } } // namespace input_method
diff --git a/chrome/browser/chromeos/kiosk_next_home/app_controller_service.cc b/chrome/browser/chromeos/kiosk_next_home/app_controller_service.cc index 75c972a..f109680b 100644 --- a/chrome/browser/chromeos/kiosk_next_home/app_controller_service.cc +++ b/chrome/browser/chromeos/kiosk_next_home/app_controller_service.cc
@@ -16,12 +16,13 @@ #include "base/optional.h" #include "base/strings/string_util.h" #include "chrome/browser/apps/app_service/app_icon_source.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/chromeos/kiosk_next_home/app_controller_service_factory.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_utils.h" #include "chrome/common/extensions/extension_constants.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "chrome/services/app_service/public/mojom/types.mojom.h" #include "chromeos/constants/chromeos_switches.h" #include "components/arc/arc_service_manager.h" @@ -43,7 +44,7 @@ AppControllerService::AppControllerService(Profile* profile) : profile_(profile), - app_service_proxy_(apps::AppServiceProxy::Get(profile)) { + app_service_proxy_(apps::AppServiceProxyFactory::GetForProfile(profile)) { DCHECK(profile); app_service_proxy_->AppRegistryCache().AddObserver(this);
diff --git a/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc b/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc index 9b8ee94..4c7e40e1 100644 --- a/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc +++ b/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc
@@ -13,12 +13,12 @@ #include "base/command_line.h" #include "base/optional.h" #include "base/test/bind_test_util.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/services/app_service/public/cpp/app_registry_cache.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "chrome/services/app_service/public/cpp/app_update.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/constants/chromeos_switches.h" @@ -67,7 +67,7 @@ profile_ = std::make_unique<TestingProfile>(); arc_test_.SetUp(profile()); - proxy_ = apps::AppServiceProxy::Get(profile()); + proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile()); app_controller_service_ = AppControllerService::Get(profile());
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc index eda3d192..c89b2de 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/profiles/profile.h" +#include "components/exo/shell_surface_util.h" #include "components/prefs/pref_service.h" namespace plugin_vm { @@ -66,8 +67,9 @@ return IsPluginVmAllowedForProfile(profile) && IsPluginVmConfigured(profile); } -// TODO(timloh): Implement this (crbug.com/940319). -bool IsPluginVmExoApplicationId(const std::string& app_id) { +// TODO(timloh): Implement detection for Plugin VM windows, e.g. by setting an +// exo application id (crbug.com/940319). +bool IsPluginVmWindow(const aura::Window* window) { return false; }
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h index dbecf5d..b041e33 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.h
@@ -7,6 +7,10 @@ #include <string> +namespace aura { +class Window; +} // namespace aura + class Profile; namespace plugin_vm { @@ -28,8 +32,8 @@ void ShowPluginVmLauncherView(Profile* profile); -// Checks if an exo window's app id is for plugin vm. -bool IsPluginVmExoApplicationId(const std::string& app_id); +// Checks if an window is for plugin vm. +bool IsPluginVmWindow(const aura::Window* window); // Retrieves the license key to be used for PluginVm. If // none is set this will return an empty string.
diff --git a/chrome/browser/devtools/inspector_protocol_config.json b/chrome/browser/devtools/inspector_protocol_config.json index 6e98d251..2137e85 100644 --- a/chrome/browser/devtools/inspector_protocol_config.json +++ b/chrome/browser/devtools/inspector_protocol_config.json
@@ -8,8 +8,9 @@ "options": [ { "domain": "Page", - "include": [ "enable", "disable", "setAdBlockingEnabled" ], - "include_events": [] + "include": [ "enable", "disable", "setAdBlockingEnabled", "getInstallabilityErrors" ], + "include_events": [], + "async": ["getInstallabilityErrors"] }, { "domain": "Browser",
diff --git a/chrome/browser/devtools/protocol/page_handler.cc b/chrome/browser/devtools/protocol/page_handler.cc index 1020609c..eea7f9c 100644 --- a/chrome/browser/devtools/protocol/page_handler.cc +++ b/chrome/browser/devtools/protocol/page_handler.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/devtools/protocol/page_handler.h" +#include "chrome/browser/installable/installable_manager.h" #include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" PageHandler::PageHandler(content::WebContents* web_contents, @@ -47,3 +48,28 @@ ToggleAdBlocking(enabled); return protocol::Response::OK(); } + +void PageHandler::GetInstallabilityErrors( + std::unique_ptr<GetInstallabilityErrorsCallback> callback) { + auto errors = protocol::Array<std::string>::create(); + InstallableManager* manager = + web_contents() ? InstallableManager::FromWebContents(web_contents()) + : nullptr; + if (!manager) { + callback->sendFailure( + protocol::Response::Error("Unable to fetch errors for target")); + return; + } + manager->GetAllErrors(base::BindOnce(&PageHandler::GotInstallabilityErrors, + std::move(callback))); +} + +// static +void PageHandler::GotInstallabilityErrors( + std::unique_ptr<GetInstallabilityErrorsCallback> callback, + std::vector<std::string> errors) { + auto result = protocol::Array<std::string>::create(); + for (const auto& error : errors) + result->addItem(error); + callback->sendSuccess(std::move(result)); +}
diff --git a/chrome/browser/devtools/protocol/page_handler.h b/chrome/browser/devtools/protocol/page_handler.h index bc0d62cc..4225193 100644 --- a/chrome/browser/devtools/protocol/page_handler.h +++ b/chrome/browser/devtools/protocol/page_handler.h
@@ -26,8 +26,14 @@ protocol::Response Enable() override; protocol::Response Disable() override; protocol::Response SetAdBlockingEnabled(bool enabled) override; + void GetInstallabilityErrors( + std::unique_ptr<GetInstallabilityErrorsCallback> callback) override; private: + static void GotInstallabilityErrors( + std::unique_ptr<GetInstallabilityErrorsCallback> callback, + std::vector<std::string> errors); + bool enabled_ = false; DISALLOW_COPY_AND_ASSIGN(PageHandler);
diff --git a/chrome/browser/extensions/api/cast_streaming/performance_test.cc b/chrome/browser/extensions/api/cast_streaming/performance_test.cc index 03a5a0e5..8d3d46c 100644 --- a/chrome/browser/extensions/api/cast_streaming/performance_test.cc +++ b/chrome/browser/extensions/api/cast_streaming/performance_test.cc
@@ -67,13 +67,13 @@ // long enough to collect sufficient tracing data; and, unfortunately, there's // nothing we can do about that. #define EXPECT_FOR_PERFORMANCE_RUN(expr) \ - if (!(expr)) { \ + do { \ if (is_full_performance_run()) { \ - LOG(ERROR) << "Failure: " << #expr; \ - } else { \ + EXPECT_TRUE(expr); \ + } else if (!(expr)) { \ LOG(WARNING) << "Allowing failure: " << #expr; \ } \ - } + } while (false) enum TestFlags { kSmallWindow = 1 << 2, // Window size: 1 = 800x600, 0 = 2000x1000 @@ -168,7 +168,7 @@ const std::string& modifier, const std::string& trace, const std::string& unit) { - if (num_values_ > 0) { + if (num_values_ >= 20) { perf_test::PrintResultMeanAndError(measurement, modifier, trace, @@ -176,7 +176,8 @@ unit, true); } else { - LOG(ERROR) << "No events for " << measurement << modifier << " " << trace; + LOG(ERROR) << "Not enough events (" << num_values_ << ") for " + << measurement << modifier << " " << trace; } }
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.cc index fe7bf28a2..7b455d2 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.cc
@@ -22,7 +22,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/test/base/tracing.h" #include "chrome/test/base/ui_test_utils.h" -#include "content/public/common/content_features.h" #include "content/public/test/browser_test_utils.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" @@ -33,7 +32,6 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" -#include "services/service_manager/sandbox/features.h" #include "third_party/zlib/google/compression_utils.h" #include "ui/gl/gl_switches.h" @@ -49,15 +47,6 @@ // Because screen capture is involved, require pixel output. EnablePixelOutput(); - feature_list_.InitWithFeatures( - { - service_manager::features::kAudioServiceSandbox, - features::kAudioServiceAudioStreams, - features::kAudioServiceLaunchOnStartup, - features::kAudioServiceOutOfProcess, - }, - {}); - InProcessBrowserTest::SetUp(); }
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.h b/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.h index 8a1c7146..51d0fd4 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.h +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_performance_test_base.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/strings/string_piece.h" -#include "base/test/scoped_feature_list.h" #include "base/test/trace_event_analyzer.h" #include "chrome/test/base/in_process_browser_test.h" @@ -136,9 +135,6 @@ const extensions::Extension* extension_ = nullptr; - // Manages the Audio Service feature set, enabled for these performance tests. - base::test::ScopedFeatureList feature_list_; - DISALLOW_COPY_AND_ASSIGN(TabCapturePerformanceTestBase); };
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc index ab4b26e..895fdee 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
@@ -2073,10 +2073,12 @@ deltas.push_back(std::move(d0)); } bool request_headers_modified0; + std::set<std::string> ignore1, ignore2; net::HttpRequestHeaders headers0; headers0.MergeFrom(base_headers); MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers0, &ignored_actions, - &logger, &request_headers_modified0); + &logger, &ignore1, &ignore2, + &request_headers_modified0); ASSERT_TRUE(headers0.GetHeader("key1", &header_value)); EXPECT_EQ("value 1", header_value); ASSERT_TRUE(headers0.GetHeader("key2", &header_value)); @@ -2096,11 +2098,14 @@ deltas.sort(&InDecreasingExtensionInstallationTimeOrder); ignored_actions.clear(); logger.clear(); + ignore1.clear(); + ignore2.clear(); bool request_headers_modified1; net::HttpRequestHeaders headers1; headers1.MergeFrom(base_headers); MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers1, &ignored_actions, - &logger, &request_headers_modified1); + &logger, &ignore1, &ignore2, + &request_headers_modified1); EXPECT_FALSE(headers1.HasHeader("key1")); ASSERT_TRUE(headers1.GetHeader("key2", &header_value)); EXPECT_EQ("value 3", header_value); @@ -2122,11 +2127,14 @@ deltas.sort(&InDecreasingExtensionInstallationTimeOrder); ignored_actions.clear(); logger.clear(); + ignore1.clear(); + ignore2.clear(); bool request_headers_modified2; net::HttpRequestHeaders headers2; headers2.MergeFrom(base_headers); MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers2, &ignored_actions, - &logger, &request_headers_modified2); + &logger, &ignore1, &ignore2, + &request_headers_modified2); EXPECT_FALSE(headers2.HasHeader("key1")); ASSERT_TRUE(headers2.GetHeader("key2", &header_value)); EXPECT_EQ("value 3", header_value); @@ -2152,11 +2160,14 @@ deltas.sort(&InDecreasingExtensionInstallationTimeOrder); ignored_actions.clear(); logger.clear(); + ignore1.clear(); + ignore2.clear(); bool request_headers_modified3; net::HttpRequestHeaders headers3; headers3.MergeFrom(base_headers); MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers3, &ignored_actions, - &logger, &request_headers_modified3); + &logger, &ignore1, &ignore2, + &request_headers_modified3); EXPECT_FALSE(headers3.HasHeader("key1")); ASSERT_TRUE(headers3.GetHeader("key2", &header_value)); EXPECT_EQ("value 3", header_value); @@ -2218,11 +2229,13 @@ } deltas.sort(&InDecreasingExtensionInstallationTimeOrder); bool request_headers_modified1; + std::set<std::string> ignore1, ignore2; net::HttpRequestHeaders headers1; headers1.MergeFrom(base_headers); ignored_actions.clear(); MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers1, &ignored_actions, - &logger, &request_headers_modified1); + &logger, &ignore1, &ignore2, + &request_headers_modified1); EXPECT_TRUE(headers1.HasHeader("Cookie")); ASSERT_TRUE(headers1.GetHeader("Cookie", &header_value)); EXPECT_EQ("name=new value; name2=new value; name4=\"value 4\"", header_value);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 68846d3..da7b75b 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2306,6 +2306,11 @@ "expiry_milestone": 80 }, { + "name": "mojo-imf", + "owners": [ "shuchen" ], + "expiry_milestone": 78 + }, + { "name": "native-filesystem-api", "owners": [ "mek", "pwnall" ], "expiry_milestone": 80 @@ -3069,11 +3074,6 @@ "expiry_milestone": 76 }, { - "name": "virtual-keyboard-overscroll", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "wake-on-wifi-packet", "owners": [ "abhishekbh", "chirantan" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 4e00821..4669071b 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3320,6 +3320,12 @@ "Runs the system UI (ash) as a mojo service, but inside the browser " "process. The browser uses the mojo window service (ws) APIs."; +const char kMojoImfName[] = "Mojo-based IMF to bridge the client and IME"; +const char kMojoImfDescription[] = + "Makes the system UI (ash) as the bridge between the client and the IME via" + " mojo APIs. This can only take effect if the flag \"single-process-masn\" " + "is enabled."; + const char kSmartTextSelectionName[] = "Smart Text Selection"; const char kSmartTextSelectionDescription[] = "Shows quick actions for text " @@ -3395,10 +3401,6 @@ const char kVirtualKeyboardName[] = "Virtual Keyboard"; const char kVirtualKeyboardDescription[] = "Enable virtual keyboard support."; -const char kVirtualKeyboardOverscrollName[] = "Virtual Keyboard Overscroll"; -const char kVirtualKeyboardOverscrollDescription[] = - "Enables virtual keyboard overscroll support."; - const char kWakeOnPacketsName[] = "Wake On Packets"; const char kWakeOnPacketsDescription[] = "Enables waking the device based on the receipt of some network packets.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 777d698..38d717f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1974,6 +1974,9 @@ extern const char kAggressiveTabDiscardThresholds[]; extern const char kAggressiveThresholds[]; +extern const char kMojoImfName[]; +extern const char kMojoImfDescription[]; + extern const char kMtpWriteSupportName[]; extern const char kMtpWriteSupportDescription[]; @@ -2055,9 +2058,6 @@ extern const char kVirtualKeyboardName[]; extern const char kVirtualKeyboardDescription[]; -extern const char kVirtualKeyboardOverscrollName[]; -extern const char kVirtualKeyboardOverscrollDescription[]; - extern const char kWakeOnPacketsName[]; extern const char kWakeOnPacketsDescription[];
diff --git a/chrome/browser/lookalikes/lookalike_url_interstitial_page.h b/chrome/browser/lookalikes/lookalike_url_interstitial_page.h index b6c928f..c98b603e 100644 --- a/chrome/browser/lookalikes/lookalike_url_interstitial_page.h +++ b/chrome/browser/lookalikes/lookalike_url_interstitial_page.h
@@ -31,10 +31,11 @@ kTopSite = 1, kSiteEngagement = 2, kEditDistance = 3, + kEditDistanceSiteEngagement = 4, // Append new items to the end of the list above; do not modify or replace // existing values. Comment out obsolete items. - kMaxValue = kEditDistance, + kMaxValue = kEditDistanceSiteEngagement, }; // Used for UKM. There is only a single UserAction per navigation.
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index 51274e1..72567b38 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -90,6 +90,67 @@ return std::string(); } +// Returns the first matching top domain with an edit distance of at most one +// to |domain_and_registry|. +std::string GetSimilarDomainFromTop500(const DomainInfo& navigated_domain) { + for (const std::string& navigated_skeleton : navigated_domain.skeletons) { + for (const char* const top_domain_skeleton : top500_domains::kTop500) { + if (lookalikes::IsEditDistanceAtMostOne( + base::UTF8ToUTF16(navigated_skeleton), + base::UTF8ToUTF16(top_domain_skeleton))) { + const std::string top_domain = + url_formatter::LookupSkeletonInTopDomains(top_domain_skeleton); + DCHECK(!top_domain.empty()); + // If the only difference between the navigated and top + // domains is the registry part, this is unlikely to be a spoofing + // attempt. Ignore this match and continue. E.g. If the navigated domain + // is google.com.tw and the top domain is google.com.tr, this won't + // produce a match. + const std::string top_domain_without_registry = + url_formatter::top_domains::HostnameWithoutRegistry(top_domain); + DCHECK(url_formatter::top_domains::IsEditDistanceCandidate( + top_domain_without_registry)); + if (navigated_domain.domain_without_registry != + top_domain_without_registry) { + return top_domain; + } + } + } + } + return std::string(); +} + +// Returns the first matching engaged domain with an edit distance of at most +// one to |domain_and_registry|. +std::string GetSimilarDomainFromEngagedSites( + const DomainInfo& navigated_domain, + const std::vector<DomainInfo>& engaged_sites) { + for (const std::string& navigated_skeleton : navigated_domain.skeletons) { + for (const DomainInfo& engaged_site : engaged_sites) { + if (!url_formatter::top_domains::IsEditDistanceCandidate( + engaged_site.domain_and_registry)) { + continue; + } + for (const std::string& engaged_skeleton : engaged_site.skeletons) { + if (lookalikes::IsEditDistanceAtMostOne( + base::UTF8ToUTF16(navigated_skeleton), + base::UTF8ToUTF16(engaged_skeleton))) { + // If the only difference between the navigated and engaged + // domain is the registry part, this is unlikely to be a spoofing + // attempt. Ignore this match and continue. E.g. If the navigated + // domain is google.com.tw and the top domain is google.com.tr, this + // won't produce a match. + if (navigated_domain.domain_without_registry != + engaged_site.domain_without_registry) { + return engaged_site.domain_and_registry; + } + } + } + } + } + return std::string(); +} + } // namespace namespace lookalikes { @@ -98,6 +159,47 @@ const char LookalikeUrlNavigationThrottle::kHistogramName[] = "NavigationSuggestion.Event"; +bool IsEditDistanceAtMostOne(const base::string16& str1, + const base::string16& str2) { + if (str1.size() > str2.size() + 1 || str2.size() > str1.size() + 1) { + return false; + } + base::string16::const_iterator i = str1.begin(); + base::string16::const_iterator j = str2.begin(); + size_t edit_count = 0; + while (i != str1.end() && j != str2.end()) { + if (*i == *j) { + i++; + j++; + } else { + edit_count++; + if (edit_count > 1) { + return false; + } + + if (str1.size() > str2.size()) { + // First string is longer than the second. This can only happen if the + // first string has an extra character. + i++; + } else if (str2.size() > str1.size()) { + // Second string is longer than the first. This can only happen if the + // second string has an extra character. + j++; + } else { + // Both strings are the same length. This can only happen if the two + // strings differ by a single character. + i++; + j++; + } + } + } + if (i != str1.end() || j != str2.end()) { + // A character at the end did not match. + edit_count++; + } + return edit_count <= 1; +} + LookalikeUrlNavigationThrottle::LookalikeUrlNavigationThrottle( content::NavigationHandle* navigation_handle) : content::NavigationThrottle(navigation_handle), @@ -204,8 +306,8 @@ const GURL& url, const DomainInfo& navigated_domain, const std::vector<DomainInfo>& engaged_sites) { - ThrottleCheckResult result = LookalikeUrlNavigationThrottle::PerformChecks( - url, navigated_domain, engaged_sites); + ThrottleCheckResult result = + PerformChecks(url, navigated_domain, engaged_sites); if (!interstitials_enabled_) { return; @@ -273,7 +375,7 @@ ukm::SourceId source_id = ukm::ConvertToSourceId( navigation_handle()->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID); - if (interstitials_enabled_ && match_type != MatchType::kEditDistance) { + if (ShouldDisplayInterstitial(match_type)) { return ShowInterstitial(suggested_url, url, source_id, match_type); } @@ -284,12 +386,20 @@ return content::NavigationThrottle::PROCEED; } +bool LookalikeUrlNavigationThrottle::ShouldDisplayInterstitial( + MatchType match_type) const { + return interstitials_enabled_ && match_type != MatchType::kEditDistance && + match_type != MatchType::kEditDistanceSiteEngagement; +} + bool LookalikeUrlNavigationThrottle::GetMatchingDomain( const DomainInfo& navigated_domain, const std::vector<DomainInfo>& engaged_sites, std::string* matched_domain, MatchType* match_type) { DCHECK(!navigated_domain.domain_and_registry.empty()); + DCHECK(matched_domain); + DCHECK(match_type); if (navigated_domain.idn_result.has_idn_component) { // If the navigated domain is IDN, check its skeleton against engaged sites @@ -318,95 +428,34 @@ } } - // If we can't find an exact top domain or an engaged site, try to find a top - // domain within an edit distance of one. - const std::string similar_domain = + if (!url_formatter::top_domains::IsEditDistanceCandidate( + navigated_domain.domain_and_registry)) { + return false; + } + + // If we can't find an exact top domain or an engaged site, try to find an + // engaged domain within an edit distance of one. + const std::string similar_engaged_domain = + GetSimilarDomainFromEngagedSites(navigated_domain, engaged_sites); + if (!similar_engaged_domain.empty() && + navigated_domain.domain_and_registry != similar_engaged_domain) { + RecordEvent(NavigationSuggestionEvent::kMatchEditDistanceSiteEngagement); + *matched_domain = similar_engaged_domain; + *match_type = MatchType::kEditDistanceSiteEngagement; + return true; + } + + // Finally, try to find a top domain within an edit distance of one. + const std::string similar_top_domain = GetSimilarDomainFromTop500(navigated_domain); - if (!similar_domain.empty() && - navigated_domain.domain_and_registry != similar_domain) { + if (!similar_top_domain.empty() && + navigated_domain.domain_and_registry != similar_top_domain) { RecordEvent(NavigationSuggestionEvent::kMatchEditDistance); - *matched_domain = similar_domain; + *matched_domain = similar_top_domain; *match_type = MatchType::kEditDistance; return true; } return false; } -// static -bool LookalikeUrlNavigationThrottle::IsEditDistanceAtMostOne( - const base::string16& str1, - const base::string16& str2) { - if (str1.size() > str2.size() + 1 || str2.size() > str1.size() + 1) { - return false; - } - base::string16::const_iterator i = str1.begin(); - base::string16::const_iterator j = str2.begin(); - size_t edit_count = 0; - while (i != str1.end() && j != str2.end()) { - if (*i == *j) { - i++; - j++; - } else { - edit_count++; - if (edit_count > 1) { - return false; - } - - if (str1.size() > str2.size()) { - // First string is longer than the second. This can only happen if the - // first string has an extra character. - i++; - } else if (str2.size() > str1.size()) { - // Second string is longer than the first. This can only happen if the - // second string has an extra character. - j++; - } else { - // Both strings are the same length. This can only happen if the two - // strings differ by a single character. - i++; - j++; - } - } - } - if (i != str1.end() || j != str2.end()) { - // A character at the end did not match. - edit_count++; - } - return edit_count <= 1; -} - -// static -std::string LookalikeUrlNavigationThrottle::GetSimilarDomainFromTop500( - const DomainInfo& navigated_domain) { - if (!url_formatter::top_domains::IsEditDistanceCandidate( - navigated_domain.domain_and_registry)) { - return std::string(); - } - const std::string domain_without_registry = - url_formatter::top_domains::HostnameWithoutRegistry( - navigated_domain.domain_and_registry); - - for (const std::string& navigated_skeleton : navigated_domain.skeletons) { - for (const char* const top_domain_skeleton : top500_domains::kTop500) { - if (IsEditDistanceAtMostOne(base::UTF8ToUTF16(navigated_skeleton), - base::UTF8ToUTF16(top_domain_skeleton))) { - const std::string top_domain = - url_formatter::LookupSkeletonInTopDomains(top_domain_skeleton); - DCHECK(!top_domain.empty()); - // If the only difference between the navigated and top - // domains is the registry part, this is unlikely to be a spoofing - // attempt. Ignore this match and continue. E.g. If the navigated domain - // is google.com.tw and the top domain is google.com.tr, this won't - // produce a match. - const std::string top_domain_without_registry = - url_formatter::top_domains::HostnameWithoutRegistry(top_domain); - if (domain_without_registry != top_domain_without_registry) { - return top_domain; - } - } - } - } - return std::string(); -} - } // namespace lookalikes
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h index 6b283a5d..743ff61 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.h
@@ -26,6 +26,12 @@ struct DomainInfo; +// Returns true if the Levenshtein distance between |str1| and |str2| is at most +// one. This has O(max(n,m)) complexity as opposed to O(n*m) of the usual edit +// distance computation. +bool IsEditDistanceAtMostOne(const base::string16& str1, + const base::string16& str2); + // Observes navigations and shows an interstitial if the navigated domain name // is visually similar to a top domain or a domain with a site engagement score. class LookalikeUrlNavigationThrottle : public content::NavigationThrottle { @@ -39,13 +45,13 @@ kMatchTopSite = 3, kMatchSiteEngagement = 4, kMatchEditDistance = 5, + kMatchEditDistanceSiteEngagement = 6, // Append new items to the end of the list above; do not modify or // replace existing values. Comment out obsolete items. - kMaxValue = kMatchEditDistance, + kMaxValue = kMatchEditDistanceSiteEngagement, }; - static const char kHistogramName[]; explicit LookalikeUrlNavigationThrottle(content::NavigationHandle* handle); @@ -77,6 +83,9 @@ const DomainInfo& navigated_domain, const std::vector<DomainInfo>& engaged_sites); + bool ShouldDisplayInterstitial( + LookalikeUrlInterstitialPage::MatchType match_type) const; + // Returns true if a domain is visually similar to the hostname of |url|. The // matching domain can be a top domain or an engaged site. Similarity check // is made using both visual skeleton and edit distance comparison. If this @@ -87,16 +96,6 @@ std::string* matched_domain, LookalikeUrlInterstitialPage::MatchType* match_type); - // Returns if the Levenshtein distance between |str1| and |str2| is at most 1. - // This has O(max(n,m)) complexity as opposed to O(n*m) of the usual edit - // distance computation. - static bool IsEditDistanceAtMostOne(const base::string16& str1, - const base::string16& str2); - - // Returns the first matching top domain with an edit distance of at most one - // to |domain_and_registry|. - static std::string GetSimilarDomainFromTop500(const DomainInfo& domain_info); - ThrottleCheckResult ShowInterstitial( const GURL& safe_domain, const GURL& url,
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index 8dfac5ca..922d6704 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -472,6 +472,34 @@ CheckNoUkm(); } +// Navigate to a domain within an edit distance of 1 to an engaged domain. +// This should record metrics, but should not show a lookalike warning +// interstitial yet. +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest, + EditDistance_EngagedDomain_Match) { + base::HistogramTester histograms; + SetEngagementScore(browser(), GURL("https://test-site.com"), kHighEngagement); + + // The skeleton of this domain is one 1 edit away from the skeleton of + // test-site.com. + const GURL kNavigatedUrl = GetURL("best-sité.com"); + // Even if the navigated site has a low engagement score, it should be + // considered for lookalike suggestions. + SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement); + // Advance clock to force a fetch of new engaged sites list. + test_clock()->Advance(base::TimeDelta::FromHours(1)); + + TestInterstitialNotShown(browser(), kNavigatedUrl); + histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName, + 1); + histograms.ExpectBucketCount( + LookalikeUrlNavigationThrottle::kHistogramName, + NavigationSuggestionEvent::kMatchEditDistanceSiteEngagement, 1); + + CheckUkm({kNavigatedUrl}, "MatchType", + MatchType::kEditDistanceSiteEngagement); +} + // Navigate to a domain within an edit distance of 1 to a top domain. // This should record metrics, but should not show a lookalike warning // interstitial yet. @@ -512,6 +540,29 @@ CheckNoUkm(); } +// Tests negative examples for the edit distance with engaged sites. +IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest, + EditDistance_SiteEngagement_NoMatch) { + SetEngagementScore(browser(), GURL("https://test-site.com.tr"), + kHighEngagement); + SetEngagementScore(browser(), GURL("https://1234.com"), kHighEngagement); + SetEngagementScore(browser(), GURL("https://gooogle.com"), kHighEngagement); + // Advance clock to force a fetch of new engaged sites list. + test_clock()->Advance(base::TimeDelta::FromHours(1)); + + // Matches test-site.com.tr but only differs in registry. + TestInterstitialNotShown(browser(), GetURL("test-site.com.tw")); + CheckNoUkm(); + + // Matches gooogle.com but is a top domain itself. + TestInterstitialNotShown(browser(), GetURL("google.com")); + CheckNoUkm(); + + // Matches 1234.com but is too short. + TestInterstitialNotShown(browser(), GetURL("123.com")); + CheckNoUkm(); +} + // Test that the heuristics are triggered even with net errors. IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest, NetError_Interstitial) {
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_unittest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_unittest.cc index 48f6f56..d63b1471 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_unittest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_unittest.cc
@@ -61,9 +61,9 @@ {L"google.com", L"goooglé.com", false}, }; for (const TestCase& test_case : kTestCases) { - bool result = LookalikeUrlNavigationThrottle::IsEditDistanceAtMostOne( - base::WideToUTF16(test_case.domain), - base::WideToUTF16(test_case.top_domain)); + bool result = + IsEditDistanceAtMostOne(base::WideToUTF16(test_case.domain), + base::WideToUTF16(test_case.top_domain)); EXPECT_EQ(test_case.expected, result); } }
diff --git a/chrome/browser/lookalikes/lookalike_url_service.cc b/chrome/browser/lookalikes/lookalike_url_service.cc index d34f4ed..ec88525 100644 --- a/chrome/browser/lookalikes/lookalike_url_service.cc +++ b/chrome/browser/lookalikes/lookalike_url_service.cc
@@ -21,6 +21,7 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/url_formatter/top_domains/top_domain_util.h" #include "components/url_formatter/url_formatter.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -78,9 +79,11 @@ } DomainInfo::DomainInfo(const std::string& arg_domain_and_registry, + const std::string& arg_domain_without_registry, const url_formatter::IDNConversionResult& arg_idn_result, const url_formatter::Skeletons& arg_skeletons) : domain_and_registry(arg_domain_and_registry), + domain_without_registry(arg_domain_without_registry), idn_result(arg_idn_result), skeletons(arg_skeletons) {} @@ -91,10 +94,16 @@ DomainInfo GetDomainInfo(const GURL& url) { // Perform all computations on eTLD+1. const std::string domain_and_registry = GetETLDPlusOne(url.host()); + const std::string domain_without_registry = + domain_and_registry.empty() + ? std::string() + : url_formatter::top_domains::HostnameWithoutRegistry( + domain_and_registry); // eTLD+1 can be empty for private domains. if (domain_and_registry.empty()) { - return DomainInfo(domain_and_registry, url_formatter::IDNConversionResult(), + return DomainInfo(domain_and_registry, domain_without_registry, + url_formatter::IDNConversionResult(), url_formatter::Skeletons()); } // Compute skeletons using eTLD+1, skipping all spoofing checks. Spoofing @@ -105,7 +114,8 @@ url_formatter::UnsafeIDNToUnicodeWithDetails(domain_and_registry); const url_formatter::Skeletons skeletons = url_formatter::GetSkeletons(idn_result.result); - return DomainInfo(domain_and_registry, idn_result, skeletons); + return DomainInfo(domain_and_registry, domain_without_registry, idn_result, + skeletons); } LookalikeUrlService::LookalikeUrlService(Profile* profile)
diff --git a/chrome/browser/lookalikes/lookalike_url_service.h b/chrome/browser/lookalikes/lookalike_url_service.h index 4caf2f8..d17ea5b 100644 --- a/chrome/browser/lookalikes/lookalike_url_service.h +++ b/chrome/browser/lookalikes/lookalike_url_service.h
@@ -34,13 +34,19 @@ struct DomainInfo { // eTLD+1, used for skeleton and edit distance comparison. Must be ASCII. + // Can be empty. const std::string domain_and_registry; + // eTLD+1 without the registry part. For "www.google.com", this will be + // "google". Used for edit distance comparisons. Can be empty. + const std::string domain_without_registry; + // Result of IDN conversion of domain_and_registry field. const url_formatter::IDNConversionResult idn_result; // Skeletons of domain_and_registry field. const url_formatter::Skeletons skeletons; DomainInfo(const std::string& arg_domain_and_registry, + const std::string& arg_domain_without_registry, const url_formatter::IDNConversionResult& arg_idn_result, const url_formatter::Skeletons& arg_skeletons); ~DomainInfo();
diff --git a/chrome/browser/media/webrtc/desktop_media_list_ash.cc b/chrome/browser/media/webrtc/desktop_media_list_ash.cc index dc7e0606..fe498e184a 100644 --- a/chrome/browser/media/webrtc/desktop_media_list_ash.cc +++ b/chrome/browser/media/webrtc/desktop_media_list_ash.cc
@@ -108,12 +108,15 @@ CaptureThumbnail(screen_source.id, root_windows[i]); } else { - EnumerateWindowsForRoot( - sources, root_windows[i], ash::kShellWindowId_DefaultContainer); - EnumerateWindowsForRoot( - sources, root_windows[i], ash::kShellWindowId_AlwaysOnTopContainer); - EnumerateWindowsForRoot( - sources, root_windows[i], ash::kShellWindowId_PipContainer); + constexpr int kContainersIds[] = { + ash::kShellWindowId_DefaultContainerDeprecated, + // TODO(afakhry): Add rest of desks containers. + ash::kShellWindowId_AlwaysOnTopContainer, + ash::kShellWindowId_PipContainer, + }; + + for (int id : kContainersIds) + EnumerateWindowsForRoot(sources, root_windows[i], id); } } }
diff --git a/chrome/browser/net/chrome_extensions_network_delegate.cc b/chrome/browser/net/chrome_extensions_network_delegate.cc index 1181d56..feee2e8 100644 --- a/chrome/browser/net/chrome_extensions_network_delegate.cc +++ b/chrome/browser/net/chrome_extensions_network_delegate.cc
@@ -197,13 +197,22 @@ return result; } +namespace { +void OnHeadersReceivedAdapter(net::CompletionOnceCallback callback, + const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code) { + std::move(callback).Run(error_code); +} +} // namespace + int ChromeExtensionsNetworkDelegateImpl::OnBeforeStartTransaction( net::URLRequest* request, net::CompletionOnceCallback callback, net::HttpRequestHeaders* headers) { return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders( profile_, extension_info_map_.get(), GetWebRequestInfo(request), - std::move(callback), headers); + base::BindOnce(OnHeadersReceivedAdapter, std::move(callback)), headers); } void ChromeExtensionsNetworkDelegateImpl::OnStartTransaction(
diff --git a/chrome/browser/notifications/scheduler/BUILD.gn b/chrome/browser/notifications/scheduler/BUILD.gn index a3af336..195b07d 100644 --- a/chrome/browser/notifications/scheduler/BUILD.gn +++ b/chrome/browser/notifications/scheduler/BUILD.gn
@@ -73,6 +73,8 @@ "icon_store.h", "impression_history_tracker.cc", "impression_history_tracker.h", + "impression_store.cc", + "impression_store.h", "impression_types.cc", "impression_types.h", "internal_types.h", @@ -112,6 +114,7 @@ "distribution_policy_unittest.cc", "icon_store_unittest.cc", "impression_history_tracker_unittest.cc", + "impression_store_unittest.cc", "proto_conversion_unittest.cc", "scheduler_utils_unittest.cc", ]
diff --git a/chrome/browser/notifications/scheduler/impression_store.cc b/chrome/browser/notifications/scheduler/impression_store.cc new file mode 100644 index 0000000..8b79c62 --- /dev/null +++ b/chrome/browser/notifications/scheduler/impression_store.cc
@@ -0,0 +1,100 @@ +// Copyright 2019 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/notifications/scheduler/impression_store.h" + +#include "chrome/browser/notifications/scheduler/proto_conversion.h" + +namespace leveldb_proto { + +void DataToProto(notifications::ClientState* client_state, + notifications::proto::ClientState* proto) { + ClientStateToProto(client_state, proto); +} + +void ProtoToData(notifications::proto::ClientState* proto, + notifications::ClientState* client_state) { + ClientStateFromProto(proto, client_state); +} + +} // namespace leveldb_proto + +namespace notifications { + +ImpressionStore::ImpressionStore( + std::unique_ptr< + leveldb_proto::ProtoDatabase<proto::ClientState, ClientState>> db) + : db_(std::move(db)), weak_ptr_factory_(this) {} + +ImpressionStore::~ImpressionStore() = default; + +void ImpressionStore::InitAndLoad(LoadCallback callback) { + db_->Init(base::BindOnce(&ImpressionStore::OnDbInitialized, + weak_ptr_factory_.GetWeakPtr(), + std::move(callback))); +} + +void ImpressionStore::OnDbInitialized(LoadCallback callback, + leveldb_proto::Enums::InitStatus status) { + if (status != leveldb_proto::Enums::InitStatus::kOK) { + std::move(callback).Run(false, Entries()); + return; + } + + // Load the data after a successful initialization. + db_->LoadEntries(base::BindOnce(&ImpressionStore::OnDataLoaded, + weak_ptr_factory_.GetWeakPtr(), + std::move(callback))); +} + +void ImpressionStore::OnDataLoaded(LoadCallback callback, + bool success, + std::unique_ptr<EntryVector> entry_vector) { + // The database failed to load. + if (!success) { + std::move(callback).Run(false, Entries()); + return; + } + + // Success to load but no data. + if (!entry_vector) { + std::move(callback).Run(true, Entries()); + return; + } + + // Load data. + Entries entries; + for (auto it = entry_vector->begin(); it != entry_vector->end(); ++it) { + std::unique_ptr<ClientState> client_state = std::make_unique<ClientState>(); + *client_state = std::move(*it); + entries.emplace_back(std::move(client_state)); + } + + std::move(callback).Run(true, std::move(entries)); +} + +void ImpressionStore::Add(const std::string& key, + const ClientState& client_state, + UpdateCallback callback) { + Update(key, client_state, std::move(callback)); +} + +void ImpressionStore::Update(const std::string& key, + const ClientState& client_state, + UpdateCallback callback) { + auto entries_to_save = std::make_unique<KeyEntryVector>(); + entries_to_save->emplace_back(std::make_pair(key, client_state)); + db_->UpdateEntries(std::move(entries_to_save), + std::make_unique<KeyVector>() /*keys_to_remove*/, + std::move(callback)); +} + +void ImpressionStore::Delete(const std::string& key, UpdateCallback callback) { + auto keys_to_delete = std::make_unique<KeyVector>(); + keys_to_delete->emplace_back(key); + db_->UpdateEntries(std::make_unique<KeyEntryVector>() /*entries_to_save*/, + std::move(keys_to_delete), std::move(callback)); +} + +} // namespace notifications
diff --git a/chrome/browser/notifications/scheduler/impression_store.h b/chrome/browser/notifications/scheduler/impression_store.h new file mode 100644 index 0000000..3749720a --- /dev/null +++ b/chrome/browser/notifications/scheduler/impression_store.h
@@ -0,0 +1,73 @@ +// Copyright 2019 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_NOTIFICATIONS_SCHEDULER_IMPRESSION_STORE_H_ +#define CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_IMPRESSION_STORE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/notifications/proto/client_state.pb.h" +#include "chrome/browser/notifications/scheduler/collection_store.h" +#include "chrome/browser/notifications/scheduler/impression_types.h" +#include "components/leveldb_proto/public/proto_database.h" + +// Forward declaration for proto conversion. +namespace leveldb_proto { +void DataToProto(notifications::ClientState* client_state, + notifications::proto::ClientState* proto); + +void ProtoToData(notifications::proto::ClientState* proto, + notifications::ClientState* client_state); +} // namespace leveldb_proto + +namespace notifications { + +// An impression storage using a proto database to persist data. +class ImpressionStore : public CollectionStore<ClientState> { + public: + ImpressionStore( + std::unique_ptr< + leveldb_proto::ProtoDatabase<proto::ClientState, ClientState>> db); + ~ImpressionStore() override; + + private: + using KeyEntryVector = std::vector<std::pair<std::string, ClientState>>; + using KeyVector = std::vector<std::string>; + using EntryVector = std::vector<ClientState>; + + // CollectionStore implementation. + void InitAndLoad(LoadCallback callback) override; + void Add(const std::string& key, + const ClientState& client_state, + UpdateCallback callback) override; + void Update(const std::string& key, + const ClientState& client_state, + UpdateCallback callback) override; + void Delete(const std::string& key, UpdateCallback callback) override; + + // Called when the proto database is initialized but no yet loading the data + // into memory. + void OnDbInitialized(LoadCallback callback, + leveldb_proto::Enums::InitStatus status); + + // Called after loading the data from database. + void OnDataLoaded(LoadCallback callback, + bool success, + std::unique_ptr<EntryVector> entry_vector); + + std::unique_ptr<leveldb_proto::ProtoDatabase<proto::ClientState, ClientState>> + db_; + base::WeakPtrFactory<ImpressionStore> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(ImpressionStore); +}; + +} // namespace notifications + +#endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_IMPRESSION_STORE_H_
diff --git a/chrome/browser/notifications/scheduler/impression_store_unittest.cc b/chrome/browser/notifications/scheduler/impression_store_unittest.cc new file mode 100644 index 0000000..4872afe --- /dev/null +++ b/chrome/browser/notifications/scheduler/impression_store_unittest.cc
@@ -0,0 +1,207 @@ +// Copyright 2019 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/notifications/scheduler/impression_store.h" + +#include <map> +#include <memory> +#include <string> +#include <utility> + +#include "base/test/scoped_task_environment.h" +#include "chrome/browser/notifications/proto/client_state.pb.h" +#include "chrome/browser/notifications/scheduler/impression_types.h" +#include "chrome/browser/notifications/scheduler/proto_conversion.h" +#include "components/leveldb_proto/public/proto_database.h" +#include "components/leveldb_proto/testing/fake_db.h" +#include "testing/gtest/include/gtest/gtest.h" + +using leveldb_proto::test::FakeDB; +using InitStatus = leveldb_proto::Enums::InitStatus; +using Entries = notifications::ImpressionStore::Entries; +using DbEntries = std::vector<notifications::ClientState>; +using DbEntriesPtr = std::unique_ptr<std::vector<notifications::ClientState>>; +using TestClientStates = std::map<std::string, notifications::ClientState>; + +namespace notifications { +namespace { + +const char kClientStateKey[] = "guid_client_state_key1"; +const ClientState kDefaultClientState; + +// Test fixture to verify impression store. +class ImpressionStoreTest : public testing::Test { + public: + ImpressionStoreTest() : load_result_(false), db_(nullptr) {} + ~ImpressionStoreTest() override = default; + + void SetUp() override {} + + protected: + // Initialize the store with test data. + void Init(const TestClientStates& test_data, InitStatus status) { + CreateTestProto(test_data); + + auto db = + std::make_unique<FakeDB<proto::ClientState, ClientState>>(&db_entries_); + db_ = db.get(); + store_ = std::make_unique<ImpressionStore>(std::move(db)); + store_->InitAndLoad(base::BindOnce(&ImpressionStoreTest::OnEntriesLoaded, + base::Unretained(this))); + db_->InitStatusCallback(status); + } + + bool load_result() const { return load_result_; } + const Entries& loaded_entries() const { return loaded_entries_; } + FakeDB<proto::ClientState, ClientState>* db() { return db_; } + + CollectionStore<ClientState>* store() { return store_.get(); } + + void OnEntriesLoaded(bool success, Entries entries) { + loaded_entries_ = std::move(entries); + load_result_ = success; + } + + // Verifies the entries in the db is |expected|. + void VerifyDataInDb(DbEntriesPtr expected) { + db_->LoadEntries(base::BindOnce( + [](DbEntriesPtr expected, bool success, DbEntriesPtr entries) { + EXPECT_TRUE(success); + DCHECK(entries); + DCHECK(expected); + EXPECT_EQ(entries->size(), expected->size()); + for (size_t i = 0, size = entries->size(); i < size; ++i) { + EXPECT_EQ((*entries)[i], (*expected)[i]); + } + }, + std::move(expected))); + db_->LoadCallback(true); + } + + private: + void CreateTestProto(const TestClientStates& client_states) { + for (const auto& pair : client_states) { + auto client_state(pair.second); + auto key = pair.first; + notifications::proto::ClientState proto; + ClientStateToProto(&client_state, &proto); + db_entries_.emplace(key, proto); + } + } + + base::test::ScopedTaskEnvironment scoped_task_environment_; + std::map<std::string, proto::ClientState> db_entries_; + bool load_result_; + Entries loaded_entries_; + + FakeDB<proto::ClientState, ClientState>* db_; + std::unique_ptr<CollectionStore<ClientState>> store_; + + DISALLOW_COPY_AND_ASSIGN(ImpressionStoreTest); +}; + +// Initializes an empty database should success. +TEST_F(ImpressionStoreTest, InitSuccessEmptyDb) { + Init(TestClientStates(), InitStatus::kOK); + db()->LoadCallback(true); + EXPECT_EQ(load_result(), true); + EXPECT_TRUE(loaded_entries().empty()); +} + +// Initialize non-empty database should success. +TEST_F(ImpressionStoreTest, InitSuccessWithData) { + auto test_data = TestClientStates(); + test_data.emplace(kClientStateKey, kDefaultClientState); + Init(test_data, InitStatus::kOK); + db()->LoadCallback(true); + EXPECT_EQ(load_result(), true); + EXPECT_EQ(loaded_entries().size(), 1u); + EXPECT_EQ(*loaded_entries().back(), kDefaultClientState); +} + +// Failure when loading the data will result in error. +TEST_F(ImpressionStoreTest, InitSuccessLoadFailed) { + Init(TestClientStates(), InitStatus::kOK); + db()->LoadCallback(false); + EXPECT_EQ(load_result(), false); + EXPECT_TRUE(loaded_entries().empty()); +} + +// Failed database initialization will result in error. +TEST_F(ImpressionStoreTest, InitFailed) { + Init(TestClientStates(), InitStatus::kCorrupt); + EXPECT_EQ(load_result(), false); + EXPECT_TRUE(loaded_entries().empty()); +} + +// Verifies adding data. +TEST_F(ImpressionStoreTest, Add) { + Init(TestClientStates(), InitStatus::kOK); + db()->LoadCallback(true); + EXPECT_EQ(load_result(), true); + EXPECT_TRUE(loaded_entries().empty()); + + // Add data to the store. + store()->Add(kClientStateKey, kDefaultClientState, + base::BindOnce([](bool success) { EXPECT_TRUE(success); })); + db()->UpdateCallback(true); + + // Verify the new data is in the database. + auto expected = std::make_unique<DbEntries>(); + expected->emplace_back(kDefaultClientState); + VerifyDataInDb(std::move(expected)); +} + +// Verifies failure when adding data will result in error. +TEST_F(ImpressionStoreTest, AddFailed) { + Init(TestClientStates(), InitStatus::kOK); + db()->LoadCallback(true); + EXPECT_EQ(load_result(), true); + EXPECT_TRUE(loaded_entries().empty()); + + store()->Add(kClientStateKey, kDefaultClientState, + base::BindOnce([](bool success) { EXPECT_FALSE(success); })); + db()->UpdateCallback(false); +} + +// Verifies updating data. +TEST_F(ImpressionStoreTest, Update) { + auto test_data = TestClientStates(); + test_data.emplace(kClientStateKey, kDefaultClientState); + Init(test_data, InitStatus::kOK); + db()->LoadCallback(true); + EXPECT_EQ(load_result(), true); + + ClientState new_client_state; + new_client_state.current_max_daily_show = 100; + + // Update the database. + store()->Update(kClientStateKey, new_client_state, + base::BindOnce([](bool success) { EXPECT_TRUE(success); })); + db()->UpdateCallback(true); + + // Verify the updated data is in the database. + auto expected = std::make_unique<DbEntries>(); + expected->emplace_back(new_client_state); + VerifyDataInDb(std::move(expected)); +} + +// Verifies deleting data. +TEST_F(ImpressionStoreTest, Delete) { + auto test_data = TestClientStates(); + test_data.emplace(kClientStateKey, kDefaultClientState); + Init(test_data, InitStatus::kOK); + db()->LoadCallback(true); + EXPECT_EQ(load_result(), true); + + // Delete the entry. + store()->Delete(kClientStateKey, + base::BindOnce([](bool success) { EXPECT_TRUE(success); })); + + // Verify there is no data in the database. + VerifyDataInDb(std::make_unique<DbEntries>()); +} + +} // namespace +} // namespace notifications
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc index 94084a4c..54394a2 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor.cc
@@ -26,10 +26,21 @@ using resource_coordinator::GetMRUScorerPenaltyTabRanker; using resource_coordinator::GetScorerTypeForTabRanker; -// ReverseRank maps a positive number to the range (0.0, 1.0). -inline float ReverseRank(const float a) { - DCHECK_GE(a, 0.0f); - return 1.0f / (1.0f + a); +// Maps the |mru_index| to it's reverse rank in (0.0, 1.0). +// High score means more likely to be reactivated. +// We use inverse rank because we think that the first several |mru_index| is +// more significant than the larger ones. +inline float MruToScore(const float mru_index) { + DCHECK_GE(mru_index, 0.0f); + return 1.0f / (1.0f + mru_index); +} + +// Maps the |discard_count| to a score in (0.0, 1.0), for which +// High score means more likely to be reactivated. +// We use std::exp because we think that the first several |discard_count| is +// not as significant as the larger ones. +inline float DiscardCountToScore(const float discard_count) { + return std::exp(discard_count); } // Loads the preprocessor config protobuf, which lists each feature, their @@ -83,8 +94,8 @@ // The default value of discard_count_penalty_ is 0.0f, which will not change // the score. // The larger the |discard_count_penalty_| is (set from Finch), the quicker - // the score decreases based on the discard_count. - *score *= ReverseRank(tab.discard_count * discard_count_penalty_); + // the score increases based on the discard_count. + *score *= DiscardCountToScore(tab.discard_count * discard_count_penalty_); return result; } @@ -142,7 +153,7 @@ TabRankerResult TabScorePredictor::ScoreTabWithMRUScorer(const TabFeatures& tab, float* score) { - *score = ReverseRank(tab.mru_index * mru_scorer_penalty_); + *score = MruToScore(tab.mru_index * mru_scorer_penalty_); return TabRankerResult::kSuccess; }
diff --git a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc index d883647..ac22f52 100644 --- a/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_ranker/tab_score_predictor_unittest.cc
@@ -65,13 +65,13 @@ scoped_feature_list_.InitAndEnableFeatureWithParameters( features::kTabRanker, {{"scorer_type", "0"}, {"mru_scorer_penalty", "0.2345"}, - {"discard_count_penalty", "0.5678"}}); + {"discard_count_penalty", "0.2468"}}); // Pre-calculated score using the generated model outside of Chrome. auto tab = GetFullTabFeaturesForTesting(); EXPECT_FLOAT_EQ(ScoreTab(tab), 0.13639774); tab.discard_count = 3; - EXPECT_FLOAT_EQ(ScoreTab(tab), 0.05045415); + EXPECT_FLOAT_EQ(ScoreTab(tab), 0.28599524); } } // namespace tab_ranker
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js index 54527b7e..3f16cc7 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
@@ -676,10 +676,12 @@ true); } else { var root = ChromeVoxState.instance.currentRange.start.node.root; - if (root && root.anchorObject && root.focusObject) { + if (root && root.selectionStartObject && root.selectionEndObject) { var sel = new cursors.Range( - new cursors.Cursor(root.anchorObject, root.anchorOffset), - new cursors.Cursor(root.focusObject, root.focusOffset)); + new cursors.Cursor( + root.selectionStartObject, root.selectionStartOffset), + new cursors.Cursor( + root.selectionEndObject, root.selectionEndOffset)); var o = new Output() .format('@end_selection') .withSpeechAndBraille(sel, sel, Output.EventType.NAVIGATE)
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs index 9a84912..97d21f8 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
@@ -344,18 +344,18 @@ new cursors.Cursor(p2.firstChild, 4)); function verifySel() { - if (root.anchorObject == link.firstChild) { - assertEquals(link.firstChild, root.anchorObject); - assertEquals(0, root.anchorOffset); - assertEquals(link.firstChild, root.focusObject); - assertEquals(1, root.focusOffset); + if (root.selectionStartObject == link.firstChild) { + assertEquals(link.firstChild, root.selectionStartObject); + assertEquals(0, root.selectionStartOffset); + assertEquals(link.firstChild, root.selectionEndObject); + assertEquals(1, root.selectionEndOffset); this.listenOnce(root, 'textSelectionChanged', verifySel); multiSel.select(); - } else if (root.anchorObject == p1.firstChild) { - assertEquals(p1.firstChild, root.anchorObject); - assertEquals(2, root.anchorOffset); - assertEquals(p2.firstChild, root.focusObject); - assertEquals(4, root.focusOffset); + } else if (root.selectionStartObject == p1.firstChild) { + assertEquals(p1.firstChild, root.selectionStartObject); + assertEquals(2, root.selectionStartOffset); + assertEquals(p2.firstChild, root.selectionEndObject); + assertEquals(4, root.selectionEndOffset); } } @@ -400,14 +400,14 @@ */}, function(root) { root.addEventListener('textSelectionChanged', this.newCallback(function(evt) { // Test setup moves initial focus; ensure we don't test that here. - if (testNode != root.anchorObject) + if (testNode != root.selectionStartObject) return; // This is a little unexpected though not really incorrect; Ctrl+C works. - assertEquals(testNode, root.anchorObject); - assertEquals(ofSelectionNode, root.focusObject); - assertEquals(4, root.anchorOffset); - assertEquals(1, root.focusOffset); + assertEquals(testNode, root.selectionStartObject); + assertEquals(ofSelectionNode, root.selectionEndObject); + assertEquals(4, root.selectionStartOffset); + assertEquals(1, root.selectionEndOffset); })); // This is the link's static text.
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js index cd92f93..20e843e41a 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -372,10 +372,10 @@ * @param {!AutomationEvent} evt */ onDocumentSelectionChanged: function(evt) { - var anchor = evt.target.anchorObject; + var selectionStart = evt.target.selectionStartObject; // No selection. - if (!anchor) + if (!selectionStart) return; // A caller requested this event be ignored. @@ -384,10 +384,11 @@ return; // Editable selection. - if (anchor.state[StateType.EDITABLE]) { - anchor = AutomationUtil.getEditableRoot(anchor) || anchor; + if (selectionStart.state[StateType.EDITABLE]) { + selectionStart = + AutomationUtil.getEditableRoot(selectionStart) || selectionStart; this.onEditableChanged_( - new CustomAutomationEvent(evt.type, anchor, evt.eventFrom)); + new CustomAutomationEvent(evt.type, selectionStart, evt.eventFrom)); } // Non-editable selections are handled in |Background|. @@ -536,14 +537,15 @@ } // Sync the ChromeVox range to the editable, if a selection exists. - var anchorObject = evt.target.root.anchorObject; - var anchorOffset = evt.target.root.anchorOffset || 0; - var focusObject = evt.target.root.focusObject; - var focusOffset = evt.target.root.focusOffset || 0; - if (anchorObject && focusObject) { + var selectionStartObject = evt.target.root.selectionStartObject; + var selectionStartOffset = evt.target.root.selectionStartOffset || 0; + var selectionEndObject = evt.target.root.selectionEndObject; + var selectionEndOffset = evt.target.root.selectionEndOffset || 0; + if (selectionStartObject && selectionEndObject) { var selectedRange = new cursors.Range( - new cursors.WrappingCursor(anchorObject, anchorOffset), - new cursors.WrappingCursor(focusObject, focusOffset)); + new cursors.WrappingCursor( + selectionStartObject, selectionStartOffset), + new cursors.WrappingCursor(selectionEndObject, selectionEndOffset)); // Sync ChromeVox range with selection. ChromeVoxState.instance.setCurrentRange(selectedRange);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js index cab980a..ada6cbc 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js
@@ -265,18 +265,20 @@ AutomationEditableText.call(this, node); var root = this.node_.root; - if (!root || !root.anchorObject || !root.focusObject || - root.anchorOffset === undefined || root.focusOffset === undefined) + if (!root || !root.selectionStartObject || !root.selectionEndObject || + root.selectionStartOffset === undefined || + root.selectionEndOffset === undefined) return; this.anchorLine_ = new editing.EditableLine( - root.anchorObject, root.anchorOffset, root.anchorObject, - root.anchorOffset); + root.selectionStartObject, root.selectionStartOffset, + root.selectionStartObject, root.selectionStartOffset); this.focusLine_ = new editing.EditableLine( root.focusObject, root.focusOffset, root.focusObject, root.focusOffset); this.line_ = new editing.EditableLine( - root.anchorObject, root.anchorOffset, root.focusObject, root.focusOffset); + root.selectionStartObject, root.selectionStartOffset, + root.selectionEndObject, root.selectionEndOffset); this.updateIntraLineState_(this.line_); @@ -358,13 +360,14 @@ /** @override */ onUpdate: function(eventFrom) { var root = this.node_.root; - if (!root.anchorObject || !root.focusObject || - root.anchorOffset === undefined || root.focusOffset === undefined) + if (!root.selectionStartObject || !root.selectionEndObject || + root.selectionStartOffset === undefined || + root.selectionEndOffset === undefined) return; var anchorLine = new editing.EditableLine( - root.anchorObject, root.anchorOffset, root.anchorObject, - root.anchorOffset); + root.selectionStartObject, root.selectionStartOffset, + root.selectionStartObject, root.selectionStartOffset); var focusLine = new editing.EditableLine( root.focusObject, root.focusOffset, root.focusObject, root.focusOffset); @@ -386,8 +389,8 @@ return; } else { cur = new editing.EditableLine( - root.anchorObject, root.anchorOffset, root.focusObject, - root.focusOffset, baseLineOnStart); + root.selectionStartObject, root.selectionStartOffset, + root.selectionEndObject, root.selectionEndOffset, baseLineOnStart); } var prev = this.line_; this.line_ = cur;
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js index 3428953e5..37d71be 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js +++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js
@@ -184,20 +184,21 @@ */ requestSpeakSelectedText_: function(focusedNode) { // If nothing is selected, return early. - if (!focusedNode || !focusedNode.root || !focusedNode.root.anchorObject || - !focusedNode.root.focusObject) { + if (!focusedNode || !focusedNode.root || + !focusedNode.root.selectionStartObject || + !focusedNode.root.selectionEndObject) { this.onNullSelection_(); return; } - let anchorObject = focusedNode.root.anchorObject; - let anchorOffset = focusedNode.root.anchorOffset || 0; - let focusObject = focusedNode.root.focusObject; - let focusOffset = focusedNode.root.focusOffset || 0; + let anchorObject = focusedNode.root.selectionStartObject; + let anchorOffset = focusedNode.root.selectionStartOffset || 0; + let focusObject = focusedNode.root.selectionEndObject; + let focusOffset = focusedNode.root.selectionEndOffset || 0; if (anchorObject === focusObject && anchorOffset == focusOffset) { this.onNullSelection_(); return; } - // First calculate the equivalant position for this selection. + // First calculate the equivalent position for this selection. // Sometimes the automation selection returns a offset into a root // node rather than a child node, which may be a bug. This allows us to // work around that bug until it is fixed or redefined.
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index b1c488c..1772ec2c 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -112,6 +112,7 @@ "internet_page:closure_compile", "kiosk_next_shell_page:closure_compile", "multidevice_page:closure_compile", + "plugin_vm_page:closure_compile", ] } }
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index 22d4e7f2..4ce82aa8 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -19,8 +19,8 @@ <link rel="import" href="../android_apps_page/android_apps_browser_proxy.html"> <link rel="import" href="../android_apps_page/android_apps_page.html"> <link rel="import" href="../bluetooth_page/bluetooth_page.html"> -<link rel="import" href="../kiosk_next_shell_page/kiosk_next_shell_page.html"> <link rel="import" href="../crostini_page/crostini_page.html"> +<link rel="import" href="../plugin_vm_page/plugin_vm_page.html"> <link rel="import" href="../kiosk_next_shell_page/kiosk_next_shell_page.html"> <link rel="import" href="../device_page/device_page.html"> <link rel="import" href="../internet_page/internet_page.html"> @@ -214,6 +214,13 @@ </settings-crostini-page> </settings-section> </template> + <template is="dom-if" if="[[showPluginVm]]" restamp> + <settings-section page-title="$i18n{pluginVmPageTitle}" + section="pluginVm"> + <settings-plugin-vm-page prefs="{{prefs}}" + </settings-plugin-vm-page> + </settings-section> + </template> </if> <if expr="not chromeos"> <template is="dom-if" if="[[showPage_(pageVisibility.defaultBrowser)]]"
diff --git a/chrome/browser/resources/settings/plugin_vm_page/BUILD.gn b/chrome/browser/resources/settings/plugin_vm_page/BUILD.gn new file mode 100644 index 0000000..d414bf60 --- /dev/null +++ b/chrome/browser/resources/settings/plugin_vm_page/BUILD.gn
@@ -0,0 +1,28 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ + ":plugin_vm_page", + ":plugin_vm_subpage", + ] +} + +js_library("plugin_vm_page") { + deps = [ + "..:route", + "../prefs:prefs_behavior", + "//ui/webui/resources/js:i18n_behavior", + ] + externs_list = [ "$externs_path/settings_private.js" ] +} + +js_library("plugin_vm_subpage") { + deps = [ + "..:route", + "../prefs:prefs_behavior", + ] +}
diff --git a/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_page.html b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_page.html new file mode 100644 index 0000000..4587790 --- /dev/null +++ b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_page.html
@@ -0,0 +1,36 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="../i18n_setup.html"> +<link rel="import" href="../settings_page/settings_animated_pages.html"> +<link rel="import" href="../settings_page/settings_subpage.html"> +<link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="plugin_vm_subpage.html"> + +<dom-module id="settings-plugin-vm-page"> + <template> + <style include="settings-shared"></style> + + <settings-animated-pages id="pages" section="pluginVm" + focus-config="[[focusConfig_]]"> + <div route-path="default"> + <cr-link-row id="pluginVmRow" + label="$i18n{pluginVmPageLabel}" + sub-label="$i18n{pluginVmPageSubtext}" + on-click="onSubpageClick_"></cr-link-row> + </div> + + <template is="dom-if" route-path="/pluginVm/details"> + <settings-subpage + associated-control="[[$$('#pluginVmRow')]]" + page-title="$i18n{pluginVmPageLabel}"> + <settings-plugin-vm-subpage prefs="{{prefs}}"> + </settings-plugin-vm-subpage> + </settings-subpage> + </template> + </settings-animated-pages> + + </template> + <script src="plugin_vm_page.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_page.js b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_page.js new file mode 100644 index 0000000..476442b --- /dev/null +++ b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_page.js
@@ -0,0 +1,39 @@ +// Copyright 2019 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. + +/** + * @fileoverview + * 'plugin-vm-page' is the settings page for Plugin VM. + */ + +Polymer({ + is: 'settings-plugin-vm-page', + + behaviors: [PrefsBehavior], + + properties: { + /** Preferences state. */ + prefs: { + type: Object, + notify: true, + }, + + /** @private {!Map<string, string>} */ + focusConfig_: { + type: Object, + value: function() { + const map = new Map(); + if (settings.routes.PLUGIN_VM_DETAILS) { + map.set(settings.routes.PLUGIN_VM_DETAILS.path, '#pluginVmRow'); + } + return map; + }, + }, + }, + + /** @private */ + onSubpageClick_: function(event) { + settings.navigateTo(settings.routes.PLUGIN_VM_DETAILS); + }, +});
diff --git a/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_subpage.html b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_subpage.html new file mode 100644 index 0000000..3da3e1d --- /dev/null +++ b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_subpage.html
@@ -0,0 +1,14 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../controls/settings_toggle_button.html"> + +<dom-module id="settings-plugin-vm-subpage"> + <template> + <style include="settings-shared"></style> + <!-- TODO(timloh): Wire this up to a pref. --> + <settings-toggle-button label="$i18n{pluginVmPrinterAccess}"> + </settings-toggle-button> + </template> + <script src="plugin_vm_subpage.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_subpage.js b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_subpage.js new file mode 100644 index 0000000..b4f3423 --- /dev/null +++ b/chrome/browser/resources/settings/plugin_vm_page/plugin_vm_subpage.js
@@ -0,0 +1,22 @@ +// Copyright 2019 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. + +/** + * @fileoverview + * 'plugin-vm-subpage' is the settings subpage for managing Plugin VM. + */ + +Polymer({ + is: 'settings-plugin-vm-subpage', + + behaviors: [PrefsBehavior], + + properties: { + /** Preferences state. */ + prefs: { + type: Object, + notify: true, + }, + }, +});
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index c446473..a145333 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -146,6 +146,13 @@ sub-label="$i18n{manageCertificatesDescription}" on-click="onManageCertificatesTap_"></cr-link-row> </if> + <template is="dom-if" if="[[enableSecurityKeysSubpage_]]"> + <cr-link-row id="security-keys-subpage-trigger" + class="hr" + label="$i18n{securityKeysTitle}" + sub-label="$i18n{securityKeysDesc}" + on-click="onSecurityKeysTap_"></cr-link-row> + </template> <cr-link-row id="site-settings-subpage-trigger" class="hr" label="[[siteSettingsPageTitle_()]]" @@ -156,13 +163,6 @@ label="$i18n{clearBrowsingData}" sub-label="$i18n{clearBrowsingDataDescription}" on-click="onClearBrowsingDataTap_"></cr-link-row> - <template is="dom-if" if="[[enableSecurityKeysSubpage_]]"> - <cr-link-row id="security-keys-subpage-trigger" - class="hr" - label="$i18n{securityKeysTitle}" - sub-label="$i18n{securityKeysDesc}" - on-click="onSecurityKeysTap_"></cr-link-row> - </template> </div> <if expr="use_nss_certs">
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index 5507464..b647462a 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -61,6 +61,8 @@ * PASSWORDS: (undefined|!settings.Route), * PAYMENTS: (undefined|!settings.Route), * PEOPLE: (undefined|!settings.Route), + * PLUGIN_VM: (undefined|!settings.Route), + * PLUGIN_VM_DETAILS: (undefined|!settings.Route), * POINTERS: (undefined|!settings.Route), * POWER: (undefined|!settings.Route), * PRINTING: (undefined|!settings.Route), @@ -285,6 +287,12 @@ r.CROSTINI_SHARED_USB_DEVICES = r.CROSTINI.createChild('/crostini/sharedUsbDevices'); } + + if (loadTimeData.valueExists('showPluginVm') && + loadTimeData.getBoolean('showPluginVm')) { + r.PLUGIN_VM = r.BASIC.createSection('/pluginVm', 'pluginVm'); + r.PLUGIN_VM_DETAILS = r.PLUGIN_VM.createChild('/pluginVm/details'); + } // </if> if (pageVisibility.onStartup !== false) {
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html index e9be4ea..1d8db206 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.html +++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -66,6 +66,7 @@ show-android-apps="[[showAndroidApps]]" show-kiosk-next-shell="[[showKioskNextShell]]" show-crostini="[[showCrostini]]" + show-plugin-vm="[[showPluginVm]]" have-play-store-app="[[havePlayStoreApp]]" on-showing-section="onShowingSection_" on-subpage-expand="onShowingSubpage_"
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chrome/browser/resources/settings/settings_menu/settings_menu.html index 8c2ebc1..e5c162ee 100644 --- a/chrome/browser/resources/settings/settings_menu/settings_menu.html +++ b/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -138,12 +138,16 @@ <iron-icon icon="settings:play-prism"></iron-icon> $i18n{androidAppsPageTitle} </a> -</if> -<if expr="chromeos"> <a href="/crostini" hidden="[[!showCrostini]]"> <iron-icon icon="settings:crostini-mascot"></iron-icon> $i18n{crostiniPageTitle} </a> + <a href="/pluginVm" hidden="[[!showPluginVm]]"> + <!-- TODO(crbug.com/950738): The placeholder iron-icon here is needed + for spacing. Replace this once we get the proper icon. --> + <iron-icon icon="cr:info"></iron-icon> + $i18n{pluginVmPageTitle} + </a> </if> <if expr="not chromeos"> <a id="defaultBrowser" href="/defaultBrowser"
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index b2b4234..830ccc5 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -1544,6 +1544,18 @@ <structure name="IDR_SETTINGS_PEOPLE_FINGERPRINT_BROWSER_PROXY_HTML" file="people_page/fingerprint_browser_proxy.html" type="chrome_html" /> + <structure name="IDR_SETTINGS_PLUGIN_VM_PAGE_HTML" + file="plugin_vm_page/plugin_vm_page.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_PLUGIN_VM_PAGE_JS" + file="plugin_vm_page/plugin_vm_page.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_PLUGIN_VM_SUBPAGE_HTML" + file="plugin_vm_page/plugin_vm_subpage.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_PLUGIN_VM_SUBPAGE_JS" + file="plugin_vm_page/plugin_vm_subpage.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_USERS_PAGE_ADD_USER_DIALOG_JS" file="people_page/users_add_user_dialog.js" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html index 372b651..6e1e81d8 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -70,6 +70,7 @@ <settings-menu page-visibility="[[pageVisibility_]]" show-android-apps="[[showAndroidApps_]]" show-crostini="[[showCrostini_]]" + show-plugin-vm="[[showPluginVm_]]" show-multidevice="[[showMultidevice_]]" have-play-store-app="[[havePlayStoreApp_]]" on-iron-activate="onIronActivate_" @@ -85,6 +86,7 @@ show-android-apps="[[showAndroidApps_]]" show-kiosk-next-shell="[[showKioskNextShell_]]" show-crostini="[[showCrostini_]]" + show-plugin-vm="[[showPluginVm_]]" show-multidevice="[[showMultidevice_]]" have-play-store-app="[[havePlayStoreApp_]]" advanced-toggle-expanded="{{advancedOpened_}}">
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index 14c3b80..90e150c 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -60,6 +60,9 @@ showCrostini_: Boolean, /** @private */ + showPluginVm_: Boolean, + + /** @private */ havePlayStoreApp_: Boolean, /** @private */ @@ -146,6 +149,8 @@ loadTimeData.getBoolean('showKioskNextShell'); this.showCrostini_ = loadTimeData.valueExists('showCrostini') && loadTimeData.getBoolean('showCrostini'); + this.showPluginVm_ = loadTimeData.valueExists('showPluginVm') && + loadTimeData.getBoolean('showPluginVm'); this.havePlayStoreApp_ = loadTimeData.valueExists('havePlayStoreApp') && loadTimeData.getBoolean('havePlayStoreApp');
diff --git a/chrome/browser/sessions/session_restore_android.cc b/chrome/browser/sessions/session_restore_android.cc index 93632ba..fda4f5fd 100644 --- a/chrome/browser/sessions/session_restore_android.cc +++ b/chrome/browser/sessions/session_restore_android.cc
@@ -49,8 +49,7 @@ } else { DCHECK(disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB || disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB); - tab_model->CreateTab(current_tab, new_web_contents.release(), - current_tab->GetAndroidId()); + tab_model->CreateTab(current_tab, new_web_contents.release()); } return raw_new_web_contents; }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index ebd2bb8..e69ebb0 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1292,6 +1292,7 @@ "//chrome/browser/ui/webui/app_management:mojo_bindings", "//chrome/common:buildflags", "//chrome/common:search_mojom", + "//chrome/services/app_service/public/cpp:app_service_proxy", "//chrome/services/app_service/public/cpp:app_update", "//chrome/services/app_service/public/mojom", "//components/feedback/proto",
diff --git a/chrome/browser/ui/android/tab_model/android_live_tab_context.cc b/chrome/browser/ui/android/tab_model/android_live_tab_context.cc index cf2cd82..0223dab 100644 --- a/chrome/browser/ui/android/tab_model/android_live_tab_context.cc +++ b/chrome/browser/ui/android/tab_model/android_live_tab_context.cc
@@ -100,7 +100,7 @@ // Create new tab. Ownership is passed into java, which in turn creates a new // TabAndroid instance to own the WebContents. - tab_model_->CreateTab(nullptr, web_contents.release(), -1); + tab_model_->CreateTab(nullptr, web_contents.release()); raw_web_contents->GetController().LoadIfNecessary(); return sessions::ContentLiveTab::GetForWebContents(raw_web_contents); }
diff --git a/chrome/browser/ui/android/tab_model/tab_model.h b/chrome/browser/ui/android/tab_model/tab_model.h index df4e18e..81e0214 100644 --- a/chrome/browser/ui/android/tab_model/tab_model.h +++ b/chrome/browser/ui/android/tab_model/tab_model.h
@@ -121,8 +121,7 @@ // Used for restoring tabs from synced foreign sessions. virtual void CreateTab(TabAndroid* parent, - content::WebContents* web_contents, - int parent_tab_id) = 0; + content::WebContents* web_contents) = 0; virtual void HandlePopupNavigation(TabAndroid* parent, NavigateParams* params) = 0;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc index 595ba1f..ce552b2 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -90,13 +90,12 @@ } void TabModelJniBridge::CreateTab(TabAndroid* parent, - WebContents* web_contents, - int parent_tab_id) { + WebContents* web_contents) { JNIEnv* env = AttachCurrentThread(); Java_TabModelJniBridge_createTabWithWebContents( env, java_object_.get(env), (parent ? parent->GetJavaObject() : nullptr), web_contents->GetBrowserContext()->IsOffTheRecord(), - web_contents->GetJavaWebContents(), parent_tab_id); + web_contents->GetJavaWebContents()); } void TabModelJniBridge::HandlePopupNavigation(TabAndroid* parent,
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h index 443b19b2..d8b0980 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h
@@ -52,8 +52,7 @@ void CloseTabAt(int index) override; void CreateTab(TabAndroid* parent, - content::WebContents* web_contents, - int parent_tab_id) override; + content::WebContents* web_contents) override; void HandlePopupNavigation(TabAndroid* parent, NavigateParams* params) override;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc index d603b9ba..ee6eea4 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc
@@ -23,8 +23,7 @@ return nullptr; } void CreateTab(TabAndroid* parent, - content::WebContents* web_contents, - int parent_tab_id) override {} + content::WebContents* web_contents) override {} void HandlePopupNavigation(TabAndroid* parent, NavigateParams* params) override {} content::WebContents* CreateNewTabForDevTools(const GURL& url) override {
diff --git a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc index 1a5e579f..edc31823 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
@@ -36,8 +36,7 @@ return NULL; } void CreateTab(TabAndroid* parent, - content::WebContents* web_contents, - int parent_tab_id) override {} + content::WebContents* web_contents) override {} void HandlePopupNavigation(TabAndroid* parent, NavigateParams* params) override {} content::WebContents* CreateNewTabForDevTools(const GURL& url) override {
diff --git a/chrome/browser/ui/app_list/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service_app_item.cc index f993165f..09858783 100644 --- a/chrome/browser/ui/app_list/app_service_app_item.cc +++ b/chrome/browser/ui/app_list/app_service_app_item.cc
@@ -6,11 +6,12 @@ #include "ash/public/cpp/app_list/app_list_config.h" #include "base/bind.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/arc/arc_app_context_menu.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_context_menu.h" #include "chrome/browser/ui/app_list/extension_app_context_menu.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" // static const char AppServiceAppItem::kItemType[] = "AppServiceAppItem"; @@ -118,7 +119,8 @@ void AppServiceAppItem::Launch(int event_flags, apps::mojom::LaunchSource launch_source) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile()); if (proxy) { proxy->Launch(id(), event_flags, launch_source, GetController()->GetAppListDisplayId()); @@ -126,7 +128,8 @@ } void AppServiceAppItem::CallLoadIcon(bool allow_placeholder_icon) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile()); if (proxy) { proxy->LoadIcon(app_type_, id(), apps::mojom::IconCompression::kUncompressed,
diff --git a/chrome/browser/ui/app_list/app_service_app_model_builder.cc b/chrome/browser/ui/app_list/app_service_app_model_builder.cc index 00377d9b..5ad32f2 100644 --- a/chrome/browser/ui/app_list/app_service_app_model_builder.cc +++ b/chrome/browser/ui/app_list/app_service_app_model_builder.cc
@@ -4,8 +4,9 @@ #include "chrome/browser/ui/app_list/app_service_app_model_builder.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ui/app_list/app_service_app_item.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" AppServiceAppModelBuilder::AppServiceAppModelBuilder( AppListControllerDelegate* controller) @@ -14,7 +15,8 @@ AppServiceAppModelBuilder::~AppServiceAppModelBuilder() = default; void AppServiceAppModelBuilder::BuildModel() { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile()); if (proxy) { proxy->AppRegistryCache().ForEachApp( [this](const apps::AppUpdate& update) { OnAppUpdate(update); });
diff --git a/chrome/browser/ui/app_list/extension_app_context_menu.cc b/chrome/browser/ui/app_list/extension_app_context_menu.cc index 1c5513f..2d83f5b 100644 --- a/chrome/browser/ui/app_list/extension_app_context_menu.cc +++ b/chrome/browser/ui/app_list/extension_app_context_menu.cc
@@ -12,6 +12,8 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" +#include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "content/public/common/context_menu_params.h" @@ -86,8 +88,12 @@ profile(), this, menu_model, base::Bind(MenuItemHasLauncherContext)); + bool is_system_web_app = web_app::WebAppProvider::Get(profile()) + ->system_web_app_manager() + .IsSystemWebApp(app_id()); + // First, add the primary actions. - if (!is_platform_app_) + if (!is_platform_app_ && !is_system_web_app) CreateOpenNewSubmenu(menu_model); // Create default items. @@ -107,7 +113,7 @@ is_platform_app_ ? IDS_APP_LIST_UNINSTALL_ITEM : IDS_APP_LIST_EXTENSIONS_UNINSTALL); - if (controller()->CanDoShowAppInfoFlow()) { + if (controller()->CanDoShowAppInfoFlow() && !is_system_web_app) { AddContextMenuOption(menu_model, ash::SHOW_APP_INFO, IDS_APP_CONTEXT_MENU_SHOW_INFO); }
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index 1cd381a..7a73c38 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -28,7 +28,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/clock.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service.h" @@ -56,6 +56,7 @@ #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "components/sync/base/model_type.h" #include "components/sync_sessions/session_sync_service.h" #include "extensions/browser/extension_prefs.h" @@ -288,9 +289,10 @@ public: AppServiceDataSource(Profile* profile, AppSearchProvider* owner) : AppSearchProvider::DataSource(profile, owner), - icon_cache_(apps::AppServiceProxy::Get(profile), + icon_cache_(apps::AppServiceProxyFactory::GetForProfile(profile), apps::IconCache::GarbageCollectionPolicy::kExplicit) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile); if (proxy) { Observe(&proxy->AppRegistryCache()); } @@ -300,7 +302,8 @@ // AppSearchProvider::DataSource overrides: void AddApps(AppSearchProvider::Apps* apps_vector) override { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile()); if (!proxy) { return; }
diff --git a/chrome/browser/ui/app_list/search/app_service_app_result.cc b/chrome/browser/ui/app_list/search/app_service_app_result.cc index 6b8a7ea..125397eb 100644 --- a/chrome/browser/ui/app_list/search/app_service_app_result.cc +++ b/chrome/browser/ui/app_list/search/app_service_app_result.cc
@@ -7,10 +7,11 @@ #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "base/bind.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_service_app_item.h" #include "chrome/browser/ui/app_list/search/internal_app_result.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "extensions/common/extension.h" namespace app_list { @@ -26,7 +27,8 @@ is_platform_app_(false), show_in_launcher_(false), weak_ptr_factory_(this) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile); if (proxy) { proxy->AppRegistryCache().ForOneApp( @@ -117,7 +119,8 @@ void AppServiceAppResult::Launch(int event_flags, apps::mojom::LaunchSource launch_source) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile()); if (proxy) { proxy->Launch(app_id(), event_flags, launch_source, controller()->GetAppListDisplayId());
diff --git a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc index 038984be..7b8a5ee 100644 --- a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
@@ -20,7 +20,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_impl.h" #include "chrome/browser/chromeos/crostini/crostini_test_helper.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/sync/session_sync_service_factory.h" @@ -795,7 +795,8 @@ return; } - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile()); + apps::AppServiceProxyImpl* proxy = + apps::AppServiceProxyImpl::GetImplForTesting(profile()); ASSERT_NE(proxy, nullptr); apps::StubIconLoader stub_icon_loader;
diff --git a/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc b/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc index cad041f..3fa3da0e 100644 --- a/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc +++ b/chrome/browser/ui/ash/drag_to_overview_interactive_uitest.cc
@@ -201,6 +201,7 @@ gfx::Vector2d delta(0, drag_length / kSteps); // Drag tab far enough to detach. + test::WaitForNoPointerHoldLock(); drag_position.Offset(0, GetDetachY(browser_view->tabstrip())); ui_controls::SendMouseMoveNotifyWhenDone( drag_position.x(), drag_position.y(),
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc index 609610a..d7c5ef2 100644 --- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc +++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
@@ -240,8 +240,7 @@ return cached_keyboard_config_->overscroll_behavior == keyboard::mojom::KeyboardOverscrollBehavior::kEnabled; } - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - keyboard::switches::kDisableVirtualKeyboardOverscroll); + return true; } GURL ChromeKeyboardControllerClient::GetVirtualKeyboardUrl() {
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc index aa2619b..ca6c88b 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -26,7 +26,6 @@ #include "components/account_id/account_id.h" #include "components/arc/arc_util.h" #include "components/arc/session/arc_bridge_service.h" -#include "components/exo/shell_surface_util.h" #include "components/user_manager/user_manager.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" @@ -172,9 +171,13 @@ void ArcAppWindowLauncherController::OnWindowVisibilityChanged( aura::Window* window, bool visible) { + const int task_id = arc::GetWindowTaskId(window); + if (task_id == arc::kNoTaskId) + return; + // Attach window to multi-user manager now to let it manage visibility state // of the ARC window correctly. - if (GetWindowTaskId(window) > 0) { + if (task_id != arc::kSystemWindowTaskId) { MultiUserWindowManagerClient::GetInstance()->SetWindowOwner( window, user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId()); @@ -228,14 +231,15 @@ void ArcAppWindowLauncherController::AttachControllerToWindowIfNeeded( aura::Window* window) { - const int task_id = GetWindowTaskId(window); - if (task_id >= 0) { - // System windows are also arc apps. - window->SetProperty(aura::client::kAppType, - static_cast<int>(ash::AppType::ARC_APP)); - } + const int task_id = arc::GetWindowTaskId(window); + if (task_id == arc::kNoTaskId) + return; - if (task_id <= 0) + // System windows are also arc apps. + window->SetProperty(aura::client::kAppType, + static_cast<int>(ash::AppType::ARC_APP)); + + if (task_id == arc::kSystemWindowTaskId) return; // Check if we have controller for this task. @@ -540,16 +544,3 @@ app_window->SetController(nullptr); app_window_info->set_app_window(nullptr); } - -// static -int ArcAppWindowLauncherController::GetWindowTaskId(aura::Window* window) { - const std::string* arc_app_id = exo::GetShellApplicationId(window); - if (!arc_app_id) - return -1; - - int task_id = -1; - if (sscanf(arc_app_id->c_str(), "org.chromium.arc.%d", &task_id) != 1) - return -1; - - return task_id; -}
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h index 5507e9b..486958b 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
@@ -39,9 +39,6 @@ explicit ArcAppWindowLauncherController(ChromeLauncherController* owner); ~ArcAppWindowLauncherController() override; - // Returns ARC task id for the window. - static int GetWindowTaskId(aura::Window* window); - // AppWindowLauncherController: void ActiveUserChanged(const std::string& user_email) override; void AdditionalUserAddedToSession(Profile* profile) override;
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc index 69414f4..6fc603e1 100644 --- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc +++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/crostini/crostini_registry_service.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" #include "chrome/browser/chromeos/crostini/crostini_util.h" +#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/launcher/app_window_base.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" @@ -26,6 +27,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" +#include "components/arc/arc_util.h" #include "components/exo/shell_surface_util.h" #include "components/user_manager/user_manager.h" #include "extensions/browser/app_window/app_window.h" @@ -172,7 +174,11 @@ return; // Transient windows are set up after window Init, so remove them here. - if (wm::GetTransientParent(window)) { + // TODO(timloh): ARC and Plugin VM are similar, but Crostini shouldn't need to + // know about them. + if (wm::GetTransientParent(window) || + arc::GetWindowTaskId(window) != arc::kNoTaskId || + plugin_vm::IsPluginVmWindow(window)) { DCHECK(aura_window_to_app_window_.find(window) == aura_window_to_app_window_.end()); auto it = observed_windows_.find(window); @@ -199,15 +205,12 @@ return; } - // Handle genuine Crostini app windows. - const std::string* window_app_id = exo::GetShellApplicationId(window); - crostini::CrostiniRegistryService* registry_service = crostini::CrostiniRegistryServiceFactory::GetForProfile( owner()->profile()); const std::string& shelf_app_id = registry_service->GetCrostiniShelfAppId( - window_app_id, exo::GetShellStartupId(window)); - // Non-crostini apps (i.e. arc++) are filtered out here. + exo::GetShellApplicationId(window), exo::GetShellStartupId(window)); + // Windows without an application id set will get filtered out here. if (shelf_app_id.empty()) return;
diff --git a/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc index 454b57d..5783b8b 100644 --- a/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc +++ b/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc
@@ -17,6 +17,8 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h" #include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" +#include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "content/public/common/context_menu_params.h" @@ -170,12 +172,17 @@ } void ExtensionLauncherContextMenu::BuildMenu(ui::SimpleMenuModel* menu_model) { + Profile* profile = controller()->profile(); extension_items_.reset(new extensions::ContextMenuMatcher( - controller()->profile(), this, menu_model, - base::Bind(MenuItemHasLauncherContext))); + profile, this, menu_model, + base::BindRepeating(MenuItemHasLauncherContext))); if (item().type == ash::TYPE_PINNED_APP || item().type == ash::TYPE_APP) { - // V1 apps can be started from the menu - but V2 apps should not. - if (!controller()->IsPlatformApp(item().id)) + // V1 apps can be started from the menu - but V2 apps and system web apps + // should not. + bool is_system_web_app = web_app::WebAppProvider::Get(profile) + ->system_web_app_manager() + .IsSystemWebApp(item().id.app_id); + if (!controller()->IsPlatformApp(item().id) && !is_system_web_app) CreateOpenNewSubmenu(menu_model); AddPinMenu(menu_model); @@ -186,7 +193,7 @@ } else if (item().type == ash::TYPE_BROWSER_SHORTCUT) { AddContextMenuOption(menu_model, ash::MENU_NEW_WINDOW, IDS_APP_LIST_NEW_WINDOW); - if (!controller()->profile()->IsGuestSession()) { + if (!profile->IsGuestSession()) { AddContextMenuOption(menu_model, ash::MENU_NEW_INCOGNITO_WINDOW, IDS_APP_LIST_NEW_INCOGNITO_WINDOW); }
diff --git a/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc index 0d79bbe..5b10b35 100644 --- a/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc +++ b/chrome/browser/ui/ash/launcher/internal_app_window_shelf_controller.cc
@@ -102,11 +102,8 @@ ash::ShelfID::Deserialize(window->GetProperty(ash::kShelfIDKey)); if (shelf_id.IsNull()) { - const std::string* window_app_id = exo::GetShellApplicationId(window); - if (!window_app_id || - !plugin_vm::IsPluginVmExoApplicationId(*window_app_id)) { + if (!plugin_vm::IsPluginVmWindow(window)) return; - } shelf_id = ash::ShelfID(plugin_vm::kPluginVmAppId); window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize()));
diff --git a/chrome/browser/ui/ash/launcher_animations_interactive_uitest.cc b/chrome/browser/ui/ash/launcher_animations_interactive_uitest.cc new file mode 100644 index 0000000..632e8373 --- /dev/null +++ b/chrome/browser/ui/ash/launcher_animations_interactive_uitest.cc
@@ -0,0 +1,106 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/task/post_task.h" +#include "chrome/browser/ui/ash/ash_test_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/test/base/perf/performance_test.h" +#include "content/public/test/test_utils.h" +#include "ui/base/test/ui_controls.h" + +// TODO(oshima): Add tablet mode overview transition. +class LauncherAnimationsTest : public UIPerformanceTest { + public: + LauncherAnimationsTest() = default; + ~LauncherAnimationsTest() override = default; + + // UIPerformanceTest: + void SetUpOnMainThread() override { + UIPerformanceTest::SetUpOnMainThread(); + + if (base::SysInfo::IsRunningOnChromeOS()) { + base::RunLoop run_loop; + base::PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromSeconds(5)); + run_loop.Run(); + } + } + + // UIPerformanceTest: + std::vector<std::string> GetUMAHistogramNames() const override { + return { + "Apps.StateTransition.AnimationSmoothness.TabletMode", + }; + } + + private: + DISALLOW_COPY_AND_ASSIGN(LauncherAnimationsTest); +}; + +IN_PROC_BROWSER_TEST_F(LauncherAnimationsTest, Fullscreen) { + // Browser window is used to identify display, so we can use + // use the 1st browser window regardless of number of windows created. + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + aura::Window* browser_window = browser_view->GetWidget()->GetNativeWindow(); + ash::mojom::ShellTestApiPtr shell_test_api = test::GetShellTestApi(); + { + base::RunLoop waiter; + shell_test_api->WaitForLauncherAnimationState( + ash::mojom::LauncherAnimationState::kFullscreenAllApps, + waiter.QuitClosure()); + ui_controls::SendKeyPress(browser_window, ui::VKEY_BROWSER_SEARCH, + /*control=*/false, + /*shift=*/true, + /*alt=*/false, + /* command = */ false); + waiter.Run(); + } + { + base::RunLoop waiter; + shell_test_api->WaitForLauncherAnimationState( + ash::mojom::LauncherAnimationState::kClosed, waiter.QuitClosure()); + ui_controls::SendKeyPress(browser_window, ui::VKEY_BROWSER_SEARCH, + /*control=*/false, + /*shift=*/true, + /*alt=*/false, + /* command = */ false); + + waiter.Run(); + } +} + +IN_PROC_BROWSER_TEST_F(LauncherAnimationsTest, Peeking) { + // Browser window is used to identify display, so we can use + // use the 1st browser window regardless of number of windows created. + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + aura::Window* browser_window = browser_view->GetWidget()->GetNativeWindow(); + ash::mojom::ShellTestApiPtr shell_test_api = test::GetShellTestApi(); + { + base::RunLoop waiter; + shell_test_api->WaitForLauncherAnimationState( + ash::mojom::LauncherAnimationState::kPeeking, waiter.QuitClosure()); + ui_controls::SendKeyPress(browser_window, ui::VKEY_BROWSER_SEARCH, + /*control=*/false, + /*shift=*/false, + /*alt=*/false, + /* command = */ false); + waiter.Run(); + } + { + base::RunLoop waiter; + shell_test_api->WaitForLauncherAnimationState( + ash::mojom::LauncherAnimationState::kClosed, waiter.QuitClosure()); + ui_controls::SendKeyPress(browser_window, ui::VKEY_BROWSER_SEARCH, + /*control=*/false, + /*shift=*/false, + /*alt=*/false, + /* command = */ false); + waiter.Run(); + } +}
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc index c30e271..06c6d214 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/process/process_handle.h" +#include "base/strings/utf_string_conversions.h" #include "base/win/windows_version.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/themes/theme_service.h" @@ -41,8 +42,7 @@ browser_view_(browser_view), browser_frame_(browser_frame) {} -BrowserDesktopWindowTreeHostWin::~BrowserDesktopWindowTreeHostWin() { -} +BrowserDesktopWindowTreeHostWin::~BrowserDesktopWindowTreeHostWin() {} views::NativeMenuWin* BrowserDesktopWindowTreeHostWin::GetSystemMenu() { if (!system_menu_.get()) { @@ -74,6 +74,52 @@ //////////////////////////////////////////////////////////////////////////////// // BrowserDesktopWindowTreeHostWin, views::DesktopWindowTreeHostWin overrides: +void BrowserDesktopWindowTreeHostWin::Init( + const views::Widget::InitParams& params) { + DesktopWindowTreeHostWin::Init(params); + if (base::win::GetVersion() < base::win::VERSION_WIN10) + return; // VirtualDesktopManager isn't support pre Win-10. + + CHECK(SUCCEEDED(::CoCreateInstance(__uuidof(VirtualDesktopManager), nullptr, + CLSCTX_ALL, + IID_PPV_ARGS(&virtual_desktop_manager_)))); + + if (!params.workspace.empty()) { + GUID guid = GUID_NULL; + HRESULT hr = + CLSIDFromString(base::UTF8ToUTF16(params.workspace).c_str(), &guid); + if (SUCCEEDED(hr)) { + // There are valid reasons MoveWindowToDesktop can fail, e.g., + // the desktop was deleted. If it fails, the window will open on the + // current desktop. + virtual_desktop_manager_->MoveWindowToDesktop(GetHWND(), guid); + } + } + // This will force the window to re-open in this desktop on restart. + // We always want to do this even if |params.workspace| is empty, to handle + // the case of new windows. + OnHostWorkspaceChanged(); +} + +std::string BrowserDesktopWindowTreeHostWin::GetWorkspace() const { + std::string workspace_id; + if (virtual_desktop_manager_) { + GUID workspace_guid; + HRESULT hr = virtual_desktop_manager_->GetWindowDesktopId(GetHWND(), + &workspace_guid); + if (SUCCEEDED(hr)) { + LPOLESTR workspace_widestr; + StringFromCLSID(workspace_guid, &workspace_widestr); + workspace_id = base::WideToUTF8(workspace_widestr); + workspace_ = workspace_id; + CoTaskMemFree(workspace_widestr); + } else { + return workspace_.value_or(""); + } + } + return workspace_id; +} + int BrowserDesktopWindowTreeHostWin::GetInitialShowState() const { STARTUPINFO si = {0}; si.cb = sizeof(si); @@ -195,6 +241,11 @@ WPARAM w_param, LPARAM l_param) { switch (message) { + case WM_ACTIVATE: { + if (workspace_.value_or("") != GetWorkspace()) + OnHostWorkspaceChanged(); + break; + }; case WM_CREATE: minimize_button_metrics_.Init(GetHWND()); break; @@ -300,6 +351,5 @@ BrowserFrame* browser_frame) { return new BrowserDesktopWindowTreeHostWin(native_widget_delegate, desktop_native_widget_aura, - browser_view, - browser_frame); + browser_view, browser_frame); }
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.h b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.h index d547eaf..4c93fe9 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.h +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.h
@@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_DESKTOP_WINDOW_TREE_HOST_WIN_H_ #define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_DESKTOP_WINDOW_TREE_HOST_WIN_H_ +#include <shobjidl.h> +#include <wrl/client.h> + #include "base/macros.h" #include "chrome/browser/ui/views/frame/browser_desktop_window_tree_host.h" #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" @@ -38,6 +41,8 @@ bool UsesNativeSystemMenu() const override; // Overridden from DesktopWindowTreeHostWin: + void Init(const views::Widget::InitParams& params) override; + std::string GetWorkspace() const override; int GetInitialShowState() const override; bool GetClientAreaInsets(gfx::Insets* insets, HMONITOR monitor) const override; @@ -68,6 +73,16 @@ // The wrapped system menu itself. std::unique_ptr<views::NativeMenuWin> system_menu_; + // On Windows10, this is the virtual desktop the browser window was on, + // last we checked. This is used to tell if the window has moved to a + // different desktop, and notify listeners. It will only be set if + // we created |virtual_desktop_manager_|. + mutable base::Optional<std::string> workspace_; + + // Only set on Windows10. Set by GetOrCreateVirtualDesktopManager(). + mutable Microsoft::WRL::ComPtr<IVirtualDesktopManager> + virtual_desktop_manager_; + DISALLOW_COPY_AND_ASSIGN(BrowserDesktopWindowTreeHostWin); };
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index 9ff25db..cf670e9 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -763,6 +763,14 @@ caption_button_container_->SetVisible(should_show_caption_buttons); if (hosted_app_button_container()) hosted_app_button_container()->SetVisible(should_show_caption_buttons); + + // The entire frame should be repainted for v1 apps, since its visibility can + // change (see also ShouldPaint()). Do not invoke this on normal browser + // windows since it does not have to repaint frame except for the caption + // buttons and repainting might cause stuttering of the animation. See + // https://crbug.com/949227. + if (!browser_view()->IsBrowserTypeNormal()) + SchedulePaint(); } std::unique_ptr<ash::FrameHeader>
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index 4262c89..6edd5d7 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -29,46 +29,6 @@ // Opacity of the active tab background painted over inactive selected tabs. constexpr float kSelectedTabOpacity = 0.75f; -// Cache of pre-painted backgrounds for tabs. -class BackgroundCache { - public: - BackgroundCache() = default; - ~BackgroundCache() = default; - - // Updates the cache key with the new values. - // Returns true if any of the values changed. - bool UpdateCacheKey(float scale, - const gfx::Size& size, - SkColor active_color, - SkColor inactive_color, - SkColor stroke_color, - float stroke_thickness); - - const sk_sp<cc::PaintRecord>& fill_record() const { return fill_record_; } - void set_fill_record(sk_sp<cc::PaintRecord>&& record) { - fill_record_ = record; - } - - const sk_sp<cc::PaintRecord>& stroke_record() const { return stroke_record_; } - void set_stroke_record(sk_sp<cc::PaintRecord>&& record) { - stroke_record_ = record; - } - - private: - // Parameters used to construct the PaintRecords. - float scale_ = 0.f; - gfx::Size size_; - SkColor active_color_ = 0; - SkColor inactive_color_ = 0; - SkColor stroke_color_ = 0; - float stroke_thickness_ = 0.f; - - sk_sp<cc::PaintRecord> fill_record_; - sk_sp<cc::PaintRecord> stroke_record_; - - DISALLOW_COPY_AND_ASSIGN(BackgroundCache); -}; - // Tab style implementation for the GM2 refresh (Chrome 69). class GM2TabStyle : public TabStyleViews { public: @@ -153,10 +113,6 @@ std::unique_ptr<GlowHoverController> hover_controller_; - // Cache of the paint output for tab backgrounds. - mutable BackgroundCache background_active_cache_; - mutable BackgroundCache background_inactive_cache_; - DISALLOW_COPY_AND_ASSIGN(GM2TabStyle); }; @@ -183,22 +139,6 @@ return true; } -// BackgroundCache ------------------------------------------------------------- - -bool BackgroundCache::UpdateCacheKey(float scale, - const gfx::Size& size, - SkColor active_color, - SkColor inactive_color, - SkColor stroke_color, - float stroke_thickness) { - // Use | instead of || to prevent lazy evaluation. - return UpdateValue(&scale_, scale) | UpdateValue(&size_, size) | - UpdateValue(&active_color_, active_color) | - UpdateValue(&inactive_color_, inactive_color) | - UpdateValue(&stroke_color_, stroke_color) | - UpdateValue(&stroke_thickness_, stroke_thickness); -} - // GM2TabStyle ----------------------------------------------------------------- GM2TabStyle::GM2TabStyle(Tab* tab) @@ -731,61 +671,15 @@ const SkColor stroke_color = tab_->controller()->GetToolbarTopSeparatorColor(); const bool paint_hover_effect = !active && IsHoverActive(); - const float scale = canvas->image_scale(); const float stroke_thickness = GetStrokeThickness(active); - // If there is a |fill_id| we don't try to cache. This could be improved but - // would require knowing then the image from the ThemeProvider had been - // changed, and invalidating when the tab's x-coordinate or background_offset_ - // changed. - // - // If |paint_hover_effect|, we don't try to cache since hover effects change - // on every invalidation and we would need to invalidate the cache based on - // the hover states. - // - // Finally, we don't cache for non-integral scale factors, since tabs draw - // with slightly different offsets so as to pixel-align the layout rect (see - // ScaleAndAlignBounds()). - if (fill_id || paint_hover_effect || (std::trunc(scale) != scale)) { - PaintTabBackgroundFill(canvas, active, paint_hover_effect, active_color, - inactive_color, fill_id, y_inset); - if (stroke_thickness > 0) { - gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr); - if (clip) - canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true); - PaintBackgroundStroke(canvas, active, stroke_color); - } - } else { - const gfx::Size& size = tab_->size(); - BackgroundCache& cache = - active ? background_active_cache_ : background_inactive_cache_; - - // If any of the cache key values have changed, update the cached records. - if (cache.UpdateCacheKey(scale, size, active_color, inactive_color, - stroke_color, stroke_thickness)) { - cc::PaintRecorder recorder; - { - gfx::Canvas cache_canvas( - recorder.beginRecording(size.width(), size.height()), scale); - PaintTabBackgroundFill(&cache_canvas, active, paint_hover_effect, - active_color, inactive_color, fill_id, y_inset); - cache.set_fill_record(recorder.finishRecordingAsPicture()); - } - if (stroke_thickness > 0) { - gfx::Canvas cache_canvas( - recorder.beginRecording(size.width(), size.height()), scale); - PaintBackgroundStroke(&cache_canvas, active, stroke_color); - cache.set_stroke_record(recorder.finishRecordingAsPicture()); - } - } - - canvas->sk_canvas()->drawPicture(cache.fill_record()); - if (stroke_thickness > 0) { - gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr); - if (clip) - canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true); - canvas->sk_canvas()->drawPicture(cache.stroke_record()); - } + PaintTabBackgroundFill(canvas, active, paint_hover_effect, active_color, + inactive_color, fill_id, y_inset); + if (stroke_thickness > 0) { + gfx::ScopedCanvas scoped_canvas(clip ? canvas : nullptr); + if (clip) + canvas->sk_canvas()->clipPath(*clip, SkClipOp::kDifference, true); + PaintBackgroundStroke(canvas, active, stroke_color); } PaintSeparators(canvas);
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc index 91ff996..1cbf7df 100644 --- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc +++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -9,10 +9,11 @@ #include "base/containers/flat_map.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/services/app_service/public/cpp/app_registry_cache.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" #include "chrome/services/app_service/public/mojom/types.mojom.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" @@ -48,7 +49,8 @@ shelf_delegate_(this) #endif { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in // incognito @@ -62,7 +64,8 @@ void AppManagementPageHandler::OnPinnedChanged(const std::string& app_id, bool pinned) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in // incognito @@ -87,7 +90,8 @@ } void AppManagementPageHandler::GetApps(GetAppsCallback callback) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in // incognito @@ -136,7 +140,8 @@ void AppManagementPageHandler::SetPermission( const std::string& app_id, apps::mojom::PermissionPtr permission) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in // incognito @@ -147,7 +152,8 @@ } void AppManagementPageHandler::Uninstall(const std::string& app_id) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in // incognito @@ -158,7 +164,8 @@ } void AppManagementPageHandler::OpenNativeSettings(const std::string& app_id) { - apps::AppServiceProxy* proxy = apps::AppServiceProxy::Get(profile_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile_); // TODO(crbug.com/826982): revisit pending decision on AppServiceProxy in // incognito
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc index 239730a..eb22e97 100644 --- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc +++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" #include "components/arc/arc_prefs.h" +#include "components/arc/arc_util.h" #include "components/exo/shell_surface_util.h" #include "components/exo/surface.h" #include "components/exo/wm_helper.h" @@ -226,8 +227,7 @@ // Handle ARC current active window if any. DiscardActiveArcWindow(); - active_task_id_ = - ArcAppWindowLauncherController::GetWindowTaskId(gained_active); + active_task_id_ = arc::GetWindowTaskId(gained_active); if (active_task_id_ <= 0) return;
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index fa40b7e..b083f92 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" #include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" +#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" @@ -148,6 +149,9 @@ html_source->AddBoolean("allowCrostini", crostini::IsCrostiniUIAllowedForProfile(profile)); + html_source->AddBoolean("showPluginVm", + plugin_vm::IsPluginVmEnabled(profile)); + html_source->AddBoolean("isDemoSession", chromeos::DemoSession::IsDeviceInDemoMode());
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 4259c13..ba0f3da 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -490,6 +490,21 @@ base::FeatureList::IsEnabled(chromeos::features::kCrostiniUsbSupport)); } +void AddPluginVmStrings(content::WebUIDataSource* html_source, + Profile* profile) { + static constexpr LocalizedString kLocalizedStrings[] = { + {"pluginVmPageTitle", IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE}, + {"pluginVmPageLabel", IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL}, + {"pluginVmPrinterAccess", IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS}, + }; + AddLocalizedStringsBulk(html_source, kLocalizedStrings, + base::size(kLocalizedStrings)); + html_source->AddString( + "pluginVmPageSubtext", + l10n_util::GetStringFUTF16(IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT, + ui::GetChromeOSDeviceName())); +} + void AddKioskNextShellStrings(content::WebUIDataSource* html_source) { static constexpr LocalizedString kLocalizedStrings[] = { {"kioskNextShellPageTitle", IDS_SETTINGS_KIOSK_NEXT_SHELL_TITLE}, @@ -2861,6 +2876,7 @@ #if defined(OS_CHROMEOS) AddCrostiniStrings(html_source, profile); + AddPluginVmStrings(html_source, profile); AddKioskNextShellStrings(html_source); AddAndroidAppStrings(html_source); AddBluetoothStrings(html_source);
diff --git a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc index bc07536..1ea5ba7 100644 --- a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc
@@ -196,6 +196,9 @@ WebAppProvider::Get(browser()->profile()) ->system_web_app_manager() .GetAppIdForSystemApp(web_app::SystemAppType::SETTINGS)); + EXPECT_TRUE(WebAppProvider::Get(browser()->profile()) + ->system_web_app_manager() + .IsSystemWebApp(app->id())); } } // namespace web_app
diff --git a/chrome/browser/web_applications/components/pending_app_manager.h b/chrome/browser/web_applications/components/pending_app_manager.h index 1b4c158a..afd16b0 100644 --- a/chrome/browser/web_applications/components/pending_app_manager.h +++ b/chrome/browser/web_applications/components/pending_app_manager.h
@@ -14,6 +14,7 @@ #include "base/containers/flat_map.h" #include "base/macros.h" #include "chrome/browser/web_applications/components/install_options.h" +#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "url/gurl.h" namespace web_app { @@ -104,7 +105,13 @@ SynchronizeCallback callback); // Returns the app id for |url| if the PendingAppManager is aware of it. - virtual base::Optional<std::string> LookupAppId(const GURL& url) const = 0; + virtual base::Optional<AppId> LookupAppId(const GURL& url) const = 0; + + // Returns whether the PendingAppManager has installed an app with |app_id| + // from |install_source|. + virtual bool HasAppIdWithInstallSource( + const AppId& app_id, + web_app::InstallSource install_source) const = 0; private: struct SynchronizeRequest {
diff --git a/chrome/browser/web_applications/components/test_pending_app_manager.cc b/chrome/browser/web_applications/components/test_pending_app_manager.cc index b05481c..3c0443e 100644 --- a/chrome/browser/web_applications/components/test_pending_app_manager.cc +++ b/chrome/browser/web_applications/components/test_pending_app_manager.cc
@@ -91,9 +91,15 @@ return urls; } -base::Optional<std::string> TestPendingAppManager::LookupAppId( +base::Optional<AppId> TestPendingAppManager::LookupAppId( const GURL& url) const { return base::Optional<std::string>(); } +bool TestPendingAppManager::HasAppIdWithInstallSource( + const AppId& app_id, + web_app::InstallSource install_source) const { + return false; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/components/test_pending_app_manager.h b/chrome/browser/web_applications/components/test_pending_app_manager.h index 69ebab7..d635d2a 100644 --- a/chrome/browser/web_applications/components/test_pending_app_manager.h +++ b/chrome/browser/web_applications/components/test_pending_app_manager.h
@@ -56,7 +56,10 @@ OnceInstallCallback callback) override; std::vector<GURL> GetInstalledAppUrls( InstallSource install_source) const override; - base::Optional<std::string> LookupAppId(const GURL& url) const override; + base::Optional<AppId> LookupAppId(const GURL& url) const override; + bool HasAppIdWithInstallSource( + const AppId& app_id, + web_app::InstallSource install_source) const override; private: void DoInstall(InstallOptions install_options, OnceInstallCallback callback);
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc index 4480c40..002a6642 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc
@@ -131,11 +131,18 @@ install_source); } -base::Optional<std::string> PendingBookmarkAppManager::LookupAppId( +base::Optional<web_app::AppId> PendingBookmarkAppManager::LookupAppId( const GURL& url) const { return extension_ids_map_.LookupExtensionId(url); } +bool PendingBookmarkAppManager::HasAppIdWithInstallSource( + const web_app::AppId& app_id, + web_app::InstallSource install_source) const { + return web_app::ExtensionIdsMap::HasExtensionIdWithInstallSource( + profile_->GetPrefs(), app_id, install_source); +} + void PendingBookmarkAppManager::SetTaskFactoryForTesting( TaskFactory task_factory) { task_factory_ = std::move(task_factory);
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h index f9637e08..693bda2 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h
@@ -67,7 +67,10 @@ OnceInstallCallback callback) override; std::vector<GURL> GetInstalledAppUrls( web_app::InstallSource install_source) const override; - base::Optional<std::string> LookupAppId(const GURL& url) const override; + base::Optional<web_app::AppId> LookupAppId(const GURL& url) const override; + bool HasAppIdWithInstallSource( + const web_app::AppId& app_id, + web_app::InstallSource install_source) const override; void SetTaskFactoryForTesting(TaskFactory task_factory); void SetUninstallerForTesting(
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index 6583d62..0785fd12f 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -77,6 +77,11 @@ return pending_app_manager_->LookupAppId(app->second); } +bool SystemWebAppManager::IsSystemWebApp(const AppId& app_id) const { + return pending_app_manager_->HasAppIdWithInstallSource( + app_id, InstallSource::kSystemInstalled); +} + void SystemWebAppManager::SetSystemAppsForTesting( base::flat_map<SystemAppType, GURL> system_app_urls) { system_app_urls_ = std::move(system_app_urls);
diff --git a/chrome/browser/web_applications/system_web_app_manager.h b/chrome/browser/web_applications/system_web_app_manager.h index d6fef20..538de46 100644 --- a/chrome/browser/web_applications/system_web_app_manager.h +++ b/chrome/browser/web_applications/system_web_app_manager.h
@@ -40,6 +40,9 @@ // Returns the app id for the given System App |id|. base::Optional<std::string> GetAppIdForSystemApp(SystemAppType id) const; + // Returns whether |app_id| points to an installed System App. + bool IsSystemWebApp(const AppId& app_id) const; + protected: void SetSystemAppsForTesting( base::flat_map<SystemAppType, GURL> system_app_urls);
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc index 99c7e1a0..463a90e 100644 --- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc +++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -572,45 +572,104 @@ "GetAnchorObjectID", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper) { - result.Set(v8::Number::New( - isolate, tree_wrapper->tree()->data().sel_anchor_object_id)); + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + result.Set(v8::Number::New(isolate, tree_data.sel_anchor_object_id)); }); RouteTreeIDFunction( "GetAnchorOffset", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper) { - result.Set(v8::Number::New( - isolate, tree_wrapper->tree()->data().sel_anchor_offset)); + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + result.Set(v8::Number::New(isolate, tree_data.sel_anchor_offset)); }); RouteTreeIDFunction( "GetAnchorAffinity", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper) { - result.Set(CreateV8String( - isolate, - ui::ToString(tree_wrapper->tree()->data().sel_anchor_affinity))); + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + result.Set(CreateV8String(isolate, + ui::ToString(tree_data.sel_anchor_affinity))); }); RouteTreeIDFunction( "GetFocusObjectID", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper) { - result.Set(v8::Number::New( - isolate, tree_wrapper->tree()->data().sel_focus_object_id)); + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + result.Set(v8::Number::New(isolate, tree_data.sel_focus_object_id)); }); RouteTreeIDFunction( "GetFocusOffset", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper) { - result.Set(v8::Number::New( - isolate, tree_wrapper->tree()->data().sel_focus_offset)); + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + result.Set(v8::Number::New(isolate, tree_data.sel_focus_offset)); }); RouteTreeIDFunction( "GetFocusAffinity", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper) { - result.Set(CreateV8String( - isolate, - ui::ToString(tree_wrapper->tree()->data().sel_focus_affinity))); + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + result.Set(CreateV8String(isolate, + ui::ToString(tree_data.sel_focus_affinity))); + }); + RouteTreeIDFunction( + "GetSelectionStartObjectID", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper) { + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + int32_t start_object_id = tree_data.sel_is_backward + ? tree_data.sel_focus_object_id + : tree_data.sel_anchor_object_id; + result.Set(v8::Number::New(isolate, start_object_id)); + }); + RouteTreeIDFunction( + "GetSelectionStartOffset", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper) { + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + int start_offset = tree_data.sel_is_backward + ? tree_data.sel_focus_offset + : tree_data.sel_anchor_offset; + result.Set(v8::Number::New(isolate, start_offset)); + }); + RouteTreeIDFunction( + "GetSelectionStartAffinity", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper) { + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + ax::mojom::TextAffinity start_affinity = + tree_data.sel_is_backward ? tree_data.sel_focus_affinity + : tree_data.sel_anchor_affinity; + result.Set(CreateV8String(isolate, ui::ToString(start_affinity))); + }); + RouteTreeIDFunction( + "GetSelectionEndObjectID", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper) { + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + int32_t end_object_id = tree_data.sel_is_backward + ? tree_data.sel_anchor_object_id + : tree_data.sel_focus_object_id; + result.Set(v8::Number::New(isolate, end_object_id)); + }); + RouteTreeIDFunction( + "GetSelectionEndOffset", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper) { + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + int end_offset = tree_data.sel_is_backward ? tree_data.sel_anchor_offset + : tree_data.sel_focus_offset; + result.Set(v8::Number::New(isolate, end_offset)); + }); + RouteTreeIDFunction( + "GetSelectionEndAffinity", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper) { + const ui::AXTreeData& tree_data = tree_wrapper->tree()->data(); + ax::mojom::TextAffinity end_affinity = + tree_data.sel_is_backward ? tree_data.sel_anchor_affinity + : tree_data.sel_focus_affinity; + result.Set(CreateV8String(isolate, ui::ToString(end_affinity))); }); // Bindings that take a Tree ID and Node ID and return a property of the node.
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js index b3896fa..3e78ab9e 100644 --- a/chrome/renderer/resources/extensions/automation/automation_node.js +++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -78,6 +78,55 @@ var GetFocusAffinity = natives.GetFocusAffinity; /** + * The start of the selection always comes before its end in the accessibility + * tree. + * @param {string} axTreeID The id of the accessibility tree. + * @return {?number} The ID of the object at the start of the + * selection. + */ +var GetSelectionStartObjectID = natives.GetSelectionStartObjectID; + +/** + * The start of the selection always comes before its end in the accessibility + * tree. + * @param {string} axTreeID The id of the accessibility tree. + * @return {?number} The offset at the start of the selection. + */ +var GetSelectionStartOffset = natives.GetSelectionStartOffset; + +/** + * The start of the selection always comes before its end in the accessibility + * tree. + * @param {string} axTreeID The id of the accessibility tree. + * @return {?string} The affinity at the start of the selection. + */ +var GetSelectionStartAffinity = natives.GetSelectionStartAffinity; + +/** + * The end of the selection always comes after its start in the accessibility + * tree. + * @param {string} axTreeID The id of the accessibility tree. + * @return {?number} The ID of the object at the end of the selection. + */ +var GetSelectionEndObjectID = natives.GetSelectionEndObjectID; + +/** + * The end of the selection always comes after its start in the accessibility + * tree. + * @param {string} axTreeID The id of the accessibility tree. + * @return {?number} The offset at the end of the selection. + */ +var GetSelectionEndOffset = natives.GetSelectionEndOffset; + +/** + * The end of the selection always comes after its start in the accessibility + * tree. + * @param {string} axTreeID The id of the accessibility tree. + * @return {?string} The affinity at the end of the selection. + */ +var GetSelectionEndAffinity = natives.GetSelectionEndAffinity; + +/** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?number} The id of the node's parent, or undefined if it's the @@ -1374,43 +1423,87 @@ }, get anchorObject() { - var id = GetAnchorObjectID(this.treeID); + const id = GetAnchorObjectID(this.treeID); if (id && id != -1) return this.get(id); - else - return undefined; + return undefined; }, get anchorOffset() { - var id = GetAnchorObjectID(this.treeID); + const id = GetAnchorObjectID(this.treeID); if (id && id != -1) return GetAnchorOffset(this.treeID); + return undefined; }, get anchorAffinity() { - var id = GetAnchorObjectID(this.treeID); + const id = GetAnchorObjectID(this.treeID); if (id && id != -1) return GetAnchorAffinity(this.treeID); + return undefined; }, get focusObject() { - var id = GetFocusObjectID(this.treeID); + const id = GetFocusObjectID(this.treeID); if (id && id != -1) return this.get(id); - else - return undefined; + return undefined; }, get focusOffset() { - var id = GetFocusObjectID(this.treeID); + const id = GetFocusObjectID(this.treeID); if (id && id != -1) return GetFocusOffset(this.treeID); + return undefined; }, get focusAffinity() { - var id = GetFocusObjectID(this.treeID); + const id = GetFocusObjectID(this.treeID); if (id && id != -1) return GetFocusAffinity(this.treeID); + return undefined; + }, + + get selectionStartObject() { + const id = GetSelectionStartObjectID(this.treeID); + if (id && id != -1) + return this.get(id); + return undefined; + }, + + get selectionStartOffset() { + const id = GetSelectionStartObjectID(this.treeID); + if (id && id != -1) + return GetSelectionStartOffset(this.treeID); + return undefined; + }, + + get selectionStartAffinity() { + const id = GetSelectionStartObjectID(this.treeID); + if (id && id != -1) + return GetSelectionStartAffinity(this.treeID); + return undefined; + }, + + get selectionEndObject() { + const id = GetSelectionEndObjectID(this.treeID); + if (id && id != -1) + return this.get(id); + return undefined; + }, + + get selectionEndOffset() { + const id = GetSelectionEndObjectID(this.treeID); + if (id && id != -1) + return GetSelectionEndOffset(this.treeID); + return undefined; + }, + + get selectionEndAffinity() { + const id = GetSelectionEndObjectID(this.treeID); + if (id && id != -1) + return GetSelectionEndAffinity(this.treeID); + return undefined; }, get: function(id) { @@ -1614,6 +1707,12 @@ 'focusObject', 'focusOffset', 'focusAffinity', + 'selectionStartObject', + 'selectionStartOffset', + 'selectionStartAffinity', + 'selectionEndObject', + 'selectionEndOffset', + 'selectionEndAffinity', ], });
diff --git a/chrome/services/app_service/public/cpp/BUILD.gn b/chrome/services/app_service/public/cpp/BUILD.gn index 9431776a..93f59cd 100644 --- a/chrome/services/app_service/public/cpp/BUILD.gn +++ b/chrome/services/app_service/public/cpp/BUILD.gn
@@ -2,6 +2,18 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +source_set("app_service_proxy") { + sources = [ + "app_service_proxy.cc", + "app_service_proxy.h", + ] + + deps = [ + ":app_update", + ":icon_loader", + ] +} + source_set("app_update") { sources = [ "app_registry_cache.cc",
diff --git a/chrome/services/app_service/public/cpp/app_service_proxy.cc b/chrome/services/app_service/public/cpp/app_service_proxy.cc new file mode 100644 index 0000000..6d2fe0d --- /dev/null +++ b/chrome/services/app_service/public/cpp/app_service_proxy.cc
@@ -0,0 +1,52 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" + +#include <utility> + +namespace apps { + +AppServiceProxy::AppServiceProxy() = default; + +AppServiceProxy::~AppServiceProxy() = default; + +apps::mojom::AppServicePtr& AppServiceProxy::AppService() { + return app_service_; +} + +apps::AppRegistryCache& AppServiceProxy::AppRegistryCache() { + return cache_; +} + +apps::mojom::IconKeyPtr AppServiceProxy::GetIconKey(const std::string& app_id) { + return apps::mojom::IconKey::New(); +} + +std::unique_ptr<apps::IconLoader::Releaser> +AppServiceProxy::LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, + apps::mojom::IconCompression icon_compression, + int32_t size_hint_in_dip, + bool allow_placeholder_icon, + apps::mojom::Publisher::LoadIconCallback callback) { + std::move(callback).Run(apps::mojom::IconValue::New()); + return nullptr; +} + +void AppServiceProxy::Launch(const std::string& app_id, + int32_t event_flags, + apps::mojom::LaunchSource launch_source, + int64_t display_id) {} + +void AppServiceProxy::SetPermission(const std::string& app_id, + apps::mojom::PermissionPtr permission) {} + +void AppServiceProxy::Uninstall(const std::string& app_id) {} + +void AppServiceProxy::OpenNativeSettings(const std::string& app_id) {} + +} // namespace apps
diff --git a/chrome/services/app_service/public/cpp/app_service_proxy.h b/chrome/services/app_service/public/cpp/app_service_proxy.h new file mode 100644 index 0000000..38adb8b1 --- /dev/null +++ b/chrome/services/app_service/public/cpp/app_service_proxy.h
@@ -0,0 +1,62 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_APP_SERVICE_PROXY_H_ +#define CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_APP_SERVICE_PROXY_H_ + +#include <memory> + +#include "base/macros.h" +#include "chrome/services/app_service/public/cpp/app_registry_cache.h" +#include "chrome/services/app_service/public/cpp/icon_loader.h" +#include "chrome/services/app_service/public/mojom/app_service.mojom.h" + +namespace apps { + +// Abstract superclass (with default no-op methods) for the App Service proxy. +// See chrome/services/app_service/README.md. +// +// Most code, outside of tests, should use an AppServiceProxyImpl. +class AppServiceProxy : public apps::IconLoader { + public: + AppServiceProxy(); + ~AppServiceProxy() override; + + apps::mojom::AppServicePtr& AppService(); + apps::AppRegistryCache& AppRegistryCache(); + + // apps::IconLoader overrides. + apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override; + std::unique_ptr<IconLoader::Releaser> LoadIconFromIconKey( + apps::mojom::AppType app_type, + const std::string& app_id, + apps::mojom::IconKeyPtr icon_key, + apps::mojom::IconCompression icon_compression, + int32_t size_hint_in_dip, + bool allow_placeholder_icon, + apps::mojom::Publisher::LoadIconCallback callback) override; + + virtual void Launch(const std::string& app_id, + int32_t event_flags, + apps::mojom::LaunchSource launch_source, + int64_t display_id); + + virtual void SetPermission(const std::string& app_id, + apps::mojom::PermissionPtr permission); + + virtual void Uninstall(const std::string& app_id); + + virtual void OpenNativeSettings(const std::string& app_id); + + protected: + apps::mojom::AppServicePtr app_service_; + apps::AppRegistryCache cache_; + + private: + DISALLOW_COPY_AND_ASSIGN(AppServiceProxy); +}; + +} // namespace apps + +#endif // CHROME_SERVICES_APP_SERVICE_PUBLIC_CPP_APP_SERVICE_PROXY_H_
diff --git a/chrome/services/app_service/public/cpp/icon_cache.h b/chrome/services/app_service/public/cpp/icon_cache.h index 6ee992d..41d5b25 100644 --- a/chrome/services/app_service/public/cpp/icon_cache.h +++ b/chrome/services/app_service/public/cpp/icon_cache.h
@@ -67,7 +67,7 @@ }; IconCache(IconLoader* wrapped_loader, GarbageCollectionPolicy gc_policy); - ~IconCache(); + ~IconCache() override; // IconLoader overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override;
diff --git a/chrome/services/app_service/public/cpp/icon_loader.cc b/chrome/services/app_service/public/cpp/icon_loader.cc index 8ffef2b..f455c3b 100644 --- a/chrome/services/app_service/public/cpp/icon_loader.cc +++ b/chrome/services/app_service/public/cpp/icon_loader.cc
@@ -60,6 +60,10 @@ return this->app_id_ < that.app_id_; } +IconLoader::IconLoader() = default; + +IconLoader::~IconLoader() = default; + std::unique_ptr<IconLoader::Releaser> IconLoader::LoadIcon( apps::mojom::AppType app_type, const std::string& app_id,
diff --git a/chrome/services/app_service/public/cpp/icon_loader.h b/chrome/services/app_service/public/cpp/icon_loader.h index ca18e90..9223cd8 100644 --- a/chrome/services/app_service/public/cpp/icon_loader.h +++ b/chrome/services/app_service/public/cpp/icon_loader.h
@@ -45,6 +45,9 @@ DISALLOW_COPY_AND_ASSIGN(Releaser); }; + IconLoader(); + virtual ~IconLoader(); + // Looks up the IconKey for the given app ID. virtual apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) = 0;
diff --git a/chrome/services/app_service/public/cpp/stub_icon_loader.h b/chrome/services/app_service/public/cpp/stub_icon_loader.h index 81c282bd1..07cf37e 100644 --- a/chrome/services/app_service/public/cpp/stub_icon_loader.h +++ b/chrome/services/app_service/public/cpp/stub_icon_loader.h
@@ -17,7 +17,7 @@ class StubIconLoader : public IconLoader { public: StubIconLoader(); - ~StubIconLoader(); + ~StubIconLoader() override; // IconLoader overrides. apps::mojom::IconKeyPtr GetIconKey(const std::string& app_id) override;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 0ae4c287..6bf33111 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3551,7 +3551,7 @@ if (!is_android) { sources += [ - "../browser/apps/app_service/app_service_proxy_unittest.cc", + "../browser/apps/app_service/app_service_proxy_impl_unittest.cc", "../browser/apps/intent_helper/apps_navigation_throttle_unittest.cc", "../browser/apps/intent_helper/page_transition_util_unittest.cc", "../browser/devtools/devtools_file_system_indexer_unittest.cc", @@ -5225,6 +5225,7 @@ ] sources += [ "../browser/ui/ash/drag_to_overview_interactive_uitest.cc", + "../browser/ui/ash/launcher_animations_interactive_uitest.cc", "../browser/ui/ash/overview_animations_interactive_uitest.cc", "../browser/ui/ash/split_view_interactive_uitest.cc", ]
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_extra_headers.js b/chrome/test/data/extensions/api_test/webrequest/test_extra_headers.js index 1d012b63..e0936f2 100644 --- a/chrome/test/data/extensions/api_test/webrequest/test_extra_headers.js +++ b/chrome/test/data/extensions/api_test/webrequest/test_extra_headers.js
@@ -8,6 +8,56 @@ return getServerURL('set-cookie?' + name + '=' + value); } +function testModifyHeadersOnRedirect(useExtraHeaders) { + // Use /echoheader instead of observing headers in onSendHeaders to + // ensure we're looking at what the server receives. This avoids bugs in the + // webRequest implementation from being masked. + var finalURL = getServerURL('echoheader?User-Agent&Accept&X-New-Header'); + var url = getServerURL('server-redirect?' + finalURL); + var listener = callbackPass(function(details) { + var headers = details.requestHeaders; + + // Test modification. + var accept_value; + for (var i = 0; i < headers.length; i++) { + if (headers[i].name.toLowerCase() === 'user-agent') { + headers[i].value = 'foo'; + } else if (headers[i].name.toLowerCase() === 'accept') { + accept_value = headers[i].value; + } + } + + // Test removal. + chrome.test.assertTrue(accept_value.indexOf('image/webp') >= 0); + removeHeader(headers, 'accept'); + + // Test addition. + headers.push({name: 'X-New-Header', value: 'Baz'}); + + return {requestHeaders: headers}; + }); + + var extraInfo = ['requestHeaders', 'blocking']; + if (useExtraHeaders) + extraInfo.push('extraHeaders'); + chrome.webRequest.onBeforeSendHeaders.addListener(listener, + {urls: [finalURL]}, extraInfo); + + navigateAndWait(url, function(tab) { + chrome.webRequest.onBeforeSendHeaders.removeListener(listener); + chrome.tabs.executeScript(tab.id, { + code: 'document.body.innerText' + }, callbackPass(function(results) { + chrome.test.assertTrue(results[0].indexOf('foo') >= 0, + 'User-Agent should be modified.'); + chrome.test.assertTrue(results[0].indexOf('image/webp') == -1, + 'Accept should be removed.'); + chrome.test.assertTrue(results[0].indexOf('Baz') >= 0, + 'X-New-Header should be added.'); + })); + }); +} + runTests([ function testSpecialRequestHeadersVisible() { // Set a cookie so the cookie request header is set. @@ -200,6 +250,14 @@ }); }, + function testModifyHeadersOnRedirectWithoutExtraHeaders() { + testModifyHeadersOnRedirect(false); + }, + + function testModifyHeadersOnRedirectWithExtraHeaders() { + testModifyHeadersOnRedirect(true); + }, + // Successful Set-Cookie modification is tested in test_blocking_cookie.js. function testCannotModifySpecialResponseHeadersWithoutExtraHeaders() { // Use unique name and value so other tests don't interfere.
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 066600df..e21e0a8d 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -469,6 +469,7 @@ sources = [ "cast_content_gesture_handler_test.cc", "cast_media_blocker_browsertest.cc", + "cast_web_contents_browsertest.cc", "renderer_prelauncher_test.cc", "test/cast_features_browsertest.cc", "test/cast_navigation_browsertest.cc", @@ -478,15 +479,20 @@ deps = [ ":test_support", + "//base", "//chromecast:chromecast_buildflags", "//chromecast/base", "//chromecast/base:chromecast_switches", "//chromecast/base/metrics", "//components/prefs", + "//content/public/browser", + "//content/test:test_support", "//media:test_support", + "//net:test_support", ] data = [ + "//chromecast/browser/test/data/", "//media/test/data/", ] }
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h index d60a174..4c64868 100644 --- a/chromecast/browser/cast_web_contents.h +++ b/chromecast/browser/cast_web_contents.h
@@ -28,6 +28,70 @@ }; // Simplified WebContents wrapper class for Cast platforms. +// +// Proper usage of content::WebContents relies on understanding the meaning +// behind various WebContentsObserver methods, and then translating those +// signals into some concrete state. CastWebContents does *not* own the +// underlying WebContents (usually whatever class implements +// content::WebContentsDelegate is the actual owner). +// +// ============================================================================= +// Lifetime +// ============================================================================= +// CastWebContents *must* be created before WebContents begins loading any +// content. Once content begins loading (via CWC::LoadUrl() or one of the +// WebContents navigation APIs), CastWebContents will calculate its state based +// on the status of the WebContents' *main* RenderFrame. Events from sub-frames +// (e.g. iframes) are ignored, since we expect the web app to take care of +// sub-frame errors. +// +// We consider the CastWebContents to be in a LOADED state when the content of +// the main frame is fully loaded and running (all resources fetched, JS is +// running). Iframes might still be loading in this case, but in general we +// consider the page to be in a presentable state at this stage. It is +// appropriate to display the WebContents to the user. +// +// During or after the page is loaded, there are multiple error conditions that +// can occur. The following events will cause the page to enter an ERROR state: +// +// 1. If the main frame is served an HTTP error page (such as a 404 page), then +// it means the desired content wasn't loaded. +// +// 2. If the main frame fails to load, such as when the browser blocked the URL +// request, we treat this as an error. +// +// 3. The RenderProcess for the main frame could crash, so the page is not in a +// usable state. +// +// The CastWebContents user can respond to these errors in a few ways: The +// content can be reloaded, or the entire page activity can be cancelled. If we +// totally cancel the activity, we prefer to notify the user with an error +// screen or visible/audible error message. Otherwise, a silent retry is +// preferred. +// +// CastWebContents can be used to close the underlying WebContents gracefully +// via CWC::Close(). This initiates web page tear-down logic so that the web +// app has a chance to perform its own finalization logic in JS. Next, we call +// WebContents::ClosePage(), which defers the page closure logic to the +// content::WebContentsDelegate. Usually, it will run its own finalization +// logic and then destroy the WebContents. CastWebContents will be notified of +// the WebContents destruction and enter the DESTROYED state. In the event +// the page isn't destroyed, the page will enter the CLOSED state automatically +// after a timeout. CastWebContents users should not try to reload the page, as +// page closure is intentional. +// +// The web app may decide to close itself (such as via "window.close()" in JS). +// This is similar to initiating the close flow via CWC::Close(), with the end +// result being the same. We consider this an intentional closure, and should +// not attempt to reload the page. +// +// Once CastWebContents is in the DESTROYED state, it is not really usable +// anymore; most of the methods will simply no-op, and no more observer signals +// will be emitted. +// +// CastWebContents can be deleted at any time, *except* during Observer +// notifications. If the owner wants to destroy CastWebContents as a result of +// an Observer event, it should post a task to destroy CastWebContents. class CastWebContents { public: class Delegate { @@ -39,17 +103,19 @@ // Called when the page has stopped. e.g.: A 404 occurred when loading the // page or if the render process for the main frame crashes. |error_code| // will return a net::Error describing the failure, or net::OK if the page - // closed naturally. + // closed intentionally. // // After this method, the page state will be one of the following: - // CLOSED: Page was closed as expected and the WebContents exists. + // CLOSED: Page was closed as expected and the WebContents exists. The page + // should generally not be reloaded, since the page closure was + // triggered intentionally. + // ERROR: Page is in an error state. It should be reloaded or deleted. // DESTROYED: Page was closed due to deletion of WebContents. The // CastWebContents instance is no longer usable and should be deleted. - // ERROR: Page is in an error state. It should be reloaded or deleted. virtual void OnPageStopped(CastWebContents* cast_web_contents, int error_code) = 0; - // Notify that a inner WebContents was created. |inner_contents| is created + // Notify that an inner WebContents was created. |inner_contents| is created // in a default-initialized state with no delegate, and can be safely // initialized by the delegate. virtual void InnerContentsCreated(CastWebContents* inner_contents, @@ -66,6 +132,9 @@ virtual void RenderFrameCreated(int render_process_id, int render_frame_id) {} + // Notifies that a resource for the main frame failed to load. + virtual void ResourceLoadFailed(CastWebContents* cast_web_contents) {} + // Adds |this| to the ObserverList in the implementation of // |cast_web_contents|. void Observe(CastWebContents* cast_web_contents); @@ -83,10 +152,15 @@ CastWebContents* cast_web_contents_; }; + // Initialization parameters for CastWebContents. struct InitParams { Delegate* delegate; + // Whether the underlying WebContents is exposed to the remote debugger. bool enabled_for_dev; + // Chooses a media renderer for the WebContents. bool use_cma_renderer; + // Whether the WebContents is a root native window, or if it is embedded in + // another WebContents (see Delegate::InnerContentsCreated()). bool is_root_window = false; }; @@ -142,8 +216,8 @@ // Stop the page immediately. This will automatically invoke // Delegate::OnPageStopped(error_code), allowing the delegate to delete or - // reload the page without waiting for page teardown, which may be handled - // independently. + // reload the page without waiting for the WebContents owner to tear down the + // page. virtual void Stop(int error_code) = 0; // Used to add or remove |observer| to the ObserverList in the implementation.
diff --git a/chromecast/browser/cast_web_contents_browsertest.cc b/chromecast/browser/cast_web_contents_browsertest.cc new file mode 100644 index 0000000..7773646 --- /dev/null +++ b/chromecast/browser/cast_web_contents_browsertest.cc
@@ -0,0 +1,604 @@ +// Copyright 2019 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 CHROMECAST_BROWSER_CAST_WEB_CONTENTS_BROWSERTEST_H_ +#define CHROMECAST_BROWSER_CAST_WEB_CONTENTS_BROWSERTEST_H_ + +#include <algorithm> +#include <memory> + +#include "base/command_line.h" +#include "base/containers/flat_set.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "chromecast/base/chromecast_switches.h" +#include "chromecast/base/metrics/cast_metrics_helper.h" +#include "chromecast/browser/cast_browser_context.h" +#include "chromecast/browser/cast_browser_process.h" +#include "chromecast/browser/cast_web_contents_impl.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/url_loader_interceptor.h" +#include "net/http/http_status_code.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +using ::testing::_; +using ::testing::AllOf; +using ::testing::AtLeast; +using ::testing::Eq; +using ::testing::Expectation; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::Mock; +using ::testing::Property; + +namespace content { +class WebContents; +} + +namespace chromecast { + +namespace { + +const base::FilePath::CharType kTestDataPath[] = + FILE_PATH_LITERAL("chromecast/browser/test/data"); + +base::FilePath GetTestDataPath() { + return base::FilePath(kTestDataPath); +} + +base::FilePath GetTestDataFilePath(const std::string& name) { + base::FilePath file_path; + CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); + return file_path.Append(GetTestDataPath()).AppendASCII(name); +} + +std::unique_ptr<net::test_server::HttpResponse> DefaultHandler( + net::HttpStatusCode status_code, + const net::test_server::HttpRequest& request) { + auto http_response = std::make_unique<net::test_server::BasicHttpResponse>(); + http_response->set_code(status_code); + return http_response; +} + +// ============================================================================= +// Mocks +// ============================================================================= +class MockCastWebContentsDelegate : public CastWebContents::Delegate { + public: + MockCastWebContentsDelegate() {} + ~MockCastWebContentsDelegate() override = default; + + MOCK_METHOD1(OnPageStateChanged, void(CastWebContents* cast_web_contents)); + MOCK_METHOD2(OnPageStopped, + void(CastWebContents* cast_web_contents, int error_code)); + MOCK_METHOD2(InnerContentsCreated, + void(CastWebContents* inner_contents, + CastWebContents* outer_contents)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockCastWebContentsDelegate); +}; + +class MockCastWebContentsObserver : public CastWebContents::Observer { + public: + MockCastWebContentsObserver() {} + ~MockCastWebContentsObserver() override = default; + + MOCK_METHOD2(RenderFrameCreated, + void(int render_process_id, int render_frame_id)); + MOCK_METHOD1(ResourceLoadFailed, void(CastWebContents* cast_web_contents)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockCastWebContentsObserver); +}; + +class MockWebContentsDelegate : public content::WebContentsDelegate { + public: + MockWebContentsDelegate() = default; + ~MockWebContentsDelegate() override = default; + + MOCK_METHOD1(CloseContents, void(content::WebContents* source)); +}; + +} // namespace + +// ============================================================================= +// Test class +// ============================================================================= +class CastWebContentsBrowserTest : public content::BrowserTestBase, + public content::WebContentsObserver { + protected: + CastWebContentsBrowserTest() = default; + ~CastWebContentsBrowserTest() override = default; + + void SetUp() final { + SetUpCommandLine(base::CommandLine::ForCurrentProcess()); + BrowserTestBase::SetUp(); + } + void SetUpCommandLine(base::CommandLine* command_line) final { + command_line->AppendSwitch(switches::kNoWifi); + command_line->AppendSwitchASCII(switches::kTestType, "browser"); + } + void PreRunTestOnMainThread() override { + // Pump startup related events. + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + base::RunLoop().RunUntilIdle(); + + metrics::CastMetricsHelper::GetInstance()->SetDummySessionIdForTesting(); + content::WebContents::CreateParams create_params( + shell::CastBrowserProcess::GetInstance()->browser_context(), nullptr); + web_contents_ = content::WebContents::Create(create_params); + web_contents_->SetDelegate(&mock_wc_delegate_); + + CastWebContents::InitParams init_params = { + &mock_cast_wc_delegate_, false /* enabled_for_dev */, + false /* use_cma_renderer */, true /* is_root_window */}; + cast_web_contents_ = + std::make_unique<CastWebContentsImpl>(web_contents_.get(), init_params); + mock_cast_wc_observer_.Observe(cast_web_contents_.get()); + + render_frames_.clear(); + content::WebContentsObserver::Observe(web_contents_.get()); + } + void PostRunTestOnMainThread() override { + cast_web_contents_.reset(); + web_contents_.reset(); + } + + // content::WebContentsObserver implementation: + void RenderFrameCreated(content::RenderFrameHost* render_frame_host) final { + render_frames_.insert(render_frame_host); + } + + void StartTestServer() { + ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); + embedded_test_server()->StartAcceptingConnections(); + } + + MockWebContentsDelegate mock_wc_delegate_; + MockCastWebContentsDelegate mock_cast_wc_delegate_; + MockCastWebContentsObserver mock_cast_wc_observer_; + std::unique_ptr<content::WebContents> web_contents_; + std::unique_ptr<CastWebContentsImpl> cast_web_contents_; + + base::flat_set<content::RenderFrameHost*> render_frames_; + + private: + DISALLOW_COPY_AND_ASSIGN(CastWebContentsBrowserTest); +}; + +MATCHER_P2(CheckPageState, cwc_ptr, expected_state, "") { + if (arg != cwc_ptr) + return false; + return arg->page_state() == expected_state; +} + +// ============================================================================= +// Test cases +// ============================================================================= +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, Lifecycle) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: Load a blank page successfully, verify LOADED state. + // =========================================================================== + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); + run_loop->Run(); + + // =========================================================================== + // Test: Load a blank page via WebContents API, verify LOADED state. + // =========================================================================== + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + run_loop = std::make_unique<base::RunLoop>(); + web_contents_->GetController().LoadURL(GURL(url::kAboutBlankURL), + content::Referrer(), + ui::PAGE_TRANSITION_TYPED, ""); + run_loop->Run(); + + // =========================================================================== + // Test: Inject an iframe, verify no events are received for the frame. + // =========================================================================== + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + std::string script = + "var iframe = document.createElement('iframe');" + "document.body.appendChild(iframe);" + "iframe.src = 'about:blank';"; + ASSERT_TRUE(ExecJs(web_contents_.get(), script)); + + // =========================================================================== + // Test: Inject an iframe and navigate it to an error page. Verify no events. + // =========================================================================== + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + script = "iframe.src = 'https://www.fake-non-existent-cast-page.com';"; + ASSERT_TRUE(ExecJs(web_contents_.get(), script)); + + // =========================================================================== + // Test: Close the CastWebContents. WebContentsDelegate will be told to close + // the page, and then after the timeout elapses CWC will enter the CLOSED + // state and notify that the page has stopped. + // =========================================================================== + EXPECT_CALL(mock_wc_delegate_, CloseContents(web_contents_.get())) + .Times(AtLeast(1)); + EXPECT_CALL(mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::CLOSED), + net::OK)) + .WillOnce(InvokeWithoutArgs(quit_closure)); + run_loop = std::make_unique<base::RunLoop>(); + cast_web_contents_->ClosePage(); + run_loop->Run(); + + // =========================================================================== + // Test: Destroy the underlying WebContents. Verify DESTROYED state. + // =========================================================================== + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::DESTROYED))); + web_contents_.reset(); + cast_web_contents_.reset(); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, WebContentsDestroyed) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); + run_loop->Run(); + + // =========================================================================== + // Test: Destroy the WebContents. Verify OnPageStopped(DESTROYED, net::OK). + // =========================================================================== + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::DESTROYED), + net::OK)); + web_contents_.reset(); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, ErrorPageCrash) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: If the page's main render process crashes, enter ERROR state. + // =========================================================================== + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); + run_loop->Run(); + + EXPECT_CALL(mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::ERROR), + net::ERR_UNEXPECTED)); + CrashTab(web_contents_.get()); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, ErrorLocalFileMissing) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: Loading a page with an HTTP error should enter ERROR state. + // =========================================================================== + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL(mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::ERROR), + _)) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + base::FilePath path = GetTestDataFilePath("this_file_does_not_exist.html"); + cast_web_contents_->LoadUrl(content::GetFileUrlWithQuery(path, "")); + run_loop->Run(); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, ErrorLoadFailSubFrames) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: Ignore load errors in sub-frames. + // =========================================================================== + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); + run_loop->Run(); + + // Create a sub-frame. + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + std::string script = + "var iframe = document.createElement('iframe');" + "document.body.appendChild(iframe);" + "iframe.src = 'about:blank';"; + ASSERT_TRUE(ExecJs(web_contents_.get(), script)); + + ASSERT_EQ(2, (int)render_frames_.size()); + auto it = + std::find_if(render_frames_.begin(), render_frames_.end(), + [this](content::RenderFrameHost* frame) { + return frame->GetParent() == web_contents_->GetMainFrame(); + }); + ASSERT_NE(render_frames_.end(), it); + content::RenderFrameHost* sub_frame = *it; + ASSERT_NE(nullptr, sub_frame); + cast_web_contents_->DidFailLoad(sub_frame, sub_frame->GetLastCommittedURL(), + net::ERR_FAILED, base::string16()); + + // =========================================================================== + // Test: Ignore main frame load failures with net::ERR_ABORTED. + // =========================================================================== + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStateChanged(_)).Times(0); + EXPECT_CALL(mock_cast_wc_delegate_, OnPageStopped(_, _)).Times(0); + cast_web_contents_->DidFailLoad( + web_contents_->GetMainFrame(), + web_contents_->GetMainFrame()->GetLastCommittedURL(), net::ERR_ABORTED, + base::string16()); + + // =========================================================================== + // Test: If main frame fails to load, page should enter ERROR state. + // =========================================================================== + EXPECT_CALL(mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::ERROR), + net::ERR_FAILED)); + cast_web_contents_->DidFailLoad( + web_contents_->GetMainFrame(), + web_contents_->GetMainFrame()->GetLastCommittedURL(), net::ERR_FAILED, + base::string16()); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, ErrorHttp4XX) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: If a server responds with an HTTP 4XX error, page should enter ERROR + // state. + // =========================================================================== + embedded_test_server()->RegisterRequestHandler( + base::BindRepeating(&DefaultHandler, net::HTTP_NOT_FOUND)); + StartTestServer(); + + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL(mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::ERROR), + net::ERR_FAILED)) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl(embedded_test_server()->GetURL("/dummy.html")); + run_loop->Run(); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, ErrorLoadFailed) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: When main frame load fails, enter ERROR state. This test simulates a + // load error by intercepting the URL request and failing it with an arbitrary + // error code. + // =========================================================================== + base::FilePath path = GetTestDataFilePath("dummy.html"); + GURL gurl = content::GetFileUrlWithQuery(path, ""); + content::URLLoaderInterceptor url_interceptor(base::BindRepeating( + [](const GURL& url, + content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url != url) + return false; + network::URLLoaderCompletionStatus status; + status.error_code = net::ERR_ADDRESS_UNREACHABLE; + params->client->OnComplete(status); + return true; + }, + gurl)); + + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL(mock_cast_wc_delegate_, + OnPageStopped(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::ERROR), + net::ERR_ADDRESS_UNREACHABLE)) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl(gurl); + run_loop->Run(); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, LoadCanceledByApp) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: When the app calls window.stop(), the page should not enter the ERROR + // state. Instead, we treat it as LOADED. This is a historical behavior for + // some apps which intentionally stop the page and reload content. + // =========================================================================== + embedded_test_server()->ServeFilesFromSourceDirectory(GetTestDataPath()); + StartTestServer(); + + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + + cast_web_contents_->LoadUrl( + embedded_test_server()->GetURL("/load_cancel.html")); + run_loop->Run(); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, NotifyMissingResource) { + auto run_loop = std::make_unique<base::RunLoop>(); + auto quit_closure = [&run_loop]() { + if (run_loop->running()) { + run_loop->QuitWhenIdle(); + } + }; + + // =========================================================================== + // Test: Loading a page with a missing resource should notify observers. + // =========================================================================== + { + InSequence seq; + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState( + cast_web_contents_.get(), CastWebContents::PageState::LOADING))); + EXPECT_CALL( + mock_cast_wc_delegate_, + OnPageStateChanged(CheckPageState(cast_web_contents_.get(), + CastWebContents::PageState::LOADED))) + .WillOnce(InvokeWithoutArgs(quit_closure)); + } + EXPECT_CALL(mock_cast_wc_observer_, + ResourceLoadFailed(cast_web_contents_.get())); + + base::FilePath path = GetTestDataFilePath("missing_resource.html"); + cast_web_contents_->LoadUrl(content::GetFileUrlWithQuery(path, "")); + run_loop->Run(); +} + +} // namespace chromecast + +#endif // CHROMECAST_BROWSER_CAST_WEB_CONTENTS_BROWSERTEST_H_
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc index b961102..41ee8b4f 100644 --- a/chromecast/browser/cast_web_contents_impl.cc +++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -20,6 +20,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/bindings_policy.h" +#include "content/public/common/resource_load_info.mojom.h" #include "net/base/net_errors.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -61,6 +62,7 @@ remote_debugging_server_( shell::CastBrowserProcess::GetInstance()->remote_debugging_server()), tab_id_(init_params.is_root_window ? 0 : next_tab_id++), + main_frame_loaded_(false), closing_(false), stopped_(false), stop_notified_(false), @@ -127,13 +129,8 @@ LOG(ERROR) << "Cannot load URL for WebContents while closing"; return; } - closing_ = false; - stopped_ = false; - stop_notified_ = false; - last_error_ = net::OK; - start_loading_ticks_ = base::TimeTicks::Now(); + OnPageLoading(); LOG(INFO) << "Load url: " << url.possibly_invalid_spec(); - TracePageLoadBegin(url); web_contents_->GetController().LoadURL(url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, ""); UpdatePageState(); @@ -299,6 +296,29 @@ Stop(net::ERR_UNEXPECTED); } +void CastWebContentsImpl::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(navigation_handle); + if (!web_contents_ || closing_ || stopped_) + return; + if (!navigation_handle->IsInMainFrame()) + return; + // Main frame has begun navigating/loading. + OnPageLoading(); + start_loading_ticks_ = base::TimeTicks::Now(); + GURL loading_url; + content::NavigationEntry* nav_entry = + web_contents()->GetController().GetVisibleEntry(); + if (nav_entry) { + loading_url = nav_entry->GetVirtualURL(); + } + TracePageLoadBegin(loading_url); + UpdatePageState(); + DCHECK_EQ(page_state_, PageState::LOADING); + NotifyObservers(); +} + void CastWebContentsImpl::DidFinishNavigation( content::NavigationHandle* navigation_handle) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -311,6 +331,10 @@ return; } + // Return early if we didn't navigate to an error page. Note that even if we + // haven't navigated to an error page, there could still be errors in loading + // the desired content: e.g. if the server returned HTTP 404, or if there is + // an error with the content itself. if (!navigation_handle->IsErrorPage()) return; @@ -328,48 +352,91 @@ LOG(ERROR) << "Got error on navigation: url=" << navigation_handle->GetURL() << ", error_code=" << error_code - << ", description= " << net::ErrorToShortString(error_code); + << ", description=" << net::ErrorToShortString(error_code); Stop(error_code); DCHECK_EQ(page_state_, PageState::ERROR); } -void CastWebContentsImpl::DidStartLoading() { +void CastWebContentsImpl::DidFinishLoad( + content::RenderFrameHost* render_frame_host, + const GURL& validated_url) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - UpdatePageState(); - DCHECK_EQ(page_state_, PageState::LOADING); - NotifyObservers(); -} - -void CastWebContentsImpl::DidStopLoading() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (page_state_ != PageState::LOADING || !web_contents_ || + render_frame_host != web_contents_->GetMainFrame()) { + return; + } + // The main frame finished loading. Before proceeding, we need to verify that + // the loaded page is the one that was requested. + TracePageLoadEnd(validated_url); int http_status_code = 0; - GURL final_url; content::NavigationEntry* nav_entry = web_contents()->GetController().GetVisibleEntry(); if (nav_entry) { http_status_code = nav_entry->GetHttpStatusCode(); - final_url = nav_entry->GetVirtualURL(); } - TracePageLoadEnd(final_url); if (http_status_code != 0 && http_status_code / 100 != 2) { - // We successfully loaded an error HTML page. - LOG(INFO) << "Failed loading page for: " << final_url - << "; http status code: " << http_status_code; + // An error HTML page was loaded instead of the content we requested. + LOG(ERROR) << "Failed loading page for: " << validated_url + << "; http status code: " << http_status_code; Stop(net::ERR_FAILED); DCHECK_EQ(page_state_, PageState::ERROR); return; } - // Main frame finished loading. + // Main frame finished loading properly. base::TimeDelta load_time = base::TimeTicks::Now() - start_loading_ticks_; LOG(INFO) << "Finished loading page after " << load_time.InMilliseconds() - << " ms, url=" << final_url; - PageState previous = page_state_; + << " ms, url=" << validated_url; + OnPageLoaded(); +} + +void CastWebContentsImpl::DidFailLoad( + content::RenderFrameHost* render_frame_host, + const GURL& validated_url, + int error_code, + const base::string16& error_description) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Only report an error if we are the main frame. See b/8433611. + if (render_frame_host->GetParent()) { + LOG(ERROR) << "Got error on sub-iframe: url=" << validated_url.spec() + << ", error=" << error_code; + return; + } + if (error_code == net::ERR_ABORTED) { + // ERR_ABORTED means download was aborted by the app, typically this happens + // when flinging URL for direct playback, the initial URLRequest gets + // cancelled/aborted and then the same URL is requested via the buffered + // data source for media::Pipeline playback. + LOG(INFO) << "Load canceled: url=" << validated_url.spec(); + + // We consider the page to be fully loaded in this case, since the app has + // intentionally entered this state. If the app wanted to stop, it would + // have called window.close() instead. + OnPageLoaded(); + return; + } + + LOG(ERROR) << "Got error on load: url=" << validated_url.spec() + << ", error_code=" << error_code; + + TracePageLoadEnd(validated_url); + Stop(error_code); + DCHECK_EQ(PageState::ERROR, page_state_); +} + +void CastWebContentsImpl::OnPageLoading() { + closing_ = false; + stopped_ = false; + stop_notified_ = false; + main_frame_loaded_ = false; + last_error_ = net::OK; +} + +void CastWebContentsImpl::OnPageLoaded() { + main_frame_loaded_ = true; UpdatePageState(); - DCHECK((previous == PageState::ERROR && page_state_ == PageState::ERROR) || - page_state_ == PageState::LOADED) - << "Page is in unexpected state: " << page_state_; + DCHECK(page_state_ == PageState::LOADED); NotifyObservers(); } @@ -380,10 +447,10 @@ DCHECK(stopped_); page_state_ = PageState::DESTROYED; } else if (!stopped_) { - if (web_contents_->IsLoading()) { - page_state_ = PageState::LOADING; - } else { + if (main_frame_loaded_) { page_state_ = PageState::LOADED; + } else { + page_state_ = PageState::LOADING; } } else if (stopped_) { if (last_error_ != net::OK) { @@ -413,33 +480,21 @@ notifying_ = false; } -void CastWebContentsImpl::DidFailLoad( +void CastWebContentsImpl::ResourceLoadComplete( content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Only report an error if we are the main frame. See b/8433611. - if (render_frame_host->GetParent()) { - LOG(ERROR) << "Got error on sub-iframe: url=" << validated_url.spec() - << ", error=" << error_code; + const content::GlobalRequestID& request_id, + const content::mojom::ResourceLoadInfo& resource_load_info) { + if (!web_contents_ || render_frame_host != web_contents_->GetMainFrame()) return; - } - if (error_code == net::ERR_ABORTED) { - // ERR_ABORTED means download was aborted by the app, typically this happens - // when flinging URL for direct playback, the initial URLRequest gets - // cancelled/aborted and then the same URL is requested via the buffered - // data source for media::Pipeline playback. - LOG(INFO) << "Load canceled: url=" << validated_url.spec(); + int net_error = resource_load_info.net_error; + if (net_error == net::OK) return; + LOG(ERROR) << "Resource \"" << resource_load_info.url << "\" failed to load " + << " with net_error=" << net_error + << ", description=" << net::ErrorToShortString(net_error); + for (auto& observer : observer_list_) { + observer.ResourceLoadFailed(this); } - - LOG(ERROR) << "Got error on load: url=" << validated_url.spec() - << ", error_code=" << error_code; - - TracePageLoadEnd(validated_url); - Stop(error_code); - DCHECK_EQ(PageState::ERROR, page_state_); } void CastWebContentsImpl::InnerWebContentsCreated(
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h index e4cd03f..07f8008 100644 --- a/chromecast/browser/cast_web_contents_impl.h +++ b/chromecast/browser/cast_web_contents_impl.h
@@ -57,26 +57,34 @@ void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; - private: - // WebContentsObserver implementation: + // content::WebContentsObserver implementation: void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void OnInterfaceRequestFromFrame( content::RenderFrameHost* /* render_frame_host */, const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) override; void RenderProcessGone(base::TerminationStatus status) override; + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; - void DidStartLoading() override; - void DidStopLoading() override; + void DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) override; void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description) override; + void ResourceLoadComplete( + content::RenderFrameHost* render_frame_host, + const content::GlobalRequestID& request_id, + const content::mojom::ResourceLoadInfo& resource_load_info) override; void InnerWebContentsCreated( content::WebContents* inner_web_contents) override; void WebContentsDestroyed() override; + private: + void OnPageLoading(); + void OnPageLoaded(); void UpdatePageState(); void NotifyObservers(); void TracePageLoadBegin(const GURL& url); @@ -98,6 +106,7 @@ const int tab_id_; base::TimeTicks start_loading_ticks_; + bool main_frame_loaded_; bool closing_; bool stopped_; bool stop_notified_;
diff --git a/chromecast/browser/test/data/load_cancel.html b/chromecast/browser/test/data/load_cancel.html new file mode 100644 index 0000000..d39e807 --- /dev/null +++ b/chromecast/browser/test/data/load_cancel.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<head> +</head> +<body> + <script type="text/javascript"> + window.stop(); + </script> +</body>
diff --git a/chromecast/browser/test/data/missing_resource.html b/chromecast/browser/test/data/missing_resource.html new file mode 100644 index 0000000..36da320 --- /dev/null +++ b/chromecast/browser/test/data/missing_resource.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<head> +</head> +<body> + <script type="text/javascript" src="this_file_does_not_exist.js"></script> +</body>
diff --git a/chromecast/renderer/cast_content_renderer_client_simple.cc b/chromecast/renderer/cast_content_renderer_client_simple.cc index 5932e01..315c5171 100644 --- a/chromecast/renderer/cast_content_renderer_client_simple.cc +++ b/chromecast/renderer/cast_content_renderer_client_simple.cc
@@ -7,7 +7,6 @@ #include <memory> #include "base/memory/ptr_util.h" -#include "ipc/message_filter.h" namespace chromecast { namespace shell {
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc index fc93f8e3..86b94e9 100644 --- a/chromeos/constants/chromeos_switches.cc +++ b/chromeos/constants/chromeos_switches.cc
@@ -542,6 +542,11 @@ // of network packets from whitelisted sources. const char kWakeOnWifiPacket[] = "wake-on-wifi-packet"; +// Prevents any CPU restrictions being set on the ARC container. Only meant to +// be used by tests as some tests may time out if the ARC container is +// throttled. +const char kDisableArcCpuRestriction[] = "disable-arc-cpu-restriction"; + bool WakeOnWifiEnabled() { return !base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableWakeOnWifi); } @@ -650,5 +655,10 @@ kDisableGaiaServices); } +bool IsArcCpuRestrictionDisabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + kDisableArcCpuRestriction); +} + } // namespace switches } // namespace chromeos
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h index 45e7b2af..aed69b8 100644 --- a/chromeos/constants/chromeos_switches.h +++ b/chromeos/constants/chromeos_switches.h
@@ -185,6 +185,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kOobeSkipPostLogin[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kOobeSkipToLogin[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kOobeTimerInterval[]; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const char kDisableArcCpuRestriction[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kProfileRequiresPolicy[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kRedirectLibassistantLogging[]; @@ -290,6 +292,9 @@ // Returns true if GAIA services has been disabled. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsGaiaServicesDisabled(); +// Returns true if |kDisableArcCpuRestriction| is true. +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsArcCpuRestrictionDisabled(); + } // namespace switches } // namespace chromeos
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index ae0a271..f08d9b4 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -171,6 +171,7 @@ "//base", "//chromeos/constants", "//chromeos/dbus/session_manager", + "//components/exo", "//ui/aura", ] }
diff --git a/components/arc/arc_util.cc b/components/arc/arc_util.cc index 62f9833..d6e0d2b 100644 --- a/components/arc/arc_util.cc +++ b/components/arc/arc_util.cc
@@ -5,7 +5,7 @@ #include "components/arc/arc_util.h" #include <algorithm> -#include <string> +#include <cstdio> #include "ash/public/cpp/app_types.h" #include "base/bind.h" @@ -14,6 +14,7 @@ #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/session_manager/session_manager_client.h" #include "components/arc/arc_features.h" +#include "components/exo/shell_surface_util.h" #include "components/user_manager/user_manager.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" @@ -177,11 +178,29 @@ static_cast<int>(ash::AppType::ARC_APP); } +int GetWindowTaskId(const aura::Window* window) { + const std::string* arc_app_id = exo::GetShellApplicationId(window); + if (!arc_app_id) + return kNoTaskId; + return GetTaskIdFromWindowAppId(*arc_app_id); +} + +int GetTaskIdFromWindowAppId(const std::string& app_id) { + int task_id; + if (std::sscanf(app_id.c_str(), "org.chromium.arc.%d", &task_id) != 1) + return kNoTaskId; + return task_id; +} + void SetArcCpuRestriction(bool do_restrict) { if (!chromeos::SessionManagerClient::Get()) { LOG(WARNING) << "SessionManagerClient is not available"; return; } + + if (chromeos::switches::IsArcCpuRestrictionDisabled()) + return; + const login_manager::ContainerCpuRestrictionState state = do_restrict ? login_manager::CONTAINER_CPU_RESTRICTION_BACKGROUND : login_manager::CONTAINER_CPU_RESTRICTION_FOREGROUND;
diff --git a/components/arc/arc_util.h b/components/arc/arc_util.h index 0cb529de..bea5bf3 100644 --- a/components/arc/arc_util.h +++ b/components/arc/arc_util.h
@@ -10,6 +10,7 @@ // users' preferences, and FeatureList. #include <stdint.h> +#include <string> namespace aura { class Window; @@ -105,6 +106,13 @@ // |window| is nullptr, returns false. bool IsArcAppWindow(const aura::Window* window); +constexpr int kNoTaskId = -1; +constexpr int kSystemWindowTaskId = 0; +// Returns the task id given by the exo shell's application id, or |kNoTaskId| +// if not an ARC window. +int GetWindowTaskId(const aura::Window* window); +int GetTaskIdFromWindowAppId(const std::string& app_id); + // Returns true if ARC app icons are forced to cache. bool IsArcForceCacheAppIcon();
diff --git a/components/arc/ime/arc_ime_service.cc b/components/arc/ime/arc_ime_service.cc index 54ba67f..a06cc25 100644 --- a/components/arc/ime/arc_ime_service.cc +++ b/components/arc/ime/arc_ime_service.cc
@@ -13,7 +13,6 @@ #include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_util.h" #include "components/arc/ime/arc_ime_bridge_impl.h" -#include "components/exo/shell_surface_util.h" #include "components/exo/wm_helper.h" #include "ui/aura/env.h" #include "ui/aura/window.h" @@ -33,9 +32,6 @@ namespace { -// TODO(yhanada): Remove this once IsArcAppWindow is fixed for ARC++ Kiosk app. -constexpr char kArcAppIdPrefix[] = "org.chromium.arc"; - base::Optional<double> g_override_default_device_scale_factor; double GetDefaultDeviceScaleFactor() { @@ -66,13 +62,9 @@ // TODO(yhanada): Make IsArcAppWindow support a window of ARC++ Kiosk. // Specifically, a window of ARC++ Kiosk should have ash::AppType::ARC_APP // property. Please see implementation of IsArcAppWindow(). - if (window == active) { - const std::string* app_id = exo::GetShellApplicationId(window); - if (IsArcKioskMode() && app_id && - base::StartsWith(*app_id, kArcAppIdPrefix, - base::CompareCase::SENSITIVE)) { - return true; - } + if (window == active && IsArcKioskMode() && + GetWindowTaskId(window) != kNoTaskId) { + return true; } } return false;
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn index a403d87..e0b03cf 100644 --- a/components/download/internal/common/BUILD.gn +++ b/components/download/internal/common/BUILD.gn
@@ -18,6 +18,7 @@ ] sources = [ + "all_download_event_notifier.cc", "base_file.cc", "base_file_win.cc", "download_create_info.cc",
diff --git a/components/download/internal/common/all_download_event_notifier.cc b/components/download/internal/common/all_download_event_notifier.cc new file mode 100644 index 0000000..e28d8b0 --- /dev/null +++ b/components/download/internal/common/all_download_event_notifier.cc
@@ -0,0 +1,88 @@ +// Copyright 2019 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/download/public/common/all_download_event_notifier.h" + +namespace download { + +AllDownloadEventNotifier::AllDownloadEventNotifier( + SimpleDownloadManagerCoordinator* simple_download_manager_coordinator) + : simple_download_manager_coordinator_(simple_download_manager_coordinator), + download_initialized_(false) { + simple_download_manager_coordinator_->AddObserver(this); + std::vector<DownloadItem*> downloads; + simple_download_manager_coordinator_->GetAllDownloads(&downloads); + for (auto* download : downloads) { + download->AddObserver(this); + observing_.insert(download); + } +} + +AllDownloadEventNotifier::~AllDownloadEventNotifier() { + if (simple_download_manager_coordinator_) + simple_download_manager_coordinator_->RemoveObserver(this); + for (auto it = observing_.begin(); it != observing_.end(); ++it) { + (*it)->RemoveObserver(this); + } + observing_.clear(); +} + +void AllDownloadEventNotifier::AddObserver(Observer* observer) { + observers_.AddObserver(observer); + if (download_initialized_) { + observer->OnDownloadsInitialized( + simple_download_manager_coordinator_, + !simple_download_manager_coordinator_->has_all_history_downloads()); + } +} + +void AllDownloadEventNotifier::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void AllDownloadEventNotifier::OnDownloadsInitialized( + bool active_downloads_only) { + download_initialized_ = true; + for (auto& observer : observers_) + observer.OnDownloadsInitialized(simple_download_manager_coordinator_, + active_downloads_only); +} + +void AllDownloadEventNotifier::OnManagerGoingDown() { + for (auto& observer : observers_) + observer.OnManagerGoingDown(simple_download_manager_coordinator_); + simple_download_manager_coordinator_->RemoveObserver(this); + simple_download_manager_coordinator_ = nullptr; +} + +void AllDownloadEventNotifier::OnDownloadCreated(DownloadItem* item) { + if (observing_.find(item) != observing_.end()) + return; + item->AddObserver(this); + observing_.insert(item); + for (auto& observer : observers_) + observer.OnDownloadCreated(simple_download_manager_coordinator_, item); +} + +void AllDownloadEventNotifier::OnDownloadUpdated(DownloadItem* item) { + for (auto& observer : observers_) + observer.OnDownloadUpdated(simple_download_manager_coordinator_, item); +} + +void AllDownloadEventNotifier::OnDownloadOpened(DownloadItem* item) { + for (auto& observer : observers_) + observer.OnDownloadOpened(simple_download_manager_coordinator_, item); +} + +void AllDownloadEventNotifier::OnDownloadRemoved(DownloadItem* item) { + for (auto& observer : observers_) + observer.OnDownloadRemoved(simple_download_manager_coordinator_, item); +} + +void AllDownloadEventNotifier::OnDownloadDestroyed(DownloadItem* item) { + item->RemoveObserver(this); + observing_.erase(item); +} + +} // namespace download
diff --git a/components/download/internal/common/simple_download_manager_coordinator.cc b/components/download/internal/common/simple_download_manager_coordinator.cc index e0c3038..ca14a7f4 100644 --- a/components/download/internal/common/simple_download_manager_coordinator.cc +++ b/components/download/internal/common/simple_download_manager_coordinator.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "components/download/public/common/all_download_event_notifier.h" #include "components/download/public/common/download_item.h" #include "components/download/public/common/simple_download_manager.h" @@ -82,4 +83,10 @@ observer.OnDownloadCreated(item); } +AllDownloadEventNotifier* SimpleDownloadManagerCoordinator::GetNotifier() { + if (!notifier_) + notifier_ = std::make_unique<AllDownloadEventNotifier>(this); + return notifier_.get(); +} + } // namespace download
diff --git a/components/download/public/common/BUILD.gn b/components/download/public/common/BUILD.gn index 30d3d52..71b81807 100644 --- a/components/download/public/common/BUILD.gn +++ b/components/download/public/common/BUILD.gn
@@ -15,6 +15,7 @@ component("public") { sources = [ + "all_download_event_notifier.h", "auto_resumption_handler.cc", "auto_resumption_handler.h", "base_file.h",
diff --git a/components/download/public/common/all_download_event_notifier.h b/components/download/public/common/all_download_event_notifier.h new file mode 100644 index 0000000..90275c1 --- /dev/null +++ b/components/download/public/common/all_download_event_notifier.h
@@ -0,0 +1,80 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_ALL_DOWNLOAD_EVENT_NOTIFIER_H_ +#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_ALL_DOWNLOAD_EVENT_NOTIFIER_H_ + +#include <set> + +#include "base/macros.h" +#include "base/observer_list.h" +#include "components/download/public/common/download_item.h" +#include "components/download/public/common/simple_download_manager_coordinator.h" + +namespace download { + +// Observes all the download events from a single +// SimpleDownloadManagerCoordinator. +class AllDownloadEventNotifier + : public SimpleDownloadManagerCoordinator::Observer, + public DownloadItem::Observer { + public: + // All of the methods take the SimpleDownloadManagerCoordinator so that + // subclasses can observe multiple managers at once and easily distinguish + // which manager a given item belongs to. + class Observer { + public: + Observer() = default; + virtual ~Observer() = default; + + virtual void OnDownloadsInitialized( + SimpleDownloadManagerCoordinator* coordinator, + bool active_downloads_only) {} + virtual void OnManagerGoingDown( + SimpleDownloadManagerCoordinator* coordinator) {} + virtual void OnDownloadCreated(SimpleDownloadManagerCoordinator* manager, + DownloadItem* item) {} + virtual void OnDownloadUpdated(SimpleDownloadManagerCoordinator* manager, + DownloadItem* item) {} + virtual void OnDownloadOpened(SimpleDownloadManagerCoordinator* manager, + DownloadItem* item) {} + virtual void OnDownloadRemoved(SimpleDownloadManagerCoordinator* manager, + DownloadItem* item) {} + + private: + DISALLOW_COPY_AND_ASSIGN(Observer); + }; + + explicit AllDownloadEventNotifier(SimpleDownloadManagerCoordinator* manager); + ~AllDownloadEventNotifier() override; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + private: + // SimpleDownloadManagerCoordinator::Observer + void OnDownloadsInitialized(bool active_downloads_only) override; + void OnManagerGoingDown() override; + void OnDownloadCreated(DownloadItem* item) override; + + // DownloadItem::Observer + void OnDownloadUpdated(DownloadItem* item) override; + void OnDownloadOpened(DownloadItem* item) override; + void OnDownloadRemoved(DownloadItem* item) override; + void OnDownloadDestroyed(DownloadItem* item) override; + + SimpleDownloadManagerCoordinator* simple_download_manager_coordinator_; + std::set<DownloadItem*> observing_; + + bool download_initialized_; + + // Observers that want to be notified of download events. + base::ObserverList<Observer>::Unchecked observers_; + + DISALLOW_COPY_AND_ASSIGN(AllDownloadEventNotifier); +}; + +} // namespace download + +#endif // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_ALL_DOWNLOAD_EVENT_NOTIFIER_H_
diff --git a/components/download/public/common/simple_download_manager_coordinator.h b/components/download/public/common/simple_download_manager_coordinator.h index f8cdf75..03ebf4e6 100644 --- a/components/download/public/common/simple_download_manager_coordinator.h +++ b/components/download/public/common/simple_download_manager_coordinator.h
@@ -18,6 +18,7 @@ namespace download { +class AllDownloadEventNotifier; class DownloadItem; // This object allows swapping between different SimppleDownloadManager @@ -65,6 +66,9 @@ // Return whether this object has download manager set. bool HasSetDownloadManager(); + // Returns a non-empty notifier to be used for observing download events. + AllDownloadEventNotifier* GetNotifier(); + bool has_all_history_downloads() const { return has_all_history_downloads_; } private: @@ -77,6 +81,9 @@ SimpleDownloadManager* simple_download_manager_; + // Object for notifying others about various download events. + std::unique_ptr<AllDownloadEventNotifier> notifier_; + // Whether all the history downloads are ready. bool has_all_history_downloads_;
diff --git a/components/exo/display.cc b/components/exo/display.cc index c2f533d..8337349 100644 --- a/components/exo/display.cc +++ b/components/exo/display.cc
@@ -35,6 +35,7 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/shell_window_ids.h" +#include "ash/wm/desks/desks_util.h" #include "components/exo/client_controlled_shell_surface.h" #include "components/exo/input_method_surface.h" #include "components/exo/shell_surface.h" @@ -135,7 +136,7 @@ return std::make_unique<ShellSurface>( surface, gfx::Point(), true /* activatable */, false /* can_minimize */, - ash::kShellWindowId_DefaultContainer); + ash::desks_util::GetActiveDeskContainerId()); } std::unique_ptr<XdgShellSurface> Display::CreateXdgShellSurface( @@ -149,7 +150,7 @@ return std::make_unique<XdgShellSurface>( surface, gfx::Point(), true /* activatable */, false /* can_minimize */, - ash::kShellWindowId_DefaultContainer); + ash::desks_util::GetActiveDeskContainerId()); } std::unique_ptr<ClientControlledShellSurface>
diff --git a/components/exo/display_unittest.cc b/components/exo/display_unittest.cc index 922ee66..3ce4dcd8 100644 --- a/components/exo/display_unittest.cc +++ b/components/exo/display_unittest.cc
@@ -4,6 +4,7 @@ #include "components/exo/display.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ash/wm/desks/desks_util.h" #include "components/exo/buffer.h" #include "components/exo/client_controlled_shell_surface.h" #include "components/exo/data_device.h" @@ -128,7 +129,7 @@ // Create a remote shell surface for surface2. std::unique_ptr<ShellSurfaceBase> shell_surface2 = display->CreateClientControlledShellSurface( - surface2.get(), ash::kShellWindowId_DefaultContainer, + surface2.get(), ash::desks_util::GetActiveDeskContainerId(), 1.0 /* default_scale_factor */); EXPECT_TRUE(shell_surface2); }
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc index 2b7a8bb..15d63a3e 100644 --- a/components/exo/pointer_unittest.cc +++ b/components/exo/pointer_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_positioning_utils.h" #include "base/bind.h" #include "base/run_loop.h" @@ -481,7 +482,7 @@ std::unique_ptr<Surface> child_surface(new Surface); std::unique_ptr<ShellSurface> child_shell_surface( new ShellSurface(child_surface.get(), gfx::Point(9, 9), true, false, - ash::kShellWindowId_DefaultContainer)); + ash::desks_util::GetActiveDeskContainerId())); child_shell_surface->DisableMovement(); child_shell_surface->SetParent(shell_surface.get()); gfx::Size child_buffer_size(15, 15);
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index aea68e11..4138a75 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -7,6 +7,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_state_type.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" @@ -137,7 +138,7 @@ gfx::Point(), true, true, - ash::kShellWindowId_DefaultContainer) {} + ash::desks_util::GetActiveDeskContainerId()) {} ShellSurface::~ShellSurface() { DCHECK(!scoped_configure_); @@ -273,9 +274,9 @@ parent ? views::Widget::GetTopLevelWidgetForNativeView(parent->window()) : nullptr; if (parent_widget) { - // Set parent window if using default container and the container itself - // is not the parent. - if (container_ == ash::kShellWindowId_DefaultContainer) + // Set parent window if using one of the desks container and the container + // itself is not the parent. + if (ash::desks_util::IsDeskContainerId(container_)) SetParentWindow(parent_widget->GetNativeWindow()); origin_ = position;
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index afc54f2..0e134ba 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/window_state_type.h" #include "ash/public/interfaces/window_pin_type.mojom.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/drag_window_resizer.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" @@ -673,7 +674,7 @@ bool ShellSurfaceBase::CanMaximize() const { // Shell surfaces in system modal container cannot be maximized. - if (container_ != ash::kShellWindowId_DefaultContainer) + if (!ash::desks_util::IsDeskContainerId(container_)) return false; // Non-transient shell surfaces can be maximized.
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 06dc3f35..dcca225 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -50,6 +50,10 @@ #include "ui/gfx/transform_util.h" #include "ui/views/widget/widget.h" +#if defined(OS_CHROMEOS) +#include "ash/wm/desks/desks_util.h" +#endif // defined(OS_CHROMEOS) + DEFINE_UI_CLASS_PROPERTY_TYPE(exo::Surface*) namespace exo { @@ -112,6 +116,14 @@ NOTREACHED(); } +bool IsDeskContainer(aura::Window* container) { +#if defined(OS_CHROMEOS) + return ash::desks_util::IsDeskContainer(container); +#else + return container->id() == ash::kShellWindowId_DefaultContainerDeprecated; +#endif // defined(OS_CHROMEOS) +} + class CustomWindowDelegate : public aura::WindowDelegate { public: explicit CustomWindowDelegate(Surface* surface) : surface_(surface) {} @@ -132,9 +144,7 @@ int GetNonClientComponent(const gfx::Point& point) const override { views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(surface_->window()); - if (widget && - widget->GetNativeView()->parent()->id() == - ash::kShellWindowId_DefaultContainer && + if (widget && IsDeskContainer(widget->GetNativeView()->parent()) && surface_->HitTest(point)) { return HTCLIENT; }
diff --git a/components/exo/test/exo_test_helper.cc b/components/exo/test/exo_test_helper.cc index ad160f7b..6a44e3f 100644 --- a/components/exo/test/exo_test_helper.cc +++ b/components/exo/test/exo_test_helper.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/public/cpp/shell_window_ids.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_positioner.h" #include "ash/wm/window_positioning_utils.h" #include "components/exo/buffer.h" @@ -30,7 +31,7 @@ bool is_modal) { surface_.reset(new Surface()); int container = is_modal ? ash::kShellWindowId_SystemModalContainer - : ash::kShellWindowId_DefaultContainer; + : ash::desks_util::GetActiveDeskContainerId(); shell_surface_ = std::make_unique<ShellSurface>(surface_.get(), gfx::Point(), true, false, container); @@ -84,7 +85,7 @@ ExoTestHelper::CreateClientControlledShellSurface(Surface* surface, bool is_modal) { int container = is_modal ? ash::kShellWindowId_SystemModalContainer - : ash::kShellWindowId_DefaultContainer; + : ash::desks_util::GetActiveDeskContainerId(); return Display().CreateClientControlledShellSurface( surface, container, WMHelper::GetInstance()->GetDefaultDeviceScaleFactor());
diff --git a/components/exo/wayland/zaura_shell_unittest.cc b/components/exo/wayland/zaura_shell_unittest.cc index 1b16962..938ef83 100644 --- a/components/exo/wayland/zaura_shell_unittest.cc +++ b/components/exo/wayland/zaura_shell_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/session/session_controller.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_util.h" #include "base/time/time.h" #include "components/exo/test/exo_test_base.h" @@ -113,7 +114,7 @@ std::unique_ptr<views::Widget> CreateOpaqueWidget(const gfx::Rect& bounds) { return CreateTestWidget( /*delegate=*/nullptr, - /*container_id=*/ash::kShellWindowId_DefaultContainer, bounds, + /*container_id=*/ash::desks_util::GetActiveDeskContainerId(), bounds, /*show=*/false); }
diff --git a/components/exo/wayland/zcr_remote_shell.cc b/components/exo/wayland/zcr_remote_shell.cc index 8a6a5d2..9aac427c 100644 --- a/components/exo/wayland/zcr_remote_shell.cc +++ b/components/exo/wayland/zcr_remote_shell.cc
@@ -14,6 +14,7 @@ #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/tablet_mode/tablet_mode_observer.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" @@ -839,12 +840,12 @@ int RemoteSurfaceContainer(uint32_t container) { switch (container) { case ZCR_REMOTE_SHELL_V1_CONTAINER_DEFAULT: - return ash::kShellWindowId_DefaultContainer; + return ash::desks_util::GetActiveDeskContainerId(); case ZCR_REMOTE_SHELL_V1_CONTAINER_OVERLAY: return ash::kShellWindowId_SystemModalContainer; default: DLOG(WARNING) << "Unsupported container: " << container; - return ash::kShellWindowId_DefaultContainer; + return ash::desks_util::GetActiveDeskContainerId(); } }
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index 6b19481..91f035b8 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -160,6 +160,7 @@ INLINE_UPDATE_READY_INFOBAR_ANDROID = 89, INLINE_UPDATE_FAILED_INFOBAR_ANDROID = 90, FLASH_DEPRECATION_INFOBAR_DELEGATE = 91, + SEND_TAB_TO_SELF_INFOBAR_DELEGATE = 92, }; // Describes navigation events, used to decide whether infobars should be
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index 33ea39c7..358d052 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -224,6 +224,14 @@ } void PdfAccessibilityTree::UpdateAXTreeDataFromSelection() { + tree_data_.sel_is_backward = false; + if (selection_start_page_index_ > selection_end_page_index_) { + tree_data_.sel_is_backward = true; + } else if (selection_start_page_index_ == selection_end_page_index_ && + selection_start_char_index_ > selection_end_char_index_) { + tree_data_.sel_is_backward = true; + } + FindNodeOffset(selection_start_page_index_, selection_start_char_index_, &tree_data_.sel_anchor_object_id, &tree_data_.sel_anchor_offset); @@ -420,6 +428,7 @@ // bool PdfAccessibilityTree::GetTreeData(ui::AXTreeData* tree_data) const { + tree_data->sel_is_backward = tree_data_.sel_is_backward; tree_data->sel_anchor_object_id = tree_data_.sel_anchor_object_id; tree_data->sel_anchor_offset = tree_data_.sel_anchor_offset; tree_data->sel_focus_object_id = tree_data_.sel_focus_object_id;
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index 7402f85..a3c9f79 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -247,8 +247,10 @@ content::RenderWidgetHostView* view = web_contents_ ? web_contents_->GetRenderWidgetHostView() : nullptr; - if (!view) + if (!view) { SendRequest(); + return; + } visual_feature_start_time_ = base::TimeTicks::Now();
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc index 340eca0..75b72ea6 100644 --- a/components/safe_browsing/web_ui/safe_browsing_ui.cc +++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -1180,6 +1180,7 @@ if (!provider) { AllowJavascript(); ResolveJavascriptCallback(base::Value(callback_id), base::Value("")); + return; } ReferrerChain referrer_chain;
diff --git a/components/send_tab_to_self/BUILD.gn b/components/send_tab_to_self/BUILD.gn index 7a9d8a73..0c44fc7 100644 --- a/components/send_tab_to_self/BUILD.gn +++ b/components/send_tab_to_self/BUILD.gn
@@ -28,6 +28,13 @@ public_deps = [ "//components/send_tab_to_self/proto:send_tab_to_self_proto", ] + if (is_ios || is_android) { + sources += [ + "send_tab_to_self_infobar_delegate.cc", + "send_tab_to_self_infobar_delegate.h", + ] + deps += [ "//components/infobars/core" ] + } } source_set("test_support") {
diff --git a/components/send_tab_to_self/DEPS b/components/send_tab_to_self/DEPS index 8da4a5b5..615aeb3 100644 --- a/components/send_tab_to_self/DEPS +++ b/components/send_tab_to_self/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/infobars", "+components/keyed_service/core", "+components/sync", "+components/version_info",
diff --git a/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc new file mode 100644 index 0000000..9072e11 --- /dev/null +++ b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc
@@ -0,0 +1,47 @@ +// Copyright 2019 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/send_tab_to_self/send_tab_to_self_infobar_delegate.h" + +#include <memory> + +#include "base/memory/ptr_util.h" +#include "base/strings/utf_string_conversions.h" +#include "components/send_tab_to_self/send_tab_to_self_entry.h" +#include "url/gurl.h" + +namespace send_tab_to_self { + +SendTabToSelfInfoBarDelegate::SendTabToSelfInfoBarDelegate( + const SendTabToSelfEntry* entry) { + entry_ = entry; +} + +std::unique_ptr<SendTabToSelfInfoBarDelegate> +SendTabToSelfInfoBarDelegate::Create(const SendTabToSelfEntry* entry) { + return base::WrapUnique(new SendTabToSelfInfoBarDelegate(entry)); +} + +SendTabToSelfInfoBarDelegate::~SendTabToSelfInfoBarDelegate() {} + +base::string16 SendTabToSelfInfoBarDelegate::GetInfobarMessage() const { + // TODO(crbug.com/944602): Define real string. + NOTIMPLEMENTED(); + return base::UTF8ToUTF16("Open"); +} + +void SendTabToSelfInfoBarDelegate::OpenTab() { + NOTIMPLEMENTED(); +} + +void SendTabToSelfInfoBarDelegate::InfoBarDismissed() { + NOTIMPLEMENTED(); +} + +infobars::InfoBarDelegate::InfoBarIdentifier +SendTabToSelfInfoBarDelegate::GetIdentifier() const { + return SEND_TAB_TO_SELF_INFOBAR_DELEGATE; +} + +} // namespace send_tab_to_self
diff --git a/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h new file mode 100644 index 0000000..280aaa89 --- /dev/null +++ b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h
@@ -0,0 +1,48 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ +#define COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/strings/string16.h" +#include "components/infobars/core/infobar_delegate.h" + +namespace send_tab_to_self { + +class SendTabToSelfEntry; + +// Delegate containing logic about what to display and how to behave +// in the SendTabToSelf infobar. Used across Android and iOS. +// TODO(crbug.com/ +class SendTabToSelfInfoBarDelegate : public infobars::InfoBarDelegate { + public: + static std::unique_ptr<SendTabToSelfInfoBarDelegate> Create( + const SendTabToSelfEntry* entry); + ~SendTabToSelfInfoBarDelegate() override; + + // Returns the message to be shown in the infobar. + base::string16 GetInfobarMessage() const; + + // Opens a tab to the url of the shared |entry_|. + void OpenTab(); + + // InfoBarDelegate: + void InfoBarDismissed() override; + infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; + + private: + SendTabToSelfInfoBarDelegate(const SendTabToSelfEntry* entry); + + // The entry that was share to this device. Must outlive this instance. + const SendTabToSelfEntry* entry_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(SendTabToSelfInfoBarDelegate); +}; + +} // namespace send_tab_to_self + +#endif // COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_
diff --git a/components/user_manager/known_user.cc b/components/user_manager/known_user.cc index 52c554b..74ebcdb 100644 --- a/components/user_manager/known_user.cc +++ b/components/user_manager/known_user.cc
@@ -143,6 +143,19 @@ AccountId::AccountTypeToString(account_id.GetAccountType())); } +void ClearPref(const AccountId& account_id, const std::string& path) { + const base::DictionaryValue* user_pref_dict = nullptr; + if (!FindPrefs(account_id, &user_pref_dict)) + return; + + base::Value updated_user_pref = user_pref_dict->Clone(); + base::DictionaryValue* updated_user_pref_dict; + updated_user_pref.GetAsDictionary(&updated_user_pref_dict); + + updated_user_pref_dict->RemovePath(path); + UpdatePrefs(account_id, *updated_user_pref_dict, true); +} + } // namespace bool FindPrefs(const AccountId& account_id, @@ -285,16 +298,7 @@ for (const std::string& key : kReservedKeys) CHECK_NE(path, key); - const base::DictionaryValue* user_pref_dict = nullptr; - if (!FindPrefs(account_id, &user_pref_dict)) - return; - - base::Value updated_user_pref = user_pref_dict->Clone(); - base::DictionaryValue* updated_user_pref_dict; - updated_user_pref.GetAsDictionary(&updated_user_pref_dict); - - updated_user_pref_dict->RemovePath(path); - UpdatePrefs(account_id, *updated_user_pref_dict, true); + ClearPref(account_id, path); } AccountId GetAccountId(const std::string& user_email, @@ -531,6 +535,10 @@ return ProfileRequiresPolicy::kUnknown; } +void ClearProfileRequiresPolicy(const AccountId& account_id) { + ClearPref(account_id, kProfileRequiresPolicy); +} + void UpdateReauthReason(const AccountId& account_id, const int reauth_reason) { SetIntegerPref(account_id, kReauthReasonKey, reauth_reason); }
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h index 1c65bf88..b703c3e9 100644 --- a/components/user_manager/known_user.h +++ b/components/user_manager/known_user.h
@@ -172,6 +172,10 @@ SetProfileRequiresPolicy(const AccountId& account_id, ProfileRequiresPolicy policy_required); +// Clears information whether profile requires policy. +void USER_MANAGER_EXPORT +ClearProfileRequiresPolicy(const AccountId& account_id); + // Saves why the user has to go through re-auth flow. void USER_MANAGER_EXPORT UpdateReauthReason(const AccountId& account_id, const int reauth_reason);
diff --git a/components/user_manager/user.cc b/components/user_manager/user.cc index a1f9589..a23a0ae 100644 --- a/components/user_manager/user.cc +++ b/components/user_manager/user.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "components/account_id/account_id.h" +#include "components/user_manager/known_user.h" #include "components/user_manager/user_manager.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -382,6 +383,11 @@ return; const bool old_is_child = is_child_; is_child_ = user_type == user_manager::USER_TYPE_CHILD; + + // Clear information about profile policy requirements to enforce setting it + // again for the new account type. + user_manager::known_user::ClearProfileRequiresPolicy(GetAccountId()); + LOG(WARNING) << "User type has changed: " << current_type << " (is_child=" << old_is_child << ") => " << user_type << " (is_child=" << is_child_ << ")";
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index 73929b3..d0adc36d 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1155,5 +1155,13 @@ return Response::Error("Unidentified lifecycle state"); } +void PageHandler::GetInstallabilityErrors( + std::unique_ptr<GetInstallabilityErrorsCallback> callback) { + auto errors = protocol::Array<std::string>::create(); + // TODO: Use InstallableManager once it moves into content/. + // Until then, this code is only used to return empty array in the tests. + callback->sendSuccess(std::move(errors)); +} + } // namespace protocol } // namespace content
diff --git a/content/browser/devtools/protocol/page_handler.h b/content/browser/devtools/protocol/page_handler.h index b3f45b3..4bee8ba 100644 --- a/content/browser/devtools/protocol/page_handler.h +++ b/content/browser/devtools/protocol/page_handler.h
@@ -155,6 +155,8 @@ std::unique_ptr<GetAppManifestCallback> callback) override; Response SetWebLifecycleState(const std::string& state) override; + void GetInstallabilityErrors( + std::unique_ptr<GetInstallabilityErrorsCallback> callback) override; private: enum EncodingFormat { PNG, JPEG };
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc index b475eff..3ae38448 100644 --- a/content/browser/devtools/protocol/target_handler.cc +++ b/content/browser/devtools/protocol/target_handler.cc
@@ -203,8 +203,9 @@ std::string encoded; base::Base64Encode(message, &encoded); - std::string eval_code = "window." + binding_name_ + ".onmessage(atob(\""; - std::string eval_suffix = "\"))"; + std::string eval_code = + "try { window." + binding_name_ + ".onmessage(atob(\""; + std::string eval_suffix = "\")); } catch(e) { console.error(e); }"; eval_code.reserve(eval_code.size() + encoded.size() + eval_suffix.size()); eval_code.append(encoded); eval_code.append(eval_suffix);
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json index cdb51646a..3e9a571 100644 --- a/content/browser/devtools/protocol_config.json +++ b/content/browser/devtools/protocol_config.json
@@ -57,9 +57,9 @@ "domain": "Page", "include": ["enable", "disable", "reload", "navigate", "stopLoading", "getNavigationHistory", "navigateToHistoryEntry", "resetNavigationHistory", "captureScreenshot", "startScreencast", "stopScreencast", "screencastFrameAck", "handleJavaScriptDialog", "setColorPickerEnabled", - "printToPDF", "bringToFront", "setDownloadBehavior", "getAppManifest", "crash", "close", "setWebLifecycleState", "captureSnapshot"], + "printToPDF", "bringToFront", "setDownloadBehavior", "getAppManifest", "crash", "close", "setWebLifecycleState", "captureSnapshot", "getInstallabilityErrors"], "include_events": ["colorPicked", "interstitialShown", "interstitialHidden", "javascriptDialogOpening", "javascriptDialogClosed", "screencastVisibilityChanged", "screencastFrame"], - "async": ["captureScreenshot", "printToPDF", "navigate", "getAppManifest", "reload", "captureSnapshot"] + "async": ["captureScreenshot", "printToPDF", "navigate", "getAppManifest", "reload", "captureSnapshot", "getInstallabilityErrors"] }, { "domain": "Runtime",
diff --git a/content/browser/renderer_host/direct_manipulation_event_handler_win.cc b/content/browser/renderer_host/direct_manipulation_event_handler_win.cc index eec54fc..c98d4507 100644 --- a/content/browser/renderer_host/direct_manipulation_event_handler_win.cc +++ b/content/browser/renderer_host/direct_manipulation_event_handler_win.cc
@@ -28,19 +28,15 @@ } // namespace DirectManipulationEventHandler::DirectManipulationEventHandler( - DirectManipulationHelper* helper) - : helper_(helper) {} + ui::WindowEventTarget* event_target) + : event_target_(event_target) {} -void DirectManipulationEventHandler::SetWindowEventTarget( - ui::WindowEventTarget* event_target) { - if (!event_target && LoggingEnabled()) { - DebugLogging("Event target is null.", S_OK); - if (event_target_) - DebugLogging("Previous event target is not null", S_OK); - else - DebugLogging("Previous event target is null", S_OK); - } - event_target_ = event_target; +bool DirectManipulationEventHandler::SetViewportSizeInPixels( + const gfx::Size& viewport_size_in_pixels) { + if (viewport_size_in_pixels_ == viewport_size_in_pixels) + return false; + viewport_size_in_pixels_ = viewport_size_in_pixels; + return true; } void DirectManipulationEventHandler::SetDeviceScaleFactor( @@ -175,19 +171,29 @@ if (current != DIRECTMANIPULATION_READY) return S_OK; - // Reset the viewport when we're idle, so the content transforms always start - // at identity. - // Every animation will receive 2 ready message, we should stop request - // compositor animation at the second ready. - first_ready_ = !first_ready_; - HRESULT hr = helper_->Reset(first_ready_); + // Normally gesture sequence will receive 2 READY message, the first one is + // gesture end, the second one is from viewport reset. We don't have content + // transform in the second RUNNING -> READY. We should not reset on an empty + // RUNNING -> READY sequence. + if (!FloatEquals(1.0f, last_scale_) || last_x_offset_ != 0 || + last_y_offset_ != 0) { + HRESULT hr = viewport->ZoomToRect( + static_cast<float>(0), static_cast<float>(0), + static_cast<float>(viewport_size_in_pixels_.width()), + static_cast<float>(viewport_size_in_pixels_.height()), FALSE); + if (!SUCCEEDED(hr)) { + DebugLogging("Viewport zoom to rect failed.", hr); + return hr; + } + } + last_scale_ = 1.0f; last_x_offset_ = 0.0f; last_y_offset_ = 0.0f; TransitionToState(GestureState::kNone); - return hr; + return S_OK; } HRESULT DirectManipulationEventHandler::OnViewportUpdated(
diff --git a/content/browser/renderer_host/direct_manipulation_event_handler_win.h b/content/browser/renderer_host/direct_manipulation_event_handler_win.h index 270e85a..e06c680 100644 --- a/content/browser/renderer_host/direct_manipulation_event_handler_win.h +++ b/content/browser/renderer_host/direct_manipulation_event_handler_win.h
@@ -11,6 +11,7 @@ #include <wrl.h> #include "base/macros.h" +#include "ui/gfx/geometry/size.h" namespace ui { @@ -20,7 +21,6 @@ namespace content { -class DirectManipulationHelper; class DirectManipulationUnitTest; // DirectManipulationEventHandler receives status update and gesture events from @@ -35,11 +35,10 @@ Microsoft::WRL::FtmBase, IDirectManipulationViewportEventHandler>> { public: - explicit DirectManipulationEventHandler(DirectManipulationHelper* helper); + explicit DirectManipulationEventHandler(ui::WindowEventTarget* event_target); - // WindowEventTarget updates for every DM_POINTERHITTEST in case window - // hierarchy changed. - void SetWindowEventTarget(ui::WindowEventTarget* event_target); + // Return true if viewport_size_in_pixels_ changed. + bool SetViewportSizeInPixels(const gfx::Size& viewport_size_in_pixels); void SetDeviceScaleFactor(float device_scale_factor); @@ -65,18 +64,18 @@ OnContentUpdated(_In_ IDirectManipulationViewport* viewport, _In_ IDirectManipulationContent* content) override; - DirectManipulationHelper* helper_ = nullptr; ui::WindowEventTarget* event_target_ = nullptr; float device_scale_factor_ = 1.0f; float last_scale_ = 1.0f; int last_x_offset_ = 0; int last_y_offset_ = 0; - bool first_ready_ = false; bool should_send_scroll_begin_ = false; // Current recognized gesture from Direct Manipulation. GestureState gesture_state_ = GestureState::kNone; + gfx::Size viewport_size_in_pixels_; + DISALLOW_COPY_AND_ASSIGN(DirectManipulationEventHandler); };
diff --git a/content/browser/renderer_host/direct_manipulation_helper_win.cc b/content/browser/renderer_host/direct_manipulation_helper_win.cc index d04c3e1..c05fd59 100644 --- a/content/browser/renderer_host/direct_manipulation_helper_win.cc +++ b/content/browser/renderer_host/direct_manipulation_helper_win.cc
@@ -13,6 +13,8 @@ #include "base/win/windows_version.h" #include "ui/base/ui_base_features.h" #include "ui/base/win/window_event_target.h" +#include "ui/compositor/compositor.h" +#include "ui/compositor/compositor_animation_observer.h" #include "ui/display/win/screen_win.h" #include "ui/gfx/geometry/rect.h" @@ -38,8 +40,9 @@ // static std::unique_ptr<DirectManipulationHelper> DirectManipulationHelper::CreateInstance(HWND window, + ui::Compositor* compositor, ui::WindowEventTarget* event_target) { - if (!::IsWindow(window)) + if (!::IsWindow(window) || !compositor || !event_target) return nullptr; if (!base::FeatureList::IsEnabled(features::kPrecisionTouchpad)) @@ -50,8 +53,7 @@ return nullptr; std::unique_ptr<DirectManipulationHelper> instance = - base::WrapUnique(new DirectManipulationHelper()); - instance->window_ = window; + base::WrapUnique(new DirectManipulationHelper(window, compositor)); if (instance->Initialize(event_target)) return instance; @@ -72,11 +74,10 @@ return nullptr; std::unique_ptr<DirectManipulationHelper> instance = - base::WrapUnique(new DirectManipulationHelper()); + base::WrapUnique(new DirectManipulationHelper(0, nullptr)); instance->event_handler_ = - Microsoft::WRL::Make<DirectManipulationEventHandler>(instance.get()); - instance->event_handler_->SetWindowEventTarget(event_target); + Microsoft::WRL::Make<DirectManipulationEventHandler>(event_target); instance->viewport_ = viewport; @@ -84,11 +85,25 @@ } DirectManipulationHelper::~DirectManipulationHelper() { - if (viewport_) - viewport_->Abandon(); + Destroy(); } -DirectManipulationHelper::DirectManipulationHelper() {} +DirectManipulationHelper::DirectManipulationHelper(HWND window, + ui::Compositor* compositor) + : window_(window), compositor_(compositor) {} + +void DirectManipulationHelper::OnAnimationStep(base::TimeTicks timestamp) { + // Simulate 1 frame in update_manager_. + HRESULT hr = update_manager_->Update(nullptr); + if (!SUCCEEDED(hr)) + DebugLogging("UpdateManager update failed.", hr); +} + +void DirectManipulationHelper::OnCompositingShuttingDown( + ui::Compositor* compositor) { + DCHECK_EQ(compositor, compositor_); + Destroy(); +} bool DirectManipulationHelper::Initialize(ui::WindowEventTarget* event_target) { // IDirectManipulationUpdateManager is the first COM object created by the @@ -141,8 +156,8 @@ return false; } - event_handler_ = Microsoft::WRL::Make<DirectManipulationEventHandler>(this); - event_handler_->SetWindowEventTarget(event_target); + event_handler_ = + Microsoft::WRL::Make<DirectManipulationEventHandler>(event_target); // We got Direct Manipulation transform from // IDirectManipulationViewportEventHandler. @@ -154,8 +169,9 @@ } // Set default rect for viewport before activate. - viewport_size_in_pixels_ = {1000, 1000}; - RECT rect = gfx::Rect(viewport_size_in_pixels_).ToRECT(); + gfx::Size viewport_size_in_pixels = {1000, 1000}; + event_handler_->SetViewportSizeInPixels(viewport_size_in_pixels); + RECT rect = gfx::Rect(viewport_size_in_pixels).ToRECT(); hr = viewport_->SetViewportRect(&rect); if (!SUCCEEDED(hr)) { DebugLogging("Viewport set rect failed.", hr); @@ -180,37 +196,16 @@ return false; } + DCHECK(compositor_); + compositor_->AddAnimationObserver(this); + DebugLogging("DirectManipulation initialization complete", S_OK); return true; } -void DirectManipulationHelper::Activate() { - HRESULT hr = viewport_->Stop(); - if (!SUCCEEDED(hr)) { - DebugLogging("Viewport stop failed.", hr); - return; - } - - hr = manager_->Activate(window_); - if (!SUCCEEDED(hr)) - DebugLogging("DirectManipulationManager activate failed.", hr); -} - -void DirectManipulationHelper::Deactivate() { - HRESULT hr = viewport_->Stop(); - if (!SUCCEEDED(hr)) { - DebugLogging("Viewport stop failed.", hr); - return; - } - - hr = manager_->Deactivate(window_); - if (!SUCCEEDED(hr)) - DebugLogging("DirectManipulationManager deactivate failed.", hr); -} - void DirectManipulationHelper::SetSizeInPixels( const gfx::Size& size_in_pixels) { - if (viewport_size_in_pixels_ == size_in_pixels) + if (!event_handler_->SetViewportSizeInPixels(size_in_pixels)) return; HRESULT hr = viewport_->Stop(); @@ -219,16 +214,13 @@ return; } - viewport_size_in_pixels_ = size_in_pixels; - RECT rect = gfx::Rect(viewport_size_in_pixels_).ToRECT(); + RECT rect = gfx::Rect(size_in_pixels).ToRECT(); hr = viewport_->SetViewportRect(&rect); if (!SUCCEEDED(hr)) DebugLogging("Viewport set rect failed.", hr); } -bool DirectManipulationHelper::OnPointerHitTest( - WPARAM w_param, - ui::WindowEventTarget* event_target) { +void DirectManipulationHelper::OnPointerHitTest(WPARAM w_param) { // Update the device scale factor. event_handler_->SetDeviceScaleFactor( display::win::ScreenWin::GetScaleFactorForHWND(window_)); @@ -239,53 +231,50 @@ // For WM_POINTER, the pointer type will show the event from mouse. // For WM_POINTERACTIVATE, the pointer id will be different with the following // message. - event_handler_->SetWindowEventTarget(event_target); - using GetPointerTypeFn = BOOL(WINAPI*)(UINT32, POINTER_INPUT_TYPE*); UINT32 pointer_id = GET_POINTERID_WPARAM(w_param); POINTER_INPUT_TYPE pointer_type; static GetPointerTypeFn get_pointer_type = reinterpret_cast<GetPointerTypeFn>( GetProcAddress(GetModuleHandleA("user32.dll"), "GetPointerType")); if (get_pointer_type && get_pointer_type(pointer_id, &pointer_type) && - pointer_type == PT_TOUCHPAD && event_target) { + pointer_type == PT_TOUCHPAD) { HRESULT hr = viewport_->SetContact(pointer_id); - if (!SUCCEEDED(hr)) { + if (!SUCCEEDED(hr)) DebugLogging("Viewport set contact failed.", hr); - return false; - } - - // Request begin frame for fake viewport. - need_poll_events_ = true; } - return need_poll_events_; -} - -HRESULT DirectManipulationHelper::Reset(bool need_poll_events) { - // By zooming the primary content to a rect that match the viewport rect, we - // reset the content's transform to identity. - HRESULT hr = viewport_->ZoomToRect( - static_cast<float>(0), static_cast<float>(0), - static_cast<float>(viewport_size_in_pixels_.width()), - static_cast<float>(viewport_size_in_pixels_.height()), FALSE); - if (!SUCCEEDED(hr)) { - DebugLogging("Viewport zoom to rect failed.", hr); - return hr; - } - - need_poll_events_ = need_poll_events; - return S_OK; -} - -bool DirectManipulationHelper::PollForNextEvent() { - // Simulate 1 frame in update_manager_. - HRESULT hr = update_manager_->Update(nullptr); - if (!SUCCEEDED(hr)) - DebugLogging("UpdateManager update failed.", hr); - return need_poll_events_; } void DirectManipulationHelper::SetDeviceScaleFactorForTesting(float factor) { event_handler_->SetDeviceScaleFactor(factor); } +void DirectManipulationHelper::Destroy() { + if (!compositor_) + return; + + compositor_->RemoveAnimationObserver(this); + compositor_ = nullptr; + + HRESULT hr; + if (viewport_) { + hr = viewport_->Stop(); + if (!SUCCEEDED(hr)) + DebugLogging("Viewport stop failed.", hr); + + hr = viewport_->RemoveEventHandler(view_port_handler_cookie_); + if (!SUCCEEDED(hr)) + DebugLogging("Viewport remove event handler failed.", hr); + + hr = viewport_->Abandon(); + if (!SUCCEEDED(hr)) + DebugLogging("Viewport abandon failed.", hr); + } + + if (manager_) { + hr = manager_->Deactivate(window_); + if (!SUCCEEDED(hr)) + DebugLogging("DirectManipulationManager deactivate failed.", hr); + } +} + } // namespace content
diff --git a/content/browser/renderer_host/direct_manipulation_helper_win.h b/content/browser/renderer_host/direct_manipulation_helper_win.h index 76c889b..c644d4c4 100644 --- a/content/browser/renderer_host/direct_manipulation_helper_win.h +++ b/content/browser/renderer_host/direct_manipulation_helper_win.h
@@ -16,10 +16,12 @@ #include "base/macros.h" #include "content/browser/renderer_host/direct_manipulation_event_handler_win.h" #include "content/common/content_export.h" +#include "ui/compositor/compositor_animation_observer.h" #include "ui/gfx/geometry/size.h" namespace ui { +class Compositor; class WindowEventTarget; } // namespace ui @@ -44,13 +46,15 @@ // when DM_POINTERHITTEST. // 3. OnViewportStatusChanged will be called when the gesture phase change. // OnContentUpdated will be called when the gesture update. -class CONTENT_EXPORT DirectManipulationHelper { +class CONTENT_EXPORT DirectManipulationHelper + : public ui::CompositorAnimationObserver { public: // Creates and initializes an instance of this class if Direct Manipulation is // enabled on the platform. Returns nullptr if it disabled or failed on // initialization. static std::unique_ptr<DirectManipulationHelper> CreateInstance( HWND window, + ui::Compositor* compositor, ui::WindowEventTarget* event_target); // Creates and initializes an instance for testing. @@ -58,49 +62,41 @@ ui::WindowEventTarget* event_target, Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport); - ~DirectManipulationHelper(); + ~DirectManipulationHelper() override; - // Actives Direct Manipulation, call when window show. - void Activate(); - - // Deactivates Direct Manipulation, call when window show. - void Deactivate(); + // CompositorAnimationObserver implements. + // DirectManipulation needs to poll for new events every frame while finger + // gesturing on touchpad. + void OnAnimationStep(base::TimeTicks timestamp) override; + void OnCompositingShuttingDown(ui::Compositor* compositor) override; // Updates viewport size. Call it when window bounds updated. void SetSizeInPixels(const gfx::Size& size_in_pixels); - // Reset for gesture end. - HRESULT Reset(bool need_animtation); - - // Pass the pointer hit test to Direct Manipulation. Return true indicated we - // need poll for new events every frame from here. - bool OnPointerHitTest(WPARAM w_param, ui::WindowEventTarget* event_target); - - // On each frame poll new Direct Manipulation events. Return true if we still - // need poll for new events on next frame, otherwise stop request need begin - // frame. - bool PollForNextEvent(); + // Pass the pointer hit test to Direct Manipulation. + void OnPointerHitTest(WPARAM w_param); private: friend class content::DirectManipulationBrowserTest; friend class DirectManipulationUnitTest; - DirectManipulationHelper(); + DirectManipulationHelper(HWND window, ui::Compositor* compositor); // This function instantiates Direct Manipulation and creates a viewport for - // the passed in |window|. Return false if initialize failed. + // |window_|. Return false if initialize failed. bool Initialize(ui::WindowEventTarget* event_target); void SetDeviceScaleFactorForTesting(float factor); + void Destroy(); + Microsoft::WRL::ComPtr<IDirectManipulationManager> manager_; Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> update_manager_; Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport_; Microsoft::WRL::ComPtr<DirectManipulationEventHandler> event_handler_; HWND window_; + ui::Compositor* compositor_ = nullptr; DWORD view_port_handler_cookie_; - bool need_poll_events_ = false; - gfx::Size viewport_size_in_pixels_; DISALLOW_COPY_AND_ASSIGN(DirectManipulationHelper); };
diff --git a/content/browser/renderer_host/direct_manipulation_win_browsertest.cc b/content/browser/renderer_host/direct_manipulation_win_browsertest.cc index 6690f4ef..47675942 100644 --- a/content/browser/renderer_host/direct_manipulation_win_browsertest.cc +++ b/content/browser/renderer_host/direct_manipulation_win_browsertest.cc
@@ -49,35 +49,12 @@ return rwhva->legacy_render_widget_host_HWND_; } - HWND GetSubWindowHWND() { - LegacyRenderWidgetHostHWND* lrwhh = GetLegacyRenderWidgetHostHWND(); - - return lrwhh->hwnd(); - } - ui::WindowEventTarget* GetWindowEventTarget() { LegacyRenderWidgetHostHWND* lrwhh = GetLegacyRenderWidgetHostHWND(); return lrwhh->GetWindowEventTarget(lrwhh->GetParent()); } - void SimulatePointerHitTest() { - LegacyRenderWidgetHostHWND* lrwhh = GetLegacyRenderWidgetHostHWND(); - - lrwhh->direct_manipulation_helper_->need_poll_events_ = true; - lrwhh->CreateAnimationObserver(); - } - - void UpdateParent(HWND hwnd) { - LegacyRenderWidgetHostHWND* lrwhh = GetLegacyRenderWidgetHostHWND(); - - lrwhh->UpdateParent(hwnd); - } - - bool HasCompositorAnimationObserver(LegacyRenderWidgetHostHWND* lrwhh) { - return lrwhh->compositor_animation_observer_ != nullptr; - } - private: base::test::ScopedFeatureList scoped_feature_list_; @@ -88,37 +65,6 @@ DirectManipulationBrowserTest, testing::Bool()); -// Ensure the AnimationObserver destroy when hwnd reparent to other hwnd. -IN_PROC_BROWSER_TEST_P(DirectManipulationBrowserTest, HWNDReparent) { - if (base::win::GetVersion() < base::win::VERSION_WIN10) - return; - - NavigateToURL(shell(), GURL(url::kAboutBlankURL)); - - LegacyRenderWidgetHostHWND* lrwhh = GetLegacyRenderWidgetHostHWND(); - ASSERT_TRUE(lrwhh); - - // The observer should not create before it needed. - ASSERT_TRUE(!HasCompositorAnimationObserver(lrwhh)); - - // Add AnimationObserver to tab to simulate direct manipulation start. - SimulatePointerHitTest(); - ASSERT_TRUE(HasCompositorAnimationObserver(lrwhh)); - - // Create another browser. - Shell* shell2 = CreateBrowser(); - NavigateToURL(shell2, GURL(url::kAboutBlankURL)); - - // Move to the tab to browser2. - UpdateParent( - shell2->window()->GetRootWindow()->GetHost()->GetAcceleratedWidget()); - - // The animation observer should be removed. - EXPECT_FALSE(HasCompositorAnimationObserver(lrwhh)); - - shell2->Close(); -} - // EventLogger is to observe the events sent from WindowEventTarget (the root // window). class EventLogger : public ui::EventRewriter {
diff --git a/content/browser/renderer_host/direct_manipulation_win_unittest.cc b/content/browser/renderer_host/direct_manipulation_win_unittest.cc index 3c85312..ce91625 100644 --- a/content/browser/renderer_host/direct_manipulation_win_unittest.cc +++ b/content/browser/renderer_host/direct_manipulation_win_unittest.cc
@@ -31,6 +31,12 @@ ~MockDirectManipulationViewport() override {} + bool IsZoomToRectCalled() { + bool called = zoom_to_rect_called_; + zoom_to_rect_called_ = false; + return called; + } + HRESULT STDMETHODCALLTYPE Enable() override { return S_OK; } HRESULT STDMETHODCALLTYPE Disable() override { return S_OK; } @@ -75,6 +81,7 @@ _In_ const float right, _In_ const float bottom, _In_ BOOL animate) override { + zoom_to_rect_called_ = true; return S_OK; } @@ -161,6 +168,8 @@ HRESULT STDMETHODCALLTYPE Abandon() override { return S_OK; } private: + bool zoom_to_rect_called_ = false; + DISALLOW_COPY_AND_ASSIGN(MockDirectManipulationViewport); }; @@ -397,13 +406,7 @@ viewport_.Get(), content_.Get()); } - void SetNeedAnimation(bool need_poll_events) { - direct_manipulation_helper_->need_poll_events_ = need_poll_events; - } - - bool NeedAnimation() { - return direct_manipulation_helper_->need_poll_events_; - } + bool IsZoomToRectCalled() { return viewport_->IsZoomToRectCalled(); } void SetDeviceScaleFactor(float factor) { direct_manipulation_helper_->SetDeviceScaleFactorForTesting(factor); @@ -721,21 +724,19 @@ } TEST_F(DirectManipulationUnitTest, - NeedAnimtationShouldBeFalseAfterSecondReset) { + ZoomToRectShouldNotBeCalledInEmptyRunningReadySequence) { if (!GetDirectManipulationHelper()) return; - // Direct Manipulation will set need_poll_events_ true when DM_POINTERTEST - // from touchpad. - SetNeedAnimation(true); + ContentUpdated(1.0f, 5, 0); // Receive first ready when gesture end. ViewportStatusChanged(DIRECTMANIPULATION_READY, DIRECTMANIPULATION_RUNNING); - EXPECT_TRUE(NeedAnimation()); + EXPECT_TRUE(IsZoomToRectCalled()); // Receive second ready from ZoomToRect. ViewportStatusChanged(DIRECTMANIPULATION_READY, DIRECTMANIPULATION_RUNNING); - EXPECT_FALSE(NeedAnimation()); + EXPECT_FALSE(IsZoomToRectCalled()); } TEST_F(DirectManipulationUnitTest, HiDPIScroll) {
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc index b781869..e32f482 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.cc +++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -27,7 +27,6 @@ #include "ui/base/view_prop.h" #include "ui/base/win/internal_constants.h" #include "ui/base/win/window_event_target.h" -#include "ui/compositor/compositor.h" #include "ui/display/win/screen_win.h" #include "ui/gfx/geometry/rect.h" @@ -38,47 +37,6 @@ // accessibility support. const int kIdScreenReaderHoneyPot = 1; -// DirectManipulation needs to poll for new events every frame while finger -// gesturing on touchpad. -class CompositorAnimationObserverForDirectManipulation - : public ui::CompositorAnimationObserver { - public: - CompositorAnimationObserverForDirectManipulation( - LegacyRenderWidgetHostHWND* render_widget_host_hwnd, - ui::Compositor* compositor) - : render_widget_host_hwnd_(render_widget_host_hwnd), - compositor_(compositor) { - DCHECK(compositor_); - compositor_->AddAnimationObserver(this); - DebugLogging("Add AnimationObserverForDirectManipulation."); - } - - ~CompositorAnimationObserverForDirectManipulation() override { - if (compositor_) { - compositor_->RemoveAnimationObserver(this); - DebugLogging("Remove AnimationObserverForDirectManipulation."); - } - } - - // ui::CompositorAnimationObserver - void OnAnimationStep(base::TimeTicks timestamp) override { - render_widget_host_hwnd_->PollForNextEvent(); - } - - // ui::CompositorAnimationObserver - void OnCompositingShuttingDown(ui::Compositor* compositor) override { - DebugLogging("OnCompositingShuttingDown."); - compositor->RemoveAnimationObserver(this); - compositor_ = nullptr; - } - - private: - LegacyRenderWidgetHostHWND* render_widget_host_hwnd_; - ui::Compositor* compositor_; - - DISALLOW_COPY_AND_ASSIGN(CompositorAnimationObserverForDirectManipulation); -}; - // static LegacyRenderWidgetHostHWND* LegacyRenderWidgetHostHWND::Create( HWND parent) { @@ -103,8 +61,6 @@ } void LegacyRenderWidgetHostHWND::Destroy() { - // Stop the AnimationObserver when window close. - DestroyAnimationObserver(); host_ = nullptr; if (::IsWindow(hwnd())) ::DestroyWindow(hwnd()); @@ -113,10 +69,16 @@ void LegacyRenderWidgetHostHWND::UpdateParent(HWND parent) { if (GetWindowEventTarget(GetParent())) GetWindowEventTarget(GetParent())->HandleParentChanged(); - // Stop the AnimationObserver when window hide. eg. tab switch, move tab to - // another window. - DestroyAnimationObserver(); + ::SetParent(hwnd(), parent); + + // Direct Manipulation is enabled on Windows 10+. The CreateInstance function + // returns NULL if Direct Manipulation is not available. Recreate + // |direct_manipulation_helper_| when parent changed (compositor and window + // event target updated). + direct_manipulation_helper_ = DirectManipulationHelper::CreateInstance( + hwnd(), host_->GetNativeView()->GetHost()->compositor(), + GetWindowEventTarget(GetParent())); } HWND LegacyRenderWidgetHostHWND::GetParent() { @@ -125,14 +87,10 @@ void LegacyRenderWidgetHostHWND::Show() { ::ShowWindow(hwnd(), SW_SHOW); - if (direct_manipulation_helper_) - direct_manipulation_helper_->Activate(); } void LegacyRenderWidgetHostHWND::Hide() { ::ShowWindow(hwnd(), SW_HIDE); - if (direct_manipulation_helper_) - direct_manipulation_helper_->Deactivate(); } void LegacyRenderWidgetHostHWND::SetBounds(const gfx::Rect& bounds) { @@ -191,11 +149,6 @@ CHILDID_SELF); } - // Direct Manipulation is enabled on Windows 10+. The CreateInstance function - // returns NULL if Direct Manipulation is not available. - direct_manipulation_helper_ = DirectManipulationHelper::CreateInstance( - hwnd(), GetWindowEventTarget(GetParent())); - // Disable pen flicks (http://crbug.com/506977) base::win::DisableFlicks(hwnd()); @@ -501,21 +454,6 @@ return 0; } -LRESULT LegacyRenderWidgetHostHWND::OnWindowPosChanged(UINT message, - WPARAM w_param, - LPARAM l_param) { - WINDOWPOS* window_pos = reinterpret_cast<WINDOWPOS*>(l_param); - if (direct_manipulation_helper_) { - if (window_pos->flags & SWP_SHOWWINDOW) { - direct_manipulation_helper_->Activate(); - } else if (window_pos->flags & SWP_HIDEWINDOW) { - direct_manipulation_helper_->Deactivate(); - } - } - SetMsgHandled(FALSE); - return 0; -} - LRESULT LegacyRenderWidgetHostHWND::OnDestroy(UINT message, WPARAM w_param, LPARAM l_param) { @@ -534,30 +472,12 @@ return 0; DebugLogging("Receive DM_POINTERHITTEST."); - // Update window event target for each DM_POINTERHITTEST. - if (direct_manipulation_helper_->OnPointerHitTest( - w_param, GetWindowEventTarget(GetParent()))) { - if (compositor_animation_observer_) { - // This is reach if Windows send a DM_POINTERHITTEST before the last - // DM_POINTERHITTEST receive READY status. We never see this but still - // worth to handle it. - DebugLogging("AnimationObserverForDirectManipulation exists."); - return 0; - } - CreateAnimationObserver(); - } + direct_manipulation_helper_->OnPointerHitTest(w_param); return 0; } -void LegacyRenderWidgetHostHWND::PollForNextEvent() { - DCHECK(direct_manipulation_helper_); - - if (!direct_manipulation_helper_->PollForNextEvent()) - DestroyAnimationObserver(); -} - gfx::NativeViewAccessible LegacyRenderWidgetHostHWND::GetOrCreateWindowRootAccessible() { if (!host_) @@ -589,20 +509,4 @@ return root->GetNativeViewAccessible(); } -void LegacyRenderWidgetHostHWND::CreateAnimationObserver() { - DCHECK(!compositor_animation_observer_); - DCHECK(host_); - DCHECK(host_->GetNativeView()->GetHost()); - DCHECK(host_->GetNativeView()->GetHost()->compositor()); - - compositor_animation_observer_ = - std::make_unique<CompositorAnimationObserverForDirectManipulation>( - this, host_->GetNativeView()->GetHost()->compositor()); -} - -void LegacyRenderWidgetHostHWND::DestroyAnimationObserver() { - DebugLogging("DestroyAnimationObserver."); - compositor_animation_observer_.reset(); -} - } // namespace content
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h index 950515b4..6c06a240 100644 --- a/content/browser/renderer_host/legacy_render_widget_host_win.h +++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "base/win/atl.h" #include "content/common/content_export.h" -#include "ui/compositor/compositor_animation_observer.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" @@ -96,7 +95,6 @@ OnMouseRange) MESSAGE_HANDLER_EX(WM_NCCALCSIZE, OnNCCalcSize) MESSAGE_HANDLER_EX(WM_SIZE, OnSize) - MESSAGE_HANDLER_EX(WM_WINDOWPOSCHANGED, OnWindowPosChanged) MESSAGE_HANDLER_EX(WM_DESTROY, OnDestroy) MESSAGE_HANDLER_EX(DM_POINTERHITTEST, OnPointerHitTest) END_MSG_MAP() @@ -123,10 +121,6 @@ host_ = host; } - // DirectManipulation needs to poll for new events every frame while finger - // gesturing on touchpad. - void PollForNextEvent(); - // Return the root accessible object for either MSAA or UI Automation. gfx::NativeViewAccessible GetOrCreateWindowRootAccessible(); @@ -163,15 +157,10 @@ LRESULT OnSetCursor(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnNCCalcSize(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnSize(UINT message, WPARAM w_param, LPARAM l_param); - LRESULT OnWindowPosChanged(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnDestroy(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnPointerHitTest(UINT message, WPARAM w_param, LPARAM l_param); - void CreateAnimationObserver(); - - void DestroyAnimationObserver(); - Microsoft::WRL::ComPtr<IAccessible> window_accessible_; // Set to true if we turned on mouse tracking. @@ -190,9 +179,6 @@ // in Chrome on Windows 10. std::unique_ptr<DirectManipulationHelper> direct_manipulation_helper_; - std::unique_ptr<ui::CompositorAnimationObserver> - compositor_animation_observer_; - DISALLOW_COPY_AND_ASSIGN(LegacyRenderWidgetHostHWND); };
diff --git a/content/common/accessibility_messages.h b/content/common/accessibility_messages.h index 9344a5e..2ed10364 100644 --- a/content/common/accessibility_messages.h +++ b/content/common/accessibility_messages.h
@@ -76,6 +76,7 @@ IPC_STRUCT_TRAITS_MEMBER(loaded) IPC_STRUCT_TRAITS_MEMBER(loading_progress) IPC_STRUCT_TRAITS_MEMBER(focus_id) + IPC_STRUCT_TRAITS_MEMBER(sel_is_backward) IPC_STRUCT_TRAITS_MEMBER(sel_anchor_object_id) IPC_STRUCT_TRAITS_MEMBER(sel_anchor_offset) IPC_STRUCT_TRAITS_MEMBER(sel_anchor_affinity)
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index d74bbd0..9512126 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -100,6 +100,8 @@ "effective_connection_type_helper.h", "fetchers/associated_resource_fetcher_impl.cc", "fetchers/associated_resource_fetcher_impl.h", + "fetchers/manifest_fetcher.cc", + "fetchers/manifest_fetcher.h", "fetchers/multi_resolution_image_resource_fetcher.cc", "fetchers/multi_resolution_image_resource_fetcher.h", "fetchers/resource_fetcher_impl.cc",
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc index 1c0e46c..f26597e 100644 --- a/content/renderer/accessibility/blink_ax_tree_source.cc +++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <algorithm> #include <set> #include "base/memory/ptr_util.h" @@ -377,12 +378,14 @@ if (!focus().IsNull()) tree_data->focus_id = focus().AxID(); + bool is_selection_backward = false; WebAXObject anchor_object, focus_object; int anchor_offset, focus_offset; ax::mojom::TextAffinity anchor_affinity, focus_affinity; if (base::FeatureList::IsEnabled(features::kNewAccessibilitySelection)) { - root().Selection(anchor_object, anchor_offset, anchor_affinity, - focus_object, focus_offset, focus_affinity); + root().Selection(is_selection_backward, anchor_object, anchor_offset, + anchor_affinity, focus_object, focus_offset, + focus_affinity); } else { root().SelectionDeprecated(anchor_object, anchor_offset, anchor_affinity, focus_object, focus_offset, focus_affinity); @@ -391,6 +394,7 @@ focus_offset >= 0) { int32_t anchor_id = anchor_object.AxID(); int32_t focus_id = focus_object.AxID(); + tree_data->sel_is_backward = is_selection_backward; tree_data->sel_anchor_object_id = anchor_id; tree_data->sel_anchor_offset = anchor_offset; tree_data->sel_focus_object_id = focus_id;
diff --git a/content/renderer/fetchers/manifest_fetcher.cc b/content/renderer/fetchers/manifest_fetcher.cc new file mode 100644 index 0000000..8c45f2e --- /dev/null +++ b/content/renderer/fetchers/manifest_fetcher.cc
@@ -0,0 +1,59 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/fetchers/manifest_fetcher.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "content/public/renderer/associated_resource_fetcher.h" +#include "services/network/public/mojom/request_context_frame_type.mojom.h" +#include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/public/web/web_associated_url_loader_options.h" +#include "third_party/blink/public/web/web_local_frame.h" + +namespace content { + +ManifestFetcher::ManifestFetcher(const GURL& url) + : completed_(false) { + fetcher_.reset(AssociatedResourceFetcher::Create(url)); +} + +ManifestFetcher::~ManifestFetcher() { + if (!completed_) + Cancel(); +} + +void ManifestFetcher::Start(blink::WebLocalFrame* frame, + bool use_credentials, + const Callback& callback) { + callback_ = callback; + + blink::WebAssociatedURLLoaderOptions options; + fetcher_->SetLoaderOptions(options); + + // See https://w3c.github.io/manifest/. Use "include" when use_credentials is + // true, and "omit" otherwise. + fetcher_->Start( + frame, blink::mojom::RequestContextType::MANIFEST, + network::mojom::FetchRequestMode::kCors, + use_credentials ? network::mojom::FetchCredentialsMode::kInclude + : network::mojom::FetchCredentialsMode::kOmit, + base::Bind(&ManifestFetcher::OnLoadComplete, base::Unretained(this))); +} + +void ManifestFetcher::Cancel() { + DCHECK(!completed_); + fetcher_->Cancel(); +} + +void ManifestFetcher::OnLoadComplete(const blink::WebURLResponse& response, + const std::string& data) { + DCHECK(!completed_); + completed_ = true; + + Callback callback = callback_; + std::move(callback).Run(response, data); +} + +} // namespace content
diff --git a/content/renderer/fetchers/manifest_fetcher.h b/content/renderer/fetchers/manifest_fetcher.h new file mode 100644 index 0000000..ef48c184 --- /dev/null +++ b/content/renderer/fetchers/manifest_fetcher.h
@@ -0,0 +1,59 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_FETCHERS_MANIFEST_FETCHER_H_ +#define CONTENT_RENDERER_FETCHERS_MANIFEST_FETCHER_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "content/common/content_export.h" +#include "third_party/blink/public/platform/web_url_response.h" + +class GURL; + +namespace blink { +class WebLocalFrame; +} + +namespace content { + +class AssociatedResourceFetcher; + +// Helper class to download a Web Manifest. When an instance is created, the +// caller need to call Start() and wait for the passed callback to be executed. +// If the fetch fails, the callback will be called with two empty objects. +class CONTENT_EXPORT ManifestFetcher { + public: + // This will be called asynchronously after the URL has been fetched, + // successfully or not. If there is a failure, response and data will both be + // empty. |response| and |data| are both valid until the URLFetcher instance + // is destroyed. + typedef base::Callback<void(const blink::WebURLResponse& response, + const std::string& data)> Callback; + + explicit ManifestFetcher(const GURL& url); + virtual ~ManifestFetcher(); + + void Start(blink::WebLocalFrame* frame, + bool use_credentials, + const Callback& callback); + void Cancel(); + + private: + void OnLoadComplete(const blink::WebURLResponse& response, + const std::string& data); + + bool completed_; + Callback callback_; + std::unique_ptr<AssociatedResourceFetcher> fetcher_; + + DISALLOW_COPY_AND_ASSIGN(ManifestFetcher); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_FETCHERS_MANIFEST_FETCHER_H_
diff --git a/content/renderer/manifest/manifest_manager.cc b/content/renderer/manifest/manifest_manager.cc index 4cefec39..77b5333b 100644 --- a/content/renderer/manifest/manifest_manager.cc +++ b/content/renderer/manifest/manifest_manager.cc
@@ -10,6 +10,7 @@ #include "base/no_destructor.h" #include "base/strings/nullable_string16.h" #include "content/public/renderer/render_frame.h" +#include "content/renderer/fetchers/manifest_fetcher.h" #include "content/renderer/manifest/manifest_uma_util.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom.h" @@ -17,7 +18,6 @@ #include "third_party/blink/public/web/web_console_message.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" -#include "third_party/blink/public/web/web_manifest_fetcher.h" #include "third_party/blink/public/web/web_manifest_parser.h" namespace content { @@ -114,8 +114,7 @@ return; } - blink::WebDocument document = render_frame()->GetWebFrame()->GetDocument(); - manifest_url_ = document.ManifestURL(); + manifest_url_ = render_frame()->GetWebFrame()->GetDocument().ManifestURL(); if (manifest_url_.is_empty()) { ManifestUmaUtil::FetchFailed(ManifestUmaUtil::FETCH_EMPTY_URL); @@ -123,11 +122,13 @@ return; } - fetcher_.reset(new blink::WebManifestFetcher(manifest_url_)); - - fetcher_->Start(&document, document.ManifestUseCredentials(), - base::BindOnce(&ManifestManager::OnManifestFetchComplete, - base::Unretained(this), document.Url())); + fetcher_.reset(new ManifestFetcher(manifest_url_)); + fetcher_->Start( + render_frame()->GetWebFrame(), + render_frame()->GetWebFrame()->GetDocument().ManifestUseCredentials(), + base::Bind(&ManifestManager::OnManifestFetchComplete, + base::Unretained(this), + render_frame()->GetWebFrame()->GetDocument().Url())); } static const std::string& GetMessagePrefix() { @@ -138,9 +139,9 @@ void ManifestManager::OnManifestFetchComplete( const GURL& document_url, const blink::WebURLResponse& response, - const blink::WebString& data) { + const std::string& data) { fetcher_.reset(); - if (response.IsNull() && data.IsEmpty()) { + if (response.IsNull() && data.empty()) { manifest_debug_info_ = nullptr; ManifestUmaUtil::FetchFailed(ManifestUmaUtil::FETCH_UNSPECIFIED_REASON); ResolveCallbacks(ResolveStateFailure); @@ -149,15 +150,14 @@ ManifestUmaUtil::FetchSucceeded(); GURL response_url = response.CurrentRequestUrl(); - std::string data_string = data.Utf8(); - base::StringPiece data_piece(data_string); + base::StringPiece data_piece(data); blink::WebVector<blink::ManifestError> errors; bool result = blink::WebManifestParser::ParseManifest( data_piece, response_url, document_url, &manifest_, &errors); manifest_debug_info_ = blink::mojom::ManifestDebugInfo::New(); - manifest_debug_info_->raw_manifest = data_string; + manifest_debug_info_->raw_manifest = data; for (const auto& error : errors) { blink::WebConsoleMessage message;
diff --git a/content/renderer/manifest/manifest_manager.h b/content/renderer/manifest/manifest_manager.h index a1920c9..5836e41 100644 --- a/content/renderer/manifest/manifest_manager.h +++ b/content/renderer/manifest/manifest_manager.h
@@ -20,7 +20,6 @@ class GURL; namespace blink { -class WebManifestFetcher; class WebURLResponse; } @@ -72,10 +71,10 @@ void FetchManifest(); void OnManifestFetchComplete(const GURL& document_url, const blink::WebURLResponse& response, - const blink::WebString& data); + const std::string& data); void ResolveCallbacks(ResolveState state); - std::unique_ptr<blink::WebManifestFetcher> fetcher_; + std::unique_ptr<ManifestFetcher> fetcher_; // Whether the RenderFrame may have an associated Manifest. If true, the frame // may have a manifest, if false, it can't have one. This boolean is true when
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index fec6ca58..3027321 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -1018,7 +1018,7 @@ kGpuStreamIdDefault, kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, GURL(top_document_web_url), automatic_flushes, support_locking, support_grcontext, - gpu::SharedMemoryLimits(), attributes, + gpu::SharedMemoryLimits::ForWebGPUContext(), attributes, ws::command_buffer_metrics::ContextType::WEBGPU)); return std::make_unique<WebGraphicsContext3DProviderImpl>( std::move(provider));
diff --git a/content/renderer/skia_benchmarking_extension.cc b/content/renderer/skia_benchmarking_extension.cc index e125a2d..af81a67 100644 --- a/content/renderer/skia_benchmarking_extension.cc +++ b/content/renderer/skia_benchmarking_extension.cc
@@ -285,8 +285,9 @@ v8::Array::New(isolate, benchmarking_canvas.CommandCount()); for (size_t i = 0; i < benchmarking_canvas.CommandCount(); ++i) { op_times - ->Set(context, i, - v8::Number::New(isolate, benchmarking_canvas.GetTime(i))) + ->CreateDataProperty( + context, i, + v8::Number::New(isolate, benchmarking_canvas.GetTime(i))) .Check(); }
diff --git a/content/shell/test_runner/web_ax_object_proxy.cc b/content/shell/test_runner/web_ax_object_proxy.cc index 5298659f..0e03fabc 100644 --- a/content/shell/test_runner/web_ax_object_proxy.cc +++ b/content/shell/test_runner/web_ax_object_proxy.cc
@@ -656,6 +656,8 @@ .SetProperty("stepValue", &WebAXObjectProxy::StepValue) .SetProperty("valueDescription", &WebAXObjectProxy::ValueDescription) .SetProperty("childrenCount", &WebAXObjectProxy::ChildrenCount) + .SetProperty("selectionIsBackward", + &WebAXObjectProxy::SelectionIsBackward) .SetProperty("selectionAnchorObject", &WebAXObjectProxy::SelectionAnchorObject) .SetProperty("selectionAnchorOffset", @@ -946,17 +948,35 @@ return count; } -v8::Local<v8::Value> WebAXObjectProxy::SelectionAnchorObject() { +bool WebAXObjectProxy::SelectionIsBackward() { accessibility_object_.UpdateLayoutAndCheckValidity(); + bool is_selection_backward = false; blink::WebAXObject anchorObject; int anchorOffset = -1; ax::mojom::TextAffinity anchorAffinity; blink::WebAXObject focusObject; int focusOffset = -1; ax::mojom::TextAffinity focusAffinity; - accessibility_object_.Selection(anchorObject, anchorOffset, anchorAffinity, - focusObject, focusOffset, focusAffinity); + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); + return is_selection_backward; +} + +v8::Local<v8::Value> WebAXObjectProxy::SelectionAnchorObject() { + accessibility_object_.UpdateLayoutAndCheckValidity(); + + bool is_selection_backward = false; + blink::WebAXObject anchorObject; + int anchorOffset = -1; + ax::mojom::TextAffinity anchorAffinity; + blink::WebAXObject focusObject; + int focusOffset = -1; + ax::mojom::TextAffinity focusAffinity; + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); if (anchorObject.IsNull()) return v8::Null(blink::MainThreadIsolate()); @@ -966,14 +986,16 @@ int WebAXObjectProxy::SelectionAnchorOffset() { accessibility_object_.UpdateLayoutAndCheckValidity(); + bool is_selection_backward = false; blink::WebAXObject anchorObject; int anchorOffset = -1; ax::mojom::TextAffinity anchorAffinity; blink::WebAXObject focusObject; int focusOffset = -1; ax::mojom::TextAffinity focusAffinity; - accessibility_object_.Selection(anchorObject, anchorOffset, anchorAffinity, - focusObject, focusOffset, focusAffinity); + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); if (anchorOffset < 0) return -1; @@ -983,14 +1005,16 @@ std::string WebAXObjectProxy::SelectionAnchorAffinity() { accessibility_object_.UpdateLayoutAndCheckValidity(); + bool is_selection_backward = false; blink::WebAXObject anchorObject; int anchorOffset = -1; ax::mojom::TextAffinity anchorAffinity; blink::WebAXObject focusObject; int focusOffset = -1; ax::mojom::TextAffinity focusAffinity; - accessibility_object_.Selection(anchorObject, anchorOffset, anchorAffinity, - focusObject, focusOffset, focusAffinity); + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); return anchorAffinity == ax::mojom::TextAffinity::kUpstream ? "upstream" : "downstream"; } @@ -998,14 +1022,16 @@ v8::Local<v8::Value> WebAXObjectProxy::SelectionFocusObject() { accessibility_object_.UpdateLayoutAndCheckValidity(); + bool is_selection_backward = false; blink::WebAXObject anchorObject; int anchorOffset = -1; ax::mojom::TextAffinity anchorAffinity; blink::WebAXObject focusObject; int focusOffset = -1; ax::mojom::TextAffinity focusAffinity; - accessibility_object_.Selection(anchorObject, anchorOffset, anchorAffinity, - focusObject, focusOffset, focusAffinity); + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); if (focusObject.IsNull()) return v8::Null(blink::MainThreadIsolate()); @@ -1015,14 +1041,16 @@ int WebAXObjectProxy::SelectionFocusOffset() { accessibility_object_.UpdateLayoutAndCheckValidity(); + bool is_selection_backward = false; blink::WebAXObject anchorObject; int anchorOffset = -1; ax::mojom::TextAffinity anchorAffinity; blink::WebAXObject focusObject; int focusOffset = -1; ax::mojom::TextAffinity focusAffinity; - accessibility_object_.Selection(anchorObject, anchorOffset, anchorAffinity, - focusObject, focusOffset, focusAffinity); + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); if (focusOffset < 0) return -1; @@ -1032,14 +1060,16 @@ std::string WebAXObjectProxy::SelectionFocusAffinity() { accessibility_object_.UpdateLayoutAndCheckValidity(); + bool is_selection_backward = false; blink::WebAXObject anchorObject; int anchorOffset = -1; ax::mojom::TextAffinity anchorAffinity; blink::WebAXObject focusObject; int focusOffset = -1; ax::mojom::TextAffinity focusAffinity; - accessibility_object_.Selection(anchorObject, anchorOffset, anchorAffinity, - focusObject, focusOffset, focusAffinity); + accessibility_object_.Selection(is_selection_backward, anchorObject, + anchorOffset, anchorAffinity, focusObject, + focusOffset, focusAffinity); return focusAffinity == ax::mojom::TextAffinity::kUpstream ? "upstream" : "downstream"; }
diff --git a/content/shell/test_runner/web_ax_object_proxy.h b/content/shell/test_runner/web_ax_object_proxy.h index da30a01b..3348c58 100644 --- a/content/shell/test_runner/web_ax_object_proxy.h +++ b/content/shell/test_runner/web_ax_object_proxy.h
@@ -76,6 +76,7 @@ // The following selection functions return global information about the // current selection and can be called on any object in the tree. + bool SelectionIsBackward(); v8::Local<v8::Value> SelectionAnchorObject(); int SelectionAnchorOffset(); std::string SelectionAnchorAffinity();
diff --git a/content/test/gpu/gather_power_measurement_results.py b/content/test/gpu/gather_power_measurement_results.py index 44d7b1a..519fc68 100755 --- a/content/test/gpu/gather_power_measurement_results.py +++ b/content/test/gpu/gather_power_measurement_results.py
@@ -118,6 +118,7 @@ lines = data.splitlines() pattern = re.compile('^\[(\d+)/(\d+)\]$') results = None + bot_candidates = [] for line in lines: if results is not None: my_results = results @@ -139,16 +140,26 @@ elif line.startswith('Chrome Env: '): chrome_env = ast.literal_eval(line[len('Chrome Env: '):]) if 'COMPUTERNAME' in chrome_env: - entry['bot'] = chrome_env['COMPUTERNAME'] + bot_candidates.append(chrome_env['COMPUTERNAME']) elif line.startswith('INFO:root:Chrome Env: '): chrome_env = ast.literal_eval(line[len('INFO:root:Chrome Env: '):]) if 'COMPUTERNAME' in chrome_env: - entry['bot'] = chrome_env['COMPUTERNAME'] + bot_candidates.append(chrome_env['COMPUTERNAME']) + elif line.startswith('Env: '): + chrome_env = ast.literal_eval(line[len('Env: '):]) + if 'COMPUTERNAME' in chrome_env: + bot_candidates.append(chrome_env['COMPUTERNAME']) elif line.startswith(' COMPUTERNAME: '): - entry['bot'] = line.strip()[len('COMPUTERNAME: '):] + bot_candidates.append(line.strip()[len('COMPUTERNAME: '):]) elif line.startswith('Results: '): assert results is None results = ast.literal_eval(line[len('Results: '):]) + for name in bot_candidates: + if name.startswith('BUILD'): + entry['bot'] = name + break + else: + logging.warn('[BUILD %d] Fail to locate the bot name' % number) def CollectBuildData(build, data_entry):
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 48bc227..af810c9d 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -120,8 +120,6 @@ ['win', 'no_passthrough'], bug=3033) # angle bug ID self.Fail('conformance2/glsl3/tricky-loop-conditions.html', ['win'], bug=1465) # anglebug.com/1465 - self.Fail('conformance/textures/misc/texture-active-bind.html', - ['win'], bug=931006) # Win / NVidia self.Flaky('deqp/functional/gles3/fbomultisample*', @@ -1392,18 +1390,10 @@ self.Fail('conformance2/textures/video/' + 'tex-2d-rgba8ui-rgba_integer-unsigned_byte.html', ['android', 'qualcomm'], bug=906735) - self.Fail('conformance2/textures/misc/tex-new-formats.html', - ['android', 'qualcomm'], bug=906740) - self.Fail('conformance2/textures/misc/copy-texture-image-luma-format.html', - ['android', 'qualcomm'], bug=906740) # This test is failing on Android Pixel 2 and 3 (Qualcomm) # Seems to be an OpenGL ES bug. self.Fail('conformance2/rendering/vertex-id.html', ['android', 'qualcomm'], bug=945903) - self.Fail('deqp/functional/gles3/textureformat/unsized_2d_array.html', - ['android', 'qualcomm'], bug=906740) - self.Fail('deqp/functional/gles3/textureformat/unsized_3d.html', - ['android', 'qualcomm'], bug=906740) self.Fail('deqp/functional/gles3/shaderderivate_dfdy.html', ['android', 'qualcomm'], bug=906745) self.Flaky('deqp/functional/gles3/multisample.html',
diff --git a/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.csv b/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.csv index 206a203..cb370d0 100644 --- a/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.csv +++ b/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.csv
@@ -127,86 +127,86 @@ 0.5752608695652168,0.028234113712374536,3.7860000000000027,0.7194749163879598,0.718672240802676,0.11918729096989966,7.898334448160533,0.1195953177257526,7.776668896321074,0.7800802675585287,0.7235418060200668,0.12331438127090302,8.028535117056862,0.24157525083612028,8.092204013377927,BUILD125-A9,4004 0.5728862876254179,0.0378327759197324,2.5182274247491643,0.7275400000000001,0.7163812709030098,0.12215050167224081,5.453923076923076,0.12363666666666655,5.559556666666673,0.784923076923076,0.7299866220735789,0.13145150501672243,5.719056856187285,0.25047157190635455,5.775404682274247,BUILD133-A9,4003 0.5932073578595313,0.024598662207357833,3.6061003344481612,0.7247826086956517,0.718889632107023,0.140438127090301,6.623324414715718,0.1439163879598662,6.3651705685618705,0.7805752508361201,0.7344280936454851,0.152361204013378,6.899003344481609,0.26318060200668913,6.9050869565217425,BUILD147-A9,4002 -0.5737725752508361,0.030150501672240797,2.872792642140466,0.7187224080267561,0.7177424749163881,0.12533444816053507,5.542765886287626,0.12189297658862878,5.572204013377922,0.7852709030100331,0.7358394648829435,0.1318595317725753,5.684491638795985,0.24972575250836118,5.705953177257523,SWARM761-C4,4001 -0.5700200668896318,0.02394983277591971,3.273270903010033,0.7300200668896324,0.7192006688963207,0.12675919732441476,6.993692307692311,0.12455518394648829,6.917822742474914,0.7867892976588625,0.7245083612040136,0.1371973244147158,7.093695652173919,0.27090301003344497,7.147177257525083,SWARM761-C4,4000 -0.5741375838926172,0.02351342281879194,2.5692483221476525,0.7196287625418062,0.7349464882943149,0.09894648829431434,5.5296521739130435,0.09775919732441471,5.465822742474917,0.7810133779264207,0.7954882154882156,0.10468686868686869,7.647148148148149,0.20208361204013373,5.6527458193979925,SWARM761-C4,3999 -0.5772742474916389,0.008816053511705687,2.798759197324414,0.7176454849498326,0.7274782608695646,0.13828093645484943,6.051581939799331,0.13235451505016724,6.0693745819398,0.779183946488294,0.726501672240803,0.14813712374581933,6.35122073578595,0.2564949832775919,6.287622073578598,SWARM761-C4,3998 -0.5769966329966328,0.03242424242424239,2.5547239057239044,0.7277090301003343,0.7176655518394647,0.11656187290969901,5.189702341137124,0.1165819397993311,5.202237458193981,0.7802909698996652,0.7237658862876254,0.12438127090301014,5.381438127090299,0.23398996655518392,5.33338795986622,SWARM761-C4,3997 -0.5797959866220737,0.025040133779264173,3.6298862876254168,0.7176655518394647,0.7213244147157186,0.12470903010033434,6.865411371237459,0.1207056856187292,6.773598662207364,0.7931270903010028,0.7267859531772576,0.13173913043478255,6.850327759197326,0.24390301003344445,7.365020066889637,SWARM761-C4,3996 -0.5751170568561875,0.0279163879598662,3.01229431438127,0.7268327759197325,0.7188595317725756,0.10694983277591977,6.321357859531768,0.10729431438127096,6.272548494983277,0.7941371237458188,0.7284127516778522,0.11568791946308728,6.7030100671140955,0.23475919732441475,6.549926421404683,SWARM761-C4,3995 -0.5719966555183951,0.023816053511705647,3.0481839464882947,0.7228993288590606,0.7187725752508362,0.12845484949832778,6.2951103678929785,0.1312818791946309,6.463949664429528,0.7804749163879597,0.725464882943144,0.13783946488294324,6.206605351170567,0.2533545150501672,6.480859531772572,SWARM761-C4,3994 -0.5878461538461536,0.025354515050167194,3.5771036789297654,0.7266989966555187,0.725848993288591,0.12475838926174491,6.731359060402689,0.12955518394648824,6.260966555183948,0.7775150501672236,0.7168060200668896,0.13292642140468228,7.808695652173912,0.2540702341137124,7.797739130434791,SWARM761-C4,3993 -0.5830233333333332,0.00933,2.383490000000001,0.7336555183946492,0.7235652173913049,0.1292541806020068,5.132230769230772,0.12777926421404687,5.02438127090301,0.8023879598662204,0.7293244147157191,0.13685284280936452,5.2357558528428045,0.2505016722408026,5.428852842809364,SWARM761-C4,3992 -0.5830936454849504,0.029294314381270857,4.162518394648829,0.715334448160535,0.7247324414715725,0.11882943143812716,7.751080267558524,0.12002006688963217,7.8378193979933055,0.7805016722408025,0.7217190635451505,0.13004347826086962,7.8579832775919725,0.24649498327759212,7.9921939799331065,SWARM761-C4,3991 -0.571341137123746,0.026197324414715697,2.394046822742474,0.7206923076923076,0.7298628762541802,0.13220066889632112,5.481896321070235,0.13425083612040137,5.246896321070233,0.7806588628762541,0.7261409395973155,0.14293288590604028,5.48185570469799,0.26045150501672243,5.430408026755849,SWARM761-C4,3990 -0.5731906354515054,0.025468227424749135,2.962234113712376,0.7243745819397991,0.7190602006688964,0.11862876254180602,6.106240802675584,0.12156521739130433,6.137625418060202,0.7798260869565221,0.7316120401337787,0.1265953177257526,6.023331103678928,0.23920735785953162,6.218662207357857,SWARM761-C4,3989 -0.5778996655518394,0.0085685618729097,2.8353545150501684,0.7179030100334444,0.7175953177257526,0.11557859531772578,5.916528428093644,0.11364548494983279,5.802494983277595,0.7897056856187293,0.7224782608695652,0.12314715719063547,5.788006688963207,0.2642073578595318,6.330133779264214,SWARM761-C4,3988 -0.569367892976589,0.026207357859531755,3.0752909698996644,0.7168361204013375,0.7145418060200662,0.1273846153846154,7.008060200668897,0.13000668896321071,6.847876254180603,0.7772408026755855,0.7265117056856191,0.13559866220735786,7.034103678929761,0.2513277591973243,7.161434782608697,SWARM761-C4,3987 -0.5704194630872486,0.0317181208053691,2.5595369127516783,0.7200969899665558,0.7234949832775925,0.14043478260869569,5.3492040133779275,0.14318394648829433,5.255555183946487,0.8063344481605352,0.7339030100334446,0.14436454849498329,5.2371471571906385,0.27155518394648825,5.572137123745825,SWARM761-C4,3986 -0.5750635451505021,0.025729096989966536,2.656103678929765,0.7238394648829427,0.7205819397993309,0.12108361204013375,5.535635451505015,0.12225752508361201,5.445695652173916,0.7956199999999991,0.737836120401338,0.1299030100334448,5.338969899665548,0.23949666666666686,5.515420000000001,SWARM761-C4,3985 -0.5726677852348995,0.029503355704697976,3.0893758389261743,0.7187625418060208,0.7190301003344484,0.12803678929765894,6.9882775919732465,0.1282107023411371,6.9719832775919715,0.7779464882943141,0.7248657718120795,0.1331442953020134,7.283278523489931,0.24979933110367888,7.119351170568563,SWARM761-C4,3984 -0.5838233333333331,0.009076666666666667,5.471726666666671,0.7201137123745815,0.7287056856187292,0.11536789297658868,9.008464882943144,0.11412040133779276,9.12337123745819,0.7902675585284276,0.7263143812709028,0.12333110367892972,8.831668896321075,0.24242809364548487,9.020381270903012,SWARM761-C4,3983 -0.5823478260869562,0.025063545150501635,3.427000000000001,0.7304766666666661,0.7374448160535126,0.1571906354515051,6.492956521739126,0.13785999999999993,6.582673333333332,0.7986989966555178,0.7323478260869568,0.14121739130434788,6.1969698996655485,0.2635953177257524,6.329742474916388,SWARM761-C4,3982 -0.5521739130434787,0.009682274247491638,4.952260869565218,0.6794481605351173,0.673304347826087,0.1347692307692308,8.050598662207355,0.13612709030100337,7.898254180602011,0.743665551839465,0.683612040133779,0.14267558528428093,8.338658862876246,0.2841638795986622,8.337100334448156,SWARM761-C4,3981 -0.5759464882943147,0.027535117056856143,3.0257458193979914,0.7240100334448165,0.722227424749164,0.13526086956521752,6.157772575250841,0.1373745819397993,6.260173913043477,0.7798963210702337,0.7268494983277592,0.1557959866220736,6.213709030100337,0.2704916387959868,6.265080267558525,SWARM761-C4,3980 -0.5710066889632107,0.023173913043478222,2.6294782608695675,0.7163210702341137,0.7188959731543625,0.11605369127516785,5.4151778523489975,0.11643478260869565,5.282551839464882,0.7851036789297657,0.737852842809364,0.12473913043478262,5.235588628762537,0.23394648829431425,5.447013377926418,SWARM761-C4,3978 -0.5751538461538465,0.03138127090301001,2.7357558528428116,0.7180301003344485,0.717953177257525,0.137876254180602,5.9149832775919755,0.1413444816053511,5.899234113712378,0.7942140468227425,0.7343779264214042,0.1448060200668897,6.324090301003342,0.28602675585284293,6.248016722408029,SWARM761-C4,3977 -0.572558528428094,0.020548494983277557,3.2146053511705697,0.721993311036789,0.749443333333333,0.15047999999999995,7.005676666666665,0.1341872909698997,6.434103678929768,0.7835819397993307,0.721170568561873,0.1378428093645486,6.390190635451501,0.25918394648829435,6.62716722408027,SWARM761-C4,3976 -0.5702140468227427,0.009093645484949835,2.8254849498327754,0.7222374581939804,0.7250100334448158,0.1266254180602007,6.013411371237458,0.12878260869565214,5.855755852842811,0.7795986622073574,0.7307458193979932,0.13245819397993297,5.703347826086954,0.2538428093645485,5.830668896321071,SWARM761-C4,3975 -0.5771140939597315,0.03104026845637579,3.5493322147651,0.7223578595317727,0.7154147157190637,0.13121070234113716,6.4363076923076905,0.1325150501672241,6.828829431438129,0.7906822742474914,0.7296521739130437,0.14254849498327762,6.5379765886287595,0.2692040133779266,6.644321070234113,SWARM761-C4,3974 -0.6290201342281877,0.026822147651006673,3.901197986577183,0.7515752508361206,0.7170033444816056,0.10493645484949837,5.370040133779265,0.10287625418060209,7.60757190635451,0.7894046822742471,0.734672240802676,0.11079598662207349,5.679284280936457,0.21772909698996665,5.540842809364551,SWARM761-C4,3973 -0.5706655518394653,0.02932107023411369,3.0259665551839467,0.7402040133779271,0.7193745819397993,0.1267658862876254,6.64846488294314,0.13069230769230772,6.6243444816053465,0.780013377926421,0.7235083612040129,0.13413712374581943,6.647290969899667,0.2605585284280937,6.622826086956524,SWARM761-C4,3972 -0.5787826086956526,0.02671571906354511,2.944177257525083,0.721702341137124,0.7284682274247489,0.13489632107023414,6.077110367892977,0.1343745819397993,5.958143812709028,0.7805384615384607,0.7253311036789292,0.14179598662207357,5.862247491638797,0.2510401337792643,6.023280936454848,SWARM761-C4,3971 -0.5749664429530201,0.028077181208053664,2.682365771812082,0.7204347826086962,0.718274247491639,0.12512040133779273,5.4335484949832775,0.12389632107023411,5.546160535117058,0.7896421404682272,0.7255953177257525,0.1343946488294313,5.502384615384617,0.24891638795986618,5.568404682274251,SWARM761-C4,3970 -0.6355622895622897,0.03125252525252522,5.38030976430977,0.7253511705685615,0.7200606060606062,0.14185185185185178,6.282370370370367,0.14837458193979944,6.049933110367893,0.7777926421404682,0.7219030100334449,0.1461538461538461,6.157785953177257,0.2774147157190638,6.049508361204013,SWARM761-C4,3969 -0.577201342281879,0.03044630872483218,3.225969798657719,0.7200836120401335,0.7182742474916388,0.1312240802675585,6.153157190635448,0.12962207357859534,6.179137123745823,0.7876755852842807,0.7365083612040136,0.1362274247491638,6.122193979933114,0.2837759197324414,6.238096989966556,SWARM761-C4,3968 -0.5746755852842814,0.03218060200668893,2.9621538461538464,0.7185852842809366,0.7279632107023416,0.14631772575250832,6.487347826086962,0.14790301003344472,6.501882943143808,0.782294314381271,0.7251705685618725,0.15442140468227405,6.759882943143812,0.28450167224080275,6.735247491638796,SWARM761-C4,3967 -0.576217391304348,0.028444816053511686,2.5558963210702332,0.7170234113712376,0.7235919732441473,0.12115050167224087,5.602127090301007,0.12305685618729094,5.256190635451506,0.7828026755852845,0.7312341137123752,0.13125083612040128,5.518545150501667,0.2390367892976589,5.741123745819395,SWARM761-C4,3966 -0.5774228187919461,0.030708053691275137,2.697322147651008,0.7198394648829428,0.7237859531772576,0.09628762541806019,5.616030100334449,0.09859531772575254,5.623675585284281,0.7806321070234109,0.7251739130434784,0.10263879598662208,5.843872909698996,0.21496989966555188,5.957207357859533,SWARM761-C4,3965 -0.5759865771812078,0.036758389261744955,2.9319395973154356,0.7191003344481606,0.7192474916387955,0.14573578595317732,6.150274247491638,0.14988628762541822,6.08908695652174,0.779183946488294,0.7245484949832773,0.15834113712374584,6.401093645484949,0.28313377926421424,6.34434448160535,SWARM761-C4,3964 -0.5715785953177267,0.02948829431438124,2.569963210702343,0.7215150501672238,0.7117692307692307,0.14139464882943142,5.419297658862877,0.14605685618729103,5.411150501672242,0.7735250836120403,0.7209063545150497,0.15194983277591967,5.808812709030099,0.30766220735785954,5.701397993311034,SWARM761-C4,3963 -0.5768053691275166,0.026983221476510045,2.8690637583892604,0.7199498327759198,0.7162107023411376,0.10800334448160533,6.07056856187291,0.10929096989966552,5.998632107023413,0.7792274247491636,0.7225986622073576,0.1172006688963211,6.222327759197326,0.23226086956521733,6.21909364548495,SWARM761-C4,3962 -0.5704515050167226,0.004779264214046822,2.338668896321069,0.7290033444816054,0.7318394648829433,0.14307692307692305,5.60170568561873,0.14644481605351176,5.401070234113713,0.7798093645484946,0.7227257525083608,0.15390635451505028,5.593735785953175,0.2700602006688964,5.70205685618729,SWARM761-C4,3961 -0.5752742474916388,0.02985953177257523,3.652354515050168,0.722943143812709,0.719023411371238,0.11531103678929765,7.291615384615382,0.12005351170568579,7.3373678929765935,0.7779665551839458,0.7331040268456375,0.12381879194630867,8.060932885906047,0.24406688963210682,7.599769230769228,SWARM761-C4,3960 -0.5758628762541809,0.027698996655518334,3.0467725752508397,0.7240936454849499,0.7245685618729095,0.13715050167224088,5.992073578595318,0.13655852842809355,6.053441471571905,0.7777525083612038,0.7208260869565218,0.1453177257525084,6.1641438127090336,0.29341471571906375,6.183474916387964,SWARM761-C4,3959 -0.5716555183946486,0.013963210702341133,2.839137123745821,0.7176789297658863,0.7265752508361205,0.11275250836120411,6.166715719063547,0.11633110367892972,6.139591973244149,0.7850969899665547,0.7252408026755854,0.12110702341137125,6.688812709030095,0.23491638795986602,6.810224080267557,SWARM761-C4,3958 -0.5757550335570469,0.02671140939597311,3.0432315436241586,0.7180769230769226,0.7198561872909698,0.1518060200668896,6.77678929765886,0.15486956521739126,6.729003344481602,0.7791137123745819,0.7228428093645481,0.16300668896321063,6.807421404682276,0.294916387959866,6.971638795986624,SWARM761-C4,3957 -0.5803478260869562,0.027842809364548457,2.9640668896321087,0.7304347826086953,0.7179197324414713,0.10790969899665559,5.2156755852842815,0.0943913043478261,5.37356856187291,0.7793010033444817,0.7231204013377925,0.0979799331103679,5.293692307692307,0.19817056856187312,5.409314381270905,SWARM761-C4,3956 -0.5694766666666676,0.008683333333333331,2.6936533333333332,0.7262508361204014,0.7232842809364546,0.11707692307692308,6.631260869565214,0.11854515050167219,6.155856187290972,0.7816454849498329,0.7238026755852843,0.11863879598662207,6.392317725752511,0.23702341137123734,6.520341137123745,SWARM761-C4,3955 -0.574548494983278,0.022100334448160508,2.9308862876254222,0.718775919732442,0.7291204013377932,0.11472909698996649,6.1612207357859585,0.11296321070234122,6.402655518394644,0.7811571906354514,0.7315518394648833,0.12202006688963218,6.352224080267561,0.23767892976588612,6.365571906354518,SWARM761-C4,3954 -0.5709966555183953,0.02598996655518391,2.7516488294314385,0.7156387959866222,0.7175886287625423,0.1410903010033445,5.928197324414717,0.14296321070234097,5.96597658862876,0.7782307692307686,0.7218333333333334,0.14581666666666654,6.166476666666667,0.2758428093645488,6.127250836120403,SWARM761-C4,3953 -0.5881610738255031,0.04199664429530199,4.4503892617449665,0.7186387959866223,0.7201270903010033,0.16627759197324407,7.1302541806020034,0.16565217391304357,7.281110367892972,0.7953545150501673,0.7299866220735796,0.17521739130434777,7.093471571906351,0.34571237458193943,7.410267558528427,SWARM761-C4,3952 -0.5749597315436243,0.02822818791946305,3.3186006711409375,0.7248127090301002,0.7279464882943137,0.12283277591973253,6.584060200668893,0.12557190635451507,6.747956521739128,0.7836387959866216,0.7240869565217387,0.12625083612040133,6.698882943143808,0.24532441471571917,6.740371237458191,SWARM761-C4,3950 -0.575371237458194,0.03710033444816051,2.878438127090303,0.7132107023411373,0.7228829431438122,0.13410702341137115,6.200508361204016,0.13815384615384624,6.081260869565215,0.774755852842809,0.7291610738255043,0.15064765100671137,6.369453020134225,0.3058829431438127,6.344110367892976,SWARM761-C4,3949 -0.5724228187919461,0.027265100671140914,2.9698020134228207,0.714826666666666,0.7204481605351177,0.13995317725752507,6.2426488294314355,0.13393999999999995,6.064716666666666,0.7910301003344489,0.7317751677852352,0.1510973154362415,6.3687248322147685,0.2915852842809366,6.334889632107021,SWARM761-C4,3948 -0.5734566666666668,0.015013333333333332,3.440013333333335,0.7182240802675586,0.7190468227424744,0.12867892976588632,6.937060200668899,0.13136789297658866,7.148541806020069,0.7881003344481601,0.7240334448160537,0.13621739130434793,7.038762541806021,0.2504648829431438,7.169210702341139,SWARM761-C4,3947 -0.57447491638796,0.026424749163879574,2.9051471571906378,0.7233846153846155,0.716030100334448,0.13744481605351178,6.250474916387961,0.14111705685618733,6.210290969899667,0.7789698996655517,0.7261174496644296,0.14960738255033562,6.679946308724833,0.27532775919732455,6.440294314381269,SWARM761-C4,3946 -0.5732909698996652,0.01372240802675585,2.580137123745821,0.7191605351170569,0.718361204013378,0.1116789297658863,5.136545150501671,0.11453511705685619,5.16003678929766,0.7866889632107019,0.7243478260869568,0.12128762541806022,5.217137123745819,0.22709030100334435,5.278638795986625,SWARM761-C4,3945 -0.5691778523489935,0.031157718120805335,2.4849563758389266,0.7168193979933111,0.7227859531772577,0.126571906354515,5.277234113712377,0.1268795986622074,5.2109297658862905,0.7897290969899662,0.7332809364548489,0.13152173913043488,5.341391304347826,0.24585953177257525,5.706842809364547,SWARM761-C4,3944 -0.6153712374581942,0.01428428093645485,3.719795986622075,0.7489531772575254,0.7196521739130437,0.12077926421404682,5.451635451505016,0.11850501672240815,6.606157190635451,0.7777926421404683,0.7345685618729093,0.12581605351170566,5.552277591973241,0.23914715719063528,5.621130434782607,SWARM761-C4,3943 -0.5787324414715715,0.008414715719063545,2.583739130434783,0.7267391304347823,0.7169397993311034,0.11436789297658864,5.122732441471573,0.11625752508361215,5.303264214046824,0.7878695652173908,0.7249464882943146,0.12842140468227403,5.194023411371235,0.230458193979933,5.329648829431438,SWARM761-C4,3942 -0.5808193979933111,0.03350836120401335,2.6704481605351154,0.7188327759197319,0.7249598662207358,0.11968561872909704,5.431969899665549,0.11832775919732447,5.109163879598663,0.7884448160535117,0.7237090301003339,0.12432441471571908,5.360618729096989,0.25609030100334457,5.36935117056856,SWARM761-C4,3941 -0.574521739130435,0.029555183946488234,2.848046822742476,0.7199531772575254,0.7295819397993318,0.11516053511705686,6.743143812709031,0.11270903010033445,6.481354515050172,0.7785886287625418,0.724839464882943,0.12243478260869561,6.550826086956522,0.23760869565217357,6.614779264214045,SWARM761-C4,3940 -0.5739464882943142,0.027578595317725725,2.6171036789297673,0.7193311036789303,0.7194548494983283,0.11300000000000007,5.107367892976584,0.11443143812709039,5.11719063545151,0.7838428093645485,0.7306733333333334,0.11910333333333337,5.496940000000003,0.2266755852842809,5.329535117056859,SWARM761-C4,3939 -0.5754581939799334,0.020842809364548482,2.549575250836122,0.7221237458193975,0.7345986622073574,0.09451505016722404,5.479702341137122,0.09562876254180605,5.267518394648832,0.7792374581939796,0.7249799331103677,0.10226086956521745,5.141418060200667,0.20433110367892968,5.222692307692307,SWARM761-C4,3938 -0.5750100000000005,0.009996666666666668,3.086056666666669,0.7236086956521741,0.7253712374581944,0.12707357859531773,5.929913043478258,0.13067558528428105,5.950270903010037,0.7950735785953177,0.7301705685618731,0.13850167224080265,5.941481605351171,0.24743812709030089,6.098946488294315,SWARM761-C4,3937 -0.5740602006688966,0.023240802675585245,2.733501672240804,0.7198595317725752,0.7197157190635455,0.12111705685618739,5.5181070234113685,0.12225083612040143,5.550618729096993,0.7797725752508357,0.7396488294314386,0.12805016722408027,5.505110367892976,0.23715050167224058,5.576153846153849,SWARM761-C4,3936 -0.5748724832214769,0.036087248322147616,3.095946308724834,0.7178394648829431,0.7167424749163883,0.13453846153846152,6.8643745819398,0.1353110367892976,6.833725752508358,0.777538461538461,0.721401337792642,0.14866220735785948,7.136227424749166,0.2787759197324416,6.961277591973247,SWARM761-C4,3935 -0.5765317725752507,0.03670903010033443,2.8997926421404703,0.7162709030100335,0.7175117056856187,0.14148160535117055,6.134498327759198,0.13748160535117063,6.1754046822742445,0.7783277591973243,0.7310969899665549,0.15195317725752516,6.402923076923078,0.28137458193979964,6.353698996655516,SWARM761-C4,3934 -0.584655518394649,0.009100334448160536,4.376494983277592,0.7250334448160537,0.7227692307692313,0.13601003344481605,7.695916387959864,0.13640802675585276,7.609023411371235,0.7923678929765879,0.7411471571906355,0.14424414715719072,7.950511705685625,0.25483277591973236,8.0006889632107,SWARM761-C4,3933 -0.5807348993288584,0.025318791946308684,2.6897751677852364,0.7190668896321072,0.7178762541806021,0.11560869565217398,5.270545150501672,0.1094548494983278,5.168267558528428,0.7902651006711412,0.7260100334448166,0.12104347826086971,5.370755852842809,0.2378187919463085,5.578224832214766,SWARM761-C4,3932 -0.5774113712374584,0.042050167224080254,2.6277424749163876,0.7204414715719061,0.7121270903010033,0.1452642140468227,5.637217391304347,0.14780602006688964,5.491254180602009,0.7730836120401332,0.7263076923076921,0.16376588628762548,5.916140468227428,0.3380836120401338,5.758020066889626,SWARM761-C4,3931 -0.5781375838926172,0.03122483221476507,2.9609664429530187,0.7217458193979939,0.7205284280936451,0.11927759197324406,5.839842809364545,0.11865217391304352,5.873210702341136,0.7955652173913045,0.7262976588628756,0.12223745819397994,5.831240802675589,0.24547826086956512,6.092137123745817,SWARM761-C4,3930 -0.5750869565217391,0.02844481605351168,2.482357859531773,0.7334715719063547,0.7194280936454851,0.13139799331103674,5.259966555183941,0.1366755852842809,5.262207357859528,0.7797959866220733,0.7266889632107029,0.14006354515050176,5.503187290969905,0.26532441471571927,5.513321070234116,SWARM761-C4,3929 -0.5746789297658864,0.021575250836120368,2.3915752508361208,0.721842809364548,0.7203745819397994,0.08385618729096996,5.044956521739134,0.0875117056856188,5.06289966555184,0.7904949832775919,0.7281371237458192,0.09017056856187294,5.341331103678936,0.226257525083612,5.38454180602007,SWARM761-C4,3928 -0.5736174496644303,0.030187919463087215,3.6837281879194617,0.7215484949832781,0.6901304347826083,0.1064816053511706,6.131588628762536,0.10820735785953177,7.442615384615385,0.7841337792642142,0.7486856187290972,0.11374247491638793,8.119117056856192,0.24284949832775918,7.840364548494984,SWARM761-C4,3927 -0.5731677852348995,0.033291946308724805,2.522322147651006,0.7194749163879592,0.7276521739130436,0.10267558528428103,5.116133779264213,0.1035551839464883,5.132458193979931,0.7810301003344481,0.7270234113712379,0.10844147157190645,5.295374581939799,0.21746153846153846,5.40732441471572,SWARM761-C4,3926 -0.5767449664429534,0.030604026845637552,2.5929328859060394,0.7274381270903013,0.7207826086956522,0.08611705685618734,5.52629431438127,0.08887959866220735,5.531130434782605,0.7790535117056855,0.7371170568561869,0.09586287625418066,5.705351170568563,0.20651839464882946,5.890705685618732,SWARM761-C4,3925 -0.5721538461538462,0.025632107023411333,2.8410434782608704,0.735889632107024,0.7223846153846152,0.12678595317725747,6.143401337792643,0.13158528428093647,5.874698996655517,0.8451107382550331,0.7266354515050167,0.1354782608695651,6.20066220735786,0.25717449664429526,8.501090604026855,SWARM761-C4,3924 -0.5713645484949832,0.014377926421404673,3.018919732441472,0.7315585284280933,0.719809364548495,0.11922408026755849,6.397147157190638,0.11393645484949835,6.3150267558528395,0.7963221476510065,0.7268026755852846,0.1261103678929765,6.716200668896324,0.273553691275168,7.242073825503357,SWARM761-C4,3923 -0.5729362416107382,0.029453020134228163,2.9319127516778507,0.7225551839464884,0.7256555183946486,0.11894648829431437,5.6302274247491635,0.11848829431438124,5.788408026755855,0.7810969899665551,0.7290501672240801,0.1291571906354516,5.626351170568564,0.25159531772575244,5.850003344481604,SWARM761-C4,3922 -0.5758428093645483,0.03633444816053507,2.631418060200669,0.7201806020066885,0.7199464882943144,0.1220033444816054,5.266183946488291,0.12759866220735794,5.243414715719068,0.7790434782608694,0.7255785953177253,0.1292307692307692,5.5810635451505,0.25682608695652165,5.589692307692307,SWARM761-C4,3921 -0.5707684563758393,0.03206711409395971,3.0611812080536915,0.7184648829431434,0.7158795986622074,0.13064882943143824,5.957739130434781,0.13187625418060198,5.9663745819397995,0.8540402684563759,0.7217290969899668,0.1427090301003344,6.001749163879603,0.29916442953020167,8.81292281879195,SWARM761-C4,3920 +0.5737725752508361,0.030150501672240797,2.872792642140466,0.7187224080267561,0.7177424749163881,0.12533444816053507,5.542765886287626,0.12189297658862878,5.572204013377922,0.7852709030100331,0.7358394648829435,0.1318595317725753,5.684491638795985,0.24972575250836118,5.705953177257523,BUILD170-A9,4001 +0.5700200668896318,0.02394983277591971,3.273270903010033,0.7300200668896324,0.7192006688963207,0.12675919732441476,6.993692307692311,0.12455518394648829,6.917822742474914,0.7867892976588625,0.7245083612040136,0.1371973244147158,7.093695652173919,0.27090301003344497,7.147177257525083,BUILD130-A9,4000 +0.5741375838926172,0.02351342281879194,2.5692483221476525,0.7196287625418062,0.7349464882943149,0.09894648829431434,5.5296521739130435,0.09775919732441471,5.465822742474917,0.7810133779264207,0.7954882154882156,0.10468686868686869,7.647148148148149,0.20208361204013373,5.6527458193979925,BUILD182-A9,3999 +0.5772742474916389,0.008816053511705687,2.798759197324414,0.7176454849498326,0.7274782608695646,0.13828093645484943,6.051581939799331,0.13235451505016724,6.0693745819398,0.779183946488294,0.726501672240803,0.14813712374581933,6.35122073578595,0.2564949832775919,6.287622073578598,BUILD168-A9,3998 +0.5769966329966328,0.03242424242424239,2.5547239057239044,0.7277090301003343,0.7176655518394647,0.11656187290969901,5.189702341137124,0.1165819397993311,5.202237458193981,0.7802909698996652,0.7237658862876254,0.12438127090301014,5.381438127090299,0.23398996655518392,5.33338795986622,BUILD138-A9,3997 +0.5797959866220737,0.025040133779264173,3.6298862876254168,0.7176655518394647,0.7213244147157186,0.12470903010033434,6.865411371237459,0.1207056856187292,6.773598662207364,0.7931270903010028,0.7267859531772576,0.13173913043478255,6.850327759197326,0.24390301003344445,7.365020066889637,BUILD177-A9,3996 +0.5751170568561875,0.0279163879598662,3.01229431438127,0.7268327759197325,0.7188595317725756,0.10694983277591977,6.321357859531768,0.10729431438127096,6.272548494983277,0.7941371237458188,0.7284127516778522,0.11568791946308728,6.7030100671140955,0.23475919732441475,6.549926421404683,BUILD175-A9,3995 +0.5719966555183951,0.023816053511705647,3.0481839464882947,0.7228993288590606,0.7187725752508362,0.12845484949832778,6.2951103678929785,0.1312818791946309,6.463949664429528,0.7804749163879597,0.725464882943144,0.13783946488294324,6.206605351170567,0.2533545150501672,6.480859531772572,BUILD168-A9,3994 +0.5878461538461536,0.025354515050167194,3.5771036789297654,0.7266989966555187,0.725848993288591,0.12475838926174491,6.731359060402689,0.12955518394648824,6.260966555183948,0.7775150501672236,0.7168060200668896,0.13292642140468228,7.808695652173912,0.2540702341137124,7.797739130434791,BUILD21-B1,3993 +0.5830233333333332,0.00933,2.383490000000001,0.7336555183946492,0.7235652173913049,0.1292541806020068,5.132230769230772,0.12777926421404687,5.02438127090301,0.8023879598662204,0.7293244147157191,0.13685284280936452,5.2357558528428045,0.2505016722408026,5.428852842809364,BUILD161-A9,3992 +0.5830936454849504,0.029294314381270857,4.162518394648829,0.715334448160535,0.7247324414715725,0.11882943143812716,7.751080267558524,0.12002006688963217,7.8378193979933055,0.7805016722408025,0.7217190635451505,0.13004347826086962,7.8579832775919725,0.24649498327759212,7.9921939799331065,BUILD125-A9,3991 +0.571341137123746,0.026197324414715697,2.394046822742474,0.7206923076923076,0.7298628762541802,0.13220066889632112,5.481896321070235,0.13425083612040137,5.246896321070233,0.7806588628762541,0.7261409395973155,0.14293288590604028,5.48185570469799,0.26045150501672243,5.430408026755849,BUILD162-A9,3990 +0.5731906354515054,0.025468227424749135,2.962234113712376,0.7243745819397991,0.7190602006688964,0.11862876254180602,6.106240802675584,0.12156521739130433,6.137625418060202,0.7798260869565221,0.7316120401337787,0.1265953177257526,6.023331103678928,0.23920735785953162,6.218662207357857,BUILD126-A9,3989 +0.5778996655518394,0.0085685618729097,2.8353545150501684,0.7179030100334444,0.7175953177257526,0.11557859531772578,5.916528428093644,0.11364548494983279,5.802494983277595,0.7897056856187293,0.7224782608695652,0.12314715719063547,5.788006688963207,0.2642073578595318,6.330133779264214,BUILD118-A9,3988 +0.569367892976589,0.026207357859531755,3.0752909698996644,0.7168361204013375,0.7145418060200662,0.1273846153846154,7.008060200668897,0.13000668896321071,6.847876254180603,0.7772408026755855,0.7265117056856191,0.13559866220735786,7.034103678929761,0.2513277591973243,7.161434782608697,BUILD137-A9,3987 +0.5704194630872486,0.0317181208053691,2.5595369127516783,0.7200969899665558,0.7234949832775925,0.14043478260869569,5.3492040133779275,0.14318394648829433,5.255555183946487,0.8063344481605352,0.7339030100334446,0.14436454849498329,5.2371471571906385,0.27155518394648825,5.572137123745825,BUILD162-A9,3986 +0.5750635451505021,0.025729096989966536,2.656103678929765,0.7238394648829427,0.7205819397993309,0.12108361204013375,5.535635451505015,0.12225752508361201,5.445695652173916,0.7956199999999991,0.737836120401338,0.1299030100334448,5.338969899665548,0.23949666666666686,5.515420000000001,BUILD143-A9,3985 +0.5726677852348995,0.029503355704697976,3.0893758389261743,0.7187625418060208,0.7190301003344484,0.12803678929765894,6.9882775919732465,0.1282107023411371,6.9719832775919715,0.7779464882943141,0.7248657718120795,0.1331442953020134,7.283278523489931,0.24979933110367888,7.119351170568563,BUILD137-A9,3984 +0.5838233333333331,0.009076666666666667,5.471726666666671,0.7201137123745815,0.7287056856187292,0.11536789297658868,9.008464882943144,0.11412040133779276,9.12337123745819,0.7902675585284276,0.7263143812709028,0.12333110367892972,8.831668896321075,0.24242809364548487,9.020381270903012,BUILD125-A9,3983 +0.5823478260869562,0.025063545150501635,3.427000000000001,0.7304766666666661,0.7374448160535126,0.1571906354515051,6.492956521739126,0.13785999999999993,6.582673333333332,0.7986989966555178,0.7323478260869568,0.14121739130434788,6.1969698996655485,0.2635953177257524,6.329742474916388,BUILD120-A9,3982 +0.5521739130434787,0.009682274247491638,4.952260869565218,0.6794481605351173,0.673304347826087,0.1347692307692308,8.050598662207355,0.13612709030100337,7.898254180602011,0.743665551839465,0.683612040133779,0.14267558528428093,8.338658862876246,0.2841638795986622,8.337100334448156,BUILD149-A9,3981 +0.5759464882943147,0.027535117056856143,3.0257458193979914,0.7240100334448165,0.722227424749164,0.13526086956521752,6.157772575250841,0.1373745819397993,6.260173913043477,0.7798963210702337,0.7268494983277592,0.1557959866220736,6.213709030100337,0.2704916387959868,6.265080267558525,BUILD120-A9,3980 +0.5710066889632107,0.023173913043478222,2.6294782608695675,0.7163210702341137,0.7188959731543625,0.11605369127516785,5.4151778523489975,0.11643478260869565,5.282551839464882,0.7851036789297657,0.737852842809364,0.12473913043478262,5.235588628762537,0.23394648829431425,5.447013377926418,BUILD138-A9,3978 +0.5751538461538465,0.03138127090301001,2.7357558528428116,0.7180301003344485,0.717953177257525,0.137876254180602,5.9149832775919755,0.1413444816053511,5.899234113712378,0.7942140468227425,0.7343779264214042,0.1448060200668897,6.324090301003342,0.28602675585284293,6.248016722408029,BUILD166-A9,3977 +0.572558528428094,0.020548494983277557,3.2146053511705697,0.721993311036789,0.749443333333333,0.15047999999999995,7.005676666666665,0.1341872909698997,6.434103678929768,0.7835819397993307,0.721170568561873,0.1378428093645486,6.390190635451501,0.25918394648829435,6.62716722408027,BUILD120-A9,3976 +0.5702140468227427,0.009093645484949835,2.8254849498327754,0.7222374581939804,0.7250100334448158,0.1266254180602007,6.013411371237458,0.12878260869565214,5.855755852842811,0.7795986622073574,0.7307458193979932,0.13245819397993297,5.703347826086954,0.2538428093645485,5.830668896321071,BUILD21-B1,3975 +0.5771140939597315,0.03104026845637579,3.5493322147651,0.7223578595317727,0.7154147157190637,0.13121070234113716,6.4363076923076905,0.1325150501672241,6.828829431438129,0.7906822742474914,0.7296521739130437,0.14254849498327762,6.5379765886287595,0.2692040133779266,6.644321070234113,BUILD180-A9,3974 +0.6290201342281877,0.026822147651006673,3.901197986577183,0.7515752508361206,0.7170033444816056,0.10493645484949837,5.370040133779265,0.10287625418060209,7.60757190635451,0.7894046822742471,0.734672240802676,0.11079598662207349,5.679284280936457,0.21772909698996665,5.540842809364551,BUILD145-A9,3973 +0.5706655518394653,0.02932107023411369,3.0259665551839467,0.7402040133779271,0.7193745819397993,0.1267658862876254,6.64846488294314,0.13069230769230772,6.6243444816053465,0.780013377926421,0.7235083612040129,0.13413712374581943,6.647290969899667,0.2605585284280937,6.622826086956524,BUILD174-A9,3972 +0.5787826086956526,0.02671571906354511,2.944177257525083,0.721702341137124,0.7284682274247489,0.13489632107023414,6.077110367892977,0.1343745819397993,5.958143812709028,0.7805384615384607,0.7253311036789292,0.14179598662207357,5.862247491638797,0.2510401337792643,6.023280936454848,BUILD146-A9,3971 +0.5749664429530201,0.028077181208053664,2.682365771812082,0.7204347826086962,0.718274247491639,0.12512040133779273,5.4335484949832775,0.12389632107023411,5.546160535117058,0.7896421404682272,0.7255953177257525,0.1343946488294313,5.502384615384617,0.24891638795986618,5.568404682274251,BUILD133-A9,3970 +0.6355622895622897,0.03125252525252522,5.38030976430977,0.7253511705685615,0.7200606060606062,0.14185185185185178,6.282370370370367,0.14837458193979944,6.049933110367893,0.7777926421404682,0.7219030100334449,0.1461538461538461,6.157785953177257,0.2774147157190638,6.049508361204013,BUILD166-A9,3969 +0.577201342281879,0.03044630872483218,3.225969798657719,0.7200836120401335,0.7182742474916388,0.1312240802675585,6.153157190635448,0.12962207357859534,6.179137123745823,0.7876755852842807,0.7365083612040136,0.1362274247491638,6.122193979933114,0.2837759197324414,6.238096989966556,BUILD120-A9,3968 +0.5746755852842814,0.03218060200668893,2.9621538461538464,0.7185852842809366,0.7279632107023416,0.14631772575250832,6.487347826086962,0.14790301003344472,6.501882943143808,0.782294314381271,0.7251705685618725,0.15442140468227405,6.759882943143812,0.28450167224080275,6.735247491638796,BUILD158-A9,3967 +0.576217391304348,0.028444816053511686,2.5558963210702332,0.7170234113712376,0.7235919732441473,0.12115050167224087,5.602127090301007,0.12305685618729094,5.256190635451506,0.7828026755852845,0.7312341137123752,0.13125083612040128,5.518545150501667,0.2390367892976589,5.741123745819395,BUILD143-A9,3966 +0.5774228187919461,0.030708053691275137,2.697322147651008,0.7198394648829428,0.7237859531772576,0.09628762541806019,5.616030100334449,0.09859531772575254,5.623675585284281,0.7806321070234109,0.7251739130434784,0.10263879598662208,5.843872909698996,0.21496989966555188,5.957207357859533,BUILD129-A9,3965 +0.5759865771812078,0.036758389261744955,2.9319395973154356,0.7191003344481606,0.7192474916387955,0.14573578595317732,6.150274247491638,0.14988628762541822,6.08908695652174,0.779183946488294,0.7245484949832773,0.15834113712374584,6.401093645484949,0.28313377926421424,6.34434448160535,BUILD179-A9,3964 +0.5715785953177267,0.02948829431438124,2.569963210702343,0.7215150501672238,0.7117692307692307,0.14139464882943142,5.419297658862877,0.14605685618729103,5.411150501672242,0.7735250836120403,0.7209063545150497,0.15194983277591967,5.808812709030099,0.30766220735785954,5.701397993311034,BUILD148-A9,3963 +0.5768053691275166,0.026983221476510045,2.8690637583892604,0.7199498327759198,0.7162107023411376,0.10800334448160533,6.07056856187291,0.10929096989966552,5.998632107023413,0.7792274247491636,0.7225986622073576,0.1172006688963211,6.222327759197326,0.23226086956521733,6.21909364548495,BUILD175-A9,3962 +0.5704515050167226,0.004779264214046822,2.338668896321069,0.7290033444816054,0.7318394648829433,0.14307692307692305,5.60170568561873,0.14644481605351176,5.401070234113713,0.7798093645484946,0.7227257525083608,0.15390635451505028,5.593735785953175,0.2700602006688964,5.70205685618729,BUILD147-A9,3961 +0.5752742474916388,0.02985953177257523,3.652354515050168,0.722943143812709,0.719023411371238,0.11531103678929765,7.291615384615382,0.12005351170568579,7.3373678929765935,0.7779665551839458,0.7331040268456375,0.12381879194630867,8.060932885906047,0.24406688963210682,7.599769230769228,BUILD125-A9,3960 +0.5758628762541809,0.027698996655518334,3.0467725752508397,0.7240936454849499,0.7245685618729095,0.13715050167224088,5.992073578595318,0.13655852842809355,6.053441471571905,0.7777525083612038,0.7208260869565218,0.1453177257525084,6.1641438127090336,0.29341471571906375,6.183474916387964,BUILD139-A9,3959 +0.5716555183946486,0.013963210702341133,2.839137123745821,0.7176789297658863,0.7265752508361205,0.11275250836120411,6.166715719063547,0.11633110367892972,6.139591973244149,0.7850969899665547,0.7252408026755854,0.12110702341137125,6.688812709030095,0.23491638795986602,6.810224080267557,BUILD144-A9,3958 +0.5757550335570469,0.02671140939597311,3.0432315436241586,0.7180769230769226,0.7198561872909698,0.1518060200668896,6.77678929765886,0.15486956521739126,6.729003344481602,0.7791137123745819,0.7228428093645481,0.16300668896321063,6.807421404682276,0.294916387959866,6.971638795986624,BUILD158-A9,3957 +0.5803478260869562,0.027842809364548457,2.9640668896321087,0.7304347826086953,0.7179197324414713,0.10790969899665559,5.2156755852842815,0.0943913043478261,5.37356856187291,0.7793010033444817,0.7231204013377925,0.0979799331103679,5.293692307692307,0.19817056856187312,5.409314381270905,BUILD153-A9,3956 +0.5694766666666676,0.008683333333333331,2.6936533333333332,0.7262508361204014,0.7232842809364546,0.11707692307692308,6.631260869565214,0.11854515050167219,6.155856187290972,0.7816454849498329,0.7238026755852843,0.11863879598662207,6.392317725752511,0.23702341137123734,6.520341137123745,BUILD144-A9,3955 +0.574548494983278,0.022100334448160508,2.9308862876254222,0.718775919732442,0.7291204013377932,0.11472909698996649,6.1612207357859585,0.11296321070234122,6.402655518394644,0.7811571906354514,0.7315518394648833,0.12202006688963218,6.352224080267561,0.23767892976588612,6.365571906354518,BUILD144-A9,3954 +0.5709966555183953,0.02598996655518391,2.7516488294314385,0.7156387959866222,0.7175886287625423,0.1410903010033445,5.928197324414717,0.14296321070234097,5.96597658862876,0.7782307692307686,0.7218333333333334,0.14581666666666654,6.166476666666667,0.2758428093645488,6.127250836120403,BUILD166-A9,3953 +0.5881610738255031,0.04199664429530199,4.4503892617449665,0.7186387959866223,0.7201270903010033,0.16627759197324407,7.1302541806020034,0.16565217391304357,7.281110367892972,0.7953545150501673,0.7299866220735796,0.17521739130434777,7.093471571906351,0.34571237458193943,7.410267558528427,BUILD154-A9,3952 +0.5749597315436243,0.02822818791946305,3.3186006711409375,0.7248127090301002,0.7279464882943137,0.12283277591973253,6.584060200668893,0.12557190635451507,6.747956521739128,0.7836387959866216,0.7240869565217387,0.12625083612040133,6.698882943143808,0.24532441471571917,6.740371237458191,BUILD177-A9,3950 +0.575371237458194,0.03710033444816051,2.878438127090303,0.7132107023411373,0.7228829431438122,0.13410702341137115,6.200508361204016,0.13815384615384624,6.081260869565215,0.774755852842809,0.7291610738255043,0.15064765100671137,6.369453020134225,0.3058829431438127,6.344110367892976,BUILD139-A9,3949 +0.5724228187919461,0.027265100671140914,2.9698020134228207,0.714826666666666,0.7204481605351177,0.13995317725752507,6.2426488294314355,0.13393999999999995,6.064716666666666,0.7910301003344489,0.7317751677852352,0.1510973154362415,6.3687248322147685,0.2915852842809366,6.334889632107021,BUILD120-A9,3948 +0.5734566666666668,0.015013333333333332,3.440013333333335,0.7182240802675586,0.7190468227424744,0.12867892976588632,6.937060200668899,0.13136789297658866,7.148541806020069,0.7881003344481601,0.7240334448160537,0.13621739130434793,7.038762541806021,0.2504648829431438,7.169210702341139,BUILD130-A9,3947 +0.57447491638796,0.026424749163879574,2.9051471571906378,0.7233846153846155,0.716030100334448,0.13744481605351178,6.250474916387961,0.14111705685618733,6.210290969899667,0.7789698996655517,0.7261174496644296,0.14960738255033562,6.679946308724833,0.27532775919732455,6.440294314381269,BUILD142-A9,3946 +0.5732909698996652,0.01372240802675585,2.580137123745821,0.7191605351170569,0.718361204013378,0.1116789297658863,5.136545150501671,0.11453511705685619,5.16003678929766,0.7866889632107019,0.7243478260869568,0.12128762541806022,5.217137123745819,0.22709030100334435,5.278638795986625,BUILD172-A9,3945 +0.5691778523489935,0.031157718120805335,2.4849563758389266,0.7168193979933111,0.7227859531772577,0.126571906354515,5.277234113712377,0.1268795986622074,5.2109297658862905,0.7897290969899662,0.7332809364548489,0.13152173913043488,5.341391304347826,0.24585953177257525,5.706842809364547,BUILD176-A9,3944 +0.6153712374581942,0.01428428093645485,3.719795986622075,0.7489531772575254,0.7196521739130437,0.12077926421404682,5.451635451505016,0.11850501672240815,6.606157190635451,0.7777926421404683,0.7345685618729093,0.12581605351170566,5.552277591973241,0.23914715719063528,5.621130434782607,BUILD143-A9,3943 +0.5787324414715715,0.008414715719063545,2.583739130434783,0.7267391304347823,0.7169397993311034,0.11436789297658864,5.122732441471573,0.11625752508361215,5.303264214046824,0.7878695652173908,0.7249464882943146,0.12842140468227403,5.194023411371235,0.230458193979933,5.329648829431438,BUILD172-A9,3942 +0.5808193979933111,0.03350836120401335,2.6704481605351154,0.7188327759197319,0.7249598662207358,0.11968561872909704,5.431969899665549,0.11832775919732447,5.109163879598663,0.7884448160535117,0.7237090301003339,0.12432441471571908,5.360618729096989,0.25609030100334457,5.36935117056856,BUILD172-A9,3941 +0.574521739130435,0.029555183946488234,2.848046822742476,0.7199531772575254,0.7295819397993318,0.11516053511705686,6.743143812709031,0.11270903010033445,6.481354515050172,0.7785886287625418,0.724839464882943,0.12243478260869561,6.550826086956522,0.23760869565217357,6.614779264214045,BUILD144-A9,3940 +0.5739464882943142,0.027578595317725725,2.6171036789297673,0.7193311036789303,0.7194548494983283,0.11300000000000007,5.107367892976584,0.11443143812709039,5.11719063545151,0.7838428093645485,0.7306733333333334,0.11910333333333337,5.496940000000003,0.2266755852842809,5.329535117056859,BUILD172-A9,3939 +0.5754581939799334,0.020842809364548482,2.549575250836122,0.7221237458193975,0.7345986622073574,0.09451505016722404,5.479702341137122,0.09562876254180605,5.267518394648832,0.7792374581939796,0.7249799331103677,0.10226086956521745,5.141418060200667,0.20433110367892968,5.222692307692307,BUILD127-A9,3938 +0.5750100000000005,0.009996666666666668,3.086056666666669,0.7236086956521741,0.7253712374581944,0.12707357859531773,5.929913043478258,0.13067558528428105,5.950270903010037,0.7950735785953177,0.7301705685618731,0.13850167224080265,5.941481605351171,0.24743812709030089,6.098946488294315,BUILD131-A9,3937 +0.5740602006688966,0.023240802675585245,2.733501672240804,0.7198595317725752,0.7197157190635455,0.12111705685618739,5.5181070234113685,0.12225083612040143,5.550618729096993,0.7797725752508357,0.7396488294314386,0.12805016722408027,5.505110367892976,0.23715050167224058,5.576153846153849,BUILD140-A9,3936 +0.5748724832214769,0.036087248322147616,3.095946308724834,0.7178394648829431,0.7167424749163883,0.13453846153846152,6.8643745819398,0.1353110367892976,6.833725752508358,0.777538461538461,0.721401337792642,0.14866220735785948,7.136227424749166,0.2787759197324416,6.961277591973247,BUILD149-A9,3935 +0.5765317725752507,0.03670903010033443,2.8997926421404703,0.7162709030100335,0.7175117056856187,0.14148160535117055,6.134498327759198,0.13748160535117063,6.1754046822742445,0.7783277591973243,0.7310969899665549,0.15195317725752516,6.402923076923078,0.28137458193979964,6.353698996655516,BUILD142-A9,3934 +0.584655518394649,0.009100334448160536,4.376494983277592,0.7250334448160537,0.7227692307692313,0.13601003344481605,7.695916387959864,0.13640802675585276,7.609023411371235,0.7923678929765879,0.7411471571906355,0.14424414715719072,7.950511705685625,0.25483277591973236,8.0006889632107,BUILD141-A9,3933 +0.5807348993288584,0.025318791946308684,2.6897751677852364,0.7190668896321072,0.7178762541806021,0.11560869565217398,5.270545150501672,0.1094548494983278,5.168267558528428,0.7902651006711412,0.7260100334448166,0.12104347826086971,5.370755852842809,0.2378187919463085,5.578224832214766,BUILD136-A9,3932 +0.5774113712374584,0.042050167224080254,2.6277424749163876,0.7204414715719061,0.7121270903010033,0.1452642140468227,5.637217391304347,0.14780602006688964,5.491254180602009,0.7730836120401332,0.7263076923076921,0.16376588628762548,5.916140468227428,0.3380836120401338,5.758020066889626,BUILD148-A9,3931 +0.5781375838926172,0.03122483221476507,2.9609664429530187,0.7217458193979939,0.7205284280936451,0.11927759197324406,5.839842809364545,0.11865217391304352,5.873210702341136,0.7955652173913045,0.7262976588628756,0.12223745819397994,5.831240802675589,0.24547826086956512,6.092137123745817,BUILD126-A9,3930 +0.5750869565217391,0.02844481605351168,2.482357859531773,0.7334715719063547,0.7194280936454851,0.13139799331103674,5.259966555183941,0.1366755852842809,5.262207357859528,0.7797959866220733,0.7266889632107029,0.14006354515050176,5.503187290969905,0.26532441471571927,5.513321070234116,BUILD147-A9,3929 +0.5746789297658864,0.021575250836120368,2.3915752508361208,0.721842809364548,0.7203745819397994,0.08385618729096996,5.044956521739134,0.0875117056856188,5.06289966555184,0.7904949832775919,0.7281371237458192,0.09017056856187294,5.341331103678936,0.226257525083612,5.38454180602007,BUILD127-A9,3928 +0.5736174496644303,0.030187919463087215,3.6837281879194617,0.7215484949832781,0.6901304347826083,0.1064816053511706,6.131588628762536,0.10820735785953177,7.442615384615385,0.7841337792642142,0.7486856187290972,0.11374247491638793,8.119117056856192,0.24284949832775918,7.840364548494984,BUILD125-A9,3927 +0.5731677852348995,0.033291946308724805,2.522322147651006,0.7194749163879592,0.7276521739130436,0.10267558528428103,5.116133779264213,0.1035551839464883,5.132458193979931,0.7810301003344481,0.7270234113712379,0.10844147157190645,5.295374581939799,0.21746153846153846,5.40732441471572,BUILD136-A9,3926 +0.5767449664429534,0.030604026845637552,2.5929328859060394,0.7274381270903013,0.7207826086956522,0.08611705685618734,5.52629431438127,0.08887959866220735,5.531130434782605,0.7790535117056855,0.7371170568561869,0.09586287625418066,5.705351170568563,0.20651839464882946,5.890705685618732,BUILD129-A9,3925 +0.5721538461538462,0.025632107023411333,2.8410434782608704,0.735889632107024,0.7223846153846152,0.12678595317725747,6.143401337792643,0.13158528428093647,5.874698996655517,0.8451107382550331,0.7266354515050167,0.1354782608695651,6.20066220735786,0.25717449664429526,8.501090604026855,BUILD155-A9,3924 +0.5713645484949832,0.014377926421404673,3.018919732441472,0.7315585284280933,0.719809364548495,0.11922408026755849,6.397147157190638,0.11393645484949835,6.3150267558528395,0.7963221476510065,0.7268026755852846,0.1261103678929765,6.716200668896324,0.273553691275168,7.242073825503357,BUILD165-A9,3923 +0.5729362416107382,0.029453020134228163,2.9319127516778507,0.7225551839464884,0.7256555183946486,0.11894648829431437,5.6302274247491635,0.11848829431438124,5.788408026755855,0.7810969899665551,0.7290501672240801,0.1291571906354516,5.626351170568564,0.25159531772575244,5.850003344481604,BUILD21-B1,3922 +0.5758428093645483,0.03633444816053507,2.631418060200669,0.7201806020066885,0.7199464882943144,0.1220033444816054,5.266183946488291,0.12759866220735794,5.243414715719068,0.7790434782608694,0.7255785953177253,0.1292307692307692,5.5810635451505,0.25682608695652165,5.589692307692307,BUILD156-A9,3921 +0.5707684563758393,0.03206711409395971,3.0611812080536915,0.7184648829431434,0.7158795986622074,0.13064882943143824,5.957739130434781,0.13187625418060198,5.9663745819397995,0.8540402684563759,0.7217290969899668,0.1427090301003344,6.001749163879603,0.29916442953020167,8.81292281879195,BUILD139-A9,3920 0.5759531772575247,0.032140468227424744,2.6997692307692307,0.7194247491638792,0.7245183946488295,0.11278929765886289,5.318976588628757,0.11635451505016726,5.386404682274252,0.796943143812709,0.7304147157190638,0.11959531772575256,5.459959866220738,0.24364882943143812,5.456491638795983,BUILD143-A9,3919 0.5784697986577184,0.03631543624161071,3.0281879194630883,0.7228595317725749,0.723033444816054,0.11472240802675583,5.741521739130437,0.1158929765886288,5.746695652173914,0.7946521739130435,0.7354682274247485,0.12361872909698998,5.833240802675584,0.24684615384615405,6.010591973244147,BUILD131-A9,3918 0.5838093645484947,0.014602006688963203,2.539782608695651,0.720483221476509,0.7291906354515049,0.13324080267558527,5.108107023411368,0.13560738255033564,5.063906040268457,0.7817491638795987,0.7290568561872908,0.15345484949832774,5.292016722408028,0.26696655518394674,5.474331103678929,BUILD162-A9,3917
diff --git a/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.json b/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.json index 806dbca9..b064f52 100644 --- a/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.json +++ b/content/test/gpu/power_measurement_results/win10_intel_hd_630/build_3633_4131.json
@@ -6613,7 +6613,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD170-A9", "number": 4001, "tests": [ { @@ -6664,7 +6664,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD130-A9", "number": 4000, "tests": [ { @@ -6715,7 +6715,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD182-A9", "number": 3999, "tests": [ { @@ -6766,7 +6766,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD168-A9", "number": 3998, "tests": [ { @@ -6817,7 +6817,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD138-A9", "number": 3997, "tests": [ { @@ -6868,7 +6868,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD177-A9", "number": 3996, "tests": [ { @@ -6919,7 +6919,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD175-A9", "number": 3995, "tests": [ { @@ -6970,7 +6970,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD168-A9", "number": 3994, "tests": [ { @@ -7021,7 +7021,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD21-B1", "number": 3993, "tests": [ { @@ -7072,7 +7072,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD161-A9", "number": 3992, "tests": [ { @@ -7123,7 +7123,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD125-A9", "number": 3991, "tests": [ { @@ -7174,7 +7174,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD162-A9", "number": 3990, "tests": [ { @@ -7225,7 +7225,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD126-A9", "number": 3989, "tests": [ { @@ -7276,7 +7276,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD118-A9", "number": 3988, "tests": [ { @@ -7327,7 +7327,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD137-A9", "number": 3987, "tests": [ { @@ -7378,7 +7378,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD162-A9", "number": 3986, "tests": [ { @@ -7429,7 +7429,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD143-A9", "number": 3985, "tests": [ { @@ -7480,7 +7480,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD137-A9", "number": 3984, "tests": [ { @@ -7531,7 +7531,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD125-A9", "number": 3983, "tests": [ { @@ -7582,7 +7582,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD120-A9", "number": 3982, "tests": [ { @@ -7633,7 +7633,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD149-A9", "number": 3981, "tests": [ { @@ -7684,7 +7684,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD120-A9", "number": 3980, "tests": [ { @@ -7735,7 +7735,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD144-A9", "number": 3979, "tests": [ { @@ -7777,7 +7777,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD138-A9", "number": 3978, "tests": [ { @@ -7828,7 +7828,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD166-A9", "number": 3977, "tests": [ { @@ -7879,7 +7879,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD120-A9", "number": 3976, "tests": [ { @@ -7930,7 +7930,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD21-B1", "number": 3975, "tests": [ { @@ -7981,7 +7981,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD180-A9", "number": 3974, "tests": [ { @@ -8032,7 +8032,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD145-A9", "number": 3973, "tests": [ { @@ -8083,7 +8083,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD174-A9", "number": 3972, "tests": [ { @@ -8134,7 +8134,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD146-A9", "number": 3971, "tests": [ { @@ -8185,7 +8185,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD133-A9", "number": 3970, "tests": [ { @@ -8236,7 +8236,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD166-A9", "number": 3969, "tests": [ { @@ -8287,7 +8287,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD120-A9", "number": 3968, "tests": [ { @@ -8338,7 +8338,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD158-A9", "number": 3967, "tests": [ { @@ -8389,7 +8389,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD143-A9", "number": 3966, "tests": [ { @@ -8440,7 +8440,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD129-A9", "number": 3965, "tests": [ { @@ -8491,7 +8491,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD179-A9", "number": 3964, "tests": [ { @@ -8542,7 +8542,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD148-A9", "number": 3963, "tests": [ { @@ -8593,7 +8593,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD175-A9", "number": 3962, "tests": [ { @@ -8644,7 +8644,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD147-A9", "number": 3961, "tests": [ { @@ -8695,7 +8695,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD125-A9", "number": 3960, "tests": [ { @@ -8746,7 +8746,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD139-A9", "number": 3959, "tests": [ { @@ -8797,7 +8797,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD144-A9", "number": 3958, "tests": [ { @@ -8848,7 +8848,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD158-A9", "number": 3957, "tests": [ { @@ -8899,7 +8899,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD153-A9", "number": 3956, "tests": [ { @@ -8950,7 +8950,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD144-A9", "number": 3955, "tests": [ { @@ -9001,7 +9001,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD144-A9", "number": 3954, "tests": [ { @@ -9052,7 +9052,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD166-A9", "number": 3953, "tests": [ { @@ -9103,7 +9103,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD154-A9", "number": 3952, "tests": [ { @@ -9154,7 +9154,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD177-A9", "number": 3950, "tests": [ { @@ -9205,7 +9205,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD139-A9", "number": 3949, "tests": [ { @@ -9256,7 +9256,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD120-A9", "number": 3948, "tests": [ { @@ -9307,7 +9307,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD130-A9", "number": 3947, "tests": [ { @@ -9358,7 +9358,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD142-A9", "number": 3946, "tests": [ { @@ -9409,7 +9409,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD172-A9", "number": 3945, "tests": [ { @@ -9460,7 +9460,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD176-A9", "number": 3944, "tests": [ { @@ -9511,7 +9511,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD143-A9", "number": 3943, "tests": [ { @@ -9562,7 +9562,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD172-A9", "number": 3942, "tests": [ { @@ -9613,7 +9613,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD172-A9", "number": 3941, "tests": [ { @@ -9664,7 +9664,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD144-A9", "number": 3940, "tests": [ { @@ -9715,7 +9715,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD172-A9", "number": 3939, "tests": [ { @@ -9766,7 +9766,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD127-A9", "number": 3938, "tests": [ { @@ -9817,7 +9817,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD131-A9", "number": 3937, "tests": [ { @@ -9868,7 +9868,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD140-A9", "number": 3936, "tests": [ { @@ -9919,7 +9919,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD149-A9", "number": 3935, "tests": [ { @@ -9970,7 +9970,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD142-A9", "number": 3934, "tests": [ { @@ -10021,7 +10021,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD141-A9", "number": 3933, "tests": [ { @@ -10072,7 +10072,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD136-A9", "number": 3932, "tests": [ { @@ -10123,7 +10123,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD148-A9", "number": 3931, "tests": [ { @@ -10174,7 +10174,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD126-A9", "number": 3930, "tests": [ { @@ -10225,7 +10225,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD147-A9", "number": 3929, "tests": [ { @@ -10276,7 +10276,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD127-A9", "number": 3928, "tests": [ { @@ -10327,7 +10327,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD125-A9", "number": 3927, "tests": [ { @@ -10378,7 +10378,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD136-A9", "number": 3926, "tests": [ { @@ -10429,7 +10429,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD129-A9", "number": 3925, "tests": [ { @@ -10480,7 +10480,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD155-A9", "number": 3924, "tests": [ { @@ -10531,7 +10531,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD165-A9", "number": 3923, "tests": [ { @@ -10582,7 +10582,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD21-B1", "number": 3922, "tests": [ { @@ -10633,7 +10633,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD156-A9", "number": 3921, "tests": [ { @@ -10684,7 +10684,7 @@ ] }, { - "bot": "SWARM761-C4", + "bot": "BUILD139-A9", "number": 3920, "tests": [ {
diff --git a/device/vr/buildflags/buildflags.gni b/device/vr/buildflags/buildflags.gni index faedebf..ef0161b0 100644 --- a/device/vr/buildflags/buildflags.gni +++ b/device/vr/buildflags/buildflags.gni
@@ -53,4 +53,7 @@ # Whether to create AR module as an asynchronous DFM. async_ar = false + + # Whether to create VR module as an asynchronous DFM. + async_vr = false }
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 13598c2..1d5ae26 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -852,6 +852,20 @@ // The callback to call when we get a response from all event handlers. net::CompletionOnceCallback callback; + // The callback to invoke for onBeforeSendHeaders. If + // |before_send_headers_callback.is_null()| is false, |callback| must be NULL. + // Only valid for OnBeforeSendHeaders. + BeforeSendHeadersCallback before_send_headers_callback; + + // The callback to invoke for auth. If |auth_callback.is_null()| is false, + // |callback| must be NULL. + // Only valid for OnAuthRequired. + net::NetworkDelegate::AuthCallback auth_callback; + + // If non-empty, this contains the auth credentials that may be filled in. + // Only valid for OnAuthRequired. + net::AuthCredentials* auth_credentials = nullptr; + // If non-empty, this contains the new URL that the request will redirect to. // Only valid for OnBeforeRequest and OnHeadersReceived. GURL* new_url = nullptr; @@ -868,15 +882,6 @@ // OnHeadersReceived. scoped_refptr<net::HttpResponseHeaders>* override_response_headers = nullptr; - // If non-empty, this contains the auth credentials that may be filled in. - // Only valid for OnAuthRequired. - net::AuthCredentials* auth_credentials = nullptr; - - // The callback to invoke for auth. If |auth_callback.is_null()| is false, - // |callback| must be NULL. - // Only valid for OnAuthRequired. - net::NetworkDelegate::AuthCallback auth_callback; - // Time the request was paused. Used for logging purposes. base::Time blocking_time; @@ -1092,7 +1097,7 @@ void* browser_context, const InfoMap* extension_info_map, const WebRequestInfo* request, - net::CompletionOnceCallback callback, + BeforeSendHeadersCallback callback, net::HttpRequestHeaders* headers) { if (ShouldHideEvent(browser_context, extension_info_map, *request)) return net::OK; @@ -1130,7 +1135,7 @@ blocked_request.event = kOnBeforeSendHeaders; blocked_request.is_incognito |= IsIncognitoBrowserContext(browser_context); blocked_request.request = request; - blocked_request.callback = std::move(callback); + blocked_request.before_send_headers_callback = std::move(callback); blocked_request.request_headers = headers; if (blocked_request.num_handlers_blocking == 0) { @@ -2215,6 +2220,9 @@ bool request_headers_modified = false; bool response_headers_modified = false; bool credentials_set = false; + // The set of request headers which were removed or set to new values. + std::set<std::string> request_headers_removed; + std::set<std::string> request_headers_set; deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); @@ -2229,11 +2237,12 @@ request->url, blocked_request.response_deltas, blocked_request.new_url, &ignored_actions, request->logger.get()); } else if (blocked_request.event == kOnBeforeSendHeaders) { - CHECK(!blocked_request.callback.is_null()); + CHECK(!blocked_request.before_send_headers_callback.is_null()); helpers::MergeOnBeforeSendHeadersResponses( request->url, blocked_request.response_deltas, blocked_request.request_headers, &ignored_actions, - request->logger.get(), &request_headers_modified); + request->logger.get(), &request_headers_removed, &request_headers_set, + &request_headers_modified); } else if (blocked_request.event == kOnHeadersReceived) { CHECK(!blocked_request.callback.is_null()); helpers::MergeOnHeadersReceivedResponses( @@ -2293,6 +2302,13 @@ blocked_requests_.erase(request->id); if (call_callback) std::move(callback).Run(rv); + } else if (!blocked_request.before_send_headers_callback.is_null()) { + auto callback = std::move(blocked_request.before_send_headers_callback); + // Ensure that request is removed before callback because the callback + // might trigger the next event. + blocked_requests_.erase(request->id); + if (call_callback) + std::move(callback).Run(request_headers_removed, request_headers_set, rv); } else if (!blocked_request.auth_callback.is_null()) { net::NetworkDelegate::AuthRequiredResponse response; if (canceled)
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h index e0322509..bd9ea87 100644 --- a/extensions/browser/api/web_request/web_request_api.h +++ b/extensions/browser/api/web_request/web_request_api.h
@@ -359,6 +359,11 @@ GURL* new_url, bool* should_collapse_initiator); + using BeforeSendHeadersCallback = + base::OnceCallback<void(const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code)>; + // Dispatches the onBeforeSendHeaders event. This is fired for HTTP(s) // requests only, and allows modification of the outgoing request headers. // Returns net::ERR_IO_PENDING if an extension is intercepting the request, OK @@ -366,7 +371,7 @@ int OnBeforeSendHeaders(void* browser_context, const extensions::InfoMap* extension_info_map, const WebRequestInfo* request, - net::CompletionOnceCallback callback, + BeforeSendHeadersCallback callback, net::HttpRequestHeaders* headers); // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests
diff --git a/extensions/browser/api/web_request/web_request_api_helpers.cc b/extensions/browser/api/web_request/web_request_api_helpers.cc index 362b80fe..03f2d1c 100644 --- a/extensions/browser/api/web_request/web_request_api_helpers.cc +++ b/extensions/browser/api/web_request/web_request_api_helpers.cc
@@ -709,15 +709,14 @@ net::HttpRequestHeaders* request_headers, IgnoredActions* ignored_actions, extensions::WebRequestInfo::Logger* logger, + std::set<std::string>* removed_headers, + std::set<std::string>* set_headers, bool* request_headers_modified) { DCHECK(request_headers_modified); + DCHECK(removed_headers->empty()); + DCHECK(set_headers->empty()); *request_headers_modified = false; - // Here we collect which headers we have removed or set to new values - // so far due to extensions of higher precedence. - std::set<std::string> removed_headers; - std::set<std::string> set_headers; - // We assume here that the deltas are sorted in decreasing extension // precedence (i.e. decreasing extension installation time). for (const auto& delta : deltas) { @@ -739,14 +738,14 @@ const std::string& value = modification.value(); // We must not delete anything that has been modified before. - if (removed_headers.find(key) != removed_headers.end() && + if (removed_headers->find(key) != removed_headers->end() && !extension_conflicts) { extension_conflicts = true; } // We must not modify anything that has been set to a *different* // value before. - if (set_headers.find(key) != set_headers.end() && + if (set_headers->find(key) != set_headers->end() && !extension_conflicts) { std::string current_value; if (!request_headers->GetHeader(key, ¤t_value) || @@ -763,7 +762,7 @@ for (auto key = delta.deleted_request_headers.begin(); key != delta.deleted_request_headers.end() && !extension_conflicts; ++key) { - if (set_headers.find(*key) != set_headers.end()) { + if (set_headers->find(*key) != set_headers->end()) { std::string current_value; request_headers->GetHeader(*key, ¤t_value); extension_conflicts = true; @@ -780,14 +779,14 @@ net::HttpRequestHeaders::Iterator modification( delta.modified_request_headers); while (modification.GetNext()) - set_headers.insert(modification.name()); + set_headers->insert(modification.name()); } // Perform all deletions and record which keys were deleted. { for (const auto& header : delta.deleted_request_headers) { request_headers->RemoveHeader(header); - removed_headers.insert(header); + removed_headers->insert(header); } } logger->LogEvent(net::NetLogEventType::CHROME_EXTENSION_MODIFIED_HEADERS, @@ -815,7 +814,7 @@ {"referer", WebRequestSpecialRequestHeaderModification::kReferer}, }; int special_headers_removed = 0; - for (const auto& header : removed_headers) { + for (const auto& header : *removed_headers) { auto it = kHeaderMap.find(base::ToLowerASCII(header)); if (it != kHeaderMap.end()) { special_headers_removed++; @@ -831,7 +830,7 @@ } int special_headers_changed = 0; - for (const auto& header : set_headers) { + for (const auto& header : *set_headers) { auto it = kHeaderMap.find(base::ToLowerASCII(header)); if (it != kHeaderMap.end()) { special_headers_changed++;
diff --git a/extensions/browser/api/web_request/web_request_api_helpers.h b/extensions/browser/api/web_request/web_request_api_helpers.h index 24e3c911..0698fc3a 100644 --- a/extensions/browser/api/web_request/web_request_api_helpers.h +++ b/extensions/browser/api/web_request/web_request_api_helpers.h
@@ -332,6 +332,8 @@ net::HttpRequestHeaders* request_headers, IgnoredActions* ignored_actions, extensions::WebRequestInfo::Logger* logger, + std::set<std::string>* removed_headers, + std::set<std::string>* set_headers, bool* request_headers_modified); // Modifies the "Set-Cookie" headers in |override_response_headers| according to // |deltas.response_cookie_modifications|. If |override_response_headers| is
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc index 7df76569..d14153d0 100644 --- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc +++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -26,6 +26,11 @@ namespace extensions { +WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams:: + FollowRedirectParams() = default; +WebRequestProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams:: + ~FollowRedirectParams() = default; + WebRequestProxyingURLLoaderFactory::InProgressRequest::InProgressRequest( WebRequestProxyingURLLoaderFactory* factory, uint64_t request_id, @@ -80,7 +85,12 @@ } void WebRequestProxyingURLLoaderFactory::InProgressRequest::Restart() { - request_completed_ = false; + UpdateRequestInfo(); + RestartInternal(); +} + +void WebRequestProxyingURLLoaderFactory::InProgressRequest:: + UpdateRequestInfo() { // Derive a new WebRequestInfo value any time |Restart()| is called, because // the details in |request_| may have changed e.g. if we've been redirected. // |request_initiator| can be modified on redirects, but we keep the original @@ -101,6 +111,12 @@ ExtensionWebRequestEventRouter::GetInstance() ->HasExtraHeadersListenerForRequest( factory_->browser_context_, factory_->info_map_, &info_.value()); +} + +void WebRequestProxyingURLLoaderFactory::InProgressRequest::RestartInternal() { + DCHECK_EQ(info_->url, request_.url) + << "UpdateRequestInfo must have been called first"; + request_completed_ = false; // If the header client will be used, we start the request immediately, and // OnBeforeSendHeaders and OnSendHeaders will be handled there. Otherwise, @@ -162,11 +178,29 @@ request_.headers.RemoveHeader(header); request_.headers.MergeFrom(modified_headers); + // Call this before checking |current_request_uses_header_client_| as it + // calculates it. + UpdateRequestInfo(); + if (target_loader_.is_bound()) { - target_loader_->FollowRedirect(removed_headers, modified_headers, new_url); + // If header_client_ is used, then we have to call FollowRedirect now as + // that's what triggers the network service calling back to + // OnBeforeSendHeaders(). Otherwise, don't call FollowRedirect now. Wait for + // the onBeforeSendHeaders callback(s) to run as these may modify request + // headers and if so we'll pass these modifications to FollowRedirect. + if (current_request_uses_header_client_) { + target_loader_->FollowRedirect(removed_headers, modified_headers, + new_url); + } else { + auto params = std::make_unique<FollowRedirectParams>(); + params->removed_headers = removed_headers; + params->modified_headers = modified_headers; + params->new_url = new_url; + pending_follow_redirect_params_ = std::move(params); + } } - Restart(); + RestartInternal(); } void WebRequestProxyingURLLoaderFactory::InProgressRequest:: @@ -447,7 +481,8 @@ DCHECK_EQ(net::OK, result); } - ContinueToSendHeaders(net::OK); + ContinueToSendHeaders(std::set<std::string>(), std::set<std::string>(), + net::OK); } void WebRequestProxyingURLLoaderFactory::InProgressRequest:: @@ -490,7 +525,9 @@ } void WebRequestProxyingURLLoaderFactory::InProgressRequest:: - ContinueToSendHeaders(int error_code) { + ContinueToSendHeaders(const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code) { if (error_code != net::OK) { OnRequestError(network::URLLoaderCompletionStatus(error_code)); return; @@ -500,6 +537,29 @@ DCHECK(on_before_send_headers_callback_); std::move(on_before_send_headers_callback_) .Run(error_code, request_.headers); + } else if (pending_follow_redirect_params_) { + pending_follow_redirect_params_->removed_headers.insert( + pending_follow_redirect_params_->removed_headers.end(), + removed_headers.begin(), removed_headers.end()); + + for (auto& set_header : set_headers) { + std::string header_value; + if (request_.headers.GetHeader(set_header, &header_value)) { + pending_follow_redirect_params_->modified_headers.SetHeader( + set_header, header_value); + } else { + NOTREACHED(); + } + } + + if (target_loader_.is_bound()) { + target_loader_->FollowRedirect( + pending_follow_redirect_params_->removed_headers, + pending_follow_redirect_params_->modified_headers, + pending_follow_redirect_params_->new_url); + } + + pending_follow_redirect_params_.reset(); } if (proxied_client_binding_.is_bound())
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h index 2226b1ea..e9108ef 100644 --- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h +++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -103,8 +103,14 @@ OnHeadersReceivedCallback callback) override; private: + // These two methods combined form the implementation of Restart(). + void UpdateRequestInfo(); + void RestartInternal(); + void ContinueToBeforeSendHeaders(int error_code); - void ContinueToSendHeaders(int error_code); + void ContinueToSendHeaders(const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code); void ContinueToStartRequest(int error_code); void ContinueToHandleOverrideHeaders(int error_code); void ContinueToResponseStarted(int error_code); @@ -168,6 +174,21 @@ OnHeadersReceivedCallback on_headers_received_callback_; mojo::Binding<network::mojom::TrustedHeaderClient> header_client_binding_; + // If |has_any_extra_headers_listeners_| is set to false and a redirect is + // in progress, this stores the parameters to FollowRedirect that came from + // the client. That way we can combine it with any other changes that + // extensions made to headers in their callbacks. + struct FollowRedirectParams { + FollowRedirectParams(); + ~FollowRedirectParams(); + std::vector<std::string> removed_headers; + net::HttpRequestHeaders modified_headers; + base::Optional<GURL> new_url; + + DISALLOW_COPY_AND_ASSIGN(FollowRedirectParams); + }; + std::unique_ptr<FollowRedirectParams> pending_follow_redirect_params_; + base::WeakPtrFactory<InProgressRequest> weak_factory_; DISALLOW_COPY_AND_ASSIGN(InProgressRequest);
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.cc b/extensions/browser/api/web_request/web_request_proxying_websocket.cc index 41baffb..4921b10 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.cc +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.cc
@@ -379,10 +379,14 @@ return; DCHECK_EQ(net::OK, result); - OnBeforeSendHeadersComplete(net::OK); + OnBeforeSendHeadersComplete(std::set<std::string>(), std::set<std::string>(), + net::OK); } -void WebRequestProxyingWebSocket::OnBeforeSendHeadersComplete(int error_code) { +void WebRequestProxyingWebSocket::OnBeforeSendHeadersComplete( + const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code) { DCHECK(binding_as_header_client_ || !binding_as_client_.is_bound()); if (error_code != net::OK) { OnError(error_code);
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.h b/extensions/browser/api/web_request/web_request_proxying_websocket.h index 1e5d162..e11ae727 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.h +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.h
@@ -112,7 +112,9 @@ private: void OnBeforeRequestComplete(int error_code); - void OnBeforeSendHeadersComplete(int error_code); + void OnBeforeSendHeadersComplete(const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code); void ContinueToStartRequest(int error_code); void OnHeadersReceivedComplete(int error_code); void ContinueToHeadersReceived();
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 5cee00c..efdbf85 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -1115,6 +1115,7 @@ IPC_STRUCT_TRAITS_MEMBER(loaded) IPC_STRUCT_TRAITS_MEMBER(loading_progress) IPC_STRUCT_TRAITS_MEMBER(focus_id) + IPC_STRUCT_TRAITS_MEMBER(sel_is_backward) IPC_STRUCT_TRAITS_MEMBER(sel_anchor_object_id) IPC_STRUCT_TRAITS_MEMBER(sel_anchor_offset) IPC_STRUCT_TRAITS_MEMBER(sel_anchor_affinity)
diff --git a/extensions/shell/browser/shell_network_delegate.cc b/extensions/shell/browser/shell_network_delegate.cc index b3ffe0f..9d6ca65f 100644 --- a/extensions/shell/browser/shell_network_delegate.cc +++ b/extensions/shell/browser/shell_network_delegate.cc
@@ -70,13 +70,22 @@ return result; } +namespace { +void OnHeadersReceivedAdapter(net::CompletionOnceCallback callback, + const std::set<std::string>& removed_headers, + const std::set<std::string>& set_headers, + int error_code) { + std::move(callback).Run(error_code); +} +} // namespace + int ShellNetworkDelegate::OnBeforeStartTransaction( net::URLRequest* request, net::CompletionOnceCallback callback, net::HttpRequestHeaders* headers) { return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders( browser_context_, extension_info_map_.get(), GetWebRequestInfo(request), - std::move(callback), headers); + base::BindOnce(OnHeadersReceivedAdapter, std::move(callback)), headers); } void ShellNetworkDelegate::OnStartTransaction(
diff --git a/gpu/command_buffer/client/shared_memory_limits.h b/gpu/command_buffer/client/shared_memory_limits.h index bef14c3b..eb68c2f9 100644 --- a/gpu/command_buffer/client/shared_memory_limits.h +++ b/gpu/command_buffer/client/shared_memory_limits.h
@@ -66,6 +66,15 @@ return limits; } + static SharedMemoryLimits ForWebGPUContext() { + // Most WebGPU commands are sent via transfer buffer, so we use a smaller + // command buffer. + SharedMemoryLimits limits; + limits.command_buffer_size = 64 * 1024; + + return limits; + } + #if defined(OS_ANDROID) static SharedMemoryLimits ForDisplayCompositor(const gfx::Size& screen_size) { DCHECK(!screen_size.IsEmpty());
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc index 8c3615d0..792e036 100644 --- a/gpu/command_buffer/client/webgpu_implementation.cc +++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -4,8 +4,10 @@ #include "gpu/command_buffer/client/webgpu_implementation.h" +#include <algorithm> #include <vector> +#include "base/numerics/checked_math.h" #include "gpu/command_buffer/client/gpu_control.h" #include "gpu/command_buffer/client/shared_memory_limits.h" @@ -42,12 +44,8 @@ return result; } - // TODO(enga): Keep track of how much command space the application is using - // and adjust c2s_buffer_size_ accordingly. - c2s_buffer_size_ = limits.start_transfer_buffer_size; - DCHECK_GT(c2s_buffer_size_, 0u); - DCHECK( - base::CheckAdd(c2s_buffer_size_, c2s_buffer_size_).IsValid<uint32_t>()); + c2s_buffer_default_size_ = limits.start_transfer_buffer_size; + DCHECK_GT(c2s_buffer_default_size_, 0u); return gpu::ContextResult::kSuccess; } @@ -214,36 +212,37 @@ void* WebGPUImplementation::GetCmdSpace(size_t size) { // The buffer size must be initialized before any commands are serialized. - if (c2s_buffer_size_ == 0u) { + if (c2s_buffer_default_size_ == 0u) { NOTREACHED(); return nullptr; } - // TODO(enga): Handle chunking commands if size > c2s_buffer_size_. - if (size > c2s_buffer_size_) { - NOTREACHED(); - return nullptr; - } + base::CheckedNumeric<uint32_t> checked_next_offset(c2s_put_offset_); + checked_next_offset += size; - // This should never be more than 2 * c2s_buffer_size_ which is checked in - // WebGPUImplementation::Initialize. - DCHECK_LE(c2s_put_offset_, c2s_buffer_size_); - DCHECK_LE(size, c2s_buffer_size_); - uint32_t next_offset = c2s_put_offset_ + static_cast<uint32_t>(size); + uint32_t next_offset; + bool next_offset_valid = checked_next_offset.AssignIfValid(&next_offset); // If the buffer does not have enough space, or if the buffer is not // initialized, flush and reset the command stream. - if (next_offset > c2s_buffer_.size() || !c2s_buffer_.valid()) { + if (!next_offset_valid || next_offset > c2s_buffer_.size() || + !c2s_buffer_.valid()) { Flush(); - c2s_buffer_.Reset(c2s_buffer_size_); + uint32_t max_allocation = transfer_buffer_->GetMaxSize(); + // TODO(crbug.com/951558): Handle command chunking or ensure commands aren't + // this large. + CHECK_LE(size, max_allocation); + + uint32_t allocation_size = + std::max(c2s_buffer_default_size_, static_cast<uint32_t>(size)); + c2s_buffer_.Reset(allocation_size); c2s_put_offset_ = 0; next_offset = size; - if (size > c2s_buffer_.size() || !c2s_buffer_.valid()) { - // TODO(enga): Handle OOM. - return nullptr; - } + // TODO(crbug.com/951558): Handle OOM. + CHECK(c2s_buffer_.valid()); + CHECK_LE(size, c2s_buffer_.size()); } DCHECK(c2s_buffer_.valid()); @@ -256,6 +255,7 @@ bool WebGPUImplementation::Flush() { if (c2s_buffer_.valid()) { + c2s_buffer_.Shrink(c2s_put_offset_); helper_->DawnCommands(c2s_buffer_.shm_id(), c2s_buffer_.offset(), c2s_put_offset_); c2s_put_offset_ = 0;
diff --git a/gpu/command_buffer/client/webgpu_implementation.h b/gpu/command_buffer/client/webgpu_implementation.h index c06d9b2b..3032f99 100644 --- a/gpu/command_buffer/client/webgpu_implementation.h +++ b/gpu/command_buffer/client/webgpu_implementation.h
@@ -124,7 +124,7 @@ #endif DawnProcTable procs_ = {}; - uint32_t c2s_buffer_size_ = 0; + uint32_t c2s_buffer_default_size_ = 0; uint32_t c2s_put_offset_ = 0; ScopedTransferBufferPtr c2s_buffer_;
diff --git a/gpu/command_buffer/common/shared_image_usage.h b/gpu/command_buffer/common/shared_image_usage.h index 34311eb..fdce596 100644 --- a/gpu/command_buffer/common/shared_image_usage.h +++ b/gpu/command_buffer/common/shared_image_usage.h
@@ -20,9 +20,10 @@ SHARED_IMAGE_USAGE_DISPLAY = 1 << 3, // Image will be used as a scanout buffer (overlay) SHARED_IMAGE_USAGE_SCANOUT = 1 << 4, - // Image will be used in OOP rasterization - // TODO(backer): Fold back into SHARED_IMAGE_USAGE_RASTER once RasterInterface - // can CPU raster (CopySubImage?) to SkImage. + // Image will be used in OOP rasterization. This flag is used on top of + // SHARED_IMAGE_USAGE_RASTER to indicate that the client will only use + // RasterInterface for OOP rasterization. TODO(backer): Eliminate once we can + // CPU raster to SkImage via RasterInterface. SHARED_IMAGE_USAGE_OOP_RASTERIZATION = 1 << 5, // Image will be used for RGB emulation in WebGL on Mac. SHARED_IMAGE_USAGE_RGB_EMULATION = 1 << 6,
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index 86d40301..66d40d6b 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -208,12 +208,13 @@ SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage( uint32_t usage, bool* allow_legacy_mailbox) { - // wrapped_sk_image_factory_ is only used for OOPR. - constexpr auto kUsageOOPR = SHARED_IMAGE_USAGE_RASTER | - SHARED_IMAGE_USAGE_OOP_RASTERIZATION | - SHARED_IMAGE_USAGE_DISPLAY; - bool oopr_only_usage = !(usage & ~kUsageOOPR); - bool using_wrapped_sk_image = wrapped_sk_image_factory_ && oopr_only_usage; + // wrapped_sk_image_factory_ is only used for OOPR and supports + // a limited number of flags (e.g. no SHARED_IMAGE_USAGE_SCANOUT). + constexpr auto kWrappedSkImageUsage = SHARED_IMAGE_USAGE_RASTER | + SHARED_IMAGE_USAGE_OOP_RASTERIZATION | + SHARED_IMAGE_USAGE_DISPLAY; + bool using_wrapped_sk_image = + wrapped_sk_image_factory_ && (usage == kWrappedSkImageUsage); bool vulkan_usage = using_vulkan_ && (usage & SHARED_IMAGE_USAGE_DISPLAY); bool gl_usage = usage & SHARED_IMAGE_USAGE_GLES2;
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h index c51cb5f..acd37899 100644 --- a/gpu/command_buffer/tests/webgpu_test.h +++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -27,7 +27,8 @@ Options(); // Shared memory limits - SharedMemoryLimits shared_memory_limits = {}; + SharedMemoryLimits shared_memory_limits = + SharedMemoryLimits::ForWebGPUContext(); }; WebGPUTest();
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 1b80593..13964b8 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -679,6 +679,12 @@ } } +builder_mixins { + name: "builderless" + auto_builder_dimension: NO + dimensions: "builderless:1" +} + buckets { name: "ci" acl_sets: "ci" @@ -711,6 +717,7 @@ builders { name: "Android arm Builder (dbg)" mixins: "android-ci" + mixins: "builderless" dimensions: "os:Ubuntu-14.04" execution_timeout_secs: 14400 # 4h } @@ -718,6 +725,7 @@ builders { name: "Android arm64 Builder (dbg)" mixins: "android-ci" + mixins: "builderless" mixins: "goma-many-jobs-for-ci" dimensions: "os:Ubuntu-14.04" execution_timeout_secs: 14400 # 4h @@ -865,6 +873,7 @@ builders { name: "Android x64 Builder (dbg)" mixins: "android-ci" + mixins: "builderless" dimensions: "os:Ubuntu-14.04" execution_timeout_secs: 14400 # 4h } @@ -872,6 +881,7 @@ builders { name: "Android x86 Builder (dbg)" mixins: "android-ci" + mixins: "builderless" dimensions: "os:Ubuntu-14.04" } @@ -1044,6 +1054,7 @@ builders { name: "chromeos-amd64-generic-asan-rel" mixins: "chromeos-ci" + mixins: "builderless" } builders { @@ -1223,6 +1234,7 @@ name: "linux-blink-heap-concurrent-marking-tsan-rel" mixins: "fyi-ci" mixins: "linux" + mixins: "builderless" } builders { @@ -1510,62 +1522,64 @@ name: "GPU FYI Mac dEQP Builder" mixins: "mac-gpu-fyi-ci" } + # Note that the Mac testers are all thin Linux VMs, triggering jobs on the + # physical Mac hardware in the Swarming pool, and therefore use the + # linux-dawn-ci mixin. builders { name: "Mac FYI 10.14 Release (AMD)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" mixins: "gpu-slow-bot" } builders { name: "Mac FYI 10.14 Release (Intel)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" mixins: "gpu-slow-bot" } builders { name: "Mac FYI 10.14 Release (NVIDIA)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" mixins: "gpu-slow-bot" } builders { name: "Mac FYI Release (Intel)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI Debug (Intel)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac Pro FYI Release (AMD)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" mixins: "gpu-slow-bot" } builders { name: "Mac FYI Retina Release (NVIDIA)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI Retina Debug (NVIDIA)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { - # TODO(kbr): testing running this on a thin Linux VM. name: "Mac FYI Retina Release (AMD)" mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI Retina Debug (AMD)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI Experimental Release (Intel)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI Experimental Retina Release (AMD)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI Experimental Retina Release (NVIDIA)" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" # This bot has one machine backing its tests at the moment. # If it gets more, this should be switched back to gpu-slow-bot. # See crbug.com/853307 for more context. @@ -1573,16 +1587,16 @@ } builders { name: "Mac FYI GPU ASAN Release" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" execution_timeout_secs: 14400 # 4h } builders { name: "Mac FYI dEQP Release AMD" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } builders { name: "Mac FYI dEQP Release Intel" - mixins: "mac-gpu-fyi-ci" + mixins: "linux-gpu-fyi-ci" } # iOS bots. @@ -3660,6 +3674,7 @@ builders { mixins: "ios-try" name: "ios-simulator-eg" } builders { mixins: "ios-try" name: "ios-simulator-xcode-clang" } builders { mixins: "ios-try" name: "ios-slimnav" } + builders { mixins: "mac-dawn-try" name: "dawn-mac-x64-deps-rel" } builders { mixins: "mac-angle-try" name: "mac-angle-rel" } builders { mixins: "mac-angle-try" name: "mac_angle_compile_dbg_ng" } builders { mixins: "mac-angle-try" name: "mac_angle_dbg_ng" }
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm index 0b6ac7f..33a24224 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
@@ -150,12 +150,17 @@ kSelectedTabHistogramName, TabUsageRecorder::IN_MEMORY, 1, failureBlock); // Evict the tab. - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); + GREYAssertTrue(chrome_test_util::IsIncognitoMode(), @"Failed to switch to incognito mode"); // Switch back to the normal tabs. Should be on tab one. - SwitchToNormalMode(); + + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + [ChromeEarlGrey waitForWebViewContainingText:kURL1FirstWord]; histogramTester.ExpectTotalCount(kSelectedTabHistogramName, 2, failureBlock); @@ -216,11 +221,14 @@ // Evict the tab. Create a dummy tab so that switching back to normal mode // does not trigger a reload immediately. [ChromeEarlGrey openNewTab]; - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); [ChromeEarlGrey waitForIncognitoTabCount:1]; // Switch back to the normal tabs. Should be on tab one. - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + chrome_test_util::SelectTabAtIndexInCurrentMode(0); [ChromeEarlGrey waitForWebViewContainingText:kURL1FirstWord]; @@ -254,12 +262,17 @@ @"Fail to state tabs as cold start tabs"); // Open two incognito tabs with urls, clearing normal tabs from memory. - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* firstTabError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(firstTabError, firstTabError.localizedDescription); + NSError* secondTabError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(secondTabError, secondTabError.localizedDescription); + [ChromeEarlGrey waitForIncognitoTabCount:2]; // Switch back to the normal tabs. - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + [ChromeEarlGrey waitForWebViewContainingText:kURL2FirstWord]; // Select the other one so it also reloads. @@ -308,13 +321,16 @@ @"Fail to simulate tab backgrounding."); // Open incognito and clear normal tabs from memory. - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); GREYAssertTrue(chrome_test_util::IsIncognitoMode(), @"Failed to switch to incognito mode"); histogramTester.ExpectTotalCount(kEvictedTabReloadTime, 0, failureBlock); // Switch back to the normal tabs. - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + [ChromeEarlGrey waitForWebViewContainingText:kURL2FirstWord]; const GURL url1 = web::test::HttpServer::MakeUrl(kTestUrl1); @@ -345,8 +361,12 @@ [ChromeEarlGrey closeAllTabsInCurrentMode]; GURL URL = web::test::HttpServer::MakeUrl(kTestUrl1); NewMainTabWithURL(URL, kURL1FirstWord); - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); - SwitchToNormalMode(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); + + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + [ChromeEarlGrey waitForWebViewContainingText:kURL1FirstWord]; [ChromeEarlGrey waitForMainTabCount:1]; @@ -378,12 +398,18 @@ [ChromeEarlGrey openNewTab]; [ChromeEarlGrey openNewTab]; chrome_test_util::LoadUrl(slowURL); - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); web::test::SetUpHttpServer(std::make_unique<web::DelayedResponseProvider>( std::make_unique<HtmlResponseProvider>(responses), kSlowURLDelay)); - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + // TODO(crbug.com/951600): We avoid asserting directly unless the test fails, + // due to timing issues. + if (switchError != nil) { + GREYAssert(false, switchError.localizedDescription); + } // Turn off synchronization of GREYAssert to test the pending states. [[GREYConfiguration sharedInstance] @@ -425,11 +451,17 @@ NewMainTabWithURL(slowURL, "Slow"); - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); web::test::SetUpHttpServer(std::make_unique<web::DelayedResponseProvider>( std::make_unique<HtmlResponseProvider>(responses), kSlowURLDelay)); - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + // TODO(crbug.com/951600): We avoid asserting directly unless the test fails, + // due to timing issues. + if (switchError != nil) { + GREYAssert(false, switchError.localizedDescription); + } // Letting page load start. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); @@ -470,9 +502,12 @@ }; NewMainTabWithURL(slowURL, responses[slowURL]); - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + [ChromeEarlGreyUI openSettingsMenu]; [ChromeEarlGreyUI tapSettingsMenuButton:SettingsMenuPrivacyButton()]; [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] @@ -500,11 +535,17 @@ [ChromeEarlGrey openNewTab]; chrome_test_util::LoadUrl(slowURL); - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); web::test::SetUpHttpServer(std::make_unique<web::DelayedResponseProvider>( std::make_unique<HtmlResponseProvider>(responses), kSlowURLDelay)); - SwitchToNormalMode(); + NSError* switchError = SwitchToNormalMode(); + // TODO(crbug.com/951600): We avoid asserting directly unless the test fails, + // due to timing issues. + if (switchError != nil) { + GREYAssert(false, switchError.localizedDescription); + } // Letting page load start. base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5)); @@ -585,8 +626,12 @@ NSUInteger tabIndex = chrome_test_util::GetMainTabCount() - 1; [ChromeEarlGrey openNewTab]; - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); - SwitchToNormalMode(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); + + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + chrome_test_util::SelectTabAtIndexInCurrentMode(tabIndex); [ChromeEarlGrey waitForWebViewContainingText:"arrived"]; @@ -632,8 +677,12 @@ [ChromeEarlGrey waitForWebViewContainingText:"Whee"]; NSUInteger tabIndex = chrome_test_util::GetMainTabCount() - 1; [ChromeEarlGrey openNewTab]; - OpenNewIncognitoTabUsingUIAndEvictMainTabs(); - SwitchToNormalMode(); + NSError* openError = OpenNewIncognitoTabUsingUIAndEvictMainTabs(); + GREYAssertNil(openError, openError.localizedDescription); + + NSError* switchError = SwitchToNormalMode(); + GREYAssertNil(switchError, switchError.localizedDescription); + chrome_test_util::SelectTabAtIndexInCurrentMode(tabIndex); [ChromeEarlGrey waitForWebViewContainingText:"Whee"]; @@ -665,11 +714,11 @@ web::test::HttpServer::MakeUrl("http://destination"); // Make the link that cover the whole page so that long pressing the web view // will trigger the link context menu. - responses[initialURL] = base::StringPrintf( - "<body style='width:auto; height:auto;'><a href='%s' " - "id='link'><div style='width:100%%; " - "height:100%%;'>link</div></a></body>", - destinationURL.spec().c_str()); + responses[initialURL] = + base::StringPrintf("<body style='width:auto; height:auto;'><a href='%s' " + "id='link'><div style='width:100%%; " + "height:100%%;'>link</div></a></body>", + destinationURL.spec().c_str()); responses[destinationURL] = "Whee!"; web::test::SetUpHttpServer(std::make_unique<HtmlResponseProvider>(responses)); chrome_test_util::HistogramTester histogramTester;
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_test_util.h b/ios/chrome/browser/metrics/tab_usage_recorder_test_util.h index 3ca044c2..3a5224a 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_test_util.h +++ b/ios/chrome/browser/metrics/tab_usage_recorder_test_util.h
@@ -5,14 +5,16 @@ #ifndef IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_TEST_UTIL_H_ #define IOS_CHROME_BROWSER_METRICS_TAB_USAGE_RECORDER_TEST_UTIL_H_ +@class NSError; + namespace tab_usage_recorder_test_util { // Opens a new incognito tab using the UI and evicts any main tab model tabs. -void OpenNewIncognitoTabUsingUIAndEvictMainTabs(); +NSError* OpenNewIncognitoTabUsingUIAndEvictMainTabs(); // Switches to normal mode using the tab switcher and selects the // previously-selected normal tab. Assumes current mode is Incognito. -void SwitchToNormalMode(); +NSError* SwitchToNormalMode(); } // namespace tab_usage_recorder_test_util
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm b/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm index e5a4c5f..9a1e59cc 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder_test_util.mm
@@ -21,6 +21,7 @@ #import "ios/chrome/test/app/tab_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_error_util.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -35,7 +36,7 @@ // Shows the tab switcher by tapping the switcher button. Works on both phone // and tablet. -void ShowTabSwitcher() { +bool ShowTabSwitcher() { id<GREYMatcher> matcher = chrome_test_util::TabGridOpenButton(); // Perform a tap with a timeout. Occasionally EG doesn't sync up properly to // the animations of tab switcher, so it is necessary to poll here. @@ -50,15 +51,14 @@ }]; // Wait until 2 seconds for the tap. - BOOL hasClicked = [tapTabSwitcher waitWithTimeout:2]; - GREYAssertTrue(hasClicked, @"Tab switcher could not be tapped."); + return [tapTabSwitcher waitWithTimeout:2]; } } // namespace namespace tab_usage_recorder_test_util { -void OpenNewIncognitoTabUsingUIAndEvictMainTabs() { +NSError* OpenNewIncognitoTabUsingUIAndEvictMainTabs() { int nb_incognito_tab = chrome_test_util::GetIncognitoTabCount(); [ChromeEarlGreyUI openToolsMenu]; id<GREYMatcher> new_incognito_tab_button_matcher = @@ -69,18 +69,29 @@ ConditionBlock condition = ^bool { return chrome_test_util::IsIncognitoMode(); }; - GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(kWaitElementTimeout, - condition), - @"Waiting switch to incognito mode."); + + bool success = base::test::ios::WaitUntilConditionOrTimeout( + kWaitElementTimeout, condition); + if (!success) { + return chrome_test_util::NSErrorWithLocalizedDescription( + @"Waiting switch to incognito mode."); + } + chrome_test_util::EvictOtherTabModelTabs(); + return nil; } -void SwitchToNormalMode() { - GREYAssertTrue(chrome_test_util::IsIncognitoMode(), - @"Switching to normal mode is only allowed from Incognito."); +NSError* SwitchToNormalMode() { + if (!chrome_test_util::IsIncognitoMode()) { + return chrome_test_util::NSErrorWithLocalizedDescription( + @"Switching to normal mode is only allowed from Incognito."); + } // Enter the tab grid to switch modes. - ShowTabSwitcher(); + if (!ShowTabSwitcher()) { + return chrome_test_util::NSErrorWithLocalizedDescription( + @"Tab switcher could not be tapped."); + } // Switch modes and exit the tab grid. TabModel* model = chrome_test_util::GetMainController() @@ -99,13 +110,17 @@ ConditionBlock condition = ^bool { return !chrome_test_util::IsIncognitoMode(); }; - GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(kWaitElementTimeout, - condition), - @"Waiting switch to normal mode."); + + if (!base::test::ios::WaitUntilConditionOrTimeout(kWaitElementTimeout, + condition)) { + return chrome_test_util::NSErrorWithLocalizedDescription( + @"Waiting switch to normal mode."); + } [[GREYConfiguration sharedInstance] setValue:@(YES) forConfigKey:kGREYConfigKeySynchronizationEnabled]; + return nil; } } // namespace tab_usage_recorder_test_util
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm index ef801d04..5f5e5308 100644 --- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
@@ -58,7 +58,7 @@ // YES if the view should be dismissed after any touch gesture has ended. @property(nonatomic, assign) BOOL shouldDismissAfterTouchesEnded; // UIButton with title |self.buttonText|, which triggers the Infobar action. -@property(nonatomic, weak) UIButton* infobarButton; +@property(nonatomic, strong) UIButton* infobarButton; // UILabel displaying |self.titleText|. @property(nonatomic, strong) UILabel* titleLabel; // UILabel displaying |self.subTitleText|.
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm index ee26ceb..22907ad 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm
@@ -81,6 +81,9 @@ self.modalViewController.infobarModalDelegate = self; self.modalViewController.username = self.passwordInfoBarDelegate->GetUserNameText(); + self.modalViewController.saveButtonText = + base::SysUTF16ToNSString(self.passwordInfoBarDelegate->GetButtonLabel( + ConfirmInfoBarDelegate::BUTTON_OK)); self.modalViewController.URL = self.passwordInfoBarDelegate->GetURLHostText(); }
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.h b/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.h index a524c21..f956098 100644 --- a/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.h +++ b/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.h
@@ -19,6 +19,8 @@ @property(nonatomic, copy) NSString* username; // The URL being displayed in the InfobarModal. @property(nonatomic, copy) NSString* URL; +// The text used for the save credentials button. +@property(nonatomic, copy) NSString* saveButtonText; @end
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.mm index a9cc9de..40aaa9d 100644 --- a/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.mm +++ b/ios/chrome/browser/ui/infobars/modals/infobar_password_table_view_controller.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -27,9 +28,18 @@ ItemTypeURL = kItemTypeEnumZero, ItemTypeUsername, ItemTypePassword, - ItemTypeSavePassword, + ItemTypeSaveCredentials, }; +@interface InfobarPasswordTableViewController () +// Item that holds the Username TextField information. +@property(nonatomic, strong) TableViewTextEditItem* usernameItem; +// Item that holds the Password TextField information. +@property(nonatomic, strong) TableViewTextEditItem* passwordItem; +// Item that holds the SaveCredentials Button information. +@property(nonatomic, strong) TableViewTextButtonItem* saveCredentialsItem; +@end + @implementation InfobarPasswordTableViewController #pragma mark - ViewController Lifecycle @@ -78,30 +88,30 @@ [model addItem:URLDetailItem toSectionWithIdentifier:SectionIdentifierContent]; - TableViewDetailIconItem* usernameDetailItem = - [[TableViewDetailIconItem alloc] initWithType:ItemTypeUsername]; - usernameDetailItem.text = + TableViewTextEditItem* usernameTextEditItem = + [[TableViewTextEditItem alloc] initWithType:ItemTypeUsername]; + usernameTextEditItem.textFieldName = l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME); - usernameDetailItem.detailText = self.username; - [model addItem:usernameDetailItem + usernameTextEditItem.textFieldValue = self.username; + usernameTextEditItem.textFieldEnabled = YES; + [model addItem:usernameTextEditItem toSectionWithIdentifier:SectionIdentifierContent]; - TableViewDetailIconItem* passwordDetailItem = - [[TableViewDetailIconItem alloc] initWithType:ItemTypePassword]; - passwordDetailItem.text = + self.passwordItem = + [[TableViewTextEditItem alloc] initWithType:ItemTypePassword]; + self.passwordItem.textFieldName = l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD); // TODO(crbug.com/927064): Set the number of dots depending on Password // length? - passwordDetailItem.detailText = @"•••••••••"; - [model addItem:passwordDetailItem + self.passwordItem.textFieldValue = @"•••••••••"; + self.passwordItem.textFieldEnabled = YES; + [model addItem:self.passwordItem toSectionWithIdentifier:SectionIdentifierContent]; - TableViewTextButtonItem* savePasswordButtonItem = - [[TableViewTextButtonItem alloc] initWithType:ItemTypeSavePassword]; - // TODO(crbug.com/927064): Create IDS String for this once we're sure about - // the exact text. - savePasswordButtonItem.buttonText = @"Save Password"; - [model addItem:savePasswordButtonItem + self.saveCredentialsItem = + [[TableViewTextButtonItem alloc] initWithType:ItemTypeSaveCredentials]; + self.saveCredentialsItem.buttonText = self.saveButtonText; + [model addItem:self.saveCredentialsItem toSectionWithIdentifier:SectionIdentifierContent]; } @@ -111,16 +121,30 @@ cellForRowAtIndexPath:(NSIndexPath*)indexPath { UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; - NSInteger itemTypeSelected = - [self.tableViewModel itemTypeForIndexPath:indexPath]; + ItemType itemType = static_cast<ItemType>( + [self.tableViewModel itemTypeForIndexPath:indexPath]); - if (itemTypeSelected == ItemTypeSavePassword) { - TableViewTextButtonCell* tableViewTextButtonCell = - base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell); - [tableViewTextButtonCell.button - addTarget:self.infobarModalDelegate - action:@selector(modalInfobarButtonWasPressed:) - forControlEvents:UIControlEventTouchUpInside]; + switch (itemType) { + case ItemTypeSaveCredentials: { + TableViewTextButtonCell* tableViewTextButtonCell = + base::mac::ObjCCastStrict<TableViewTextButtonCell>(cell); + [tableViewTextButtonCell.button + addTarget:self.infobarModalDelegate + action:@selector(modalInfobarButtonWasPressed:) + forControlEvents:UIControlEventTouchUpInside]; + break; + } + case ItemTypeUsername: + case ItemTypePassword: { + TableViewTextEditCell* editCell = + base::mac::ObjCCast<TableViewTextEditCell>(cell); + [editCell.textField addTarget:self + action:@selector(updateSaveCredentialsButtonState) + forControlEvents:UIControlEventEditingChanged]; + break; + } + case ItemTypeURL: + break; } return cell; @@ -128,6 +152,15 @@ #pragma mark - Private Methods +- (void)updateSaveCredentialsButtonState { + BOOL currentButtonState = [self.saveCredentialsItem isEnabled]; + BOOL newButtonState = [self.passwordItem.textFieldValue length] ? YES : NO; + if (currentButtonState != newButtonState) { + self.saveCredentialsItem.enabled = newButtonState; + [self reconfigureCellsForItems:@[ self.saveCredentialsItem ]]; + } +} + - (void)dismissInfobarModal:(UIButton*)sender { [self.infobarModalDelegate dismissInfobarModal:sender completion:nil]; }
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h index 78d81bd52..fca2d28 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h
@@ -14,6 +14,7 @@ // Text being displayed above the button. @property(nonatomic, readwrite, strong) NSString* text; + // Text for cell button. @property(nonatomic, readwrite, strong) NSString* buttonText; @@ -23,6 +24,10 @@ // Accessibility identifier that will assigned to the button. @property(nonatomic, strong) NSString* buttonAccessibilityIdentifier; +// Whether the Item's button should be enabled or not. Button is enabled by +// default. +@property(nonatomic, assign, getter=isEnabled) BOOL enabled; + @end // TableViewTextButtonCell contains a textLabel and a UIbutton @@ -31,6 +36,7 @@ // Cell text information. @property(nonatomic, strong) UILabel* textLabel; + // Action button. Note: Set action method in the TableView datasource method. @property(nonatomic, strong) UIButton* button;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm index 8e40c89d..774bdb7 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.mm
@@ -16,6 +16,8 @@ const CGFloat grayHexColor = 0x6d6d72; // Action button blue background color. const CGFloat blueHexColor = 0x1A73E8; +// Alpha value for the disabled action button. +const CGFloat disabledButtonAlpha = 0.5; // Vertical spacing between stackView and cell contentView. const CGFloat stackViewVerticalSpacing = 9.0; // Horizontal spacing between stackView and cell contentView. @@ -42,6 +44,7 @@ self = [super initWithType:type]; if (self) { self.cellClass = [TableViewTextButtonCell class]; + _enabled = YES; } return self; } @@ -58,6 +61,11 @@ ? self.buttonBackgroundColor : UIColorFromRGB(blueHexColor); [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + cell.button.enabled = self.enabled; + if (!self.enabled) { + cell.button.backgroundColor = [cell.button.backgroundColor + colorWithAlphaComponent:disabledButtonAlpha]; + } } @end
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index a6666ca..a3718969 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -227,6 +227,8 @@ "chrome_earl_grey.mm", "chrome_earl_grey_ui.h", "chrome_earl_grey_ui.mm", + "chrome_error_util.h", + "chrome_error_util.mm", "chrome_matchers.h", "chrome_matchers.mm", "chrome_matchers_shorthand.h",
diff --git a/ios/chrome/test/earl_grey/chrome_error_util.h b/ios/chrome/test/earl_grey/chrome_error_util.h new file mode 100644 index 0000000..c3b7258 --- /dev/null +++ b/ios/chrome/test/earl_grey/chrome_error_util.h
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_TEST_EARL_GREY_CHROME_ERROR_UTIL_H_ +#define IOS_CHROME_TEST_EARL_GREY_CHROME_ERROR_UTIL_H_ + +@class NSError; +@class NSString; + +namespace chrome_test_util { + +// Returns a NSError with generic domain and error code, and the provided string +// as localizedDescription. +NSError* NSErrorWithLocalizedDescription(NSString* error_description); + +} // namespace chrome_test_util + +#endif // IOS_CHROME_TEST_EARL_GREY_CHROME_ERROR_UTIL_H_
diff --git a/ios/chrome/test/earl_grey/chrome_error_util.mm b/ios/chrome/test/earl_grey/chrome_error_util.mm new file mode 100644 index 0000000..1d9207bd --- /dev/null +++ b/ios/chrome/test/earl_grey/chrome_error_util.mm
@@ -0,0 +1,25 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/test/earl_grey/chrome_error_util.h" + +#import <Foundation/Foundation.h> + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace chrome_test_util { + +NSError* NSErrorWithLocalizedDescription(NSString* error_description) { + NSDictionary* userInfo = @{ + NSLocalizedDescriptionKey : error_description, + }; + + return [[NSError alloc] initWithDomain:@"com.google.chrome.errorDomain" + code:0 + userInfo:userInfo]; +} + +} // namespace chrome_test_util
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium index 24df9a2..fb3a9cd 100644 --- a/ios/third_party/material_components_ios/README.chromium +++ b/ios/third_party/material_components_ios/README.chromium
@@ -1,7 +1,7 @@ Name: Material Components for iOS URL: https://github.com/material-components/material-components-ios Version: 0 -Revision: d4fdb374214cfe2010d167338affd3fa9e67263c +Revision: 82cfc2ceebd3d1bfbaf6b5129d08f2b1f4054508 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/ios/third_party/material_roboto_font_loader_ios/README.chromium b/ios/third_party/material_roboto_font_loader_ios/README.chromium index 5cec40ca..e9730cc 100644 --- a/ios/third_party/material_roboto_font_loader_ios/README.chromium +++ b/ios/third_party/material_roboto_font_loader_ios/README.chromium
@@ -1,7 +1,7 @@ Name: Material Roboto Font Loader iOS URL: https://github.com/material-foundation/material-roboto-font-loader-ios Version: 0 -Revision: 4aa51e906e5671c71d24e991f1f10d782a58409f +Revision: bc63eabbbd1e14cee0779b05827e08db2e413553 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index eccf4872..c99a549 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -72,6 +72,7 @@ ":buildflags", ":common", ":image_processor", + ":video_frame_mapper", "//base", "//gpu", "//media",
diff --git a/media/gpu/linux/platform_video_frame_utils.cc b/media/gpu/linux/platform_video_frame_utils.cc index 81ac1d8a4..e68df74 100644 --- a/media/gpu/linux/platform_video_frame_utils.cc +++ b/media/gpu/linux/platform_video_frame_utils.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/scoped_file.h" +#include "build/build_config.h" #include "media/base/scopedfd_helper.h" #include "media/base/video_frame_layout.h" #include "media/gpu/format_utils.h" @@ -102,18 +103,28 @@ DCHECK(video_frame); gfx::GpuMemoryBufferHandle handle; +#if defined(OS_LINUX) handle.type = gfx::NATIVE_PIXMAP; std::vector<base::ScopedFD> duped_fds = DuplicateFDs(video_frame->DmabufFds()); const size_t num_planes = VideoFrame::NumPlanes(video_frame->format()); - DCHECK_EQ(num_planes, duped_fds.size()); + const size_t num_buffers = video_frame->layout().buffer_sizes().size(); + DCHECK_EQ(video_frame->layout().planes().size(), num_planes); + + // TODO(crbug.com/946880): Handles case that num_planes mismatches num_buffers for (size_t i = 0; i < num_planes; ++i) { const auto& plane = video_frame->layout().planes()[i]; + size_t buffer_size = 0; + if (i < num_buffers) + buffer_size = video_frame->layout().buffer_sizes()[i]; handle.native_pixmap_handle.planes.emplace_back( - plane.stride, plane.offset, i, std::move(duped_fds[i]), plane.modifier); + plane.stride, plane.offset, buffer_size, std::move(duped_fds[i]), + plane.modifier); } - +#else + NOTREACHED(); +#endif // defined(OS_LINUX) return handle; }
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn index 60eb18f..de591d3f 100644 --- a/media/gpu/test/BUILD.gn +++ b/media/gpu/test/BUILD.gn
@@ -50,7 +50,6 @@ ":decode_helpers", ":helpers", "//media/gpu", - "//media/gpu:video_frame_mapper", ] } @@ -64,7 +63,6 @@ ":helpers", ":render_helpers", "//media/gpu", - "//media/gpu:video_frame_mapper", "//ui/gfx/codec:codec", ] } @@ -100,7 +98,6 @@ ] deps = [ "//media/gpu", - "//media/gpu:video_frame_mapper", ] }
diff --git a/media/gpu/test/video_player/video.cc b/media/gpu/test/video_player/video.cc index 91be797..f731f1a2 100644 --- a/media/gpu/test/video_player/video.cc +++ b/media/gpu/test/video_player/video.cc
@@ -46,21 +46,21 @@ int64_t file_size; if (!base::GetFileSize(file_path_, &file_size) || (file_size < 0)) { - VLOGF(1) << "Failed to read file size: " << file_path_; + LOG(ERROR) << "Failed to read file size: " << file_path_; return false; } std::vector<uint8_t> data(file_size); if (base::ReadFile(file_path_, reinterpret_cast<char*>(data.data()), base::checked_cast<int>(file_size)) != file_size) { - VLOGF(1) << "Failed to read file: " << file_path_; + LOG(ERROR) << "Failed to read file: " << file_path_; return false; } data_ = std::move(data); if (!LoadMetadata()) { - VLOGF(1) << "Failed to load metadata"; + LOG(ERROR) << "Failed to load metadata"; return false; } @@ -114,7 +114,7 @@ bool Video::LoadMetadata() { if (IsMetadataLoaded()) { - VLOGF(1) << "Video metadata is already loaded"; + LOG(ERROR) << "Video metadata is already loaded"; return false; } @@ -125,14 +125,14 @@ base::Optional<base::FilePath> resolved_path = ResolveFilePath(metadata_file_path_); if (!resolved_path) { - VLOGF(1) << "Video metadata file not found: " << metadata_file_path_; + LOG(ERROR) << "Video metadata file not found: " << metadata_file_path_; return false; } metadata_file_path_ = resolved_path.value(); std::string json_data; if (!base::ReadFileToString(metadata_file_path_, &json_data)) { - VLOGF(1) << "Failed to read video metadata file: " << metadata_file_path_; + LOG(ERROR) << "Failed to read video metadata file: " << metadata_file_path_; return false; } @@ -140,28 +140,28 @@ std::unique_ptr<base::Value> metadata( reader.ReadToValueDeprecated(json_data)); if (!metadata) { - VLOGF(1) << "Failed to parse video metadata: " << metadata_file_path_ - << ": " << reader.GetErrorMessage(); + LOG(ERROR) << "Failed to parse video metadata: " << metadata_file_path_ + << ": " << reader.GetErrorMessage(); return false; } const base::Value* profile = metadata->FindKeyOfType("profile", base::Value::Type::STRING); if (!profile) { - VLOGF(1) << "Key \"profile\" is not found in " << metadata_file_path_; + LOG(ERROR) << "Key \"profile\" is not found in " << metadata_file_path_; return false; } profile_ = ConvertStringtoProfile(profile->GetString()); codec_ = ConvertProfileToCodec(profile_); if (profile_ == VIDEO_CODEC_PROFILE_UNKNOWN || codec_ == kUnknownVideoCodec) { - VLOGF(1) << profile->GetString() << " is not supported"; + LOG(ERROR) << profile->GetString() << " is not supported"; return false; } const base::Value* num_frames = metadata->FindKeyOfType("num_frames", base::Value::Type::INTEGER); if (!num_frames) { - VLOGF(1) << "Key \"num_frames\" is not found in " << metadata_file_path_; + LOG(ERROR) << "Key \"num_frames\" is not found in " << metadata_file_path_; return false; } num_frames_ = static_cast<uint32_t>(num_frames->GetInt()); @@ -169,7 +169,8 @@ const base::Value* num_fragments = metadata->FindKeyOfType("num_fragments", base::Value::Type::INTEGER); if (!num_fragments) { - VLOGF(1) << "Key \"num_fragments\" is not found in " << metadata_file_path_; + LOG(ERROR) << "Key \"num_fragments\" is not found in " + << metadata_file_path_; return false; } num_fragments_ = static_cast<uint32_t>(num_fragments->GetInt()); @@ -177,13 +178,13 @@ const base::Value* width = metadata->FindKeyOfType("width", base::Value::Type::INTEGER); if (!width) { - VLOGF(1) << "Key \"width\" is not found in " << metadata_file_path_; + LOG(ERROR) << "Key \"width\" is not found in " << metadata_file_path_; return false; } const base::Value* height = metadata->FindKeyOfType("height", base::Value::Type::INTEGER); if (!height) { - VLOGF(1) << "Key \"height\" is not found in " << metadata_file_path_; + LOG(ERROR) << "Key \"height\" is not found in " << metadata_file_path_; return false; } resolution_ = gfx::Size(static_cast<uint32_t>(width->GetInt()), @@ -192,7 +193,8 @@ const base::Value* md5_checksums = metadata->FindKeyOfType("md5_checksums", base::Value::Type::LIST); if (!md5_checksums) { - VLOGF(1) << "Key \"md5_checksums\" is not found in " << metadata_file_path_; + LOG(ERROR) << "Key \"md5_checksums\" is not found in " + << metadata_file_path_; return false; } for (const base::Value& checksum : md5_checksums->GetList()) { @@ -202,8 +204,8 @@ const base::Value* thumbnail_checksums = metadata->FindKeyOfType("thumbnail_checksums", base::Value::Type::LIST); if (!thumbnail_checksums) { - VLOGF(1) << "Key \"thumbnail_checksums\" is not found in " - << metadata_file_path_; + LOG(ERROR) << "Key \"thumbnail_checksums\" is not found in " + << metadata_file_path_; return false; } for (const base::Value& checksum : thumbnail_checksums->GetList()) {
diff --git a/media/gpu/test/video_player/video_decoder_client.cc b/media/gpu/test/video_player/video_decoder_client.cc index 09808e0..c894f02 100644 --- a/media/gpu/test/video_player/video_decoder_client.cc +++ b/media/gpu/test/video_player/video_decoder_client.cc
@@ -153,12 +153,19 @@ WaitingCB waiting_cb = base::BindRepeating([](WaitingReason) { NOTIMPLEMENTED(); }); - // TODO(dstaessens@) Currently we always create a VDA-based video decoder, - // change to use a factory that can create different types of decoders. - decoder_ = base::WrapUnique( - new TestVDAVideoDecoder(decoder_client_config_.allocation_mode, - gfx::ColorSpace(), frame_renderer_.get())); - decoder_->Initialize(config, false, nullptr, init_cb, output_cb, waiting_cb); + if (decoder_client_config_.use_vd) { + // TODO(dstaessens@) Create VD-based video decoder. + NOTIMPLEMENTED(); + } else { + // The video decoder client expects decoders to use the VD interface. We can + // use the TestVDAVideoDecoder wrapper here to test VDA-based video + // decoders. + decoder_ = base::WrapUnique( + new TestVDAVideoDecoder(decoder_client_config_.allocation_mode, + gfx::ColorSpace(), frame_renderer_.get())); + decoder_->Initialize(config, false, nullptr, init_cb, output_cb, + waiting_cb); + } DCHECK_LE(decoder_client_config_.max_outstanding_decode_requests, static_cast<size_t>(decoder_->GetMaxDecodeRequests()));
diff --git a/media/gpu/test/video_player/video_decoder_client.h b/media/gpu/test/video_player/video_decoder_client.h index 73756dc6..30bac98 100644 --- a/media/gpu/test/video_player/video_decoder_client.h +++ b/media/gpu/test/video_player/video_decoder_client.h
@@ -43,6 +43,8 @@ size_t max_outstanding_decode_requests = 1; // How the pictures buffers should be allocated. AllocationMode allocation_mode = AllocationMode::kImport; + // Use VD-based video decoders instead of VDA-based video decoders. + bool use_vd = false; }; // The video decoder client is responsible for the communication between the
diff --git a/media/gpu/test/video_player/video_player_test_environment.cc b/media/gpu/test/video_player/video_player_test_environment.cc index 4dc9586a..750084c 100644 --- a/media/gpu/test/video_player/video_player_test_environment.cc +++ b/media/gpu/test/video_player/video_player_test_environment.cc
@@ -35,7 +35,8 @@ const base::FilePath& video_path, const base::FilePath& video_metadata_path, bool enable_validator, - bool output_frames) { + bool output_frames, + bool use_vd) { auto video = std::make_unique<media::test::Video>( video_path.empty() ? base::FilePath(kDefaultTestVideoPath) : video_path, video_metadata_path); @@ -45,16 +46,18 @@ } return new VideoPlayerTestEnvironment(std::move(video), enable_validator, - output_frames); + output_frames, use_vd); } VideoPlayerTestEnvironment::VideoPlayerTestEnvironment( std::unique_ptr<media::test::Video> video, bool enable_validator, - bool output_frames) + bool output_frames, + bool use_vd) : video_(std::move(video)), enable_validator_(enable_validator), - output_frames_(output_frames) {} + output_frames_(output_frames), + use_vd_(use_vd) {} VideoPlayerTestEnvironment::~VideoPlayerTestEnvironment() = default; @@ -115,6 +118,10 @@ return output_frames_; } +bool VideoPlayerTestEnvironment::UseVD() const { + return use_vd_; +} + base::FilePath::StringType VideoPlayerTestEnvironment::GetTestName() const { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
diff --git a/media/gpu/test/video_player/video_player_test_environment.h b/media/gpu/test/video_player/video_player_test_environment.h index 6a5a4dd..e4cd659a 100644 --- a/media/gpu/test/video_player/video_player_test_environment.h +++ b/media/gpu/test/video_player/video_player_test_environment.h
@@ -30,7 +30,8 @@ const base::FilePath& video_path, const base::FilePath& video_metadata_path, bool enable_validator, - bool output_frames); + bool output_frames, + bool use_vd); ~VideoPlayerTestEnvironment() override; // Set up the video decode test environment, only called once. @@ -44,6 +45,8 @@ bool IsValidatorEnabled() const; // Check whether outputting frames is enabled. bool IsFramesOutputEnabled() const; + // Check whether we should use VD-based video decoders instead of VDA-based. + bool UseVD() const; // Get the name of the current test. base::FilePath::StringType GetTestName() const; @@ -51,12 +54,14 @@ private: VideoPlayerTestEnvironment(std::unique_ptr<media::test::Video> video, bool enable_validator, - bool output_frames); + bool output_frames, + bool use_vd); std::unique_ptr<base::test::ScopedTaskEnvironment> task_environment_; const std::unique_ptr<media::test::Video> video_; const bool enable_validator_; const bool output_frames_; + const bool use_vd_; // An exit manager is required to run callbacks on shutdown. base::AtExitManager at_exit_manager;
diff --git a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc index 3e31e41c..56279f08 100644 --- a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc +++ b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc
@@ -15,9 +15,9 @@ #include "media/gpu/vaapi/vaapi_wrapper.h" #include "media/video/picture.h" -#if defined(USE_OZONE) || defined(USE_EGL) -#include "media/gpu/vaapi/vaapi_picture_native_pixmap.h" -#endif // defined(USE_OZONE) || defined(USE_EGL) +#if defined(OS_LINUX) +#include "media/gpu/linux/platform_video_frame_utils.h" +#endif namespace media { @@ -115,11 +115,9 @@ } gfx::GpuMemoryBufferHandle gmb_handle; -#if defined(USE_OZONE) || defined(USE_EGL) - gmb_handle = - VaapiPictureNativePixmap::CreateGpuMemoryBufferHandleFromVideoFrame( - video_frame.get()); -#endif // defined(USE_OZONE) || defined(USE_EGL) +#if defined(OS_LINUX) + gmb_handle = CreateGpuMemoryBufferHandle(video_frame.get()); +#endif if (gmb_handle.is_null()) { VLOGF(1) << "Failed to CreateGMBHandleFromVideoFrame."; return nullptr;
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc index 82304a0..13ed1e9 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
@@ -50,29 +50,4 @@ return va_surface_->id(); } -// static -gfx::GpuMemoryBufferHandle -VaapiPictureNativePixmap::CreateGpuMemoryBufferHandleFromVideoFrame( - const VideoFrame* const video_frame) { - DCHECK(video_frame->HasDmaBufs()); - - const auto& planes = video_frame->layout().planes(); - const auto& fds = video_frame->DmabufFds(); - DCHECK_EQ(fds.size(), planes.size()); - - gfx::GpuMemoryBufferHandle handle; - handle.type = gfx::NATIVE_PIXMAP; - for (size_t i = 0; i < planes.size(); ++i) { - int dup_fd = HANDLE_EINTR(dup(fds[i].get())); - if (dup_fd == -1) { - PLOG(ERROR) << "Failed duplicating dmabuf fd"; - return gfx::GpuMemoryBufferHandle(); - } - - handle.native_pixmap_handle.planes.emplace_back( - planes[i].stride, planes[i].offset, 0, base::ScopedFD(dup_fd)); - } - return handle; -} - } // namespace media
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.h b/media/gpu/vaapi/vaapi_picture_native_pixmap.h index 8d70ec8a..f506341 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.h
@@ -24,7 +24,6 @@ namespace media { -class VideoFrame; class VaapiWrapper; // Implementation of VaapiPicture based on NativePixmaps. @@ -41,9 +40,6 @@ uint32_t texture_target); ~VaapiPictureNativePixmap() override; - static gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferHandleFromVideoFrame( - const VideoFrame* const video_frame); - // VaapiPicture implementation. bool DownloadFromSurface(const scoped_refptr<VASurface>& va_surface) override; bool AllowOverlay() const override;
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index f9bbfd6..0a70709 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -41,8 +41,8 @@ #include "media/gpu/vp8_reference_frame_vector.h" #include "media/gpu/vp9_reference_frame_vector.h" -#if defined(OS_POSIX) -#include "media/gpu/vaapi/vaapi_picture_native_pixmap.h" +#if defined(OS_LINUX) +#include "media/gpu/linux/platform_video_frame_utils.h" #endif #define NOTIFY_ERROR(error, msg) \ @@ -555,10 +555,8 @@ vaapi_wrapper_, MakeGLContextCurrentCallback(), BindGLImageCallback(), PictureBuffer(kDummyPictureBufferId, frame->coded_size())); gfx::GpuMemoryBufferHandle gmb_handle; -#if defined(OS_POSIX) - gmb_handle = - VaapiPictureNativePixmap::CreateGpuMemoryBufferHandleFromVideoFrame( - frame.get()); +#if defined(OS_LINUX) + gmb_handle = CreateGpuMemoryBufferHandle(frame.get()); #endif if (gmb_handle.is_null()) { NOTIFY_ERROR(kPlatformFailureError,
diff --git a/media/gpu/video_decode_accelerator_perf_tests.cc b/media/gpu/video_decode_accelerator_perf_tests.cc index 48245aa..ba41040f 100644 --- a/media/gpu/video_decode_accelerator_perf_tests.cc +++ b/media/gpu/video_decode_accelerator_perf_tests.cc
@@ -20,6 +20,29 @@ namespace { +// Video decoder perf tests usage message. +constexpr const char* usage_msg = + "usage: video_decode_accelerator_perf_tests\n" + " [-v=<level>] [--vmodule=<config>] [--use_vd] [--gtest_help]\n" + " [--help] [<video path>] [<video metadata path>]\n"; + +// Video decoder perf tests help message. +constexpr const char* help_msg = + "Run the video decode accelerator performance tests on the video\n" + "specified by <video path>. If no <video path> is given the default\n" + "\"test-25fps.h264\" video will be used.\n" + "\nThe <video metadata path> should specify the location of a json file\n" + "containing the video's metadata, such as frame checksums. By default\n" + "<video path>.json will be used.\n" + "\nThe following arguments are supported:\n" + " -v enable verbose mode, e.g. -v=2.\n" + " --vmodule enable verbose mode for the specified module,\n" + " e.g. --vmodule=*media/gpu*=2.\n" + " --use_vd use the new VD-based video decoders, instead of\n" + " the default VDA-based video decoders.\n" + " --gtest_help display the gtest help and exit.\n" + " --help display this help and exit.\n"; + media::test::VideoPlayerTestEnvironment* g_env; // Default output folder used to store performance metrics. @@ -147,9 +170,13 @@ auto performance_evaluator = std::make_unique<PerformanceEvaluator>(); performance_evaluator_ = performance_evaluator.get(); frame_processors.push_back(std::move(performance_evaluator)); + + // Use the new VD-based video decoders if requested. + VideoDecoderClientConfig config; + config.use_vd = g_env->UseVD(); + return VideoPlayer::Create(video, FrameRendererDummy::Create(), - std::move(frame_processors), - VideoDecoderClientConfig()); + std::move(frame_processors), config); } PerformanceEvaluator* performance_evaluator_; @@ -177,26 +204,53 @@ } // namespace media int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); + // Set the default test data path. + media::test::Video::SetTestDataPath(media::GetTestDataPath()); + + // Print the help message if requested. This needs to be done before + // initializing gtest, to overwrite the default gtest help message. base::CommandLine::Init(argc, argv); + const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + LOG_ASSERT(cmd_line); + if (cmd_line->HasSwitch("help")) { + std::cout << media::test::usage_msg << "\n" << media::test::help_msg; + return 0; + } // Check if a video was specified on the command line. - const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); base::CommandLine::StringVector args = cmd_line->GetArgs(); base::FilePath video_path = (args.size() >= 1) ? base::FilePath(args[0]) : base::FilePath(); base::FilePath video_metadata_path = (args.size() >= 2) ? base::FilePath(args[1]) : base::FilePath(); - // Set the default test data path. - media::test::Video::SetTestDataPath(media::GetTestDataPath()); + // Parse command line arguments. + bool use_vd = false; + base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); + for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); + it != switches.end(); ++it) { + if (it->first.find("gtest_") == 0 || // Handled by GoogleTest + it->first == "v" || it->first == "vmodule") { // Handled by Chrome + continue; + } + + if (it->first == "use_vd") { + use_vd = true; + } else { + std::cout << "unknown option: --" << it->first << "\n" + << media::test::usage_msg; + return EXIT_FAILURE; + } + } + + testing::InitGoogleTest(&argc, argv); // Set up our test environment. media::test::VideoPlayerTestEnvironment* test_environment = media::test::VideoPlayerTestEnvironment::Create( - video_path, video_metadata_path, false, false); + video_path, video_metadata_path, false, false, use_vd); if (!test_environment) - return 0; + return EXIT_FAILURE; media::test::g_env = static_cast<media::test::VideoPlayerTestEnvironment*>( testing::AddGlobalTestEnvironment(test_environment));
diff --git a/media/gpu/video_decode_accelerator_tests.cc b/media/gpu/video_decode_accelerator_tests.cc index 0970a25c..5153294 100644 --- a/media/gpu/video_decode_accelerator_tests.cc +++ b/media/gpu/video_decode_accelerator_tests.cc
@@ -22,21 +22,29 @@ // Video decoder tests usage message. constexpr const char* usage_msg = "usage: video_decode_accelerator_tests\n" - " [--help] [--disable_validator] [--output_frames]\n" + " [-v=<level>] [--vmodule=<config>] [--disable_validator]\n" + " [--output_frames] [--use_vd] [--gtest_help] [--help]\n" " [<video path>] [<video metadata path>]\n"; // Video decoder tests help message. constexpr const char* help_msg = - "Run the video decode accelerator tests on the specified video. If no\n" - "video is specified the default \"test-25fps.h264\" video will be used.\n" - "\nThe video metadata path should specify the location of a json file\n" + "Run the video decode accelerator tests on the video specified by\n" + "<video path>. If no <video path> is given the default\n" + "\"test-25fps.h264\" video will be used.\n" + "\nThe <video metadata path> should specify the location of a json file\n" "containing the video's metadata, such as frame checksums. By default\n" "<video path>.json will be used.\n" "\nThe following arguments are supported:\n" + " -v enable verbose mode, e.g. -v=2.\n" + " --vmodule enable verbose mode for the specified module,\n" + " e.g. --vmodule=*media/gpu*=2.\n" " --disable_validator disable frame validation, useful on old\n" " platforms that don't support import mode.\n" " --output_frames write all decoded video frames to the\n" " \"video_frames\" folder.\n" + " --use_vd use the new VD-based video decoders, instead of\n" + " the default VDA-based video decoders.\n" + " --gtest_help display the gtest help and exit.\n" " --help display this help and exit.\n"; media::test::VideoPlayerTestEnvironment* g_env; @@ -46,7 +54,7 @@ public: std::unique_ptr<VideoPlayer> CreateVideoPlayer( const Video* video, - const VideoDecoderClientConfig& config = VideoDecoderClientConfig(), + VideoDecoderClientConfig config = VideoDecoderClientConfig(), std::unique_ptr<FrameRenderer> frame_renderer = FrameRendererDummy::Create()) { LOG_ASSERT(video); @@ -66,6 +74,9 @@ frame_processors.push_back(VideoFrameFileWriter::Create(output_folder)); } + // Use the new VD-based video decoders if requested. + config.use_vd = g_env->UseVD(); + return VideoPlayer::Create(video, std::move(frame_renderer), std::move(frame_processors), config); } @@ -266,22 +277,19 @@ } // namespace media int main(int argc, char** argv) { - base::CommandLine::Init(argc, argv); - const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + // Set the default test data path. + media::test::Video::SetTestDataPath(media::GetTestDataPath()); // Print the help message if requested. This needs to be done before // initializing gtest, to overwrite the default gtest help message. + base::CommandLine::Init(argc, argv); + const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); LOG_ASSERT(cmd_line); if (cmd_line->HasSwitch("help")) { std::cout << media::test::usage_msg << "\n" << media::test::help_msg; return 0; } - testing::InitGoogleTest(&argc, argv); - - // Set the default test data path. - media::test::Video::SetTestDataPath(media::GetTestDataPath()); - // Check if a video was specified on the command line. base::CommandLine::StringVector args = cmd_line->GetArgs(); base::FilePath video_path = @@ -292,6 +300,7 @@ // Parse command line arguments. bool enable_validator = true; bool output_frames = false; + bool use_vd = false; base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); it != switches.end(); ++it) { @@ -304,19 +313,24 @@ enable_validator = false; } else if (it->first == "output_frames") { output_frames = true; + } else if (it->first == "use_vd") { + use_vd = true; } else { std::cout << "unknown option: --" << it->first << "\n" << media::test::usage_msg; - return 0; + return EXIT_FAILURE; } } + testing::InitGoogleTest(&argc, argv); + // Set up our test environment. media::test::VideoPlayerTestEnvironment* test_environment = media::test::VideoPlayerTestEnvironment::Create( - video_path, video_metadata_path, enable_validator, output_frames); + video_path, video_metadata_path, enable_validator, output_frames, + use_vd); if (!test_environment) - return 0; + return EXIT_FAILURE; media::test::g_env = static_cast<media::test::VideoPlayerTestEnvironment*>( testing::AddGlobalTestEnvironment(test_environment));
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc index 7919d47..275fa7b 100644 --- a/services/ws/client_root.cc +++ b/services/ws/client_root.cc
@@ -8,6 +8,7 @@ #include "base/callback_forward.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/trace_event/trace_event.h" #include "components/viz/common/surfaces/surface_info.h" #include "components/viz/host/host_frame_sink_manager.h" #include "services/ws/client_change.h" @@ -331,6 +332,9 @@ void ClientRoot::NotifyClientOfNewBounds() { last_bounds_ = GetBoundsToSend(window_); auto id = ProxyWindow::GetMayBeNull(window_)->local_surface_id_allocation(); + TRACE_EVENT_WITH_FLOW0("ui", "ClientRoot::NotifyClientOfNewBounds", + id->local_surface_id().hash(), + TRACE_EVENT_FLAG_FLOW_OUT); window_tree_->window_tree_client_->OnWindowBoundsChanged( window_tree_->TransportIdForWindow(window_), last_bounds_, ProxyWindow::GetMayBeNull(window_)->local_surface_id_allocation());
diff --git a/services/ws/input_devices/input_device_server.cc b/services/ws/input_devices/input_device_server.cc index f8b82b2..072be9d 100644 --- a/services/ws/input_devices/input_device_server.cc +++ b/services/ws/input_devices/input_device_server.cc
@@ -57,6 +57,8 @@ OnTouchpadDeviceConfigurationChanged(); if (input_device_types & ui::InputDeviceEventObserver::kTouchscreen) OnTouchscreenDeviceConfigurationChanged(); + if (input_device_types & ui::InputDeviceEventObserver::kUncategorized) + OnUncategorizedDeviceConfigurationChanged(); } void InputDeviceServer::OnKeyboardDeviceConfigurationChanged() { @@ -112,6 +114,7 @@ observer->OnDeviceListsComplete( manager_->GetKeyboardDevices(), manager_->GetTouchscreenDevices(), manager_->GetMouseDevices(), manager_->GetTouchpadDevices(), + manager_->GetUncategorizedDevices(), manager_->AreTouchscreenTargetDisplaysValid()); } @@ -129,4 +132,14 @@ }); } +void InputDeviceServer::OnUncategorizedDeviceConfigurationChanged() { + if (!manager_->AreDeviceListsComplete()) + return; + + auto& devices = manager_->GetUncategorizedDevices(); + observers_.ForAllPtrs([&devices](mojom::InputDeviceObserverMojo* observer) { + observer->OnUncategorizedDeviceConfigurationChanged(devices); + }); +} + } // namespace ws
diff --git a/services/ws/input_devices/input_device_server.h b/services/ws/input_devices/input_device_server.h index 01c4763..5830d727 100644 --- a/services/ws/input_devices/input_device_server.h +++ b/services/ws/input_devices/input_device_server.h
@@ -51,6 +51,7 @@ void OnTouchscreenDeviceConfigurationChanged(); void OnMouseDeviceConfigurationChanged(); void OnTouchpadDeviceConfigurationChanged(); + void OnUncategorizedDeviceConfigurationChanged(); mojo::BindingSet<mojom::InputDeviceServer> bindings_; mojo::InterfacePtrSet<mojom::InputDeviceObserverMojo> observers_;
diff --git a/services/ws/public/cpp/input_devices/input_device_client.cc b/services/ws/public/cpp/input_devices/input_device_client.cc index ffcb9e7..a58e7ae4 100644 --- a/services/ws/public/cpp/input_devices/input_device_client.cc +++ b/services/ws/public/cpp/input_devices/input_device_client.cc
@@ -39,6 +39,11 @@ return touchpad_devices_; } +const std::vector<ui::InputDevice>& InputDeviceClient::GetUncategorizedDevices() + const { + return uncategorized_devices_; +} + bool InputDeviceClient::AreDeviceListsComplete() const { return device_lists_complete_; } @@ -79,6 +84,12 @@ NotifyObserversKeyboardDeviceConfigurationChanged(); } +void InputDeviceClient::OnUncategorizedDeviceConfigurationChanged( + const std::vector<ui::InputDevice>& devices) { + uncategorized_devices_ = devices; + NotifyObserversUncategorizedDeviceConfigurationChanged(); +} + void InputDeviceClient::OnTouchscreenDeviceConfigurationChanged( const std::vector<ui::TouchscreenDevice>& devices, bool touchscreen_target_display_ids_changed) { @@ -116,6 +127,7 @@ const std::vector<ui::TouchscreenDevice>& touchscreen_devices, const std::vector<ui::InputDevice>& mouse_devices, const std::vector<ui::InputDevice>& touchpad_devices, + const std::vector<ui::InputDevice>& uncategorized_devices, bool are_touchscreen_target_displays_valid) { are_touchscreen_target_displays_valid_ = are_touchscreen_target_displays_valid; @@ -133,6 +145,9 @@ if (!touchpad_devices.empty()) OnTouchpadDeviceConfigurationChanged(touchpad_devices); + if (!uncategorized_devices.empty()) + OnUncategorizedDeviceConfigurationChanged(uncategorized_devices); + if (!device_lists_complete_) { device_lists_complete_ = true; NotifyObserversDeviceListsComplete(); @@ -170,4 +185,12 @@ } } +void InputDeviceClient:: + NotifyObserversUncategorizedDeviceConfigurationChanged() { + for (auto& observer : observers_) { + observer.OnInputDeviceConfigurationChanged( + ui::InputDeviceEventObserver::kUncategorized); + } +} + } // namespace ws
diff --git a/services/ws/public/cpp/input_devices/input_device_client.h b/services/ws/public/cpp/input_devices/input_device_client.h index 8b8b8c6..a8864ab 100644 --- a/services/ws/public/cpp/input_devices/input_device_client.h +++ b/services/ws/public/cpp/input_devices/input_device_client.h
@@ -39,6 +39,7 @@ const override; const std::vector<ui::InputDevice>& GetMouseDevices() const override; const std::vector<ui::InputDevice>& GetTouchpadDevices() const override; + const std::vector<ui::InputDevice>& GetUncategorizedDevices() const override; bool AreDeviceListsComplete() const override; bool AreTouchscreensEnabled() const override; bool AreTouchscreenTargetDisplaysValid() const override; @@ -61,11 +62,14 @@ const std::vector<ui::InputDevice>& devices) override; void OnTouchpadDeviceConfigurationChanged( const std::vector<ui::InputDevice>& devices) override; + void OnUncategorizedDeviceConfigurationChanged( + const std::vector<ui::InputDevice>& devices) override; void OnDeviceListsComplete( const std::vector<ui::InputDevice>& keyboard_devices, const std::vector<ui::TouchscreenDevice>& touchscreen_devices, const std::vector<ui::InputDevice>& mouse_devices, const std::vector<ui::InputDevice>& touchpad_devices, + const std::vector<ui::InputDevice>& uncategorized_devices, bool are_touchscreen_target_displays_valid) override; void OnStylusStateChanged(ui::StylusState state) override; @@ -76,6 +80,7 @@ void NotifyObserversKeyboardDeviceConfigurationChanged(); void NotifyObserversTouchscreenDeviceConfigurationChanged(); void NotifyObserversTouchpadDeviceConfigurationChanged(); + void NotifyObserversUncategorizedDeviceConfigurationChanged(); mojo::Binding<mojom::InputDeviceObserverMojo> binding_; @@ -87,6 +92,7 @@ std::vector<ui::TouchscreenDevice> touchscreen_devices_; std::vector<ui::InputDevice> mouse_devices_; std::vector<ui::InputDevice> touchpad_devices_; + std::vector<ui::InputDevice> uncategorized_devices_; bool device_lists_complete_ = false; bool are_touchscreen_target_displays_valid_ = false;
diff --git a/services/ws/public/cpp/input_devices/input_device_client_test_api.cc b/services/ws/public/cpp/input_devices/input_device_client_test_api.cc index 20f630d..170276f8 100644 --- a/services/ws/public/cpp/input_devices/input_device_client_test_api.cc +++ b/services/ws/public/cpp/input_devices/input_device_client_test_api.cc
@@ -66,7 +66,7 @@ if (ui::DeviceDataManager::instance_) ui::DeviceDataManager::instance_->OnDeviceListsComplete(); else - GetInputDeviceClient()->OnDeviceListsComplete({}, {}, {}, {}, false); + GetInputDeviceClient()->OnDeviceListsComplete({}, {}, {}, {}, {}, false); } void InputDeviceClientTestApi::SetKeyboardDevices(
diff --git a/services/ws/public/mojom/input_devices/input_device_server.mojom b/services/ws/public/mojom/input_devices/input_device_server.mojom index c06fc1e..4fe97c9 100644 --- a/services/ws/public/mojom/input_devices/input_device_server.mojom +++ b/services/ws/public/mojom/input_devices/input_device_server.mojom
@@ -25,6 +25,11 @@ // Is called when the list of touchpads changes. OnTouchpadDeviceConfigurationChanged(array<ui.mojom.InputDevice> devices); + // Is called when the list of uncategorized input devices (besides keyboards, + // touchscreens, mice and touchpads) changes. + OnUncategorizedDeviceConfigurationChanged( + array<ui.mojom.InputDevice> devices); + // Is called once all of the input-device lists are available. This will // always be the first call that an observer receives. OnDeviceListsComplete( @@ -32,6 +37,7 @@ array<ui.mojom.TouchscreenDevice> touchscreen_devices, array<ui.mojom.InputDevice> mouse_devices, array<ui.mojom.InputDevice> touchpad_devices, + array<ui.mojom.InputDevice> uncategorized_devices, bool are_touchscreen_target_displays_valid); // Is called when a stylus is removed or inserted into the device.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 9447c82ed..df12c146 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5691,21 +5691,6 @@ ] } ], - "WebContentsOcclusion": [ - { - "platforms": [ - "windows" - ], - "experiments": [ - { - "name": "WindowsWebContentsOcclusion", - "enable_features": [ - "WebContentsOcclusion" - ] - } - ] - } - ], "WebPaymentsPerMethodCanMakePaymentQuota": [ { "platforms": [ @@ -6062,6 +6047,21 @@ ] } ], + "WindowsWebContentsOcclusion": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "WindowsWebContentsOcclusion", + "enable_features": [ + "WebContentsOcclusion" + ] + } + ] + } + ], "history-manipulation-intervention": [ { "platforms": [
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 0a8edd5..9b623ee 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -461,7 +461,6 @@ "web/web_language_detection_details.h", "web/web_local_frame.h", "web/web_local_frame_client.h", - "web/web_manifest_fetcher.h", "web/web_manifest_parser.h", "web/web_meaningful_layout.h", "web/web_media_player_action.h",
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h index 9e401922..f56b763e 100644 --- a/third_party/blink/public/web/web_ax_object.h +++ b/third_party/blink/public/web/web_ax_object.h
@@ -79,6 +79,12 @@ return *this; } + BLINK_EXPORT bool operator==(const WebAXObject& other) const; + BLINK_EXPORT bool operator!=(const WebAXObject& other) const; + BLINK_EXPORT bool operator<(const WebAXObject& other) const; + BLINK_EXPORT bool operator<=(const WebAXObject& other) const; + BLINK_EXPORT bool operator>(const WebAXObject& other) const; + BLINK_EXPORT bool operator>=(const WebAXObject& other) const; BLINK_EXPORT static WebAXObject FromWebNode(const WebNode&); BLINK_EXPORT static WebAXObject FromWebDocument(const WebDocument&); BLINK_EXPORT static WebAXObject FromWebDocumentByID(const WebDocument&, int); @@ -224,7 +230,8 @@ WebAXObject& focus_object, int& focus_offset, ax::mojom::TextAffinity& focus_affinity) const; - BLINK_EXPORT void Selection(WebAXObject& anchor_object, + BLINK_EXPORT void Selection(bool& is_selection_backward, + WebAXObject& anchor_object, int& anchor_offset, ax::mojom::TextAffinity& anchor_affinity, WebAXObject& focus_object, @@ -369,6 +376,9 @@ SkMatrix44& container_transform, bool* clips_children = nullptr) const; + // Exchanges a WebAXObject with another. + BLINK_EXPORT void Swap(WebAXObject& other); + // Returns a brief description of the object, suitable for debugging. E.g. its // role and name. BLINK_EXPORT WebString ToString() const;
diff --git a/third_party/blink/public/web/web_manifest_fetcher.h b/third_party/blink/public/web/web_manifest_fetcher.h deleted file mode 100644 index 58bf778..0000000 --- a/third_party/blink/public/web/web_manifest_fetcher.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MANIFEST_FETCHER_H_ -#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MANIFEST_FETCHER_H_ - -#include <memory> -#include "base/callback.h" -#include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_private_ptr.h" - -namespace blink { - -class ManifestFetcher; -class WebDocument; -class WebURL; -class WebURLResponse; -class WebString; - -class WebManifestFetcher { - public: - // This will be called asynchronously after the URL has been fetched, - // successfully or not. If there is a failure, response and data will both be - // empty. |response| and |data| are both valid until the ManifestFetcher - // instance is destroyed. - using Callback = - base::OnceCallback<void(const WebURLResponse&, const WebString&)>; - - BLINK_EXPORT explicit WebManifestFetcher(const WebURL& url); - BLINK_EXPORT ~WebManifestFetcher() { Reset(); } - - BLINK_EXPORT void Reset(); - - BLINK_EXPORT void Start(WebDocument* web_document, - bool use_credentials, - Callback callback); - BLINK_EXPORT void Cancel(); - - private: - bool IsNull() const { return private_.IsNull(); } - - WebPrivatePtr<ManifestFetcher> private_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_MANIFEST_FETCHER_H_
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl index de95335..4a543fa 100644 --- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl +++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -5173,6 +5173,10 @@ # Manifest content. optional string data + experimental command getInstallabilityErrors + returns + array of string errors + # Returns all browser cookies. Depending on the backend support, will return detailed cookie # information in the `cookies` field. experimental deprecated command getCookies @@ -5705,7 +5709,6 @@ # Base64-encoded data binary data - domain Performance # Run-time execution metric.
diff --git a/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html b/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html index bfb0011a..03a17962 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html +++ b/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html
@@ -594,6 +594,18 @@ boxY = canvasHeight - arrowHalfWidth - titleHeight; } + // If tooltip intersects with the bounds, hide it. + if (boxX < bounds.maxX && boxX + titleWidth > bounds.minX && + boxY < bounds.maxY && boxY + titleHeight > bounds.minY) { + tooltipContent.style.display = 'none'; + return; + } + + if (boxX + titleWidth >= bounds.minX && boxX + titleWidth <= bounds.maxX && boxY + titleHeight >= bounds.minY && boxY + titleHeight <= bounds.maxY) { + tooltipContent.style.display = 'none'; + return; + } + tooltipContent.style.top = boxY + "px"; tooltipContent.style.left = boxX + "px"; tooltipContent.style.setProperty('--arrow-visibility', arrowHidden ? 'hidden' : 'visible');
diff --git a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json index 0003c4d..7b29fd67 100644 --- a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json +++ b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
@@ -74,7 +74,7 @@ { "domain": "Page", "exclude": ["getNavigationHistory", "navigateToHistoryEntry", "resetNavigationHistory", "captureScreenshot", "screencastFrameAck", "handleJavaScriptDialog", "setColorPickerEnabled", - "getAppManifest", "setControlNavigations", "processNavigation", "printToPDF", "bringToFront", "setDownloadBehavior", "navigate", "crash", "close", "setWebLifecycleState", "captureSnapshot"], + "getAppManifest", "setControlNavigations", "processNavigation", "printToPDF", "bringToFront", "setDownloadBehavior", "navigate", "crash", "close", "setWebLifecycleState", "captureSnapshot", "getInstallabilityErrors"], "async": ["getResourceContent", "searchInResource"], "exclude_events": ["screencastFrame", "screencastVisibilityChanged", "colorPicked", "interstitialShown", "interstitialHidden", "javascriptDialogOpening", "javascriptDialogClosed", "navigationRequested"] },
diff --git a/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc b/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc index d4198ae..0b5ff29 100644 --- a/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc +++ b/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc
@@ -73,6 +73,17 @@ } } +void NGPhysicalOffsetRect::ExpandEdgesToPixelBoundaries() { + int left = FloorToInt(offset.left); + int top = FloorToInt(offset.top); + int max_right = (offset.left + size.width).Ceil(); + int max_bottom = (offset.top + size.height).Ceil(); + offset.left = LayoutUnit(left); + offset.top = LayoutUnit(top); + size.width = LayoutUnit(max_right - left); + size.height = LayoutUnit(max_bottom - top); +} + NGPhysicalOffsetRect::NGPhysicalOffsetRect(const LayoutRect& source) : NGPhysicalOffsetRect({source.X(), source.Y()}, {source.Width(), source.Height()}) {}
diff --git a/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h b/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h index 82754b6..2ef735b 100644 --- a/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h +++ b/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h
@@ -43,6 +43,7 @@ void UniteEvenIfEmpty(const NGPhysicalOffsetRect&); void Expand(const NGPhysicalBoxStrut&); + void ExpandEdgesToPixelBoundaries(); // Conversions from/to existing code. New code prefers type safety for // logical/physical distinctions.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc index 4ce2a71f..6db5844 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc
@@ -267,8 +267,6 @@ ink_overflow.Expand(text_shadow_logical_outsets); } - ink_overflow.ExpandEdgesToPixelBoundaries(); - // Uniting the frame rect ensures that non-ink spaces such side bearings, or // even space characters, are included in the visual rect for decorations. NGPhysicalOffsetRect local_ink_overflow = ConvertToLocal(ink_overflow); @@ -278,6 +276,7 @@ return; } local_ink_overflow.Unite(local_rect); + local_ink_overflow.ExpandEdgesToPixelBoundaries(); EnsureRareData()->self_ink_overflow_ = local_ink_overflow; }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h index 6c9aa94..c3f7669 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
@@ -144,6 +144,9 @@ scoped_refptr<const ShapeResultView> shape_result); struct RareData { + USING_FAST_MALLOC(RareData); + + public: NGPhysicalOffsetRect self_ink_overflow_; scoped_refptr<const ComputedStyle> style_; // Used only for ellipsis. };
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h index 35f9638..49832c5 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -348,6 +348,9 @@ // The ink overflow storage for when |InkOverflowOwnerBox()| is nullptr. struct NGInkOverflowModel { + USING_FAST_MALLOC(NGInkOverflowModel); + + public: NGInkOverflowModel(const NGPhysicalOffsetRect& self_ink_overflow, const NGPhysicalOffsetRect& contents_ink_overflow);
diff --git a/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js b/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js index 14a0a8ad..6f8f6b97 100644 --- a/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js +++ b/third_party/blink/renderer/devtools/front_end/application_test_runner/CacheStorageTestRunner.js
@@ -26,7 +26,6 @@ TestRunner.addResult(' '.repeat(8) + entries.join(', ')); } } - UI.panels.resources._sidebar.cacheStorageListTreeElement.expand(); if (!pathFilter)
diff --git a/third_party/blink/renderer/devtools/front_end/inline_editor/bezierEditor.css b/third_party/blink/renderer/devtools/front_end/inline_editor/bezierEditor.css index f1ecc31..6da7ab04 100644 --- a/third_party/blink/renderer/devtools/front_end/inline_editor/bezierEditor.css +++ b/third_party/blink/renderer/devtools/front_end/inline_editor/bezierEditor.css
@@ -180,8 +180,7 @@ margin-top: 16px; } -svg.bezier-preset-modify:active, -.-theme-selection-color { +svg.bezier-preset-modify:active { transform: scale(1.1); background-color: var(--selection-bg-color); }
diff --git a/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js b/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js index d61a88a2..baef908 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js +++ b/third_party/blink/renderer/devtools/front_end/resources/AppManifestView.js
@@ -93,15 +93,17 @@ */ async _updateManifest(immediately) { const {url, data, errors} = await this._resourceTreeModel.fetchAppManifest(); - this._throttler.schedule(() => this._renderManifest(url, data, errors), immediately); + const installabilityErrors = await this._resourceTreeModel.getInstallabilityErrors(); + this._throttler.schedule(() => this._renderManifest(url, data, errors, installabilityErrors), immediately); } /** * @param {string} url * @param {?string} data * @param {!Array<!Protocol.Page.AppManifestError>} errors + * @param {!Array<string>} installabilityErrors */ - async _renderManifest(url, data, errors) { + async _renderManifest(url, data, errors, installabilityErrors) { if (!data && !errors.length) { this._emptyView.showWidget(); this._reportView.hideWidget(); @@ -121,31 +123,20 @@ if (!data) return; - const installabilityErrors = []; - if (data.charCodeAt(0) === 0xFEFF) data = data.slice(1); // Trim the BOM as per https://tools.ietf.org/html/rfc7159#section-8.1. const parsedManifest = JSON.parse(data); this._nameField.textContent = stringProperty('name'); this._shortNameField.textContent = stringProperty('short_name'); - if (!this._nameField.textContent && !this._shortNameField.textContent) - installabilityErrors.push(ls`Either 'name' or 'short_name' is required`); this._startURLField.removeChildren(); const startURL = stringProperty('start_url'); if (startURL) { const completeURL = /** @type {string} */ (Common.ParsedURL.completeURL(url, startURL)); this._startURLField.appendChild(Components.Linkifier.linkifyURL(completeURL, {text: startURL})); - if (!this._serviceWorkerManager.hasRegistrationForURLs([completeURL, this._target.inspectedURL()])) - installabilityErrors.push(ls`Service worker is not registered or does not control the Start URL`); - else if (!await this._swHasFetchHandler()) - installabilityErrors.push(ls`Service worker does not have the 'fetch' handler`); - } else { - installabilityErrors.push(ls`'start_url' needs to be a valid URL`); } - this._themeColorSwatch.classList.toggle('hidden', !stringProperty('theme_color')); const themeColor = Common.Color.parse(stringProperty('theme_color') || 'white') || Common.Color.parse('white'); this._themeColorSwatch.setColor(/** @type {!Common.Color} */ (themeColor)); @@ -157,33 +148,17 @@ this._orientationField.textContent = stringProperty('orientation'); const displayType = stringProperty('display'); this._displayField.textContent = displayType; - if (!['minimal-ui', 'standalone', 'fullscreen'].includes(displayType)) - installabilityErrors.push(ls`'display' property must be set to 'standalone', 'fullscreen' or 'minimal-ui'`); const icons = parsedManifest['icons'] || []; - let hasInstallableIcon = false; this._iconsSection.clearContent(); for (const icon of icons) { - if (!icon.sizes) - hasInstallableIcon = true; // any const title = (icon['sizes'] || '') + '\n' + (icon['type'] || ''); - try { - const widthHeight = icon['sizes'].split('x'); - if (parseInt(widthHeight[0], 10) >= 144 && parseInt(widthHeight[1], 10) >= 144) - hasInstallableIcon = true; - } catch (e) { - } - const field = this._iconsSection.appendField(title); const image = await this._loadImage(Common.ParsedURL.completeURL(url, icon['src'])); if (image) field.appendChild(image); - else - installabilityErrors.push(ls`Some of the icons could not be loaded`); } - if (!hasInstallableIcon) - installabilityErrors.push(ls`An icon at least 144px x 144px large is required`); this._installabilitySection.clearContent(); this._installabilitySection.element.classList.toggle('hidden', !installabilityErrors.length); @@ -203,32 +178,6 @@ } /** - * @return {!Promise<boolean>} - */ - async _swHasFetchHandler() { - for (const target of SDK.targetManager.targets()) { - if (target.type() !== SDK.Target.Type.Worker) - continue; - if (!target.parentTarget() || target.parentTarget().type() !== SDK.Target.Type.ServiceWorker) - continue; - - const ec = target.model(SDK.RuntimeModel).defaultExecutionContext(); - const result = await ec.evaluate( - { - expression: `'fetch' in getEventListeners(self)`, - includeCommandLineAPI: true, - silent: true, - returnByValue: true - }, - false, false); - if (!result.object || !result.object.value) - continue; - return true; - } - return false; - } - - /** * @param {?string} url * @return {!Promise<?Image>} */
diff --git a/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js b/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js index 10123401..de8b0eb 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js +++ b/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js
@@ -29,7 +29,6 @@ */ /** * @implements {SDK.TargetManager.Observer} - * @implements {SDK.SDKModelObserver<!Resources.DOMStorageModel>} * @unrestricted */ Resources.ApplicationPanelSidebar = class extends UI.VBox { @@ -196,18 +195,22 @@ this._addCookieDocument(frame); this._databaseModel.enable(); - const indexedDBModel = this._target.model(Resources.IndexedDBModel); - if (indexedDBModel) - indexedDBModel.enable(); - const cacheStorageModel = this._target.model(SDK.ServiceWorkerCacheModel); if (cacheStorageModel) cacheStorageModel.enable(); const resourceTreeModel = this._target.model(SDK.ResourceTreeModel); if (resourceTreeModel) this._populateApplicationCacheTree(resourceTreeModel); - SDK.targetManager.observeModels(Resources.DOMStorageModel, this); + SDK.targetManager.observeModels(Resources.DOMStorageModel, /** @type {!SDK.SDKModelObserver} */ ({ + modelAdded: model => this._domStorageModelAdded(model), + modelRemoved: model => this._domStorageModelRemoved(model) + })); this.indexedDBListTreeElement._initialize(); + SDK.targetManager.observeModels( + Resources.IndexedDBModel, /** @type {!SDK.SDKModelObserver} */ ({ + modelAdded: model => model.enable(), + modelRemoved: model => this.indexedDBListTreeElement.removeIndexedDBForModel(model) + })); const serviceWorkerCacheModel = this._target.model(SDK.ServiceWorkerCacheModel); this.cacheStorageListTreeElement._initialize(serviceWorkerCacheModel); const backgroundServiceModel = this._target.model(Resources.BackgroundServiceModel); @@ -218,25 +221,22 @@ } /** - * @override - * @param {!Resources.DOMStorageModel} domStorageModel + * @param {!Resources.DOMStorageModel} model */ - modelAdded(domStorageModel) { - domStorageModel.enable(); - domStorageModel.storages().forEach(this._addDOMStorage.bind(this)); - domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); - domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); + _domStorageModelAdded(model) { + model.enable(); + model.storages().forEach(this._addDOMStorage.bind(this)); + model.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); + model.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); } /** - * @override - * @param {!Resources.DOMStorageModel} domStorageModel + * @param {!Resources.DOMStorageModel} model */ - modelRemoved(domStorageModel) { - domStorageModel.storages().forEach(this._removeDOMStorage.bind(this)); - domStorageModel.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); - domStorageModel.removeEventListener( - Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); + _domStorageModelRemoved(model) { + model.storages().forEach(this._removeDOMStorage.bind(this)); + model.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); + model.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); } _resetWithFrames() { @@ -287,8 +287,11 @@ this.cookieListTreeElement.removeChildren(); } + /** + * @param {!Common.Event} event + */ _frameNavigated(event) { - const frame = event.data; + const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data); if (frame.isTopFrame()) this._reset(); @@ -1138,6 +1141,15 @@ } /** + * @param {!Resources.IndexedDBModel} model + */ + removeIndexedDBForModel(model) { + const idbDatabaseTreeElements = this._idbDatabaseTreeElements.filter(element => element._model === model); + for (const idbDatabaseTreeElement of idbDatabaseTreeElements) + this._removeIDBDatabaseTreeElement(idbDatabaseTreeElement); + } + + /** * @override */ onattach() { @@ -1186,7 +1198,13 @@ const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId); if (!idbDatabaseTreeElement) return; + this._removeIDBDatabaseTreeElement(idbDatabaseTreeElement); + } + /** + * @param {!Resources.IDBDatabaseTreeElement} idbDatabaseTreeElement + */ + _removeIDBDatabaseTreeElement(idbDatabaseTreeElement) { idbDatabaseTreeElement.clear(); this.removeChild(idbDatabaseTreeElement); this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement); @@ -1205,6 +1223,11 @@ if (!idbDatabaseTreeElement) return; idbDatabaseTreeElement.update(database, entriesUpdated); + this._indexedDBLoadedForTest(); + } + + _indexedDBLoadedForTest() { + // For sniffing in tests. } /** @@ -1222,23 +1245,12 @@ } /** - * @param {!Resources.IndexedDBModel.DatabaseId} databaseId * @param {!Resources.IndexedDBModel} model + * @param {!Resources.IndexedDBModel.DatabaseId} databaseId * @return {?Resources.IDBDatabaseTreeElement} */ _idbDatabaseTreeElement(model, databaseId) { - let index = -1; - let i; - for (i = 0; i < this._idbDatabaseTreeElements.length; ++i) { - if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) && - this._idbDatabaseTreeElements[i]._model === model) { - index = i; - break; - } - } - if (index !== -1) - return this._idbDatabaseTreeElements[i]; - return null; + return this._idbDatabaseTreeElements.find(x => x._databaseId.equals(databaseId) && x._model === model) || null; } };
diff --git a/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js b/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js index 2ece1b2..5d531f3d 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js +++ b/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js
@@ -499,7 +499,7 @@ } }; -SDK.SDKModel.register(Resources.IndexedDBModel, SDK.Target.Capability.None, false); +SDK.SDKModel.register(Resources.IndexedDBModel, SDK.Target.Capability.DOM, false); Resources.IndexedDBModel.KeyTypes = { NumberType: 'number',
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/ResourceTreeModel.js b/third_party/blink/renderer/devtools/front_end/sdk/ResourceTreeModel.js index e4ca040..d3c947f 100644 --- a/third_party/blink/renderer/devtools/front_end/sdk/ResourceTreeModel.js +++ b/third_party/blink/renderer/devtools/front_end/sdk/ResourceTreeModel.js
@@ -411,6 +411,15 @@ return {url: response.url, data: null, errors: []}; return {url: response.url, data: response.data || null, errors: response.errors}; } + + /** + * @return {!Promise<!Array<string>>} + */ + async getInstallabilityErrors() { + const response = await this._agent.invoke_getInstallabilityErrors({}); + return response.errors || []; + } + /** * @param {!SDK.ExecutionContext} a * @param {!SDK.ExecutionContext} b
diff --git a/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css b/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css index ced1f40..7ee95b6 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css +++ b/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css
@@ -62,8 +62,7 @@ pointer-events: none; } -.soft-context-menu-item-mouse-over, -.-theme-selection-color { +.soft-context-menu-item-mouse-over { border-top: 1px solid var(--context-menu-hover-bg); border-bottom: 1px solid var(--context-menu-hover-bg); background-color: var(--context-menu-hover-bg);
diff --git a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css index fb5e0db..5e0a3263 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css +++ b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css
@@ -147,13 +147,11 @@ } .toolbar-button.toolbar-state-on .toolbar-glyph, -.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover:not(:active), -.-theme-selection-color { +.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover:not(:active) { background-color: var(--accent-color); } -.toolbar-button.toolbar-state-on .toolbar-text, -.-theme-selection-color { +.toolbar-button.toolbar-state-on .toolbar-text { color: var(--accent-color); } @@ -166,13 +164,11 @@ } .toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-glyph, -.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:active:hover, -.-theme-selection-color { +.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:active:hover { background-color: var(--accent-color); } -.toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-text, -.-theme-selection-color { +.toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-text { color: var(--accent-color); }
diff --git a/third_party/blink/renderer/modules/exported/BUILD.gn b/third_party/blink/renderer/modules/exported/BUILD.gn index b62c939..74f7348 100644 --- a/third_party/blink/renderer/modules/exported/BUILD.gn +++ b/third_party/blink/renderer/modules/exported/BUILD.gn
@@ -13,7 +13,6 @@ "web_dom_media_stream_track.cc", "web_embedded_worker_impl.cc", "web_embedded_worker_impl.h", - "web_manifest_fetcher.cc", "web_manifest_parser.cc", "web_storage_event_dispatcher_impl.cc", "web_user_media_request.cc",
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc index 16a8acf..0d4d396 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_object.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -769,12 +769,14 @@ } } -void WebAXObject::Selection(WebAXObject& anchor_object, +void WebAXObject::Selection(bool& is_selection_backward, + WebAXObject& anchor_object, int& anchor_offset, ax::mojom::TextAffinity& anchor_affinity, WebAXObject& focus_object, int& focus_offset, ax::mojom::TextAffinity& focus_affinity) const { + is_selection_backward = false; anchor_object = WebAXObject(); anchor_offset = -1; anchor_affinity = ax::mojom::TextAffinity::kDownstream; @@ -802,6 +804,7 @@ const AXPosition extent = ax_selection.Extent(); focus_object = WebAXObject(const_cast<AXObject*>(extent.ContainerObject())); + is_selection_backward = base > extent; if (base.IsTextPosition()) { anchor_offset = base.TextOffset(); anchor_affinity = ToAXAffinity(base.Affinity()); @@ -1542,6 +1545,16 @@ return private_->RequestScrollToGlobalPointAction(point); } +void WebAXObject::Swap(WebAXObject& other) { + if (IsDetached() || other.IsDetached()) + return; + + AXObject* temp = private_.Get(); + DCHECK(temp) << "|private_| should not be null."; + this->Assign(other); + other = temp; +} + WebString WebAXObject::ToString() const { if (IsDetached()) return WebString(); @@ -1556,6 +1569,42 @@ return *this; } +bool WebAXObject::operator==(const WebAXObject& other) const { + if (IsDetached() || other.IsDetached()) + return false; + return *private_ == *other.private_; +} + +bool WebAXObject::operator!=(const WebAXObject& other) const { + if (IsDetached() || other.IsDetached()) + return false; + return *private_ != *other.private_; +} + +bool WebAXObject::operator<(const WebAXObject& other) const { + if (IsDetached() || other.IsDetached()) + return false; + return *private_ < *other.private_; +} + +bool WebAXObject::operator<=(const WebAXObject& other) const { + if (IsDetached() || other.IsDetached()) + return false; + return *private_ <= *other.private_; +} + +bool WebAXObject::operator>(const WebAXObject& other) const { + if (IsDetached() || other.IsDetached()) + return false; + return *private_ > *other.private_; +} + +bool WebAXObject::operator>=(const WebAXObject& other) const { + if (IsDetached() || other.IsDetached()) + return false; + return *private_ >= *other.private_; +} + WebAXObject::operator AXObject*() const { return private_.Get(); }
diff --git a/third_party/blink/renderer/modules/exported/web_manifest_fetcher.cc b/third_party/blink/renderer/modules/exported/web_manifest_fetcher.cc deleted file mode 100644 index f2bffec69..0000000 --- a/third_party/blink/renderer/modules/exported/web_manifest_fetcher.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/public/web/web_manifest_fetcher.h" - -#include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/web/web_document.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/modules/manifest/manifest_fetcher.h" -#include "third_party/blink/renderer/platform/weborigin/kurl.h" - -namespace blink { - -WebManifestFetcher::WebManifestFetcher(const WebURL& url) - : private_(MakeGarbageCollected<ManifestFetcher>(url)) {} - -void WebManifestFetcher::Start(WebDocument* web_document, - bool use_credentials, - Callback callback) { - DCHECK(!IsNull()); - - Document* document = web_document->Unwrap<Document>(); - private_->Start(*document, use_credentials, std::move(callback)); -} - -void WebManifestFetcher::Cancel() { - DCHECK(!IsNull()); - private_->Cancel(); -} - -void WebManifestFetcher::Reset() { - private_.Reset(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/manifest/BUILD.gn b/third_party/blink/renderer/modules/manifest/BUILD.gn index dc27426..31862cc 100644 --- a/third_party/blink/renderer/modules/manifest/BUILD.gn +++ b/third_party/blink/renderer/modules/manifest/BUILD.gn
@@ -8,8 +8,6 @@ sources = [ "image_resource_type_converters.cc", "image_resource_type_converters.h", - "manifest_fetcher.cc", - "manifest_fetcher.h", "manifest_parser.cc", "manifest_parser.h", "manifest_uma_util.cc",
diff --git a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc deleted file mode 100644 index f6c0cf1..0000000 --- a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/manifest/manifest_fetcher.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/loader/threadable_loader.h" -#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" - -namespace blink { - -ManifestFetcher::ManifestFetcher(const KURL& url) - : url_(url), completed_(false) {} - -ManifestFetcher::~ManifestFetcher() { - if (!completed_) - Cancel(); -} - -void ManifestFetcher::Start(Document& document, - bool use_credentials, - WebManifestFetcher::Callback callback) { - callback_ = std::move(callback); - - ResourceRequest request(url_); - request.SetRequestContext(mojom::RequestContextType::MANIFEST); - request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); - // See https://w3c.github.io/manifest/. Use "include" when use_credentials is - // true, and "omit" otherwise. - request.SetFetchCredentialsMode( - use_credentials ? network::mojom::FetchCredentialsMode::kInclude - : network::mojom::FetchCredentialsMode::kOmit); - - ResourceLoaderOptions resource_loader_options; - resource_loader_options.data_buffering_policy = kDoNotBufferData; - - loader_ = MakeGarbageCollected<ThreadableLoader>(document, this, - resource_loader_options); - loader_->Start(request); -} - -void ManifestFetcher::Cancel() { - if (!loader_) - return; - - DCHECK(!completed_); - - ThreadableLoader* loader = loader_.Release(); - loader->Cancel(); -} - -void ManifestFetcher::DidReceiveResponse(uint64_t, - const ResourceResponse& response) { - response_ = response; -} - -void ManifestFetcher::DidReceiveData(const char* data, unsigned length) { - if (!length) - return; - - data_.Append(data, length); -} - -void ManifestFetcher::DidFinishLoading(uint64_t) { - DCHECK(!completed_); - completed_ = true; - - WrappedResourceResponse wrapped_response(response_); - std::move(callback_).Run(wrapped_response, data_.ToString()); - data_.Clear(); -} - -void ManifestFetcher::DidFail(const ResourceError& error) { - if (!callback_) - return; - - data_.Clear(); - - WrappedResourceResponse wrapped_response(response_); - std::move(callback_).Run(wrapped_response, String()); -} - -void ManifestFetcher::DidFailRedirectCheck() { - DidFail(ResourceError::Failure(NullURL())); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/manifest/manifest_fetcher.h b/third_party/blink/renderer/modules/manifest/manifest_fetcher.h deleted file mode 100644 index 9a73ed4..0000000 --- a/third_party/blink/renderer/modules/manifest/manifest_fetcher.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_FETCHER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_FETCHER_H_ - -#include <memory> - -#include "base/callback.h" -#include "third_party/blink/public/web/web_manifest_fetcher.h" -#include "third_party/blink/renderer/core/loader/threadable_loader.h" -#include "third_party/blink/renderer/core/loader/threadable_loader_client.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/heap/member.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" - -namespace blink { - -class Document; -class KURL; - -// Helper class to download a Web Manifest. When an instance is created, the -// caller need to call Start() and wait for the passed callback to be executed. -// If the fetch fails, the callback will be called with two empty objects. -class ManifestFetcher final : public GarbageCollectedFinalized<ManifestFetcher>, - public ThreadableLoaderClient { - USING_GARBAGE_COLLECTED_MIXIN(ManifestFetcher); - - public: - explicit ManifestFetcher(const KURL& url); - ~ManifestFetcher() override; - - void Start(Document& document, - bool use_credentials, - WebManifestFetcher::Callback callback); - void Cancel(); - - // ThreadableLoaderClient - void DidReceiveResponse(uint64_t, const ResourceResponse&) override; - void DidReceiveData(const char*, unsigned) override; - void DidFinishLoading(uint64_t) override; - void DidFail(const ResourceError&) override; - void DidFailRedirectCheck() override; - - void Trace(Visitor* visitor) override { visitor->Trace(loader_); } - - private: - KURL url_; - bool completed_; - WebManifestFetcher::Callback callback_; - ResourceResponse response_; - StringBuilder data_; - Member<ThreadableLoader> loader_; - - DISALLOW_COPY_AND_ASSIGN(ManifestFetcher); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_FETCHER_H_
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index 1449ea8..25d194906 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -4,16 +4,103 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_extent_3d.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_origin_3d.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture_view.h" namespace blink { +DawnRenderPassColorAttachmentDescriptor AsDawnType( + const GPURenderPassColorAttachmentDescriptor* webgpu_desc) { + DCHECK(webgpu_desc); + + DawnRenderPassColorAttachmentDescriptor dawn_desc; + dawn_desc.attachment = webgpu_desc->attachment()->GetHandle(); + dawn_desc.resolveTarget = webgpu_desc->resolveTarget() + ? webgpu_desc->resolveTarget()->GetHandle() + : nullptr; + dawn_desc.loadOp = AsDawnEnum<DawnLoadOp>(webgpu_desc->loadOp()); + dawn_desc.storeOp = AsDawnEnum<DawnStoreOp>(webgpu_desc->storeOp()); + dawn_desc.clearColor = AsDawnType(webgpu_desc->clearColor()); + + return dawn_desc; +} + +namespace { + +DawnRenderPassDepthStencilAttachmentDescriptor AsDawnType( + const GPURenderPassDepthStencilAttachmentDescriptor* webgpu_desc) { + DCHECK(webgpu_desc); + + DawnRenderPassDepthStencilAttachmentDescriptor dawn_desc; + dawn_desc.attachment = webgpu_desc->attachment()->GetHandle(); + dawn_desc.depthLoadOp = AsDawnEnum<DawnLoadOp>(webgpu_desc->depthLoadOp()); + dawn_desc.depthStoreOp = AsDawnEnum<DawnStoreOp>(webgpu_desc->depthStoreOp()); + dawn_desc.clearDepth = webgpu_desc->clearDepth(); + dawn_desc.stencilLoadOp = + AsDawnEnum<DawnLoadOp>(webgpu_desc->stencilLoadOp()); + dawn_desc.stencilStoreOp = + AsDawnEnum<DawnStoreOp>(webgpu_desc->stencilStoreOp()); + dawn_desc.clearStencil = webgpu_desc->clearStencil(); + + return dawn_desc; +} + +DawnBufferCopyView AsDawnType(const GPUBufferCopyView* webgpu_view) { + DCHECK(webgpu_view); + DCHECK(webgpu_view->buffer()); + + DawnBufferCopyView dawn_view; + dawn_view.nextInChain = nullptr; + dawn_view.buffer = webgpu_view->buffer()->GetHandle(); + dawn_view.offset = webgpu_view->offset(); + dawn_view.rowPitch = webgpu_view->rowPitch(); + dawn_view.imageHeight = webgpu_view->imageHeight(); + + return dawn_view; +} + +DawnTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) { + DCHECK(webgpu_view); + DCHECK(webgpu_view->texture()); + + DawnTextureCopyView dawn_view; + dawn_view.nextInChain = nullptr; + dawn_view.texture = webgpu_view->texture()->GetHandle(); + dawn_view.level = webgpu_view->mipLevel(); + dawn_view.slice = webgpu_view->arrayLayer(); + dawn_view.origin = AsDawnType(webgpu_view->origin()); + + return dawn_view; +} + +} // anonymous namespace + // static GPUCommandEncoder* GPUCommandEncoder::Create( GPUDevice* device, const GPUCommandEncoderDescriptor* webgpu_desc) { - NOTIMPLEMENTED(); - return nullptr; + DCHECK(device); + DCHECK(webgpu_desc); + ALLOW_UNUSED_LOCAL(webgpu_desc); + + return MakeGarbageCollected<GPUCommandEncoder>( + device, + device->GetProcs().deviceCreateCommandEncoder(device->GetHandle())); } GPUCommandEncoder::GPUCommandEncoder(GPUDevice* device, @@ -27,4 +114,102 @@ GetProcs().commandEncoderRelease(GetHandle()); } +GPURenderPassEncoder* GPUCommandEncoder::beginRenderPass( + const GPURenderPassDescriptor* descriptor) { + DCHECK(descriptor); + + uint32_t color_attachment_count = + static_cast<uint32_t>(descriptor->colorAttachments().size()); + + DawnRenderPassDescriptor dawn_desc; + dawn_desc.colorAttachmentCount = color_attachment_count; + dawn_desc.colorAttachments = nullptr; + + using DescriptorPtr = DawnRenderPassColorAttachmentDescriptor*; + using DescriptorArray = DawnRenderPassColorAttachmentDescriptor[]; + using DescriptorPtrArray = DescriptorPtr[]; + + std::unique_ptr<DescriptorArray> color_attachments; + std::unique_ptr<DescriptorPtrArray> color_attachment_ptrs; + + if (color_attachment_count > 0) { + color_attachments = AsDawnType(descriptor->colorAttachments()); + + color_attachment_ptrs = std::unique_ptr<DescriptorPtrArray>( + new DescriptorPtr[color_attachment_count]); + + for (uint32_t i = 0; i < color_attachment_count; ++i) { + color_attachment_ptrs[i] = color_attachments.get() + i; + } + dawn_desc.colorAttachments = color_attachment_ptrs.get(); + } + + DawnRenderPassDepthStencilAttachmentDescriptor depthStencilAttachment = {}; + if (descriptor->hasDepthStencilAttachment()) { + depthStencilAttachment = AsDawnType(descriptor->depthStencilAttachment()); + dawn_desc.depthStencilAttachment = &depthStencilAttachment; + } else { + dawn_desc.depthStencilAttachment = nullptr; + } + + return GPURenderPassEncoder::Create( + device_, + GetProcs().commandEncoderBeginRenderPass(GetHandle(), &dawn_desc)); +} + +GPUComputePassEncoder* GPUCommandEncoder::beginComputePass() { + return GPUComputePassEncoder::Create( + device_, GetProcs().commandEncoderBeginComputePass(GetHandle())); +} + +void GPUCommandEncoder::copyBufferToBuffer(GPUBuffer* src, + uint64_t src_offset, + GPUBuffer* dst, + uint64_t dst_offset, + uint64_t size) { + DCHECK(src); + DCHECK(dst); + GetProcs().commandEncoderCopyBufferToBuffer(GetHandle(), src->GetHandle(), + src_offset, dst->GetHandle(), + dst_offset, size); +} + +void GPUCommandEncoder::copyBufferToTexture(GPUBufferCopyView* source, + GPUTextureCopyView* destination, + GPUExtent3D* copy_size) { + DawnBufferCopyView dawn_source = AsDawnType(source); + DawnTextureCopyView dawn_destination = AsDawnType(destination); + DawnExtent3D dawn_copy_size = AsDawnType(copy_size); + + GetProcs().commandEncoderCopyBufferToTexture( + GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size); +} + +void GPUCommandEncoder::copyTextureToBuffer(GPUTextureCopyView* source, + GPUBufferCopyView* destination, + GPUExtent3D* copy_size) { + DawnTextureCopyView dawn_source = AsDawnType(source); + DawnBufferCopyView dawn_destination = AsDawnType(destination); + DawnExtent3D dawn_copy_size = AsDawnType(copy_size); + + GetProcs().commandEncoderCopyTextureToBuffer( + GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size); +} + +void GPUCommandEncoder::copyTextureToTexture(GPUTextureCopyView* source, + GPUTextureCopyView* destination, + GPUExtent3D* copy_size) { + DawnTextureCopyView dawn_source = AsDawnType(source); + DawnTextureCopyView dawn_destination = AsDawnType(destination); + DawnExtent3D dawn_copy_size = AsDawnType(copy_size); + + GetProcs().commandEncoderCopyTextureToTexture( + GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size); +} + +GPUCommandBuffer* GPUCommandEncoder::finish() { + return GPUCommandBuffer::Create(device_, + GetProcs().commandEncoderFinish(GetHandle())); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h index 20286ca..adb50dc 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h
@@ -9,7 +9,15 @@ namespace blink { +class GPUBuffer; +class GPUBufferCopyView; +class GPUCommandBuffer; class GPUCommandEncoderDescriptor; +class GPUComputePassEncoder; +class GPUExtent3D; +class GPURenderPassDescriptor; +class GPURenderPassEncoder; +class GPUTextureCopyView; class GPUCommandEncoder : public DawnObject<DawnCommandEncoder> { DEFINE_WRAPPERTYPEINFO(); @@ -23,7 +31,24 @@ ~GPUCommandEncoder() override; // gpu_command_encoder.idl - // TODO(crbug.com/877147): implement GPUCommandEncoder. + GPURenderPassEncoder* beginRenderPass( + const GPURenderPassDescriptor* descriptor); + GPUComputePassEncoder* beginComputePass(); + void copyBufferToBuffer(GPUBuffer* src, + uint64_t src_offset, + GPUBuffer* dst, + uint64_t dst_offset, + uint64_t size); + void copyBufferToTexture(GPUBufferCopyView* source, + GPUTextureCopyView* destination, + GPUExtent3D* copy_size); + void copyTextureToBuffer(GPUTextureCopyView* source, + GPUBufferCopyView* destination, + GPUExtent3D* copy_size); + void copyTextureToTexture(GPUTextureCopyView* source, + GPUTextureCopyView* destination, + GPUExtent3D* copy_size); + GPUCommandBuffer* finish(); private: DISALLOW_COPY_AND_ASSIGN(GPUCommandEncoder);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl index 4036658..83a719f 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
@@ -7,4 +7,28 @@ [ RuntimeEnabled=WebGPU ] interface GPUCommandEncoder { + GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); + GPUComputePassEncoder beginComputePass(); + + void copyBufferToBuffer( + GPUBuffer src, unsigned long long srcOffset, + GPUBuffer dst, unsigned long long dstOffset, + unsigned long long size); + + void copyBufferToTexture( + GPUBufferCopyView source, + GPUTextureCopyView destination, + GPUExtent3D copySize); + + void copyTextureToBuffer( + GPUTextureCopyView source, + GPUBufferCopyView destination, + GPUExtent3D copySize); + + void copyTextureToTexture( + GPUTextureCopyView source, + GPUTextureCopyView destination, + GPUExtent3D copySize); + + GPUCommandBuffer finish(); };
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc index 8d66a2d..8bfcba0 100644 --- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc +++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -72,7 +72,7 @@ bool want_depth_buffer = initializer->depth(); bool want_stencil_buffer = initializer->stencil(); bool want_alpha_channel = initializer->alpha(); - bool ignore_depth_values = initializer->ignoreDepthValues(); + bool want_ignore_depth_values = initializer->ignoreDepthValues(); double framebuffer_scale = 1.0; @@ -110,6 +110,16 @@ return nullptr; } + // TODO: In the future this should be communicated by the drawing buffer and + // indicate whether the depth buffers are being supplied to the XR compositor. + bool compositor_supports_depth_values = false; + + // The ignoreDepthValues attribute of XRWebGLLayer may only be set to false if + // the compositor is actually making use of the depth values and the user did + // not set ignoreDepthValues to true explicitly. + bool ignore_depth_values = + !compositor_supports_depth_values || want_ignore_depth_values; + return MakeGarbageCollected<XRWebGLLayer>( session, webgl_context, std::move(drawing_buffer), framebuffer, framebuffer_scale, ignore_depth_values);
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7a81c05..aeded0bc 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6260,3 +6260,8 @@ # Sheriff 2019-04-09 crbug.com/946335 [ Linux Mac ] fast/filesystem/file-writer-abort-depth.html [ Pass Crash ] + +# Sheriff 2019-04-10 +crbug.com/951638 [ Linux ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ] +crbug.com/951638 [ Mac10.13 Debug ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ] +crbug.com/951638 [ Win7 ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 08af3f8..21d36d02 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -192,8 +192,7 @@ "prefix": "android", "base": "fullscreen", "args": ["--enable-features=OverlayScrollbar", "--enable-threaded-compositing", - "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text", - "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch", + "--enable-prefer-compositing-to-lcd-text", "--force-overlay-fullscreen-video", "--enable-overscroll-notifications", "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"] }, @@ -201,8 +200,7 @@ "prefix": "android", "base": "rootscroller", "args": ["--enable-features=OverlayScrollbar", "--enable-threaded-compositing", - "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text", - "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch", + "--enable-prefer-compositing-to-lcd-text", "--force-overlay-fullscreen-video", "--enable-overscroll-notifications", "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"] }, @@ -210,8 +208,7 @@ "prefix": "android", "base": "url-bar", "args": ["--enable-features=OverlayScrollbar", "--enable-threaded-compositing", - "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text", - "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch", + "--enable-prefer-compositing-to-lcd-text", "--force-overlay-fullscreen-video", "--enable-overscroll-notifications", "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"] }, @@ -219,8 +216,7 @@ "prefix": "android", "base": "frame-size", "args": ["--enable-features=OverlayScrollbar", "--enable-threaded-compositing", - "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text", - "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch", + "--enable-prefer-compositing-to-lcd-text", "--force-overlay-fullscreen-video", "--enable-overscroll-notifications", "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"] },
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 6b5ac85d..a2b53c33 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -120403,6 +120403,11 @@ {} ] ], + "content-security-policy/generic/eval-typecheck-callout-order.tentative.html.headers": [ + [ + {} + ] + ], "content-security-policy/generic/fail-0_1.js": [ [ {} @@ -216060,6 +216065,12 @@ {} ] ], + "content-security-policy/generic/eval-typecheck-callout-order.tentative.html": [ + [ + "/content-security-policy/generic/eval-typecheck-callout-order.tentative.html", + {} + ] + ], "content-security-policy/generic/filesystem-urls-do-not-match-self.sub.html": [ [ "/content-security-policy/generic/filesystem-urls-do-not-match-self.sub.html", @@ -324796,6 +324807,14 @@ "7810533e455968eea8eb0bdf4d8edf62e495f956", "testharness" ], + "content-security-policy/generic/eval-typecheck-callout-order.tentative.html": [ + "7b3c12e396445ff72480a1e9c7cc77550f93f75c", + "testharness" + ], + "content-security-policy/generic/eval-typecheck-callout-order.tentative.html.headers": [ + "85de8bd415def35ca45c0abf74590cdfa393d0f4", + "support" + ], "content-security-policy/generic/fail-0_1.js": [ "5c580273dcfc94eff137a0ae65314bebc9b7b5c0", "support" @@ -485685,7 +485704,7 @@ "support" ], "webxr/idlharness.https.window-expected.txt": [ - "93f6ab5a8da7b4a9740101195dae3fc8c158911a", + "20cbc03f1b67ec30b60be9da9729095a778956bc", "support" ], "webxr/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/generic/eval-typecheck-callout-order.tentative.html b/third_party/blink/web_tests/external/wpt/content-security-policy/generic/eval-typecheck-callout-order.tentative.html new file mode 100644 index 0000000..7b3c12e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/generic/eval-typecheck-callout-order.tentative.html
@@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src='/resources/testharness.js' nonce='abc'></script> + <script src='/resources/testharnessreport.js' nonce='abc'></script> + <title>Test for order of Type(evalInput) and host callout</title> +</head> +<body> + <div id='log'></div> + + <script nonce='abc'> + test(function() { + assert_throws(new EvalError, function() { + eval("0"); + }, "eval of a string should reach host callout"); + }, "eval of a string should be checked by CSP"); + + test(function() { + let array = ["0"]; + assert_equals( + eval(array), + array, + "eval is identity when applied to non-strings"); + }, "eval of a non-string should not be checked by CSP"); + </script> + +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/generic/eval-typecheck-callout-order.tentative.html.headers b/third_party/blink/web_tests/external/wpt/content-security-policy/generic/eval-typecheck-callout-order.tentative.html.headers new file mode 100644 index 0000000..85de8bd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/generic/eval-typecheck-callout-order.tentative.html.headers
@@ -0,0 +1 @@ +Content-Security-Policy: script-src 'nonce-abc'
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt index ef62d260..f92d635 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-1-expected.txt
@@ -133,16 +133,6 @@ "reason": "geometry" }, { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment 'about once in a minute.'", "rect": [14, 460, 355, 59], "reason": "geometry" @@ -158,8 +148,18 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { @@ -169,7 +169,7 @@ }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt index 8c72a3fc..68be8c9 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-10-expected.txt
@@ -103,16 +103,6 @@ "reason": "geometry" }, { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment ' was in a furious passion, and went stamping'", "rect": [14, 460, 355, 59], "reason": "appeared" @@ -143,6 +133,16 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The chief difficulty Alice found at first was in managing'", "rect": [14, 80, 354, 119], "reason": "geometry" @@ -174,12 +174,7 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'the'", - "rect": [302, 440, 68, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt index dc60591..7b921bdf 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-2-expected.txt
@@ -193,26 +193,6 @@ "reason": "geometry" }, { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 421, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 421, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment 'about once in a minute.'", "rect": [14, 461, 355, 59], "reason": "geometry" @@ -243,6 +223,26 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 421, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 421, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The chief difficulty Alice found at first was in managing'", "rect": [14, 80, 354, 120], "reason": "geometry" @@ -274,22 +274,22 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 401, 305, 19], + "rect": [65, 401, 304, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 441, 68, 19], + "rect": [302, 441, 67, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.txt index 7fda67f..70aa3f33 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-3-expected.txt
@@ -164,37 +164,37 @@ }, { "object": "NGPhysicalTextFragment ' was in'", - "rect": [14, 440, 340, 79], + "rect": [14, 440, 339, 79], "reason": "appeared" }, { "object": "NGPhysicalTextFragment 'a furious passion, and went stamping about, and'", - "rect": [14, 440, 340, 79], + "rect": [14, 440, 339, 79], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'about once in a minute.'", - "rect": [14, 440, 340, 79], + "rect": [14, 440, 339, 79], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'shouting \u2018Off with his head!\u2019 or \u2018Off with her head!\u2019'", - "rect": [14, 440, 340, 79], + "rect": [14, 440, 339, 79], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting '", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [242, 440, 67, 19], + "rect": [242, 440, 66, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.txt index ef82eb1..c3afda5 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-4-expected.txt
@@ -119,12 +119,12 @@ }, { "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], + "rect": [14, 420, 355, 39], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], + "rect": [14, 420, 355, 39], "reason": "geometry" }, { @@ -159,12 +159,12 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.txt index 1d6190c6..420fd6fc 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-5-expected.txt
@@ -103,26 +103,6 @@ "reason": "geometry" }, { - "object": "NGPhysicalTextFragment ' was in a'", - "rect": [14, 440, 356, 79], - "reason": "appeared" - }, - { - "object": "NGPhysicalTextFragment 'furious passion, and went stamping about, and shouting'", - "rect": [14, 440, 356, 79], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'in a minute.'", - "rect": [14, 440, 356, 79], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment '\u2018Off with his head!\u2019 or \u2018Off with her head!\u2019 about once'", - "rect": [14, 440, 356, 79], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment 'for'", "rect": [14, 400, 356, 59], "reason": "appeared" @@ -138,6 +118,26 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment ' was in a'", + "rect": [14, 440, 355, 79], + "reason": "appeared" + }, + { + "object": "NGPhysicalTextFragment 'furious passion, and went stamping about, and shouting'", + "rect": [14, 440, 355, 79], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'in a minute.'", + "rect": [14, 440, 355, 79], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment '\u2018Off with his head!\u2019 or \u2018Off with her head!\u2019 about once'", + "rect": [14, 440, 355, 79], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The chief difficulty Alice found at first was in managing'", "rect": [14, 80, 354, 119], "reason": "geometry" @@ -169,7 +169,7 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting '", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { @@ -179,7 +179,7 @@ }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.txt index 0b777ca4..bddd578 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-6-expected.txt
@@ -103,16 +103,6 @@ "reason": "geometry" }, { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment 'about once in a minute.'", "rect": [14, 460, 355, 59], "reason": "geometry" @@ -128,6 +118,16 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The chief difficulty Alice found at first was in managing'", "rect": [14, 80, 354, 119], "reason": "geometry" @@ -159,12 +159,12 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt index 7af269a280..82d45e15 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-7-expected.txt
@@ -103,16 +103,6 @@ "reason": "geometry" }, { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment 'about once in a minute.'", "rect": [14, 460, 355, 59], "reason": "geometry" @@ -128,6 +118,16 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The chief difficulty Alice found at first was in managing'", "rect": [14, 80, 354, 119], "reason": "geometry" @@ -159,12 +159,12 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [298, 440, 72, 19], + "rect": [298, 440, 71, 19], "reason": "style change" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.txt index c77a74b..6a915e0 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-8-expected.txt
@@ -129,16 +129,6 @@ }, { "object": "NGPhysicalTextFragment 'and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'quarrelling all the while, and fighting for the hedgehogs;'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'and in a very short time '", "rect": [14, 400, 355, 59], "reason": "geometry" }, @@ -184,7 +174,7 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting '", - "rect": [65, 400, 305, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, { @@ -194,12 +184,12 @@ }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [184, 440, 70, 19], + "rect": [184, 440, 69, 19], "reason": "geometry" }, { "object": "NGPhysicalTextFragment 'the Queen'", - "rect": [302, 440, 68, 19], + "rect": [302, 440, 67, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt index 55f60db..4baf7cc6 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/line-flow-with-floats-9-expected.txt
@@ -108,16 +108,6 @@ "reason": "disappeared" }, { - "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", - "rect": [14, 420, 356, 39], - "reason": "geometry" - }, - { "object": "NGPhysicalTextFragment ' was in a furious passion, and went stamping'", "rect": [14, 460, 355, 59], "reason": "appeared" @@ -148,6 +138,16 @@ "reason": "geometry" }, { + "object": "NGPhysicalTextFragment 'for the hedgehogs; and in a very short time '", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { + "object": "NGPhysicalTextFragment 'for turns, quarrelling all the while, and fighting'", + "rect": [14, 420, 355, 39], + "reason": "geometry" + }, + { "object": "NGPhysicalTextFragment 'The chief difficulty Alice found at first was in managing'", "rect": [14, 80, 354, 119], "reason": "geometry" @@ -179,12 +179,7 @@ }, { "object": "NGPhysicalTextFragment 'The players all played at once without waiting'", - "rect": [65, 400, 305, 19], - "reason": "geometry" - }, - { - "object": "NGPhysicalTextFragment 'the'", - "rect": [302, 440, 68, 19], + "rect": [65, 400, 304, 19], "reason": "geometry" }, {
diff --git a/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-iframe-idb-expected.txt b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-iframe-idb-expected.txt new file mode 100644 index 0000000..8cefe027 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-iframe-idb-expected.txt
@@ -0,0 +1,79 @@ +Tests Application Panel's handling of storages in iframes. + +Initial tree... + +Application + Manifest + Service Workers + Clear storage +Storage + Local Storage + http://127.0.0.1:8000 + http://localhost:8000 + Session Storage + http://127.0.0.1:8000 + http://localhost:8000 + IndexedDB + Database-iframe - http://localhost:8000 + Database-iframe + Database-main-frame - http://127.0.0.1:8000 + Web SQL + Cookies + http://127.0.0.1:8000 + http://localhost:8000 +Cache + Cache Storage + Application Cache +Frames + top + +Remove iframe from page... + +Application + Manifest + Service Workers + Clear storage +Storage + Local Storage + http://127.0.0.1:8000 + Session Storage + http://127.0.0.1:8000 + IndexedDB + Database-main-frame - http://127.0.0.1:8000 + Web SQL + Cookies + http://127.0.0.1:8000 + http://localhost:8000 +Cache + Cache Storage + Application Cache +Frames + top + +Add iframe to page again... + +Application + Manifest + Service Workers + Clear storage +Storage + Local Storage + http://127.0.0.1:8000 + http://localhost:8000 + Session Storage + http://127.0.0.1:8000 + http://localhost:8000 + IndexedDB + Database-main-frame - http://127.0.0.1:8000 + Database-iframe - http://localhost:8000 + Database-iframe + Web SQL + Cookies + http://127.0.0.1:8000 + http://localhost:8000 +Cache + Cache Storage + Application Cache +Frames + top +
diff --git a/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-iframe-idb.js b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-iframe-idb.js new file mode 100644 index 0000000..d03bcaf --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-iframe-idb.js
@@ -0,0 +1,64 @@ +// Copyright 2019 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. + +(async function() { + TestRunner.addResult(`Tests Application Panel's handling of storages in iframes.\n`); + await TestRunner.loadModule('application_test_runner'); + // Note: every test that uses a storage API must manually clean-up state from previous tests. + await ApplicationTestRunner.resetState(); + + await TestRunner.loadModule('console_test_runner'); + await TestRunner.showPanel('resources'); + + function createIndexedDBInMainFrame(callback) { + var mainFrameId = TestRunner.resourceTreeModel.mainFrame.id; + var model = TestRunner.mainTarget.model(Resources.IndexedDBModel); + ApplicationTestRunner.createDatabase(mainFrameId, 'Database-main-frame', () => { + var event = model.addEventListener(Resources.IndexedDBModel.Events.DatabaseAdded, () => { + Common.EventTarget.removeEventListeners([event]); + callback(); + }); + model.refreshDatabaseNames(); + }); + } + + function dumpTree(node, level) { + for (var child of node.children()) { + TestRunner.addResult(' '.repeat(level) + child.listItemElement.textContent); + dumpTree(child, level + 1); + } + } + + // create IndexedDB in iframe + await TestRunner.addIframe('http://localhost:8000/devtools/application-panel/resources/indexeddb-in-iframe.html', {'id': 'indexeddb_page'}); + await TestRunner.addSnifferPromise(UI.panels.resources._sidebar.indexedDBListTreeElement, '_indexedDBLoadedForTest'); + + // create IndexedDB in main frame + await new Promise(createIndexedDBInMainFrame); + await TestRunner.addSnifferPromise(UI.panels.resources._sidebar.indexedDBListTreeElement, '_indexedDBLoadedForTest'); + + const view = UI.panels.resources; + + TestRunner.addResult('Initial tree...\n'); + + dumpTree(view._sidebar._sidebarTree.rootElement(), 0); + + TestRunner.addResult('\nRemove iframe from page...\n'); + await TestRunner.evaluateInPageAsync(` + (function(){ + let iframe = document.getElementById('indexeddb_page'); + iframe.parentNode.removeChild(iframe); + })(); + `); + + dumpTree(view._sidebar._sidebarTree.rootElement(), 0); + + TestRunner.addResult('\nAdd iframe to page again...\n'); + await TestRunner.addIframe('http://localhost:8000/devtools/application-panel/resources/indexeddb-in-iframe.html', {'id': 'indexeddb_page'}); + await TestRunner.addSnifferPromise(UI.panels.resources._sidebar.indexedDBListTreeElement, '_indexedDBLoadedForTest'); + + dumpTree(view._sidebar._sidebarTree.rootElement(), 0); + + TestRunner.completeTest(); +})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-selection-on-reload.js b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-selection-on-reload.js index 2ccb2c8..c120296a 100644 --- a/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-selection-on-reload.js +++ b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources-panel-selection-on-reload.js
@@ -43,11 +43,6 @@ TestRunner.addResult('Visible view is a cookie view: ' + (view.visibleView instanceof Resources.CookieItemsView)); } - function fireFrameNavigated() { - var rtm = TestRunner.resourceTreeModel; - rtm.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameNavigated, rtm.mainFrame); - } - await new Promise(createIndexedDB); await ApplicationTestRunner.createWebSQLDatabase('database-for-test'); UI.viewManager.showView('resources');
diff --git a/third_party/blink/web_tests/http/tests/devtools/application-panel/resources/indexeddb-in-iframe.html b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources/indexeddb-in-iframe.html new file mode 100644 index 0000000..5d94f53 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/application-panel/resources/indexeddb-in-iframe.html
@@ -0,0 +1,22 @@ +<script> + function makeDB() { + return new Promise((resolve) => { + indexedDB.open('Database-iframe').onupgradeneeded = event => { + const db = event.target.result; + const objectStore = db.createObjectStore('Database-iframe'); + objectStore.transaction.oncomplete = _ => { + indexedDB.open('Database-iframe').onsuccess = event => event.target.result + .transaction('Database-iframe', 'readwrite') + .objectStore('Database-iframe') + .add(940123, 'key'); + } + resolve(); + } + }); + } + + window.addEventListener("load", async function(e) { + await makeDB(); + }, false); + +</script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/target/target-expose-devtools-protocol-errors-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/target/target-expose-devtools-protocol-errors-expected.txt new file mode 100644 index 0000000..641557cb --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/target/target-expose-devtools-protocol-errors-expected.txt
@@ -0,0 +1,5 @@ +Verify that errors in the protocol handlers are dispatched in the page. +ReferenceError: c is not defined + at Object.window.cdp.onmessage (<anonymous>:5:37) + at <anonymous>:1:18 +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/target/target-expose-devtools-protocol-errors.js b/third_party/blink/web_tests/http/tests/inspector-protocol/target/target-expose-devtools-protocol-errors.js new file mode 100644 index 0000000..912b127 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/target/target-expose-devtools-protocol-errors.js
@@ -0,0 +1,30 @@ +(async function(testRunner) { + // 1. Create a page, connect to it and use browser connection to grant it a remote debugging capability. + const {page, session, dp} = await testRunner.startBlank( + 'Verify that errors in the protocol handlers are dispatched in the page.'); + await testRunner.browserP().Target.exposeDevToolsProtocol({targetId: page._targetId, bindingName: 'cdp'}); + + // 2. To avoid implementing a protocol client in test, use target domain to validate protocol binding. + await dp.Target.setDiscoverTargets({discover: true}); + + dp.Runtime.enable(); + dp.Runtime.onConsoleAPICalled(result => { + testRunner.log(result.params.args[0].description); + testRunner.completeTest(); + }); + + session.evaluate(() => { + // Redirect unhandled errors into console. + window.onerror = msg => console.log('Unhandled error: ' + msg); + // Inject unhandled error. + window.cdp.onmessage = msg => a = c; + window.cdp.send(JSON.stringify({ + id: 0, + method: 'Target.setDiscoverTargets', + params: { + discover: true + } + })); + }); +}) +
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index d334e07db..1716b22 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js
@@ -942,6 +942,48 @@ chrome.automation.AutomationNode.prototype.focusAffinity; /** + * The node at the start of the selection, if any. + * @type {(!chrome.automation.AutomationNode|undefined)} + * @see https://developer.chrome.com/extensions/automation#type-selectionStartObject + */ +chrome.automation.AutomationNode.prototype.selectionStartObject; + +/** + * The offset at the start of the selection, if any. + * @type {(number|undefined)} + * @see https://developer.chrome.com/extensions/automation#type-selectionStartOffset + */ +chrome.automation.AutomationNode.prototype.selectionStartOffset; + +/** + * The affinity at the start of the selection, if any. + * @type {(string|undefined)} + * @see https://developer.chrome.com/extensions/automation#type-selectionStartAffinity + */ +chrome.automation.AutomationNode.prototype.selectionStartAffinity; + +/** + * The node at the end of the selection, if any. + * @type {(!chrome.automation.AutomationNode|undefined)} + * @see https://developer.chrome.com/extensions/automation#type-selectionEndObject + */ +chrome.automation.AutomationNode.prototype.selectionEndObject; + +/** + * The offset at the end of the selection, if any. + * @type {(number|undefined)} + * @see https://developer.chrome.com/extensions/automation#type-selectionEndOffset + */ +chrome.automation.AutomationNode.prototype.selectionEndOffset; + +/** + * The affinity at the end of the selection, if any. + * @type {(string|undefined)} + * @see https://developer.chrome.com/extensions/automation#type-selectionEndAffinity + */ +chrome.automation.AutomationNode.prototype.selectionEndAffinity; + +/** * The current value for this range. * @type {(number|undefined)} * @see https://developer.chrome.com/extensions/automation#type-valueForRange
diff --git a/third_party/fuchsia-sdk/gen_build_defs.py b/third_party/fuchsia-sdk/gen_build_defs.py index ec501c7..eeb3a4c9 100755 --- a/third_party/fuchsia-sdk/gen_build_defs.py +++ b/third_party/fuchsia-sdk/gen_build_defs.py
@@ -187,12 +187,10 @@ with open(build_output_path, 'w') as buildfile: buildfile.write(_GENERATED_PREAMBLE) - for next_part in toplevel_meta['parts']: - parsed = json.load(open(os.path.join(sdk_base_dir, next_part))) - if 'type' not in parsed: - raise Exception("Couldn't find 'type' node in %s." % next_part) + for part in toplevel_meta['new_parts']: + parsed = json.load(open(os.path.join(sdk_base_dir, part['meta']))) - convert_function = _CONVERSION_FUNCTION_MAP.get(parsed['type']) + convert_function = _CONVERSION_FUNCTION_MAP.get(part['type']) if convert_function is None: raise Exception('Unexpected SDK artifact type %s in %s.' % (parsed['type'], next_part))
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium index 3496570..5ce3406 100644 --- a/third_party/metrics_proto/README.chromium +++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@ Name: Metrics Protos Short Name: metrics_proto URL: This is the canonical public repository -Version: 240367580 -Date: 2019/03/26 UTC +Version: 241818494 +Date: 2019/04/03 UTC License: BSD Security Critical: Yes
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto index c876225..43f9ce58 100644 --- a/third_party/metrics_proto/system_profile.proto +++ b/third_party/metrics_proto/system_profile.proto
@@ -1019,7 +1019,8 @@ // Next Tag: 5 message LinkedAndroidPhoneData { // The pii-free model name of the phone used for Better Together with this - // device. Will not be set if Better Together is not set up. + // device. Will not be set if Better Together is not set up. Hashed using + // variations::HashName() to produce a 32-bit SHA1 hash. optional fixed32 phone_model_name_hash = 1; // True if SmartLock is enabled on this Chromebook.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 10aa162..87cbc3e8 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -160,7 +160,8 @@ 'ToTWinCFI64': 'clang_tot_win_cfi_full_cfi_diag_thin_lto_release_static_dcheck_always_on', 'ToTWinLibcxx64': 'clang_tot_official_optimize_minimal_symbols_static_release_libcxx', 'ToTWinThinLTO64': 'clang_tot_win_official_full_symbols_thin_lto_static', - 'ToTiOS': 'ios_error', + 'ToTiOS': 'clang_tot_ios_simulator', + 'ToTiOSDevice': 'clang_tot_ios_device', 'UBSanVptr Linux': 'ubsan_vptr_release_bot', }, @@ -235,6 +236,15 @@ 'mac-hermetic-upgrade-rel': 'release_bot', 'Chromium Mac 10.13': 'release_bot', + 'ios-device-goma-canary-clobber': 'ios_device', + 'ios-device-goma-latest-clobber': 'ios_device', + 'ios-simulator': 'ios_simulator', + 'ios-simulator-cronet': 'ios_simulator_cronet_no_tss_preload', + 'ios12-beta-simulator': 'ios_simulator', + 'ios12-sdk-device': 'ios_device', + 'ios12-sdk-simulator': 'ios_simulator', + 'ios13-beta-simulator': 'ios_simulator', + 'Mac Builder (dbg) Goma Canary (clobber)': 'debug_bot', 'Mac Builder (dbg) Goma Canary': 'debug_bot', 'Mac Builder (dbg) Goma Latest Client (clobber)': 'debug_bot', @@ -265,11 +275,7 @@ 'fuchsia-fyi-x64-dbg': 'debug_bot_fuchsia', 'fuchsia-fyi-x64-rel': 'release_bot_fuchsia', - 'ios-device-goma-canary-clobber': 'ios_error', - 'ios-device-goma-latest-clobber': 'ios_error', - 'ios-simulator-code-coverage': 'clang_code_coverage_ios', - 'ios-simulator': 'ios_error', 'Jumbo Linux x64': 'jumbo_large_chunks_release_bot_minimal_symbols', 'Jumbo Mac': 'jumbo_release_bot_minimal_symbols', 'Jumbo Win x64': 'jumbo_release_bot_minimal_symbols', @@ -462,12 +468,15 @@ 'Mac Builder': 'gpu_tests_release_bot_minimal_symbols', 'Mac Builder (dbg)': 'gpu_tests_debug_bot', 'mac-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols', - 'ios-device': 'ios_error', - 'ios-device-xcode-clang': 'ios_error', - 'ios-simulator': 'ios_error', - 'ios-simulator-cronet': 'ios_error', - 'ios-simulator-full-configs': 'ios_error', - 'ios-simulator-xcode-clang': 'ios_error', + 'ios-device': 'ios_device_no_symbols', + 'ios-device-xcode-clang': 'ios_device_no_symbols_xcode_clang', + 'ios-simulator': 'ios_simulator', + 'ios-simulator-cronet': 'ios_simulator_cronet', + 'ios-simulator-full-configs': 'ios_simulator', + 'ios-simulator-xcode-clang': 'ios_simulator_no_symbols_xcode_clang', + 'ios-slimnav': 'ios_simulator', + 'ios-uirefresh-simulator': 'ios_simulator', + 'ios12-sdk-simulator': 'ios_simulator', 'WebKit Mac10.13 (retina)': 'release_bot', }, @@ -569,6 +578,8 @@ 'WebRTC Chromium FYI Android Builder': 'android_release_bot_minimal_symbols', 'WebRTC Chromium FYI Android Builder (dbg)': 'android_debug_static_bot', 'WebRTC Chromium FYI Android Builder ARM64 (dbg)': 'android_debug_static_bot_arm64', + 'WebRTC Chromium FYI ios-device': 'ios_device', + 'WebRTC Chromium FYI ios-simulator': 'ios_simulator', 'WebRTC Chromium FYI Linux Builder': 'gpu_tests_release_bot', 'WebRTC Chromium FYI Linux Builder (RBE)': 'gpu_tests_release_bot', 'WebRTC Chromium FYI Linux Builder (dbg)': 'debug_bot', @@ -707,6 +718,7 @@ 'tryserver.chromium.dawn': { 'dawn-linux-x64-deps-rel': 'dawn_tests_release_trybot', + 'dawn-mac-x64-deps-rel': 'dawn_tests_release_trybot', 'dawn-win10-x86-deps-rel': 'dawn_tests_release_trybot_x86', 'dawn-win10-x64-deps-rel': 'dawn_tests_release_trybot', 'linux-dawn-rel': 'gpu_fyi_tests_release_trybot', @@ -785,12 +797,15 @@ }, 'tryserver.chromium.mac': { - 'ios-device': 'ios_error', - 'ios-device-xcode-clang': 'ios_error', - 'ios-simulator': 'ios_error', - 'ios-simulator-full-configs': 'ios_error', - 'ios-simulator-cronet': 'ios_error', - 'ios-simulator-xcode-clang': 'ios_error', + 'ios-device': 'ios_device_no_symbols', + 'ios-device-xcode-clang': 'ios_device_no_symbols_xcode_clang', + 'ios-simulator': 'ios_simulator', + 'ios-simulator-cronet': 'ios_simulator_cronet', + 'ios-simulator-full-configs': 'ios_simulator', + 'ios-simulator-xcode-clang': 'ios_simulator_no_symbols_xcode_clang', + 'ios-slimnav': 'ios_simulator', + 'ios-uirefresh-simulator': 'ios_simulator', + 'ios12-sdk-simulator': 'ios_simulator', 'mac-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols', 'mac_chromium_10.10': 'gpu_tests_release_trybot', 'mac_chromium_10.12_rel_ng': 'gpu_tests_release_trybot', @@ -1257,6 +1272,11 @@ 'dcheck_always_on', 'x86', 'win_linker_timing', ], + # TODO(thakis): Can we use clang_tot here instead of llvm_force_head? + # https://crbug.com/951182. + 'clang_tot_ios_device': ['ios_device', 'ios_disable_code_signing', 'static', 'llvm_force_head'], + 'clang_tot_ios_simulator': ['ios_simulator', 'ios_disable_code_signing', 'static', 'release', 'llvm_force_head'], + 'clang_tot_ubsan_no_recover_hack_static_release': [ 'clang_tot', 'ubsan_no_recover_hack', 'static', 'release', ], @@ -1596,12 +1616,15 @@ 'gn_linux_upload', 'official', 'goma', ], - # The 'ios_error' config is just used for auditing. iOS bots - # actually use the ios recipes, not the chromium recipe, and look - # up their GN arguments via files checked in under //ios/build/bots. - # It is an error to actually use one of these configs to generate the - # build files. - 'ios_error': [ 'error'], + 'ios_device': ['ios_device', 'release_bot', 'ios_disable_code_signing'], + # TODO(justincohen): Why do we build with no_symbols on main waterfall? + # Shouldn't we just build with symbols everywhere? https://crbug.com/951182. + 'ios_device_no_symbols': ['ios_device', 'release_bot', 'ios_disable_code_signing', 'no_symbols'], + 'ios_device_no_symbols_xcode_clang': ['ios_device', 'release_bot', 'ios_disable_code_signing', 'no_symbols', 'xcode_clang'], + 'ios_simulator': ['ios_simulator', 'debug', 'minimal_symbols', 'goma'], + 'ios_simulator_cronet': ['ios_simulator', 'debug', 'minimal_symbols', 'goma', 'ios_cronet_mixins'], + 'ios_simulator_cronet_no_tss_preload': ['ios_simulator', 'debug', 'minimal_symbols', 'goma', 'ios_cronet_mixins_no_tss_preload'], + 'ios_simulator_no_symbols_xcode_clang': ['ios_simulator', 'debug', 'ios_disable_code_signing', 'goma', 'no_symbols', 'xcode_clang'], 'jumbo_release_bot_minimal_symbols': [ 'jumbo', 'release_bot', 'compile_only', @@ -2176,6 +2199,29 @@ 'gn_args': 'target_os="ios"', }, + 'ios_disable_code_signing': { + 'gn_args': 'ios_enable_code_signing=false', + }, + + 'ios_device': { + 'mixins': ['ios'], + 'gn_args': 'target_cpu="arm64"', + }, + + 'ios_simulator': { + 'mixins': ['ios'], + 'gn_args': 'target_cpu="x64"', + }, + + 'ios_cronet_mixins': { + 'gn_args': 'additional_target_cpus=["x86"] disable_brotli_filter=false disable_file_support=true disable_ftp_support=true enable_websockets=false ios_deployment_target="9.0" use_crash_key_stubs=true is_cronet_build=true use_platform_icu_alternatives=true', + }, + + 'ios_cronet_mixins_no_tss_preload': { + 'mixins': ['ios_cronet_mixins'], + 'gn_args': 'include_transport_security_state_preload_list=false', + }, + 'java_coverage': { 'gn_args': 'emma_coverage=true emma_filter="org.chromium.*"', }, @@ -2194,6 +2240,10 @@ 'libfuzzer': { 'gn_args': 'use_libfuzzer=true' }, + 'llvm_force_head': { + 'gn_args': 'llvm_force_head_revision=true', + }, + 'lsan': { 'gn_args': 'is_lsan=true', }, @@ -2410,6 +2460,10 @@ 'gn_args': 'target_os="win"', }, + 'xcode_clang': { + 'gn_args': 'use_xcode_clang=true', + }, + 'x64': { 'gn_args': 'target_cpu="x64"', },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a20d7d3..3bffbe7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -28833,6 +28833,7 @@ <int value="89" label="INLINE_UPDATE_READY_INFOBAR_ANDROID"/> <int value="90" label="INLINE_UPDATE_FAILED_INFOBAR_ANDROID"/> <int value="91" label="FLASH_DEPRECATION_INFOBAR_DELEGATE"/> + <int value="92" label="SEND_TAB_TO_SELF_INFOBAR_DELEGATE"/> </enum> <enum name="InfoBarResponse"> @@ -32034,6 +32035,7 @@ label="AutofillCreditCardLastUsedDateDisplay:enabled"/> <int value="-2080504230" label="TabHoverCards:disabled"/> <int value="-2077268643" label="disable-device-enumeration"/> + <int value="-2076250656" label="MojoIMF:enabled"/> <int value="-2075870708" label="MediaRemotingEncrypted:disabled"/> <int value="-2075807193" label="enable-webusb-on-any-origin"/> <int value="-2075725205" label="disable-new-zip-unpacker"/> @@ -32175,6 +32177,7 @@ <int value="-1892555086" label="disable-compositor-animation-timelines"/> <int value="-1892000374" label="SeccompSandboxAndroid:enabled"/> <int value="-1890374564" label="OobeRecommendAppsScreen:disabled"/> + <int value="-1890060129" label="MojoIMF:disabled"/> <int value="-1888273969" label="tab-capture-upscale-quality"/> <int value="-1887862464" label="SpannableInlineAutocomplete:disabled"/> <int value="-1887053262" @@ -38032,7 +38035,12 @@ <int value="3" label="A navigation suggestion is found using top sites list"/> <int value="4" label="A navigation suggestion is found using site engagement"/> - <int value="5" label="A navigation suggestion is found using edit distance"/> + <int value="5" + label="A navigation suggestion is found using edit distance against a + top domain"/> + <int value="6" + label="A navigation suggestion is found using edit distance against an + engaged site"/> </enum> <enum name="NavigationWasServedFromCache">
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc index b5e60f700..f7d3f50f 100644 --- a/ui/accessibility/ax_event_generator.cc +++ b/ui/accessibility/ax_event_generator.cc
@@ -404,7 +404,8 @@ AddEvent(tree->root(), Event::LOAD_COMPLETE); } - if (new_tree_data.sel_anchor_object_id != + if (new_tree_data.sel_is_backward != old_tree_data.sel_is_backward || + new_tree_data.sel_anchor_object_id != old_tree_data.sel_anchor_object_id || new_tree_data.sel_anchor_offset != old_tree_data.sel_anchor_offset || new_tree_data.sel_anchor_affinity != old_tree_data.sel_anchor_affinity ||
diff --git a/ui/accessibility/ax_tree_combiner.cc b/ui/accessibility/ax_tree_combiner.cc index 207a2aa3..3d57d47 100644 --- a/ui/accessibility/ax_tree_combiner.cc +++ b/ui/accessibility/ax_tree_combiner.cc
@@ -52,6 +52,8 @@ focused_tree = tree_id_map_[focused_tree_id]; combined_.tree_data.focus_id = MapId(focused_tree_id, focused_tree->tree_data.focus_id); + combined_.tree_data.sel_is_backward = + MapId(focused_tree_id, focused_tree->tree_data.sel_is_backward); combined_.tree_data.sel_anchor_object_id = MapId(focused_tree_id, focused_tree->tree_data.sel_anchor_object_id); combined_.tree_data.sel_focus_object_id =
diff --git a/ui/accessibility/ax_tree_data.cc b/ui/accessibility/ax_tree_data.cc index ee2a8e13..7380fe3 100644 --- a/ui/accessibility/ax_tree_data.cc +++ b/ui/accessibility/ax_tree_data.cc
@@ -48,6 +48,8 @@ if (sel_anchor_object_id != -1) { result += + (sel_is_backward ? " sel_is_backward=true" : " sel_is_backward=false"); + result += " sel_anchor_object_id=" + base::NumberToString(sel_anchor_object_id); result += " sel_anchor_offset=" + base::NumberToString(sel_anchor_offset); result += " sel_anchor_affinity=";
diff --git a/ui/accessibility/ax_tree_data.h b/ui/accessibility/ax_tree_data.h index 2470f4e..39e88c6 100644 --- a/ui/accessibility/ax_tree_data.h +++ b/ui/accessibility/ax_tree_data.h
@@ -60,6 +60,7 @@ // (selection end). If the offset could correspond to a position on two // different lines, sel_upstream_affinity means the cursor is on the first // line, otherwise it's on the second line. + bool sel_is_backward = false; int32_t sel_anchor_object_id = -1; int32_t sel_anchor_offset = -1; ax::mojom::TextAffinity sel_anchor_affinity =
diff --git a/ui/accessibility/mojom/ax_tree_data.mojom b/ui/accessibility/mojom/ax_tree_data.mojom index c2fabbf2..626691f 100644 --- a/ui/accessibility/mojom/ax_tree_data.mojom +++ b/ui/accessibility/mojom/ax_tree_data.mojom
@@ -19,6 +19,7 @@ string title; string url; int32 focus_id; + bool sel_is_backward; int32 sel_anchor_object_id; int32 sel_anchor_offset; ax.mojom.TextAffinity sel_anchor_affinity;
diff --git a/ui/accessibility/mojom/ax_tree_data_mojom_traits.cc b/ui/accessibility/mojom/ax_tree_data_mojom_traits.cc index 50ad6115..9450001 100644 --- a/ui/accessibility/mojom/ax_tree_data_mojom_traits.cc +++ b/ui/accessibility/mojom/ax_tree_data_mojom_traits.cc
@@ -27,6 +27,7 @@ if (!data.ReadUrl(&out->url)) return false; out->focus_id = data.focus_id(); + out->sel_is_backward = data.sel_is_backward(); out->sel_anchor_object_id = data.sel_anchor_object_id(); out->sel_anchor_offset = data.sel_anchor_offset(); out->sel_anchor_affinity = data.sel_anchor_affinity();
diff --git a/ui/accessibility/mojom/ax_tree_data_mojom_traits.h b/ui/accessibility/mojom/ax_tree_data_mojom_traits.h index 6beea97..6be48769 100644 --- a/ui/accessibility/mojom/ax_tree_data_mojom_traits.h +++ b/ui/accessibility/mojom/ax_tree_data_mojom_traits.h
@@ -35,6 +35,9 @@ static const std::string& title(const ui::AXTreeData& p) { return p.title; } static const std::string& url(const ui::AXTreeData& p) { return p.url; } static int32_t focus_id(const ui::AXTreeData& p) { return p.focus_id; } + static bool sel_is_backward(const ui::AXTreeData& p) { + return p.sel_is_backward; + } static int32_t sel_anchor_object_id(const ui::AXTreeData& p) { return p.sel_anchor_object_id; }
diff --git a/ui/accessibility/mojom/ax_tree_data_mojom_traits_unittest.cc b/ui/accessibility/mojom/ax_tree_data_mojom_traits_unittest.cc index fa3cb0e..2508d22 100644 --- a/ui/accessibility/mojom/ax_tree_data_mojom_traits_unittest.cc +++ b/ui/accessibility/mojom/ax_tree_data_mojom_traits_unittest.cc
@@ -26,6 +26,7 @@ input.title = "7"; input.url = "8"; input.focus_id = 9; + input.sel_is_backward = true; // Set to true only for testing purposes. input.sel_anchor_object_id = 10; input.sel_anchor_offset = 11; input.sel_anchor_affinity = ax::mojom::TextAffinity::kUpstream; @@ -45,6 +46,7 @@ EXPECT_EQ("7", output.title); EXPECT_EQ("8", output.url); EXPECT_EQ(9, output.focus_id); + EXPECT_TRUE(output.sel_is_backward); EXPECT_EQ(10, output.sel_anchor_object_id); EXPECT_EQ(11, output.sel_anchor_offset); EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, output.sel_anchor_affinity);
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 91c6b26..5e93250 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -21,6 +21,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/threading/thread.h" +#include "base/trace_event/trace_event.h" #include "cc/base/switches.h" #include "components/discardable_memory/client/client_discardable_shared_memory_manager.h" #include "mojo/public/cpp/bindings/map.h" @@ -1224,6 +1225,14 @@ if (!window) return; + if (IsRoot(window)) { + TRACE_EVENT_WITH_FLOW0( + "ui", "ClientRoot::NotifyClientOfNewBounds", + local_surface_id_allocation->local_surface_id().hash(), + TRACE_EVENT_FLAG_FLOW_IN); + } + TRACE_EVENT0("ui", "WindowTreeClient::OnWindowBoundsChanged"); + InFlightBoundsChange new_change(this, window, new_bounds, /* from_server */ true, local_surface_id_allocation);
diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc index a59d08c..dadc140 100644 --- a/ui/base/accelerators/accelerator.cc +++ b/ui/base/accelerators/accelerator.cc
@@ -65,7 +65,8 @@ // |modifiers_| may include the repeat flag. modifiers_(key_event.flags() & kInterestingFlagsMask), time_stamp_(key_event.time_stamp()), - interrupted_by_mouse_event_(false) {} + interrupted_by_mouse_event_(false), + source_device_id_(key_event.source_device_id()) {} Accelerator::Accelerator(const Accelerator& accelerator) { key_code_ = accelerator.key_code_; @@ -73,6 +74,7 @@ modifiers_ = accelerator.modifiers_; time_stamp_ = accelerator.time_stamp_; interrupted_by_mouse_event_ = accelerator.interrupted_by_mouse_event_; + source_device_id_ = accelerator.source_device_id_; } Accelerator::~Accelerator() {
diff --git a/ui/base/accelerators/accelerator.h b/ui/base/accelerators/accelerator.h index 643d508f..5ece4bf 100644 --- a/ui/base/accelerators/accelerator.h +++ b/ui/base/accelerators/accelerator.h
@@ -78,6 +78,8 @@ base::TimeTicks time_stamp() const { return time_stamp_; } + int source_device_id() const { return source_device_id_; } + bool IsShiftDown() const; bool IsCtrlDown() const; bool IsAltDown() const; @@ -121,6 +123,9 @@ // TOGGLE_APP_LIST and TOGGLE_APP_LIST_FULLSCREEN are disabled when mouse // press/release occurs between search key down and up. See crbug.com/665897) bool interrupted_by_mouse_event_; + + // The |source_device_id_| of the KeyEvent. + int source_device_id_ = -1; }; // An interface that classes that want to register for keyboard accelerators
diff --git a/ui/events/devices/device_data_manager.cc b/ui/events/devices/device_data_manager.cc index f94d420..71389f36 100644 --- a/ui/events/devices/device_data_manager.cc +++ b/ui/events/devices/device_data_manager.cc
@@ -149,6 +149,11 @@ return touchpad_devices_; } +const std::vector<InputDevice>& DeviceDataManager::GetUncategorizedDevices() + const { + return uncategorized_devices_; +} + bool DeviceDataManager::AreDeviceListsComplete() const { return device_lists_complete_; } @@ -217,6 +222,17 @@ NotifyObserversTouchpadDeviceConfigurationChanged(); } +void DeviceDataManager::OnUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) { + if (devices.size() == uncategorized_devices_.size() && + std::equal(devices.begin(), devices.end(), uncategorized_devices_.begin(), + InputDeviceEquals)) { + return; + } + uncategorized_devices_ = devices; + NotifyObserversUncategorizedDeviceConfigurationChanged(); +} + void DeviceDataManager::OnDeviceListsComplete() { if (!device_lists_complete_) { device_lists_complete_ = true; @@ -241,6 +257,10 @@ OnInputDeviceConfigurationChanged(InputDeviceEventObserver::kTouchpad)) NOTIFY_OBSERVERS( + NotifyObserversUncategorizedDeviceConfigurationChanged(), + OnInputDeviceConfigurationChanged(InputDeviceEventObserver::kUncategorized)) + +NOTIFY_OBSERVERS( NotifyObserversTouchscreenDeviceConfigurationChanged(), OnInputDeviceConfigurationChanged(InputDeviceEventObserver::kTouchscreen))
diff --git a/ui/events/devices/device_data_manager.h b/ui/events/devices/device_data_manager.h index 22062276..d5be2ea 100644 --- a/ui/events/devices/device_data_manager.h +++ b/ui/events/devices/device_data_manager.h
@@ -60,6 +60,7 @@ const std::vector<InputDevice>& GetKeyboardDevices() const override; const std::vector<InputDevice>& GetMouseDevices() const override; const std::vector<InputDevice>& GetTouchpadDevices() const override; + const std::vector<InputDevice>& GetUncategorizedDevices() const override; bool AreDeviceListsComplete() const override; bool AreTouchscreensEnabled() const override; bool AreTouchscreenTargetDisplaysValid() const override; @@ -80,6 +81,8 @@ const std::vector<InputDevice>& devices) override; void OnTouchpadDevicesUpdated( const std::vector<InputDevice>& devices) override; + void OnUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) override; void OnDeviceListsComplete() override; void OnStylusStateChanged(StylusState state) override; @@ -96,6 +99,7 @@ void NotifyObserversKeyboardDeviceConfigurationChanged(); void NotifyObserversMouseDeviceConfigurationChanged(); void NotifyObserversTouchpadDeviceConfigurationChanged(); + void NotifyObserversUncategorizedDeviceConfigurationChanged(); void NotifyObserversDeviceListsComplete(); void NotifyObserversStylusStateChanged(StylusState stylus_state); @@ -105,6 +109,7 @@ std::vector<InputDevice> keyboard_devices_; std::vector<InputDevice> mouse_devices_; std::vector<InputDevice> touchpad_devices_; + std::vector<InputDevice> uncategorized_devices_; bool device_lists_complete_ = false; base::ObserverList<InputDeviceEventObserver>::Unchecked observers_;
diff --git a/ui/events/devices/device_hotplug_event_observer.h b/ui/events/devices/device_hotplug_event_observer.h index 7b846bc..ec7f678 100644 --- a/ui/events/devices/device_hotplug_event_observer.h +++ b/ui/events/devices/device_hotplug_event_observer.h
@@ -40,6 +40,12 @@ virtual void OnTouchpadDevicesUpdated( const std::vector<InputDevice>& devices) = 0; + // On a hotplug event this is called with the list of the available + // uncategorized input devices, which means not touchscreens, keyboards, mice + // and touchpads. + virtual void OnUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) = 0; + // On completion of the initial startup scan. This means all of the above // OnDevicesUpdated() methods have been called with a complete list. virtual void OnDeviceListsComplete() = 0;
diff --git a/ui/events/devices/input_device_event_observer.h b/ui/events/devices/input_device_event_observer.h index 6310592..ca4c974 100644 --- a/ui/events/devices/input_device_event_observer.h +++ b/ui/events/devices/input_device_event_observer.h
@@ -22,6 +22,7 @@ static constexpr uint8_t kMouse = 1 << 1; static constexpr uint8_t kTouchpad = 1 << 2; static constexpr uint8_t kTouchscreen = 1 << 3; + static constexpr uint8_t kUncategorized = 1 << 4; virtual ~InputDeviceEventObserver() {}
diff --git a/ui/events/devices/input_device_manager.h b/ui/events/devices/input_device_manager.h index 4f72ea6..0a4317e9 100644 --- a/ui/events/devices/input_device_manager.h +++ b/ui/events/devices/input_device_manager.h
@@ -32,6 +32,10 @@ virtual const std::vector<InputDevice>& GetMouseDevices() const = 0; virtual const std::vector<InputDevice>& GetTouchpadDevices() const = 0; + // Returns all the uncategorized input devices, which means input devices + // besides keyboards, touchscreens, mice and touchpads. + virtual const std::vector<InputDevice>& GetUncategorizedDevices() const = 0; + virtual bool AreDeviceListsComplete() const = 0; virtual bool AreTouchscreensEnabled() const = 0;
diff --git a/ui/events/keycodes/dom/keycode_converter_data.inc b/ui/events/keycodes/dom/keycode_converter_data.inc index d4174fc5..53cc8a3 100644 --- a/ui/events/keycodes/dom/keycode_converter_data.inc +++ b/ui/events/keycodes/dom/keycode_converter_data.inc
@@ -103,6 +103,9 @@ USB_KEYMAP(0x000014, 0x0000, 0x0000, 0x0000, 0xffff, "Suspend", SUSPEND), USB_KEYMAP(0x000015, 0x0000, 0x0000, 0x0000, 0xffff, "Resume", RESUME), USB_KEYMAP(0x000016, 0x0000, 0x0000, 0x0000, 0xffff, "Turbo", TURBO), + // AL Context-aware desktop assistant, not in HID specification (yet?) + USB_KEYMAP(0x000017, 0x0247, 0x024f, 0x0000, 0xffff, "LaunchAssistant", + LAUNCH_ASSISTANT), // ========================================= // USB Usage Page 0x01: Generic Desktop Page @@ -113,9 +116,6 @@ // USB evdev XKB Win Mac USB_KEYMAP(0x010082, 0x008e, 0x0096, 0xe05f, 0xffff, "Sleep", SLEEP), // SystemSleep USB_KEYMAP(0x010083, 0x008f, 0x0097, 0xe063, 0xffff, "WakeUp", WAKE_UP), - USB_KEYMAP(0x0100b5, 0x00e3, 0x00eb, 0x0000, 0xffff, NULL, - DISPLAY_TOGGLE_INT_EXT), // System Display Toggle Int/Ext - // ========================================= // USB Usage Page 0x07: Keyboard/Keypad Page @@ -539,9 +539,7 @@ USB_KEYMAP(0x0c01ae, 0x0176, 0x017e, 0x0000, 0xffff, NULL, LAUNCH_KEYBOARD_LAYOUT), USB_KEYMAP(0x0c01b1, 0x0245, 0x024d, 0x0000, 0xffff, "LaunchScreenSaver", LAUNCH_SCREEN_SAVER), // AL Screen Saver - USB_KEYMAP(0x0c01cb, 0x0247, 0x024f, 0x0000, 0xffff, NULL, - LAUNCH_ASSISTANT), // AL Context-aware desktop assistant - // USB#0c01b4: Home Directory (AL_FileBrowser) (Explorer) + // USB#0c01b4: Home Directory (AL_FileBrowser) (Explorer) //USB_KEYMAP(0x0c01b4, 0x0000, 0x0000, 0x0000, 0xffff, NULL, LAUNCH_FILE_BROWSER), // USB#0x0c01b7: AL Audio Browser USB_KEYMAP(0x0c01b7, 0x0188, 0x0190, 0x0000, 0xffff, NULL, LAUNCH_AUDIO_BROWSER), @@ -576,8 +574,8 @@ //USB_KEYMAP(0x0c0230, 0x0000, 0x0000, 0x0000, 0xffff, NULL, ZOOM_FULL), // USB#0x0c0231: AC Normal View //USB_KEYMAP(0x0c0231, 0x0000, 0x0000, 0x0000, 0xffff, NULL, ZOOM_NORMAL), - USB_KEYMAP(0x0c0232, 0x0174, 0x017c, 0x0000, 0xffff, NULL, - ZOOM_TOGGLE), // AC View Toggle + // USB#0x0c0232: AC View Toggle + USB_KEYMAP(0x0c0232, 0x0000, 0x0000, 0x0000, 0xffff, "ZoomToggle", ZOOM_TOGGLE), // USB#0x0c0279: AC Redo/Repeat USB_KEYMAP(0x0c0279, 0x00b6, 0x00be, 0x0000, 0xffff, NULL, REDO), // USB#0x0c0289: AC_Reply @@ -586,6 +584,4 @@ USB_KEYMAP(0x0c028b, 0x00e9, 0x00f1, 0x0000, 0xffff, "MailForward", MAIL_FORWARD), // USB#0x0c028c: AC_Send USB_KEYMAP(0x0c028c, 0x00e7, 0x00ef, 0x0000, 0xffff, "MailSend", MAIL_SEND), - USB_KEYMAP(0x0c029f, 0x0078, 0x0080, 0x0000, 0xffff, NULL, - SHOW_ALL_WINDOWS), // AC Desktop Show All Windows };
diff --git a/ui/events/keycodes/dom/keycode_converter_unittest.cc b/ui/events/keycodes/dom/keycode_converter_unittest.cc index b82d525..d3e51aa3 100644 --- a/ui/events/keycodes/dom/keycode_converter_unittest.cc +++ b/ui/events/keycodes/dom/keycode_converter_unittest.cc
@@ -24,10 +24,10 @@ // These are in the same order as the columns in keycode_converter_data.inc // as reflected in the USB_KEYMAP() macro below. const size_t expected_mapped_key_count[] = { - 211, // evdev - 211, // xkb - 157, // windows - 118, // mac + 208, // evdev + 208, // xkb + 157, // windows + 118, // mac }; const size_t kNativeColumns = base::size(expected_mapped_key_count);
diff --git a/ui/events/keycodes/dom_us_layout_data.h b/ui/events/keycodes/dom_us_layout_data.h index b61b001..3bfcadcb 100644 --- a/ui/events/keycodes/dom_us_layout_data.h +++ b/ui/events/keycodes/dom_us_layout_data.h
@@ -416,6 +416,10 @@ // DomCode::SUSPEND 0x000014 Suspend // DomCode::RESUME 0x000015 Resume // DomCode::TURBO 0x000016 Turbo +#if defined(OS_POSIX) + {DomCode::LAUNCH_ASSISTANT, + VKEY_ASSISTANT}, // 0x000017 Launch Assistant +#endif {DomCode::SLEEP, VKEY_SLEEP}, // 0x010082 Sleep // DomCode::WAKE_UP 0x010083 WakeUp {DomCode::US_A, VKEY_A}, // 0x070004 KeyA @@ -600,8 +604,6 @@ #if defined(OS_POSIX) {DomCode::LAUNCH_CONTROL_PANEL, VKEY_SETTINGS}, // 0x0C019F Launch Assistant - {DomCode::LAUNCH_ASSISTANT, - VKEY_ASSISTANT}, // 0x0C01CB Launch Assistant #endif {DomCode::BROWSER_SEARCH, VKEY_BROWSER_SEARCH}, // 0x0C0221 BrowserSearch
diff --git a/ui/events/ozone/evdev/device_event_dispatcher_evdev.h b/ui/events/ozone/evdev/device_event_dispatcher_evdev.h index f37d66b7..197be1d3 100644 --- a/ui/events/ozone/evdev/device_event_dispatcher_evdev.h +++ b/ui/events/ozone/evdev/device_event_dispatcher_evdev.h
@@ -183,6 +183,8 @@ virtual void DispatchStylusStateChanged(StylusState stylus_state) = 0; virtual void DispatchGamepadDevicesUpdated( const std::vector<InputDevice>& devices) = 0; + virtual void DispatchUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) = 0; }; } // namespace ui
diff --git a/ui/events/ozone/evdev/event_converter_test_util.cc b/ui/events/ozone/evdev/event_converter_test_util.cc index 52d339c..57b14c7 100644 --- a/ui/events/ozone/evdev/event_converter_test_util.cc +++ b/ui/events/ozone/evdev/event_converter_test_util.cc
@@ -78,6 +78,10 @@ const std::vector<InputDevice>& devices) override { event_factory_evdev_->DispatchTouchpadDevicesUpdated(devices); } + void DispatchUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) override { + event_factory_evdev_->DispatchUncategorizedDevicesUpdated(devices); + } void DispatchDeviceListsComplete() override { event_factory_evdev_->DispatchDeviceListsComplete(); }
diff --git a/ui/events/ozone/evdev/event_device_info_unittest.cc b/ui/events/ozone/evdev/event_device_info_unittest.cc index 3e7c081..f09d730 100644 --- a/ui/events/ozone/evdev/event_device_info_unittest.cc +++ b/ui/events/ozone/evdev/event_device_info_unittest.cc
@@ -43,6 +43,18 @@ EXPECT_EQ(ui::InputDeviceType::INPUT_DEVICE_INTERNAL, devinfo.device_type()); } +TEST(EventDeviceInfoTest, SideVolumeButton) { + EventDeviceInfo devinfo; + EXPECT_TRUE(CapabilitiesToDeviceInfo(kSideVolumeButton, &devinfo)); + + EXPECT_FALSE(devinfo.HasKeyboard()); + EXPECT_FALSE(devinfo.HasMouse()); + EXPECT_FALSE(devinfo.HasTouchpad()); + EXPECT_FALSE(devinfo.HasTouchscreen()); + EXPECT_FALSE(devinfo.HasTablet()); + EXPECT_FALSE(devinfo.HasGamepad()); +} + TEST(EventDeviceInfoTest, BasicCrosTouchscreen) { EventDeviceInfo devinfo; EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
diff --git a/ui/events/ozone/evdev/event_device_test_util.cc b/ui/events/ozone/evdev/event_device_test_util.cc index e652ea7..0cdb1f6a 100644 --- a/ui/events/ozone/evdev/event_device_test_util.cc +++ b/ui/events/ozone/evdev/event_device_test_util.cc
@@ -760,6 +760,28 @@ base::size(kIlitekTPAbsAxes), }; +const DeviceCapabilities kSideVolumeButton = { + /* path */ + "/sys/devices/pci0000:00/0000:00:1f.0/PNP0C09:00/GOOG0004:00/GOOG0007:00/" + "input/input5/event4", + /* name */ "cros_ec_buttons", + /* phys */ "GOOG0004:00/input1", + /* uniq */ "", + /* bustype */ "0006", + /* vendor */ "0000", + /* product */ "0000", + /* version */ "0001", + /* prop */ "0", + /* ev */ "100023", + /* key */ "1c000000000000 0", + /* rel */ "0", + /* abs */ "0", + /* msc */ "0", + /* sw */ "1", + /* led */ "0", + /* ff */ "0", +}; + // NB: Please use the capture_device_capabilities.py script to add more // test data here. This will help ensure the data matches what the kernel // reports for a real device and is entered correctly.
diff --git a/ui/events/ozone/evdev/event_device_test_util.h b/ui/events/ozone/evdev/event_device_test_util.h index 533690f..203b8aa 100644 --- a/ui/events/ozone/evdev/event_device_test_util.h +++ b/ui/events/ozone/evdev/event_device_test_util.h
@@ -81,6 +81,7 @@ extern const DeviceCapabilities kHammerTouchpad; extern const DeviceCapabilities kIlitekTP_Mouse; extern const DeviceCapabilities kIlitekTP; +extern const DeviceCapabilities kSideVolumeButton; } // namspace ui
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc index cdc68677..067f5662 100644 --- a/ui/events/ozone/evdev/event_factory_evdev.cc +++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -140,6 +140,14 @@ event_factory_evdev_, devices)); } + void DispatchUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) override { + ui_thread_runner_->PostTask( + FROM_HERE, + base::BindOnce(&EventFactoryEvdev::DispatchUncategorizedDevicesUpdated, + event_factory_evdev_, devices)); + } + private: scoped_refptr<base::SingleThreadTaskRunner> ui_thread_runner_; base::WeakPtr<EventFactoryEvdev> event_factory_evdev_; @@ -409,6 +417,14 @@ observer->OnStylusStateChanged(stylus_state); } +void EventFactoryEvdev::DispatchUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) { + TRACE_EVENT0("evdev", + "EventFactoryEvdev::DispatchUncategorizedDevicesUpdated"); + DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); + observer->OnUncategorizedDevicesUpdated(devices); +} + void EventFactoryEvdev::DispatchGamepadDevicesUpdated( const std::vector<InputDevice>& devices) { TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchGamepadDevicesUpdated");
diff --git a/ui/events/ozone/evdev/event_factory_evdev.h b/ui/events/ozone/evdev/event_factory_evdev.h index 1c6a1cc..ce77fb1 100644 --- a/ui/events/ozone/evdev/event_factory_evdev.h +++ b/ui/events/ozone/evdev/event_factory_evdev.h
@@ -81,6 +81,8 @@ const std::vector<TouchscreenDevice>& devices); void DispatchMouseDevicesUpdated(const std::vector<InputDevice>& devices); void DispatchTouchpadDevicesUpdated(const std::vector<InputDevice>& devices); + void DispatchUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices); void DispatchDeviceListsComplete(); void DispatchStylusStateChanged(StylusState stylus_state);
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index 0871b55..b621db9 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -156,6 +156,12 @@ return CreateConverter(params, std::move(fd), devinfo); } +bool IsUncategorizedDevice(const EventConverterEvdev& converter) { + return !converter.HasTouchscreen() && !converter.HasKeyboard() && + !converter.HasMouse() && !converter.HasTouchpad() && + !converter.HasGamepad(); +} + } // namespace InputDeviceFactoryEvdev::InputDeviceFactoryEvdev( @@ -391,6 +397,9 @@ if (converter->HasGamepad()) gamepad_list_dirty_ = true; + + if (IsUncategorizedDevice(*converter)) + uncategorized_list_dirty_ = true; } void InputDeviceFactoryEvdev::NotifyDevicesUpdated() { @@ -406,6 +415,8 @@ NotifyTouchpadDevicesUpdated(); if (gamepad_list_dirty_) NotifyGamepadDevicesUpdated(); + if (uncategorized_list_dirty_) + NotifyUncategorizedDevicesUpdated(); if (!startup_devices_opened_) { dispatcher_->DispatchDeviceListsComplete(); startup_devices_opened_ = true; @@ -415,6 +426,7 @@ mouse_list_dirty_ = false; touchpad_list_dirty_ = false; gamepad_list_dirty_ = false; + uncategorized_list_dirty_ = false; } void InputDeviceFactoryEvdev::NotifyTouchscreensUpdated() { @@ -474,6 +486,16 @@ dispatcher_->DispatchGamepadDevicesUpdated(gamepads); } +void InputDeviceFactoryEvdev::NotifyUncategorizedDevicesUpdated() { + std::vector<InputDevice> uncategorized_devices; + for (auto it = converters_.begin(); it != converters_.end(); ++it) { + if (IsUncategorizedDevice(*(it->second))) + uncategorized_devices.push_back(it->second->input_device()); + } + + dispatcher_->DispatchUncategorizedDevicesUpdated(uncategorized_devices); +} + void InputDeviceFactoryEvdev::SetIntPropertyForOneType( const EventDeviceType type, const std::string& name,
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.h b/ui/events/ozone/evdev/input_device_factory_evdev.h index a47c9b4..085908f3 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.h +++ b/ui/events/ozone/evdev/input_device_factory_evdev.h
@@ -86,6 +86,7 @@ void NotifyMouseDevicesUpdated(); void NotifyTouchpadDevicesUpdated(); void NotifyGamepadDevicesUpdated(); + void NotifyUncategorizedDevicesUpdated(); void SetIntPropertyForOneType(const EventDeviceType type, const std::string& name, @@ -117,6 +118,7 @@ bool mouse_list_dirty_ = true; bool touchpad_list_dirty_ = true; bool gamepad_list_dirty_ = true; + bool uncategorized_list_dirty_ = true; // Whether we have a list of devices that were present at startup. bool startup_devices_enumerated_ = false;
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index 4b04146..0104171 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -159,6 +159,8 @@ const std::vector<InputDevice>& devices) override {} void DispatchTouchpadDevicesUpdated( const std::vector<InputDevice>& devices) override {} + void DispatchUncategorizedDevicesUpdated( + const std::vector<InputDevice>& devices) override {} void DispatchDeviceListsComplete() override {} void DispatchStylusStateChanged(StylusState stylus_state) override {}
diff --git a/ui/file_manager/image_loader/piex/tests.js b/ui/file_manager/image_loader/piex/tests.js index 0763897f..2b15b1f 100644 --- a/ui/file_manager/image_loader/piex/tests.js +++ b/ui/file_manager/image_loader/piex/tests.js
@@ -95,11 +95,11 @@ return window.createFileSystem(length); }, images.length); - for (let i = 0; i < images.length; ++i) { - await page.evaluate((image) => { + await Promise.all(images.map((image) => { + return page.evaluate((image) => { return window.writeToFileSystem(image); - }, images[i]); - } + }, image); + })); await page.evaluate(() => { window.testTime = 0;
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc index 9692d59a..6bcb61d 100644 --- a/ui/keyboard/keyboard_controller.cc +++ b/ui/keyboard/keyboard_controller.cc
@@ -571,8 +571,7 @@ mojom::KeyboardOverscrollBehavior::kEnabled; } - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableVirtualKeyboardOverscroll); + return true; } // private
diff --git a/ui/keyboard/public/keyboard_switches.cc b/ui/keyboard/public/keyboard_switches.cc index 14eb206..247b92a 100644 --- a/ui/keyboard/public/keyboard_switches.cc +++ b/ui/keyboard/public/keyboard_switches.cc
@@ -9,8 +9,6 @@ const char kDisableGestureTyping[] = "disable-gesture-typing"; const char kEnableVirtualKeyboard[] = "enable-virtual-keyboard"; -const char kDisableVirtualKeyboardOverscroll[] = - "disable-virtual-keyboard-overscroll"; } // namespace switches } // namespace keyboard
diff --git a/ui/keyboard/public/keyboard_switches.h b/ui/keyboard/public/keyboard_switches.h index d4e7469..6931e7c 100644 --- a/ui/keyboard/public/keyboard_switches.h +++ b/ui/keyboard/public/keyboard_switches.h
@@ -16,11 +16,6 @@ // Enables the virtual keyboard. KEYBOARD_EXPORT extern const char kEnableVirtualKeyboard[]; -// Disabled overscrolling of web content when the virtual keyboard is displayed. -// If disabled, the work area is resized to restrict windows from overlapping -// with the keybaord area. -KEYBOARD_EXPORT extern const char kDisableVirtualKeyboardOverscroll[]; - } // namespace switches } // namespace keyboard
diff --git a/ui/message_center/views/notification_header_view.cc b/ui/message_center/views/notification_header_view.cc index 4e6d92c..8ef9bbf 100644 --- a/ui/message_center/views/notification_header_view.cc +++ b/ui/message_center/views/notification_header_view.cc
@@ -202,6 +202,7 @@ summary_text_divider_->SetLineHeight(font_list_height); summary_text_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT); summary_text_divider_->SetBorder(views::CreateEmptyBorder(text_view_padding)); + summary_text_divider_->SetEnabledColor(accent_color_); summary_text_divider_->SetVisible(false); DCHECK_EQ(kInnerHeaderHeight, summary_text_divider_->GetPreferredSize().height()); @@ -213,6 +214,7 @@ summary_text_view_->SetLineHeight(font_list_height); summary_text_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); summary_text_view_->SetBorder(views::CreateEmptyBorder(text_view_padding)); + summary_text_view_->SetEnabledColor(accent_color_); summary_text_view_->SetVisible(false); DCHECK_EQ(kInnerHeaderHeight, summary_text_view_->GetPreferredSize().height()); @@ -287,7 +289,14 @@ UpdateSummaryTextVisibility(); } +void NotificationHeaderView::SetSummaryText(const base::string16& text) { + DCHECK(!has_progress_); + summary_text_view_->SetText(text); + UpdateSummaryTextVisibility(); +} + void NotificationHeaderView::ClearProgress() { + summary_text_view_->SetText(base::string16()); has_progress_ = false; UpdateSummaryTextVisibility(); } @@ -296,15 +305,10 @@ if (count > 0) { summary_text_view_->SetText(l10n_util::GetStringFUTF16Int( IDS_MESSAGE_CENTER_LIST_NOTIFICATION_HEADER_OVERFLOW_INDICATOR, count)); - has_overflow_indicator_ = true; } else { - has_overflow_indicator_ = false; + summary_text_view_->SetText(base::string16()); } - UpdateSummaryTextVisibility(); -} -void NotificationHeaderView::ClearOverflowIndicator() { - has_overflow_indicator_ = false; UpdateSummaryTextVisibility(); } @@ -353,6 +357,8 @@ void NotificationHeaderView::SetAccentColor(SkColor color) { accent_color_ = color; app_name_view_->SetEnabledColor(accent_color_); + summary_text_view_->SetEnabledColor(accent_color_); + summary_text_divider_->SetEnabledColor(accent_color_); SetExpanded(is_expanded_); } @@ -381,7 +387,7 @@ } void NotificationHeaderView::UpdateSummaryTextVisibility() { - const bool visible = has_progress_ || has_overflow_indicator_; + const bool visible = !summary_text_view_->text().empty(); summary_text_divider_->SetVisible(visible); summary_text_view_->SetVisible(visible); timestamp_divider_->SetVisible(!has_progress_ && has_timestamp_);
diff --git a/ui/message_center/views/notification_header_view.h b/ui/message_center/views/notification_header_view.h index 7b607b6..adc254a 100644 --- a/ui/message_center/views/notification_header_view.h +++ b/ui/message_center/views/notification_header_view.h
@@ -28,8 +28,13 @@ void SetAppIcon(const gfx::ImageSkia& img); void SetAppName(const base::string16& name); void SetAppNameElideBehavior(gfx::ElideBehavior elide_behavior); + + // Progress, summary and overflow indicator are all the same UI element so are + // mutually exclusive. void SetProgress(int progress); + void SetSummaryText(const base::string16& text); void SetOverflowIndicator(int count); + void SetTimestamp(base::Time timestamp); void SetExpandButtonEnabled(bool enabled); void SetExpanded(bool expanded); @@ -41,7 +46,6 @@ void SetAccentColor(SkColor color); void ClearAppIcon(); void ClearProgress(); - void ClearOverflowIndicator(); void ClearTimestamp(); bool IsExpandButtonEnabled(); void SetSubpixelRenderingEnabled(bool enabled); @@ -56,6 +60,10 @@ SkColor accent_color_for_testing() { return accent_color_; } + const views::Label* summary_text_for_testing() const { + return summary_text_view_; + } + const base::string16& app_name_for_testing() const; const gfx::ImageSkia& app_icon_for_testing() const; @@ -76,7 +84,6 @@ bool settings_button_enabled_ = false; bool has_progress_ = false; - bool has_overflow_indicator_ = false; bool has_timestamp_ = false; bool is_expanded_ = false;
diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc index ebb9cb4..9ddc227 100644 --- a/ui/views/controls/slider.cc +++ b/ui/views/controls/slider.cc
@@ -51,9 +51,9 @@ // The radius of the thumb and the highlighted thumb of the slider, // respectively. -constexpr float kThumbRadius = 6.f; +constexpr float kThumbRadius = 4.f; constexpr float kThumbWidth = 2 * kThumbRadius; -constexpr float kThumbHighlightRadius = 10.f; +constexpr float kThumbHighlightRadius = 12.f; // Duration of the thumb highlight growing effect animation. constexpr int kSlideHighlightChangeDurationMs = 150; @@ -270,9 +270,10 @@ is_active_ ? kEmptySliderColor : SkColorSetA(kEmptySliderColor, kHighlightColorAlpha); - // Extra space used to hide slider ends behind the thumb when slider is - // disabled. - const int extra_padding = is_active_ ? 0 : kSliderPadding; + // Padding used to adjust space between slider ends and slider thumb. + // Value is negative when slider is active so that there is no separation + // between slider and thumb. + const int extra_padding = is_active_ ? -kSliderPadding : kSliderPadding; cc::PaintFlags slider_flags; slider_flags.setAntiAlias(true);