diff --git a/.gn b/.gn index 50a46403..b79cfb64 100644 --- a/.gn +++ b/.gn
@@ -511,8 +511,6 @@ "//third_party/objenesis/*", "//third_party/ocmock/*", "//third_party/openh264/*", - - # "//third_party/openmax_dl/*", # 1 error "//third_party/openvr/*", "//third_party/opus/*", "//third_party/ots/*",
diff --git a/BUILD.gn b/BUILD.gn index 6b43e6b..79d7364 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -66,6 +66,7 @@ ":gn_visibility", "//base:base_perftests", "//base:base_unittests", + "//base/util:base_util_unittests", "//chrome/installer", "//chrome/updater", "//net:net_unittests",
diff --git a/DEPS b/DEPS index f86b534a..4852a29 100644 --- a/DEPS +++ b/DEPS
@@ -133,11 +133,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': 'dbded16fadde7924ad23687ca13ad9134a60e7f8', + 'skia_revision': '4f6eb15178d80041c296a665749932b608573bf1', # 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': '71f4b565e3bac4f90f2fbcba860519a01d303018', + 'v8_revision': '382308145fae4cf8c95e95355c93bb0028b5d63e', # 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. @@ -149,15 +149,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '7a60e31e4a236c3c2296fbd9dea5538499b6ea47', + 'swiftshader_revision': '3e6f60b3096f71903f88cc53d1b7b65bb60d1d28', # 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': '94908c491899a1baf566826cc4faa253844b4e6a', - # 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. - 'openmax_dl_revision': '25492ab7195649acce190708e095692402593e2b', + 'pdfium_revision': '00714a05fb5d4766e9f460d9764191eda9706db9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -200,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': '580e942266666fd5cb2de90aa04d266f02fbf7bc', + 'catapult_revision': '2cf3aa8e54dbe385c6d1ba4e2b885801d1031bba', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -256,7 +252,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. - 'spv_tools_revision': '89fe836fe22c3e5c2a062ebeade012e2c2f0839b', + 'spv_tools_revision': 'f6d9a1784313a88d6b1a1ca680458264cce4c2bd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -276,7 +272,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. - 'quiche_revision': '87c39c1ba976f007fdcc8f2f4e02231c3217eb01', + 'quiche_revision': 'ff86db3f4a3d59250eeafbb9787fb52b70e6ac31', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -708,7 +704,7 @@ Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'), 'src/third_party/dav1d/libdav1d': - Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'f8cac8c56b3e8afec0e356b297c373a352746a1b', + Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + 'd400361524ce739db30d552a9e54809d812710c6', 'src/third_party/dawn': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'), @@ -806,7 +802,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '052c9073a10d0e622cd5aa2920fe38e1f1036c46', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '4b03532de07b8ae91b0c8a27e2ff15246981bf3d', 'condition': 'checkout_linux', }, @@ -1157,9 +1153,6 @@ 'src/third_party/openh264/src': Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '6f26bce0b1c4e8ce0e13332f7c0083788def5fdf', - 'src/third_party/openmax_dl': - Var('webrtc_git') + '/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), - 'src/third_party/openscreen/src': Var('chromium_git') + '/openscreen' + '@' + 'b1d095ba4f8f3ec1efd90dbd5cb0a37e5b4b21f7', @@ -1184,7 +1177,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '2e8d209fba4bd4cfcc66aaa0b243edafdff7a924', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '77f9a12a3f08f3228a4333371e919ad9fd88f213', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1396,7 +1389,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@cc1b74c2b7a7e1f7c81af629846808176e7a6019', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e932f4a7787d061c8b94d84b14d631314ddaa7f7', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 8df833e..efb805a 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -706,6 +706,9 @@ 'filepath': 'chrome/browser/resource_coordinator/'\ '|services/resource_coordinator/', }, + 'chrome_performance_manager': { + 'filepath': 'chrome/browser/performance_manager/', + }, 'chromecast': { 'filepath': 'chromecast/', }, @@ -728,7 +731,6 @@ }, 'chromeos_bluetooth': { 'filepath': 'ash/system/bluetooth/'\ - '|chrome/browser/ui/bluetooth/'\ '|chrome/browser/ui/webui/chromeos/bluetooth*'\ '|chrome/browser/resources/settings/bluetooth_page/'\ '|chrome/browser/resources/chromeos/bluetooth_pairing_dialog/'\ @@ -2163,6 +2165,7 @@ 'chrome_cleaner': ['joenotcharles+watch@google.com'], 'chrome_elf': ['caitkp+watch@chromium.org'], 'chrome_grc': ['chrome-grc-reviews@chromium.org'], + 'chrome_performance_manager': ['performance-manager-reviews@chromium.org'], 'chromecast': ['alokp+watch@chromium.org', 'halliwell+watch@chromium.org', 'lcwu+watch@chromium.org'], @@ -2175,6 +2178,10 @@ 'jlklein+watch-bluetooth@chromium.org'], 'chromeos_calculator': ['dharcourt@chromium.org'], 'chromeos_cellular': ['azeemarshad+watch-cellular@chromium.org', + 'benchan+watch-cellular@chromium.org', + 'ejcaruso+watch-cellular@chromium.org', + 'jhawkins+watch-cellular@chromium.org', + 'jlklein+watch-cellular@chromium.org', 'khorimoto+watch-cellular@chromium.org'], 'chromeos_device_policy': ['ljusten+watch@chromium.org'], 'chromeos_geolocation': ['alemate+watch@chromium.org'], @@ -2186,6 +2193,10 @@ 'rsorokin+watch@chromium.org', 'tbarzic+watch@chromium.org'], 'chromeos_net': ['azeemarshad+watch-network@chromium.org', + 'benchan+watch-network@chromium.org', + 'ejcaruso+watch-network@chromium.org', + 'jhawkins+watch-network@chromium.org', + 'jlklein+watch-network@chromium.org', 'khorimoto+watch-network@chromium.org', 'stevenjb+watch-network@chromium.org'], 'chromeos_power': ['derat+watch@chromium.org'],
diff --git a/android_webview/browser/gfx/deferred_gpu_command_service.cc b/android_webview/browser/gfx/deferred_gpu_command_service.cc index 2b0535e..f54642f 100644 --- a/android_webview/browser/gfx/deferred_gpu_command_service.cc +++ b/android_webview/browser/gfx/deferred_gpu_command_service.cc
@@ -163,6 +163,7 @@ nullptr, gl::GLSurfaceFormat(), shared_image_manager.get(), + nullptr, nullptr), sync_point_manager_(std::move(sync_point_manager)), mailbox_manager_(std::move(mailbox_manager)),
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index d84c702e..8633288 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -51,6 +51,7 @@ "public/cpp/multi_user_window_manager.h", "public/cpp/multi_user_window_manager_delegate.h", "public/cpp/multi_user_window_manager_observer.h", + "public/cpp/window_tree_host_lookup.h", "root_window_controller.h", "screenshot_delegate.h", "session/session_controller_impl.h", @@ -89,7 +90,6 @@ "wm/window_util.h", "wm/wm_event.h", "wm/workspace/workspace_window_resizer.h", - "ws/window_lookup.h", ] sources = [ "accelerators/accelerator_commands.cc", @@ -1044,6 +1044,7 @@ "wallpaper/wallpaper_window_state_manager.h", "window_factory.cc", "window_factory.h", + "window_tree_host_lookup.cc", "window_user_data.h", "wm/always_on_top_controller.cc", "wm/always_on_top_controller.h", @@ -1272,13 +1273,6 @@ "wm/workspace/workspace_window_resizer.cc", "wm/workspace_controller.cc", "wm/workspace_controller.h", - "ws/ash_gpu_interface_provider.cc", - "ws/ash_gpu_interface_provider.h", - "ws/window_lookup.cc", - "ws/window_service_delegate_impl.cc", - "ws/window_service_delegate_impl.h", - "ws/window_service_owner.cc", - "ws/window_service_owner.h", ] configs += [ "//build/config:precompiled_headers" ] @@ -1913,7 +1907,6 @@ deps = [ ":ash", - ":ash_service_resources", ":test_support", "//ash/app_list:test_support", "//ash/app_list/presenter", @@ -2027,8 +2020,6 @@ ] data_deps = [ - ":ash_service_resources", - ":ash_service", "//ash/resources:ash_test_resources_100_percent", "//services/viz", ] @@ -2279,67 +2270,3 @@ "//ash/resources:ash_test_resources_200_percent", ] } - -service_executable("ash_service") { - output_name = "ash" - - sources = [ - "main.cc", - ] - - deps = [ - ":ash", - ":ash_service_resources", - ":ash_service_resources_200", - "//services/service_manager/public/cpp", - ] - - data_deps = [ - ":ash_service_resources", - ":ash_service_resources_200", - ] -} - -# TODO: Load locale-specific strings. -# TODO: Avoid duplication between Mash and Chrome pak files: crbug.com/628715. -repack("ash_service_resources") { - output = "$root_out_dir/ash_service_resources.pak" - sources = [ - "$root_gen_dir/ash/components/resources/ash_components_resources_100_percent.pak", - "$root_gen_dir/ash/strings/ash_strings_en-US.pak", - "$root_gen_dir/chromeos/strings/chromeos_strings_en-US.pak", - "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_100_percent.pak", - "$root_gen_dir/ui/chromeos/strings/ui_chromeos_strings_en-US.pak", - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak", - ] - deps = [ - "//ash/components/resources", - "//ash/strings", - "//chromeos/strings", - "//ui/chromeos/resources", - "//ui/chromeos/strings", - "//ui/resources", - "//ui/strings", - "//ui/views/mus:resources", - "//ui/views/resources", - ] -} - -repack("ash_service_resources_200") { - output = "$root_out_dir/ash_service_resources_200.pak" - sources = [ - "$root_gen_dir/ash/components/resources/ash_components_resources_200_percent.pak", - "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_200_percent.pak", - "$root_gen_dir/ui/resources/ui_resources_200_percent.pak", - "$root_gen_dir/ui/views/resources/views_resources_200_percent.pak", - ] - deps = [ - "//ash/components/resources", - "//ui/chromeos/resources", - "//ui/resources", - "//ui/views/resources", - ] -}
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc index 7f7a2a3..26db6e8 100644 --- a/ash/accelerators/debug_commands.cc +++ b/ash/accelerators/debug_commands.cc
@@ -17,18 +17,13 @@ #include "ash/wm/window_properties.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" -#include "ash/ws/window_lookup.h" -#include "ash/ws/window_service_owner.h" #include "base/command_line.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/utf_string_conversions.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/ws/window_service.h" #include "ui/accessibility/ax_tree_id.h" #include "ui/accessibility/platform/aura_window_properties.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/base/ui_base_features.h" #include "ui/compositor/debug_utils.h" #include "ui/compositor/layer.h" #include "ui/display/manager/display_manager.h" @@ -36,7 +31,6 @@ #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_rep.h" #include "ui/views/debug_utils.h" -#include "ui/views/mus/mus_client.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/window_properties.h" @@ -52,16 +46,6 @@ layer, RootWindowController::ForWindow(root)->GetLastMouseLocationInRoot()); } - - if (!features::IsSingleProcessMash()) - return; - - for (aura::Window* mus_root : - views::MusClient::Get()->window_tree_client()->GetRoots()) { - ui::Layer* layer = mus_root->layer(); - if (layer) - ui::PrintLayerHierarchy(layer, gfx::Point()); - } } void HandlePrintViewHierarchy() { @@ -74,8 +58,7 @@ views::PrintViewHierarchy(widget->GetRootView()); } -void PrintWindowHierarchy(ws::WindowService* window_service, - const aura::Window* active_window, +void PrintWindowHierarchy(const aura::Window* active_window, const aura::Window* focused_window, aura::Window* window, int indent, @@ -87,8 +70,6 @@ const gfx::Vector2dF& subpixel_position_offset = window->layer()->subpixel_position_offset(); *out << indent_str; - if (window_service && ws::WindowService::IsProxyWindow(window)) - *out << " [proxy] id=" << window_service->GetIdForDebugging(window) << " "; *out << name << " (" << window << ")" << " type=" << window->type(); if (window->GetProperty(kWindowStateKey)) @@ -104,46 +85,23 @@ *out << " [snapped]"; if (!subpixel_position_offset.IsZero()) *out << " subpixel offset=" + subpixel_position_offset.ToString(); - if (features::IsSingleProcessMash()) { - aura::Window* proxy_window = - window_lookup::GetProxyWindowForClientWindow(window); - if (proxy_window) - *out << " id=" << window_service->GetIdForDebugging(proxy_window); - } std::string* tree_id = window->GetProperty(ui::kChildAXTreeID); if (tree_id) *out << " ax_tree_id=" << *tree_id; *out << '\n'; - for (aura::Window* child : window->children()) { - PrintWindowHierarchy(window_service, active_window, focused_window, child, - indent + 3, out); - } + for (aura::Window* child : window->children()) + PrintWindowHierarchy(active_window, focused_window, child, indent + 3, out); } void HandlePrintWindowHierarchy() { aura::Window* active_window = wm::GetActiveWindow(); aura::Window* focused_window = wm::GetFocusedWindow(); aura::Window::Windows roots = Shell::Get()->GetAllRootWindows(); - ws::WindowService* window_service = - Shell::Get()->window_service_owner()->window_service(); for (size_t i = 0; i < roots.size(); ++i) { std::ostringstream out; out << "RootWindow " << i << ":\n"; - PrintWindowHierarchy(window_service, active_window, focused_window, - roots[i], 0, &out); - // Error so logs can be collected from end-users. - LOG(ERROR) << out.str(); - } - - if (!features::IsSingleProcessMash()) - return; - - for (aura::Window* mus_root : - views::MusClient::Get()->window_tree_client()->GetRoots()) { - std::ostringstream out; - out << "WindowService Client RootWindow\n"; - PrintWindowHierarchy(nullptr, nullptr, nullptr, mus_root, 0, &out); + PrintWindowHierarchy(active_window, focused_window, roots[i], 0, &out); // Error so logs can be collected from end-users. LOG(ERROR) << out.str(); }
diff --git a/ash/accelerometer/accelerometer_reader.cc b/ash/accelerometer/accelerometer_reader.cc index 631598b..40e47a1 100644 --- a/ash/accelerometer/accelerometer_reader.cc +++ b/ash/accelerometer/accelerometer_reader.cc
@@ -660,19 +660,23 @@ } void AccelerometerReader::AddObserver(Observer* observer) { - accelerometer_file_reader_->AddObserver(observer); + if (accelerometer_file_reader_) + accelerometer_file_reader_->AddObserver(observer); } void AccelerometerReader::RemoveObserver(Observer* observer) { - accelerometer_file_reader_->RemoveObserver(observer); + if (accelerometer_file_reader_) + accelerometer_file_reader_->RemoveObserver(observer); } void AccelerometerReader::StartListenToTabletModeController() { - accelerometer_file_reader_->StartListenToTabletModeController(); + if (accelerometer_file_reader_) + accelerometer_file_reader_->StartListenToTabletModeController(); } void AccelerometerReader::StopListenToTabletModeController() { - accelerometer_file_reader_->StopListenToTabletModeController(); + if (accelerometer_file_reader_) + accelerometer_file_reader_->StopListenToTabletModeController(); } AccelerometerReader::AccelerometerReader() @@ -680,4 +684,11 @@ AccelerometerReader::~AccelerometerReader() = default; +void AccelerometerReader::DisableForTest() { + if (accelerometer_file_reader_) { + accelerometer_file_reader_->StopListenToTabletModeController(); + accelerometer_file_reader_.reset(); + } +} + } // namespace ash
diff --git a/ash/accelerometer/accelerometer_reader.h b/ash/accelerometer/accelerometer_reader.h index f869427..ab1b5b3 100644 --- a/ash/accelerometer/accelerometer_reader.h +++ b/ash/accelerometer/accelerometer_reader.h
@@ -54,6 +54,10 @@ void StartListenToTabletModeController(); void StopListenToTabletModeController(); + void DisableForTest(); + + bool is_disabled() const { return !accelerometer_file_reader_; } + protected: AccelerometerReader(); virtual ~AccelerometerReader();
diff --git a/ash/ash_service.cc b/ash/ash_service.cc index 7cfc034..28b368d0 100644 --- a/ash/ash_service.cc +++ b/ash/ash_service.cc
@@ -4,187 +4,18 @@ #include "ash/ash_service.h" -#include "ash/dbus/ash_dbus_helper.h" #include "ash/mojo_interface_factory.h" -#include "ash/network_connect_delegate_mus.h" -#include "ash/shell.h" -#include "ash/shell_delegate_mash.h" -#include "ash/shell_init_params.h" -#include "ash/ws/ash_gpu_interface_provider.h" -#include "ash/ws/window_service_owner.h" -#include "base/bind.h" -#include "base/feature_list.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/hammerd/hammerd_client.h" -#include "chromeos/dbus/initialize_dbus_client.h" -#include "chromeos/dbus/power/power_policy_controller.h" -#include "chromeos/dbus/shill/shill_clients.h" -#include "chromeos/dbus/system_clock/system_clock_client.h" -#include "chromeos/network/network_connect.h" -#include "chromeos/network/network_handler.h" -#include "chromeos/system/fake_statistics_provider.h" -#include "components/discardable_memory/service/discardable_shared_memory_manager.h" -#include "components/viz/common/frame_sinks/begin_frame_source.h" -#include "components/viz/common/switches.h" -#include "components/viz/host/host_frame_sink_manager.h" -#include "device/bluetooth/bluetooth_adapter_factory.h" -#include "device/bluetooth/dbus/bluez_dbus_manager.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/ws/gpu_host/gpu_host.h" -#include "services/ws/host_context_factory.h" -#include "services/ws/public/cpp/gpu/gpu.h" -#include "services/ws/public/cpp/input_devices/input_device_controller.h" -#include "services/ws/public/mojom/constants.mojom.h" -#include "services/ws/window_service.h" -#include "ui/aura/env.h" -#include "ui/aura/window_tree_host.h" -#include "ui/base/ui_base_features.h" -#include "ui/views/layout/layout_provider.h" -#include "ui/views/views_delegate.h" -#include "ui/wm/core/wm_state.h" namespace ash { -namespace { - -class AshViewsDelegate : public views::ViewsDelegate { - public: - AshViewsDelegate() = default; - ~AshViewsDelegate() override = default; - - private: - // views::ViewsDelegate: - void OnBeforeWidgetInit( - views::Widget::InitParams* params, - views::internal::NativeWidgetDelegate* delegate) override {} - - // TODO: this may need to create ChromeLayoutProvider. - // https://crbug.com/853989 . - views::LayoutProvider layout_provider_; - - DISALLOW_COPY_AND_ASSIGN(AshViewsDelegate); -}; - -} // namespace AshService::AshService(service_manager::mojom::ServiceRequest request) : service_binding_(this, std::move(request)) {} -AshService::~AshService() { - if (!::features::IsMultiProcessMash()) - return; - - // Shutdown part of GpuHost before deleting Shell. This is necessary to - // avoid a deadlock between the raster thread and main thread. GpuHost can't - // be deleted here as that causes other DCHECKs. - gpu_host_->Shutdown(); - - Shell::DeleteInstance(); - - statistics_provider_.reset(); - - chromeos::NetworkConnect::Shutdown(); - network_connect_delegate_.reset(); - chromeos::NetworkHandler::Shutdown(); - chromeos::PowerPolicyController::Shutdown(); - chromeos::CrasAudioHandler::Shutdown(); - - device::BluetoothAdapterFactory::Shutdown(); - bluez::BluezDBusManager::Shutdown(); - - chromeos::shill_clients::Shutdown(); - chromeos::SystemClockClient::Shutdown(); - chromeos::PowerManagerClient::Shutdown(); - chromeos::HammerdClient::Shutdown(); - chromeos::CrasAudioClient::Shutdown(); - - // |gpu_host_| must be completely destroyed before Env as GpuHost depends on - // Ozone, which Env owns. - gpu_host_.reset(); -} - -void AshService::InitForMash() { - wm_state_ = std::make_unique<::wm::WMState>(); - - discardable_shared_memory_manager_ = - std::make_unique<discardable_memory::DiscardableSharedMemoryManager>(); - - gpu_host_ = std::make_unique<ws::gpu_host::GpuHost>( - this, discardable_shared_memory_manager_.get()); - - host_frame_sink_manager_ = std::make_unique<viz::HostFrameSinkManager>(); - CreateFrameSinkManager(); - io_thread_ = std::make_unique<base::Thread>("IOThread"); - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); - thread_options.priority = base::ThreadPriority::NORMAL; - CHECK(io_thread_->StartWithOptions(thread_options)); - gpu_ = ws::Gpu::Create(service_binding_.GetConnector(), - ws::mojom::kServiceName, io_thread_->task_runner()); - - context_factory_ = std::make_unique<ws::HostContextFactory>( - gpu_.get(), host_frame_sink_manager_.get()); - - env_ = aura::Env::CreateInstanceToHostViz(service_binding_.GetConnector()); - - views_delegate_ = std::make_unique<AshViewsDelegate>(); - - // Must occur after mojo::ApplicationRunner has initialized AtExitManager, but - // before WindowManager::Init(). Tests might initialize their own instance. - ash_dbus_helper_ = AshDBusHelper::Create(); - InitializeDBusClients(); - - // TODO(jamescook): Refactor StatisticsProvider so we can get just the data - // we need in ash. Right now StatisticsProviderImpl launches the crossystem - // binary to get system data, which we don't want to do twice on startup. - statistics_provider_.reset( - new chromeos::system::ScopedFakeStatisticsProvider()); - statistics_provider_->SetMachineStatistic("initial_locale", "en-US"); - statistics_provider_->SetMachineStatistic("keyboard_layout", ""); - - ShellInitParams shell_init_params; - shell_init_params.delegate = std::make_unique<ShellDelegateMash>(); - shell_init_params.context_factory = context_factory_.get(); - shell_init_params.context_factory_private = - context_factory_->GetContextFactoryPrivate(); - shell_init_params.connector = service_binding_.GetConnector(); - shell_init_params.gpu_interface_provider = - std::make_unique<AshGpuInterfaceProvider>( - gpu_host_.get(), discardable_shared_memory_manager_.get()); - Shell::CreateInstance(std::move(shell_init_params)); - Shell::GetPrimaryRootWindow()->GetHost()->Show(); -} - -void AshService::InitializeDBusClients() { - dbus::Bus* bus = ash_dbus_helper_->bus(); - - chromeos::InitializeDBusClient<chromeos::CrasAudioClient>(bus); - chromeos::InitializeDBusClient<chromeos::HammerdClient>(bus); - chromeos::InitializeDBusClient<chromeos::PowerManagerClient>(bus); - chromeos::InitializeDBusClient<chromeos::SystemClockClient>(bus); - // TODO(ortuno): Eliminate BluezDBusManager code from Ash, crbug.com/830893. - chromeos::InitializeDBusClient<bluez::BluezDBusManager>(bus); - chromeos::shill_clients::Initialize(bus); - - // TODO(https://crbug.com/644336): Initialize real audio handler. - chromeos::CrasAudioHandler::InitializeForTesting(); - - chromeos::PowerPolicyController::Initialize( - chromeos::PowerManagerClient::Get()); - - // TODO(stevenjb): Eliminate NetworkHandler code from Ash, crbug.com/644355. - CHECK(!chromeos::NetworkHandler::IsInitialized()); - chromeos::NetworkHandler::Initialize(); - network_connect_delegate_ = std::make_unique<NetworkConnectDelegateMus>(); - chromeos::NetworkConnect::Initialize(network_connect_delegate_.get()); -} +AshService::~AshService() = default; void AshService::OnStart() { mojo_interface_factory::RegisterInterfaces( ®istry_, base::ThreadTaskRunnerHandle::Get()); - - if (::features::IsMultiProcessMash()) - InitForMash(); } void AshService::OnBindInterface( @@ -194,37 +25,4 @@ registry_.BindInterface(interface_name, std::move(handle)); } -void AshService::CreatePackagedServiceInstance( - const std::string& service_name, - mojo::PendingReceiver<service_manager::mojom::Service> receiver, - CreatePackagedServiceInstanceCallback callback) { - DCHECK_EQ(service_name, ws::mojom::kServiceName); - Shell::Get()->window_service_owner()->BindWindowService(std::move(receiver)); - if (::features::IsMultiProcessMash()) { - ws::WindowService* window_service = - Shell::Get()->window_service_owner()->window_service(); - input_device_controller_ = std::make_unique<ws::InputDeviceController>(); - input_device_controller_->AddInterface(window_service->registry()); - } - std::move(callback).Run(base::GetCurrentProcId()); -} - -void AshService::CreateFrameSinkManager() { - viz::mojom::FrameSinkManagerPtr frame_sink_manager; - viz::mojom::FrameSinkManagerRequest frame_sink_manager_request = - mojo::MakeRequest(&frame_sink_manager); - viz::mojom::FrameSinkManagerClientPtr frame_sink_manager_client; - viz::mojom::FrameSinkManagerClientRequest frame_sink_manager_client_request = - mojo::MakeRequest(&frame_sink_manager_client); - - gpu_host_->CreateFrameSinkManager(std::move(frame_sink_manager_request), - frame_sink_manager_client.PassInterface()); - - host_frame_sink_manager_->BindAndSetManager( - std::move(frame_sink_manager_client_request), nullptr /* task_runner */, - std::move(frame_sink_manager)); -} - -void AshService::OnGpuServiceInitialized() {} - } // namespace ash
diff --git a/ash/ash_service.h b/ash/ash_service.h index 97d4add..e65dd9d 100644 --- a/ash/ash_service.h +++ b/ash/ash_service.h
@@ -7,63 +7,17 @@ #include "ash/ash_export.h" #include "base/macros.h" -#include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/mojom/service.mojom.h" -#include "services/ws/gpu_host/gpu_host_delegate.h" -#include "services/ws/public/mojom/gpu.mojom.h" - -namespace aura { -class Env; -} // namespace aura - -namespace base { -class Thread; -} - -namespace chromeos { -namespace system { -class ScopedFakeStatisticsProvider; -} -} // namespace chromeos - -namespace discardable_memory { -class DiscardableSharedMemoryManager; -} - -namespace views { -class ViewsDelegate; -} - -namespace viz { -class HostFrameSinkManager; -} - -namespace wm { -class WMState; -} - -namespace ws { -class Gpu; -class HostContextFactory; -class InputDeviceController; -namespace gpu_host { -class GpuHost; -} // namespace gpu_host -} // namespace ws namespace ash { -class AshDBusHelper; -class NetworkConnectDelegateMus; - // Used to export Ash's mojo services, specifically the interfaces defined in // Ash's manifest.json. Also responsible for creating the // UI-Service/WindowService when ash runs out of process. -class ASH_EXPORT AshService : public service_manager::Service, - public ws::gpu_host::GpuHostDelegate { +class ASH_EXPORT AshService : public service_manager::Service { public: explicit AshService(service_manager::mojom::ServiceRequest request); ~AshService() override; @@ -73,52 +27,11 @@ void OnBindInterface(const service_manager::BindSourceInfo& remote_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle handle) override; - void CreatePackagedServiceInstance( - const std::string& service_name, - mojo::PendingReceiver<service_manager::mojom::Service> receiver, - CreatePackagedServiceInstanceCallback callback) override; private: - // Does initialization necessary when ash runs out of process. This is called - // once the service starts (from OnStart()). - void InitForMash(); - - void InitializeDBusClients(); - - void CreateFrameSinkManager(); - - // ui::ws::GpuHostDelegate: - void OnGpuServiceInitialized() override; - service_manager::ServiceBinding service_binding_; service_manager::BinderRegistry registry_; - std::unique_ptr<::wm::WMState> wm_state_; - - std::unique_ptr<discardable_memory::DiscardableSharedMemoryManager> - discardable_shared_memory_manager_; - - std::unique_ptr<ws::gpu_host::GpuHost> gpu_host_; - - std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_; - - // IO thread for GPU and discardable shared memory IPC. - std::unique_ptr<base::Thread> io_thread_; - std::unique_ptr<ws::Gpu> gpu_; - std::unique_ptr<ws::HostContextFactory> context_factory_; - - std::unique_ptr<aura::Env> env_; - - std::unique_ptr<views::ViewsDelegate> views_delegate_; - - std::unique_ptr<AshDBusHelper> ash_dbus_helper_; - - std::unique_ptr<NetworkConnectDelegateMus> network_connect_delegate_; - std::unique_ptr<chromeos::system::ScopedFakeStatisticsProvider> - statistics_provider_; - - std::unique_ptr<ws::InputDeviceController> input_device_controller_; - DISALLOW_COPY_AND_ASSIGN(AshService); };
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc index da34601..5142652 100644 --- a/ash/display/window_tree_host_manager.cc +++ b/ash/display/window_tree_host_manager.cc
@@ -25,13 +25,11 @@ #include "ash/system/status_area_widget.h" #include "ash/system/unified/unified_system_tray.h" #include "ash/wm/window_util.h" -#include "ash/ws/window_service_owner.h" #include "base/command_line.h" #include "base/metrics/histogram.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" -#include "services/ws/window_service.h" #include "ui/aura/client/capture_client.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/client/screen_position_client.h" @@ -126,14 +124,6 @@ return width >= 3000 ? "1024" : "512"; } -// Returns the Shell's WindowService instance or nullptr if Shell's -// |window_service_owner_| is not yet created. -ws::WindowService* GetWindowService() { - return Shell::Get()->window_service_owner() - ? Shell::Get()->window_service_owner()->window_service() - : nullptr; -} - } // namespace // A utility class to store/restore focused/active window @@ -552,8 +542,6 @@ GetRootWindowSettings(GetWindow(ash_host))->display_id = display.id(); for (auto& observer : observers_) observer.OnWindowTreeHostReusedForDisplay(ash_host, display); - if (auto* window_service = GetWindowService()) - window_service->OnWindowTreeHostsDisplayIdChanged({GetWindow(ash_host)}); const display::ManagedDisplayInfo& display_info = GetDisplayManager()->GetDisplayInfo(display.id()); ash_host->AsWindowTreeHost()->SetBoundsInPixels( @@ -621,10 +609,6 @@ for (auto& observer : observers_) observer.OnWindowTreeHostsSwappedDisplays(host_to_delete, primary_host); - if (auto* window_service = GetWindowService()) { - window_service->OnWindowTreeHostsDisplayIdChanged( - {GetWindow(host_to_delete), GetWindow(primary_host)}); - } OnDisplayMetricsChanged( GetDisplayManager()->GetDisplayForId(primary_display_id), @@ -642,12 +626,6 @@ void WindowTreeHostManager::OnDisplayMetricsChanged( const display::Display& display, uint32_t metrics) { - // Shell creates |window_service_owner_| from Shell::Init(), but this - // function may be called before |window_service_owner_| is created. It's safe - // to ignore the call in this case as no clients have connected yet. - if (auto* window_service = GetWindowService()) - window_service->OnDisplayMetricsChanged(display, metrics); - if (!(metrics & (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION | DISPLAY_METRIC_DEVICE_SCALE_FACTOR))) { return; @@ -765,10 +743,6 @@ for (auto& observer : observers_) observer.OnWindowTreeHostsSwappedDisplays(primary_host, non_primary_host); - if (auto* window_service = GetWindowService()) { - window_service->OnWindowTreeHostsDisplayIdChanged( - {primary_window, non_primary_window}); - } const display::DisplayLayout& layout = GetDisplayManager()->GetCurrentDisplayLayout();
diff --git a/ash/host/ash_window_tree_host.h b/ash/host/ash_window_tree_host.h index 96d28ba..7bb22aae 100644 --- a/ash/host/ash_window_tree_host.h +++ b/ash/host/ash_window_tree_host.h
@@ -8,7 +8,6 @@ #include <memory> #include "ash/ash_export.h" -#include "services/ws/public/mojom/ime/ime.mojom.h" #include "ui/display/display.h" namespace aura { @@ -63,11 +62,6 @@ display::Display::Rotation rotation) = 0; virtual void ClearCursorConfig() = 0; - // Updates IME of underlying PlatformWindow. - virtual void UpdateTextInputState(ui::mojom::TextInputStatePtr state) {} - virtual void UpdateImeVisibility(bool visible, - ui::mojom::TextInputStatePtr state) {} - protected: // Returns true if cursor confinement should be allowed. For development // builds this will return false, for ease of switching between windows,
diff --git a/ash/host/ash_window_tree_host_platform.cc b/ash/host/ash_window_tree_host_platform.cc index fb6924f8..7c917a3 100644 --- a/ash/host/ash_window_tree_host_platform.cc +++ b/ash/host/ash_window_tree_host_platform.cc
@@ -11,18 +11,12 @@ #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/window_factory.h" -#include "ash/ws/window_service_owner.h" #include "base/feature_list.h" #include "base/trace_event/trace_event.h" -#include "services/ws/event_queue.h" #include "services/ws/public/cpp/input_devices/input_device_controller_client.h" -#include "services/ws/public/mojom/window_manager.mojom.h" -#include "services/ws/window_service.h" -#include "ui/aura/mus/input_method_mus.h" #include "ui/aura/null_window_targeter.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host_platform.h" -#include "ui/base/ui_base_features.h" #include "ui/events/event_sink.h" #include "ui/events/null_event_targeter.h" #include "ui/events/ozone/chromeos/cursor_controller.h" @@ -37,20 +31,11 @@ #include "ui/platform_window/text_input_state.h" namespace ash { -namespace { - -// String passed to Compositor to identify who is submitting compositor frames. -// Used by telemetry. -const char* kTraceEnvironmentName = "ash"; - -} // namespace AshWindowTreeHostPlatform::AshWindowTreeHostPlatform( ui::PlatformWindowInitProperties properties) - : aura::WindowTreeHostPlatform( - std::move(properties), - window_factory::NewWindow(), - ::features::IsUsingWindowService() ? kTraceEnvironmentName : nullptr), + : aura::WindowTreeHostPlatform(std::move(properties), + window_factory::NewWindow()), transformer_helper_(this) { CommonInit(); } @@ -58,12 +43,10 @@ AshWindowTreeHostPlatform::AshWindowTreeHostPlatform() : aura::WindowTreeHostPlatform(window_factory::NewWindow()), transformer_helper_(this) { - CreateCompositor( - viz::FrameSinkId(), - /* force_software_compositor */ false, - /* external_begin_frame_client */ nullptr, - /* are_events_in_pixels */ true, - ::features::IsUsingWindowService() ? kTraceEnvironmentName : nullptr); + CreateCompositor(viz::FrameSinkId(), + /* force_software_compositor */ false, + /* external_begin_frame_client */ nullptr, + /* are_events_in_pixels */ true); CommonInit(); } @@ -114,17 +97,6 @@ GetAcceleratedWidget()); } -void AshWindowTreeHostPlatform::UpdateTextInputState( - ui::mojom::TextInputStatePtr state) { - SetTextInputState(std::move(state)); -} - -void AshWindowTreeHostPlatform::UpdateImeVisibility( - bool visible, - ui::mojom::TextInputStatePtr state) { - SetImeVisibility(visible, std::move(state)); -} - void AshWindowTreeHostPlatform::SetRootWindowTransformer( std::unique_ptr<RootWindowTransformer> transformer) { transformer_helper_.SetRootWindowTransformer(std::move(transformer)); @@ -183,16 +155,6 @@ void AshWindowTreeHostPlatform::CommonInit() { transformer_helper_.Init(); - - event_queue_ = - Shell::Get()->window_service_owner()->window_service()->event_queue(); - - if (!::features::IsMultiProcessMash()) - return; - - input_method_ = std::make_unique<aura::InputMethodMus>(this, this); - input_method_->Init(Shell::Get()->connector()); - SetSharedInputMethod(input_method_.get()); } void AshWindowTreeHostPlatform::SetTapToClickPaused(bool state) { @@ -205,13 +167,6 @@ input_device_controller_client->SetTapToClickPaused(state); } -bool AshWindowTreeHostPlatform::ShouldSendKeyEventToIme() { - // Don't send key events to IME if they are going to go to a remote client. - // Remote clients handle forwarding to IME (as necessary). - aura::Window* target = window()->targeter()->FindTargetForKeyEvent(window()); - return !target || !ws::WindowService::IsProxyWindow(target); -} - void AshWindowTreeHostPlatform::DispatchEvent(ui::Event* event) { TRACE_EVENT0("input", "AshWindowTreeHostPlatform::DispatchEvent"); if (event->IsLocatedEvent()) @@ -219,31 +174,4 @@ return aura::WindowTreeHostPlatform::DispatchEvent(event); } -ui::EventDispatchDetails AshWindowTreeHostPlatform::DeliverEventToSink( - ui::Event* event) { - // Queue the event if needed, or deliver it directly to the sink. - auto result = event_queue_->DeliverOrQueueEvent(this, event); - return result.value_or(ui::EventDispatchDetails()); -} - -void AshWindowTreeHostPlatform::SetTextInputState( - ui::mojom::TextInputStatePtr state) { - ui::PlatformImeController* ime = - platform_window()->GetPlatformImeController(); - if (ime) - ime->UpdateTextInputState(state.To<ui::TextInputState>()); -} - -void AshWindowTreeHostPlatform::SetImeVisibility( - bool visible, - ui::mojom::TextInputStatePtr state) { - if (!state.is_null()) - SetTextInputState(std::move(state)); - - ui::PlatformImeController* ime = - platform_window()->GetPlatformImeController(); - if (ime) - ime->SetImeVisibility(visible); -} - } // namespace ash
diff --git a/ash/host/ash_window_tree_host_platform.h b/ash/host/ash_window_tree_host_platform.h index 09476d63..0b8652b 100644 --- a/ash/host/ash_window_tree_host_platform.h +++ b/ash/host/ash_window_tree_host_platform.h
@@ -10,17 +10,8 @@ #include "ash/ash_export.h" #include "ash/host/ash_window_tree_host.h" #include "ash/host/transformer_helper.h" -#include "ui/aura/mus/input_method_mus_delegate.h" #include "ui/aura/window_tree_host_platform.h" -namespace aura { -class InputMethodMus; -} - -namespace ws { -class EventQueue; -} - namespace ui { struct PlatformWindowInitProperties; } @@ -30,8 +21,7 @@ class ASH_EXPORT AshWindowTreeHostPlatform : public AshWindowTreeHost, - public aura::WindowTreeHostPlatform, - public aura::InputMethodMusDelegate { + public aura::WindowTreeHostPlatform { public: explicit AshWindowTreeHostPlatform( ui::PlatformWindowInitProperties properties); @@ -57,9 +47,6 @@ void SetCursorConfig(const display::Display& display, display::Display::Rotation rotation) override; void ClearCursorConfig() override; - void UpdateTextInputState(ui::mojom::TextInputStatePtr state) override; - void UpdateImeVisibility(bool visible, - ui::mojom::TextInputStatePtr state) override; // aura::WindowTreeHostPlatform: void SetRootTransform(const gfx::Transform& transform) override; @@ -71,14 +58,7 @@ void SetBoundsInPixels(const gfx::Rect& bounds, const viz::LocalSurfaceIdAllocation& local_surface_id_allocation) override; - bool ShouldSendKeyEventToIme() override; void DispatchEvent(ui::Event* event) override; - ui::EventDispatchDetails DeliverEventToSink(ui::Event* event) override; - - // aura::InputMethodMusDelegate: - void SetTextInputState(ui::mojom::TextInputStatePtr state) override; - void SetImeVisibility(bool visible, - ui::mojom::TextInputStatePtr state) override; private: // All constructors call into this. @@ -91,15 +71,6 @@ gfx::Rect last_cursor_confine_bounds_in_pixels_; - // Use InputMethodMus as the InputMethod implementation. InputMethodMus ends - // up connection to the UI Service over mojo, which is in process, but - // simplifies things. In particular, even though the WindowService is in - // process, parts of ime live in it's own process, so by using InputMethodMus - // those connections are correctly established. - std::unique_ptr<aura::InputMethodMus> input_method_; - - ws::EventQueue* event_queue_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(AshWindowTreeHostPlatform); };
diff --git a/ash/lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc b/ash/lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc index c9431869..2879038 100644 --- a/ash/lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc +++ b/ash/lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc
@@ -80,9 +80,7 @@ .GetContentsView(); views::View* background = LockScreenActionBackgroundViewTestApi(contents_view).GetBackground(); - // The ink drop's layer is a sibling of the background's layer, so call this - // from the background's layer's parent. - background->layer()->parent()->CompleteAllAnimations(); + background->layer()->CompleteAllAnimations(); } views::Widget* GetBackgroundWidget() {
diff --git a/ash/media/media_notification_view.cc b/ash/media/media_notification_view.cc index 3b4507c..0923282 100644 --- a/ash/media/media_notification_view.cc +++ b/ash/media/media_notification_view.cc
@@ -116,57 +116,59 @@ control_buttons_view_->set_owned_by_client(); // |header_row_| contains app_icon, app_name, control buttons, etc. - header_row_ = new message_center::NotificationHeaderView(this); - header_row_->AddChildView(control_buttons_view_.get()); - header_row_->SetAppName( + auto header_row = + std::make_unique<message_center::NotificationHeaderView>(this); + header_row->AddChildView(control_buttons_view_.get()); + header_row->SetAppName( message_center::MessageCenter::Get()->GetSystemNotificationAppName()); - header_row_->ClearAppIcon(); - header_row_->SetProperty(views::kMarginsKey, - new gfx::Insets(kMediaNotificationHeaderTopInset, - kMediaNotificationHeaderInset, - kMediaNotificationHeaderInset, - kMediaNotificationHeaderRightInset)); - AddChildView(header_row_); + header_row->ClearAppIcon(); + header_row->SetProperty(views::kMarginsKey, + new gfx::Insets(kMediaNotificationHeaderTopInset, + kMediaNotificationHeaderInset, + kMediaNotificationHeaderInset, + kMediaNotificationHeaderRightInset)); + header_row_ = AddChildView(std::move(header_row)); // |main_row_| holds the main content of the notification. - main_row_ = new views::View(); - AddChildView(main_row_); + auto main_row = std::make_unique<views::View>(); + main_row_ = AddChildView(std::move(main_row)); // |title_artist_row_| contains the title and artist labels. - title_artist_row_ = new views::View(); + auto title_artist_row = std::make_unique<views::View>(); title_artist_row_layout_ = - title_artist_row_->SetLayoutManager(std::make_unique<views::BoxLayout>( + title_artist_row->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kVertical, kMediaTitleArtistInsets, 0)); title_artist_row_layout_->set_main_axis_alignment( views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER); title_artist_row_layout_->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); - main_row_->AddChildView(title_artist_row_); + title_artist_row_ = main_row_->AddChildView(std::move(title_artist_row)); - title_label_ = new views::Label(base::string16(), views::style::CONTEXT_LABEL, - views::style::STYLE_PRIMARY); + auto title_label = std::make_unique<views::Label>( + base::string16(), views::style::CONTEXT_LABEL, + views::style::STYLE_PRIMARY); const gfx::FontList& base_font_list = views::Label::GetDefaultFontList(); - title_label_->SetFontList(base_font_list.Derive( + title_label->SetFontList(base_font_list.Derive( 0, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::MEDIUM)); - title_label_->SetLineHeight(kTitleArtistLineHeight); - title_artist_row_->AddChildView(title_label_); + title_label->SetLineHeight(kTitleArtistLineHeight); + title_label_ = title_artist_row_->AddChildView(std::move(title_label)); - artist_label_ = - new views::Label(base::string16(), views::style::CONTEXT_LABEL, - views::style::STYLE_PRIMARY); - artist_label_->SetLineHeight(kTitleArtistLineHeight); - title_artist_row_->AddChildView(artist_label_); + auto artist_label = std::make_unique<views::Label>( + base::string16(), views::style::CONTEXT_LABEL, + views::style::STYLE_PRIMARY); + artist_label->SetLineHeight(kTitleArtistLineHeight); + artist_label_ = title_artist_row_->AddChildView(std::move(artist_label)); // |button_row_| contains the buttons for controlling playback. - button_row_ = new views::View(); + auto button_row = std::make_unique<views::View>(); auto* button_row_layout = - button_row_->SetLayoutManager(std::make_unique<views::BoxLayout>( + button_row->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kHorizontal, gfx::Insets(), kMediaButtonRowSeparator)); button_row_layout->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); - button_row_->SetPreferredSize(kMediaNotificationButtonRowSize); - main_row_->AddChildView(button_row_); + button_row->SetPreferredSize(kMediaNotificationButtonRowSize); + button_row_ = main_row_->AddChildView(std::move(button_row)); CreateMediaButton(MediaSessionAction::kPreviousTrack, l10n_util::GetStringUTF16( @@ -176,15 +178,15 @@ IDS_ASH_MEDIA_NOTIFICATION_ACTION_SEEK_BACKWARD)); // |play_pause_button_| toggles playback. - play_pause_button_ = views::CreateVectorToggleImageButton(this); - play_pause_button_->set_tag(static_cast<int>(MediaSessionAction::kPlay)); - play_pause_button_->SetPreferredSize(kMediaButtonSize); - play_pause_button_->SetFocusBehavior(views::View::FocusBehavior::ALWAYS); - play_pause_button_->SetTooltipText( + auto play_pause_button = views::CreateVectorToggleImageButton(this); + play_pause_button->set_tag(static_cast<int>(MediaSessionAction::kPlay)); + play_pause_button->SetPreferredSize(kMediaButtonSize); + play_pause_button->SetFocusBehavior(views::View::FocusBehavior::ALWAYS); + play_pause_button->SetTooltipText( l10n_util::GetStringUTF16(IDS_ASH_MEDIA_NOTIFICATION_ACTION_PLAY)); - play_pause_button_->SetToggledTooltipText( + play_pause_button->SetToggledTooltipText( l10n_util::GetStringUTF16(IDS_ASH_MEDIA_NOTIFICATION_ACTION_PAUSE)); - button_row_->AddChildView(play_pause_button_); + play_pause_button_ = button_row_->AddChildView(std::move(play_pause_button)); CreateMediaButton(MediaSessionAction::kSeekForward, l10n_util::GetStringUTF16(
diff --git a/ash/public/cpp/lock_screen_widget_factory.cc b/ash/public/cpp/lock_screen_widget_factory.cc index b8276c9e..14a4423 100644 --- a/ash/public/cpp/lock_screen_widget_factory.cc +++ b/ash/public/cpp/lock_screen_widget_factory.cc
@@ -4,11 +4,6 @@ #include "ash/public/cpp/lock_screen_widget_factory.h" -#include "ash/public/cpp/shell_window_ids.h" -#include "mojo/public/cpp/bindings/type_converter.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/window_manager.mojom.h" -#include "ui/aura/mus/property_converter.h" #include "ui/aura/window.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" @@ -49,11 +44,6 @@ params.show_state = ui::SHOW_STATE_FULLSCREEN; params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.parent = parent; - if (!parent) { - params.mus_properties[ws::mojom::WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int32_t>(ash::kShellWindowId_OverlayContainer)); - } widget->Init(params); widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); return widget;
diff --git a/ash/public/cpp/window_tree_host_lookup.h b/ash/public/cpp/window_tree_host_lookup.h new file mode 100644 index 0000000..7364c9a --- /dev/null +++ b/ash/public/cpp/window_tree_host_lookup.h
@@ -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. + +#ifndef ASH_PUBLIC_CPP_WINDOW_TREE_HOST_LOOKUP_H_ +#define ASH_PUBLIC_CPP_WINDOW_TREE_HOST_LOOKUP_H_ + +#include <stdint.h> + +#include "ash/ash_export.h" + +namespace aura { +class WindowTreeHost; +} + +namespace ash { + +// Returns the WindowTreeHost for a particular display id, null if there is +// no display for |display_id|. +ASH_EXPORT aura::WindowTreeHost* GetWindowTreeHostForDisplay( + int64_t display_id); + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_WINDOW_TREE_HOST_LOOKUP_H_
diff --git a/ash/shell.cc b/ash/shell.cc index f5ab3ec5..eaf0f6c 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -163,7 +163,6 @@ #include "ash/wm/window_util.h" #include "ash/wm/wm_shadow_controller_delegate.h" #include "ash/wm/workspace_controller.h" -#include "ash/ws/window_service_owner.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" @@ -185,8 +184,6 @@ #include "services/preferences/public/cpp/pref_service_factory.h" #include "services/preferences/public/mojom/preferences.mojom.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/ws/public/cpp/host/gpu_interface_provider.h" -#include "services/ws/window_service.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" #include "ui/aura/layout_manager.h" @@ -231,8 +228,6 @@ using aura::Window; using views::Widget; -bool g_is_browser_process_with_mash = false; - // A Corewm VisibilityController subclass that calls the Ash animation routine // so we can pick up our extended animations. See ash/wm/window_animations.h. class AshVisibilityController : public ::wm::VisibilityController { @@ -285,17 +280,12 @@ instance_->Init( init_params.context_factory, init_params.context_factory_private, std::move(init_params.initial_display_prefs), - std::move(init_params.gpu_interface_provider), std::move(init_params.keyboard_ui_factory), init_params.dbus_bus); return instance_; } // static Shell* Shell::Get() { - CHECK(!g_is_browser_process_with_mash) // Implies null |instance_|. - << "Ash is running in its own process so Shell::Get() will return null. " - "The browser process must use the mojo interfaces in //ash/public to " - "access ash. See ash/README.md for details."; CHECK(instance_); return instance_; } @@ -399,11 +389,6 @@ } // static -bool Shell::IsProxyWindow(aura::Window* window) { - return ws::WindowService::IsProxyWindow(window); -} - -// static void Shell::RegisterLocalStatePrefs(PrefRegistrySimple* registry, bool for_test) { PaletteTray::RegisterLocalStatePrefs(registry); @@ -624,11 +609,6 @@ observer.OnShelfAutoHideBehaviorChanged(root_window); } -// static -void Shell::SetIsBrowserProcessWithMash() { - g_is_browser_process_with_mash = true; -} - //////////////////////////////////////////////////////////////////////////////// // Shell, private: @@ -887,10 +867,6 @@ // Similarly for DockedMagnifierController. docked_magnifier_controller_ = nullptr; - // May own windows and other objects that have indirect hooks into - // WindowTreeHostManager. - window_service_owner_.reset(); - // Must be released before |focus_controller_|. ime_focus_handler_.reset(); @@ -973,7 +949,6 @@ ui::ContextFactory* context_factory, ui::ContextFactoryPrivate* context_factory_private, std::unique_ptr<base::Value> initial_display_prefs, - std::unique_ptr<ws::GpuInterfaceProvider> gpu_interface_provider, std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory, scoped_refptr<dbus::Bus> dbus_bus) { if (::features::IsSingleProcessMash()) { @@ -1093,10 +1068,6 @@ screen_position_controller_ = std::make_unique<ScreenPositionController>(); - // Must be before CreatePrimaryHost(). - window_service_owner_ = - std::make_unique<WindowServiceOwner>(std::move(gpu_interface_provider)); - window_tree_host_manager_->Start(); AshWindowTreeHostInitParams ash_init_params; window_tree_host_manager_->CreatePrimaryHost(ash_init_params);
diff --git a/ash/shell.h b/ash/shell.h index da5bafb9b..d9f3320 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -87,10 +87,6 @@ class WindowModalityController; } // namespace wm -namespace ws { -class GpuInterfaceProvider; -} - namespace ash { class AcceleratorControllerImpl; @@ -207,7 +203,6 @@ class VpnList; class WallpaperController; class WaylandServerController; -class WindowServiceOwner; class WindowCycleController; class WindowPositioner; class WindowTreeHostManager; @@ -280,11 +275,6 @@ // Returns true if a system-modal dialog window is currently open. static bool IsSystemModalWindowOpen(); - // Returns true if |window| is a proxy window. A proxy window is a window that - // was created by way of a WindowService client (e.g. the keyboard shortcut - // viewer app under classic ash, or a browser window under mash). - static bool IsProxyWindow(aura::Window* window); - // Registers all ash related local state prefs to the given |registry|. static void RegisterLocalStatePrefs(PrefRegistrySimple* registry, bool for_test); @@ -567,9 +557,6 @@ OverviewController* overview_controller() { return overview_controller_.get(); } - WindowServiceOwner* window_service_owner() { - return window_service_owner_.get(); - } WindowTreeHostManager* window_tree_host_manager() { return window_tree_host_manager_.get(); } @@ -641,9 +628,6 @@ // TODO(jamescook): Move to Shelf. void NotifyShelfAutoHideBehaviorChanged(aura::Window* root_window); - // Used to provide better error messages for Shell::Get() under mash. - static void SetIsBrowserProcessWithMash(); - private: FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, TestCursor); FRIEND_TEST_ALL_PREFIXES(WindowManagerTest, MouseEventCursors); @@ -662,7 +646,6 @@ void Init(ui::ContextFactory* context_factory, ui::ContextFactoryPrivate* context_factory_private, std::unique_ptr<base::Value> initial_display_prefs, - std::unique_ptr<ws::GpuInterfaceProvider> gpu_interface_provider, std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory, scoped_refptr<dbus::Bus> dbus_bus); @@ -792,7 +775,6 @@ std::unique_ptr<ui::UserActivityDetector> user_activity_detector_; std::unique_ptr<VideoDetector> video_detector_; std::unique_ptr<WaylandServerController> wayland_server_controller_; - std::unique_ptr<WindowServiceOwner> window_service_owner_; std::unique_ptr<WindowTreeHostManager> window_tree_host_manager_; std::unique_ptr<PersistentWindowController> persistent_window_controller_; std::unique_ptr<HighContrastController> high_contrast_controller_;
diff --git a/ash/shell/content/client/shell_browser_main_parts.cc b/ash/shell/content/client/shell_browser_main_parts.cc index 8610dbe..22e27152 100644 --- a/ash/shell/content/client/shell_browser_main_parts.cc +++ b/ash/shell/content/client/shell_browser_main_parts.cc
@@ -37,7 +37,6 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/context_factory.h" -#include "content/public/browser/gpu_interface_provider_factory.h" #include "content/public/common/content_switches.h" #include "content/public/common/service_manager_connection.h" #include "content/shell/browser/shell_browser_context.h" @@ -124,7 +123,6 @@ init_params.delegate = std::make_unique<ash::shell::ShellDelegateImpl>(); init_params.context_factory = content::GetContextFactory(); init_params.context_factory_private = content::GetContextFactoryPrivate(); - init_params.gpu_interface_provider = content::CreateGpuInterfaceProvider(); init_params.connector = connector; init_params.keyboard_ui_factory = std::make_unique<TestKeyboardUIFactory>(); ash::Shell::CreateInstance(std::move(init_params));
diff --git a/ash/shell/content/client/shell_content_browser_client.cc b/ash/shell/content/client/shell_content_browser_client.cc index 844e3eb0..8b4ce62 100644 --- a/ash/shell/content/client/shell_content_browser_client.cc +++ b/ash/shell/content/client/shell_content_browser_client.cc
@@ -7,7 +7,6 @@ #include <memory> #include <utility> -#include "ash/ash_service.h" #include "ash/public/cpp/manifest.h" #include "ash/public/cpp/test_manifest.h" #include "ash/public/cpp/window_properties.h" @@ -98,12 +97,5 @@ &base::ASCIIToUTF16, test_ime_driver::mojom::kServiceName); } -void ShellContentBrowserClient::HandleServiceRequest( - const std::string& service_name, - service_manager::mojom::ServiceRequest request) { - service_manager::Service::RunAsyncUntilTermination( - std::make_unique<AshService>(std::move(request))); -} - } // namespace shell } // namespace ash
diff --git a/ash/shell/content/client/shell_content_browser_client.h b/ash/shell/content/client/shell_content_browser_client.h index 54c934a..a924dce2 100644 --- a/ash/shell/content/client/shell_content_browser_client.h +++ b/ash/shell/content/client/shell_content_browser_client.h
@@ -35,9 +35,6 @@ base::Optional<service_manager::Manifest> GetServiceManifestOverlay( base::StringPiece name) override; void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; - void HandleServiceRequest( - const std::string& service_name, - service_manager::mojom::ServiceRequest request) override; private: ShellBrowserMainParts* shell_browser_main_parts_;
diff --git a/ash/shell/content/embedded_browser.cc b/ash/shell/content/embedded_browser.cc index a2af3c8..9127df26 100644 --- a/ash/shell/content/embedded_browser.cc +++ b/ash/shell/content/embedded_browser.cc
@@ -5,19 +5,15 @@ #include "ash/shell/content/embedded_browser.h" #include "ash/shell.h" -#include "ash/ws/window_service_owner.h" #include "base/bind_helpers.h" #include "base/optional.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "base/unguessable_token.h" #include "content/public/browser/web_contents.h" -#include "services/ws/remote_view_host/server_remote_view_host.h" #include "ui/base/ui_base_features.h" #include "ui/views/controls/label.h" #include "ui/views/controls/native/native_view_host.h" #include "ui/views/layout/fill_layout.h" -#include "ui/views/mus/remote_view/remote_view_provider.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" #include "url/gurl.h" @@ -33,21 +29,14 @@ // moved to ash process somehow and invoked over mojo. class HostWidget : public views::WidgetDelegateView { public: - // Creates HostWidget to host remote content represented by |token| for mash. - static void CreateFromToken(const base::UnguessableToken& token) { - // HostWidget deletes itself when underlying widget closes. - new HostWidget(nullptr, token); - } - // Creates HostWidget that hosts |native_window| directly for classic. static void CreateFromNativeWindow(gfx::NativeWindow native_window) { // HostWidget deletes itself when underlying widget closes. - new HostWidget(native_window, base::nullopt); + new HostWidget(native_window); } private: - HostWidget(gfx::NativeWindow native_window, - base::Optional<base::UnguessableToken> token) { + HostWidget(gfx::NativeWindow native_window) { // Note this does not work under multi process mash. DCHECK(!features::IsMultiProcessMash()); @@ -61,18 +50,10 @@ widget->Init(params); widget->Show(); - if (native_window) { - title_ = base::ASCIIToUTF16("Classic: Embed by NativeViewHost"); - auto* host = new views::NativeViewHost(); - AddChildView(host); - host->Attach(native_window); - } else { - title_ = base::ASCIIToUTF16("SPM: Embed by ServerRemoteViewHost"); - auto* host = new ws::ServerRemoteViewHost( - ash::Shell::Get()->window_service_owner()->window_service()); - AddChildView(host); - host->EmbedUsingToken(token.value(), 0, base::DoNothing()); - } + title_ = base::ASCIIToUTF16("Classic: Embed by NativeViewHost"); + auto* host = new views::NativeViewHost(); + AddChildView(host); + host->Attach(native_window); Layout(); } @@ -95,17 +76,7 @@ content::NavigationController::LoadURLParams(url)); contents_->GetNativeView()->Show(); - if (!features::IsUsingWindowService()) { - HostWidget::CreateFromNativeWindow(contents_->GetNativeView()); - return; - } - - remote_view_provider_ = - std::make_unique<views::RemoteViewProvider>(contents_->GetNativeView()); - remote_view_provider_->GetEmbedToken( - base::BindOnce([](const base::UnguessableToken& token) { - HostWidget::CreateFromToken(token); - })); + HostWidget::CreateFromNativeWindow(contents_->GetNativeView()); } EmbeddedBrowser::~EmbeddedBrowser() = default;
diff --git a/ash/shell/content/embedded_browser.h b/ash/shell/content/embedded_browser.h index da9b4cf..0ae66f9 100644 --- a/ash/shell/content/embedded_browser.h +++ b/ash/shell/content/embedded_browser.h
@@ -16,10 +16,6 @@ class WebContents; } // namespace content -namespace views { -class RemoteViewProvider; -} - namespace ash { namespace shell { @@ -37,7 +33,6 @@ void OnUnembed(); std::unique_ptr<content::WebContents> contents_; - std::unique_ptr<views::RemoteViewProvider> remote_view_provider_; DISALLOW_COPY_AND_ASSIGN(EmbeddedBrowser); };
diff --git a/ash/shell_init_params.cc b/ash/shell_init_params.cc index 12d462ff..e3263f0 100644 --- a/ash/shell_init_params.cc +++ b/ash/shell_init_params.cc
@@ -6,7 +6,6 @@ #include "ash/shell_delegate.h" #include "base/values.h" -#include "services/ws/public/cpp/host/gpu_interface_provider.h" #include "ui/keyboard/keyboard_ui_factory.h" namespace ash {
diff --git a/ash/shell_init_params.h b/ash/shell_init_params.h index 657a5b5a..b0128ce 100644 --- a/ash/shell_init_params.h +++ b/ash/shell_init_params.h
@@ -28,10 +28,6 @@ class ContextFactoryPrivate; } -namespace ws { -class GpuInterfaceProvider; -} - namespace ash { class ShellDelegate; @@ -48,10 +44,6 @@ // ShellObserver::OnLocalStatePrefServiceInitialized is called. std::unique_ptr<base::Value> initial_display_prefs; - // Allows gpu interfaces to be injected while avoiding direct content - // dependencies. - std::unique_ptr<ws::GpuInterfaceProvider> gpu_interface_provider; - // Connector used by Shell to establish connections. service_manager::Connector* connector = nullptr;
diff --git a/ash/shell_state.cc b/ash/shell_state.cc index 9200fab..54ef0c4 100644 --- a/ash/shell_state.cc +++ b/ash/shell_state.cc
@@ -8,8 +8,6 @@ #include <utility> #include "ash/shell.h" -#include "ash/ws/window_service_owner.h" -#include "services/ws/window_service.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -35,14 +33,6 @@ void ShellState::NotifyAllClients() { const int64_t display_id = GetDisplayIdForNewWindows(); display::Screen::GetScreen()->SetDisplayForNewWindows(display_id); - - // WindowService broadcasts the display id over mojo to all remote apps. - // TODO(jamescook): Move this into Shell when ShellState is removed. - WindowServiceOwner* ws_owner = Shell::Get()->window_service_owner(); - // |ws_owner| is null during shutdown and tests. |window_service()| is null - // during early startup. - if (ws_owner && ws_owner->window_service()) - ws_owner->window_service()->SetDisplayForNewWindows(display_id); } int64_t ShellState::GetDisplayIdForNewWindows() const {
diff --git a/ash/shell_test_api.cc b/ash/shell_test_api.cc index d3cbc40..aba234c 100644 --- a/ash/shell_test_api.cc +++ b/ash/shell_test_api.cc
@@ -8,6 +8,7 @@ #include <utility> #include "ash/accelerators/accelerator_commands.h" +#include "ash/accelerometer/accelerometer_reader.h" #include "ash/app_list/app_list_controller_impl.h" #include "ash/app_list/views/app_list_view.h" #include "ash/keyboard/ash_keyboard_controller.h" @@ -20,12 +21,9 @@ #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/workspace_controller.h" -#include "ash/ws/window_service_owner.h" #include "base/run_loop.h" #include "components/prefs/testing_pref_service.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/ws/window_service.h" -#include "services/ws/window_tree.h" #include "ui/aura/window_tree_host.h" #include "ui/compositor/compositor.h" #include "ui/compositor/compositor_observer.h" @@ -196,6 +194,7 @@ } void ShellTestApi::EnableTabletModeWindowManager(bool enable) { + AccelerometerReader::GetInstance()->DisableForTest(); shell_->tablet_mode_controller()->EnableTabletModeWindowManager(enable); }
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index e46d559..5d717d5 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -33,7 +33,6 @@ #include "ash/wm/top_level_window_factory.h" #include "ash/wm/window_positioner.h" #include "ash/wm/work_area_insets.h" -#include "ash/ws/window_service_owner.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" @@ -43,6 +42,7 @@ #include "mojo/public/cpp/bindings/map.h" #include "services/ws/public/cpp/input_devices/input_device_client.h" #include "services/ws/public/cpp/input_devices/input_device_client_test_api.h" +#include "services/ws/public/mojom/window_tree_constants.mojom.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/window_parenting_client.h" #include "ui/aura/env.h"
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index 07f1463..1bec61e 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc
@@ -41,7 +41,6 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "services/service_manager/public/cpp/bind_source_info.h" -#include "services/ws/public/cpp/host/gpu_interface_provider.h" #include "services/ws/public/mojom/constants.mojom.h" #include "services/ws/public/mojom/gpu.mojom.h" #include "ui/aura/env.h" @@ -53,7 +52,6 @@ #include "ui/base/ime/init/input_method_initializer.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/base/platform_window_defaults.h" -#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_switches_util.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/test/test_context_factories.h" @@ -68,41 +66,6 @@ namespace ash { -// An implementation of GpuInterfaceProvider that queues up requests for -// interfaces. The requests are never actually bound, but are kept alive to -// ensure the requestor doesn't detect a close and try to exit. -class TestGpuInterfaceProvider : public ws::GpuInterfaceProvider { - public: - TestGpuInterfaceProvider() = default; - ~TestGpuInterfaceProvider() override = default; - - // ws::GpuInterfaceProvider: - void RegisterGpuInterfaces( - service_manager::BinderRegistry* registry) override { - registry->AddInterface(base::BindRepeating( - &TestGpuInterfaceProvider::BindDiscardableSharedMemoryManager, - base::Unretained(this))); - registry->AddInterface(base::BindRepeating( - &TestGpuInterfaceProvider::BindGpuRequest, base::Unretained(this))); - } - void BindOzoneGpuInterface(const std::string& interface_name, - mojo::ScopedMessagePipeHandle handle) override {} - - private: - void BindDiscardableSharedMemoryManager( - discardable_memory::mojom::DiscardableSharedMemoryManagerRequest - request) { - request_handles_.push_back(request.PassMessagePipe()); - } - void BindGpuRequest(ws::mojom::GpuRequest request) { - request_handles_.push_back(request.PassMessagePipe()); - } - - std::vector<mojo::ScopedMessagePipeHandle> request_handles_; - - DISALLOW_COPY_AND_ASSIGN(TestGpuInterfaceProvider); -}; - AshTestHelper::AshTestHelper() : command_line_(std::make_unique<base::test::ScopedCommandLine>()) { ui::test::EnableTestConfigForPlatformWindows(); @@ -322,8 +285,6 @@ init_params.context_factory = context_factories_->GetContextFactory(); init_params.context_factory_private = context_factories_->GetContextFactoryPrivate(); - init_params.gpu_interface_provider = - std::make_unique<TestGpuInterfaceProvider>(); init_params.keyboard_ui_factory = std::make_unique<TestKeyboardUIFactory>(); Shell::CreateInstance(std::move(init_params)); }
diff --git a/ash/window_tree_host_lookup.cc b/ash/window_tree_host_lookup.cc new file mode 100644 index 0000000..f58e12f --- /dev/null +++ b/ash/window_tree_host_lookup.cc
@@ -0,0 +1,18 @@ +// 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 "ash/public/cpp/window_tree_host_lookup.h" + +#include "ash/root_window_controller.h" +#include "ash/shell.h" + +namespace ash { + +aura::WindowTreeHost* GetWindowTreeHostForDisplay(int64_t display_id) { + auto* root_window_controller = + Shell::GetRootWindowControllerWithDisplayId(display_id); + return root_window_controller ? root_window_controller->GetHost() : nullptr; +} + +} // namespace ash
diff --git a/ash/wm/non_client_frame_controller.cc b/ash/wm/non_client_frame_controller.cc index 9ac3311..e1ced8f 100644 --- a/ash/wm/non_client_frame_controller.cc +++ b/ash/wm/non_client_frame_controller.cc
@@ -19,7 +19,6 @@ #include "ash/wm/property_util.h" #include "ash/wm/window_properties.h" #include "ash/wm/window_util.h" -#include "ash/ws/window_service_owner.h" #include "base/macros.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" @@ -32,6 +31,7 @@ #include "ui/accessibility/ax_tree_id.h" #include "ui/accessibility/platform/aura_window_properties.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/property_utils.h" #include "ui/aura/mus/window_port_mus.h" #include "ui/aura/window.h"
diff --git a/ash/wm/overview/caption_container_view.cc b/ash/wm/overview/caption_container_view.cc index 694c27de..b2aeb6e 100644 --- a/ash/wm/overview/caption_container_view.cc +++ b/ash/wm/overview/caption_container_view.cc
@@ -4,6 +4,8 @@ #include "ash/wm/overview/caption_container_view.h" +#include <memory> + #include "ash/public/cpp/ash_features.h" #include "ash/wm/overview/rounded_rect_view.h" #include "ash/wm/window_preview_view.h"
diff --git a/ash/wm/overview/caption_container_view.h b/ash/wm/overview/caption_container_view.h index 7e8813128..671911a 100644 --- a/ash/wm/overview/caption_container_view.h +++ b/ash/wm/overview/caption_container_view.h
@@ -43,7 +43,7 @@ class EventDelegate { public: - // TODO: Maybe consolidate into just mouse and gesture events. + // TODO(sammiequon): Maybe consolidate into just mouse and gesture events. virtual void HandlePressEvent(const gfx::PointF& location_in_screen) = 0; virtual void HandleDragEvent(const gfx::PointF& location_in_screen) = 0; virtual void HandleReleaseEvent(const gfx::PointF& location_in_screen) = 0;
diff --git a/ash/wm/overview/cleanup_animation_observer.cc b/ash/wm/overview/cleanup_animation_observer.cc index 834b593..e5cb207 100644 --- a/ash/wm/overview/cleanup_animation_observer.cc +++ b/ash/wm/overview/cleanup_animation_observer.cc
@@ -4,6 +4,8 @@ #include "ash/wm/overview/cleanup_animation_observer.h" +#include <utility> + #include "ash/wm/overview/overview_delegate.h" #include "ui/aura/window.h" #include "ui/views/widget/widget.h"
diff --git a/ash/wm/overview/cleanup_animation_observer_unittest.cc b/ash/wm/overview/cleanup_animation_observer_unittest.cc index 9d38512..6e80b49 100644 --- a/ash/wm/overview/cleanup_animation_observer_unittest.cc +++ b/ash/wm/overview/cleanup_animation_observer_unittest.cc
@@ -4,6 +4,7 @@ #include "ash/wm/overview/cleanup_animation_observer.h" +#include <utility> #include <vector> #include "ash/test/ash_test_base.h"
diff --git a/ash/wm/overview/delayed_animation_observer_impl_unittest.cc b/ash/wm/overview/delayed_animation_observer_impl_unittest.cc index a842233..0ce1d2a8 100644 --- a/ash/wm/overview/delayed_animation_observer_impl_unittest.cc +++ b/ash/wm/overview/delayed_animation_observer_impl_unittest.cc
@@ -4,6 +4,8 @@ #include "ash/wm/overview/delayed_animation_observer_impl.h" +#include <memory> +#include <utility> #include <vector> #include "ash/test/ash_test_base.h"
diff --git a/ash/wm/overview/drop_target_view.cc b/ash/wm/overview/drop_target_view.cc index 8582287..bdc525df 100644 --- a/ash/wm/overview/drop_target_view.cc +++ b/ash/wm/overview/drop_target_view.cc
@@ -4,6 +4,8 @@ #include "ash/wm/overview/drop_target_view.h" +#include <algorithm> + #include "ash/public/cpp/ash_features.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/wm/overview/overview_constants.h"
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc index be2b2237..f22285b 100644 --- a/ash/wm/overview/overview_controller.cc +++ b/ash/wm/overview/overview_controller.cc
@@ -5,6 +5,7 @@ #include "ash/wm/overview/overview_controller.h" #include <algorithm> +#include <utility> #include "ash/app_list/app_list_controller_impl.h" #include "ash/public/cpp/window_properties.h"
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 14a248ff..0fd1915 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -431,7 +431,7 @@ int animate_count = 0; bool has_non_cover_animating = false; - OverviewAnimationType animation_types[rects.size()]; + std::vector<OverviewAnimationType> animation_types(rects.size()); for (size_t i = 0; i < window_list_.size(); ++i) { OverviewItem* window_item = window_list_[i].get();
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 3c89481..0beb98f 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -5,6 +5,7 @@ #include "ash/wm/overview/overview_item.h" #include <algorithm> +#include <utility> #include <vector> #include "ash/public/cpp/ash_features.h" @@ -462,7 +463,8 @@ // There is a bug where the first OverviewItem |window_| will always return // the identity, even though a transform has been visually applied. For this // case use the y location of the screen bounds. - // TODO: Investigate why this is happening and remove the if clause. + // TODO(sammiequon): Investigate why this is happening and remove the if + // clause. if (window->transform().IsIdentity() && (window == GetWindow() || ::wm::HasTransientAncestor(window, GetWindow()))) {
diff --git a/ash/wm/overview/overview_observer.h b/ash/wm/overview/overview_observer.h index d4408c3..3d5164ea 100644 --- a/ash/wm/overview/overview_observer.h +++ b/ash/wm/overview/overview_observer.h
@@ -38,4 +38,4 @@ } // namespace ash -#endif // ASH_WM_OVERVIEW_OVERVIEW_OBSERVER_H_ \ No newline at end of file +#endif // ASH_WM_OVERVIEW_OVERVIEW_OBSERVER_H_
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index e98d0bd0..6046d366 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -2,8 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/wm/overview/overview_session.h" + #include <algorithm> #include <memory> +#include <string> +#include <utility> #include <vector> #include "ash/accelerators/accelerator_controller_impl.h" @@ -30,7 +34,6 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_item.h" -#include "ash/wm/overview/overview_session.h" #include "ash/wm/overview/overview_utils.h" #include "ash/wm/overview/overview_window_drag_controller.h" #include "ash/wm/overview/rounded_label_widget.h"
diff --git a/ash/wm/overview/rounded_label_widget.cc b/ash/wm/overview/rounded_label_widget.cc index 9a50ce4..c73ea7a 100644 --- a/ash/wm/overview/rounded_label_widget.cc +++ b/ash/wm/overview/rounded_label_widget.cc
@@ -4,6 +4,8 @@ #include "ash/wm/overview/rounded_label_widget.h" +#include <memory> + #include "ash/public/cpp/ash_features.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ash/wm/overview/scoped_overview_animation_settings.cc b/ash/wm/overview/scoped_overview_animation_settings.cc index f8a96dd6..3ceed60 100644 --- a/ash/wm/overview/scoped_overview_animation_settings.cc +++ b/ash/wm/overview/scoped_overview_animation_settings.cc
@@ -75,7 +75,7 @@ case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW: case OVERVIEW_ANIMATION_SELECTION_WINDOW: return kOverviewSelectorTransition; - }; + } NOTREACHED(); return base::TimeDelta(); }
diff --git a/ash/wm/overview/scoped_overview_transform_window.cc b/ash/wm/overview/scoped_overview_transform_window.cc index b552448..3046553 100644 --- a/ash/wm/overview/scoped_overview_transform_window.cc +++ b/ash/wm/overview/scoped_overview_transform_window.cc
@@ -71,7 +71,7 @@ class ScopedOverviewTransformWindow::LayerCachingAndFilteringObserver : public ui::LayerObserver { public: - LayerCachingAndFilteringObserver(ui::Layer* layer) : layer_(layer) { + explicit LayerCachingAndFilteringObserver(ui::Layer* layer) : layer_(layer) { layer_->AddObserver(this); layer_->AddCacheRenderSurfaceRequest(); layer_->AddTrilinearFilteringRequest();
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index 34e30b8..fb128d0 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -670,6 +670,10 @@ base::Optional<chromeos::PowerManagerClient::SwitchStates> result) { if (!result.has_value()) return; + + if (AccelerometerReader::GetInstance()->is_disabled()) + return; + LidEventReceived(result->lid_state, base::TimeTicks::Now()); TabletModeEventReceived(result->tablet_mode, base::TimeTicks::Now()); }
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc index 225eb5e..57ecd7e 100644 --- a/ash/wm/window_util.cc +++ b/ash/wm/window_util.cc
@@ -22,8 +22,6 @@ #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" -#include "ash/ws/window_service_owner.h" -#include "services/ws/window_service.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/capture_client.h" #include "ui/aura/client/focus_client.h" @@ -65,14 +63,6 @@ return true; } -// Asks the remote client that owns |window| to close it. Returns true if there -// was a remote client for |window|, false otherwise. -bool AskRemoteClientToCloseWindow(aura::Window* window) { - ws::WindowService* window_service = - Shell::Get()->window_service_owner()->window_service(); - return window_service && window_service->RequestClose(window); -} - // This window targeter reserves space for the portion of the resize handles // that extend within a top level window. class InteriorResizeHandleTargeter : public aura::WindowTargeter { @@ -248,9 +238,6 @@ } void CloseWidgetForWindow(aura::Window* window) { - if (AskRemoteClientToCloseWindow(window)) - return; - views::Widget* widget = GetInternalWidgetForWindow(window); DCHECK(widget); widget->Close();
diff --git a/ash/ws/ash_gpu_interface_provider.cc b/ash/ws/ash_gpu_interface_provider.cc deleted file mode 100644 index 1de5ee7..0000000 --- a/ash/ws/ash_gpu_interface_provider.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/ws/ash_gpu_interface_provider.h" - -#include "base/bind.h" -#include "components/discardable_memory/service/discardable_shared_memory_manager.h" -#include "services/service_manager/public/cpp/bind_source_info.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/ws/gpu_host/gpu_host.h" -#include "ui/ozone/public/ozone_platform.h" - -namespace ash { - -AshGpuInterfaceProvider::AshGpuInterfaceProvider( - ws::gpu_host::GpuHost* gpu_host, - discardable_memory::DiscardableSharedMemoryManager* - discardable_shared_memory_manager) - : gpu_host_(gpu_host), - discardable_shared_memory_manager_(discardable_shared_memory_manager) { - DCHECK(gpu_host_); - DCHECK(discardable_shared_memory_manager_); -} - -AshGpuInterfaceProvider::~AshGpuInterfaceProvider() = default; - -void AshGpuInterfaceProvider::RegisterGpuInterfaces( - service_manager::BinderRegistry* registry) { - registry->AddInterface<ws::mojom::ArcGpu>(base::BindRepeating( - &AshGpuInterfaceProvider::BindArcGpuRequest, base::Unretained(this))); - registry->AddInterface(base::BindRepeating( - &AshGpuInterfaceProvider::BindDiscardableSharedMemoryManagerRequest, - base::Unretained(this))); - registry->AddInterface(base::BindRepeating( - &AshGpuInterfaceProvider::BindGpuRequest, base::Unretained(this))); -} - -void AshGpuInterfaceProvider::BindOzoneGpuInterface( - const std::string& interface_name, - mojo::ScopedMessagePipeHandle handle) { - gpu_host_->BindOzoneGpuInterface(interface_name, std::move(handle)); -} - -void AshGpuInterfaceProvider::BindArcGpuRequest( - ws::mojom::ArcGpuRequest request) { - gpu_host_->AddArcGpu(std::move(request)); -} - -void AshGpuInterfaceProvider::BindDiscardableSharedMemoryManagerRequest( - discardable_memory::mojom::DiscardableSharedMemoryManagerRequest request) { - discardable_shared_memory_manager_->Bind(std::move(request), - service_manager::BindSourceInfo()); -} - -void AshGpuInterfaceProvider::BindGpuRequest(ws::mojom::GpuRequest request) { - gpu_host_->Add(std::move(request)); -} - -} // namespace ash
diff --git a/ash/ws/ash_gpu_interface_provider.h b/ash/ws/ash_gpu_interface_provider.h deleted file mode 100644 index 2bb665a..0000000 --- a/ash/ws/ash_gpu_interface_provider.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_WS_ASH_GPU_INTERFACE_PROVIDER_H_ -#define ASH_WS_ASH_GPU_INTERFACE_PROVIDER_H_ - -#include "components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom.h" -#include "services/ws/public/cpp/host/gpu_interface_provider.h" -#include "services/ws/public/mojom/arc_gpu.mojom.h" -#include "services/ws/public/mojom/gpu.mojom.h" - -namespace discardable_memory { -class DiscardableSharedMemoryManager; -} - -namespace ws { -namespace gpu_host { -class GpuHost; -} -} // namespace ws - -namespace ash { - -// Implementation of GpuInterfaceProvider used when Ash runs out of process. -class AshGpuInterfaceProvider : public ws::GpuInterfaceProvider { - public: - AshGpuInterfaceProvider(ws::gpu_host::GpuHost* gpu_host, - discardable_memory::DiscardableSharedMemoryManager* - discardable_shared_memory_manager); - ~AshGpuInterfaceProvider() override; - - // ws::GpuInterfaceProvider: - void RegisterGpuInterfaces( - service_manager::BinderRegistry* registry) override; - void BindOzoneGpuInterface(const std::string& interface_name, - mojo::ScopedMessagePipeHandle handle) override; - - private: - void BindArcGpuRequest(ws::mojom::ArcGpuRequest request); - void BindDiscardableSharedMemoryManagerRequest( - discardable_memory::mojom::DiscardableSharedMemoryManagerRequest request); - void BindGpuRequest(ws::mojom::GpuRequest request); - - ws::gpu_host::GpuHost* gpu_host_; - discardable_memory::DiscardableSharedMemoryManager* - discardable_shared_memory_manager_; - - DISALLOW_COPY_AND_ASSIGN(AshGpuInterfaceProvider); -}; - -} // namespace ash - -#endif // ASH_WS_ASH_GPU_INTERFACE_PROVIDER_H_
diff --git a/ash/ws/window_lookup.cc b/ash/ws/window_lookup.cc deleted file mode 100644 index 53b81b4..0000000 --- a/ash/ws/window_lookup.cc +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/ws/window_lookup.h" - -#include "ash/shell.h" -#include "ash/ws/window_service_owner.h" -#include "services/ws/common/util.h" -#include "services/ws/window_service.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/window_port_mus.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/base/ui_base_features.h" -#include "ui/views/mus/mus_client.h" - -namespace ash { -namespace window_lookup { -namespace { - -ws::Id GetTransportId(aura::Window* window) { - return Shell::Get() - ->window_service_owner() - ->window_service() - ->GetCompleteTransportIdForWindow(window); -} - -} // namespace - -bool IsProxyWindow(aura::Window* window) { - return ws::WindowService::IsProxyWindow(window); -} - -aura::Window* GetProxyWindowForClientWindow(aura::Window* window) { - // This function only make sense in classic/single-process mash. - DCHECK(!features::IsMultiProcessMash()); - if (!aura::WindowMus::Get(window)) - return nullptr; - - DCHECK(views::MusClient::Exists()); - aura::WindowTreeClient* window_tree_client = - views::MusClient::Get()->window_tree_client(); - DCHECK(window_tree_client); - - aura::WindowPortMus* window_port_mus = aura::WindowPortMus::Get(window); - if (!window_tree_client->id().has_value()) - return nullptr; // The client doesn't know the id yet. - - const ws::ClientSpecificId client_id = *(window_tree_client->id()); - const ws::Id transport_id = ws::BuildTransportId( - client_id, - static_cast<ws::ClientSpecificId>(window_port_mus->server_id())); - return Shell::Get() - ->window_service_owner() - ->window_service() - ->GetWindowByClientId(transport_id); -} - -aura::Window* GetClientWindowForProxyWindow(aura::Window* window) { - // This function only make sense in classic/single-process mash. - DCHECK(!features::IsMultiProcessMash()); - DCHECK(IsProxyWindow(window)); - DCHECK(views::MusClient::Get()); - - const ws::Id window_id = GetTransportId(window); - if (window_id == ws::kInvalidTransportId) - return nullptr; - - aura::WindowTreeClient* window_tree_client = - views::MusClient::Get()->window_tree_client(); - - if (!window_tree_client->id().has_value()) - return nullptr; // The client doesn't know its id yet. - - const ws::ClientSpecificId client_id = *(window_tree_client->id()); - if (ws::ClientIdFromTransportId(window_id) != client_id) { - // |window| is a proxy window, the client is in another process. - return nullptr; - } - - // Clients use a client_id of 0 for all their windows. - aura::WindowMus* window_mus = window_tree_client->GetWindowByServerId( - ws::BuildTransportId(0, ws::ClientWindowIdFromTransportId(window_id))); - return window_mus ? window_mus->GetWindow() : nullptr; -} - -bool IsProxyWindowForOutOfProcess(aura::Window* window) { - if (!IsProxyWindow(window)) - return false; - - const ws::Id window_id = GetTransportId(window); - if (window_id == ws::kInvalidTransportId) - return false; - - aura::WindowTreeClient* window_tree_client = - views::MusClient::Get()->window_tree_client(); - - if (!window_tree_client->id().has_value()) - return false; // The client doesn't know its id yet. - - const ws::ClientSpecificId client_id = *(window_tree_client->id()); - return ws::ClientIdFromTransportId(window_id) != client_id; -} - -} // namespace window_lookup -} // namespace ash
diff --git a/ash/ws/window_lookup.h b/ash/ws/window_lookup.h deleted file mode 100644 index d806d10..0000000 --- a/ash/ws/window_lookup.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_WS_WINDOW_LOOKUP_H_ -#define ASH_WS_WINDOW_LOOKUP_H_ - -#include "ash/ash_export.h" -#include "services/ws/common/types.h" - -namespace aura { -class Window; -} - -// TODO: this file is only necessary for single-process mash and should be -// removed. -namespace ash { -namespace window_lookup { - -// Returns true if |window| is a proxy created by the WindowService to represent -// a window created by another client. -ASH_EXPORT bool IsProxyWindow(aura::Window* window); - -// Returns the proxy aura::Window that represents a window created with aura -// configured to use mus. -ASH_EXPORT aura::Window* GetProxyWindowForClientWindow(aura::Window* window); - -// Returns the client window for a proxy window. -ASH_EXPORT aura::Window* GetClientWindowForProxyWindow(aura::Window* window); - -// Returns true if |window| is a proxy for a window created by a client that -// is running in its own process (e.g. shortcut_viewer). -ASH_EXPORT bool IsProxyWindowForOutOfProcess(aura::Window* window); - -} // namespace window_lookup -} // namespace ash - -#endif // ASH_WS_WINDOW_LOOKUP_H_
diff --git a/ash/ws/window_service_delegate_impl.cc b/ash/ws/window_service_delegate_impl.cc deleted file mode 100644 index b6a9b12..0000000 --- a/ash/ws/window_service_delegate_impl.cc +++ /dev/null
@@ -1,253 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/ws/window_service_delegate_impl.h" - -#include "ash/accelerators/accelerator_controller_impl.h" -#include "ash/host/ash_window_tree_host.h" -#include "ash/ime/ime_engine_factory_registry.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ash/wm/container_finder.h" -#include "ash/wm/non_client_frame_controller.h" -#include "ash/wm/resize_shadow_controller.h" -#include "ash/wm/top_level_window_factory.h" -#include "ash/wm/toplevel_window_event_handler.h" -#include "ash/wm/window_finder.h" -#include "ash/wm/window_util.h" -#include "base/bind.h" -#include "mojo/public/cpp/bindings/map.h" -#include "services/ws/public/mojom/window_manager.mojom.h" -#include "services/ws/public/mojom/window_tree_constants.mojom.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/client/drag_drop_client.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/property_utils.h" -#include "ui/aura/window.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/base/hit_test.h" -#include "ui/events/system_input_injector.h" -#include "ui/ozone/public/ozone_platform.h" -#include "ui/views/widget/widget.h" -#include "ui/wm/core/compound_event_filter.h" -#include "ui/wm/core/coordinate_conversion.h" - -namespace ash { -namespace { - -// Function supplied to ToplevelWindowEventHandler::AttemptToStartDrag(). -// |end_closure| is the callback that was supplied to RunWindowMoveLoop(). -void OnMoveLoopCompleted(base::OnceCallback<void(bool success)> end_closure, - ToplevelWindowEventHandler::DragResult result) { - std::move(end_closure) - .Run(result == ToplevelWindowEventHandler::DragResult::SUCCESS); -} - -// Returns true if there is a drag and drop in progress. -bool InDragLoop(aura::Window* window) { - aura::client::DragDropClient* drag_drop_client = - aura::client::GetDragDropClient(window->GetRootWindow()); - return drag_drop_client && drag_drop_client->IsDragDropInProgress(); -} - -// Returns true if there is a window move loop in progress. -bool InWindowMoveLoop() { - return Shell::Get() - ->toplevel_window_event_handler() - ->is_drag_in_progress(); -} - -// Returns true if a window move loop can be started. -bool ShouldStartMoveLoop(aura::Window* window) { - // A window move can only be started when there is no in progress drag loop or - // window move loop. - return !InDragLoop(window) && !InWindowMoveLoop(); -} - -// Returns true if a drag loop can be started. -bool ShouldStartDragLoop(aura::Window* window) { - // A drag loop can only be started when there is no in progress drag loop or - // window move loop. - return !InDragLoop(window) && !InWindowMoveLoop(); -} - -} // namespace - -WindowServiceDelegateImpl::WindowServiceDelegateImpl() = default; - -WindowServiceDelegateImpl::~WindowServiceDelegateImpl() = default; - -std::unique_ptr<aura::Window> WindowServiceDelegateImpl::NewTopLevel( - ws::TopLevelProxyWindow* top_level_proxy_window, - aura::PropertyConverter* property_converter, - const base::flat_map<std::string, std::vector<uint8_t>>& properties) { - std::map<std::string, std::vector<uint8_t>> property_map = - mojo::FlatMapToMap(properties); - ws::mojom::WindowType window_type = - aura::GetWindowTypeFromProperties(property_map); - - auto* window = CreateAndParentTopLevelWindow( - top_level_proxy_window, window_type, property_converter, &property_map); - return base::WrapUnique<aura::Window>(window); -} - -void WindowServiceDelegateImpl::OnUnhandledKeyEvent( - const ui::KeyEvent& key_event) { - Shell::Get()->accelerator_controller()->Process(ui::Accelerator(key_event)); -} - -bool WindowServiceDelegateImpl::StoreAndSetCursor(aura::Window* window, - ui::Cursor cursor) { - auto* frame = NonClientFrameController::Get(window); - if (frame) - frame->StoreCursor(cursor); - - ash::Shell::Get()->env_filter()->SetCursorForWindow(window, cursor); - - return !!frame; -} - -void WindowServiceDelegateImpl::RunWindowMoveLoop( - aura::Window* window, - ws::mojom::MoveLoopSource source, - const gfx::Point& cursor, - int window_component, - DoneCallback callback) { - if (!ShouldStartMoveLoop(window)) { - std::move(callback).Run(false); - return; - } - - if (source == ws::mojom::MoveLoopSource::MOUSE) - window->SetCapture(); - - const ::wm::WindowMoveSource aura_source = - source == ws::mojom::MoveLoopSource::MOUSE - ? ::wm::WINDOW_MOVE_SOURCE_MOUSE - : ::wm::WINDOW_MOVE_SOURCE_TOUCH; - - gfx::Point location_in_parent = cursor; - ::wm::ConvertPointFromScreen(window->parent(), &location_in_parent); - - Shell::Get() - ->toplevel_window_event_handler() - ->AttemptToStartDrag( - window, location_in_parent, window_component, aura_source, - base::BindOnce(&OnMoveLoopCompleted, std::move(callback)), - /*update_gesture_target=*/false); -} - -void WindowServiceDelegateImpl::CancelWindowMoveLoop() { - Shell::Get() - ->toplevel_window_event_handler() - ->RevertDrag(); -} - -void WindowServiceDelegateImpl::RunDragLoop( - aura::Window* window, - const ui::OSExchangeData& data, - const gfx::Point& screen_location, - uint32_t drag_operation, - ui::DragDropTypes::DragEventSource source, - DragDropCompletedCallback callback) { - if (!ShouldStartDragLoop(window)) { - std::move(callback).Run(ui::DragDropTypes::DRAG_NONE); - return; - } - - aura::Window* const root_window = window->GetRootWindow(); - aura::client::DragDropClient* drag_drop_client = - aura::client::GetDragDropClient(root_window); - DCHECK(drag_drop_client); - - std::move(callback).Run(drag_drop_client->StartDragAndDrop( - data, root_window, window, screen_location, drag_operation, source)); -} - -void WindowServiceDelegateImpl::CancelDragLoop(aura::Window* window) { - if (!InDragLoop(window)) - return; - - aura::client::GetDragDropClient(window->GetRootWindow())->DragCancel(); -} - -void WindowServiceDelegateImpl::SetWindowResizeShadow(aura::Window* window, - int hit_test) { - ResizeShadowController* controller = Shell::Get()->resize_shadow_controller(); - if (hit_test == HTNOWHERE) - controller->HideShadow(window); - else - controller->ShowShadow(window, hit_test); -} - -void WindowServiceDelegateImpl::UpdateTextInputState( - aura::Window* window, - ui::mojom::TextInputStatePtr state) { - if (!wm::IsActiveWindow(window)) - return; - - RootWindowController::ForWindow(window)->ash_host()->UpdateTextInputState( - std::move(state)); -} - -void WindowServiceDelegateImpl::UpdateImeVisibility( - aura::Window* window, - bool visible, - ui::mojom::TextInputStatePtr state) { - if (!wm::IsActiveWindow(window)) - return; - - RootWindowController::ForWindow(window)->ash_host()->UpdateImeVisibility( - visible, std::move(state)); -} - -void WindowServiceDelegateImpl::SetModalType(aura::Window* window, - ui::ModalType type) { - const ui::ModalType old_type = window->GetProperty(aura::client::kModalKey); - if (old_type == type) - return; - - window->SetProperty(aura::client::kModalKey, type); - - // Reparent the window if it will become, or will no longer be, system modal. - if (type == ui::MODAL_TYPE_SYSTEM || old_type == ui::MODAL_TYPE_SYSTEM) { - aura::Window* const parent = - wm::GetDefaultParent(window, window->GetBoundsInScreen()); - if (parent != window->parent()) - parent->AddChild(window); - } -} - -ui::SystemInputInjector* WindowServiceDelegateImpl::GetSystemInputInjector() { - if (!system_input_injector_) { - system_input_injector_ = - ui::OzonePlatform::GetInstance()->CreateSystemInputInjector(); - } - return system_input_injector_.get(); -} - -ui::EventTarget* WindowServiceDelegateImpl::GetGlobalEventTarget() { - return Shell::Get(); -} - -aura::Window* WindowServiceDelegateImpl::GetRootWindowForDisplayId( - int64_t display_id) { - return Shell::Get()->GetRootWindowForDisplayId(display_id); -} - -aura::Window* WindowServiceDelegateImpl::GetTopmostWindowAtPoint( - const gfx::Point& location_in_screen, - const std::set<aura::Window*>& ignore, - aura::Window** real_topmost) { - return wm::GetTopmostWindowAtPoint(location_in_screen, ignore, real_topmost); -} - -void WindowServiceDelegateImpl::ConnectToImeEngine( - ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) { - Shell::Get()->ime_engine_factory_registry()->ConnectToImeEngine( - std::move(engine_request), std::move(client)); -} - -} // namespace ash
diff --git a/ash/ws/window_service_delegate_impl.h b/ash/ws/window_service_delegate_impl.h deleted file mode 100644 index 4adee68..0000000 --- a/ash/ws/window_service_delegate_impl.h +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_WS_WINDOW_SERVICE_DELEGATE_IMPL_H_ -#define ASH_WS_WINDOW_SERVICE_DELEGATE_IMPL_H_ - -#include <memory> - -#include "services/ws/window_service_delegate.h" - -namespace ash { - -class WindowServiceDelegateImpl : public ws::WindowServiceDelegate { - public: - WindowServiceDelegateImpl(); - ~WindowServiceDelegateImpl() override; - - // ws::WindowServiceDelegate: - std::unique_ptr<aura::Window> NewTopLevel( - ws::TopLevelProxyWindow* top_level_proxy_window, - aura::PropertyConverter* property_converter, - const base::flat_map<std::string, std::vector<uint8_t>>& properties) - override; - void OnUnhandledKeyEvent(const ui::KeyEvent& key_event) override; - bool StoreAndSetCursor(aura::Window* window, ui::Cursor cursor) override; - void RunWindowMoveLoop(aura::Window* window, - ws::mojom::MoveLoopSource source, - const gfx::Point& cursor, - int window_component, - DoneCallback callback) override; - void CancelWindowMoveLoop() override; - void RunDragLoop(aura::Window* window, - const ui::OSExchangeData& data, - const gfx::Point& screen_location, - uint32_t drag_operation, - ui::DragDropTypes::DragEventSource source, - DragDropCompletedCallback callback) override; - void CancelDragLoop(aura::Window* window) override; - void SetWindowResizeShadow(aura::Window* window, int hit_test) override; - void UpdateTextInputState(aura::Window* window, - ui::mojom::TextInputStatePtr state) override; - void UpdateImeVisibility(aura::Window* window, - bool visible, - ui::mojom::TextInputStatePtr state) override; - void SetModalType(aura::Window* window, ui::ModalType type) override; - ui::SystemInputInjector* GetSystemInputInjector() override; - ui::EventTarget* GetGlobalEventTarget() override; - aura::Window* GetRootWindowForDisplayId(int64_t display_id) override; - aura::Window* GetTopmostWindowAtPoint(const gfx::Point& location_in_screen, - const std::set<aura::Window*>& ignores, - aura::Window** real_topmost) override; - void ConnectToImeEngine(ime::mojom::ImeEngineRequest engine_request, - ime::mojom::ImeEngineClientPtr client) override; - - private: - std::unique_ptr<ui::SystemInputInjector> system_input_injector_; - - DISALLOW_COPY_AND_ASSIGN(WindowServiceDelegateImpl); -}; - -} // namespace ash - -#endif // ASH_WS_WINDOW_SERVICE_DELEGATE_IMPL_H_
diff --git a/ash/ws/window_service_owner.cc b/ash/ws/window_service_owner.cc deleted file mode 100644 index aca2496..0000000 --- a/ash/ws/window_service_owner.cc +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/ws/window_service_owner.h" - -#include <cstdint> - -#include "ash/public/cpp/window_properties.h" -#include "ash/shell.h" -#include "ash/wm/non_client_frame_controller.h" -#include "ash/ws/window_service_delegate_impl.h" -#include "base/bind_helpers.h" -#include "base/lazy_instance.h" -#include "base/unguessable_token.h" -#include "services/content/public/cpp/buildflags.h" -#include "services/ws/public/cpp/host/gpu_interface_provider.h" -#include "ui/base/ui_base_features.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" -#include "ui/wm/core/focus_controller.h" - -#if BUILDFLAG(ENABLE_REMOTE_NAVIGABLE_CONTENTS_VIEW) -#include "services/content/public/cpp/navigable_contents_view.h" -#include "services/ws/remote_view_host/server_remote_view_host.h" -#endif // BUILDFLAG(ENABLE_REMOTE_NAVIGABLE_CONTENTS_VIEW) - -namespace ash { - -#if BUILDFLAG(ENABLE_REMOTE_NAVIGABLE_CONTENTS_VIEW) - -namespace { - -class ServerRemoteContentViewManager - : public content::NavigableContentsView::RemoteViewManager { - public: - explicit ServerRemoteContentViewManager(ws::WindowService* window_service) - : window_service_(window_service) {} - ~ServerRemoteContentViewManager() override = default; - - // content::NavigableContentsView::RemoteViewManager: - std::unique_ptr<views::NativeViewHost> CreateRemoteViewHost() override { - return std::make_unique<ws::ServerRemoteViewHost>(window_service_); - } - - void EmbedUsingToken(views::NativeViewHost* view_host, - const base::UnguessableToken& token) override { - constexpr uint32_t kEmbedFlags = - ws::mojom::kEmbedFlagEmbedderControlsVisibility; - static_cast<ws::ServerRemoteViewHost*>(view_host)->EmbedUsingToken( - token, kEmbedFlags, base::DoNothing()); - } - - private: - ws::WindowService* const window_service_; - - DISALLOW_COPY_AND_ASSIGN(ServerRemoteContentViewManager); -}; - -} // namespace - -#endif // BUILDFLAG(ENABLE_REMOTE_NAVIGABLE_CONTENTS_VIEW) - -WindowServiceOwner::WindowServiceOwner( - std::unique_ptr<ws::GpuInterfaceProvider> gpu_interface_provider) - : window_service_delegate_(std::make_unique<WindowServiceDelegateImpl>()), - window_service_(window_service_delegate_.get(), - std::move(gpu_interface_provider), - Shell::Get()->focus_controller(), - !::features::IsMultiProcessMash(), - Shell::Get()->aura_env()) { - window_service_.SetFrameDecorationValues( - NonClientFrameController::GetPreferredClientAreaInsets(), - NonClientFrameController::GetMaxTitleBarButtonWidth()); - window_service_.SetDisplayForNewWindows( - display::Screen::GetScreen()->GetDisplayForNewWindows().id()); - RegisterWindowProperties(window_service_.property_converter()); - -#if BUILDFLAG(ENABLE_REMOTE_NAVIGABLE_CONTENTS_VIEW) - content::NavigableContentsView::SetRemoteViewManager( - std::make_unique<ServerRemoteContentViewManager>(&window_service_)); -#endif // BUILDFLAG(ENABLE_REMOTE_NAVIGABLE_CONTENTS_VIEW) -} - -WindowServiceOwner::~WindowServiceOwner() = default; - -void WindowServiceOwner::BindWindowService( - service_manager::mojom::ServiceRequest request) { - window_service_.BindServiceRequest(std::move(request)); -} - -} // namespace ash
diff --git a/ash/ws/window_service_owner.h b/ash/ws/window_service_owner.h deleted file mode 100644 index 3a66b38..0000000 --- a/ash/ws/window_service_owner.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_WS_WINDOW_SERVICE_OWNER_H_ -#define ASH_WS_WINDOW_SERVICE_OWNER_H_ - -#include <memory> - -#include "ash/ash_export.h" -#include "ash/shell_init_params.h" -#include "base/memory/scoped_refptr.h" -#include "services/service_manager/public/mojom/service.mojom.h" -#include "services/ws/window_service.h" - -namespace ws { -class GpuInterfaceProvider; -} // namespace ws - -namespace ash { - -class WindowServiceDelegateImpl; - -// WindowServiceOwner indirectly owns the WindowService. This class is -// responsible for responding to the ServiceRequest for the WindowService. When -// BindWindowService() is called the WindowService is created. -class ASH_EXPORT WindowServiceOwner { - public: - explicit WindowServiceOwner( - std::unique_ptr<ws::GpuInterfaceProvider> gpu_interface_provider); - ~WindowServiceOwner(); - - // Called from the ServiceManager when a request is made for the - // WindowService. - void BindWindowService(service_manager::mojom::ServiceRequest request); - - ws::WindowService* window_service() { return &window_service_; } - - private: - friend class AshTestHelper; - - std::unique_ptr<WindowServiceDelegateImpl> window_service_delegate_; - ws::WindowService window_service_; - - DISALLOW_COPY_AND_ASSIGN(WindowServiceOwner); -}; - -} // namespace ash - -#endif // ASH_WS_WINDOW_SERVICE_OWNER_H_
diff --git a/base/BUILD.gn b/base/BUILD.gn index 74cf7da..0b03c11 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -752,13 +752,8 @@ "task/lazy_task_runner.h", "task/post_task.cc", "task/post_task.h", - "task/promise/abstract_promise.cc", - "task/promise/abstract_promise.h", "task/promise/dependent_list.cc", "task/promise/dependent_list.h", - "task/promise/no_op_promise_executor.cc", - "task/promise/no_op_promise_executor.h", - "task/promise/small_unique_object.h", "task/scoped_set_task_priority_for_current_thread.cc", "task/scoped_set_task_priority_for_current_thread.h", "task/sequence_manager/associated_thread_id.cc", @@ -2612,7 +2607,6 @@ "task/common/task_annotator_unittest.cc", "task/lazy_task_runner_unittest.cc", "task/post_task_unittest.cc", - "task/promise/abstract_promise_unittest.cc", "task/promise/dependent_list_unittest.cc", "task/scoped_set_task_priority_for_current_thread_unittest.cc", "task/sequence_manager/atomic_flag_set_unittest.cc",
diff --git a/base/android/bundle_utils.cc b/base/android/bundle_utils.cc index 759494b5..68a326f 100644 --- a/base/android/bundle_utils.cc +++ b/base/android/bundle_utils.cc
@@ -1,31 +1,101 @@ -// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// 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/android/bundle_utils.h" +#include <android/dlext.h> #include <dlfcn.h> #include "base/android/jni_android.h" #include "base/android/jni_string.h" +#include "base/files/file_path.h" +#include "base/logging.h" #include "jni/BundleUtils_jni.h" +// These symbols are added by the lld linker when creating a partitioned shared +// library. The symbols live in the base library, and are used to properly load +// the other partitions (feature libraries) when needed. +struct PartitionIndexEntry { + int32_t name_relptr; + int32_t addr_relptr; + uint32_t size; +}; +static_assert(sizeof(PartitionIndexEntry) == 12U, + "Unexpected PartitionIndexEntry size"); + +// Marked as weak_import because these symbols are lld-specific. The method that +// uses them will only be invoked in builds that have lld-generated partitions. +extern PartitionIndexEntry __part_index_begin[] __attribute__((weak_import)); +extern PartitionIndexEntry __part_index_end[] __attribute__((weak_import)); + +extern "C" { +// Marked as weak_import because this symbol is either supplied by the system +// (on Android N+), or by Crazy Linker (Android M and prior). +extern void* android_dlopen_ext(const char* __filename, + int __flags, + const android_dlextinfo* __info) + __attribute__((weak_import)); +} // extern "C" + namespace base { namespace android { +namespace { + +const void* ReadRelPtr(const int32_t* relptr) { + return reinterpret_cast<const char*>(relptr) + *relptr; +} + +std::string ResolveLibraryPath(const std::string& library_name) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jstring> java_path = Java_BundleUtils_getNativeLibraryPath( + env, base::android::ConvertUTF8ToJavaString(env, library_name)); + DCHECK(java_path); + return base::android::ConvertJavaStringToUTF8(env, java_path); +} + +} // namespace + // static bool BundleUtils::IsBundle() { return Java_BundleUtils_isBundle(base::android::AttachCurrentThread()); } // static -void* BundleUtils::DlOpenModuleLibrary(const std::string& libary_name) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> java_path = Java_BundleUtils_getNativeLibraryPath( - env, base::android::ConvertUTF8ToJavaString(env, libary_name)); - std::string library_path = - base::android::ConvertJavaStringToUTF8(env, java_path); - return dlopen(library_path.c_str(), RTLD_LOCAL | RTLD_NOW); +void* BundleUtils::DlOpenModuleLibrary(const std::string& library_name) { + std::string library_path = ResolveLibraryPath(library_name); + return dlopen(library_path.c_str(), RTLD_LOCAL); +} + +// static +void* BundleUtils::DlOpenModuleLibraryPartition( + const std::string& library_name) { + std::string library_path = ResolveLibraryPath(library_name); + std::string partition = base::FilePath(library_path).BaseName().value(); + + // Linear search is required here because the partition descriptors are not + // ordered. If a large number of partitions come into existence, lld could be + // modified to sort the partitions. + DCHECK(__part_index_begin != nullptr); + DCHECK(__part_index_end != nullptr); + for (const PartitionIndexEntry* part = __part_index_begin; + part != __part_index_end; ++part) { + std::string name( + reinterpret_cast<const char*>(ReadRelPtr(&part->name_relptr))); + if (name == partition) { + android_dlextinfo info = {}; + info.flags = ANDROID_DLEXT_RESERVED_ADDRESS; + info.reserved_addr = const_cast<void*>(ReadRelPtr(&part->addr_relptr)); + info.reserved_size = part->size; + + DCHECK(android_dlopen_ext != nullptr); + return android_dlopen_ext(library_path.c_str(), RTLD_LOCAL, &info); + } + } + + NOTREACHED(); + return nullptr; } } // namespace android
diff --git a/base/android/bundle_utils.h b/base/android/bundle_utils.h index e28c137..806e79f6 100644 --- a/base/android/bundle_utils.h +++ b/base/android/bundle_utils.h
@@ -1,4 +1,4 @@ -// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// 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. @@ -18,8 +18,14 @@ // Returns true if the current build is a bundle. static bool IsBundle(); - // dlopen variant that works for native libraries in dynamic feature modules. + // dlopen wrapper that works for native libraries in dynamic feature modules. static void* DlOpenModuleLibrary(const std::string& libary_name); + + // dlopen wrapper that works for partitioned native libraries in dynamic + // feature modules. This routine looks up the partition's address space in a + // table of main library symbols, and uses it when loading the feature + // library. + static void* DlOpenModuleLibraryPartition(const std::string& library_name); }; } // namespace android
diff --git a/base/containers/any_internal.h b/base/containers/any_internal.h index d4c16624..d42ad567 100644 --- a/base/containers/any_internal.h +++ b/base/containers/any_internal.h
@@ -85,8 +85,8 @@ }; struct alignas(sizeof(void*)) InlineAlloc { - // Holds a T if small. Tweaked to hold a promise executor inline. - char bytes[sizeof(void*) * 3]; + // Holds a T if small. + char bytes[sizeof(void*)]; template <typename T> T& value_as() {
diff --git a/base/containers/any_internal_unittest.cc b/base/containers/any_internal_unittest.cc index 5afb279..2b237f7 100644 --- a/base/containers/any_internal_unittest.cc +++ b/base/containers/any_internal_unittest.cc
@@ -13,8 +13,6 @@ struct OutOfLineStruct { void* one; void* two; - void* three; - void* four; }; } // namespace @@ -28,7 +26,7 @@ "std::unique_ptr<int> should be stored inline"); static_assert( !AnyInternal::InlineStorageHelper<OutOfLineStruct>::kUseInlineStorage, - "A struct with four pointers should be stored out of line"); + "A struct with two pointers should be stored out of line"); } } // namespace internal
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h index 6a5b75c..16e9785 100644 --- a/base/process/process_metrics.h +++ b/base/process/process_metrics.h
@@ -96,7 +96,6 @@ // Resident Set Size is a Linux/Android specific memory concept. Do not // attempt to extend this to other platforms. BASE_EXPORT size_t GetResidentSetSize() const; - BASE_EXPORT size_t GetPeakResidentSetSize() const; #endif #if defined(OS_CHROMEOS)
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc index c66c772c..0c119bd 100644 --- a/base/process/process_metrics_linux.cc +++ b/base/process/process_metrics_linux.cc
@@ -198,10 +198,6 @@ getpagesize(); } -size_t ProcessMetrics::GetPeakResidentSetSize() const { - return ReadProcStatusAndGetFieldAsSizeT(process_, "VmHWM") * 1024; -} - TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return internal::ClockTicksToTimeDelta(GetProcessCPU(process_)); }
diff --git a/base/task/promise/abstract_promise.cc b/base/task/promise/abstract_promise.cc deleted file mode 100644 index 46b53c8c..0000000 --- a/base/task/promise/abstract_promise.cc +++ /dev/null
@@ -1,510 +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 "base/task/promise/abstract_promise.h" -#include "base/bind.h" -#include "base/lazy_instance.h" -#include "base/sequenced_task_runner.h" -#include "base/threading/sequenced_task_runner_handle.h" - -namespace base { -namespace internal { - -AbstractPromise::~AbstractPromise() { -#if DCHECK_IS_ON() - CheckedAutoLock lock(GetCheckedLock()); - - DCHECK(!must_catch_ancestor_that_could_reject_ || - passed_catch_responsibility_) - << "Promise chain ending at " << from_here_.ToString() - << " didn't have a catch for potentially rejecting promise here " - << must_catch_ancestor_that_could_reject_->from_here().ToString(); - - DCHECK(!this_must_catch_ || passed_catch_responsibility_) - << "Potentially rejecting promise at " << from_here_.ToString() - << " doesn't have a catch ."; -#endif -} - -bool AbstractPromise::IsCanceled() const { - if (dependents_.IsCanceled()) - return true; - - const Executor* executor = GetExecutor(); - return executor && executor->IsCancelled(); -} - -const AbstractPromise* AbstractPromise::FindNonCurriedAncestor() const { - const AbstractPromise* promise = this; - while (promise->IsResolvedWithPromise()) { - promise = - unique_any_cast<scoped_refptr<AbstractPromise>>(promise->value_).get(); - } - return promise; -} - -void AbstractPromise::AddAsDependentForAllPrerequisites() { - DCHECK(prerequisites_); - - for (AdjacencyListNode& node : prerequisites_->prerequisite_list) { - node.dependent_node.dependent = this; - - // If |node.prerequisite| was canceled then early out because - // |prerequisites_->prerequisite_list| will have been cleared. - if (!node.prerequisite->InsertDependentOnAnyThread(&node.dependent_node)) - break; - } -} - -bool AbstractPromise::InsertDependentOnAnyThread(DependentList::Node* node) { - scoped_refptr<AbstractPromise>& dependent = node->dependent; - -#if DCHECK_IS_ON() - { - CheckedAutoLock lock(GetCheckedLock()); - node->dependent->MaybeInheritChecks(this); - } -#endif - - // If |dependents_| has been consumed (i.e. this promise has been resolved - // or rejected) then |node| may be ready to run now. - switch (dependents_.Insert(node)) { - case DependentList::InsertResult::SUCCESS: - break; - - case DependentList::InsertResult::FAIL_PROMISE_RESOLVED: - dependent->OnPrerequisiteResolved(); - break; - - case DependentList::InsertResult::FAIL_PROMISE_REJECTED: - dependent->OnPrerequisiteRejected(); - break; - - case DependentList::InsertResult::FAIL_PROMISE_CANCELED: - return dependent->OnPrerequisiteCancelled(); - } - - return true; -} - -#if DCHECK_IS_ON() - -// static -CheckedLock& AbstractPromise::GetCheckedLock() { - static base::NoDestructor<CheckedLock> instance; - return *instance; -} - -void AbstractPromise::DoubleMoveDetector::CheckForDoubleMoveErrors( - const base::Location& new_dependent_location, - Executor::ArgumentPassingType new_dependent_executor_type) { - switch (new_dependent_executor_type) { - case Executor::ArgumentPassingType::kNoCallback: - return; - - case Executor::ArgumentPassingType::kNormal: - DCHECK(!dependent_move_only_promise_) - << "Can't mix move only and non-move only " << callback_type_ - << "callback arguments for the same " << callback_type_ - << " prerequisite. See " << new_dependent_location.ToString() - << " and " << dependent_move_only_promise_->ToString() - << " with common ancestor " << from_here_.ToString(); - dependent_normal_promise_ = - std::make_unique<Location>(new_dependent_location); - return; - - case Executor::ArgumentPassingType::kMove: - DCHECK(!dependent_move_only_promise_) - << "Can't have multiple move only " << callback_type_ - << " callbacks for same " << callback_type_ << " prerequisite. See " - << new_dependent_location.ToString() << " and " - << dependent_move_only_promise_->ToString() << " with common " - << callback_type_ << " prerequisite " << from_here_.ToString(); - DCHECK(!dependent_normal_promise_) - << "Can't mix move only and non-move only " << callback_type_ - << " callback arguments for the same " << callback_type_ - << " prerequisite. See " << new_dependent_location.ToString() - << " and " << dependent_normal_promise_->ToString() << " with common " - << callback_type_ << " prerequisite " << from_here_.ToString(); - dependent_move_only_promise_ = - std::make_unique<Location>(new_dependent_location); - return; - } -} - -void AbstractPromise::MaybeInheritChecks(AbstractPromise* prerequisite) { - if (!ancestor_that_could_resolve_) { - // Inherit |prerequisite|'s resolve ancestor if it doesn't have a resolve - // callback. - if (prerequisite->resolve_argument_passing_type_ == - Executor::ArgumentPassingType::kNoCallback) { - ancestor_that_could_resolve_ = prerequisite->ancestor_that_could_resolve_; - } - - // If |prerequisite| didn't have a resolve callback (but it's reject - // callback could resolve) or if - // |prerequisite->ancestor_that_could_resolve_| is null then assign - // |prerequisite->this_resolve_|. - if (!ancestor_that_could_resolve_ && prerequisite->executor_can_resolve_) - ancestor_that_could_resolve_ = prerequisite->this_resolve_; - } - - if (!ancestor_that_could_reject_) { - // Inherit |prerequisite|'s reject ancestor if it doesn't have a Catch. - if (prerequisite->reject_argument_passing_type_ == - Executor::ArgumentPassingType::kNoCallback) { - ancestor_that_could_reject_ = prerequisite->ancestor_that_could_reject_; - } - - // If |prerequisite| didn't have a reject callback (but it's resolve - // callback could reject) or if - // |prerequisite->ancestor_that_could_resolve_| is null then assign - // |prerequisite->this_reject_|. - if (!ancestor_that_could_reject_ && prerequisite->executor_can_reject_) - ancestor_that_could_reject_ = prerequisite->this_reject_; - } - - if (!must_catch_ancestor_that_could_reject_) { - // Inherit |prerequisite|'s must catch ancestor if it doesn't have a Catch. - if (prerequisite->reject_argument_passing_type_ == - Executor::ArgumentPassingType::kNoCallback) { - must_catch_ancestor_that_could_reject_ = - prerequisite->must_catch_ancestor_that_could_reject_; - } - - // If |prerequisite| didn't have a reject callback (but it's resolve - // callback could reject) or if - // |prerequisite->must_catch_ancestor_that_could_reject_| is null then - // assign |prerequisite->this_must_catch_|. - if (!must_catch_ancestor_that_could_reject_ && - prerequisite->executor_can_reject_) { - must_catch_ancestor_that_could_reject_ = prerequisite->this_must_catch_; - } - } - - if (ancestor_that_could_resolve_) { - ancestor_that_could_resolve_->CheckForDoubleMoveErrors( - from_here_, resolve_argument_passing_type_); - } - - if (ancestor_that_could_reject_) { - ancestor_that_could_reject_->CheckForDoubleMoveErrors( - from_here_, reject_argument_passing_type_); - } - - prerequisite->passed_catch_responsibility_ = true; -} - -void AbstractPromise::PassCatchResponsibilityOntoDependentsForCurriedPromise( - DependentList::Node* dependent_list) { - CheckedAutoLock lock(GetCheckedLock()); - if (!dependent_list) - return; - - if (IsResolvedWithPromise()) { - for (DependentList::Node* node = dependent_list; node; - node = node->next.load(std::memory_order_relaxed)) { - node->dependent->MaybeInheritChecks(this); - } - } -} - -AbstractPromise::LocationRef::LocationRef(const Location& from_here) - : from_here_(from_here) {} - -AbstractPromise::LocationRef::~LocationRef() = default; - -AbstractPromise::DoubleMoveDetector::DoubleMoveDetector( - const Location& from_here, - const char* callback_type) - : from_here_(from_here), callback_type_(callback_type) {} - -AbstractPromise::DoubleMoveDetector::~DoubleMoveDetector() = default; - -#endif - -const AbstractPromise::Executor* AbstractPromise::GetExecutor() const { - const SmallUniqueObject<Executor>* executor = - base::unique_any_cast<SmallUniqueObject<Executor>>(&value_); - if (!executor) - return nullptr; - return executor->get(); -} - -AbstractPromise::Executor::PrerequisitePolicy -AbstractPromise::GetPrerequisitePolicy() { - Executor* executor = GetExecutor(); - if (!executor) { - // If there's no executor it's because the promise has already run. We - // can't run again however. The only circumstance in which we expect - // GetPrerequisitePolicy() to be called after execution is when it was - // resolved with a promise. - DCHECK(IsResolvedWithPromise()); - return Executor::PrerequisitePolicy::kNever; - } - return executor->GetPrerequisitePolicy(); -} - -void AbstractPromise::Execute() { - if (IsCanceled()) - return; - -#if DCHECK_IS_ON() - // Clear |must_catch_ancestor_that_could_reject_| if we can catch it. - if (reject_argument_passing_type_ != - Executor::ArgumentPassingType::kNoCallback) { - CheckedAutoLock lock(GetCheckedLock()); - must_catch_ancestor_that_could_reject_ = nullptr; - } -#endif - - if (IsResolvedWithPromise()) { - bool settled = DispatchIfNonCurriedRootSettled(); - DCHECK(settled); - - prerequisites_->prerequisite_list.clear(); - return; - } - - DCHECK(GetExecutor()) << from_here_.ToString() << " value_ contains " - << value_.type(); - - // This is likely to delete the executor. - GetExecutor()->Execute(this); - - // We need to release any AdjacencyListNodes we own to prevent memory leaks - // due to refcount cycles. - if (prerequisites_ && !IsResolvedWithPromise()) - prerequisites_->prerequisite_list.clear(); -} - -bool AbstractPromise::DispatchIfNonCurriedRootSettled() { - const AbstractPromise* curried_root = FindNonCurriedAncestor(); - if (!curried_root->IsSettled()) - return false; - - if (curried_root->IsResolved()) { - OnResolvePostReadyDependents(); - } else if (curried_root->IsRejected()) { - OnRejectPostReadyDependents(); - } else { - DCHECK(curried_root->IsCanceled()); - OnPrerequisiteCancelled(); - } - return true; -} - -void AbstractPromise::OnPrerequisiteResolved() { - if (IsResolvedWithPromise()) { - bool settled = DispatchIfNonCurriedRootSettled(); - DCHECK(settled); - return; - } - - switch (GetPrerequisitePolicy()) { - case Executor::PrerequisitePolicy::kAll: - if (prerequisites_->DecrementPrerequisiteCountAndCheckIfZero()) - task_runner_->PostPromiseInternal(this, TimeDelta()); - break; - - case Executor::PrerequisitePolicy::kAny: - // PrerequisitePolicy::kAny should resolve immediately. - task_runner_->PostPromiseInternal(this, TimeDelta()); - break; - - case Executor::PrerequisitePolicy::kNever: - break; - } -} - -void AbstractPromise::OnPrerequisiteRejected() { - task_runner_->PostPromiseInternal(this, TimeDelta()); -} - -bool AbstractPromise::OnPrerequisiteCancelled() { - switch (GetPrerequisitePolicy()) { - case Executor::PrerequisitePolicy::kAll: - // PrerequisitePolicy::kAll should cancel immediately. - OnCanceled(); - return false; - - case Executor::PrerequisitePolicy::kAny: - // PrerequisitePolicy::kAny should only cancel if all if it's - // pre-requisites have been canceled. - if (prerequisites_->DecrementPrerequisiteCountAndCheckIfZero()) { - OnCanceled(); - return false; - } - return true; - - case Executor::PrerequisitePolicy::kNever: - // If we we where resolved with a promise then we can't have had - // PrerequisitePolicy::kAny or PrerequisitePolicy::kNever before the - // executor was replaced with the curried promise, so pass on - // cancellation. - if (IsResolvedWithPromise()) - OnCanceled(); - return false; - } -} - -void AbstractPromise::OnResolvePostReadyDependents() { - DependentList::Node* dependent_list = dependents_.ConsumeOnceForResolve(); - dependent_list = NonThreadSafeReverseList(dependent_list); - -#if DCHECK_IS_ON() - PassCatchResponsibilityOntoDependentsForCurriedPromise(dependent_list); -#endif - - // Propagate resolve to dependents. - for (DependentList::Node* node = dependent_list; node; - node = node->next.load(std::memory_order_relaxed)) { - // We want to release |node->dependent| but we need to do so before - // we post a task to execute |dependent| on what might be another thread. - scoped_refptr<AbstractPromise> dependent = std::move(node->dependent); - dependent->OnPrerequisiteResolved(); - } -} - -void AbstractPromise::OnRejectPostReadyDependents() { - DependentList::Node* dependent_list = dependents_.ConsumeOnceForReject(); - dependent_list = NonThreadSafeReverseList(dependent_list); - -#if DCHECK_IS_ON() - PassCatchResponsibilityOntoDependentsForCurriedPromise(dependent_list); -#endif - - // Propagate rejection to dependents. We always propagate rejection - // immediately. - for (DependentList::Node* node = dependent_list; node; - node = node->next.load(std::memory_order_relaxed)) { - // We want to release |node->dependent| but we need to do so before - // we post a task to execute |dependent| on what might be another thread. - scoped_refptr<AbstractPromise> dependent = std::move(node->dependent); - dependent->OnPrerequisiteRejected(); - } -} - -void AbstractPromise::OnCanceled() { - if (dependents_.IsCanceled() || dependents_.IsResolved() || - dependents_.IsRejected()) { - return; - } - -#if DCHECK_IS_ON() - { - CheckedAutoLock lock(GetCheckedLock()); - passed_catch_responsibility_ = true; - } -#endif - - DependentList::Node* dependent_list = dependents_.ConsumeOnceForCancel(); - - // Release all pre-requisites to prevent memory leaks - if (prerequisites_) { - for (AdjacencyListNode& node : prerequisites_->prerequisite_list) { - node.prerequisite = nullptr; - } - } - - // Propagate cancellation to dependents. - while (dependent_list) { - scoped_refptr<AbstractPromise> dependent = - std::move(dependent_list->dependent); - dependent->OnPrerequisiteCancelled(); - dependent_list = dependent_list->next.load(std::memory_order_relaxed); - } -} - -void AbstractPromise::OnResolved() { -#if DCHECK_IS_ON() - DCHECK(executor_can_resolve_) << from_here_.ToString(); -#endif - if (IsResolvedWithPromise()) { - scoped_refptr<AbstractPromise> curried_promise = - unique_any_cast<scoped_refptr<AbstractPromise>>(value_); - - // This only happens for PostTasks that returned a promise. - if (!task_runner_) - task_runner_ = SequencedTaskRunnerHandle::Get(); - - if (!curried_promise->prerequisites_) - curried_promise->prerequisites_ = std::make_unique<AdjacencyList>(); - - // Throw away any existing dependencies and make |curried_promise| the - // only dependency of this promise. -#if DCHECK_IS_ON() - { - CheckedAutoLock lock(GetCheckedLock()); - ancestor_that_could_resolve_ = nullptr; - ancestor_that_could_reject_ = nullptr; - } -#endif - prerequisites_->ResetWithSingleDependency(curried_promise); - AddAsDependentForAllPrerequisites(); - } else { - OnResolvePostReadyDependents(); - } -} - -void AbstractPromise::OnRejected() { -#if DCHECK_IS_ON() - DCHECK(executor_can_reject_) << from_here_.ToString(); -#endif - OnRejectPostReadyDependents(); -} - -// static -DependentList::Node* AbstractPromise::NonThreadSafeReverseList( - DependentList::Node* list) { - DependentList::Node* prev = nullptr; - while (list) { - DependentList::Node* next = list->next.load(std::memory_order_relaxed); - list->next.store(prev, std::memory_order_relaxed); - prev = list; - list = next; - } - return prev; -} - -AbstractPromise::AdjacencyListNode::AdjacencyListNode() = default; - -AbstractPromise::AdjacencyListNode::AdjacencyListNode( - scoped_refptr<AbstractPromise> promise) - : prerequisite(std::move(promise)) {} - -AbstractPromise::AdjacencyListNode::~AdjacencyListNode() = default; - -AbstractPromise::AdjacencyListNode::AdjacencyListNode( - AdjacencyListNode&& other) noexcept = default; - -AbstractPromise::AdjacencyList::AdjacencyList() = default; - -AbstractPromise::AdjacencyList::AdjacencyList( - scoped_refptr<AbstractPromise> prerequisite) - : prerequisite_list(1), action_prerequisite_count(1) { - prerequisite_list[0].prerequisite = std::move(prerequisite); -} - -AbstractPromise::AdjacencyList::AdjacencyList( - std::vector<AdjacencyListNode> nodes) - : prerequisite_list(std::move(nodes)), - action_prerequisite_count(prerequisite_list.size()) {} - -AbstractPromise::AdjacencyList::~AdjacencyList() = default; - -bool AbstractPromise::AdjacencyList:: - DecrementPrerequisiteCountAndCheckIfZero() { - return action_prerequisite_count.fetch_sub(1, std::memory_order_acq_rel) == 1; -} - -void AbstractPromise::AdjacencyList::ResetWithSingleDependency( - scoped_refptr<AbstractPromise> prerequisite) { - prerequisite_list.clear(); - prerequisite_list.push_back(AdjacencyListNode{std::move(prerequisite)}); - action_prerequisite_count = 1; -} - -} // namespace internal -} // namespace base
diff --git a/base/task/promise/abstract_promise.h b/base/task/promise/abstract_promise.h deleted file mode 100644 index 6656229..0000000 --- a/base/task/promise/abstract_promise.h +++ /dev/null
@@ -1,471 +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 BASE_TASK_PROMISE_ABSTRACT_PROMISE_H_ -#define BASE_TASK_PROMISE_ABSTRACT_PROMISE_H_ - -#include <utility> - -#include "base/containers/unique_any.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/no_destructor.h" -#include "base/task/common/checked_lock.h" -#include "base/task/promise/dependent_list.h" -#include "base/task/promise/small_unique_object.h" -#include "base/thread_annotations.h" - -namespace base { -class TaskRunner; - -// std::variant, std::tuple and other templates can't contain void but they can -// contain the empty type Void. This is the same idea as std::monospace. -struct Void {}; - -// Signals that a promise doesn't reject. E.g. Promise<int, NoReject> -struct NoReject {}; - -// This enum is used to configure AbstractPromise's uncaught reject detection. -// Usually not catching a reject reason is a coding error, but at times that can -// become onerous. When that happens kCatchNotRequired should be used. -enum class RejectPolicy { - kMustCatchRejection, - kCatchNotRequired, -}; - -// Internally Resolved<> is used to store the result of a promise callback that -// resolved. This lets us disambiguate promises with the same resolve and reject -// type. -template <typename T> -struct BASE_EXPORT Resolved { - using Type = T; - - Resolved() = default; - - template <typename... Args> - Resolved(Args&&... args) noexcept : value(std::forward<Args>(args)...) {} - - T value; -}; - -template <> -struct BASE_EXPORT Resolved<void> { - using Type = void; - Void value; -}; - -// Internally Rejected<> is used to store the result of a promise callback that -// rejected. This lets us disambiguate promises with the same resolve and reject -// type. -template <typename T> -struct BASE_EXPORT Rejected { - using Type = T; - T value; - - Rejected() = default; - - template <typename... Args> - Rejected(Args&&... args) noexcept : value(std::forward<Args>(args)...) {} -}; - -template <> -struct BASE_EXPORT Rejected<void> { - using Type = void; - Void value; -}; - -namespace internal { - -// Internal promise representation, maintains a graph of dependencies and posts -// promises as they become ready. In debug builds various sanity checks are -// performed to catch common errors such as double move or forgetting to catch a -// potential reject (NB this last check can be turned off with -// RejectPolicy::kCatchNotRequired). -class BASE_EXPORT AbstractPromise - : public RefCountedThreadSafe<AbstractPromise> { - public: - struct AdjacencyList; - - template <typename ConstructType, typename DerivedExecutorType> - struct ConstructWith {}; - - template <typename ConstructType, - typename DerivedExecutorType, - typename... ExecutorArgs> - AbstractPromise(scoped_refptr<TaskRunner>&& task_runner, - const Location& from_here, - std::unique_ptr<AdjacencyList> prerequisites, - RejectPolicy reject_policy, - ConstructWith<ConstructType, DerivedExecutorType>, - ExecutorArgs&&... executor_args) noexcept - : task_runner_(std::move(task_runner)), - from_here_(std::move(from_here)), - value_(in_place_type_t<SmallUniqueObject<Executor>>(), - in_place_type_t<DerivedExecutorType>(), - std::forward<ExecutorArgs>(executor_args)...), -#if DCHECK_IS_ON() - reject_policy_(reject_policy), - resolve_argument_passing_type_( - GetExecutor()->ResolveArgumentPassingType()), - reject_argument_passing_type_( - GetExecutor()->RejectArgumentPassingType()), - executor_can_resolve_(GetExecutor()->CanResolve()), - executor_can_reject_(GetExecutor()->CanReject()), -#endif - dependents_(ConstructType()), - prerequisites_(std::move(prerequisites)) { -#if DCHECK_IS_ON() - { - CheckedAutoLock lock(GetCheckedLock()); - if (executor_can_resolve_) { - this_resolve_ = - MakeRefCounted<DoubleMoveDetector>(from_here_, "resolve"); - } - - if (executor_can_reject_) { - this_reject_ = MakeRefCounted<DoubleMoveDetector>(from_here_, "reject"); - - if (reject_policy_ == RejectPolicy::kMustCatchRejection) { - this_must_catch_ = MakeRefCounted<LocationRef>(from_here_); - } - } - } -#endif - - if (prerequisites_) - AddAsDependentForAllPrerequisites(); - } - - AbstractPromise(const AbstractPromise&) = delete; - AbstractPromise& operator=(const AbstractPromise&) = delete; - - const Location& from_here() const { return from_here_; } - - bool IsCanceled() const; - bool IsRejected() const { return dependents_.IsRejected(); } - bool IsResolved() const { return dependents_.IsResolved(); } - bool IsSettled() const { return dependents_.IsSettled(); } - - bool IsResolvedWithPromise() const { - return value_.type() == - TypeId::From<scoped_refptr<internal::AbstractPromise>>(); - } - - const unique_any& value() const { return FindNonCurriedAncestor()->value_; } - - // Moves the value from within T::value. - template <typename T> - auto TakeInnerValue() { - T* ptr = unique_any_cast<T>(&FindNonCurriedAncestor()->value_); - DCHECK(ptr); - return std::move(ptr->value); - } - - // If this promise isn't curried, returns this. Otherwise follows the chain of - // currying until a non-curried promise is found. - const AbstractPromise* FindNonCurriedAncestor() const; - - AbstractPromise* FindNonCurriedAncestor() { - return const_cast<AbstractPromise*>( - const_cast<const AbstractPromise*>(this)->FindNonCurriedAncestor()); - } - - // Sets the |value_| to |t|. The caller should call OnResolved() or - // OnRejected() afterwards. - template <typename T> - void emplace(T&& t) { - DCHECK(GetExecutor() != nullptr) << "Only valid to emplace once"; - value_ = std::forward<T>(t); - } - - // Unresolved promises have an executor which invokes one of the callbacks - // associated with the promise. Once the callback has been invoked the - // Executor is destroyed. - class BASE_EXPORT Executor { - public: - virtual ~Executor() {} - - // Controls whether or not a promise should wait for its prerequisites - // before becoming eligible for execution. - enum class PrerequisitePolicy : uint8_t { - // Wait for all prerequisites to resolve (or any to reject) before - // becoming eligible for execution. If any prerequisites are canceled it - // will be canceled too. - kAll, - - // Wait for any prerequisite to resolve or reject before becoming eligible - // for execution. If all prerequisites are canceled it will be canceled - // too. - kAny, - - // Never become eligible for execution. Cancellation is ignored. - kNever, - }; - - // Returns the associated PrerequisitePolicy. - virtual PrerequisitePolicy GetPrerequisitePolicy() = 0; - - // NB if there is both a resolve and a reject executor we require them to - // be both canceled at the same time. - virtual bool IsCancelled() const = 0; - - // Describes an executor callback. - enum class ArgumentPassingType : uint8_t { - // No callback. E.g. the RejectArgumentPassingType in a promise with a - // resolve callback but no reject callback. - kNoCallback, - - // Executor callback argument passed by value or by reference. - kNormal, - - // Executor callback argument passed by r-value reference. - kMove, - }; - -#if DCHECK_IS_ON() - // Returns details of the resolve and reject executor callbacks if any. This - // data is used to diagnose double moves and missing catches. - virtual ArgumentPassingType ResolveArgumentPassingType() const = 0; - virtual ArgumentPassingType RejectArgumentPassingType() const = 0; - virtual bool CanResolve() const = 0; - virtual bool CanReject() const = 0; -#endif - - // Invokes the associate callback for |promise|. If the callback was - // cancelled it should call |promise->OnCanceled()|. If the callback - // resolved it should store the resolve result via |promise->emplace()| and - // call |promise->OnResolved()|. If the callback was rejected it should - // store the reject result in |promise->state()| and call - // |promise->OnResolved()|. - // Caution the Executor will be destructed when |promise->state()| is - // written to. - virtual void Execute(AbstractPromise* promise) = 0; - }; - - // Signals that this promise was cancelled. If executor hasn't run yet, this - // will prevent it from running and cancels any dependent promises unless they - // have PrerequisitePolicy::kAny, in which case they will only be canceled if - // all of their prerequisites are canceled. If OnCanceled() or OnResolved() or - // OnRejected() has already run, this does nothing. - void OnCanceled(); - - // Signals that |value_| now contains a resolve value. Dependent promises may - // scheduled for execution. - void OnResolved(); - - // Signals that |value_| now contains a reject value. Dependent promises may - // scheduled for execution. - void OnRejected(); - - struct BASE_EXPORT AdjacencyListNode { - AdjacencyListNode(); - explicit AdjacencyListNode(scoped_refptr<AbstractPromise> prerequisite); - explicit AdjacencyListNode(AdjacencyListNode&& other) noexcept; - ~AdjacencyListNode(); - - scoped_refptr<AbstractPromise> prerequisite; - DependentList::Node dependent_node; - }; - - // This is separate from AbstractPromise to reduce the memory footprint of - // regular PostTask without promise chains. - struct BASE_EXPORT AdjacencyList { - AdjacencyList(); - explicit AdjacencyList(scoped_refptr<AbstractPromise> prerequisite); - explicit AdjacencyList(std::vector<AdjacencyListNode> prerequisite_list); - ~AdjacencyList(); - - void ResetWithSingleDependency(scoped_refptr<AbstractPromise> prerequisite); - - bool DecrementPrerequisiteCountAndCheckIfZero(); - - std::vector<AdjacencyListNode> prerequisite_list; - - // PrerequisitePolicy::kAny waits for at most 1 resolve or N cancellations. - // PrerequisitePolicy::kAll waits for N resolves or at most 1 cancellation. - // PrerequisitePolicy::kNever doesn't use this. - std::atomic_int action_prerequisite_count; - }; - - const std::vector<AdjacencyListNode>* prerequisite_list() const { - if (!prerequisites_) - return nullptr; - return &prerequisites_->prerequisite_list; - } - - // Returns the first and only prerequisite AbstractPromise. It's an error to - // call this if the number of prerequisites isn't exactly one. - AbstractPromise* GetOnlyPrerequisite() const { - DCHECK(prerequisites_); - DCHECK_EQ(prerequisites_->prerequisite_list.size(), 1u); - return prerequisites_->prerequisite_list[0].prerequisite.get(); - } - - // Calls |RunExecutor()| or posts a task to do so if |from_here_| is not - // nullopt. - void Execute(); - - private: - friend base::RefCountedThreadSafe<AbstractPromise>; - - NOINLINE ~AbstractPromise(); - - // Returns the associated Executor if there is one. - const Executor* GetExecutor() const; - - Executor* GetExecutor() { - return const_cast<Executor*>( - const_cast<const AbstractPromise*>(this)->GetExecutor()); - } - - // With the exception of curried promises, this may only be called before the - // executor has run. - Executor::PrerequisitePolicy GetPrerequisitePolicy(); - - void AddAsDependentForAllPrerequisites(); - - // If the promise hasn't executed then |node| is added to the list. If it has - // and it was resolved or rejected then the corresponding promise is scheduled - // for execution if necessary. If this promise was canceled this is a NOP. - // Returns false if this operation failed because this promise became canceled - // as a result of adding a dependency on a canceled |node|. - bool InsertDependentOnAnyThread(DependentList::Node* node); - - // Checks if the promise is now ready to be executed and if so posts it on the - // given task runner. - void OnPrerequisiteResolved(); - - // Schedules the promise for execution. - void OnPrerequisiteRejected(); - - // Returns true if we are still potentially eligible to run despite the - // cancellation. - bool OnPrerequisiteCancelled(); - - // This promise was resolved, post any dependent promises that are now ready - // as a result. - void OnResolvePostReadyDependents(); - - // This promise was rejected, post any dependent promises that are now ready - // as a result. - void OnRejectPostReadyDependents(); - - // Reverses |list| so dependents can be dispatched in the order they where - // added. Assumes no other thread is accessing |list|. - static DependentList::Node* NonThreadSafeReverseList( - DependentList::Node* list); - - // Finds the non-curried root, and if settled ready dependents are posted. - // Returns true if the non-curried root was settled. - bool DispatchIfNonCurriedRootSettled(); - - scoped_refptr<TaskRunner> task_runner_; - - const Location from_here_; - - // To save memory |value_| contains SmallUniqueObject<Executor> (which is - // stored inline) before it has run and afterwards it contains one of: - // * Resolved<T> - // * Rejected<T> - // * scoped_refptr<AbstractPromise> (for curried promises - i.e. a promise - // which is resolved with a promise). - unique_any value_; - -#if DCHECK_IS_ON() - void MaybeInheritChecks(AbstractPromise* source) - EXCLUSIVE_LOCKS_REQUIRED(GetCheckedLock()); - - // Does nothing if this promise wasn't resolved by a promise. - void PassCatchResponsibilityOntoDependentsForCurriedPromise( - DependentList::Node* dependent_list); - - // Controls how we deal with unhandled rejection. - const RejectPolicy reject_policy_; - - // Cached because we need to access these values after the Executor they came - // from has gone away. - const Executor::ArgumentPassingType resolve_argument_passing_type_; - const Executor::ArgumentPassingType reject_argument_passing_type_; - const bool executor_can_resolve_; - const bool executor_can_reject_; - - // Whether responsibility for catching rejected promise has been passed on to - // this promise's dependents. - bool passed_catch_responsibility_ GUARDED_BY(GetCheckedLock()) = false; - - static CheckedLock& GetCheckedLock(); - - // Used to avoid refcounting cycles. - class BASE_EXPORT LocationRef : public RefCountedThreadSafe<LocationRef> { - public: - explicit LocationRef(const Location& from_here); - - const Location& from_here() const { return from_here_; } - - private: - Location from_here_; - - friend class RefCountedThreadSafe<LocationRef>; - ~LocationRef(); - }; - - // For catching missing catches. - scoped_refptr<LocationRef> must_catch_ancestor_that_could_reject_ - GUARDED_BY(GetCheckedLock()); - - // Used to supply all child nodes with a single LocationRef. - scoped_refptr<LocationRef> this_must_catch_ GUARDED_BY(GetCheckedLock()); - - class BASE_EXPORT DoubleMoveDetector - : public RefCountedThreadSafe<DoubleMoveDetector> { - public: - DoubleMoveDetector(const Location& from_here, const char* callback_type); - - void CheckForDoubleMoveErrors( - const base::Location& new_dependent_location, - Executor::ArgumentPassingType new_dependent_executor_type); - - private: - const Location from_here_; - const char* callback_type_; - std::unique_ptr<Location> dependent_move_only_promise_; - std::unique_ptr<Location> dependent_normal_promise_; - - friend class RefCountedThreadSafe<DoubleMoveDetector>; - ~DoubleMoveDetector(); - }; - - // Used to supply all child nodes with a single DoubleMoveDetector. - scoped_refptr<DoubleMoveDetector> this_resolve_ GUARDED_BY(GetCheckedLock()); - - // Used to supply all child nodes with a single DoubleMoveDetector. - scoped_refptr<DoubleMoveDetector> this_reject_ GUARDED_BY(GetCheckedLock()); - - // Validates that the value of this promise, or the value of the closest - // ancestor that can resolve if this promise can't resolve, is not - // double-moved. - scoped_refptr<DoubleMoveDetector> ancestor_that_could_resolve_ - GUARDED_BY(GetCheckedLock()); - - // Validates that the value of this promise, or the value of the closest - // ancestor that can reject if this promise can't reject, is not - // double-moved. - scoped_refptr<DoubleMoveDetector> ancestor_that_could_reject_ - GUARDED_BY(GetCheckedLock()); -#endif - - // List of promises which are dependent on this one. - DependentList dependents_; - - // Details of any promises this promise is dependent on. If there are none - // |prerequisites_| will be null. This is a space optimization for the common - // case of a non-chained PostTask. - std::unique_ptr<AdjacencyList> prerequisites_; -}; - -} // namespace internal -} // namespace base - -#endif // BASE_TASK_PROMISE_ABSTRACT_PROMISE_H_
diff --git a/base/task/promise/abstract_promise_unittest.cc b/base/task/promise/abstract_promise_unittest.cc deleted file mode 100644 index 5da9fbf..0000000 --- a/base/task/promise/abstract_promise_unittest.cc +++ /dev/null
@@ -1,2151 +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 "base/task/promise/abstract_promise.h" - -#include "base/test/bind_test_util.h" -#include "base/test/do_nothing_promise.h" -#include "base/test/gtest_util.h" -#include "base/test/scoped_task_environment.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::ElementsAre; - -using ArgumentPassingType = - base::internal::AbstractPromise::Executor::ArgumentPassingType; - -using PrerequisitePolicy = - base::internal::AbstractPromise::Executor::PrerequisitePolicy; - -namespace base { -namespace internal { - -class TestExecutor : public AbstractPromise::Executor { - public: - TestExecutor(PrerequisitePolicy policy, -#if DCHECK_IS_ON() - ArgumentPassingType resolve_executor_type, - ArgumentPassingType reject_executor_type, - bool can_resolve, - bool can_reject, -#endif - base::OnceCallback<void(AbstractPromise*)> callback) - : callback_(std::move(callback)), -#if DCHECK_IS_ON() - resolve_argument_passing_type_(resolve_executor_type), - reject_argument_passing_type_(reject_executor_type), - resolve_flags_(can_resolve + (can_reject << 1)), -#endif - policy_(policy) { - } - -#if DCHECK_IS_ON() - ArgumentPassingType ResolveArgumentPassingType() const override { - return resolve_argument_passing_type_; - } - - ArgumentPassingType RejectArgumentPassingType() const override { - return reject_argument_passing_type_; - } - - bool CanResolve() const override { return resolve_flags_ & 1; } - - bool CanReject() const override { return resolve_flags_ & 2; } -#endif - - PrerequisitePolicy GetPrerequisitePolicy() override { return policy_; } - - bool IsCancelled() const override { return false; } - - void Execute(AbstractPromise* p) override { std::move(callback_).Run(p); } - - private: - base::OnceCallback<void(AbstractPromise*)> callback_; -#if DCHECK_IS_ON() - const ArgumentPassingType resolve_argument_passing_type_; - const ArgumentPassingType reject_argument_passing_type_; - // On 32 bit platform we need to pack to fit in the space requirement of 3x - // void*. - uint8_t resolve_flags_; -#endif - const PrerequisitePolicy policy_; -}; - -class AbstractPromiseTest : public testing::Test { - public: - enum class CallbackResultType : uint8_t { - kNoCallback, - kCanResolve, - kCanReject, - kCanResolveOrReject, - }; - - struct PromiseSettings { - PromiseSettings( - Location from_here, - std::unique_ptr<AbstractPromise::AdjacencyList> prerequisites) - : from_here(from_here), prerequisites(std::move(prerequisites)) {} - - Location from_here; - - std::unique_ptr<AbstractPromise::AdjacencyList> prerequisites; - - PrerequisitePolicy prerequisite_policy = - AbstractPromise::Executor::PrerequisitePolicy::kAll; - - bool executor_can_resolve = true; - - bool executor_can_reject = false; - - ArgumentPassingType resolve_executor_type = ArgumentPassingType::kNormal; - - ArgumentPassingType reject_executor_type = ArgumentPassingType::kNoCallback; - - RejectPolicy reject_policy = RejectPolicy::kMustCatchRejection; - - base::OnceCallback<void(AbstractPromise*)> callback; - - scoped_refptr<TaskRunner> task_runner = ThreadTaskRunnerHandle::Get(); - }; - - class PromiseSettingsBuilder { - public: - PromiseSettingsBuilder( - Location from_here, - std::unique_ptr<AbstractPromise::AdjacencyList> prerequisites) - : settings(from_here, std::move(prerequisites)) {} - - PromiseSettingsBuilder& With(PrerequisitePolicy prerequisite_policy) { - settings.prerequisite_policy = prerequisite_policy; - return *this; - } - - PromiseSettingsBuilder& With(const scoped_refptr<TaskRunner>& task_runner) { - settings.task_runner = task_runner; - return *this; - } - - PromiseSettingsBuilder& With(RejectPolicy reject_policy) { - settings.reject_policy = reject_policy; - return *this; - } - - PromiseSettingsBuilder& With( - base::OnceCallback<void(AbstractPromise*)> callback) { - settings.callback = std::move(callback); - return *this; - } - - PromiseSettingsBuilder& With(CallbackResultType callback_result_type) { - switch (callback_result_type) { - case CallbackResultType::kNoCallback: - settings.executor_can_resolve = false; - settings.executor_can_reject = false; - break; - case CallbackResultType::kCanResolve: - settings.executor_can_resolve = true; - settings.executor_can_reject = false; - break; - case CallbackResultType::kCanReject: - settings.executor_can_resolve = false; - settings.executor_can_reject = true; - break; - case CallbackResultType::kCanResolveOrReject: - settings.executor_can_resolve = true; - settings.executor_can_reject = true; - break; - }; - return *this; - } - - PromiseSettingsBuilder& WithResolve( - ArgumentPassingType resolve_executor_type) { - settings.resolve_executor_type = resolve_executor_type; - return *this; - } - - PromiseSettingsBuilder& WithReject( - ArgumentPassingType reject_executor_type) { - settings.reject_executor_type = reject_executor_type; - return *this; - } - - operator scoped_refptr<AbstractPromise>() { - return subtle::AdoptRefIfNeeded( - new AbstractPromise( - std::move(settings.task_runner), settings.from_here, - std::move(settings.prerequisites), settings.reject_policy, - AbstractPromise::ConstructWith<DependentList::ConstructUnresolved, - TestExecutor>(), - settings.prerequisite_policy, -#if DCHECK_IS_ON() - settings.resolve_executor_type, settings.reject_executor_type, - settings.executor_can_resolve, settings.executor_can_reject, -#endif - std::move(settings.callback)), - AbstractPromise::kRefCountPreference); - } - - private: - PromiseSettings settings; - }; - - PromiseSettingsBuilder ThenPromise(Location from_here, - scoped_refptr<AbstractPromise> parent) { - PromiseSettingsBuilder builder( - from_here, parent ? std::make_unique<AbstractPromise::AdjacencyList>( - std::move(parent)) - : std::make_unique<AbstractPromise::AdjacencyList>()); - builder.With(BindOnce([](AbstractPromise* p) { - AbstractPromise* prerequisite = p->GetOnlyPrerequisite(); - if (prerequisite->IsResolved()) { - p->emplace(Resolved<void>()); - p->OnResolved(); - } else if (prerequisite->IsRejected()) { - // Consistent with BaseThenAndCatchExecutor::ProcessNullExecutor. - p->emplace(scoped_refptr<AbstractPromise>(prerequisite)); - p->OnResolved(); - } - })); - return builder; - } - - PromiseSettingsBuilder CatchPromise(Location from_here, - scoped_refptr<AbstractPromise> parent) { - PromiseSettingsBuilder builder( - from_here, parent ? std::make_unique<AbstractPromise::AdjacencyList>( - std::move(parent)) - : std::make_unique<AbstractPromise::AdjacencyList>()); - builder.With(CallbackResultType::kNoCallback) - .With(CallbackResultType::kCanResolve) - .WithResolve(ArgumentPassingType::kNoCallback) - .WithReject(ArgumentPassingType::kNormal) - .With(BindOnce([](AbstractPromise* p) { - AbstractPromise* prerequisite = p->GetOnlyPrerequisite(); - if (prerequisite->IsResolved()) { - // Consistent with BaseThenAndCatchExecutor::ProcessNullExecutor. - p->emplace(scoped_refptr<AbstractPromise>(prerequisite)); - p->OnResolved(); - } else if (prerequisite->IsRejected()) { - p->emplace(Resolved<void>()); - p->OnResolved(); - } - })); - return builder; - } - - PromiseSettingsBuilder AllPromise( - Location from_here, - std::vector<internal::AbstractPromise::AdjacencyListNode> - prerequisite_list) { - PromiseSettingsBuilder builder( - from_here, std::make_unique<AbstractPromise::AdjacencyList>( - std::move(prerequisite_list))); - builder.With(PrerequisitePolicy::kAll) - .With(BindOnce([](AbstractPromise* p) { - // Reject if any prerequisites rejected. - for (const AbstractPromise::AdjacencyListNode& node : - *p->prerequisite_list()) { - if (node.prerequisite->IsRejected()) { - p->emplace(Rejected<void>()); - p->OnRejected(); - return; - } - } - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - return builder; - } - - PromiseSettingsBuilder AnyPromise( - Location from_here, - std::vector<internal::AbstractPromise::AdjacencyListNode> - prerequisite_list) { - PromiseSettingsBuilder builder( - from_here, std::make_unique<AbstractPromise::AdjacencyList>( - std::move(prerequisite_list))); - builder.With(PrerequisitePolicy::kAny) - .With(BindOnce([](AbstractPromise* p) { - // Reject if any prerequisites rejected. - for (const AbstractPromise::AdjacencyListNode& node : - *p->prerequisite_list()) { - if (node.prerequisite->IsRejected()) { - p->emplace(Rejected<void>()); - p->OnRejected(); - return; - } - } - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - return builder; - } - - test::ScopedTaskEnvironment scoped_task_environment_; -}; - -TEST_F(AbstractPromiseTest, UnfulfilledPromise) { - scoped_refptr<AbstractPromise> promise = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - EXPECT_FALSE(promise->IsResolved()); - EXPECT_FALSE(promise->IsRejected()); - EXPECT_FALSE(promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, OnResolve) { - scoped_refptr<AbstractPromise> promise = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - EXPECT_FALSE(promise->IsResolved()); - promise->OnResolved(); - EXPECT_TRUE(promise->IsResolved()); -} - -TEST_F(AbstractPromiseTest, OnReject) { - scoped_refptr<AbstractPromise> promise = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetRejectPolicy( - RejectPolicy::kCatchNotRequired); - EXPECT_FALSE(promise->IsRejected()); - promise->OnRejected(); - EXPECT_TRUE(promise->IsRejected()); -} - -TEST_F(AbstractPromiseTest, ExecuteOnResolve) { - scoped_refptr<AbstractPromise> promise = - ThenPromise(FROM_HERE, nullptr).With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - EXPECT_FALSE(promise->IsResolved()); - promise->Execute(); - EXPECT_TRUE(promise->IsResolved()); -} - -TEST_F(AbstractPromiseTest, ExecuteOnReject) { - scoped_refptr<AbstractPromise> promise = - ThenPromise(FROM_HERE, nullptr) - .With(RejectPolicy::kCatchNotRequired) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - EXPECT_FALSE(promise->IsRejected()); - promise->Execute(); - EXPECT_TRUE(promise->IsRejected()); -} - -TEST_F(AbstractPromiseTest, ExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p3); - scoped_refptr<AbstractPromise> p5 = ThenPromise(FROM_HERE, p4); - - p1->OnResolved(); - - EXPECT_FALSE(p2->IsResolved()); - EXPECT_FALSE(p3->IsResolved()); - EXPECT_FALSE(p4->IsResolved()); - EXPECT_FALSE(p5->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p1->IsResolved()); - EXPECT_TRUE(p3->IsResolved()); - EXPECT_TRUE(p4->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, MoveExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1).WithResolve(ArgumentPassingType::kMove); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p2).WithResolve(ArgumentPassingType::kMove); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3).WithResolve(ArgumentPassingType::kMove); - - scoped_refptr<AbstractPromise> p5 = - ThenPromise(FROM_HERE, p4).WithResolve(ArgumentPassingType::kMove); - - p1->OnResolved(); - - EXPECT_FALSE(p2->IsResolved()); - EXPECT_FALSE(p3->IsResolved()); - EXPECT_FALSE(p4->IsResolved()); - EXPECT_FALSE(p5->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p1->IsResolved()); - EXPECT_TRUE(p3->IsResolved()); - EXPECT_TRUE(p4->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, MoveResolveCatchExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1) - .With(CallbackResultType::kCanReject) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p3 = - CatchPromise(FROM_HERE, p2) - .With(CallbackResultType::kCanResolve) - .WithReject(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3) - .With(CallbackResultType::kCanReject) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p5 = - CatchPromise(FROM_HERE, p4) - .With(CallbackResultType::kCanResolve) - .WithReject(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - p1->OnResolved(); - - EXPECT_FALSE(p2->IsRejected()); - EXPECT_FALSE(p3->IsResolved()); - EXPECT_FALSE(p4->IsRejected()); - EXPECT_FALSE(p5->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p2->IsRejected()); - EXPECT_TRUE(p3->IsResolved()); - EXPECT_TRUE(p4->IsRejected()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, MoveResolveCatchExecutionChainType2) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1) - .With(CallbackResultType::kCanReject) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p3 = - CatchPromise(FROM_HERE, p2) - .With(CallbackResultType::kCanReject) - .WithReject(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p4 = - CatchPromise(FROM_HERE, p3) - .With(CallbackResultType::kCanResolve) - .WithReject(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p5 = - ThenPromise(FROM_HERE, p4) - .With(CallbackResultType::kCanResolve) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p6 = - ThenPromise(FROM_HERE, p5) - .With(CallbackResultType::kCanReject) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p7 = - CatchPromise(FROM_HERE, p6) - .With(CallbackResultType::kCanReject) - .WithReject(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p8 = - CatchPromise(FROM_HERE, p7) - .With(CallbackResultType::kCanResolve) - .WithReject(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p9 = - ThenPromise(FROM_HERE, p8) - .With(CallbackResultType::kCanResolve) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - p1->OnResolved(); - - EXPECT_FALSE(p2->IsRejected()); - EXPECT_FALSE(p3->IsRejected()); - EXPECT_FALSE(p4->IsResolved()); - EXPECT_FALSE(p5->IsResolved()); - EXPECT_FALSE(p6->IsRejected()); - EXPECT_FALSE(p7->IsRejected()); - EXPECT_FALSE(p8->IsResolved()); - EXPECT_FALSE(p9->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p2->IsRejected()); - EXPECT_TRUE(p3->IsRejected()); - EXPECT_TRUE(p4->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); - EXPECT_TRUE(p6->IsRejected()); - EXPECT_TRUE(p7->IsRejected()); - EXPECT_TRUE(p8->IsResolved()); - EXPECT_TRUE(p9->IsResolved()); -} - -TEST_F(AbstractPromiseTest, MixedMoveAndNormalExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1).WithResolve(ArgumentPassingType::kMove); - - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3).WithResolve(ArgumentPassingType::kMove); - - scoped_refptr<AbstractPromise> p5 = ThenPromise(FROM_HERE, p4); - - p1->OnResolved(); - - EXPECT_FALSE(p2->IsResolved()); - EXPECT_FALSE(p3->IsResolved()); - EXPECT_FALSE(p4->IsResolved()); - EXPECT_FALSE(p5->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p1->IsResolved()); - EXPECT_TRUE(p3->IsResolved()); - EXPECT_TRUE(p4->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, MoveAtEndOfChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p2).WithResolve(ArgumentPassingType::kMove); -} - -TEST_F(AbstractPromiseTest, BranchedExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p5 = ThenPromise(FROM_HERE, p4); - - p1->OnResolved(); - - EXPECT_FALSE(p2->IsResolved()); - EXPECT_FALSE(p3->IsResolved()); - EXPECT_FALSE(p4->IsResolved()); - EXPECT_FALSE(p5->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p2->IsResolved()); - EXPECT_TRUE(p3->IsResolved()); - EXPECT_TRUE(p4->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, PrerequisiteAlreadyResolved) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - p1->OnResolved(); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - - EXPECT_FALSE(p2->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p2->IsResolved()); -} - -TEST_F(AbstractPromiseTest, PrerequisiteAlreadyRejected) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - p1->OnRejected(); - - scoped_refptr<AbstractPromise> p2 = CatchPromise(FROM_HERE, p1); - - EXPECT_FALSE(p2->IsResolved()); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p2->IsResolved()); -} - -TEST_F(AbstractPromiseTest, MultipleResolvedPrerequisitePolicyALL) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p4 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 4); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - prerequisite_list[3].prerequisite = p4; - - scoped_refptr<AbstractPromise> all_promise = - AllPromise(FROM_HERE, std::move(prerequisite_list)); - - p1->OnResolved(); - p2->OnResolved(); - p3->OnResolved(); - RunLoop().RunUntilIdle(); - - EXPECT_FALSE(all_promise->IsResolved()); - p4->OnResolved(); - - RunLoop().RunUntilIdle(); - EXPECT_TRUE(all_promise->IsResolved()); -} - -TEST_F(AbstractPromiseTest, - MultithreadedMultipleResolvedPrerequisitePolicyALL) { - constexpr int num_threads = 4; - constexpr int num_promises = 1000; - - std::unique_ptr<Thread> thread[num_threads]; - for (int i = 0; i < num_threads; i++) { - thread[i] = std::make_unique<Thread>("Test thread"); - thread[i]->Start(); - } - - scoped_refptr<AbstractPromise> promise[num_promises]; - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - num_promises); - for (int i = 0; i < num_promises; i++) { - promise[i] = DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - prerequisite_list[i].prerequisite = promise[i]; - } - - scoped_refptr<AbstractPromise> all_promise = - AllPromise(FROM_HERE, std::move(prerequisite_list)); - - RunLoop run_loop; - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, all_promise) - .With(BindLambdaForTesting( - [&](AbstractPromise* p) { run_loop.Quit(); })); - - for (int i = 0; i < num_promises; i++) { - thread[i % num_threads]->task_runner()->PostTask( - FROM_HERE, BindOnce( - [](scoped_refptr<AbstractPromise> all_promise, - scoped_refptr<AbstractPromise> promise) { - EXPECT_FALSE(all_promise->IsResolved()); - promise->OnResolved(); - }, - all_promise, promise[i])); - } - - run_loop.Run(); - - for (int i = 0; i < num_promises; i++) { - EXPECT_TRUE(promise[i]->IsResolved()); - } - - EXPECT_TRUE(all_promise->IsResolved()); - - for (int i = 0; i < num_threads; i++) { - thread[i]->Stop(); - } -} - -TEST_F(AbstractPromiseTest, SingleRejectPrerequisitePolicyALL) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - scoped_refptr<AbstractPromise> p4 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 4); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - prerequisite_list[3].prerequisite = p4; - - scoped_refptr<AbstractPromise> all_promise = - AllPromise(FROM_HERE, std::move(prerequisite_list)) - .With(CallbackResultType::kCanResolveOrReject); - - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, all_promise); - - p3->OnRejected(); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(all_promise->IsRejected()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, SingleResolvedPrerequisitesPrerequisitePolicyANY) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p4 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 4); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - prerequisite_list[3].prerequisite = p4; - - scoped_refptr<AbstractPromise> any_promise = - AnyPromise(FROM_HERE, std::move(prerequisite_list)); - - p2->OnResolved(); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(any_promise->IsResolved()); -} - -TEST_F(AbstractPromiseTest, SingleRejectPrerequisitePolicyANY) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - scoped_refptr<AbstractPromise> p4 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 4); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - prerequisite_list[3].prerequisite = p4; - - scoped_refptr<AbstractPromise> any_promise = - AnyPromise(FROM_HERE, std::move(prerequisite_list)) - .With(CallbackResultType::kCanResolveOrReject); - - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, any_promise); - - p3->OnRejected(); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(any_promise->IsRejected()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, SingleResolvePrerequisitePolicyANY) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p4 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 4); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - prerequisite_list[3].prerequisite = p4; - - scoped_refptr<AbstractPromise> any_promise = - AnyPromise(FROM_HERE, std::move(prerequisite_list)); - - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, any_promise); - - p3->OnResolved(); - RunLoop().RunUntilIdle(); - EXPECT_TRUE(any_promise->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); -} - -TEST_F(AbstractPromiseTest, IsCanceled) { - scoped_refptr<AbstractPromise> promise = ThenPromise(FROM_HERE, nullptr); - EXPECT_FALSE(promise->IsCanceled()); - promise->OnCanceled(); - EXPECT_TRUE(promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, OnCanceledPreventsExecution) { - scoped_refptr<AbstractPromise> promise = - ThenPromise(FROM_HERE, nullptr).With(BindOnce([](AbstractPromise* p) { - FAIL() << "Should not be called"; - })); - promise->OnCanceled(); - promise->Execute(); -} - -TEST_F(AbstractPromiseTest, CancelationStopsExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1).With(BindOnce([](AbstractPromise* p) { - p->OnCanceled(); - p->OnCanceled(); // NOP shouldn't crash. - })); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p3); - - p1->OnResolved(); - - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p3->IsCanceled()); - EXPECT_TRUE(p4->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, CancelationStopsBranchedExecutionChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1).With(BindOnce([](AbstractPromise* p) { - p->OnCanceled(); - })); - - // Branch one - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p3); - - // Branch two - scoped_refptr<AbstractPromise> p5 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> promise6 = ThenPromise(FROM_HERE, p5); - - p1->OnResolved(); - - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p3->IsCanceled()); - EXPECT_TRUE(p4->IsCanceled()); - EXPECT_TRUE(p5->IsCanceled()); - EXPECT_TRUE(promise6->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, CancelChainCanReject) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p2); - - p0->OnCanceled(); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, CancelationPrerequisitePolicyALL) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 3); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - - scoped_refptr<AbstractPromise> all_promise = - AllPromise(FROM_HERE, std::move(prerequisite_list)); - - p2->OnCanceled(); - EXPECT_TRUE(all_promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, CancelationPrerequisitePolicyANY) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 3); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - - scoped_refptr<AbstractPromise> any_promise = - AnyPromise(FROM_HERE, std::move(prerequisite_list)); - - p3->OnCanceled(); - p2->OnCanceled(); - EXPECT_FALSE(any_promise->IsCanceled()); - - p1->OnCanceled(); - EXPECT_TRUE(any_promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, AlreadyCanceledPrerequisitePolicyALL) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 3); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - p2->OnCanceled(); - - scoped_refptr<AbstractPromise> all_promise = - AllPromise(FROM_HERE, std::move(prerequisite_list)); - - EXPECT_TRUE(all_promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, SomeAlreadyCanceledPrerequisitePolicyANY) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 3); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - p2->OnCanceled(); - - scoped_refptr<AbstractPromise> any_promise = - AnyPromise(FROM_HERE, std::move(prerequisite_list)); - - EXPECT_FALSE(any_promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, AllAlreadyCanceledPrerequisitePolicyANY) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - scoped_refptr<AbstractPromise> p3 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - std::vector<internal::AbstractPromise::AdjacencyListNode> prerequisite_list( - 3); - prerequisite_list[0].prerequisite = p1; - prerequisite_list[1].prerequisite = p2; - prerequisite_list[2].prerequisite = p3; - p1->OnCanceled(); - p2->OnCanceled(); - p3->OnCanceled(); - - scoped_refptr<AbstractPromise> any_promise = - AnyPromise(FROM_HERE, std::move(prerequisite_list)); - - EXPECT_TRUE(any_promise->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, DetectResolveDoubleMoveHazard) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = ThenPromise(FROM_HERE, nullptr); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0).WithResolve(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH({ - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0).WithResolve(ArgumentPassingType::kMove); - }); -#endif -} - -TEST_F(AbstractPromiseTest, DetectMixedResolveCallbackMoveAndNonMoveHazard) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = ThenPromise(FROM_HERE, nullptr); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0).WithResolve(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH( - { scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p0); }); -#endif -} - -TEST_F(AbstractPromiseTest, MultipleNonMoveCatchCallbacksAreOK) { - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * T T - * | | - * \| |/ - * E3 E4 - * C C - */ - scoped_refptr<AbstractPromise> p0 = - ThenPromise(FROM_HERE, nullptr).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p1 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p2); -} - -TEST_F(AbstractPromiseTest, DetectCatchCallbackDoubleMoveHazard) { -#if DCHECK_IS_ON() - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * C C - * - * We need to make sure P3 & P4's reject callback don't both use move - * semantics since they share a common ancestor with no intermediate catches. - */ - scoped_refptr<AbstractPromise> p0 = - ThenPromise(FROM_HERE, nullptr).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p1 = - CatchPromise(FROM_HERE, p0).WithReject(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH({ - scoped_refptr<AbstractPromise> p2 = - CatchPromise(FROM_HERE, p0).WithReject(ArgumentPassingType::kMove); - }); -#endif -} - -TEST_F(AbstractPromiseTest, DetectCatchCallbackDoubleMoveHazardInChain) { -#if DCHECK_IS_ON() - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * T T - * | | - * \| |/ - * P3 P4 - * C C - * - * We need to make sure P3 & P4's reject callback don't both use move - * semantics since they share a common ancestor with no intermediate catches. - */ - scoped_refptr<AbstractPromise> p0 = - ThenPromise(FROM_HERE, nullptr).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p1 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p0); - - scoped_refptr<AbstractPromise> p3 = - CatchPromise(FROM_HERE, p1).WithReject(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH({ - scoped_refptr<AbstractPromise> p4 = - CatchPromise(FROM_HERE, p2).WithReject(ArgumentPassingType::kMove); - }); -#endif -} - -TEST_F(AbstractPromiseTest, - DetectCatchCallbackDoubleMoveHazardInChainIntermediateThensCanReject) { -#if DCHECK_IS_ON() - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * T T - * | | - * \| |/ - * P3 P4 - * C C - * - * We need to make sure P3 & P4's reject callback don't both use move - * semantics since they share a common ancestor with no intermediate catches. - */ - scoped_refptr<AbstractPromise> p0 = - ThenPromise(FROM_HERE, nullptr).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p3 = - CatchPromise(FROM_HERE, p1).WithReject(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH({ - scoped_refptr<AbstractPromise> p4 = - CatchPromise(FROM_HERE, p2).WithReject(ArgumentPassingType::kMove); - }); -#endif -} - -TEST_F(AbstractPromiseTest, DetectMixedCatchCallbackMoveAndNonMoveHazard) { -#if DCHECK_IS_ON() - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * T T - * | | - * \| |/ - * P3 P4 - * C C - * - * We can't guarantee the order in which P3 and P4's reject callbacks run so - * we need to need to catch the case where move and non-move semantics are - * mixed. - */ - scoped_refptr<AbstractPromise> p0 = - ThenPromise(FROM_HERE, nullptr).With(CallbackResultType::kCanReject); - - scoped_refptr<AbstractPromise> p1 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p0); - - scoped_refptr<AbstractPromise> p3 = - CatchPromise(FROM_HERE, p1).WithReject(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH( - { scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p2); }); -#endif -} - -TEST_F(AbstractPromiseTest, DetectThenCallbackDoubleMoveHazardInChain) { -#if DCHECK_IS_ON() - /* - * Key: T = Then, C = Catch - * - * P0 - * C C - * | | - * \| |/ - * P1 P2 - * C C - * | | - * \| |/ - * P3 P4 - * T T - * - * We need to make sure P3 & P4's resolve callback don't both use move - * semantics since they share a common ancestor with no intermediate then's. - */ - scoped_refptr<AbstractPromise> p0 = ThenPromise(FROM_HERE, nullptr); - scoped_refptr<AbstractPromise> p1 = CatchPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p2 = CatchPromise(FROM_HERE, p0); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p1).WithResolve(ArgumentPassingType::kMove); - - EXPECT_DCHECK_DEATH({ - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p2).WithResolve(ArgumentPassingType::kMove); - }); -#endif -} - -TEST_F(AbstractPromiseTest, SimpleMissingCatch) { - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p1| is deleted. - EXPECT_DCHECK_DEATH({ p1 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p2| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p2 = CatchPromise(FROM_HERE, p1); -} - -TEST_F(AbstractPromiseTest, MissingCatch) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - // The missing catch here will get noticed. - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - - p0->OnResolved(); - - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p2| is deleted. - EXPECT_DCHECK_DEATH({ p2 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p2| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p2); -#endif -} - -TEST_F(AbstractPromiseTest, MissingCatchNotRequired) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(RejectPolicy::kCatchNotRequired) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - // The missing catch here will gets ignored. - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - - p0->OnResolved(); - - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, MissingCatchFromCurriedPromise) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, nullptr) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0) - .With(BindOnce( - [](scoped_refptr<AbstractPromise> p1, AbstractPromise* p) { - // Resolve with a promise that can and does reject. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p1)); - p->emplace(std::move(p1)); - p->OnResolved(); - }, - std::move(p1))); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p2| is deleted. - EXPECT_DCHECK_DEATH({ p2 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p2| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p2); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, MissingCatchFromCurriedPromiseWithDependent) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, nullptr) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0) - .With(BindOnce( - [&](scoped_refptr<AbstractPromise> p1, AbstractPromise* p) { - // Resolve with a promise that can and does reject. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p1)); - p->emplace(std::move(p1)); - p->OnResolved(); - }, - std::move(p1))); - - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p3| is deleted. - EXPECT_DCHECK_DEATH({ p3 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p3| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p3); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, - MissingCatchFromCurriedPromiseWithDependentAddedAfterExecution) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, nullptr) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0) - .With(BindOnce( - [&](scoped_refptr<AbstractPromise> p1, AbstractPromise* p) { - // Resolve with a promise that can and does reject. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p1)); - p->emplace(std::move(p1)); - p->OnResolved(); - }, - std::move(p1))); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p3| is deleted. - EXPECT_DCHECK_DEATH({ p3 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p3| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p3); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, MissingCatchLongChain) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p3); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p4| is deleted. - EXPECT_DCHECK_DEATH({ p4 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p4| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, p4); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, - ThenAddedToSettledPromiseWithMissingCatchAndSeveralDependents) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p2); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - scoped_refptr<AbstractPromise> p5 = ThenPromise(FROM_HERE, p2); - - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p4| is deleted. - EXPECT_DCHECK_DEATH({ p5 = nullptr; }); - - // Tidy up. - scoped_refptr<AbstractPromise> p6 = CatchPromise(FROM_HERE, p3); - scoped_refptr<AbstractPromise> p7 = CatchPromise(FROM_HERE, p4); - scoped_refptr<AbstractPromise> p8 = CatchPromise(FROM_HERE, p5); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, ThenAddedAfterChainExecutionWithMissingCatch) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - // The missing catch here will get noticed. - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p3); - - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p4| is deleted. - EXPECT_DCHECK_DEATH({ p4 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p4| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, p4); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, CatchAddedAfterChainExecution) { - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p3); - - // We shouldn't get a DCHECK failure because |p4| catches the rejection - // from |p1|. - RunLoop().RunUntilIdle(); -} - -TEST_F(AbstractPromiseTest, MultipleThensAddedAfterChainExecution) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - - // |p5| - |p7| should still inherit catch responsibility despite this. - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p3); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - // The missing catches will get noticed. - scoped_refptr<AbstractPromise> p5 = ThenPromise(FROM_HERE, p3); - scoped_refptr<AbstractPromise> p6 = ThenPromise(FROM_HERE, p3); - scoped_refptr<AbstractPromise> p7 = ThenPromise(FROM_HERE, p3); - - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p5|, |p6| or |p7| are deleted. - EXPECT_DCHECK_DEATH({ p5 = nullptr; }); - EXPECT_DCHECK_DEATH({ p6 = nullptr; }); - EXPECT_DCHECK_DEATH({ p7 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p4| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p8 = CatchPromise(FROM_HERE, p5); - scoped_refptr<AbstractPromise> p9 = CatchPromise(FROM_HERE, p6); - scoped_refptr<AbstractPromise> p10 = CatchPromise(FROM_HERE, p7); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, MultipleDependentsAddedAfterChainExecution) { - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); - - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p3); - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, p4); - scoped_refptr<AbstractPromise> p6 = ThenPromise(FROM_HERE, p3); - scoped_refptr<AbstractPromise> p7 = CatchPromise(FROM_HERE, p6); - - // We shouldn't get a DCHECK failure because |p6| and |p7| catch the rejection - // from |p1|. - RunLoop().RunUntilIdle(); -} - -TEST_F(AbstractPromiseTest, CatchAfterLongChain) { - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, p0) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p3 = ThenPromise(FROM_HERE, p2); - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p3); - - p0->OnResolved(); - - RunLoop().RunUntilIdle(); -} - -TEST_F(AbstractPromiseTest, MissingCatchOneSideOfBranchedExecutionChain) { -#if DCHECK_IS_ON() - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * T T - * | | - * \| |/ - * P3 P4 - * C T - * - * The missing catch for P4 should get noticed. - */ - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - - scoped_refptr<AbstractPromise> p1 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p4 = ThenPromise(FROM_HERE, p2); - - p0->OnRejected(); - - RunLoop().RunUntilIdle(); - - // This should DCHECK when |p4| is deleted. - EXPECT_DCHECK_DEATH({ p4 = nullptr; }); - - // Under the hood EXPECT_DCHECK_DEATH uses fork() so |p4| isn't actually - // cleared so we need to tidy up. - scoped_refptr<AbstractPromise> p5 = CatchPromise(FROM_HERE, p4); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, CantResolveIfpromiseDeclaredAsNonResolving) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p = DoNothingPromiseBuilder(FROM_HERE); - - EXPECT_DCHECK_DEATH({ p->OnResolved(); }); -#endif -} - -TEST_F(AbstractPromiseTest, CantRejectIfpromiseDeclaredAsNonRejecting) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p = DoNothingPromiseBuilder(FROM_HERE); - - EXPECT_DCHECK_DEATH({ p->OnRejected(); }); -#endif -} - -TEST_F(AbstractPromiseTest, DoubleMoveDoNothingPromise) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<int>(42)); - p->OnResolved(); - })); - - EXPECT_DCHECK_DEATH({ - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p1) - .WithResolve(ArgumentPassingType::kMove) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<int>(42)); - p->OnResolved(); - })); - }); -#endif -} - -TEST_F(AbstractPromiseTest, CatchBothSidesOfBranchedExecutionChain) { - /* - * Key: T = Then, C = Catch - * - * P0 - * T T - * | | - * \| |/ - * P1 P2 - * T T - * | | - * \| |/ - * P3 P4 - * C C - * - * This should execute without DCHECKS. - */ - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetCanResolve( - false); - - scoped_refptr<AbstractPromise> p1 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p2 = ThenPromise(FROM_HERE, p0); - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p1); - scoped_refptr<AbstractPromise> p4 = CatchPromise(FROM_HERE, p2); - - p0->OnRejected(); - - RunLoop().RunUntilIdle(); -} - -TEST_F(AbstractPromiseTest, ResolvedCurriedPromise) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - std::vector<int> run_order; - - // Promise |p3| will be resolved with. - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, nullptr) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(2); - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p1) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(3); - // Resolve with a promise. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p2)); - p->emplace(std::move(p2)); - p->OnResolved(); - - EXPECT_TRUE(p3->IsResolvedWithPromise()); - })); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(4); - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - p1->OnResolved(); - RunLoop().RunUntilIdle(); - - EXPECT_THAT(run_order, ElementsAre(3, 2, 4)); -} - -TEST_F(AbstractPromiseTest, UnresolvedCurriedPromise) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - std::vector<int> run_order; - - // Promise |p3| will be resolved with. - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p1) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(3); - // Resolve with a promise. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p2)); - p->emplace(p2); - p->OnResolved(); - - EXPECT_TRUE(p3->IsResolvedWithPromise()); - })); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(4); - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - p1->OnResolved(); - RunLoop().RunUntilIdle(); - EXPECT_THAT(run_order, ElementsAre(3)); - - p2->OnResolved(); - RunLoop().RunUntilIdle(); - EXPECT_THAT(run_order, ElementsAre(3, 4)); -} - -TEST_F(AbstractPromiseTest, CanceledCurriedPromise) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - // Promise |p3| will be resolved with. - scoped_refptr<AbstractPromise> p2 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - p2->OnCanceled(); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p1) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - // Resolve with a promise. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p2)); - p->emplace(p2); - p->OnResolved(); - - EXPECT_TRUE(p3->IsResolvedWithPromise()); - })); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3) - .With(BindLambdaForTesting( - [&](AbstractPromise* p) { FAIL() << "Should not get here"; })); - - p1->OnResolved(); - RunLoop().RunUntilIdle(); - - EXPECT_TRUE(p4->IsCanceled()); -} - -TEST_F(AbstractPromiseTest, CurriedPromiseChain) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - std::vector<int> run_order; - - // Promise |p3| will be resolved with. - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, nullptr) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(2); - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - // Promise |p4| will be resolved with. - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, nullptr) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(3); - // Resolve with a promise. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p2)); - p->emplace(std::move(p2)); - p->OnResolved(); - })); - - // Promise |p5| will be resolved with. - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, nullptr) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(4); - // Resolve with a promise. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p3)); - p->emplace(std::move(p3)); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p5 = - ThenPromise(FROM_HERE, p1) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(5); - // Resolve with a promise. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p4)); - p->emplace(std::move(p4)); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p6 = - ThenPromise(FROM_HERE, p3) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - run_order.push_back(6); - p->emplace(Resolved<void>()); - p->OnResolved(); - })); - - p1->OnResolved(); - RunLoop().RunUntilIdle(); - - EXPECT_THAT(run_order, ElementsAre(5, 4, 3, 2, 6)); -} - -TEST_F(AbstractPromiseTest, CurriedPromiseChainType2) { - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(p1); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p2) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(p2); - p->OnResolved(); - })); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(p3); - p->OnResolved(); - })); - - p1->OnResolved(); - RunLoop().RunUntilIdle(); - - EXPECT_TRUE(p4->IsResolved()); - EXPECT_EQ(p1.get(), p4->FindNonCurriedAncestor()); -} - -TEST_F(AbstractPromiseTest, CurriedPromiseMoveArg) { -#if DCHECK_IS_ON() - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, nullptr) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - })) - .WithResolve(ArgumentPassingType::kMove); - ; - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0) - .With(BindOnce( - [](scoped_refptr<AbstractPromise> p1, AbstractPromise* p) { - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p1)); - p->emplace(std::move(p1)); - p->OnResolved(); - }, - std::move(p1))) - .WithResolve(ArgumentPassingType::kMove); - - p0->OnResolved(); - RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AbstractPromiseTest, CatchCurriedPromise) { - scoped_refptr<AbstractPromise> p0 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p1 = - ThenPromise(FROM_HERE, nullptr) - .With(CallbackResultType::kCanReject) - .With(BindOnce([](AbstractPromise* p) { - p->emplace(Rejected<void>()); - p->OnRejected(); - })); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p0) - .With(BindOnce( - [&](scoped_refptr<AbstractPromise> p1, AbstractPromise* p) { - // Resolve with a promise that can and does reject. - ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::Execute, p1)); - p->emplace(std::move(p1)); - p->OnResolved(); - }, - std::move(p1))); - - scoped_refptr<AbstractPromise> p3 = CatchPromise(FROM_HERE, p2); - - p0->OnResolved(); - EXPECT_FALSE(p3->IsResolved()); - - RunLoop().RunUntilIdle(); - EXPECT_TRUE(p3->IsResolved()); -} - -TEST_F(AbstractPromiseTest, ThreadHopping) { - std::unique_ptr<Thread> thread_a(new Thread("AbstractPromiseTest_Thread_A")); - std::unique_ptr<Thread> thread_b(new Thread("AbstractPromiseTest_Thread_B")); - std::unique_ptr<Thread> thread_c(new Thread("AbstractPromiseTest_Thread_C")); - thread_a->Start(); - thread_b->Start(); - thread_c->Start(); - RunLoop run_loop; - - scoped_refptr<AbstractPromise> p1 = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - scoped_refptr<AbstractPromise> p2 = - ThenPromise(FROM_HERE, p1) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - CHECK(thread_a->task_runner()->BelongsToCurrentThread()); - })) - .With(thread_a->task_runner()); - - scoped_refptr<AbstractPromise> p3 = - ThenPromise(FROM_HERE, p2) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - CHECK(thread_b->task_runner()->BelongsToCurrentThread()); - })) - .With(thread_b->task_runner()); - - scoped_refptr<AbstractPromise> p4 = - ThenPromise(FROM_HERE, p3) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - CHECK(thread_c->task_runner()->BelongsToCurrentThread()); - })) - .With(thread_c->task_runner()); - - scoped_refptr<SingleThreadTaskRunner> main_thread = - ThreadTaskRunnerHandle::Get(); - scoped_refptr<AbstractPromise> p5 = - ThenPromise(FROM_HERE, p4) - .With(BindLambdaForTesting([&](AbstractPromise* p) { - p->emplace(Resolved<void>()); - p->OnResolved(); - run_loop.Quit(); - CHECK(main_thread->BelongsToCurrentThread()); - })) - .With(main_thread); - - p1->OnResolved(); - - EXPECT_FALSE(p2->IsResolved()); - EXPECT_FALSE(p3->IsResolved()); - EXPECT_FALSE(p4->IsResolved()); - EXPECT_FALSE(p5->IsResolved()); - run_loop.Run(); - EXPECT_TRUE(p2->IsResolved()); - EXPECT_TRUE(p3->IsResolved()); - EXPECT_TRUE(p4->IsResolved()); - EXPECT_TRUE(p5->IsResolved()); - - thread_a->Stop(); - thread_b->Stop(); - thread_c->Stop(); -} - -TEST_F(AbstractPromiseTest, MutipleThreadsAddingDependants) { - constexpr int num_threads = 4; - constexpr int num_promises = 10000; - - std::unique_ptr<Thread> thread[num_threads]; - for (int i = 0; i < num_threads; i++) { - thread[i] = std::make_unique<Thread>("Test thread"); - thread[i]->Start(); - } - - scoped_refptr<AbstractPromise> root = - DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); - - RunLoop run_loop; - std::atomic<int> pending_count(num_promises); - - // After being called |num_promises| times |decrement_cb| will quit |run_loop| - auto decrement_cb = BindLambdaForTesting([&](AbstractPromise* p) { - int count = pending_count.fetch_sub(1, std::memory_order_acq_rel); - if (count == 1) - run_loop.Quit(); - }); - - // Post a bunch of tasks on multiple threads that create Then promises - // dependent on |root| which call |decrement_cb| when resolved. - for (int i = 0; i < num_promises; i++) { - thread[i % num_threads]->task_runner()->PostTask( - FROM_HERE, BindLambdaForTesting([&]() { - scoped_refptr<AbstractPromise> p = - ThenPromise(FROM_HERE, root).With(decrement_cb); - p->OnResolved(); - })); - - // Mid way through post a task to resolve |root|. - if (i == num_promises / 2) { - thread[i % num_threads]->task_runner()->PostTask( - FROM_HERE, BindOnce(&AbstractPromise::OnResolved, root)); - } - } - - // This should exit cleanly without any TSan errors. - run_loop.Run(); - - for (int i = 0; i < num_threads; i++) { - thread[i]->Stop(); - } -} - -} // namespace internal -} // namespace base
diff --git a/base/task/promise/dependent_list.cc b/base/task/promise/dependent_list.cc index e1c1a0a7..cfe0b7d4 100644 --- a/base/task/promise/dependent_list.cc +++ b/base/task/promise/dependent_list.cc
@@ -4,8 +4,6 @@ #include "base/task/promise/dependent_list.h" -#include "base/task/promise/abstract_promise.h" - namespace base { namespace internal { @@ -19,13 +17,6 @@ DependentList::Node::Node() = default; -DependentList::Node::Node(Node&& other) { - dependent = std::move(other.dependent); - DCHECK_EQ(other.next, nullptr); -} - -DependentList::Node::~Node() = default; - DependentList::InsertResult DependentList::Insert(Node* node) { // This method uses std::memory_order_acquire semantics on read (the failure // case of compare_exchange_weak() below is a read) to ensure setting @@ -92,12 +83,6 @@ return reinterpret_cast<Node*>(prev_head); } -bool DependentList::IsSettled() const { - uintptr_t value = head_.load(std::memory_order_acquire); - return value == kResolvedSentinel || value == kRejectedSentinel || - value == kCanceledSentinel; -} - bool DependentList::IsResolved() const { return head_.load(std::memory_order_acquire) == kResolvedSentinel; } @@ -106,7 +91,7 @@ return head_.load(std::memory_order_acquire) == kRejectedSentinel; } -bool DependentList::IsCanceled() const { +bool DependentList::IsCancelled() const { return head_.load(std::memory_order_acquire) == kCanceledSentinel; }
diff --git a/base/task/promise/dependent_list.h b/base/task/promise/dependent_list.h index 02e80e4..02ab141 100644 --- a/base/task/promise/dependent_list.h +++ b/base/task/promise/dependent_list.h
@@ -10,7 +10,6 @@ #include "base/base_export.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_refptr.h" namespace base { namespace internal { @@ -42,10 +41,9 @@ struct BASE_EXPORT Node { Node(); - explicit Node(Node&& other) noexcept; - ~Node(); - scoped_refptr<AbstractPromise> dependent; + // TODO(alexclarke): Make this a scoped_refptr. + AbstractPromise* dependent; std::atomic<Node*> next{nullptr}; }; @@ -63,10 +61,9 @@ // A ConsumeXXX function may only be called once. Node* ConsumeOnceForCancel(); - bool IsSettled() const; bool IsResolved() const; bool IsRejected() const; - bool IsCanceled() const; + bool IsCancelled() const; private: std::atomic<uintptr_t> head_;
diff --git a/base/task/promise/dependent_list_unittest.cc b/base/task/promise/dependent_list_unittest.cc index 7c3c1e3fc..9df62a29 100644 --- a/base/task/promise/dependent_list_unittest.cc +++ b/base/task/promise/dependent_list_unittest.cc
@@ -13,9 +13,8 @@ DependentList::Node node; EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node)); EXPECT_FALSE(list.IsRejected()); - EXPECT_FALSE(list.IsCanceled()); + EXPECT_FALSE(list.IsCancelled()); EXPECT_FALSE(list.IsResolved()); - EXPECT_FALSE(list.IsSettled()); } TEST(DependentList, ConstructResolved) { @@ -25,8 +24,7 @@ list.Insert(&node)); EXPECT_TRUE(list.IsResolved()); EXPECT_FALSE(list.IsRejected()); - EXPECT_FALSE(list.IsCanceled()); - EXPECT_TRUE(list.IsSettled()); + EXPECT_FALSE(list.IsCancelled()); } TEST(DependentList, ConstructRejected) { @@ -35,9 +33,8 @@ EXPECT_EQ(DependentList::InsertResult::FAIL_PROMISE_REJECTED, list.Insert(&node)); EXPECT_TRUE(list.IsRejected()); - EXPECT_FALSE(list.IsCanceled()); + EXPECT_FALSE(list.IsCancelled()); EXPECT_FALSE(list.IsResolved()); - EXPECT_TRUE(list.IsSettled()); } TEST(DependentList, ConsumeOnceForResolve) { @@ -50,12 +47,10 @@ EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node3)); EXPECT_FALSE(list.IsResolved()); - EXPECT_FALSE(list.IsSettled()); DependentList::Node* result = list.ConsumeOnceForResolve(); EXPECT_TRUE(list.IsResolved()); EXPECT_FALSE(list.IsRejected()); - EXPECT_FALSE(list.IsCanceled()); - EXPECT_TRUE(list.IsSettled()); + EXPECT_FALSE(list.IsCancelled()); EXPECT_EQ(&node3, result); EXPECT_EQ(&node2, result->next.load()); @@ -78,12 +73,10 @@ EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node3)); EXPECT_FALSE(list.IsRejected()); - EXPECT_FALSE(list.IsSettled()); DependentList::Node* result = list.ConsumeOnceForReject(); EXPECT_TRUE(list.IsRejected()); EXPECT_FALSE(list.IsResolved()); - EXPECT_FALSE(list.IsCanceled()); - EXPECT_TRUE(list.IsSettled()); + EXPECT_FALSE(list.IsCancelled()); EXPECT_EQ(&node3, result); EXPECT_EQ(&node2, result->next.load()); @@ -105,13 +98,11 @@ EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node2)); EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node3)); - EXPECT_FALSE(list.IsCanceled()); - EXPECT_FALSE(list.IsSettled()); + EXPECT_FALSE(list.IsCancelled()); DependentList::Node* result = list.ConsumeOnceForCancel(); - EXPECT_TRUE(list.IsCanceled()); + EXPECT_TRUE(list.IsCancelled()); EXPECT_FALSE(list.IsResolved()); EXPECT_FALSE(list.IsRejected()); - EXPECT_TRUE(list.IsSettled()); EXPECT_EQ(&node3, result); EXPECT_EQ(&node2, result->next.load());
diff --git a/base/task/promise/no_op_promise_executor.cc b/base/task/promise/no_op_promise_executor.cc deleted file mode 100644 index 17cffac..0000000 --- a/base/task/promise/no_op_promise_executor.cc +++ /dev/null
@@ -1,67 +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 "base/task/promise/no_op_promise_executor.h" -#include "base/task_runner.h" - -namespace base { -namespace internal { - -NoOpPromiseExecutor::NoOpPromiseExecutor(bool can_resolve, bool can_reject) -#if DCHECK_IS_ON() - : can_resolve_(can_resolve), - can_reject_(can_reject) -#endif -{ -} - -NoOpPromiseExecutor::~NoOpPromiseExecutor() {} - -AbstractPromise::Executor::PrerequisitePolicy -NoOpPromiseExecutor::GetPrerequisitePolicy() { - return PrerequisitePolicy::kNever; -} - -bool NoOpPromiseExecutor::IsCancelled() const { - return false; -} - -#if DCHECK_IS_ON() -AbstractPromise::Executor::ArgumentPassingType -NoOpPromiseExecutor::ResolveArgumentPassingType() const { - return ArgumentPassingType::kNoCallback; -} - -AbstractPromise::Executor::ArgumentPassingType -NoOpPromiseExecutor::RejectArgumentPassingType() const { - return ArgumentPassingType::kNoCallback; -} - -bool NoOpPromiseExecutor::CanResolve() const { - return can_resolve_; -} - -bool NoOpPromiseExecutor::CanReject() const { - return can_reject_; -} -#endif - -void NoOpPromiseExecutor::Execute(AbstractPromise* promise) {} - -// static -scoped_refptr<internal::AbstractPromise> NoOpPromiseExecutor::Create( - Location from_here, - bool can_resolve, - bool can_reject, - RejectPolicy reject_policy) { - return MakeRefCounted<internal::AbstractPromise>( - nullptr, from_here, nullptr, reject_policy, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::NoOpPromiseExecutor>(), - can_resolve, can_reject); -} - -} // namespace internal -} // namespace base
diff --git a/base/task/promise/no_op_promise_executor.h b/base/task/promise/no_op_promise_executor.h deleted file mode 100644 index 9984249..0000000 --- a/base/task/promise/no_op_promise_executor.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 BASE_TASK_PROMISE_NO_OP_PROMISE_EXECUTOR_H_ -#define BASE_TASK_PROMISE_NO_OP_PROMISE_EXECUTOR_H_ - -#include "base/macros.h" -#include "base/task/promise/abstract_promise.h" - -namespace base { -namespace internal { - -// An Executor that doesn't do anything. -class BASE_EXPORT NoOpPromiseExecutor : public AbstractPromise::Executor { - public: - NoOpPromiseExecutor(bool can_resolve, bool can_reject); - - ~NoOpPromiseExecutor() override; - - static scoped_refptr<internal::AbstractPromise> Create( - Location from_here, - bool can_resolve, - bool can_reject, - RejectPolicy reject_policy); - - PrerequisitePolicy GetPrerequisitePolicy() override; - bool IsCancelled() const override; - -#if DCHECK_IS_ON() - ArgumentPassingType ResolveArgumentPassingType() const override; - ArgumentPassingType RejectArgumentPassingType() const override; - bool CanResolve() const override; - bool CanReject() const override; -#endif - void Execute(AbstractPromise* promise) override; - - private: -#if DCHECK_IS_ON() - bool can_resolve_; - bool can_reject_; -#endif -}; - -} // namespace internal -} // namespace base - -#endif // BASE_TASK_PROMISE_NO_OP_PROMISE_EXECUTOR_H_
diff --git a/base/task/promise/small_unique_object.h b/base/task/promise/small_unique_object.h deleted file mode 100644 index d446d035..0000000 --- a/base/task/promise/small_unique_object.h +++ /dev/null
@@ -1,98 +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 BASE_TASK_PROMISE_SMALL_UNIQUE_OBJECT_H_ -#define BASE_TASK_PROMISE_SMALL_UNIQUE_OBJECT_H_ - -#include <cstring> - -#include "base/macros.h" -#include "base/template_util.h" - -namespace base { -namespace internal { - -// A container intended for inline storage of a derived virtual object up to a -// maximum size. This is useful to avoid unnecessary heap allocations. -template <typename T, size_t MaxSize = sizeof(int*) * 3> -class BASE_EXPORT SmallUniqueObject { - public: - SmallUniqueObject() { memset(&union_, 0, sizeof(union_)); } - - template <typename Derived, typename... Args> - SmallUniqueObject(in_place_type_t<Derived>, Args&&... args) noexcept { - static_assert(std::is_base_of<T, Derived>::value, - "T is not a base of Derived"); - static_assert(sizeof(Derived) <= MaxSize, - "Derived is too big to be held by SmallUniqueObject"); - static_assert(sizeof(T) <= MaxSize, - "T is too big to be held by SmallUniqueObject"); - new (union_.storage) Derived(std::forward<Args>(args)...); - } - - ~SmallUniqueObject() { reset(); } - - explicit operator bool() const { return !Empty(); } - - bool Empty() const { - for (size_t i = 0; i < kMaxInts; i++) { - if (union_.flag[i]) - return false; - } - return true; - } - - void reset() { - if (!Empty()) { - get()->~T(); - memset(&union_, 0, sizeof(union_)); - } - } - - T* get() noexcept { - if (Empty()) - return nullptr; - return reinterpret_cast<T*>(union_.storage); - } - - const T* get() const noexcept { - if (Empty()) - return nullptr; - return reinterpret_cast<const T*>(union_.storage); - } - - const T& operator*() const { - DCHECK(!Empty()); - return *get(); - } - - T& operator*() { - DCHECK(!Empty()); - return *get(); - } - - const T* operator->() const noexcept { - DCHECK(!Empty()); - return get(); - } - - T* operator->() noexcept { - DCHECK(!Empty()); - return get(); - } - - private: - static constexpr size_t kMaxInts = MaxSize / sizeof(int); - union { - // The vtable will be stored somewhere within |storage|, the actual location - // is compiler specific but where ever it is, it can't be zero. - int flag[kMaxInts]; - char storage[MaxSize]; - } union_; -}; - -} // namespace internal -} // namespace base - -#endif // BASE_TASK_PROMISE_SMALL_UNIQUE_OBJECT_H_
diff --git a/base/task_runner.cc b/base/task_runner.cc index 0bd9ba99..73130163 100644 --- a/base/task_runner.cc +++ b/base/task_runner.cc
@@ -6,10 +6,8 @@ #include <utility> -#include "base/bind.h" #include "base/compiler_specific.h" #include "base/logging.h" -#include "base/task/promise/abstract_promise.h" #include "base/threading/post_task_and_reply_impl.h" namespace base { @@ -53,14 +51,6 @@ from_here, std::move(task), std::move(reply)); } -bool TaskRunner::PostPromiseInternal( - const scoped_refptr<internal::AbstractPromise>& promise, - base::TimeDelta delay) { - return PostDelayedTask( - promise->from_here(), - BindOnce(&internal::AbstractPromise::Execute, std::move(promise)), delay); -} - TaskRunner::TaskRunner() = default; TaskRunner::~TaskRunner() = default;
diff --git a/base/task_runner.h b/base/task_runner.h index 468e1383..1d302ab0 100644 --- a/base/task_runner.h +++ b/base/task_runner.h
@@ -15,10 +15,6 @@ namespace base { -namespace internal { -class AbstractPromise; -} // namespace internal - struct TaskRunnerTraits; // A TaskRunner is an object that runs posted tasks (in the form of @@ -137,12 +133,6 @@ OnceClosure task, OnceClosure reply); - // TODO(alexclarke): This should become pure virtual and replace - // PostDelayedTask. NB passing by reference to reduce binary size. - bool PostPromiseInternal( - const scoped_refptr<internal::AbstractPromise>& promise, - base::TimeDelta delay); - protected: friend struct TaskRunnerTraits;
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index 02e2708..1d20e94e 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -51,8 +51,6 @@ "bind_test_util.h", "copy_only_int.cc", "copy_only_int.h", - "do_nothing_promise.cc", - "do_nothing_promise.h", "fuzzed_data_provider.h", "gtest_util.cc", "gtest_util.h",
diff --git a/base/test/do_nothing_promise.cc b/base/test/do_nothing_promise.cc deleted file mode 100644 index 6b4709ae..0000000 --- a/base/test/do_nothing_promise.cc +++ /dev/null
@@ -1,15 +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 "base/test/do_nothing_promise.h" - -namespace base { - -DoNothingPromiseBuilder::operator scoped_refptr<internal::AbstractPromise>() - const { - return internal::NoOpPromiseExecutor::Create(from_here, can_resolve, - can_reject, reject_policy); -} - -} // namespace base
diff --git a/base/test/do_nothing_promise.h b/base/test/do_nothing_promise.h deleted file mode 100644 index 202d623..0000000 --- a/base/test/do_nothing_promise.h +++ /dev/null
@@ -1,41 +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 BASE_TEST_DO_NOTHING_PROMISE_H_ -#define BASE_TEST_DO_NOTHING_PROMISE_H_ - -#include "base/task/promise/no_op_promise_executor.h" - -namespace base { - -// Creates a promise whose executor doesn't do anything. -struct DoNothingPromiseBuilder { - explicit DoNothingPromiseBuilder(Location from_here) : from_here(from_here) {} - - const Location from_here; - bool can_resolve = false; - bool can_reject = false; - RejectPolicy reject_policy = RejectPolicy::kMustCatchRejection; - - DoNothingPromiseBuilder& SetCanResolve(bool can_resolve) { - this->can_resolve = can_resolve; - return *this; - } - - DoNothingPromiseBuilder& SetCanReject(bool can_reject) { - this->can_reject = can_reject; - return *this; - } - - DoNothingPromiseBuilder& SetRejectPolicy(RejectPolicy reject_policy) { - this->reject_policy = reject_policy; - return *this; - } - - operator scoped_refptr<internal::AbstractPromise>() const; -}; - -} // namespace base - -#endif // BASE_TEST_DO_NOTHING_PROMISE_H_
diff --git a/base/threading/thread_restrictions.cc b/base/threading/thread_restrictions.cc index b5397f6d..0f33688 100644 --- a/base/threading/thread_restrictions.cc +++ b/base/threading/thread_restrictions.cc
@@ -6,60 +6,25 @@ #if DCHECK_IS_ON() -#include "base/debug/stack_trace.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/threading/thread_local.h" -#include "build/build_config.h" namespace base { namespace { -#if defined(OS_NACL) -using ThreadLocalBooleanWithStacks = ThreadLocalBoolean; -#else -class ThreadLocalBooleanWithStacks { - public: - ThreadLocalBooleanWithStacks() = default; - - bool Get() const { return bool_.Get(); } - - void Set(bool val) { - stack_.Set(std::make_unique<debug::StackTrace>()); - bool_.Set(val); - } - - friend std::ostream& operator<<(std::ostream& out, - const ThreadLocalBooleanWithStacks& tl) { - out << "currently set to " << (tl.bool_.Get() ? "true" : "false") << " by "; - - if (!tl.stack_.Get()) - return out << "default value\n"; - out << "\n"; - tl.stack_.Get()->OutputToStream(&out); - return out; - } - - private: - ThreadLocalBoolean bool_; - ThreadLocalOwnedPointer<debug::StackTrace> stack_; - - DISALLOW_COPY_AND_ASSIGN(ThreadLocalBooleanWithStacks); -}; -#endif // defined(OS_NACL) - -LazyInstance<ThreadLocalBooleanWithStacks>::Leaky g_blocking_disallowed = +LazyInstance<ThreadLocalBoolean>::Leaky g_blocking_disallowed = LAZY_INSTANCE_INITIALIZER; -LazyInstance<ThreadLocalBooleanWithStacks>::Leaky g_singleton_disallowed = +LazyInstance<ThreadLocalBoolean>::Leaky + g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER; + +LazyInstance<ThreadLocalBoolean>::Leaky g_base_sync_primitives_disallowed = LAZY_INSTANCE_INITIALIZER; -LazyInstance<ThreadLocalBooleanWithStacks>::Leaky - g_base_sync_primitives_disallowed = LAZY_INSTANCE_INITIALIZER; - -LazyInstance<ThreadLocalBooleanWithStacks>::Leaky - g_cpu_intensive_work_disallowed = LAZY_INSTANCE_INITIALIZER; +LazyInstance<ThreadLocalBoolean>::Leaky g_cpu_intensive_work_disallowed = + LAZY_INSTANCE_INITIALIZER; } // namespace @@ -71,11 +36,7 @@ "blocking! If this task is running inside the ThreadPool, it needs " "to have MayBlock() in its TaskTraits. Otherwise, consider making " "this blocking work asynchronous or, as a last resort, you may use " - "ScopedAllowBlocking (see its documentation for best practices).\n" -#if !defined(OS_NACL) - << "g_blocking_disallowed " << g_blocking_disallowed.Get() -#endif - ; + "ScopedAllowBlocking (see its documentation for best practices)."; } } // namespace internal @@ -112,11 +73,7 @@ : was_disallowed_(g_base_sync_primitives_disallowed.Get().Get()) { DCHECK(!g_blocking_disallowed.Get().Get()) << "To allow //base sync primitives in a scope where blocking is " - "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope.\n" -#if !defined(OS_NACL) - << "g_blocking_disallowed " << g_blocking_disallowed.Get() -#endif - ; + "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope."; g_base_sync_primitives_disallowed.Get().Set(false); } @@ -157,14 +114,7 @@ "prevent jank and deadlock. If waiting on a //base sync primitive is " "unavoidable, do it within the scope of a " "ScopedAllowBaseSyncPrimitives. If in a test, " - "use ScopedAllowBaseSyncPrimitivesForTesting.\n" -#if !defined(OS_NACL) - << "g_base_sync_primitives_disallowed " - << g_base_sync_primitives_disallowed.Get() - << "It can be useful to know that g_blocking_disallowed is " - << g_blocking_disallowed.Get() -#endif - ; + "use ScopedAllowBaseSyncPrimitivesForTesting."; } void ResetThreadRestrictionsForTesting() { @@ -179,13 +129,7 @@ void AssertLongCPUWorkAllowed() { DCHECK(!g_cpu_intensive_work_disallowed.Get().Get()) << "Function marked as CPU intensive was called from a scope that " - "disallows this kind of work! Consider making this work " - "asynchronous.\n" -#if !defined(OS_NACL) - << "g_cpu_intensive_work_disallowed " - << g_cpu_intensive_work_disallowed.Get() -#endif - ; + "disallows this kind of work! Consider making this work asynchronous."; } void DisallowUnresponsiveTasks() { @@ -217,18 +161,16 @@ // static void ThreadRestrictions::AssertSingletonAllowed() { - DCHECK(!g_singleton_disallowed.Get().Get()) - << "LazyInstance/Singleton is not allowed to be used on this thread. " - "Most likely it's because this thread is not joinable (or the current " - "task is running with TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN " - "semantics), so AtExitManager may have deleted the object on " - "shutdown, leading to a potential shutdown crash. If you need to use " - "the object from this context, it'll have to be updated to use Leaky " - "traits.\n" -#if !defined(OS_NACL) - << "g_singleton_disallowed " << g_singleton_disallowed.Get() -#endif - ; + if (g_singleton_disallowed.Get().Get()) { + NOTREACHED() << "LazyInstance/Singleton is not allowed to be used on this " + << "thread. Most likely it's because this thread is not " + << "joinable (or the current task is running with " + << "TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN semantics), so " + << "AtExitManager may have deleted the object on shutdown, " + << "leading to a potential shutdown crash. If you need to use " + << "the object from this context, it'll have to be updated to " + << "use Leaky traits."; + } } // static
diff --git a/base/util/BUILD.gn b/base/util/BUILD.gn new file mode 100644 index 0000000..c3b1942c --- /dev/null +++ b/base/util/BUILD.gn
@@ -0,0 +1,12 @@ +# Copyright (c) 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("//testing/test.gni") + +test("base_util_unittests") { + deps = [ + "type-safety:tests", + "//base/test:run_all_base_unittests", + ] +}
diff --git a/base/util/type-safety/BUILD.gn b/base/util/type-safety/BUILD.gn new file mode 100644 index 0000000..8b7b05e --- /dev/null +++ b/base/util/type-safety/BUILD.gn
@@ -0,0 +1,26 @@ +# Copyright (c) 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("//build/config/jumbo.gni") + +# Change this target's type to jumbo_component if it starts to contain more than +# just headers. Header-only targets cannot be compiled to libraries, so it must +# remain a source_set for now. +source_set("type-safety") { + sources = [ + "id_type.h", + ] +} + +source_set("tests") { + testonly = true + sources = [ + "id_type_unittest.cc", + ] + + deps = [ + ":type-safety", + "//testing/gtest", + ] +}
diff --git a/base/util/type-safety/DEPS b/base/util/type-safety/DEPS new file mode 100644 index 0000000..d8f89b0 --- /dev/null +++ b/base/util/type-safety/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "-base", + "+base/util/type-safety", + "-third_party", +]
diff --git a/base/util/type-safety/OWNERS b/base/util/type-safety/OWNERS new file mode 100644 index 0000000..3889b827 --- /dev/null +++ b/base/util/type-safety/OWNERS
@@ -0,0 +1,2 @@ +lukasza@chromium.com +mpawlowski@opera.com
diff --git a/gpu/command_buffer/common/id_type.h b/base/util/type-safety/id_type.h similarity index 95% rename from gpu/command_buffer/common/id_type.h rename to base/util/type-safety/id_type.h index e3efbfa..2563139 100644 --- a/gpu/command_buffer/common/id_type.h +++ b/base/util/type-safety/id_type.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef GPU_COMMAND_BUFFER_COMMON_ID_TYPE_H_ -#define GPU_COMMAND_BUFFER_COMMON_ID_TYPE_H_ +#ifndef BASE_UTIL_TYPE_SAFETY_ID_TYPE_H_ +#define BASE_UTIL_TYPE_SAFETY_ID_TYPE_H_ #include <stdint.h> #include <cstddef> @@ -43,7 +43,7 @@ // - it ensures initialization to zero and allows checking against // default-initialized values via is_null method. -namespace gpu { +namespace util { template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> class IdType { @@ -104,6 +104,6 @@ return stream << id.GetUnsafeValue(); } -} // namespace gpu +} // namespace util -#endif // CONTENT_COMMON_ID_TYPE_H_ +#endif // BASE_UTIL_TYPE_SAFETY_ID_TYPE_H_
diff --git a/gpu/command_buffer/common/id_type_unittest.cc b/base/util/type-safety/id_type_unittest.cc similarity index 98% rename from gpu/command_buffer/common/id_type_unittest.cc rename to base/util/type-safety/id_type_unittest.cc index a8f0b349..9320951 100644 --- a/gpu/command_buffer/common/id_type_unittest.cc +++ b/base/util/type-safety/id_type_unittest.cc
@@ -9,10 +9,10 @@ #include <type_traits> #include <unordered_map> -#include "gpu/command_buffer/common/id_type.h" +#include "base/util/type-safety/id_type.h" #include "testing/gtest/include/gtest/gtest.h" -namespace gpu { +namespace util { namespace { @@ -197,4 +197,4 @@ 123, std::numeric_limits<int>::max())); -} // namespace gpu +} // namespace util
diff --git a/build/android/gyp/compile_resources.py b/build/android/gyp/compile_resources.py index 3766bbb..350c215 100755 --- a/build/android/gyp/compile_resources.py +++ b/build/android/gyp/compile_resources.py
@@ -155,6 +155,15 @@ '--no-xml-namespaces', action='store_true', help='Whether to strip xml namespaces from processed xml resources.') + input_opts.add_argument( + '--short-resource-paths', + action='store_true', + help='Whether to shorten resource paths inside the apk or module.') + input_opts.add_argument( + '--strip-resource-names', + action='store_true', + help='Whether to strip resource names from the resource table of the apk ' + 'or module.') output_opts.add_argument('--arsc-path', help='Apk output for arsc format.') output_opts.add_argument('--proto-path', help='Apk output for proto format.') @@ -187,6 +196,11 @@ output_opts.add_argument( '--emit-ids-out', help='Path to file produced by aapt2 --emit-ids.') + output_opts.add_argument( + '--resources-path-map-out-path', + help='Path to file produced by aapt2 that maps original resource paths ' + 'to shortened resource paths inside the apk or module.') + options = parser.parse_args(args) resource_utils.HandleCommonOptions(options) @@ -204,6 +218,10 @@ if not options.arsc_path and not options.proto_path: parser.error('One of --arsc-path or --proto-path is required.') + if options.resources_path_map_out_path and not options.short_resource_paths: + parser.error( + '--resources-path-map-out-path requires --short-resource-paths') + if options.package_name_to_id_mapping: package_names_list = build_utils.ParseGnList( options.package_name_to_id_mapping) @@ -732,30 +750,42 @@ unoptimized_path: path of the apk to optimize. r_txt_path: path to the R.txt file of the unoptimized apk. """ - # Resources of type ID are references to UI elements/views. They are used by - # UI automation testing frameworks. They are kept in so that they dont break - # tests, even though they may not actually be used during runtime. See - # https://crbug.com/900993 - id_resources = _ExtractIdResources(r_txt_path) - gen_config_path = os.path.join(temp_dir, 'aapt2.config') - if options.resources_config_path: - shutil.copyfile(options.resources_config_path, gen_config_path) - with open(gen_config_path, 'a+') as config: - for resource in id_resources: - config.write('{}#no_obfuscate\n'.format(resource)) - - # Optimize the resources.arsc file by obfuscating resource names and only - # allow usage via R.java constant. optimize_command = [ options.aapt2_path, 'optimize', - '--enable-resource-obfuscation', + unoptimized_path, '-o', output, - '--resources-config-path', - gen_config_path, - unoptimized_path, ] + + # Optimize the resources.arsc file by obfuscating resource names and only + # allow usage via R.java constant. + if options.strip_resource_names: + # Resources of type ID are references to UI elements/views. They are used by + # UI automation testing frameworks. They are kept in so that they dont break + # tests, even though they may not actually be used during runtime. See + # https://crbug.com/900993 + id_resources = _ExtractIdResources(r_txt_path) + gen_config_path = os.path.join(temp_dir, 'aapt2.config') + if options.resources_config_path: + shutil.copyfile(options.resources_config_path, gen_config_path) + with open(gen_config_path, 'a+') as config: + for resource in id_resources: + config.write('{}#no_obfuscate\n'.format(resource)) + + optimize_command += [ + '--enable-resource-obfuscation', + '--resources-config-path', + gen_config_path, + ] + + if options.short_resource_paths: + optimize_command += ['--enable-resource-path-shortening'] + if options.resources_path_map_out_path: + optimize_command += [ + '--resource-path-shortening-map', options.resources_path_map_out_path + ] + build_utils.CheckOutput( optimize_command, print_stdout=False, print_stderr=False)
diff --git a/build/android/gyp/create_app_bundle.py b/build/android/gyp/create_app_bundle.py index b7b5106f..344990b 100755 --- a/build/android/gyp/create_app_bundle.py +++ b/build/android/gyp/create_app_bundle.py
@@ -66,6 +66,12 @@ parser.add_argument('--module-zips', required=True, help='GN-list of module zip archives.') parser.add_argument( + '--pathmap-in-paths', + action='append', + help='GN-list of module pathmap files.') + parser.add_argument( + '--pathmap-out-path', help='Path to combined pathmap file for bundle.') + parser.add_argument( '--rtxt-in-paths', action='append', help='GN-list of module R.txt files.') parser.add_argument( '--rtxt-out-path', help='Path to combined R.txt file for bundle.') @@ -94,7 +100,8 @@ options = parser.parse_args(args) options.module_zips = build_utils.ParseGnList(options.module_zips) - options.rtxt_in_paths = build_utils.ExpandFileArgs(options.rtxt_in_paths) + options.rtxt_in_paths = build_utils.ParseGnList(options.rtxt_in_paths) + options.pathmap_in_paths = build_utils.ParseGnList(options.pathmap_in_paths) if len(options.module_zips) == 0: raise Exception('The module zip list cannot be empty.') @@ -301,6 +308,25 @@ return ids_map.keys() +def _ConcatTextFiles(in_paths, out_path): + """Concatenate the contents of multiple text files into one. + + The each file contents is preceded by a line containing the original filename. + + Args: + in_paths: List of input file paths. + out_path: Path to output file. + """ + with open(out_path, 'w') as out_file: + for in_path in in_paths: + if not os.path.exists(in_path): + continue + with open(in_path, 'r') as in_file: + out_file.write('-- Contents of {}\n'.format(os.path.basename(in_path))) + out_file.write(in_file.read()) + + + def main(args): args = build_utils.ExpandFileArgs(args) options = _ParseArgs(args) @@ -362,12 +388,10 @@ shutil.move(tmp_bundle, options.out_bundle) if options.rtxt_out_path: - with open(options.rtxt_out_path, 'w') as rtxt_out: - for rtxt_in_path in options.rtxt_in_paths: - with open(rtxt_in_path, 'r') as rtxt_in: - rtxt_out.write('-- Contents of {}\n'.format( - os.path.basename(rtxt_in_path))) - rtxt_out.write(rtxt_in.read()) + _ConcatTextFiles(options.rtxt_in_paths, options.rtxt_out_path) + + if options.pathmap_out_path: + _ConcatTextFiles(options.pathmap_in_paths, options.pathmap_out_path) if __name__ == '__main__':
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index f097a4f..cb379cc 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -460,6 +460,10 @@ The path of the R.txt file generated when compiling the resources for the bundle module. +* `deps_info['module_pathmap_path']`: +The path of the pathmap file generated when compiling the resources for the +bundle module, if resource path shortening is enabled. + * `deps_info['base_whitelist_rtxt_path']`: Optional path to an R.txt file used as a whitelist for base string resources. This means that any string resource listed in this file *and* in @@ -954,6 +958,9 @@ help='Path to resources compiled in protocol buffer format ' ' for this apk.') parser.add_option( + '--module-pathmap-path', + help='Path to pathmap file for resource paths in a bundle module.') + parser.add_option( '--module-rtxt-path', help='Path to R.txt file for resources in a bundle module.') parser.add_option( @@ -1023,6 +1030,9 @@ if options.module_rtxt_path: raise Exception('--module-rxt-path can only be used with ' '--type=android_app_bundle_module') + if options.module_pathmap_path: + raise Exception('--module-pathmap-path can only be used with ' + '--type=android_app_bundle_module') if options.base_whitelist_rtxt_path: raise Exception('--base-whitelist-rtxt-path can only be used with ' '--type=android_app_bundle_module') @@ -1168,6 +1178,15 @@ if options.module_rtxt_path: deps_info['module_rtxt_path'] = options.module_rtxt_path + + if options.module_pathmap_path: + deps_info['module_pathmap_path'] = options.module_pathmap_path + else: + # Ensure there is an entry, even if it is empty, for modules + # that have not enabled resource path shortening. Otherwise + # build_utils.ExpandFileArgs fails. + deps_info['module_pathmap_path'] = '' + if options.base_whitelist_rtxt_path: deps_info['base_whitelist_rtxt_path'] = options.base_whitelist_rtxt_path else:
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 5c12c8a3..b01289a 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -332,6 +332,11 @@ _rebased_rtxt_path = rebase_path(invoker.module_rtxt_path, root_build_dir) args += [ "--module-rtxt-path=$_rebased_rtxt_path" ] } + if (defined(invoker.module_pathmap_path)) { + _rebased_pathmap_path = + rebase_path(invoker.module_pathmap_path, root_build_dir) + args += [ "--module-pathmap-path=$_rebased_pathmap_path" ] + } if (defined(invoker.shared_libraries_runtime_deps_file)) { # Don't list shared_libraries_runtime_deps_file as an input in order to @@ -2151,6 +2156,13 @@ # Use resource IDs provided by another APK target when compiling resources # (via. "aapt2 link --stable-ids") # + # short_resource_paths: (optional) + # Rename the paths within a the apk to be randomly generated short + # strings to reduce binary size. + # + # strip_resource_names: (optional) + # Strip resource names from the resources table of the apk. + # # Output variables: # arsc_output: Path to output .ap_ file (optional). # @@ -2163,6 +2175,10 @@ # r_text_out_path: (optional): # Path for the corresponding generated R.txt file. # + # resources_path_map_out_path: (optional): + # Path for the generated map between original resource paths and + # shortend resource paths. + # # srcjar_path: (optional) # Path to a generated .srcjar containing the generated R.java sources # for all dependent resource libraries. @@ -2299,6 +2315,21 @@ rebase_path(invoker.resources_config_path, root_build_dir), ] } + if (defined(invoker.short_resource_paths) && + invoker.short_resource_paths) { + args += [ "--short-resource-paths" ] + if (defined(invoker.resources_path_map_out_path)) { + outputs += [ invoker.resources_path_map_out_path ] + args += [ + "--resources-path-map-out-path", + rebase_path(invoker.resources_path_map_out_path, root_build_dir), + ] + } + } + if (defined(invoker.strip_resource_names) && + invoker.strip_resource_names) { + args += [ "--strip-resource-names" ] + } # Useful to have android:debuggable in the manifest even for Release # builds. Just omit it for officai @@ -3209,6 +3240,8 @@ # binary xml + resources.arsc). # module_rtxt_path: The path of the R.txt file generated when compiling the # resources for the bundle module. + # module_pathmap_path: The path of the pathmap file generated when compiling + # the resources for the bundle module, if path shortening is enabled. # base_whitelist_rtxt_path: The path of the R.txt file containing the # list of string resources to keep in the base split APK for any bundle # that uses this target. @@ -3448,6 +3481,7 @@ [ "base_module_target", "is_base_module", + "module_pathmap_path", "module_rtxt_path", "proto_resources_path", ])
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 2436de0..351ae1f 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2039,8 +2039,10 @@ # uncompressed in the APK. Must be unset or true if load_library_from_apk # is set to true. # uncompress_dex: Store final .dex files uncompressed in the apk. - # optimize_resources: True if resource names should be stripped from the + # strip_resource_names: True if resource names should be stripped from the # resources.arsc file in the apk or module. + # short_resource_paths: True if resource paths should be shortened in the + # apk or module. # resources_config_path: Path to the aapt2 optimize config file that tags # resources with acceptable/non-acceptable optimizations. # verify_manifest: Enables verification of expected merged manifest based @@ -2099,6 +2101,16 @@ if (!_is_bundle_module) { _final_rtxt_path = "${_final_apk_path}.R.txt" } + + _short_resource_paths = + defined(invoker.short_resource_paths) && invoker.short_resource_paths + _strip_resource_names = + defined(invoker.strip_resource_names) && invoker.strip_resource_names + _optimize_resources = _strip_resource_names || _short_resource_paths + + if (!_is_bundle_module && _short_resource_paths) { + _final_pathmap_path = "${_final_apk_path}.pathmap.txt" + } _res_size_info_path = "$target_out_dir/$target_name.ap_.info" _final_apk_path_no_ext_list = process_file_template([ _final_apk_path ], @@ -2106,9 +2118,6 @@ _final_apk_path_no_ext = _final_apk_path_no_ext_list[0] assert(_final_apk_path_no_ext != "") # Mark as used. - _optimize_resources = - defined(invoker.optimize_resources) && invoker.optimize_resources - # Non-base bundle modules create only proto resources. if (!_is_bundle_module || _is_base_module) { _arsc_resources_path = "$target_out_dir/$target_name.ap_" @@ -2366,6 +2375,11 @@ "${invoker.shared_resources_whitelist_target}__compile_resources" } + if (_short_resource_paths) { + _resources_path_map_out_path = + "${target_gen_dir}/${_template_name}_resources_path_map.txt" + } + _compile_resources_target = "${_template_name}__compile_resources" _compile_resources_rtxt_out = "${target_gen_dir}/${_compile_resources_target}_R.txt" @@ -2384,6 +2398,8 @@ "resource_blacklist_regex", "resources_config_path", "shared_resources", + "short_resource_paths", + "strip_resource_names", "shared_resources_whitelist_locales", "support_zh_hk", ]) @@ -2406,6 +2422,9 @@ if (_enable_main_dex_list) { proguard_file_main_dex = _generated_proguard_main_dex_config } + if (_short_resource_paths) { + resources_path_map_out_path = _resources_path_map_out_path + } build_config = _build_config deps = _deps + [ @@ -2504,6 +2523,23 @@ ] } _final_deps += [ ":$_copy_rtxt_target" ] + + if (_short_resource_paths) { + # Do the same for path map + _copy_pathmap_target = "${_template_name}__copy_pathmap" + copy(_copy_pathmap_target) { + deps = [ + ":$_compile_resources_target", + ] + sources = [ + _resources_path_map_out_path, + ] + outputs = [ + _final_pathmap_path, + ] + } + _final_deps += [ ":$_copy_pathmap_target" ] + } } _srcjar_deps += [ ":$_compile_resources_target" ] @@ -2682,6 +2718,12 @@ if (_is_bundle_module) { proto_resources_path = _proto_resources_path module_rtxt_path = _compile_resources_rtxt_out + if (_optimize_resources) { + proto_resources_path = _optimized_proto_resources_path + if (_short_resource_paths) { + module_pathmap_path = _resources_path_map_out_path + } + } } else { apk_path = _final_apk_path incremental_allowed = _incremental_allowed @@ -2972,9 +3014,7 @@ ]) packaged_resources_path = _arsc_resources_path - if (_optimize_resources && _is_bundle_module) { - optimized_resources_path = _optimized_proto_resources_path - } else if (_optimize_resources) { + if (_optimize_resources) { optimized_resources_path = _optimized_arsc_resources_path } @@ -3250,7 +3290,7 @@ "never_incremental", "no_build_hooks", "no_xml_namespaces", - "optimize_resources", + "strip_resource_names", "png_to_webp", "post_process_package_resources_script", "product_version_resources_dep", @@ -3268,6 +3308,7 @@ "shared_resources", "shared_resources_whitelist_locales", "shared_resources_whitelist_target", + "short_resource_paths", "srcjar_deps", "static_library_dependent_targets", "static_library_provider", @@ -3362,7 +3403,6 @@ "native_lib_version_rule", "negative_main_dex_globs", "no_xml_namespaces", - "optimize_resources", "package_name", "package_name_to_id_mapping", "png_to_webp", @@ -3379,6 +3419,8 @@ "shared_resources", "shared_resources_whitelist_locales", "shared_resources_whitelist_target", + "strip_resource_names", + "short_resource_paths", "srcjar_deps", "static_library_provider", "support_zh_hk", @@ -4559,6 +4601,7 @@ args = [ "--out-bundle=$_rebased_bundle_path", "--rtxt-out-path=$_rebased_bundle_path.R.txt", + "--pathmap-out-path=$_rebased_bundle_path.pathmap.txt", "--module-zips=$_all_rebased_module_zip_paths", ] if (_sign_bundle) { @@ -4593,6 +4636,8 @@ "$_rebased_build_config:uncompressed_assets)", "--rtxt-in-paths=@FileArg(" + "$_rebased_build_config:deps_info:module_rtxt_path)", + "--pathmap-in-paths=@FileArg(" + + "$_rebased_build_config:deps_info:module_pathmap_path)", ] } }
diff --git a/build/extract_partition.py b/build/extract_partition.py index 2e72773..52607c8 100755 --- a/build/extract_partition.py +++ b/build/extract_partition.py
@@ -35,7 +35,7 @@ objcopy_args = [args.objcopy] if args.partition: - objcopy_args += ['--extract-partition', args.extract_partition] + objcopy_args += ['--extract-partition', args.partition] else: objcopy_args += ['--extract-main-partition'] objcopy_args += [args.input, args.unstripped_output]
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index cf9b921..f2d5f73 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8913958623180868512 \ No newline at end of file +8913928381394866528 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index f8a7b3c0a..2632e4e 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8913966693334837136 \ No newline at end of file +8913934899603518544 \ No newline at end of file
diff --git a/build/partitioned_shared_library.gni b/build/partitioned_shared_library.gni index 7c48e93..33b7f1c 100644 --- a/build/partitioned_shared_library.gni +++ b/build/partitioned_shared_library.gni
@@ -90,8 +90,11 @@ "--stripped-output", rebase_path(invoker.stripped_output, root_build_dir), ] - if (defined(partition) && partition != "") { - args += [ "--partition', lib${partition}.so" ] + if (defined(invoker.partition) && invoker.partition != "") { + args += [ + "--partition", + "lib${invoker.partition}.so", + ] } args += [ rebase_path(sources[0], root_build_dir) ] }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 56c066a..dacca1a5 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2437,7 +2437,6 @@ "java/src/org/chromium/chrome/browser/content/ContentUtils.java", "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java", "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPreferenceHelper.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 3e6f22d..f2e43f9 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -301,29 +301,6 @@ "java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuPagerAdapter.java", "java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java", "java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuViewPager.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContentCoordinator.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionCardViewHolder.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBottomSheetContent.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEnabledStateUtils.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEventReporter.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModule.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSource.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImpl.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorImpl.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimer.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/PeekConditions.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarCoordinator.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarView.java", - "java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarViewBinder.java", "java/src/org/chromium/chrome/browser/contextualsearch/BarOverlapTapSuppression.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchEntityHeuristic.java", @@ -1215,7 +1192,6 @@ "java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java", "java/src/org/chromium/chrome/browser/preferences/ChromeSwitchPreference.java", "java/src/org/chromium/chrome/browser/preferences/ClearBrowsingDataCheckBoxPreference.java", - "java/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreference.java", "java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java", "java/src/org/chromium/chrome/browser/preferences/HomepageEditor.java", "java/src/org/chromium/chrome/browser/preferences/HomepagePreferences.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index c7229d5..8bcc72b 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -32,7 +32,6 @@ "junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityDisclosureControllerTest.java", "junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityOpenTimeRecorderTest.java", "junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifierTest.java", - "junit/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImplTest.java", "junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerImplTest.java", "junit/src/org/chromium/chrome/browser/compositor/EventOffsetHandlerTest.java", "junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java", @@ -40,9 +39,6 @@ "junit/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutUpdateHost.java", "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java", "junit/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java", - "junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java", - "junit/src/org/chromium/chrome/browser/contextual_suggestions/GoogleSearchRestrictionTest.java", - "junit/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimerTest.java", "junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContextForTest.java", "junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContextTest.java", "junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchEntityHeuristicTest.java",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 3fff66ec..b9f7a1f 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -143,7 +143,10 @@ support_zh_hk = true } - optimize_resources = true + strip_resource_names = true + + # TODO(753402): enable once aapt2>=3.6.0 and bundletool>0.9.0 are rolled in. + short_resource_paths = false if (defined(shared_libraries) && shared_libraries != []) { _native_lib_file =
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 5f2e94a..bfd42c4 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -85,10 +85,6 @@ "javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java", "javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java", "javatests/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUiTest.java", - "javatests/src/org/chromium/chrome/browser/contextual_suggestions/EmptyEnabledStateMonitor.java", - "javatests/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorTest.java", - "javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java", - "javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeTracker.java", "javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java", "javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInternalStateControllerWrapper.java", "javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java", @@ -369,7 +365,6 @@ "javatests/src/org/chromium/chrome/browser/photo_picker/DecoderServiceTest.java", "javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java", "javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java", - "javatests/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreferenceTest.java", "javatests/src/org/chromium/chrome/browser/preferences/NotificationsPreferencesTest.java", "javatests/src/org/chromium/chrome/browser/preferences/PasswordViewingTypeTest.java", "javatests/src/org/chromium/chrome/browser/preferences/PreferencesTest.java",
diff --git a/chrome/android/java/res/drawable-hdpi/contextual_suggestions.png b/chrome/android/java/res/drawable-hdpi/contextual_suggestions.png deleted file mode 100644 index ee61bfa..0000000 --- a/chrome/android/java/res/drawable-hdpi/contextual_suggestions.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/contextual_suggestions.png b/chrome/android/java/res/drawable-mdpi/contextual_suggestions.png deleted file mode 100644 index 914e78e0..0000000 --- a/chrome/android/java/res/drawable-mdpi/contextual_suggestions.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/contextual_suggestions.png b/chrome/android/java/res/drawable-xhdpi/contextual_suggestions.png deleted file mode 100644 index 50251ca..0000000 --- a/chrome/android/java/res/drawable-xhdpi/contextual_suggestions.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/contextual_suggestions.png b/chrome/android/java/res/drawable-xxhdpi/contextual_suggestions.png deleted file mode 100644 index 7118193..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/contextual_suggestions.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/contextual_suggestions.png b/chrome/android/java/res/drawable-xxxhdpi/contextual_suggestions.png deleted file mode 100644 index af4d207..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/contextual_suggestions.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml b/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml deleted file mode 100644 index b74bdb8..0000000 --- a/chrome/android/java/res/drawable/contextual_suggestions_placeholder_thumbnail.xml +++ /dev/null
@@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2018 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid - android:color="@color/thumbnail_placeholder_on_primary_bg" /> - <corners - android:radius="@dimen/default_rounded_corner_radius" /> -</shape> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml b/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml deleted file mode 100644 index 0b597bf..0000000 --- a/chrome/android/java/res/layout/contextual_suggestions_card_modern.xml +++ /dev/null
@@ -1,103 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2018 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<RelativeLayout - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - style="@style/SuggestionCardModern" - android:background="@drawable/hairline_border_card_background" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:padding="@dimen/snippets_padding"> - - <LinearLayout - tools:ignore="UseCompoundDrawables" - android:id="@+id/publisher_bar" - android:layout_alignParentTop="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/contextual_suggestions_publisher_margin" - android:orientation="horizontal"> - - <!-- The following attributes: - - publisher_bar's android:layout_width="wrap_content" - - article_publisher's android:layout_width="0dp" - - article_publisher's android:layout_weight="1" - - article_publisher's android:ellipsize="end" - - article_age's android:layout_width="wrap_content" - All ensure that when the publisher string is long, it starts to ellipsize - before pushing the article age string and the offline icon off the screen. - See: https://crbug.com/625775 and https://crbug.com/678568 --> - <TextView - android:id="@+id/article_publisher" - android:layout_width="0dp" - android:layout_weight="1" - android:layout_height="wrap_content" - android:drawablePadding="8dp" - android:maxLines="1" - android:singleLine="true" - android:ellipsize="end" - android:textAppearance="@style/TextAppearance.BlackCaption" - android:textDirection="locale" - tools:text="chromium.org"/> - - <TextView - android:id="@+id/article_age" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="1" - android:textAppearance="@style/TextAppearance.BlackCaption" - android:textDirection="locale" - tools:text=" - 3 hours ago" /> - - <!-- We can't add this ImageView as a CompoundDrawable to the TextView because we want to - have different paddings between the favicon (which is a compound drawable on the - TextView) and the offline icon. --> - <ImageView - android:id="@+id/offline_icon" - android:layout_width="@dimen/snippets_offline_icon_size" - android:layout_height="@dimen/snippets_offline_icon_size" - android:layout_marginStart="6dp" - android:contentDescription="@string/accessibility_ntp_offline_badge" - android:visibility="gone" - android:src="@drawable/offline_pin_round" /> - </LinearLayout> - - <LinearLayout - android:id="@+id/text_layout" - android:layout_alignParentStart="true" - android:layout_below="@+id/publisher_bar" - android:layout_toStartOf="@+id/article_thumbnail" - android:layout_alignWithParentIfMissing="true" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:orientation="vertical"> - - <org.chromium.ui.widget.TextViewWithLeading - style="@style/ContextualSuggestionCardTitleModern" - android:id="@+id/article_headline" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:text="Article headline" /> - - <org.chromium.ui.widget.TextViewWithLeading - style="@style/ContextualSuggestionCardBodyModern" - android:id="@+id/article_snippet" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:text="Article snippet" /> - </LinearLayout> - - <ImageView - android:id="@+id/article_thumbnail" - android:layout_marginStart="@dimen/snippets_padding" - android:layout_width="@dimen/snippets_thumbnail_size_small" - android:layout_height="@dimen/snippets_thumbnail_size_small" - android:layout_below="@+id/publisher_bar" - android:layout_alignParentEnd="true" - android:scaleType="centerCrop" - tools:ignore="ContentDescription" - android:src="@null" /> -</RelativeLayout>
diff --git a/chrome/android/java/res/layout/contextual_suggestions_layout.xml b/chrome/android/java/res/layout/contextual_suggestions_layout.xml deleted file mode 100644 index 72771e80..0000000 --- a/chrome/android/java/res/layout/contextual_suggestions_layout.xml +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2018 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:scrollbars="vertical" - android:scrollbarStyle="outsideOverlay" - android:layout_marginTop="@dimen/bottom_sheet_peek_height" - android:background="@color/modern_primary_color" /> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml b/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml deleted file mode 100644 index b84c2b5e..0000000 --- a/chrome/android/java/res/layout/contextual_suggestions_toolbar.xml +++ /dev/null
@@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2018 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<org.chromium.chrome.browser.contextual_suggestions.ToolbarView - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="wrap_content" > - - <LinearLayout - android:id="@+id/main_content" - android:layout_width="match_parent" - android:layout_height="@dimen/bottom_sheet_peek_height" - android:orientation="horizontal" - android:gravity="center_vertical" - android:background="@color/modern_primary_color" > - - <!-- Use 48dp width and 16dp end/start padding to produce a 16dp, centered icon. --> - <ImageView - android:layout_height="match_parent" - android:layout_width="wrap_content" - android:src="@drawable/ic_logo_googleg_24dp" - android:scaleType="center" - android:paddingStart="16dp" - android:paddingEnd="16dp" - tools:ignore="ContentDescription" /> - - <TextView - android:id="@+id/title" - android:layout_height="wrap_content" - android:layout_width="0dp" - android:layout_weight="1" - android:singleLine="true" - android:ellipsize="end" - android:textAppearance="@style/TextAppearance.BlackTitle1" - android:focusable="true" - android:focusableInTouchMode="true" /> - - <org.chromium.chrome.browser.widget.ListMenuButton - android:id="@+id/more" - android:layout_width="@dimen/contextual_suggestions_toolbar_icon_size" - android:layout_height="match_parent" - android:background="?attr/selectableItemBackground" - android:src="@drawable/ic_more_vert_black_24dp" - app:tint="@color/standard_mode_tint" - tools:ignore="ContentDescription" /> - - <org.chromium.ui.widget.ChromeImageButton - android:id="@+id/close_button" - android:layout_height="match_parent" - android:layout_width="@dimen/contextual_suggestions_toolbar_icon_size" - android:background="?attr/selectableItemBackground" - android:src="@drawable/btn_close" - android:scaleType="center" - android:contentDescription="@string/contextual_suggestions_close_button_description" - app:tint="@color/standard_mode_tint" /> - </LinearLayout> - - <ImageView - android:id="@+id/shadow" - android:layout_width="match_parent" - android:layout_height="@dimen/toolbar_shadow_height" - android:layout_marginTop="@dimen/bottom_sheet_peek_height" - android:src="@drawable/modern_toolbar_shadow" - android:scaleType="fitXY" - tools:ignore="ContentDescription" - android:visibility="gone" /> - -</org.chromium.chrome.browser.contextual_suggestions.ToolbarView> \ No newline at end of file
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 469e69c..731f3d6 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -805,17 +805,11 @@ <item name="android:ellipsize">end</item> <item name="leading">20sp</item> </style> - <style name="ContextualSuggestionCardTitleModern" parent="SuggestionCardTitleModern"> - <item name="leading">@dimen/text_size_large_leading</item> - </style> <style name="SuggestionCardBodyModern" parent="TextAppearance.BlackBody"> <item name="android:layout_marginTop">8dp</item> <item name="android:ellipsize">end</item> <item name="leading">16sp</item> </style> - <style name="ContextualSuggestionCardBodyModern" parent="SuggestionCardBodyModern"> - <item name="leading">@dimen/text_size_medium_leading</item> - </style> <style name="SuggestionCardAction" parent="@style/TextButton"> <item name="android:minHeight">48dp</item> </style>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 96ab6cb..8c2ff85 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -3,7 +3,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<resources> +<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Please see src/ui/android/java/res/values/colors.xml for the shared common colors. --> <!-- Text colors --> @@ -191,7 +191,7 @@ <color name="bottom_system_nav_color">@android:color/white</color> <color name="bottom_system_nav_divider_color">@color/black_alpha_12</color> <color name="search_box_hint">@color/default_text_color_secondary</color> - <color name="thumbnail_placeholder_on_primary_bg">@color/modern_secondary_color</color> + <color name="thumbnail_placeholder_on_primary_bg" tools:ignore="UnusedResources">@color/modern_secondary_color</color> <color name="tab_layout_selected_tab_color">@color/default_text_color_blue</color> <color name="drag_handlebar_color">#D9DBDF</color>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 2464b10..55cd39c 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -349,7 +349,6 @@ <dimen name="ntp_wide_card_lateral_margins">48dp</dimen> <dimen name="ntp_progress_indicator_diameter">56dp</dimen> <dimen name="snippets_thumbnail_size">124dp</dimen> - <dimen name="snippets_thumbnail_size_small">72dp</dimen> <!-- The default padding for the peeking card and the amount the card peeks by in the current peeking card animation (the calculations assume this is the same). --> <dimen name="snippets_padding">16dp</dimen> @@ -547,10 +546,6 @@ <!-- Padding surrounding the message. --> <dimen name="reader_mode_infobar_text_padding">8dp</dimen> - <!-- Contextual Suggestions Dimensions --> - <dimen name="contextual_suggestions_publisher_margin">12dp</dimen> - <dimen name="contextual_suggestions_toolbar_icon_size">48dp</dimen> - <!-- Defaults for TabbedModeFirstRunActivity values. --> <item type="dimen" name="dialog_fixed_width_major">100%</item> <item type="dimen" name="dialog_fixed_width_minor">100%</item>
diff --git a/chrome/android/java/res/xml/contextual_suggestions_preferences.xml b/chrome/android/java/res/xml/contextual_suggestions_preferences.xml deleted file mode 100644 index 4297d2e..0000000 --- a/chrome/android/java/res/xml/contextual_suggestions_preferences.xml +++ /dev/null
@@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2018 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<PreferenceScreen - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> - - <org.chromium.chrome.browser.preferences.ChromeSwitchPreference - android:key="contextual_suggestions_switch" - android:summaryOn="@string/text_on" - android:summaryOff="@string/text_off" - app:drawDivider="true" /> - - <org.chromium.chrome.browser.preferences.TextMessagePreference - android:key="contextual_suggestions_description" /> - - <org.chromium.chrome.browser.preferences.TextMessagePreference - android:key="contextual_suggestions_message" /> - -</PreferenceScreen>
diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml index 8ffe1baa..cd253fa 100644 --- a/chrome/android/java/res/xml/main_preferences.xml +++ b/chrome/android/java/res/xml/main_preferences.xml
@@ -56,64 +56,59 @@ android:order="9" android:title="@string/prefs_notifications"/> <Preference - android:fragment="org.chromium.chrome.browser.preferences.ContextualSuggestionsPreference" - android:key="contextual_suggestions" - android:order="10" - android:title="@string/prefs_contextual_suggestions"/> - <Preference android:fragment="org.chromium.chrome.browser.preferences.HomepagePreferences" android:key="homepage" - android:order="11" + android:order="10" android:title="@string/options_homepage_title"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.themes.ThemePreferences" android:key="ui_theme" - android:order="12" + android:order="11" android:title="@string/prefs_themes" /> <PreferenceCategory android:key="advanced_section" - android:order="13" + android:order="12" android:title="@string/prefs_section_advanced"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.privacy.PrivacyPreferences" android:key="privacy" - android:order="14" + android:order="13" android:title="@string/prefs_privacy"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.AccessibilityPreferences" android:key="accessibility" - android:order="15" + android:order="14" android:title="@string/prefs_accessibility"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.website.SiteSettingsPreferences" android:key="content_settings" - android:order="16" + android:order="15" android:title="@string/prefs_site_settings"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.languages.LanguagesPreferences" android:key="languages" - android:order="17" + android:order="16" android:title="@string/prefs_languages"/> <org.chromium.chrome.browser.preferences.datareduction.DataReductionPreference android:fragment="org.chromium.chrome.browser.preferences.datareduction.DataReductionPreferenceFragment" android:key="data_reduction" - android:order="18" + android:order="17" android:title="@string/data_reduction_title"/> <org.chromium.chrome.browser.preferences.ChromeBasePreference android:fragment="org.chromium.chrome.browser.preferences.download.DownloadPreferences" android:key="downloads" - android:order="19" + android:order="18" android:title="@string/menu_downloads"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.developer.DeveloperPreferences" android:key="developer" - android:order="20" + android:order="19" android:title="Developer options"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.AboutChromePreferences" android:key="about_chrome" - android:order="21" + android:order="20" android:title="@string/prefs_about_chrome"/> </PreferenceScreen>
diff --git a/chrome/android/java/res/xml/sync_and_services_preferences.xml b/chrome/android/java/res/xml/sync_and_services_preferences.xml index d4ee2a1..f7611767 100644 --- a/chrome/android/java/res/xml/sync_and_services_preferences.xml +++ b/chrome/android/java/res/xml/sync_and_services_preferences.xml
@@ -73,9 +73,5 @@ android:key="contextual_search" android:title="@string/contextual_search_title" android:fragment="org.chromium.chrome.browser.preferences.privacy.ContextualSearchPreferenceFragment"/> - <Preference - android:key="contextual_suggestions" - android:title="@string/prefs_contextual_suggestions" - android:fragment="org.chromium.chrome.browser.preferences.ContextualSuggestionsPreference"/> </PreferenceCategory> </PreferenceScreen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index e5775f9..1d6a50f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -71,8 +71,6 @@ import org.chromium.chrome.browser.compositor.layouts.content.ContentOffsetProvider; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManagerHandler; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; -import org.chromium.chrome.browser.contextual_suggestions.PageViewTimer; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager.ContextualSearchTabPromotionDelegate; @@ -329,9 +327,6 @@ /** Whether or not a PolicyChangeListener was added. */ private boolean mDidAddPolicyChangeListener; - /** Adds TabObserver and TabModelObserver to measure page view times. */ - private PageViewTimer mPageViewTimer; - private ActivityTabStartupMetricsTracker mActivityTabStartupMetricsTracker; /** A means of providing the foreground tab of the activity to different features. */ @@ -402,14 +397,7 @@ ? new ChromeActivityCommonsModule(this, getLifecycleDispatcher()) : overridenCommonsFactory.create(this); - ContextualSuggestionsModule.Factory overridenSuggestionsFactory = - ModuleFactoryOverrides.getOverrideFor(ContextualSuggestionsModule.Factory.class); - - ContextualSuggestionsModule suggestionsModule = overridenSuggestionsFactory == null - ? new ContextualSuggestionsModule() - : overridenSuggestionsFactory.create(); - - return createComponent(commonsModule, suggestionsModule); + return createComponent(commonsModule); } /** @@ -421,10 +409,8 @@ * You may immediately resolve some of the classes belonging to the component in this method. */ @SuppressWarnings("unchecked") - protected C createComponent(ChromeActivityCommonsModule commonsModule, - ContextualSuggestionsModule contextualSuggestionsModule) { - return (C) ChromeApplication.getComponent().createChromeActivityComponent( - commonsModule, contextualSuggestionsModule); + protected C createComponent(ChromeActivityCommonsModule commonsModule) { + return (C) ChromeApplication.getComponent().createChromeActivityComponent(commonsModule); } /** @@ -1258,11 +1244,6 @@ @SuppressLint("NewApi") @Override protected final void onDestroy() { - if (mPageViewTimer != null) { - mPageViewTimer.destroy(); - mPageViewTimer = null; - } - if (mReaderModeManager != null) { mReaderModeManager.destroy(); mReaderModeManager = null; @@ -1429,13 +1410,9 @@ getCompositorViewHolder().addCompositorViewResizer( mManualFillingComponent.getKeyboardExtensionViewResizer()); - // Create after native initialization so subclasses that override this method have a chance - // to setup. - mPageViewTimer = createPageViewTimer(); if (mBottomSheet == null && shouldInitializeBottomSheet()) { // TODO(yusufo): Unify initialization. - initializeBottomSheet( - !ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON)); + initializeBottomSheet(true); } AppHooks.get().startMonitoringNetworkQuality(); AppHooks.get().startSystemSettingsObserver(); @@ -2582,12 +2559,14 @@ } /** - * Create a PageViewTimer that's compatible with this activity. Override in subclasses to - * specialize behavior. - * @return The PageViewTimer created for this activity. + * TODO(https://crbug.com/931496): Revisit this as part of the broader discussion around + * activity-specific UI customizations. + * @return Whether this Activity supports the App Menu. */ - protected PageViewTimer createPageViewTimer() { - return new PageViewTimer(mTabModelSelector); + public boolean supportsAppMenu() { + // Derived classes that disable the toolbar should also have the Menu disabled without + // having to explicitly disable the Menu as well. + return getToolbarLayoutId() != NO_TOOLBAR_LAYOUT; } /** Returns {@link BottomSheetController}, if present. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 44d465a..944d3ca9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -212,10 +212,6 @@ "ContextualSearchTranslationModel"; public static final String CONTEXTUAL_SEARCH_UNITY_INTEGRATION = "ContextualSearchUnityIntegration"; - public static final String CONTEXTUAL_SUGGESTIONS_BUTTON = "ContextualSuggestionsButton"; - public static final String CONTEXTUAL_SUGGESTIONS_OPT_OUT = "ContextualSuggestionsOptOut"; - public static final String CONTEXTUAL_SUGGESTIONS_IPH_REVERSE_SCROLL = - "ContextualSuggestionsIPHReverseScroll"; public static final String CUSTOM_CONTEXT_MENU = "CustomContextMenu"; public static final String DATA_SAVER_LITE_MODE_REBRANDING = "DataSaverLiteModeRebranding"; public static final String DELEGATE_OVERSCROLL_SWIPES = "DelegateOverscrollSwipes";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index b71be10..91e5457 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -68,7 +68,6 @@ import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeController; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; -import org.chromium.chrome.browser.contextual_suggestions.PageViewTimer; import org.chromium.chrome.browser.cookies.CookiesFetcher; import org.chromium.chrome.browser.crypto.CipherFactory; import org.chromium.chrome.browser.datareduction.DataReductionPromoScreen; @@ -145,6 +144,7 @@ import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.toolbar.ToolbarButtonInProductHelpController; import org.chromium.chrome.browser.toolbar.top.ToolbarControlContainer; +import org.chromium.chrome.browser.touchless.TouchlessDelegate; import org.chromium.chrome.browser.usage_stats.UsageStatsService; import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.FeatureUtilities; @@ -491,7 +491,9 @@ ChromeTabbedActivity.MAIN_LAUNCHER_ACTIVITY_NAME)) { // Keep in sync with the activities that the .Main alias points to in // AndroidManifest.xml. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + if (FeatureUtilities.isNoTouchModeEnabled()) { + intent.setClass(appContext, TouchlessDelegate.getNoTouchActivityClass()); + } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { intent.setClass(appContext, ChromeLauncherActivity.class); } else { intent.setClass(appContext, ChromeTabbedActivity.class); @@ -2459,8 +2461,7 @@ @Override protected boolean shouldInitializeBottomSheet() { - return FeatureUtilities.areContextualSuggestionsEnabled(this) - || FeatureUtilities.isTabGroupsAndroidEnabled(); + return FeatureUtilities.isTabGroupsAndroidEnabled(); } @Override @@ -2478,9 +2479,4 @@ } }); } - - @Override - protected PageViewTimer createPageViewTimer() { - return new PageViewTimer(mTabModelSelectorImpl, mLayoutManager); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index 3343368..ed9fbf5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -101,6 +101,9 @@ } @Override + protected void initializeUiState() {} + + @Override public OverlayPanelContent createNewOverlayPanelContent() { return new OverlayPanelContent(mManagementDelegate.getOverlayContentDelegate(), new PanelProgressObserver(), mActivity, /* isIncognito= */ false, getBarHeight());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java deleted file mode 100644 index 873560b..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ClusterList.java +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.ntp.cards.InnerNode; -import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; -import org.chromium.ui.modelutil.RecyclerViewAdapter; - -import java.util.List; - -/** - * A node in a tree containing a list of {@link ContextualSuggestionsCluster}s. - */ -class ClusterList - extends InnerNode<NewTabPageViewHolder, NewTabPageViewHolder.PartialBindCallback> { - /** - * Replaces the list of clusters under this node with a new list. Any previous clusters will be - * destroyed. - * - * @param clusters The new list of clusters for this node. - */ - public void setClusters(List<ContextualSuggestionsCluster> clusters) { - destroyClusters(); - removeChildren(); - for (ContextualSuggestionsCluster cluster : clusters) { - addChildren(cluster); - } - } - - /** - * Destroys all clusters under this node. - */ - public void destroy() { - destroyClusters(); - } - - private void destroyClusters() { - for (RecyclerViewAdapter.Delegate c : getChildren()) { - ((ContextualSuggestionsCluster) c).destroy(); - } - } - - @VisibleForTesting - public ContextualSuggestionsCluster getClusterForTesting(int index) { - return (ContextualSuggestionsCluster) getChildren().get(index); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionCardViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionCardViewHolder.java deleted file mode 100644 index 037f6fb..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionCardViewHolder.java +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.native_page.ContextMenuManager; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; -import org.chromium.chrome.browser.suggestions.SuggestionsBinder; -import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; -import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; - -/** Holder for a contextual suggestions card. **/ -public class ContextualSuggestionCardViewHolder extends SnippetArticleViewHolder { - ContextualSuggestionCardViewHolder(SuggestionsRecyclerView parent, - ContextMenuManager contextMenuManager, SuggestionsUiDelegate uiDelegate, - UiConfig uiConfig, OfflinePageBridge offlinePageBridge) { - super(parent, contextMenuManager, uiDelegate, uiConfig, offlinePageBridge, - R.layout.contextual_suggestions_card_modern); - } - - @Override - public boolean isItemSupported(@ContextMenuManager.ContextMenuItemId int menuItemId) { - return menuItemId != ContextMenuManager.ContextMenuItemId.LEARN_MORE - && super.isItemSupported(menuItemId); - } - - @Override - public boolean isDismissable() { - return false; - } - - @Override - protected SuggestionsBinder createBinder(SuggestionsUiDelegate uiDelegate) { - return new SuggestionsBinder(itemView, uiDelegate, true); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java deleted file mode 100644 index aacb9336..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.view.ViewGroup; - -import org.chromium.chrome.browser.native_page.ContextMenuManager; -import org.chromium.chrome.browser.ntp.cards.ItemViewType; -import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; -import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback; -import org.chromium.chrome.browser.ntp.snippets.SectionHeaderViewHolder; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; -import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.ui.modelutil.RecyclerViewAdapter; - -/** - * An adapter that contains the view binder for the content component. - */ -class ContextualSuggestionsAdapter - extends RecyclerViewAdapter<NewTabPageViewHolder, PartialBindCallback> { - private static class ContextualSuggestionsViewHolderFactory - implements ViewHolderFactory<NewTabPageViewHolder> { - private final Profile mProfile; - private final UiConfig mUiConfig; - private final SuggestionsUiDelegate mUiDelegate; - private final ContextMenuManager mContextMenuManager; - - public ContextualSuggestionsViewHolderFactory(Profile profile, UiConfig uiConfig, - SuggestionsUiDelegate uiDelegate, ContextMenuManager contextMenuManager) { - mProfile = profile; - mUiConfig = uiConfig; - mUiDelegate = uiDelegate; - mContextMenuManager = contextMenuManager; - } - - @Override - public NewTabPageViewHolder createViewHolder(ViewGroup parent, int viewType) { - switch (viewType) { - case ItemViewType.HEADER: - return new SectionHeaderViewHolder((SuggestionsRecyclerView) parent, mUiConfig); - - case ItemViewType.SNIPPET: - return new ContextualSuggestionCardViewHolder((SuggestionsRecyclerView) parent, - mContextMenuManager, mUiDelegate, mUiConfig, - OfflinePageBridge.getForProfile(mProfile)); - - default: - assert false; - return null; - } - } - } - - /** - * Construct a new {@link ContextualSuggestionsAdapter}. - * @param profile The regular {@link Profile}. - * @param uiConfig The {@link UiConfig} used to adjust view display. - * @param uiDelegate The {@link SuggestionsUiDelegate} used to help construct items in the - * content view. - * @param contextMenuManager The {@link ContextMenuManager} used to display a context menu. - * @param delegate The {@link Delegate} implementing the core logic. - */ - ContextualSuggestionsAdapter(Profile profile, UiConfig uiConfig, - SuggestionsUiDelegate uiDelegate, ContextMenuManager contextMenuManager, - RecyclerViewAdapter.Delegate<NewTabPageViewHolder, PartialBindCallback> delegate) { - super(delegate, - new ContextualSuggestionsViewHolderFactory( - profile, uiConfig, uiDelegate, contextMenuManager)); - } - - @Override - public void onViewRecycled(NewTabPageViewHolder holder) { - holder.recycle(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBottomSheetContent.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBottomSheetContent.java deleted file mode 100644 index c889edf..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBottomSheetContent.java +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.view.View; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.ContentPriority; - -/** A {@link BottomSheetContent} that displays contextual suggestions. */ -public class ContextualSuggestionsBottomSheetContent implements BottomSheetContent { - private final ContentCoordinator mContentCoordinator; - private final ToolbarCoordinator mToolbarCoordinator; - - /** - * Construct a new {@link ContextualSuggestionsBottomSheetContent}. - * @param contentCoordinator The {@link ContentCoordinator} that manages content to be - * displayed. - * @param toolbarCoordinator The {@link ToolbarCoordinator} that manages the toolbar to be - * displayed. - */ - ContextualSuggestionsBottomSheetContent( - ContentCoordinator contentCoordinator, ToolbarCoordinator toolbarCoordinator) { - mContentCoordinator = contentCoordinator; - mToolbarCoordinator = toolbarCoordinator; - } - - @Override - public View getContentView() { - return mContentCoordinator.getView(); - } - - @Override - public View getToolbarView() { - return mToolbarCoordinator.getView(); - } - - @Override - public int getVerticalScrollOffset() { - return mContentCoordinator.getVerticalScrollOffset(); - } - - @Override - public void destroy() {} - - @Override - public @ContentPriority int getPriority() { - return ContentPriority.LOW; - } - - @Override - public boolean swipeToDismissEnabled() { - return true; - } - - @Override - public boolean isPeekStateEnabled() { - return false; - } - - @Override - public int getSheetContentDescriptionStringId() { - return R.string.contextual_suggestions_button_description; - } - - @Override - public int getSheetHalfHeightAccessibilityStringId() { - return R.string.contextual_suggestions_sheet_opened_half; - } - - @Override - public int getSheetFullHeightAccessibilityStringId() { - return R.string.contextual_suggestions_sheet_opened_full; - } - - @Override - public int getSheetClosedAccessibilityStringId() { - return R.string.contextual_suggestions_sheet_closed; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java deleted file mode 100644 index fabe543..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java +++ /dev/null
@@ -1,174 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.base.Callback; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.chrome.browser.ntp.snippets.KnownCategories; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.content_public.browser.WebContents; - -import java.util.ArrayList; -import java.util.List; - -/** - * Provides access to contextual suggestions. - */ -@JNINamespace("contextual_suggestions") -public class ContextualSuggestionsBridge { - private long mNativeContextualSuggestionsBridge; - - /** Result of fetching contextual suggestions. */ - public static class ContextualSuggestionsResult { - private String mPeekText; - private List<ContextualSuggestionsCluster> mClusters = new ArrayList<>(); - private PeekConditions mPeekConditions = new PeekConditions(); - - ContextualSuggestionsResult(String peekText) { - mPeekText = peekText; - } - - /** Peek text to show in UI. */ - public String getPeekText() { - return mPeekText; - } - - /** Clusters of suggestions. */ - public List<ContextualSuggestionsCluster> getClusters() { - return mClusters; - } - - /** Server-provided conditions for when to "peek" the suggestions UI. */ - public PeekConditions getPeekConditions() { - return mPeekConditions; - } - - /** Setter for mPeekConditions. */ - public void setPeekConditions(PeekConditions peekConditions) { - mPeekConditions = peekConditions; - } - } - - /** - * Creates a ContextualSuggestionsBridge for getting snippet data for the current user. - * - * @param profile Profile of the user that we will retrieve snippets for. - */ - ContextualSuggestionsBridge(Profile profile) { - mNativeContextualSuggestionsBridge = nativeInit(profile); - } - - /** - * @return Whether contextual suggestions are disabled via Enterprise Policy. - */ - public static boolean isDisabledByEnterprisePolicy() { - return nativeIsDisabledByEnterprisePolicy(); - } - - /** Destroys the bridge. */ - void destroy() { - assert mNativeContextualSuggestionsBridge != 0; - nativeDestroy(mNativeContextualSuggestionsBridge); - mNativeContextualSuggestionsBridge = 0; - } - - /** - * Fetches suggestions for a given URL. - * @param url URL for which to fetch suggestions. - * @param callback Callback used to return suggestions for a given URL. - */ - void fetchSuggestions(String url, Callback<ContextualSuggestionsResult> callback) { - assert mNativeContextualSuggestionsBridge != 0; - nativeFetchSuggestions(mNativeContextualSuggestionsBridge, url, callback); - } - - /** - * Get the url of the image used for the given suggestion. - * - * @param suggestion The suggestion that the image url is for. - * @return The url for the image or null if one can't be found. - */ - String getImageUrl(SnippetArticle suggestion) { - assert mNativeContextualSuggestionsBridge != 0; - return nativeGetImageUrl(mNativeContextualSuggestionsBridge, suggestion.mIdWithinCategory); - } - - /** - * Get the url of the favicon used for the given suggestion. - * - * @param suggestion The suggestion that the favicon url is for. - * @return The url for the image or null if one can't be found. - */ - String getFaviconUrl(SnippetArticle suggestion) { - assert mNativeContextualSuggestionsBridge != 0; - return nativeGetFaviconUrl( - mNativeContextualSuggestionsBridge, suggestion.mIdWithinCategory); - } - - /** Requests the backend to clear state related to this bridge. */ - void clearState() { - assert mNativeContextualSuggestionsBridge != 0; - nativeClearState(mNativeContextualSuggestionsBridge); - } - - /** - * Reports an event happening in the context of the current URL. - * - * @param webContents Web contents with the document for which event is reported. - * @param eventId The Id of the reported event as a {@link ContextualSuggestionsEvent} integer. - */ - void reportEvent(WebContents webContents, @ContextualSuggestionsEvent int eventId) { - assert mNativeContextualSuggestionsBridge != 0; - assert webContents != null && !webContents.isDestroyed(); - - nativeReportEvent(mNativeContextualSuggestionsBridge, webContents, eventId); - } - - @CalledByNative - private static ContextualSuggestionsResult createContextualSuggestionsResult(String peekText) { - return new ContextualSuggestionsResult(peekText); - } - - @CalledByNative - private static void setPeekConditionsOnResult(ContextualSuggestionsResult result, - float confidence, float pageScrollPercentage, float minimumSecondsOnPage, - float maximumNumberOfPeeks) { - PeekConditions peekConditions = new PeekConditions( - confidence, pageScrollPercentage, minimumSecondsOnPage, maximumNumberOfPeeks); - result.setPeekConditions(peekConditions); - } - - @CalledByNative - private static void addNewClusterToResult(ContextualSuggestionsResult result, String title) { - result.getClusters().add(new ContextualSuggestionsCluster(title)); - } - - @CalledByNative - private static void addSuggestionToLastCluster(ContextualSuggestionsResult result, String id, - String title, String snippet, String publisher, String url, boolean hasImage) { - assert result.getClusters().size() > 0; - result.getClusters() - .get(result.getClusters().size() - 1) - .getSuggestions() - .add(new SnippetArticle(KnownCategories.CONTEXTUAL, id, title, snippet, publisher, - url, /*publishTimestamp=*/0, /*score=*/0f, /*fetchTimestamp=*/0, - /*isVideoSuggestion=*/false, /*thumbnailDominantColor=*/null, hasImage)); - } - - static private native boolean nativeIsDisabledByEnterprisePolicy(); - private native long nativeInit(Profile profile); - private native void nativeDestroy(long nativeContextualSuggestionsBridge); - private native void nativeFetchSuggestions(long nativeContextualSuggestionsBridge, String url, - Callback<ContextualSuggestionsResult> callback); - private native String nativeGetImageUrl( - long nativeContextualSuggestionsBridge, String suggestionId); - private native String nativeGetFaviconUrl( - long nativeContextualSuggestionsBridge, String suggestionId); - private native void nativeClearState(long nativeContextualSuggestionsBridge); - private native void nativeReportEvent( - long nativeContextualSuggestionsBridge, WebContents webContents, int eventId); -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java deleted file mode 100644 index 0b0e860..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCluster.java +++ /dev/null
@@ -1,180 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.support.annotation.NonNull; -import android.text.TextUtils; - -import org.chromium.chrome.browser.ntp.cards.ChildNode; -import org.chromium.chrome.browser.ntp.cards.InnerNode; -import org.chromium.chrome.browser.ntp.cards.ItemViewType; -import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; -import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback; -import org.chromium.chrome.browser.ntp.cards.PartiallyBindable; -import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo; -import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsCardLayout; -import org.chromium.chrome.browser.ntp.snippets.KnownCategories; -import org.chromium.chrome.browser.ntp.snippets.SectionHeader; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; -import org.chromium.chrome.browser.offlinepages.OfflinePageItem; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.suggestions.ContentSuggestionsAdditionalAction; -import org.chromium.chrome.browser.suggestions.SuggestionsOfflineModelObserver; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -/** A node in a tree that groups contextual suggestions in a cluster of related items. */ -class ContextualSuggestionsCluster extends InnerNode<NewTabPageViewHolder, PartialBindCallback> { - private final String mTitle; - private final boolean mShouldShowTitle; - private final List<SnippetArticle> mSuggestions = new ArrayList<>(); - - private SectionHeader mHeader; - private SuggestionsList mSuggestionsList; - private OfflineModelObserver mOfflineModelObserver; - - /** Creates a new contextual suggestions cluster with provided title. */ - ContextualSuggestionsCluster(String title) { - mTitle = title; - mShouldShowTitle = !TextUtils.isEmpty(title); - } - - /** @return A title related to this cluster */ - String getTitle() { - return mTitle; - } - - /** @return A list of suggestions in this cluster */ - List<SnippetArticle> getSuggestions() { - return mSuggestions; - } - - /** - * Called to build the tree node's children. Should be called after all suggestions have been - * added. - * - * @param globalIndexOffset The index offset for setting global suggestion rank. This should be - * the total number of suggestions displayed before this cluster. - */ - void buildChildren(int globalIndexOffset) { - if (mShouldShowTitle) { - mHeader = new SectionHeader(mTitle); - addChildren(mHeader); - } - - mSuggestionsList = new SuggestionsList(); - mSuggestionsList.addAll(mSuggestions, globalIndexOffset); - addChildren(mSuggestionsList); - - // Only add observer after suggestions have been added to the cluster node to avoid - // OfflineModelObserver requesting a null list. - mOfflineModelObserver = new OfflineModelObserver( - OfflinePageBridge.getForProfile(Profile.getLastUsedProfile().getOriginalProfile())); - mOfflineModelObserver.updateAllSuggestionsOfflineAvailability(false); - } - - public void destroy() { - // TODO(bauerb): This should be part of a mediator instead of the cluster itself. - if (mOfflineModelObserver != null) mOfflineModelObserver.onDestroy(); - } - - /** A tree node that holds a list of suggestions. */ - private static class SuggestionsList - extends ChildNode<NewTabPageViewHolder, PartialBindCallback> - implements Iterable<SnippetArticle>, PartiallyBindable { - private final List<SnippetArticle> mSuggestions = new ArrayList<>(); - - private final SuggestionsCategoryInfo mCategoryInfo; - - public SuggestionsList() { - mCategoryInfo = new SuggestionsCategoryInfo(KnownCategories.CONTEXTUAL, "", - ContentSuggestionsCardLayout.FULL_CARD, ContentSuggestionsAdditionalAction.NONE, - false, ""); - } - - @Override - protected int getItemCountForDebugging() { - return mSuggestions.size(); - } - - @Override - @ItemViewType - public int getItemViewType(int position) { - checkIndex(position); - return ItemViewType.SNIPPET; - } - - @Override - public void onBindViewHolder(NewTabPageViewHolder holder, int position) { - checkIndex(position); - SnippetArticle suggestion = getSuggestionAt(position); - ((ContextualSuggestionCardViewHolder) holder) - .onBindViewHolder(suggestion, mCategoryInfo); - } - - private SnippetArticle getSuggestionAt(int position) { - return mSuggestions.get(position); - } - - public void addAll(List<SnippetArticle> suggestions, int globalIndexOffset) { - if (suggestions.isEmpty()) return; - - int insertionPointIndex = mSuggestions.size(); - for (int i = 0; i < suggestions.size(); i++) { - suggestions.get(i).setRank(i, i + globalIndexOffset); - } - mSuggestions.addAll(suggestions); - notifyItemRangeInserted(insertionPointIndex, suggestions.size()); - } - - @Override - public String describeItemForTesting(int position) { - return String.format( - Locale.US, "SUGGESTION(%1.42s)", mSuggestions.get(position).mTitle); - } - - @NonNull - @Override - public Iterator<SnippetArticle> iterator() { - return mSuggestions.iterator(); - } - - // TODO(huayinz): Look at a way to share this with SuggestionsSection. - void updateSuggestionOfflineId(SnippetArticle article, Long newId) { - int index = mSuggestions.indexOf(article); - // The suggestions could have been removed / replaced in the meantime. - if (index == -1) return; - - Long oldId = article.getOfflinePageOfflineId(); - article.setOfflinePageOfflineId(newId); - - if ((oldId == null) == (newId == null)) return; - notifyItemChanged(index, SnippetArticleViewHolder::refreshOfflineBadgeVisibility); - } - } - - /** An observer to offline changes on suggestions. */ - private class OfflineModelObserver extends SuggestionsOfflineModelObserver<SnippetArticle> { - OfflineModelObserver(OfflinePageBridge bridge) { - super(bridge); - } - - @Override - public void onSuggestionOfflineIdChanged(SnippetArticle suggestion, OfflinePageItem item) { - mSuggestionsList.updateSuggestionOfflineId( - suggestion, item == null ? null : item.getOfflineId()); - } - - @Override - public Iterable<SnippetArticle> getOfflinableSuggestions() { - return mSuggestionsList; - } - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java deleted file mode 100644 index 6758122..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsCoordinator.java +++ /dev/null
@@ -1,195 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.support.annotation.Nullable; - -import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.ChromeActivity; -import org.chromium.chrome.browser.ChromeApplication; -import org.chromium.chrome.browser.dependency_injection.ActivityScope; -import org.chromium.chrome.browser.help.HelpAndFeedback; -import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.lifecycle.Destroyable; -import org.chromium.chrome.browser.preferences.ContextualSuggestionsPreference; -import org.chromium.chrome.browser.preferences.PreferencesLauncher; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; -import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; - -import javax.inject.Inject; - -/** - * The coordinator for the contextual suggestions UI component. Manages communication with other - * parts of the UI-layer and lifecycle of shared component objects. - * - * This parent coordinator manages two sub-components, controlled by {@link ContentCoordinator} - * and {@link ToolbarCoordinator}. These sub-components each have their own views and view binders. - * They share a {@link ContextualSuggestionsMediator} and {@link ContextualSuggestionsModel}. - */ -@ActivityScope -public class ContextualSuggestionsCoordinator implements Destroyable { - private static final String FEEDBACK_CONTEXT = "contextual_suggestions"; - - private final Profile mProfile = Profile.getLastUsedProfile().getOriginalProfile(); - private final ContextualSuggestionsModel mModel; - private final ChromeActivity mActivity; - private final BottomSheetController mBottomSheetController; - private final TabModelSelector mTabModelSelector; - private final ContextualSuggestionsMediator mMediator; - - private @Nullable ToolbarCoordinator mToolbarCoordinator; - private @Nullable ContentCoordinator mContentCoordinator; - private @Nullable ContextualSuggestionsBottomSheetContent mBottomSheetContent; - - /** - * @param activity The containing {@link ChromeActivity}. - * @param bottomSheetController The {@link BottomSheetController} to request content be shown. - * @param tabModelSelector The {@link TabModelSelector} for the activity. - * @param model The model of the component. - * @param mediator The mediator of the component - */ - @Inject - ContextualSuggestionsCoordinator(ChromeActivity activity, - BottomSheetController bottomSheetController, TabModelSelector tabModelSelector, - ContextualSuggestionsModel model, ContextualSuggestionsMediator mediator, - ActivityLifecycleDispatcher lifecycleDispatcher) { - mActivity = activity; - mModel = model; - mBottomSheetController = bottomSheetController; - mTabModelSelector = tabModelSelector; - mMediator = mediator; - mediator.initialize(this); - lifecycleDispatcher.register(this); - } - - /** Called when the containing activity is destroyed. */ - @Override - public void destroy() { - mModel.getClusterList().destroy(); - mMediator.destroy(); - - if (mToolbarCoordinator != null) mToolbarCoordinator.destroy(); - if (mContentCoordinator != null) mContentCoordinator.destroy(); - if (mBottomSheetContent != null) mBottomSheetContent.destroy(); - } - - /** - * Show the contextual suggestions content in the {@link BottomSheet}. - * Only the views needed for peeking the bottom sheet will be constructed. Another - * call to {@link #displaySuggestions()} is needed to finish inflating views for the - * suggestions cards. - */ - void showContentInSheet() { - mToolbarCoordinator = - new ToolbarCoordinator(mActivity, mBottomSheetController.getBottomSheet(), mModel); - mContentCoordinator = - new ContentCoordinator(mActivity, mBottomSheetController.getBottomSheet()); - mBottomSheetContent = new ContextualSuggestionsBottomSheetContent( - mContentCoordinator, mToolbarCoordinator); - assert mBottomSheetContent != null; - mBottomSheetController.requestShowContent(mBottomSheetContent, false); - } - - /** - * Finish showing the contextual suggestions in the {@link BottomSheet}. - * {@link #showContentInSheet()} must be called prior to calling this method. - * - * @param suggestionsSource The {@link ContextualSuggestionsSource} used to retrieve additional - * things needed to display suggestions (e.g. favicons, thumbnails). - */ - void showSuggestions(ContextualSuggestionsSource suggestionsSource) { - // If the content coordinator has already been destroyed when this method is called, return - // early. See https://crbug.com/873052. - if (mContentCoordinator == null) { - assert false : "ContentCoordinator false when #showSuggestions was called."; - return; - } - - SuggestionsNavigationDelegate navigationDelegate = new SuggestionsNavigationDelegate( - mActivity, mProfile, mBottomSheetController.getBottomSheet(), mTabModelSelector); - SuggestionsUiDelegateImpl uiDelegate = new SuggestionsUiDelegateImpl(suggestionsSource, - new ContextualSuggestionsEventReporter(mTabModelSelector, suggestionsSource), - navigationDelegate, mProfile, mBottomSheetController.getBottomSheet(), - ChromeApplication.getReferencePool(), mBottomSheetController.getSnackbarManager()); - - mContentCoordinator.showSuggestions(mActivity, mProfile, uiDelegate, mModel, - mActivity.getWindowAndroid(), mActivity::closeContextMenu); - } - - /** - * Add an observer to the {@link BottomSheet}. - * @param observer The observer to add. - */ - void addBottomSheetObserver(BottomSheetObserver observer) { - mBottomSheetController.getBottomSheet().addObserver(observer); - } - - /** - * Remove an observer to the {@link BottomSheet}. - * @param observer The observer to remove. - */ - void removeBottomSheetObserver(BottomSheetObserver observer) { - mBottomSheetController.getBottomSheet().removeObserver(observer); - } - - /** - * Expand the {@link BottomSheet}. - */ - void expandBottomSheet() { - mBottomSheetController.expandSheet(); - } - - /** Removes contextual suggestions from the {@link BottomSheet}. */ - void removeSuggestions() { - if (mToolbarCoordinator != null) { - mToolbarCoordinator.destroy(); - mToolbarCoordinator = null; - } - - if (mContentCoordinator != null) { - mContentCoordinator.destroy(); - mContentCoordinator = null; - } - - if (mBottomSheetContent != null) { - mBottomSheetController.hideContent(mBottomSheetContent, true); - mBottomSheetContent.destroy(); - mBottomSheetContent = null; - } - } - - /** Show the settings page for contextual suggestions. */ - void showSettings() { - PreferencesLauncher.launchSettingsPage(mActivity, ContextualSuggestionsPreference.class); - } - - /** Show the feedback page. */ - void showFeedback() { - Tab currentTab = mActivity.getActivityTab(); - HelpAndFeedback.getInstance(mActivity).showFeedback(mActivity, mProfile, - currentTab != null ? currentTab.getUrl() : null, null, FEEDBACK_CONTEXT); - } - - /** @return The height of the bottom sheet when it's peeking. */ - float getSheetPeekHeight() { - return mActivity.getBottomSheet().getSheetHeightForState(BottomSheet.SheetState.PEEK); - } - - @VisibleForTesting - ContextualSuggestionsMediator getMediatorForTesting() { - return mMediator; - } - - @VisibleForTesting - ContextualSuggestionsModel getModelForTesting() { - return mModel; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEnabledStateUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEnabledStateUtils.java deleted file mode 100644 index 09efb288..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEnabledStateUtils.java +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.locale.LocaleManager; -import org.chromium.chrome.browser.preferences.Pref; -import org.chromium.chrome.browser.preferences.PrefServiceBridge; -import org.chromium.chrome.browser.search_engines.TemplateUrlService; -import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge; -import org.chromium.components.signin.ChromeSigninController; - -/** Utility functions related to enabled state of Contextual Suggestions. */ -public class ContextualSuggestionsEnabledStateUtils { - - private ContextualSuggestionsEnabledStateUtils() {} - - /** @return Whether the user settings for contextual suggestions should be shown. */ - public static boolean shouldShowSettings() { - return isDSEConditionMet() - && ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_OPT_OUT); - } - - /** @return Whether the settings state is currently enabled. */ - static boolean getSettingsEnabled() { - return isDSEConditionMet() && !ContextualSuggestionsBridge.isDisabledByEnterprisePolicy() - && ChromeSigninController.get().isSignedIn() - && UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionEnabled(); - } - - /** @return Whether the state is currently enabled. */ - public static boolean getEnabledState() { - return getSettingsEnabled() - && (PrefServiceBridge.getInstance().getBoolean(Pref.CONTEXTUAL_SUGGESTIONS_ENABLED) - || !ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_OPT_OUT)); - } - - public static void recordEnabled(boolean enabled) { - RecordHistogram.recordBooleanHistogram("ContextualSuggestions.EnabledState", enabled); - } - - public static void recordPreferenceEnabled(boolean enabled) { - RecordHistogram.recordBooleanHistogram("ContextualSuggestions.Preference.State", enabled); - } - - private static boolean isDSEConditionMet() { - boolean hasCompletedSearchEnginePromo = - LocaleManager.getInstance().hasCompletedSearchEnginePromo(); - boolean isGoogleDSE = TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(); - return !hasCompletedSearchEnginePromo || isGoogleDSE; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEventReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEventReporter.java deleted file mode 100644 index 7c70db7c..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsEventReporter.java +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.chrome.browser.feature_engagement.TrackerFactory; -import org.chromium.chrome.browser.ntp.cards.ActionItem; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.suggestions.SuggestionsEventReporter; -import org.chromium.chrome.browser.suggestions.SuggestionsRanker; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.components.feature_engagement.EventConstants; -import org.chromium.ui.mojom.WindowOpenDisposition; - -/** Reports events related to contextual suggestions. */ -class ContextualSuggestionsEventReporter implements SuggestionsEventReporter { - private TabModelSelector mTabModelSelector; - private ContextualSuggestionsSource mSuggestionSource; - - /** - * Constructs a new {@link ContextualSuggestionsEventReporter}. - * - * @param tabModelSelector The {@link TabModelSelector} for the containing activity. - * @param suggestionsSource The {@link ContextualSuggestionsSource} used to report events. - */ - ContextualSuggestionsEventReporter( - TabModelSelector tabModelSelector, ContextualSuggestionsSource suggestionsSource) { - mTabModelSelector = tabModelSelector; - mSuggestionSource = suggestionsSource; - } - - @Override - public void onSurfaceOpened() {} - - @Override - public void onPageShown( - int[] categories, int[] suggestionsPerCategory, boolean[] isCategoryVisible) {} - - @Override - public void onSuggestionShown(SnippetArticle suggestion) {} - - @Override - public void onSuggestionOpened(SnippetArticle suggestion, int windowOpenDisposition, - SuggestionsRanker suggestionsRanker) { - int eventId = windowOpenDisposition == WindowOpenDisposition.SAVE_TO_DISK - ? ContextualSuggestionsEvent.SUGGESTION_DOWNLOADED - : ContextualSuggestionsEvent.SUGGESTION_CLICKED; - mSuggestionSource.reportEvent(mTabModelSelector.getCurrentTab().getWebContents(), eventId); - - TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()) - .notifyEvent(EventConstants.CONTEXTUAL_SUGGESTION_TAKEN); - RecordHistogram.recordSparseHistogram( - "ContextualSuggestions.SuggestionClickPosition.Global", suggestion.getGlobalRank()); - RecordHistogram.recordSparseHistogram( - "ContextualSuggestions.SuggestionClickPosition.Cluster", - suggestion.getPerSectionRank()); - } - - @Override - public void onSuggestionMenuOpened(SnippetArticle suggestion) {} - - @Override - public void onMoreButtonShown(ActionItem category) {} - - @Override - public void onMoreButtonClicked(ActionItem category) {} -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java deleted file mode 100644 index a2f218a..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsMediator.java +++ /dev/null
@@ -1,582 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import static org.chromium.chrome.browser.dependency_injection.ChromeCommonQualifiers.LAST_USED_PROFILE; - -import android.content.Context; -import android.os.Handler; -import android.os.SystemClock; -import android.support.annotation.Nullable; -import android.text.TextUtils; -import android.view.View; - -import org.chromium.base.ContextUtils; -import org.chromium.base.VisibleForTesting; -import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; -import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; -import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsBridge.ContextualSuggestionsResult; -import org.chromium.chrome.browser.dependency_injection.ActivityScope; -import org.chromium.chrome.browser.feature_engagement.TrackerFactory; -import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; -import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; -import org.chromium.chrome.browser.fullscreen.FullscreenManager; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.toolbar.ToolbarManager; -import org.chromium.chrome.browser.toolbar.top.ToolbarPhone; -import org.chromium.chrome.browser.util.AccessibilityUtil; -import org.chromium.chrome.browser.widget.ListMenuButton; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.StateChangeReason; -import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; -import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; -import org.chromium.chrome.browser.widget.textbubble.ImageTextBubble; -import org.chromium.chrome.browser.widget.textbubble.TextBubble; -import org.chromium.components.feature_engagement.EventConstants; -import org.chromium.components.feature_engagement.FeatureConstants; -import org.chromium.components.feature_engagement.Tracker; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.widget.ViewRectProvider; - -import java.util.Collections; -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Provider; - -/** - * A mediator for the contextual suggestions UI component responsible for interacting with - * the contextual suggestions C++ components (via a bridge), updating the model, and communicating - * with the component coordinator(s). - */ -@ActivityScope -class ContextualSuggestionsMediator - implements EnabledStateMonitor.Observer, FetchHelper.Delegate, ListMenuButton.Delegate { - @VisibleForTesting - static final String IPH_CONFIDENCE_THRESHOLD_PARAM = "iph_confidence_threshold"; - private static final int IPH_AUTO_DISMISS_TIMEOUT_MS = 6000; - private static final int IPH_AUTO_DISMISS_ACCESSIBILITY_TIMEOUT_MS = 10000; - private static boolean sOverrideIPHTimeoutForTesting; - - private final Profile mProfile; - private final TabModelSelector mTabModelSelector; - private final ContextualSuggestionsModel mModel; - private final ChromeFullscreenManager mFullscreenManager; - private final ToolbarManager mToolbarManager; - private final EnabledStateMonitor mEnabledStateMonitor; - private final Handler mHandler = new Handler(); - private final Provider<ContextualSuggestionsSource> mSuggestionSourceProvider; - private @Nullable final OverviewModeBehavior mOverviewModeBehavior; - private final boolean mRequireReverseScrollForIPH; - - private ContextualSuggestionsCoordinator mCoordinator; - - private @Nullable ContextualSuggestionsSource mSuggestionsSource; - private @Nullable FetchHelper mFetchHelper; - private @Nullable String mCurrentRequestUrl; - private @Nullable BottomSheetObserver mSheetObserver; - private @Nullable TextBubble mHelpBubble; - - private boolean mModelPreparedForCurrentTab; - private boolean mSuggestionsSetOnBottomSheet; - private boolean mHasRecordedButtonShownForTab; - - /** - * Whether the browser controls have fully hidden at least once since the last time - * #clearSuggestions() was called. This is used as a proxy for whether the user has scrolled - * down on the current page. - */ - private boolean mHaveBrowserControlsFullyHidden; - private int mFullscreenToken = FullscreenManager.INVALID_TOKEN; - - private boolean mHasPeekDelayPassed; - - /** Whether the content sheet is observed to be opened for the first time. */ - private boolean mHasSheetBeenOpened; - - /** - * Whether in-product help may be shown. This is set to false if the IPH system indicates that - * it wouldn't trigger our IPH if requested and when we attempt to show the IPH bubble. - */ - private boolean mCanShowIph; - - /** - * Whether the current results are eligible for IPH based on the confidence of the results and - * the confidence threshold for showing IPH. Should be used in combination with other criteria - * e.g. {@link #mCanShowIph} to determine whether to request to show IPH. - */ - private boolean mCanShowIphForCurrentResults; - - /** - * Construct a new {@link ContextualSuggestionsMediator}. - * @param profile The last used {@link Profile}. - * @param tabModelSelector The {@link TabModelSelector} for the containing activity. - * @param fullscreenManager The {@link ChromeFullscreenManager} to listen for browser controls - * events. - * @param model The {@link ContextualSuggestionsModel} for the component. - * @param toolbarManager The {@link ToolbarManager} for the containing activity. - * @param layoutManager The {@link LayoutManager} used to retrieve the - * {@link OverviewModeBehavior} if it exists. - * @param enabledStateMonitor The state monitor that will alert the mediator if the enabled - * state for contextual suggestions changes. - * @param suggestionSourceProvider The provider of {@link ContextualSuggestionsSource} - * instances. - */ - @Inject - ContextualSuggestionsMediator(@Named(LAST_USED_PROFILE) Profile profile, - TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager, - ContextualSuggestionsModel model, ToolbarManager toolbarManager, - LayoutManager layoutManager, EnabledStateMonitor enabledStateMonitor, - Provider<ContextualSuggestionsSource> suggestionSourceProvider) { - mProfile = profile.getOriginalProfile(); - mTabModelSelector = tabModelSelector; - mModel = model; - mFullscreenManager = fullscreenManager; - - mToolbarManager = toolbarManager; - mSuggestionSourceProvider = suggestionSourceProvider; - - mEnabledStateMonitor = enabledStateMonitor; - mEnabledStateMonitor.addObserver(this); - if (mEnabledStateMonitor.getEnabledState()) { - enable(); - } - - mFullscreenManager.addListener(new FullscreenListener() { - @Override - public void onContentOffsetChanged(int offset) {} - - @Override - public void onControlsOffsetChanged( - int topOffset, int bottomOffset, boolean needsAnimate) { - if (!mHaveBrowserControlsFullyHidden) { - mHaveBrowserControlsFullyHidden = - mFullscreenManager.areBrowserControlsOffScreen(); - } else if (mCanShowIph && mCanShowIphForCurrentResults - && mRequireReverseScrollForIPH - && mFullscreenManager.areBrowserControlsFullyVisible()) { - mHandler.postDelayed(() -> maybeShowHelpBubble(), - ToolbarPhone.LOC_BAR_WIDTH_CHANGE_ANIMATION_DURATION_MS); - } - reportToolbarButtonShown(); - } - - @Override - public void onToggleOverlayVideoMode(boolean enabled) {} - - @Override - public void onBottomControlsHeightChanged(int bottomControlsHeight) {} - }); - - if (layoutManager instanceof LayoutManagerChrome) { - mOverviewModeBehavior = (LayoutManagerChrome) layoutManager; - mOverviewModeBehavior.addOverviewModeObserver(new EmptyOverviewModeObserver() { - @Override - public void onOverviewModeFinishedHiding() { - reportToolbarButtonShown(); - } - }); - } else { - mOverviewModeBehavior = null; - } - - mRequireReverseScrollForIPH = ChromeFeatureList.isEnabled( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_IPH_REVERSE_SCROLL); - } - - /** - * Sets the {@link ContextualSuggestionsCoordinator} for bidirectional communication. - */ - void initialize(ContextualSuggestionsCoordinator coordinator) { - // TODO(pshmakov): get rid of this circular dependency by establishing an observer-observable - // relationship between Mediator and Coordinator; - mCoordinator = coordinator; - } - - /** Destroys the mediator. */ - void destroy() { - if (mFetchHelper != null) { - mFetchHelper.destroy(); - mFetchHelper = null; - } - - if (mSuggestionsSource != null) { - mSuggestionsSource.destroy(); - mSuggestionsSource = null; - } - - if (mHelpBubble != null) mHelpBubble.dismiss(); - - mEnabledStateMonitor.removeObserver(this); - } - - @Override - public void onEnabledStateChanged(boolean enabled) { - if (enabled) { - enable(); - } else { - disable(); - } - } - - private void enable() { - mSuggestionsSource = mSuggestionSourceProvider.get(); - mFetchHelper = new FetchHelper(this, mTabModelSelector); - - Tracker tracker = TrackerFactory.getTrackerForProfile(mProfile); - tracker.addOnInitializedCallback(success -> { - if (!success) return; - mCanShowIph = - tracker.wouldTriggerHelpUI(FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE); - }); - } - - private void disable() { - clearSuggestions(); - - if (mFetchHelper != null) { - mFetchHelper.destroy(); - mFetchHelper = null; - } - - if (mSuggestionsSource != null) { - mSuggestionsSource.destroy(); - mSuggestionsSource = null; - } - } - - @Override - public void onSettingsStateChanged(boolean enabled) {} - - @Override - public void requestSuggestions(String url) { - // Guard against null tabs when requesting suggestions. https://crbug.com/836672. - if (mTabModelSelector.getCurrentTab() == null - || mTabModelSelector.getCurrentTab().getWebContents() == null) { - assert false; - return; - } - - reportEvent(ContextualSuggestionsEvent.FETCH_REQUESTED); - mCurrentRequestUrl = url; - mSuggestionsSource.fetchSuggestions(url, (suggestionsResult) -> { - if (mTabModelSelector.getCurrentTab() == null - || mTabModelSelector.getCurrentTab().getWebContents() == null - || mSuggestionsSource == null) { - return; - } - assert mFetchHelper != null; - - // Avoiding double fetches causing suggestions for incorrect context. - if (!TextUtils.equals(url, mCurrentRequestUrl)) return; - - List<ContextualSuggestionsCluster> clusters = suggestionsResult.getClusters(); - - if (clusters.isEmpty() || clusters.get(0).getSuggestions().isEmpty()) return; - - int globalSuggestionsCount = 0; - for (ContextualSuggestionsCluster cluster : clusters) { - cluster.buildChildren(globalSuggestionsCount); - globalSuggestionsCount += cluster.getSuggestions().size(); - } - - prepareModel(clusters, suggestionsResult.getPeekText()); - - // By default, we will show IPH if results have been sent to the UI layer unless - // otherwise configured via a field trial. - mCanShowIphForCurrentResults = suggestionsResult.getPeekConditions().getConfidence() - >= (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON, - IPH_CONFIDENCE_THRESHOLD_PARAM, 0.d); - - mToolbarManager.enableExperimentalButton( - view -> onToolbarButtonClicked(), - R.drawable.contextual_suggestions, - R.string.contextual_suggestions_button_description); - reportToolbarButtonShown(); - }); - } - - private void onToolbarButtonClicked() { - if (mSuggestionsSetOnBottomSheet || !mModelPreparedForCurrentTab) return; - - maybeShowContentInSheet(); - RecordUserAction.record("ContextualSuggestions.ToolbarButtonClicked"); - mCoordinator.showSuggestions(mSuggestionsSource); - mCoordinator.expandBottomSheet(); - } - - // TODO(twellington): Use peek criteria to determine when to show toolbar button or remove - // entirely. - private void setPeekConditions(ContextualSuggestionsResult suggestionsResult) { - PeekConditions peekConditions = suggestionsResult.getPeekConditions(); - long remainingDelay = - mFetchHelper.getFetchTimeBaselineMillis(mTabModelSelector.getCurrentTab()) - + Math.round(peekConditions.getMinimumSecondsOnPage() * 1000) - - SystemClock.uptimeMillis(); - - if (remainingDelay <= 0) { - // Don't postDelayed if the minimum delay has passed so that the suggestions may - // be shown through the following call to show contents in the bottom sheet. - mHasPeekDelayPassed = true; - } else { - // Once delay expires, the bottom sheet can be peeked if the browser controls are - // already hidden, or the next time the browser controls are fully hidden and - // reshown. Note that this triggering on the latter case is handled by - // FullscreenListener#onControlsOffsetChanged() in this class. - mHandler.postDelayed(() -> { - mHasPeekDelayPassed = true; - maybeShowContentInSheet(); - }, remainingDelay); - } - } - - private void reportToolbarButtonShown() { - if (mHasRecordedButtonShownForTab || !mFullscreenManager.areBrowserControlsFullyVisible() - || isOverviewModeVisible() || mSuggestionsSource == null - || !mModel.hasSuggestions()) { - return; - } - - mHasRecordedButtonShownForTab = true; - reportEvent(ContextualSuggestionsEvent.UI_BUTTON_SHOWN); - TrackerFactory.getTrackerForProfile(mProfile).notifyEvent( - EventConstants.CONTEXTUAL_SUGGESTIONS_BUTTON_SHOWN); - if (mCanShowIph && mCanShowIphForCurrentResults && !mRequireReverseScrollForIPH) { - mHandler.postDelayed(() -> maybeShowHelpBubble(), - ToolbarPhone.LOC_BAR_WIDTH_CHANGE_ANIMATION_DURATION_MS); - } - } - - @Override - public void clearState() { - clearSuggestions(); - } - - @Override - public void reportFetchDelayed(WebContents webContents) { - if (mTabModelSelector.getCurrentTab() != null - && mTabModelSelector.getCurrentTab().getWebContents() == webContents) { - reportEvent(ContextualSuggestionsEvent.FETCH_DELAYED); - } - } - - // ListMenuButton.Delegate implementation. - @Override - public ListMenuButton.Item[] getItems() { - final Context context = ContextUtils.getApplicationContext(); - if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_OPT_OUT)) { - return new ListMenuButton.Item[] { - new ListMenuButton.Item(context, R.string.menu_preferences, true), - new ListMenuButton.Item(context, R.string.menu_send_feedback, true)}; - } else { - return new ListMenuButton.Item[] { - new ListMenuButton.Item(context, R.string.menu_send_feedback, true)}; - } - } - - @Override - public void onItemSelected(ListMenuButton.Item item) { - if (item.getTextId() == R.string.menu_preferences) { - mCoordinator.showSettings(); - } else if (item.getTextId() == R.string.menu_send_feedback) { - mCoordinator.showFeedback(); - } else { - assert false : "Unhandled item detected."; - } - } - - private void removeSuggestionsFromSheet() { - if (mSheetObserver != null) { - mCoordinator.removeBottomSheetObserver(mSheetObserver); - mSheetObserver = null; - } - mCoordinator.removeSuggestions(); - - // Wait until suggestions are fully removed to reset {@code mSuggestionsSetOnBottomSheet}. - mCoordinator.addBottomSheetObserver(new EmptyBottomSheetObserver() { - @Override - public void onSheetContentChanged(@Nullable BottomSheet.BottomSheetContent newContent) { - if (!(newContent instanceof ContextualSuggestionsBottomSheetContent)) { - mSuggestionsSetOnBottomSheet = false; - mCoordinator.removeBottomSheetObserver(this); - } - } - }); - } - - /** - * Called when suggestions are cleared either due to the user explicitly dismissing - * suggestions via the close button or due to the FetchHelper signaling state should - * be cleared. - */ - private void clearSuggestions() { - mModelPreparedForCurrentTab = false; - - // Remove suggestions before clearing model state so that views don't respond to model - // changes while suggestions are hiding. See https://crbug.com/840579. - removeSuggestionsFromSheet(); - mToolbarManager.disableExperimentalButton(); - - mHasRecordedButtonShownForTab = false; - mHasSheetBeenOpened = false; - mHandler.removeCallbacksAndMessages(null); - mHasPeekDelayPassed = false; - mHaveBrowserControlsFullyHidden = false; - mModel.setClusterList(Collections.emptyList()); - mModel.setCloseButtonOnClickListener(null); - mModel.setMenuButtonDelegate(null); - mModel.setTitle(null); - mCurrentRequestUrl = ""; - - if (mSuggestionsSource != null) mSuggestionsSource.clearState(); - - if (mHelpBubble != null) mHelpBubble.dismiss(); - } - - private void prepareModel(List<ContextualSuggestionsCluster> clusters, String title) { - if (mSuggestionsSource == null) return; - - mModel.setClusterList(clusters); - mModel.setCloseButtonOnClickListener(view -> { - TrackerFactory.getTrackerForProfile(mProfile).notifyEvent( - EventConstants.CONTEXTUAL_SUGGESTIONS_DISMISSED); - @ContextualSuggestionsEvent - int openedEvent = - mHasSheetBeenOpened ? ContextualSuggestionsEvent.UI_DISMISSED_AFTER_OPEN - : ContextualSuggestionsEvent.UI_DISMISSED_WITHOUT_OPEN; - reportEvent(openedEvent); - removeSuggestionsFromSheet(); - - }); - mModel.setMenuButtonDelegate(this); - mModel.setTitle(!TextUtils.isEmpty(title) - ? title - : ContextUtils.getApplicationContext().getResources().getString( - R.string.contextual_suggestions_button_description)); - - mModelPreparedForCurrentTab = true; - } - - private void maybeShowContentInSheet() { - if (!mModel.hasSuggestions() || mSuggestionsSource == null) return; - - mSuggestionsSetOnBottomSheet = true; - - mSheetObserver = new EmptyBottomSheetObserver() { - @Override - public void onSheetOffsetChanged(float heightFraction, float offsetPx) { - if (mHelpBubble != null) mHelpBubble.dismiss(); - } - - @Override - public void onSheetOpened(@StateChangeReason int reason) { - if (!mHasSheetBeenOpened) { - mHasSheetBeenOpened = true; - TrackerFactory.getTrackerForProfile(mProfile).notifyEvent( - EventConstants.CONTEXTUAL_SUGGESTIONS_OPENED); - reportEvent(ContextualSuggestionsEvent.UI_OPENED); - } - } - - @Override - public void onSheetClosed(@StateChangeReason int reason) { - removeSuggestionsFromSheet(); - } - }; - - mCoordinator.addBottomSheetObserver(mSheetObserver); - mCoordinator.showContentInSheet(); - } - - private void maybeShowHelpBubble() { - View anchorView = mToolbarManager.getExperimentalButtonView(); - if (!mCanShowIph || !mCanShowIphForCurrentResults || mToolbarManager.isUrlBarFocused() - || anchorView == null || anchorView.getVisibility() != View.VISIBLE - || !mFullscreenManager.areBrowserControlsFullyVisible() - || mSuggestionsSource == null || !mModel.hasSuggestions()) { - return; - } - - // Either we'll fail to show or we'll successfully show. Either way, we can't show IPH - // after this attempt. - mCanShowIph = false; - Tracker tracker = TrackerFactory.getTrackerForProfile(mProfile); - if (!tracker.shouldTriggerHelpUI(FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE)) { - return; - } - - ViewRectProvider rectProvider = new ViewRectProvider(anchorView); - rectProvider.setInsetPx(0, 0, 0, - anchorView.getResources().getDimensionPixelOffset( - R.dimen.text_bubble_menu_anchor_y_inset)); - - mHelpBubble = new ImageTextBubble(anchorView.getContext(), anchorView, - R.string.contextual_suggestions_in_product_help, - R.string.contextual_suggestions_in_product_help_accessibility, true, rectProvider, - R.drawable.ic_logo_googleg_24dp); - - mHelpBubble.setDismissOnTouchInteraction(false); - if (!sOverrideIPHTimeoutForTesting) { - mHelpBubble.setAutoDismissTimeout(AccessibilityUtil.isAccessibilityEnabled() - ? IPH_AUTO_DISMISS_ACCESSIBILITY_TIMEOUT_MS - : IPH_AUTO_DISMISS_TIMEOUT_MS); - } - mHelpBubble.addOnDismissListener(() -> { - tracker.dismissed(FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE); - mFullscreenManager.getBrowserVisibilityDelegate().releasePersistentShowingToken( - mFullscreenToken); - mHelpBubble = null; - }); - mFullscreenToken = - mFullscreenManager.getBrowserVisibilityDelegate().showControlsPersistent(); - mHelpBubble.show(); - } - - private void reportEvent(@ContextualSuggestionsEvent int event) { - if (mTabModelSelector.getCurrentTab() == null - || mTabModelSelector.getCurrentTab().getWebContents() == null) { - // This method is not expected to be called if the current tab or webcontents are null. - // If this assert is hit, please alert someone on the Chrome Explore on Content team. - // See https://crbug.com/836672. - assert false; - return; - } - - mSuggestionsSource.reportEvent(mTabModelSelector.getCurrentTab().getWebContents(), event); - } - - private boolean isOverviewModeVisible() { - return mOverviewModeBehavior != null && mOverviewModeBehavior.overviewVisible(); - } - - @VisibleForTesting - void showContentInSheetForTesting(boolean disablePeekDelay) { - if (disablePeekDelay) mHasPeekDelayPassed = true; - maybeShowContentInSheet(); - } - - @VisibleForTesting - TextBubble getHelpBubbleForTesting() { - return mHelpBubble; - } - - @VisibleForTesting - static void setOverrideIPHTimeoutForTesting(boolean override) { - sOverrideIPHTimeoutForTesting = override; - } - - @VisibleForTesting - boolean getCanShowIphForCurrentResults() { - return mCanShowIphForCurrentResults; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java deleted file mode 100644 index 0d7b674..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModel.java +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.view.View.OnClickListener; - -import org.chromium.chrome.browser.dependency_injection.ActivityScope; -import org.chromium.chrome.browser.widget.ListMenuButton; -import org.chromium.ui.modelutil.PropertyObservable; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import javax.inject.Inject; - -/** A model for the contextual suggestions UI component. */ -@ActivityScope -class ContextualSuggestionsModel - extends PropertyObservable<ContextualSuggestionsModel.PropertyKey> { - /** Keys uniquely identifying model properties. */ - static class PropertyKey { - static final PropertyKey CLOSE_BUTTON_ON_CLICK_LISTENER = new PropertyKey(); - static final PropertyKey MENU_BUTTON_DELEGATE = new PropertyKey(); - static final PropertyKey TITLE = new PropertyKey(); - static final PropertyKey TOOLBAR_SHADOW_VISIBILITY = new PropertyKey(); - - private PropertyKey() {} - } - - private final ClusterList mClusterList = new ClusterList(); - - private OnClickListener mCloseButtonOnClickListener; - private ListMenuButton.Delegate mMenuButtonDelegate; - private String mTitle; - private boolean mToolbarShadowVisibility; - @Inject - ContextualSuggestionsModel() {} - - @Override - public Collection<PropertyKey> getAllSetProperties() { - // This is only the list of initially set properties and doesn't reflect changes after the - // object has been created. but currently this method is only called initially. - // Once this model is migrated to PropertyModel, the implementation will be correct. - return Arrays.asList(PropertyKey.CLOSE_BUTTON_ON_CLICK_LISTENER, - PropertyKey.MENU_BUTTON_DELEGATE, PropertyKey.TITLE); - } - - @Override - public Collection<PropertyKey> getAllProperties() { - return Arrays.asList(PropertyKey.CLOSE_BUTTON_ON_CLICK_LISTENER, - PropertyKey.MENU_BUTTON_DELEGATE, PropertyKey.TITLE, - PropertyKey.TOOLBAR_SHADOW_VISIBILITY); - } - - /** @param clusters The current list of clusters. */ - void setClusterList(List<ContextualSuggestionsCluster> clusters) { - mClusterList.setClusters(clusters); - } - - /** @return The current list of clusters. */ - ClusterList getClusterList() { - return mClusterList; - } - - /** @param listener The {@link OnClickListener} for the close button. */ - void setCloseButtonOnClickListener(OnClickListener listener) { - mCloseButtonOnClickListener = listener; - notifyPropertyChanged(PropertyKey.CLOSE_BUTTON_ON_CLICK_LISTENER); - } - - /** @return The {@link OnClickListener} for the close button. */ - OnClickListener getCloseButtonOnClickListener() { - return mCloseButtonOnClickListener; - } - - /** @param delegate The delegate for handles actions for the menu. */ - void setMenuButtonDelegate(ListMenuButton.Delegate delegate) { - mMenuButtonDelegate = delegate; - notifyPropertyChanged(PropertyKey.MENU_BUTTON_DELEGATE); - } - - /** @return The delegate that handles actions for the menu. */ - ListMenuButton.Delegate getMenuButtonDelegate() { - return mMenuButtonDelegate; - } - - /** @param title The title to display in the toolbar. */ - void setTitle(String title) { - mTitle = title; - notifyPropertyChanged(PropertyKey.TITLE); - } - - /** @return title The title to display in the toolbar. */ - String getTitle() { - return mTitle; - } - - /** - * @return Whether there are any suggestions to be shown. - */ - boolean hasSuggestions() { - return getClusterList().getItemCount() > 0; - } - - /** @param visible Whether the toolbar shadow should be visible. */ - void setToolbarShadowVisibility(boolean visible) { - mToolbarShadowVisibility = visible; - notifyPropertyChanged(PropertyKey.TOOLBAR_SHADOW_VISIBILITY); - } - - /** @return Whether the toolbar shadow should be visible. */ - boolean getToolbarShadowVisibility() { - return mToolbarShadowVisibility; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModule.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModule.java deleted file mode 100644 index 8012369c..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsModule.java +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import static org.chromium.chrome.browser.dependency_injection.ChromeCommonQualifiers.LAST_USED_PROFILE; - -import org.chromium.chrome.browser.profiles.Profile; - -import javax.inject.Named; - -import dagger.Module; -import dagger.Provides; - -/** - * Module for dependencies related to contextual suggestions. - */ -@Module -public class ContextualSuggestionsModule { - public interface Factory { ContextualSuggestionsModule create(); } - - @Provides - ContextualSuggestionsSource provideContextualSuggestionsSource( - @Named(LAST_USED_PROFILE) Profile profile) { - return new ContextualSuggestionsSourceImpl(profile); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSource.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSource.java deleted file mode 100644 index 34ce55f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSource.java +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.base.Callback; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsBridge.ContextualSuggestionsResult; -import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; -import org.chromium.content_public.browser.WebContents; - -/** - * Provides content for contextual suggestions. - */ -interface ContextualSuggestionsSource extends SuggestionsSource { - /** - * Fetches suggestions for a given URL. - * @param url URL for which to fetch suggestions. - * @param callback Callback used to return suggestions for a given URL. - */ - void fetchSuggestions(String url, Callback<ContextualSuggestionsResult> callback); - - /** - * Reports an event happening in the context of the current URL. - * - * @param webContents Web contents with the document for which event is reported. - * @param eventId The Id of the reported event as a {@link ContextualSuggestionsEvent} integer. - */ - void reportEvent(WebContents webContents, @ContextualSuggestionsEvent int eventId); - - /** Requests the backend to clear state. */ - void clearState(); - - // Some methods from SuggestionsSource are not applicable to contextual suggestions. - // TODO(twellington): The NTP classes used to display suggestion cards rely - // on the SuggestionsSource implementation. Refactor to limit reliance to the - // subset of methods actually used to render cards. -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImpl.java deleted file mode 100644 index 9fdb76d..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImpl.java +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.graphics.Bitmap; - -import org.chromium.base.Callback; -import org.chromium.base.VisibleForTesting; -import org.chromium.base.task.PostTask; -import org.chromium.base.task.TaskTraits; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsBridge.ContextualSuggestionsResult; -import org.chromium.chrome.browser.image_fetcher.ImageFetcher; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory; -import org.chromium.chrome.browser.ntp.snippets.EmptySuggestionsSource; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.content_public.browser.WebContents; - -/** - * Implementation of {@link ContextualSuggestionsSource}. - */ -class ContextualSuggestionsSourceImpl - extends EmptySuggestionsSource implements ContextualSuggestionsSource { - private ContextualSuggestionsBridge mBridge; - private ImageFetcher mImageFetcher; - - /** - * Creates a ContextualSuggestionsSource for getting contextual suggestions for the current - * user. - * - * @param profile Profile of the user. - */ - public ContextualSuggestionsSourceImpl(Profile profile) { - mBridge = new ContextualSuggestionsBridge(profile); - mImageFetcher = ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY); - } - - @Override - public void destroy() { - mBridge.destroy(); - mBridge = null; - mImageFetcher.destroy(); - mImageFetcher = null; - } - - @Override - public void fetchSuggestionImage(SnippetArticle suggestion, Callback<Bitmap> callback) { - String url = mBridge.getImageUrl(suggestion); - mImageFetcher.fetchImage( - url, ImageFetcher.CONTEXTUAL_SUGGESTIONS_UMA_CLIENT_NAME, callback); - } - - @Override - public void fetchContextualSuggestionImage( - SnippetArticle suggestion, Callback<Bitmap> callback) { - String url = mBridge.getImageUrl(suggestion); - if (url == null) { - PostTask.postTask(new TaskTraits(), () -> callback.onResult(null)); - return; - } - - mImageFetcher.fetchImage( - url, ImageFetcher.CONTEXTUAL_SUGGESTIONS_UMA_CLIENT_NAME, callback); - } - - @Override - public void fetchSuggestionFavicon(SnippetArticle suggestion, int minimumSizePx, - int desiredSizePx, Callback<Bitmap> callback) { - String url = mBridge.getFaviconUrl(suggestion); - if (url == null) { - PostTask.postTask(new TaskTraits(), () -> callback.onResult(null)); - return; - } - - mImageFetcher.fetchImage(url, ImageFetcher.CONTEXTUAL_SUGGESTIONS_UMA_CLIENT_NAME, - desiredSizePx, desiredSizePx, callback); - } - - @Override - public void fetchSuggestions(String url, Callback<ContextualSuggestionsResult> callback) { - mBridge.fetchSuggestions(url, callback); - } - - @Override - public void reportEvent(WebContents webContents, @ContextualSuggestionsEvent int eventId) { - mBridge.reportEvent(webContents, eventId); - } - - @Override - public void clearState() { - mBridge.clearState(); - } - - @VisibleForTesting - ContextualSuggestionsSourceImpl(ContextualSuggestionsBridge bridge, ImageFetcher imageFetcher) { - mBridge = bridge; - mImageFetcher = imageFetcher; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java deleted file mode 100644 index 10a50515..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitor.java +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -/** - * A monitor that is responsible for detecting changes to conditions required for contextual - * suggestions to be enabled. Alerts its {@link Observer}s when state changes. - */ -public interface EnabledStateMonitor { - /** An observer to be notified of enabled state changes. **/ - interface Observer { - void onEnabledStateChanged(boolean enabled); - void onSettingsStateChanged(boolean enabled); - } - - /** Add an {@link Observer} to be notified of changes to enabled state. */ - void addObserver(Observer observer); - - /** Remove an observer. */ - void removeObserver(Observer observer); - - /** @return Whether the settings state is currently enabled. */ - boolean getSettingsEnabled(); - - /** @return Whether the state is currently enabled. */ - boolean getEnabledState(); -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorImpl.java deleted file mode 100644 index e4b1d062..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorImpl.java +++ /dev/null
@@ -1,116 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.base.ObserverList; -import org.chromium.chrome.browser.locale.LocaleManager; -import org.chromium.chrome.browser.preferences.Pref; -import org.chromium.chrome.browser.preferences.PrefChangeRegistrar; -import org.chromium.chrome.browser.preferences.PrefServiceBridge; -import org.chromium.chrome.browser.search_engines.TemplateUrlService; -import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrlServiceObserver; -import org.chromium.chrome.browser.signin.SigninManager; -import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; -import org.chromium.chrome.browser.sync.ProfileSyncService; -import org.chromium.chrome.browser.sync.ProfileSyncService.SyncStateChangedListener; - -/** - * Implementation of {@link EnabledStateMonitor}. - */ -public class EnabledStateMonitorImpl implements EnabledStateMonitor, SyncStateChangedListener, - SignInStateObserver, TemplateUrlServiceObserver, - PrefChangeRegistrar.PrefObserver { - private final ObserverList<Observer> mObservers = new ObserverList<>(); - - /** Whether contextual suggestions are enabled. */ - private boolean mEnabled; - - /** Whether the user settings for contextual suggestions are enabled. */ - private boolean mSettingsEnabled; - - public EnabledStateMonitorImpl() { - // Assert that we don't need to check for the search engine promo to avoid needing to check - // every time the default search engine is updated. - assert !LocaleManager.getInstance().needToCheckForSearchEnginePromo(); - - new PrefChangeRegistrar().addObserver(Pref.CONTEXTUAL_SUGGESTIONS_ENABLED, this); - ProfileSyncService.get().addSyncStateChangedListener(this); - SigninManager.get().addSignInStateObserver(this); - TemplateUrlService.getInstance().addObserver(this); - updateEnabledState(); - ContextualSuggestionsEnabledStateUtils.recordPreferenceEnabled( - PrefServiceBridge.getInstance().getBoolean(Pref.CONTEXTUAL_SUGGESTIONS_ENABLED)); - } - - @Override - public void addObserver(Observer observer) { - mObservers.addObserver(observer); - } - - @Override - public void removeObserver(Observer observer) { - mObservers.removeObserver(observer); - } - - @Override - public boolean getSettingsEnabled() { - return ContextualSuggestionsEnabledStateUtils.getSettingsEnabled(); - } - - @Override - public boolean getEnabledState() { - return ContextualSuggestionsEnabledStateUtils.getEnabledState(); - } - - @Override - public void syncStateChanged() { - updateEnabledState(); - } - - @Override - public void onSignedIn() { - updateEnabledState(); - } - - @Override - public void onSignedOut() { - updateEnabledState(); - } - - @Override - public void onTemplateURLServiceChanged() { - updateEnabledState(); - } - - @Override - public void onPreferenceChange() { - updateEnabledState(); - } - - /** - * Updates whether contextual suggestions are enabled. Notifies the observer if the - * enabled state has changed. - */ - private void updateEnabledState() { - boolean previousSettingsState = mSettingsEnabled; - boolean previousState = mEnabled; - - mSettingsEnabled = getSettingsEnabled(); - mEnabled = getEnabledState(); - - if (mSettingsEnabled != previousSettingsState) { - for (Observer observer : mObservers) { - observer.onSettingsStateChanged(mSettingsEnabled); - } - } - - if (mEnabled != previousState) { - for (Observer observer : mObservers) { - observer.onEnabledStateChanged(mEnabled); - } - ContextualSuggestionsEnabledStateUtils.recordEnabled(mEnabled); - } - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java deleted file mode 100644 index e0ba3ba..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java +++ /dev/null
@@ -1,524 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.os.SystemClock; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.text.TextUtils; -import android.text.format.DateUtils; -import android.webkit.URLUtil; - -import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; -import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.tab.EmptyTabObserver; -import org.chromium.chrome.browser.tab.SadTab; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; -import org.chromium.chrome.browser.tabmodel.TabSelectionType; -import org.chromium.chrome.browser.util.UrlUtilities; -import org.chromium.content_public.browser.NavigationController; -import org.chromium.content_public.browser.NavigationEntry; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.base.PageTransition; - -import java.util.HashMap; -import java.util.Map; - -/** - * A helper class responsible for determining when to trigger requests for suggestions and when to - * clear state. - */ -class FetchHelper { - /** A delegate used to fetch suggestions. */ - interface Delegate { - /** - * Request a suggestions fetch for the specified {@code url}. - * @param url The url for which suggestions should be fetched. - */ - void requestSuggestions(String url); - - /** - * Called when the state should be reset e.g. when the user navigates away from a webpage. - */ - void clearState(); - - /** - * Called when a document becomes eligible for fetching but the fetch is being delayed. - */ - void reportFetchDelayed(WebContents webContents); - } - - /** State of the tab with respect to fetching readiness */ - class TabFetchReadinessState { - private long mFetchTimeBaselineMillis; - private String mUrl; - private String mCanonicalUrl; - - TabFetchReadinessState(String url) { - updateUrl(url); - } - - /** - * Updates the URL and if the context is different from the current one, resets the time at - * which we can start fetching suggestions. - * @param url A new value for URL tracked by the tab state. - */ - void updateUrl(String url) { - mUrl = URLUtil.isNetworkUrl(url) ? url : null; - mCanonicalUrl = ""; - mFetchTimeBaselineMillis = 0; - } - - /** @return The current URL tracked by this tab state. */ - String getUrl() { - return mUrl; - } - - /** Set the canonical url, which can differ from the actual URL. If the canonical url is - * set, the readiness state is considered to be tracking both urls. */ - void setCanonicalUrl(String canonicalUrl) { - mCanonicalUrl = canonicalUrl; - } - - /** - * @return Whether the tab state is tracking a tab with valid page loaded and valid status - * for fetching. - */ - boolean isTrackingPage() { - return mUrl != null; - } - - /** - * Sets the baseline from which the fetch delay is calculated if it was not - * already set (conceptually starting the timer). - * @param fetchTimeBaselineMillis The new value to set the baseline fetch time to. - * @return Whether the fetch time baseline was set. - */ - boolean setFetchTimeBaselineMillis(long fetchTimeBaselineMillis) { - if (!isTrackingPage()) return false; - if (isFetchTimeBaselineSet()) return false; - mFetchTimeBaselineMillis = fetchTimeBaselineMillis; - return true; - } - - /** @return The time at which fetch time baseline was established. */ - long getFetchTimeBaselineMillis() { - return mFetchTimeBaselineMillis; - } - - /** @return Whether the fetch timer is running. */ - boolean isFetchTimeBaselineSet() { - return mFetchTimeBaselineMillis != 0; - } - - /** - * Checks whether the provided url is the same (ignoring fragments) as the one tracked by - * tab state. - * @param url A URL to check against the URL in the tab state. - * @return Whether the URLs can be considered the same. - */ - boolean isContextTheSame(String url) { - return UrlUtilities.urlsMatchIgnoringFragments(url, mUrl) - || UrlUtilities.urlsMatchIgnoringFragments(url, mCanonicalUrl); - } - } - - @VisibleForTesting - final static int MINIMUM_FETCH_DELAY_SECONDS = 2; // 2 seconds. - private final static String FETCH_TRIGGERING_DELAY_SECONDS = "fetch_triggering_delay_seconds"; - private final static String REQUIRE_CURRENT_PAGE_FROM_SRP = "require_current_page_from_SRP"; - private final static String REQUIRE_NAV_CHAIN_FROM_SRP = "require_nav_chain_from_SRP"; - private static boolean sDisableDelayForTesting; - private static long sFetchTimeBaselineMillisForTesting; - - private final Delegate mDelegate; - private final TabModelSelector mTabModelSelector; - private final Map<Integer, TabFetchReadinessState> mObservedTabs = new HashMap<>(); - - private TabModelSelectorTabModelObserver mTabModelObserver; - private TabObserver mTabObserver; - private boolean mFetchRequestedForCurrentTab; - - private boolean mRequireCurrentPageFromSRP; - private boolean mRequireNavChainFromSRP; - - @Nullable - private Tab mCurrentTab; - - /** - * Construct a new {@link FetchHelper}. - * @param delegate The {@link Delegate} used to fetch suggestions. - * @param tabModelSelector The {@link TabModelSelector} for the containing Activity. - */ - FetchHelper(Delegate delegate, TabModelSelector tabModelSelector) { - mDelegate = delegate; - mTabModelSelector = tabModelSelector; - - mTabObserver = new EmptyTabObserver() { - @Override - public void onPageLoadStarted(Tab tab, String url) { - assert !tab.isIncognito(); - if (tab == mCurrentTab) { - clearState(); - } - getTabFetchReadinessState(tab).updateUrl(url); - } - - @Override - public void onUrlUpdated(Tab tab) { - assert !tab.isIncognito(); - // This address cases, where pages are implemented as a single page app and - // switching between articles updates URL, but does not cause a page reload. - if (tab == mCurrentTab - && !getTabFetchReadinessState(tab).isContextTheSame(tab.getUrl())) { - clearState(); - getTabFetchReadinessState(tab).updateUrl(tab.getUrl()); - } - } - - @Override - public void didFirstVisuallyNonEmptyPaint(Tab tab) { - setTimeBaselineAndMaybeFetch(tab); - } - - @Override - public void onPageLoadFinished(Tab tab, String url) { - setTimeBaselineAndMaybeFetch(tab); - } - - @Override - public void onLoadStopped(Tab tab, boolean toDifferentDocument) { - setTimeBaselineAndMaybeFetch(tab); - } - - private void setTimeBaselineAndMaybeFetch(Tab tab) { - assert !tab.isIncognito(); - if (getTabFetchReadinessState(tab).setFetchTimeBaselineMillis( - SystemClock.uptimeMillis())) { - maybeStartFetch(tab); - } - } - }; - - mTabModelObserver = new TabModelSelectorTabModelObserver(mTabModelSelector) { - @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { - startObservingTab(tab); - if (maybeSetFetchReadinessBaseline(tab)) { - maybeStartFetch(tab); - } - } - - @Override - public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { - if (tab == null) { - if (mCurrentTab != null) clearState(); - mCurrentTab = null; - return; - } - - if (mCurrentTab != null && mCurrentTab != tab) { - clearState(); - } - - if (tab.isIncognito()) { - mCurrentTab = null; - return; - } - - // Ensures that we start observing the tab, in case it was added to the tab model - // before this class. - startObservingTab(tab); - mCurrentTab = tab; - maybeStartFetch(tab); - } - - @Override - public void tabRemoved(Tab tab) { - tabGone(tab); - } - - @Override - public void willCloseTab(Tab tab, boolean animate) { - tabGone(tab); - } - }; - - mRequireCurrentPageFromSRP = requireCurrentPageFromSRP(); - mRequireNavChainFromSRP = requireNavChainFromSRP(); - - Tab currentTab = mTabModelSelector.getCurrentTab(); - if (currentTab == null) return; - - mTabModelObserver.didSelectTab(currentTab, TabSelectionType.FROM_USER, Tab.INVALID_TAB_ID); - if (maybeSetFetchReadinessBaseline(mCurrentTab)) { - maybeStartFetch(mCurrentTab); - } - } - - void destroy() { - // Remove the observer from all tracked tabs. - for (Integer tabId : mObservedTabs.keySet()) { - Tab tab = mTabModelSelector.getTabById(tabId); - if (tab == null) continue; - tab.removeObserver(mTabObserver); - } - - mObservedTabs.clear(); - mTabModelObserver.destroy(); - } - - /** - * In case the tab is no longer loading the page, it would set the fetch readiness baselines - * time. - * @param tab Tab to be checked. - * @return Whether the baseline time was set. - */ - private boolean maybeSetFetchReadinessBaseline(final Tab tab) { - if (isObservingTab(tab) && !tab.isLoading()) { - return getTabFetchReadinessState(tab).setFetchTimeBaselineMillis( - SystemClock.uptimeMillis()); - } - return false; - } - - private void maybeStartFetch(final Tab tab) { - if (tab == null || tab != mCurrentTab) return; - - assert !tab.isIncognito(); - - // Skip additional requests for current tab, until clearState is called. - if (mFetchRequestedForCurrentTab) return; - - TabFetchReadinessState tabFetchReadinessState = getTabFetchReadinessState(mCurrentTab); - - // If we are not tracking a valid page, we can bail. - if (!tabFetchReadinessState.isTrackingPage()) return; - - // Delay checks and calculations only make sense if the timer is running. - if (!tabFetchReadinessState.isFetchTimeBaselineSet()) return; - - // Return early if the current page is required to have originated from a Google search - // but did not. - if (isFromGoogleSearchRequired() && (tab.getWebContents() == null - || tab.getWebContents().getNavigationController() == null - || !isFromGoogleSearch( - tab.getWebContents().getNavigationController(), - mRequireCurrentPageFromSRP))) { - return; - } - - long currentDelayMillis = - SystemClock.uptimeMillis() - tabFetchReadinessState.getFetchTimeBaselineMillis(); - long delayMillis = Math.max(0, getMinimumFetchDelayMillis() - currentDelayMillis); - final String url = tabFetchReadinessState.getUrl(); - - if (sDisableDelayForTesting || delayMillis == 0) { - getCanonicalUrlThenFetch(tab, url); - return; - } - - mDelegate.reportFetchDelayed(tab.getWebContents()); - ThreadUtils.postOnUiThreadDelayed(() -> getCanonicalUrlThenFetch(tab, url), delayMillis); - } - - private void getCanonicalUrlThenFetch(final Tab tab, final String url) { - if (!shouldFetchCanonicalUrl(tab)) { - fetchSuggestions(tab, url); - return; - } - - tab.getWebContents().getMainFrame().getCanonicalUrlForSharing(new Callback<String>() { - @Override - public void onResult(String result) { - if (tab != mCurrentTab) return; - - TabFetchReadinessState tabFetchReadinessState = getTabFetchReadinessState(tab); - if (tabFetchReadinessState != null && tabFetchReadinessState.isTrackingPage() - && tabFetchReadinessState.isContextTheSame(url)) { - tabFetchReadinessState.setCanonicalUrl(result); - fetchSuggestions(tab, getUrlToFetchFor(tab.getUrl(), result)); - } - } - }); - } - - private void fetchSuggestions(final Tab tab, final String url) { - // Make sure that the tab is currently selected. - if (tab != mCurrentTab) return; - - if (mFetchRequestedForCurrentTab) return; - - if (!isObservingTab(tab)) return; - - // URL in tab changed since the task was originally posted. - if (!getTabFetchReadinessState(tab).isContextTheSame(url)) return; - - mFetchRequestedForCurrentTab = true; - mDelegate.requestSuggestions(url); - } - - private void clearState() { - mDelegate.clearState(); - mFetchRequestedForCurrentTab = false; - } - - /** - * Starts observing the tab. - * @param tab The {@link Tab} to be observed. - */ - private void startObservingTab(Tab tab) { - if (tab != null && !isObservingTab(tab) && !tab.isIncognito()) { - mObservedTabs.put(tab.getId(), new TabFetchReadinessState(tab.getUrl())); - tab.addObserver(mTabObserver); - } - } - - /** - * Stops observing the tab and removes its state. - * @param tab The {@link Tab} that will no longer be observed. - */ - private void stopObservingTab(Tab tab) { - if (tab != null && isObservingTab(tab)) { - mObservedTabs.remove(tab.getId()); - tab.removeObserver(mTabObserver); - } - } - - /** - * Performs necessary cleanup when a tab leaves the tab model we're associated with, whether by - * being moved to another model or closed. - */ - private void tabGone(Tab tab) { - stopObservingTab(tab); - if (tab == mCurrentTab) { - clearState(); - mCurrentTab = null; - } - } - - /** Whether the tab is currently observed. */ - @VisibleForTesting - boolean isObservingTab(Tab tab) { - return tab != null && mObservedTabs.containsKey(tab.getId()); - } - - private TabFetchReadinessState getTabFetchReadinessState(Tab tab) { - if (tab == null) return null; - return mObservedTabs.get(tab.getId()); - } - - /** - * @param tab The specified {@link Tab}. - * @return The baseline fetch time for the specified tab. - */ - long getFetchTimeBaselineMillis(@NonNull Tab tab) { - return sDisableDelayForTesting - ? sFetchTimeBaselineMillisForTesting - : mObservedTabs.get(tab.getId()).getFetchTimeBaselineMillis(); - } - - private boolean isFromGoogleSearchRequired() { - return mRequireCurrentPageFromSRP || mRequireNavChainFromSRP; - } - - @VisibleForTesting - boolean requireCurrentPageFromSRP() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON, REQUIRE_CURRENT_PAGE_FROM_SRP, - false); - } - - @VisibleForTesting - boolean requireNavChainFromSRP() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON, REQUIRE_NAV_CHAIN_FROM_SRP, false); - } - - @VisibleForTesting - boolean isGoogleSearchUrl(String url) { - return UrlUtilities.nativeIsGoogleSearchUrl(url); - } - - @VisibleForTesting - boolean isFromGoogleSearch( - NavigationController navController, boolean onlyConsiderPreviousPage) { - int currentIndex = navController.getLastCommittedEntryIndex(); - - // If the current entry is the root of the navigation history, we cannot determine whether - // it originated from a Google search. - if (currentIndex <= 0) return false; - - int endIndex = onlyConsiderPreviousPage ? currentIndex - 1 : 0; - - NavigationEntry previousEntry = null; - NavigationEntry currentEntry; - for (int i = currentIndex; i > endIndex; i--) { - if (previousEntry != null) { - currentEntry = previousEntry; - } else { - currentEntry = navController.getEntryAtIndex(i); - } - - int unmaskedTransition = currentEntry.getTransition() & ~PageTransition.QUALIFIER_MASK; - - // If the current navigation entry was not from one of the accepted transition types - // return false. - if (unmaskedTransition != PageTransition.LINK - && unmaskedTransition != PageTransition.MANUAL_SUBFRAME - && unmaskedTransition != PageTransition.FORM_SUBMIT) { - return false; - } - - previousEntry = navController.getEntryAtIndex(i - 1); - if (isGoogleSearchUrl(previousEntry.getUrl())) { - return true; - } - } - - return false; - } - - static boolean shouldFetchCanonicalUrl(final Tab currentTab) { - WebContents webContents = currentTab.getWebContents(); - if (webContents == null) return false; - if (webContents.getMainFrame() == null) return false; - String url = currentTab.getUrl(); - if (TextUtils.isEmpty(url)) return false; - if (currentTab.isShowingErrorPage() || currentTab.isShowingInterstitialPage() - || SadTab.isShowing(currentTab)) { - return false; - } - return true; - } - - static String getUrlToFetchFor(String visibleUrl, String canonicalUrl) { - return TextUtils.isEmpty(canonicalUrl) ? visibleUrl : canonicalUrl; - } - - @VisibleForTesting - static long getMinimumFetchDelayMillis() { - return DateUtils.SECOND_IN_MILLIS - * ChromeFeatureList.getFieldTrialParamByFeatureAsInt( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON, - FETCH_TRIGGERING_DELAY_SECONDS, MINIMUM_FETCH_DELAY_SECONDS); - } - - @VisibleForTesting - static void setDisableDelayForTesting(boolean disable) { - sDisableDelayForTesting = disable; - } - - @VisibleForTesting - static void setFetchTimeBaselineMillisForTesting(long uptimeMillis) { - sFetchTimeBaselineMillisForTesting = uptimeMillis; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS deleted file mode 100644 index 9037c57..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -file://chrome/android/java/src/org/chromium/chrome/browser/ntp/OWNERS - -fgorski@chromium.org - -# COMPONENT: UI>Browser>ContentSuggestions>Explore
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimer.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimer.java deleted file mode 100644 index b5d8610d..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimer.java +++ /dev/null
@@ -1,298 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.os.SystemClock; -import android.support.annotation.IntDef; -import android.webkit.URLUtil; - -import org.chromium.base.VisibleForTesting; -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; -import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; -import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; -import org.chromium.chrome.browser.tab.EmptyTabObserver; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.Tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; -import org.chromium.chrome.browser.tabmodel.TabSelectionType; -import org.chromium.chrome.browser.util.UrlUtilities; -import org.chromium.content_public.browser.NavigationController; -import org.chromium.content_public.browser.NavigationEntry; -import org.chromium.content_public.browser.WebContents; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** Class allowing to measure and report a page view time in UMA. */ -public class PageViewTimer { - @VisibleForTesting - public static final long SHORT_BUCKET_THRESHOLD_MS = 4 * 1000; - @VisibleForTesting - public static final long MEDIUM_BUCKET_THRESHOLD_MS = 180 * 1000; - - /** - * Note: Because this is used for UMA reporting, these values shouldn't be - * changed, reused or reordered. Additions should go on the end, and any - * updates should also be reflected under enums.xml. - */ - @VisibleForTesting - @IntDef({DurationBucket.SHORT_CLICK, DurationBucket.MEDIUM_CLICK, DurationBucket.LONG_CLICK}) - @Retention(RetentionPolicy.SOURCE) - public @interface DurationBucket { - int SHORT_CLICK = 0; /** Click <= 4 seconds */ - int MEDIUM_CLICK = 1; /** 4 seconds < Click <= 180 seconds */ - int LONG_CLICK = 2; /** 180 seconds < Click */ - int NUM_ENTRIES = 3; - } - - /** Track the navigation source to report the page view time under. */ - @IntDef({NavigationSource.OTHER, NavigationSource.CONTEXTUAL_SUGGESTIONS}) - @Retention(RetentionPolicy.SOURCE) - public @interface NavigationSource { - int OTHER = 0; - int CONTEXTUAL_SUGGESTIONS = 1; - } - - private final TabModelSelectorTabModelObserver mTabModelObserver; - private final TabObserver mTabObserver; - private final OverviewModeBehavior mOverviewModeBehavior; - - /** Observer for the tab switcher, can be null. */ - private OverviewModeObserver mOverviewModeObserver; - /** Currently observed tab. */ - private Tab mCurrentTab; - /** Last URL loaded in the observed tab. */ - private String mLastUrl; - /** Start time for the page that is observed. */ - private long mStartTimeMs; - /** Whether the page is showing anything. */ - private boolean mPageDidPaint; - /** The source of the navigation. */ - @NavigationSource - private int mNavigationSource; - /** Track when the timer is paused, which happens if the tab is hidden. */ - private boolean mIsPaused; - /** When the timer is paused, track when the pause began. */ - private long mPauseStartTimeMs; - /** Keep a cumulative duration of page not being visible. */ - private long mPauseDuration; - - public PageViewTimer(TabModelSelector tabModelSelector) { - this(tabModelSelector, null); - } - - public PageViewTimer( - TabModelSelector tabModelSelector, OverviewModeBehavior overviewModeBehavior) { - mOverviewModeBehavior = overviewModeBehavior; - if (mOverviewModeBehavior != null) { - mOverviewModeObserver = new EmptyOverviewModeObserver() { - @Override - public void onOverviewModeStartedShowing(boolean showToolbar) { - pauseMeasuring(); - } - - @Override - public void onOverviewModeFinishedHiding() { - resumeMeasuring(); - } - }; - mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver); - } - - mTabObserver = new EmptyTabObserver() { - @Override - public void onShown(Tab tab, @TabSelectionType int type) { - resumeMeasuring(); - } - - @Override - public void onHidden(Tab tab, @TabHidingType int type) { - pauseMeasuring(); - } - - @Override - public void onUpdateUrl(Tab tab, String url) { - assert tab == mCurrentTab; - - // In the current implementation, when the user refreshes a page or navigates to a - // fragment on the page, it is still part of the same page view. - if (UrlUtilities.urlsMatchIgnoringFragments(url, mLastUrl)) return; - - maybeReportViewTime(); - maybeStartMeasuring(url, !tab.isLoading(), tab.getWebContents()); - } - - @Override - public void didFirstVisuallyNonEmptyPaint(Tab tab) { - assert tab == mCurrentTab; - mPageDidPaint = true; - } - - @Override - public void onPageLoadFinished(Tab tab, String url) { - assert tab == mCurrentTab; - mPageDidPaint = true; - } - - @Override - public void onLoadStopped(Tab tab, boolean toDifferentDocument) { - assert tab == mCurrentTab; - mPageDidPaint = true; - } - }; - - mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) { - @Override - public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { - assert tab != null; - if (tab == mCurrentTab) return; - - // If the tab switcher is entered, then the same tab is selected again, resume - // instead of reporting/resetting. - if (UrlUtilities.urlsMatchIgnoringFragments(tab.getUrl(), mLastUrl)) return; - - maybeReportViewTime(); - switchObserverToTab(tab); - maybeStartMeasuring(tab.getUrl(), !tab.isLoading(), tab.getWebContents()); - } - - @Override - public void willCloseTab(Tab tab, boolean animate) { - assert tab != null; - if (tab != mCurrentTab) return; - - maybeReportViewTime(); - switchObserverToTab(null); - } - - @Override - public void tabRemoved(Tab tab) { - assert tab != null; - if (tab != mCurrentTab) return; - - maybeReportViewTime(); - switchObserverToTab(null); - } - }; - } - - /** Destroys the PageViewTimer. */ - public void destroy() { - maybeReportViewTime(); - switchObserverToTab(null); - mTabModelObserver.destroy(); - - // Remove the observer if it's been set. - if (mOverviewModeBehavior != null) { - mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver); - } - } - - private void maybeReportViewTime() { - if (mLastUrl != null && mStartTimeMs != 0 && mPageDidPaint) { - long durationMs = SystemClock.uptimeMillis() - mStartTimeMs - mPauseDuration; - reportDurationRaw(durationMs); - reportDurationBucket(calculateDurationBucket(durationMs)); - } - - // Reporting triggers every time the user would see something new, therefore we clean up - // reporting state every time. - mLastUrl = null; - mStartTimeMs = 0; - mPageDidPaint = false; - mIsPaused = false; - mNavigationSource = NavigationSource.OTHER; - mPauseDuration = 0; - mPauseStartTimeMs = 0; - } - - private void reportDurationRaw(long durationMs) { - RecordHistogram.recordLongTimesHistogram100( - "ContextualSuggestions.PageViewTime", durationMs); - if (mNavigationSource == NavigationSource.CONTEXTUAL_SUGGESTIONS) { - RecordHistogram.recordLongTimesHistogram100( - "ContextualSuggestions.PageViewTime.ContextualSuggestions", durationMs); - return; - } - - RecordHistogram.recordLongTimesHistogram100( - "ContextualSuggestions.PageViewTime.Other", durationMs); - } - - private void reportDurationBucket(@DurationBucket int durationBucket) { - if (mNavigationSource == NavigationSource.CONTEXTUAL_SUGGESTIONS) { - RecordHistogram.recordEnumeratedHistogram( - "ContextualSuggestions.PageViewClickLength.ContextualSuggestions", - durationBucket, DurationBucket.NUM_ENTRIES); - return; - } - - RecordHistogram.recordEnumeratedHistogram("ContextualSuggestions.PageViewClickLength.Other", - durationBucket, DurationBucket.NUM_ENTRIES); - } - - private void switchObserverToTab(Tab tab) { - if (mCurrentTab != tab && mCurrentTab != null) { - mCurrentTab.removeObserver(mTabObserver); - } - - mCurrentTab = tab; - if (mCurrentTab != null) { - mCurrentTab.addObserver(mTabObserver); - } - } - - private void maybeStartMeasuring(String url, boolean isLoaded, WebContents webContents) { - if (!URLUtil.isHttpUrl(url) && !URLUtil.isHttpsUrl(url)) return; - - mLastUrl = url; - mStartTimeMs = SystemClock.uptimeMillis(); - mPageDidPaint = isLoaded; - mNavigationSource = getNavigationSource(webContents); - } - - private void pauseMeasuring() { - if (mIsPaused) return; - - mIsPaused = true; - mPauseStartTimeMs = SystemClock.uptimeMillis(); - } - - private void resumeMeasuring() { - if (!mIsPaused) return; - - mIsPaused = false; - mPauseDuration += SystemClock.uptimeMillis() - mPauseStartTimeMs; - } - - @VisibleForTesting - public @NavigationSource int getNavigationSource(WebContents webContents) { - NavigationController navigationController = webContents.getNavigationController(); - NavigationEntry navigationEntry = navigationController.getEntryAtIndex( - navigationController.getLastCommittedEntryIndex()); - if (navigationEntry == null) { - return NavigationSource.OTHER; - } - - String referrer = navigationEntry.getReferrerUrl(); - // TODO(fgorski): Share this with other declarations of the referrer. - if ("https://goto.google.com/explore-on-content-viewer".equals(referrer)) { - return NavigationSource.CONTEXTUAL_SUGGESTIONS; - } - - return NavigationSource.OTHER; - } - - @VisibleForTesting - public @DurationBucket int calculateDurationBucket(long durationMs) { - if (durationMs <= SHORT_BUCKET_THRESHOLD_MS) return DurationBucket.SHORT_CLICK; - if (durationMs <= MEDIUM_BUCKET_THRESHOLD_MS) return DurationBucket.MEDIUM_CLICK; - - return DurationBucket.LONG_CLICK; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/PeekConditions.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/PeekConditions.java deleted file mode 100644 index c820af6..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/PeekConditions.java +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -/** Encapsulates server-provided conditions for "peeking" the contextual suggestions UI. */ -public class PeekConditions { - private final float mConfidence; - private final float mPageScrollPercentage; - private final float mMinimumSecondsOnPage; - private final float mMaximumNumberOfPeeks; - - public PeekConditions() { - this(0, 0, 0, 0); - } - - /** - * Constructs a new PeekConditions. - * @param confidence The confidence of the results that were returned. - * @param pageScrollPercentage The percentage of the page that the user scrolls required - * for an auto peek to occur. - * @param minimumSecondsOnPage The minimum time (seconds) the user spends on the page - * required for auto peek. - * @param maximumNumberOfPeeks The maximum number of auto peeks that we can show for this - * page. - */ - public PeekConditions(float confidence, float pageScrollPercentage, float minimumSecondsOnPage, - float maximumNumberOfPeeks) { - mConfidence = confidence; - mPageScrollPercentage = pageScrollPercentage; - mMinimumSecondsOnPage = minimumSecondsOnPage; - mMaximumNumberOfPeeks = maximumNumberOfPeeks; - } - - /** @return The confidence of the results that were returned.*/ - public float getConfidence() { - return mConfidence; - } - - /** - * @return The percentage of the page that the user scrolls required for an auto peek to occur. - */ - public float getPageScrollPercentage() { - return mPageScrollPercentage; - } - - /** @return The minimum time (seconds) the user spends on the page required for auto peek. */ - public float getMinimumSecondsOnPage() { - return mMinimumSecondsOnPage; - } - - /** @return The maximum number of auto peeks that we can show for this page. */ - public float getMaximumNumberOfPeeks() { - return mMaximumNumberOfPeeks; - } -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarCoordinator.java deleted file mode 100644 index d3f2776..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarCoordinator.java +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModel.PropertyKey; -import org.chromium.ui.modelutil.PropertyModelChangeProcessor; - -/** - * Coordinator for the toolbar sub-component. Responsible for communication with the parent - * {@link ContextualSuggestionsCoordinator} and lifecycle of sub-component objects. - */ -class ToolbarCoordinator { - private final ToolbarView mToolbarView; - private final PropertyModelChangeProcessor<ContextualSuggestionsModel, ToolbarView, PropertyKey> - mModelChangeProcessor; - - /** - * Construct a new {@link ToolbarCoordinator}. - * @param context The {@link Context} used to retrieve resources. - * @param parentView The parent {@link View} to which the content will eventually be attached. - * @param model The {@link ContextualSuggestionsModel} for the component. - */ - ToolbarCoordinator(Context context, ViewGroup parentView, ContextualSuggestionsModel model) { - mToolbarView = (ToolbarView) LayoutInflater.from(context).inflate( - R.layout.contextual_suggestions_toolbar, parentView, false); - - mModelChangeProcessor = - PropertyModelChangeProcessor.create(model, mToolbarView, new ToolbarViewBinder()); - } - - /** @return The content {@link View}. */ - View getView() { - return mToolbarView; - } - - /** Destroy the toolbar component. */ - void destroy() { - mModelChangeProcessor.destroy(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarView.java deleted file mode 100644 index 0663217..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarView.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.ListMenuButton; - -/** The toolbar view, containing an icon, title and close button. */ -public class ToolbarView extends FrameLayout { - private View mCloseButton; - private ListMenuButton mMenuButton; - private TextView mTitle; - private View mShadow; - - public ToolbarView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - mCloseButton = findViewById(R.id.close_button); - mMenuButton = findViewById(R.id.more); - mTitle = (TextView) findViewById(R.id.title); - mShadow = findViewById(R.id.shadow); - } - - void setCloseButtonOnClickListener(OnClickListener listener) { - mCloseButton.setOnClickListener(listener); - } - - void setMenuButtonDelegate(ListMenuButton.Delegate delegate) { - mMenuButton.setDelegate(delegate); - } - - void setTitle(String title) { - mTitle.setText(title); - } - - void setShadowVisibility(boolean visible) { - mShadow.setVisibility(visible ? View.VISIBLE : View.GONE); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarViewBinder.java deleted file mode 100644 index 243d1c2..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ToolbarViewBinder.java +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModel.PropertyKey; -import org.chromium.ui.modelutil.PropertyModelChangeProcessor; - -/** - * A view binder for use with a {@link ToolbarView}. - */ -class ToolbarViewBinder - implements PropertyModelChangeProcessor - .ViewBinder<ContextualSuggestionsModel, ToolbarView, PropertyKey> { - @Override - public void bind(ContextualSuggestionsModel model, ToolbarView view, PropertyKey propertyKey) { - if (propertyKey == PropertyKey.CLOSE_BUTTON_ON_CLICK_LISTENER) { - view.setCloseButtonOnClickListener(model.getCloseButtonOnClickListener()); - } else if (propertyKey == PropertyKey.MENU_BUTTON_DELEGATE) { - view.setMenuButtonDelegate(model.getMenuButtonDelegate()); - } else if (propertyKey == PropertyKey.TITLE) { - view.setTitle(model.getTitle()); - } else if (propertyKey == PropertyKey.TOOLBAR_SHADOW_VISIBILITY) { - view.setShadowVisibility(model.getToolbarShadowVisibility()); - } else { - assert false : "Unhandled property detected."; - } - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index b0372474..d7058b1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -53,9 +53,7 @@ import org.chromium.chrome.browser.browserservices.BrowserSessionContentHandler; import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController; -import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabFactory; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider; @@ -795,15 +793,19 @@ super.initializeToolbar(); if (mIntentDataProvider.isMediaViewer()) { getToolbarManager().setToolbarShadowVisibility(View.GONE); - - // The media viewer has no default menu items, so if there are also no custom items, we - // should hide the menu button altogether. - if (mIntentDataProvider.getMenuTitles().isEmpty()) { - getToolbarManager().getToolbar().disableMenuButton(); - } } } + @Override + public boolean supportsAppMenu() { + // The media viewer has no default menu items, so if there are also no custom items, we + // should disable the menu altogether. + if (mIntentDataProvider.isMediaViewer() && mIntentDataProvider.getMenuTitles().isEmpty()) { + return false; + } + return super.supportsAppMenu(); + } + /** * Show the web page with CustomTabActivity, without any navigation control. * Used in showing the terms of services page or help pages for Chrome. @@ -875,18 +877,18 @@ @Override public void closeAllIncognitoTabs() { - mNavigationController.finish(FinishReason.OTHER); + mNavigationController.finish(CustomTabActivityNavigationController.FinishReason.OTHER); } } @Override - protected CustomTabActivityComponent createComponent(ChromeActivityCommonsModule commonsModule, - ContextualSuggestionsModule contextualSuggestionsModule) { + protected CustomTabActivityComponent createComponent( + ChromeActivityCommonsModule commonsModule) { CustomTabActivityModule customTabsModule = new CustomTabActivityModule(mIntentDataProvider); - CustomTabActivityComponent component = ChromeApplication.getComponent() - .createCustomTabActivityComponent(commonsModule, contextualSuggestionsModule, - customTabsModule); + CustomTabActivityComponent component = + ChromeApplication.getComponent().createCustomTabActivityComponent( + commonsModule, customTabsModule); mTabObserverRegistrar = component.resolveTabObserverRegistrar(); mTabController = component.resolveTabController();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java index f7823ef..8365bc3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -247,6 +247,10 @@ }); } + /** + * This method remove bottomBarView completely. + * If you need to hide it temporarily use {@link #hideBottomBar(boolean)}. + */ private void hideBottomBar() { if (mBottomBarView == null) return; mBottomBarView.animate().alpha(0f).translationY(mBottomBarView.getHeight()) @@ -348,7 +352,18 @@ boolean keyboardExtensionHidesBottomBar = mActivity.getManualFillingComponent().getKeyboardExtensionViewResizer().getHeight() > 0; - if (keyboardExtensionHidesBottomBar) { + hideBottomBar(keyboardExtensionHidesBottomBar); + } + + /** + * This method temporarily hides bottomBarView. + * + * If you need to remove bottom bar completely use {@link #hideBottomBar()}. + * + * @param hidesBottomBar whether bottom bar needs to be hidden. + */ + public void hideBottomBar(boolean hidesBottomBar) { + if (hidesBottomBar) { getBottomBarView().setVisibility(View.GONE); mFullscreenManager.setBottomControlsHeight(0); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java index abbe913..3079ce0f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.customtabs.dependency_injection; import org.chromium.chrome.browser.browserservices.trustedwebactivityui.TrustedWebActivityCoordinator; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; import org.chromium.chrome.browser.customtabs.CustomTabActivityLifecycleUmaTracker; import org.chromium.chrome.browser.customtabs.CustomTabBottomBarDelegate; import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy; @@ -28,8 +27,7 @@ * Activity-scoped component associated with * {@link org.chromium.chrome.browser.customtabs.CustomTabActivity}. */ -@Subcomponent(modules = {ChromeActivityCommonsModule.class, ContextualSuggestionsModule.class, - CustomTabActivityModule.class}) +@Subcomponent(modules = {ChromeActivityCommonsModule.class, CustomTabActivityModule.class}) @ActivityScope public interface CustomTabActivityComponent extends ChromeActivityComponent { TrustedWebActivityCoordinator resolveTrustedWebActivityCoordinator();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java index 2246704b..032271f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java
@@ -47,6 +47,7 @@ import org.chromium.content_public.browser.NavigationHandle; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.KeyboardVisibilityDelegate; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -155,7 +156,7 @@ private final DynamicModuleNavigationEventObserver mModuleNavigationEventObserver = new DynamicModuleNavigationEventObserver(); private final DynamicModulePageLoadObserver mPageLoadObserver; - + private final KeyboardVisibilityDelegate.KeyboardVisibilityListener mKeyboardVisibilityListener; private final PageCriteria mPageCriteria; @Inject @@ -196,6 +197,11 @@ closeButtonNavigator.setLandingPageCriteria(mPageCriteria); mNavigationController.setBackHandler(this::onBackPressedAsync); + mKeyboardVisibilityListener = isShowing -> + mBottomBarDelegate.get().hideBottomBar(isShowing); + KeyboardVisibilityDelegate.getInstance() + .addKeyboardVisibilityListener(mKeyboardVisibilityListener); + activityLifecycleDispatcher.register(this); } @@ -495,6 +501,8 @@ unregisterObserver(mHeaderVisibilityObserver); unregisterObserver(mCustomRequestHeaderModifier); PageLoadMetrics.removeObserver(mPageLoadObserver); + KeyboardVisibilityDelegate.getInstance() + .removeKeyboardVisibilityListener(mKeyboardVisibilityListener); } private void unregisterObserver(TabObserver observer) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityComponent.java index 2f96c8eb..93eabab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityComponent.java
@@ -4,14 +4,13 @@ package org.chromium.chrome.browser.dependency_injection; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; - import dagger.Subcomponent; /** * Activity-scoped component associated with {@link org.chromium.chrome.browser.ChromeActivity}. */ -@Subcomponent(modules = {ChromeActivityCommonsModule.class, ContextualSuggestionsModule.class}) +// TODO(crbug.com/954585): Remove this and fix dependencies. +@Subcomponent(modules = {ChromeActivityCommonsModule.class}) @ActivityScope public interface ChromeActivityComponent { ChromeAppComponent getParent();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java index 6c39a3c..c881e96 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java
@@ -9,8 +9,6 @@ import org.chromium.chrome.browser.browserservices.TrustedWebActivityClient; import org.chromium.chrome.browser.browserservices.permissiondelegation.NotificationPermissionUpdater; import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionManager; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; -import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor; import org.chromium.chrome.browser.customtabs.CustomTabsClientFileProcessor; import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityComponent; @@ -28,11 +26,9 @@ @Component(modules = {ChromeAppModule.class, AppHooksModule.class}) @Singleton public interface ChromeAppComponent { - ChromeActivityComponent createChromeActivityComponent(ChromeActivityCommonsModule module, - ContextualSuggestionsModule contextualSuggestionsModule); + ChromeActivityComponent createChromeActivityComponent(ChromeActivityCommonsModule module); CustomTabActivityComponent createCustomTabActivityComponent(ChromeActivityCommonsModule module, - ContextualSuggestionsModule contextualSuggestionsModule, CustomTabActivityModule customTabActivityModule); CustomTabsConnection resolveCustomTabsConnection(); @@ -42,10 +38,6 @@ NotificationPermissionUpdater resolveTwaPermissionUpdater(); TrustedWebActivityClient resolveTrustedWebActivityClient(); - // Temporary getters for DI migration process. All of these getters - // should eventually be replaced with constructor injection. - EnabledStateMonitor resolveContextualSuggestionsEnabledStateMonitor(); - ExternalAuthUtils resolveExternalAuthUtils(); CustomTabsClientFileProcessor resolveCustomTabsFileProcessor();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java index 2bbf822..5fe32b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java
@@ -13,8 +13,6 @@ import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.WarmupManager; import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionStore; -import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor; -import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitorImpl; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.notifications.channels.SiteChannelsManager; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; @@ -40,13 +38,6 @@ public Profile provideLastUsedProfile() { return Profile.getLastUsedProfile(); } - - @Provides - @Singleton - public EnabledStateMonitor provideEnabledStateMonitor() { - return new EnabledStateMonitorImpl(); - } - @Provides public ChromePreferenceManager providesChromePreferenceManager() { return ChromePreferenceManager.getInstance();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java index d05a052..26d3ac0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java
@@ -21,7 +21,6 @@ // All UMA client names collected here to prevent duplicates. public static final String ASSISTANT_DETAILS_UMA_CLIENT_NAME = "AssistantDetails"; public static final String ASSISTANT_INFO_BOX_UMA_CLIENT_NAME = "AssistantInfoBox"; - public static final String CONTEXTUAL_SUGGESTIONS_UMA_CLIENT_NAME = "ContextualSuggestions"; public static final String FEED_UMA_CLIENT_NAME = "Feed"; public static final String NTP_ANIMATED_LOGO_UMA_CLIENT_NAME = "NewTabPageAnimatedLogo";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java index 7fc4b95d..16e176f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java
@@ -185,8 +185,9 @@ } /** @return whether a snippet is a contextual suggestion. */ + // TODO(crbug.com/959307): Remove this function from the codebase. public boolean isContextual() { - return mCategory == KnownCategories.CONTEXTUAL; + return false; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java index c5d9e45..132b5a43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
@@ -161,7 +161,7 @@ } protected SuggestionsBinder createBinder(SuggestionsUiDelegate uiDelegate) { - return new SuggestionsBinder(itemView, uiDelegate, false); + return new SuggestionsBinder(itemView, uiDelegate); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreference.java deleted file mode 100644 index fede6cd..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreference.java +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.preferences; - -import android.content.Context; -import android.os.Bundle; -import android.preference.PreferenceFragment; -import android.support.annotation.Nullable; -import android.text.SpannableString; -import android.text.style.ImageSpan; - -import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.ChromeApplication; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsBridge; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsEnabledStateUtils; -import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor; -import org.chromium.chrome.browser.signin.AccountSigninActivity; -import org.chromium.chrome.browser.signin.SigninAccessPoint; -import org.chromium.chrome.browser.signin.SigninActivity; -import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge; -import org.chromium.chrome.browser.sync.ui.SyncCustomizationFragment; -import org.chromium.chrome.browser.widget.TintedDrawable; -import org.chromium.components.signin.ChromeSigninController; -import org.chromium.ui.text.NoUnderlineClickableSpan; -import org.chromium.ui.text.SpanApplier; - -/** - * Fragment to manage the Contextual Suggestions preference and to explain to the user what it does. - */ -public class ContextualSuggestionsPreference - extends PreferenceFragment implements EnabledStateMonitor.Observer { - static final String PREF_CONTEXTUAL_SUGGESTIONS_SWITCH = "contextual_suggestions_switch"; - private static final String PREF_CONTEXTUAL_SUGGESTIONS_DESCRIPTION = - "contextual_suggestions_description"; - private static final String PREF_CONTEXTUAL_SUGGESTIONS_MESSAGE = - "contextual_suggestions_message"; - - private ChromeSwitchPreference mSwitch; - private EnabledStateMonitor mEnabledStateMonitor; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - PreferenceUtils.addPreferencesFromResource(this, R.xml.contextual_suggestions_preferences); - getActivity().setTitle(R.string.prefs_contextual_suggestions); - - mSwitch = (ChromeSwitchPreference) findPreference(PREF_CONTEXTUAL_SUGGESTIONS_SWITCH); - mEnabledStateMonitor = - ChromeApplication.getComponent().resolveContextualSuggestionsEnabledStateMonitor(); - mEnabledStateMonitor.addObserver(this); - onSettingsStateChanged(mEnabledStateMonitor.getSettingsEnabled()); - initialize(); - } - - @Override - public void onResume() { - super.onResume(); - updateSwitch(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - mEnabledStateMonitor.removeObserver(this); - } - - @Override - public void onEnabledStateChanged(boolean enabled) {} - - @Override - public void onSettingsStateChanged(boolean enabled) { - if (mEnabledStateMonitor != null) updateSwitch(); - } - - /** Helper method to initialize the switch preference and the message preference. */ - private void initialize() { - Context context = getActivity(); - final TextMessagePreference message = - (TextMessagePreference) findPreference(PREF_CONTEXTUAL_SUGGESTIONS_MESSAGE); - - // Show a message prompting the user to turn on required settings. If unified consent is - // enabled, and the proper settings are already enabled, show nothing. - boolean isUnifiedConsentEnabled = - ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT); - boolean isSignedIn = ChromeSigninController.get().isSignedIn(); - if (!isUnifiedConsentEnabled || !isSignedIn - || !UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionEnabled()) { - final NoUnderlineClickableSpan span = - new NoUnderlineClickableSpan(context.getResources(), (widget) -> { - if (isUnifiedConsentEnabled) { - if (isSignedIn) { - PreferencesLauncher.launchSettingsPage(context, - SyncAndServicesPreferences.class, - SyncAndServicesPreferences.createArguments(false)); - } else { - startActivity(SigninActivity.createIntentForPromoChooseAccountFlow( - context, SigninAccessPoint.SETTINGS, null)); - } - } else { - if (isSignedIn) { - PreferencesLauncher.launchSettingsPage( - context, SyncCustomizationFragment.class); - } else { - startActivity( - AccountSigninActivity.createIntentForDefaultSigninFlow( - context, SigninAccessPoint.SETTINGS, false)); - } - } - }); - final SpannableString spannable = SpanApplier.applySpans( - getResources().getString(isUnifiedConsentEnabled - ? R.string.contextual_suggestions_message_unified_consent - : R.string.contextual_suggestions_message), - new SpanApplier.SpanInfo("<link>", "</link>", span)); - message.setTitle(spannable); - } - - final TextMessagePreference description = - (TextMessagePreference) findPreference(PREF_CONTEXTUAL_SUGGESTIONS_DESCRIPTION); - if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON)) { - TintedDrawable drawable = TintedDrawable.constructTintedDrawable( - context, R.drawable.contextual_suggestions, R.color.default_icon_color); - drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - final ImageSpan imageSpan = new ImageSpan(drawable); - final SpannableString imageSpannable = SpanApplier.applySpans( - getResources().getString( - R.string.contextual_suggestions_description_toolbar_button), - new SpanApplier.SpanInfo("<icon>", "</icon>", imageSpan)); - description.setTitle(imageSpannable); - } else { - description.setTitle( - getResources().getString(R.string.contextual_suggestions_description)); - } - - updateSwitch(); - mSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - boolean enabled = (boolean) newValue; - PrefServiceBridge.getInstance().setBoolean( - Pref.CONTEXTUAL_SUGGESTIONS_ENABLED, enabled); - - ContextualSuggestionsEnabledStateUtils.recordPreferenceEnabled(enabled); - if (enabled) { - RecordUserAction.record("ContextualSuggestions.Preference.Enabled"); - } else { - RecordUserAction.record("ContextualSuggestions.Preference.Disabled"); - } - return true; - }); - mSwitch.setManagedPreferenceDelegate( - preference -> ContextualSuggestionsBridge.isDisabledByEnterprisePolicy()); - } - - /** Helper method to update the enabled state of the switch. */ - private void updateSwitch() { - mSwitch.setEnabled(mEnabledStateMonitor.getSettingsEnabled()); - mSwitch.setChecked(mEnabledStateMonitor.getEnabledState()); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java index e2b7cea..839b1ec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -16,7 +16,6 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsEnabledStateUtils; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.night_mode.NightModeUtils; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; @@ -44,7 +43,6 @@ public static final String PREF_SYNC_AND_SERVICES = "sync_and_services"; public static final String PREF_SEARCH_ENGINE = "search_engine"; public static final String PREF_SAVED_PASSWORDS = "saved_passwords"; - public static final String PREF_CONTEXTUAL_SUGGESTIONS = "contextual_suggestions"; public static final String PREF_HOMEPAGE = "homepage"; public static final String PREF_UI_THEME = "ui_theme"; public static final String PREF_DATA_REDUCTION = "data_reduction"; @@ -216,16 +214,6 @@ removePreferenceIfPresent(PREF_HOMEPAGE); } - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT) - && FeatureUtilities.areContextualSuggestionsEnabled(getActivity()) - && ContextualSuggestionsEnabledStateUtils.shouldShowSettings()) { - Preference contextualSuggestions = addPreferenceIfAbsent(PREF_CONTEXTUAL_SUGGESTIONS); - setOnOffSummary(contextualSuggestions, - ContextualSuggestionsEnabledStateUtils.getEnabledState()); - } else { - removePreferenceIfPresent(PREF_CONTEXTUAL_SUGGESTIONS); - } - if (NightModeUtils.isNightModeSupported() && FeatureUtilities.isNightModeAvailable()) { addPreferenceIfAbsent(PREF_UI_THEME); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java index 785b603..5740ebb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -36,7 +36,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.PostTask; import org.chromium.chrome.R; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsEnabledStateUtils; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.invalidation.InvalidationController; @@ -49,7 +48,6 @@ import org.chromium.chrome.browser.sync.GoogleServiceAuthError; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.ui.PassphraseDialogFragment; -import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.ChromeSigninController; @@ -90,7 +88,6 @@ private static final String PREF_USAGE_AND_CRASH_REPORTING = "usage_and_crash_reports"; private static final String PREF_URL_KEYED_ANONYMIZED_DATA = "url_keyed_anonymized_data"; private static final String PREF_CONTEXTUAL_SEARCH = "contextual_search"; - private static final String PREF_CONTEXTUAL_SUGGESTIONS = "contextual_suggestions"; @IntDef({SyncError.NO_ERROR, SyncError.ANDROID_SYNC_DISABLED, SyncError.AUTH_ERROR, SyncError.PASSPHRASE_REQUIRED, SyncError.CLIENT_OUT_OF_DATE, SyncError.OTHER_ERRORS}) @@ -127,7 +124,6 @@ private ChromeSwitchPreference mUsageAndCrashReporting; private ChromeSwitchPreference mUrlKeyedAnonymizedData; private @Nullable Preference mContextualSearch; - private @Nullable Preference mContextualSuggestions; private ProfileSyncService.SyncSetupInProgressHandle mSyncSetupInProgressHandle; @@ -213,13 +209,6 @@ mContextualSearch = null; } - mContextualSuggestions = findPreference(PREF_CONTEXTUAL_SUGGESTIONS); - if (!FeatureUtilities.areContextualSuggestionsEnabled(getActivity()) - || !ContextualSuggestionsEnabledStateUtils.shouldShowSettings()) { - removePreference(servicesCategory, mContextualSuggestions); - mContextualSuggestions = null; - } - // Prevent sync settings changes from taking effect until the user leaves this screen. mSyncSetupInProgressHandle = mProfileSyncService.getSetupInProgressHandle(); @@ -511,12 +500,6 @@ mContextualSearch.setSummary( isContextualSearchEnabled ? R.string.text_on : R.string.text_off); } - - if (mContextualSuggestions != null) { - mContextualSuggestions.setSummary( - ContextualSuggestionsEnabledStateUtils.getEnabledState() ? R.string.text_on - : R.string.text_off); - } } private void updateSyncPreferences() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingException.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingException.java index 8278b86..488d58b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingException.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingException.java
@@ -72,6 +72,10 @@ return mContentSetting; } + public int getContentSettingType() { + return mContentSettingType; + } + /** * Sets the content setting value for this exception. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java index eebcc37..6c751d5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java
@@ -7,6 +7,7 @@ import android.util.Pair; import org.chromium.base.Callback; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ContentSettingsType; import java.util.ArrayList; @@ -20,6 +21,8 @@ * that the user has set for them. */ public class WebsitePermissionsFetcher { + private WebsitePreferenceBridge mWebsitePreferenceBridge; + /** * A callback to pass to WebsitePermissionsFetcher. This is run when the * website permissions have been fetched. @@ -82,6 +85,7 @@ */ public WebsitePermissionsFetcher(boolean fetchSiteImportantInfo) { mFetchSiteImportantInfo = fetchSiteImportantInfo; + mWebsitePreferenceBridge = new WebsitePreferenceBridge(); } /** @@ -259,7 +263,7 @@ + contentSettingsType; for (ContentSettingException exception : - WebsitePreferenceBridge.getContentSettingsExceptions(contentSettingsType)) { + mWebsitePreferenceBridge.getContentSettingsExceptions(contentSettingsType)) { // The pattern "*" represents the default setting, not a specific website. if (exception.getPattern().equals("*")) continue; String address = exception.getPattern(); @@ -306,7 +310,7 @@ @Override public void run() { - for (PermissionInfo info : WebsitePreferenceBridge.getPermissionInfo(mType)) { + for (PermissionInfo info : mWebsitePreferenceBridge.getPermissionInfo(mType)) { String origin = info.getOrigin(); if (origin == null) continue; String embedder = mType == PermissionInfo.Type.SENSORS ? null : info.getEmbedder(); @@ -327,7 +331,7 @@ if (mChooserDataType == -1) return; for (ChosenObjectInfo info : - WebsitePreferenceBridge.getChosenObjectInfo(mChooserDataType)) { + mWebsitePreferenceBridge.getChosenObjectInfo(mChooserDataType)) { String origin = info.getOrigin(); if (origin == null) continue; findOrCreateSite(origin, info.getEmbedder()).addChosenObjectInfo(info); @@ -351,7 +355,7 @@ private class LocalStorageInfoFetcher extends Task { @Override public void runAsync(final TaskQueue queue) { - WebsitePreferenceBridge.fetchLocalStorageInfo(new Callback<HashMap>() { + mWebsitePreferenceBridge.fetchLocalStorageInfo(new Callback<HashMap>() { @Override public void onResult(HashMap result) { for (Object o : result.entrySet()) { @@ -371,7 +375,7 @@ private class WebStorageInfoFetcher extends Task { @Override public void runAsync(final TaskQueue queue) { - WebsitePreferenceBridge.fetchStorageInfo(new Callback<ArrayList>() { + mWebsitePreferenceBridge.fetchStorageInfo(new Callback<ArrayList>() { @Override public void onResult(ArrayList result) { @SuppressWarnings("unchecked") @@ -400,4 +404,10 @@ mCallback.onWebsitePermissionsAvailable(mSites.values()); } } + + @VisibleForTesting + public void setWebsitePreferenceBridgeForTesting( + WebsitePreferenceBridge websitePreferenceBridge) { + mWebsitePreferenceBridge = websitePreferenceBridge; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java index 81c93631..5dbb2048 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java
@@ -16,9 +16,7 @@ /** * Utility class that interacts with native to retrieve and set website settings. */ -public abstract class WebsitePreferenceBridge { - private static final String LOG_TAG = "WebsiteSettingsUtils"; - +public class WebsitePreferenceBridge { /** * Interface for an object that listens to storage info is cleared callback. */ @@ -31,7 +29,7 @@ * @return the list of all origins that have permissions in non-incognito mode. */ @SuppressWarnings("unchecked") - public static List<PermissionInfo> getPermissionInfo(@PermissionInfo.Type int type) { + public List<PermissionInfo> getPermissionInfo(@PermissionInfo.Type int type) { ArrayList<PermissionInfo> list = new ArrayList<PermissionInfo>(); // Camera, Location & Microphone can be managed by the custodian // of a supervised account or by enterprise policy. @@ -144,7 +142,7 @@ .put(origin, new LocalStorageInfo(origin, size, important)); } - public static List<ContentSettingException> getContentSettingsExceptions( + public List<ContentSettingException> getContentSettingsExceptions( @ContentSettingsType int contentSettingsType) { List<ContentSettingException> exceptions = PrefServiceBridge.getInstance().getContentSettingsExceptions( @@ -163,11 +161,11 @@ return managedExceptions; } - public static void fetchLocalStorageInfo(Callback<HashMap> callback, boolean fetchImportant) { + public void fetchLocalStorageInfo(Callback<HashMap> callback, boolean fetchImportant) { nativeFetchLocalStorageInfo(callback, fetchImportant); } - public static void fetchStorageInfo(Callback<ArrayList> callback) { + public void fetchStorageInfo(Callback<ArrayList> callback) { nativeFetchStorageInfo(callback); } @@ -178,7 +176,7 @@ * two origin/embedder pairs have permission for the same object there will be two * ChosenObjectInfo instances. */ - public static List<ChosenObjectInfo> getChosenObjectInfo( + public List<ChosenObjectInfo> getChosenObjectInfo( @ContentSettingsType int contentSettingsType) { ArrayList<ChosenObjectInfo> list = new ArrayList<ChosenObjectInfo>(); nativeGetChosenObjects(contentSettingsType, list);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java index 483799e..b4649e7b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java
@@ -29,7 +29,6 @@ import org.chromium.chrome.browser.compositor.animation.CompositorAnimationHandler; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.util.ViewUtils; /** * This class is directly connected to suggestions view holders. It takes over the responsibility @@ -44,13 +43,11 @@ private final ImageFetcher mImageFetcher; private final SuggestionsUiDelegate mUiDelegate; - private final boolean mIsContextual; protected final View mCardContainerView; private final LinearLayout mTextLayout; private final TextView mHeadlineTextView; - private final @Nullable TextView mSnippetTextView; - private final @Nullable TextView mPublisherTextView; + private final TextView mPublisherTextView; protected final TextView mAgeTextView; // TODO(twellington): Try to change this back to a TintedImageView. This was changed for a crash // in contextual suggestions that occurs when trying to mutate state when tinting a @@ -60,7 +57,6 @@ private final @Nullable ImageView mOfflineBadge; protected final @Nullable View mPublisherBar; private final int mThumbnailSize; - private final int mSmallThumbnailCornerRadius; boolean mShowThumbnail; boolean mHasVideoBadge; @@ -72,11 +68,8 @@ * Creates a new SuggestionsBinder. * @param cardContainerView The root container view for the card. * @param uiDelegate The interface between the suggestion surface and the rest of the browser. - * @param isContextual Whether this binder is used to bind contextual suggestions. */ - public SuggestionsBinder( - View cardContainerView, SuggestionsUiDelegate uiDelegate, boolean isContextual) { - mIsContextual = isContextual; + public SuggestionsBinder(View cardContainerView, SuggestionsUiDelegate uiDelegate) { mCardContainerView = cardContainerView; mUiDelegate = uiDelegate; mImageFetcher = uiDelegate.getImageFetcher(); @@ -84,7 +77,6 @@ mTextLayout = mCardContainerView.findViewById(R.id.text_layout); mThumbnailView = mCardContainerView.findViewById(R.id.article_thumbnail); mHeadlineTextView = mCardContainerView.findViewById(R.id.article_headline); - mSnippetTextView = mCardContainerView.findViewById(R.id.article_snippet); mPublisherTextView = mCardContainerView.findViewById(R.id.article_publisher); mAgeTextView = mCardContainerView.findViewById(R.id.article_age); mVideoBadge = mCardContainerView.findViewById(R.id.video_badge); @@ -92,13 +84,9 @@ mPublisherBar = mCardContainerView.findViewById(R.id.publisher_bar); mThumbnailSize = getThumbnailSize(); - mSmallThumbnailCornerRadius = mCardContainerView.getResources().getDimensionPixelSize( - R.dimen.default_rounded_corner_radius); } public void updateViewInformation(SnippetArticle suggestion) { - assert suggestion.isContextual() == mIsContextual; - mSuggestion = suggestion; mHeadlineTextView.setText(suggestion.mTitle); @@ -109,10 +97,6 @@ setFavicon(); setThumbnail(); - - if (mSnippetTextView != null) { - mSnippetTextView.setText(suggestion.mSnippet); - } } public void updateFieldsVisibility(boolean showHeadline, boolean showThumbnail, @@ -126,26 +110,20 @@ updateVisibilityForBadges(); mTextLayout.setMinimumHeight(showThumbnail ? mThumbnailSize : 0); - if (mPublisherBar != null) { - ViewGroup.MarginLayoutParams publisherBarParams = - (ViewGroup.MarginLayoutParams) mPublisherBar.getLayoutParams(); - if (showHeadline && !mIsContextual) { - // When we show a headline and not a description, we reduce the top margin of the - // publisher bar. - publisherBarParams.topMargin = mPublisherBar.getResources().getDimensionPixelSize( - R.dimen.snippets_publisher_margin_top); - } else { - // When there is no headline and no description, we remove the top margin of the - // publisher bar. - publisherBarParams.topMargin = 0; - } - mPublisherBar.setLayoutParams(publisherBarParams); - } - if (mSnippetTextView != null) { - mSnippetTextView.setVisibility(showSnippet ? View.VISIBLE : View.GONE); - mSnippetTextView.setMaxLines(MAX_SNIPPET_LINES); + ViewGroup.MarginLayoutParams publisherBarParams = + (ViewGroup.MarginLayoutParams) mPublisherBar.getLayoutParams(); + if (showHeadline) { + // When we show a headline and not a description, we reduce the top margin of the + // publisher bar. + publisherBarParams.topMargin = mPublisherBar.getResources().getDimensionPixelSize( + R.dimen.snippets_publisher_margin_top); + } else { + // When there is no headline and no description, we remove the top margin of the + // publisher bar. + publisherBarParams.topMargin = 0; } + mPublisherBar.setLayoutParams(publisherBarParams); } public void updateOfflineBadgeVisibility(boolean visible) { @@ -205,18 +183,13 @@ // Temporarily set placeholder and then fetch the thumbnail from a provider. mThumbnailView.setBackground(null); - if (mIsContextual) { - mThumbnailView.setImageResource( - R.drawable.contextual_suggestions_placeholder_thumbnail); - } else { - ColorDrawable colorDrawable = - new ColorDrawable(mSuggestion.getThumbnailDominantColor() != null - ? mSuggestion.getThumbnailDominantColor() - : ApiCompatibilityUtils.getColor(mThumbnailView.getResources(), - R.color.thumbnail_placeholder_on_primary_bg)); + ColorDrawable colorDrawable = + new ColorDrawable(mSuggestion.getThumbnailDominantColor() != null + ? mSuggestion.getThumbnailDominantColor() + : ApiCompatibilityUtils.getColor(mThumbnailView.getResources(), + R.color.thumbnail_placeholder_on_primary_bg)); - mThumbnailView.setImageDrawable(colorDrawable); - } + mThumbnailView.setImageDrawable(colorDrawable); // Fetch thumbnail for the current article. mImageFetcher.makeArticleThumbnailRequest( @@ -367,13 +340,8 @@ * @return The size of the thumbnail. */ protected int getThumbnailSize() { - if (mIsContextual) { - return mCardContainerView.getResources().getDimensionPixelSize( - R.dimen.snippets_thumbnail_size_small); - } else { - return mCardContainerView.getResources().getDimensionPixelSize( - R.dimen.snippets_thumbnail_size); - } + return mCardContainerView.getResources().getDimensionPixelSize( + R.dimen.snippets_thumbnail_size); } /** @@ -409,11 +377,7 @@ * @return A {@link Drawable} to give to the view. */ protected Drawable createThumbnailDrawable(Bitmap thumbnail) { - if (mIsContextual) { - return ViewUtils.createRoundedBitmapDrawable(thumbnail, mSmallThumbnailCornerRadius); - } else { - return ThumbnailGradient.createDrawableWithGradientIfNeeded( - thumbnail, mThumbnailView.getResources()); - } + return ThumbnailGradient.createDrawableWithGradientIfNeeded( + thumbnail, mThumbnailView.getResources()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java index 8e7c8ab..c3c96a95 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsConfig.java
@@ -42,10 +42,6 @@ private static final String DEFAULT_CONTENT_SUGGESTIONS_REFERRER_URL = "https://www.googleapis.com/auth/chrome-content-suggestions"; - /** Default value of referrer URL for contextual suggestions. */ - private static final String DEFAULT_CONTEXTUAL_SUGGESTIONS_REFERRER_URL = - "https://goto.google.com/explore-on-content-viewer"; - private SuggestionsConfig() {} /** @@ -96,13 +92,7 @@ */ public static String getReferrerUrl(String featureName) { assert ChromeFeatureList.NTP_ARTICLE_SUGGESTIONS.equals(featureName) - || ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS.equals(featureName) - || ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON.equals(featureName); - - if (ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON.equals(featureName)) { - return getReferrerUrlParamOrDefault( - featureName, DEFAULT_CONTEXTUAL_SUGGESTIONS_REFERRER_URL); - } + || ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS.equals(featureName); return getReferrerUrlParamOrDefault(featureName, DEFAULT_CONTENT_SUGGESTIONS_REFERRER_URL); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegate.java index 619843d..281ce63c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegate.java
@@ -96,15 +96,6 @@ ReferrerPolicy.ALWAYS)); } - // Set appropriate referrer for contextual suggestions to distinguish them from navigation - // from a page. - if (article.mCategory == KnownCategories.CONTEXTUAL) { - loadUrlParams.setReferrer( - new Referrer(SuggestionsConfig.getReferrerUrl( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON), - ReferrerPolicy.ALWAYS)); - } - Tab loadingTab = openUrl(windowOpenDisposition, loadUrlParams); if (loadingTab != null && !article.isContextual()) { SuggestionsMetrics.recordVisit(loadingTab, article);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index e29f1ca..0f109686 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -11,7 +11,6 @@ import android.os.Looper; import android.os.Message; import android.os.SystemClock; -import android.support.annotation.DrawableRes; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.StringRes; @@ -189,7 +188,7 @@ private TemplateUrlServiceObserver mTemplateUrlObserver; private LocationBar mLocationBar; private FindToolbarManager mFindToolbarManager; - private AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; + private @Nullable AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; private OverviewModeBehavior mOverviewModeBehavior; private LayoutManager mLayoutManager; @@ -899,9 +898,11 @@ if (tab == null) return; ChromeActivity activity = tab.getActivity(); - if (!mAppMenuPropertiesDelegate.isTranslateMenuItemVisible(tab)) return; - if (!TranslateBridge.shouldShowManualTranslateIPH(tab)) return; - + if (mAppMenuPropertiesDelegate == null + || !mAppMenuPropertiesDelegate.isTranslateMenuItemVisible(tab) + || !TranslateBridge.shouldShowManualTranslateIPH(tab)) { + return; + } // Find out if the help UI should appear. final Tracker tracker = TrackerFactory.getTrackerForProfile(tab.getProfile()); if (!tracker.shouldTriggerHelpUI(featureName)) return; @@ -983,7 +984,9 @@ mTabModelSelector.getModel(isIncognito).closeAllTabs(); }; - mAppMenuButtonHelper.setOnClickRunnable(() -> recordBottomToolbarUseForIPH()); + if (mAppMenuButtonHelper != null) { + mAppMenuButtonHelper.setOnClickRunnable(() -> recordBottomToolbarUseForIPH()); + } mBottomControlsCoordinator.initializeWithNative(mActivity, mActivity.getCompositorViewHolder().getResourceManager(), mActivity.getCompositorViewHolder().getLayoutManager(), @@ -1043,12 +1046,12 @@ /** * Enable the experimental toolbar button. * @param onClickListener The {@link OnClickListener} to be called when the button is clicked. - * @param drawableResId The resource id of the drawable to display for the button. + * @param image The drawable to display for the button. * @param contentDescriptionResId The resource id of the content description for the button. */ - public void enableExperimentalButton(OnClickListener onClickListener, - @DrawableRes int drawableResId, @StringRes int contentDescriptionResId) { - mToolbar.enableExperimentalButton(onClickListener, drawableResId, contentDescriptionResId); + public void enableExperimentalButton(OnClickListener onClickListener, Drawable image, + @StringRes int contentDescriptionResId) { + mToolbar.enableExperimentalButton(onClickListener, image, contentDescriptionResId); } /** @@ -1059,10 +1062,10 @@ } /** - * @return The experimental toolbar button if it exists. + * Updates image displayed on experimental button. */ - public @Nullable View getExperimentalButtonView() { - return mToolbar.getExperimentalButtonView(); + public void updateExperimentalButtonImage(Drawable image) { + mToolbar.updateExperimentalButtonImage(image); } /** @@ -1787,7 +1790,9 @@ if (profile != null) { mBookmarkBridge = new BookmarkBridge(profile); mBookmarkBridge.addObserver(mBookmarksObserver); - mAppMenuPropertiesDelegate.setBookmarkBridge(mBookmarkBridge); + if (mAppMenuPropertiesDelegate != null) { + mAppMenuPropertiesDelegate.setBookmarkBridge(mBookmarkBridge); + } mLocationBar.setAutocompleteProfile(profile); } mCurrentProfile = profile;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java index 6997d87..a9bf593 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarCoordinator.java
@@ -125,6 +125,7 @@ mTabSwitcherButtonCoordinator.setThemeColorProvider(themeColorProvider); mTabSwitcherButtonCoordinator.setTabCountProvider(tabCountProvider); + assert menuButtonHelper != null; mMenuButton.setAppMenuButtonHelper(menuButtonHelper); mMenuButton.setThemeColorProvider(themeColorProvider); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/TabSwitcherBottomToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/TabSwitcherBottomToolbarCoordinator.java index b978070..52f17518 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/TabSwitcherBottomToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/TabSwitcherBottomToolbarCoordinator.java
@@ -79,6 +79,7 @@ mNewTabButton.setIncognitoStateProvider(incognitoStateProvider); mNewTabButton.setThemeColorProvider(themeColorProvider); + assert menuButtonHelper != null; mMenuButton = root.findViewById(R.id.menu_button_wrapper); mMenuButton.setThemeColorProvider(themeColorProvider); mMenuButton.setAppMenuButtonHelper(menuButtonHelper);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index b2d6253..bb06a63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -11,7 +11,6 @@ import android.graphics.drawable.Drawable; import android.os.SystemClock; import android.support.annotation.ColorRes; -import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.util.AttributeSet; @@ -840,19 +839,16 @@ /** * Enable the experimental toolbar button. * @param onClickListener The {@link OnClickListener} to be called when the button is clicked. - * @param drawableResId The resource id of the drawable to display for the button. + * @param image The drawable to display for the button. * @param contentDescriptionResId The resource id of the content description for the button. */ - void enableExperimentalButton(OnClickListener onClickListener, @DrawableRes int drawableResId, + void enableExperimentalButton(OnClickListener onClickListener, Drawable image, @StringRes int contentDescriptionResId) {} /** - * @return The experimental toolbar button if it exists. + * Updates image displayed on experimental button. */ - @Nullable - View getExperimentalButtonView() { - return null; - } + void updateExperimentalButtonImage(Drawable image) {} /** * Disable the experimental toolbar button.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 29a0560..b627c31 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -26,6 +26,7 @@ import android.os.SystemClock; import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import android.support.annotation.StringRes; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.animation.FastOutSlowInInterpolator; @@ -2452,8 +2453,8 @@ } @Override - void enableExperimentalButton( - OnClickListener onClickListener, int drawableResId, int contentDescriptionResId) { + void enableExperimentalButton(OnClickListener onClickListener, Drawable image, + @StringRes int contentDescriptionResId) { if (mExperimentalButton == null) { ViewStub viewStub = findViewById(R.id.experimental_button_stub); mExperimentalButton = (ImageButton) viewStub.inflate(); @@ -2471,7 +2472,7 @@ } mExperimentalButton.setOnClickListener(onClickListener); - mExperimentalButton.setImageResource(drawableResId); + mExperimentalButton.setImageDrawable(image); mExperimentalButton.setContentDescription( getContext().getResources().getString(contentDescriptionResId)); ApiCompatibilityUtils.setImageTintList(mExperimentalButton, getTint()); @@ -2490,8 +2491,9 @@ } @Override - View getExperimentalButtonView() { - return mExperimentalButton; + void updateExperimentalButtonImage(Drawable image) { + assert mExperimentalButton != null; + mExperimentalButton.setImageDrawable(image); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 792a7820..33022845 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -6,7 +6,6 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.view.View; @@ -593,13 +592,12 @@ * Enable the experimental toolbar button. * @param onClickListener The {@link View.OnClickListener} to be called when the button is * clicked. - * @param drawableResId The resource id of the drawable to display for the button. + * @param image The drawable to display for the button. * @param contentDescriptionResId The resource id of the content description for the button. */ - public void enableExperimentalButton(View.OnClickListener onClickListener, - @DrawableRes int drawableResId, @StringRes int contentDescriptionResId) { - mToolbarLayout.enableExperimentalButton( - onClickListener, drawableResId, contentDescriptionResId); + public void enableExperimentalButton(View.OnClickListener onClickListener, Drawable image, + @StringRes int contentDescriptionResId) { + mToolbarLayout.enableExperimentalButton(onClickListener, image, contentDescriptionResId); } /** @@ -612,8 +610,10 @@ /** * @return The experimental toolbar button if it exists. */ - public @Nullable View getExperimentalButtonView() { - return mToolbarLayout == null ? null : mToolbarLayout.getExperimentalButtonView(); + public void updateExperimentalButtonImage(Drawable image) { + if (mToolbarLayout != null) { + mToolbarLayout.updateExperimentalButtonImage(image); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 35848c8..d37eb312 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -11,6 +11,7 @@ import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.appmenu.AppMenuCoordinator; +import org.chromium.chrome.browser.appmenu.AppMenuHandler; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.lifecycle.InflationObserver; import org.chromium.chrome.browser.lifecycle.NativeInitObserver; @@ -28,7 +29,7 @@ public class RootUiCoordinator implements Destroyable, NativeInitObserver, InflationObserver, ChromeActivity.MenuOrKeyboardActionHandler { private ChromeActivity mActivity; - private AppMenuCoordinator mAppMenuCoordinator; + private @Nullable AppMenuCoordinator mAppMenuCoordinator; private @Nullable ImmersiveModeManager mImmersiveModeManager; private SystemUiCoordinator mSystemUiCoordinator; @@ -57,12 +58,17 @@ @Override public void onPostInflationStartup() { - mAppMenuCoordinator = new AppMenuCoordinator(mActivity, mActivity.getLifecycleDispatcher(), - mActivity.getToolbarManager(), mActivity, mActivity.getWindow().getDecorView()); - if (mActivity.getToolbarManager() != null) { + // TODO(https://crbug.com/931496): Revisit this as part of the broader + // discussion around activity-specific UI customizations. + if (mActivity.supportsAppMenu()) { + mAppMenuCoordinator = new AppMenuCoordinator(mActivity, + mActivity.getLifecycleDispatcher(), mActivity.getToolbarManager(), mActivity, + mActivity.getWindow().getDecorView()); mActivity.getToolbarManager().onAppMenuInitialized( mAppMenuCoordinator.getAppMenuHandler(), mAppMenuCoordinator.getAppMenuPropertiesDelegate()); + } else if (mActivity.getToolbarManager() != null) { + mActivity.getToolbarManager().getToolbar().disableMenuButton(); } mImmersiveModeManager = AppHooks.get().createImmersiveModeManager( @@ -79,15 +85,19 @@ @Override public void onFinishNativeInitialization() { mSystemUiCoordinator.onNativeInitialized(mActivity.getOverviewModeBehavior()); - mAppMenuCoordinator.onNativeInitialized(mActivity.getOverviewModeBehavior()); + if (mAppMenuCoordinator != null) { + mAppMenuCoordinator.onNativeInitialized(mActivity.getOverviewModeBehavior()); + } // TODO(twellington): Move to a TabbedRootUiCoordinator or delegate? if (mActivity.getActivityType() == ChromeActivity.ActivityType.TABBED && DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) { - EmptyBackgroundViewWrapper bgViewWrapper = new EmptyBackgroundViewWrapper( - mActivity.getTabModelSelector(), mActivity.getTabCreator(false), mActivity, - mAppMenuCoordinator.getAppMenuHandler(), mActivity.getSnackbarManager(), - mActivity.getOverviewModeBehavior()); + AppMenuHandler appMenuHandler = + mAppMenuCoordinator == null ? null : mAppMenuCoordinator.getAppMenuHandler(); + EmptyBackgroundViewWrapper bgViewWrapper = + new EmptyBackgroundViewWrapper(mActivity.getTabModelSelector(), + mActivity.getTabCreator(false), mActivity, appMenuHandler, + mActivity.getSnackbarManager(), mActivity.getOverviewModeBehavior()); bgViewWrapper.initialize(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java index b07a0347..8bb16fe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -26,7 +26,6 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.firstrun.FirstRunUtils; -import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.tabmodel.DocumentModeAssassin; @@ -67,7 +66,6 @@ */ public class FeatureUtilities { private static final String TAG = "FeatureUtilities"; - private static final Integer CONTEXTUAL_SUGGESTIONS_TOOLBAR_MIN_DP = 320; private static Boolean sHasGoogleAccountAuthenticator; private static Boolean sHasRecognitionIntentHandler; @@ -587,20 +585,6 @@ return ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOAD_PROGRESS_INFOBAR); } - /** - * @param activityContext The context for the containing activity. - * @return Whether contextual suggestions are enabled. - */ - public static boolean areContextualSuggestionsEnabled(Context activityContext) { - int smallestScreenWidth = - activityContext.getResources().getConfiguration().smallestScreenWidthDp; - return !DeviceFormFactor.isNonMultiDisplayContextOnTablet(activityContext) - && !LocaleManager.getInstance().needToCheckForSearchEnginePromo() - && (smallestScreenWidth >= CONTEXTUAL_SUGGESTIONS_TOOLBAR_MIN_DP - && ChromeFeatureList.isEnabled( - ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON)); - } - private static void cacheGridTabSwitcherEnabled() { ChromePreferenceManager.getInstance().writeBoolean( ChromePreferenceManager.GRID_TAB_SWITCHER_ENABLED_KEY,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/emptybackground/EmptyBackgroundViewWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/emptybackground/EmptyBackgroundViewWrapper.java index a86d320..d7afe63f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/emptybackground/EmptyBackgroundViewWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/emptybackground/EmptyBackgroundViewWrapper.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.widget.emptybackground; import android.app.Activity; +import android.support.annotation.Nullable; import android.view.View; import android.view.View.OnAttachStateChangeListener; import android.view.ViewStub; @@ -38,7 +39,7 @@ private final SnackbarManager mSnackbarManager; private EmptyBackgroundViewTablet mBackgroundView; - private final AppMenuHandler mMenuHandler; + private final @Nullable AppMenuHandler mMenuHandler; /** * Creates a {@link EmptyBackgroundViewWrapper} instance that will lazily inflate. @@ -54,8 +55,8 @@ * is in overview mode. */ public EmptyBackgroundViewWrapper(TabModelSelector selector, TabCreator tabCreator, - Activity activity, AppMenuHandler menuHandler, SnackbarManager snackbarManager, - OverviewModeBehavior overviewModeBehavior) { + Activity activity, @Nullable AppMenuHandler menuHandler, + SnackbarManager snackbarManager, OverviewModeBehavior overviewModeBehavior) { mActivity = activity; mMenuHandler = menuHandler; mTabModelSelector = selector; @@ -126,7 +127,7 @@ R.id.empty_container_stub)).inflate(); mBackgroundView.setTabModelSelector(mTabModelSelector); mBackgroundView.setTabCreator(mTabCreator); - mBackgroundView.setMenuOnTouchListener(mMenuHandler); + if (mMenuHandler != null) mBackgroundView.setMenuOnTouchListener(mMenuHandler); mBackgroundView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { @Override public void onViewDetachedFromWindow(View v) {
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 3e9703b..1024fa9d 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -653,23 +653,6 @@ Chrome Passwords </message> - <!-- Contextual suggestions preferences --> - <message name="IDS_PREFS_CONTEXTUAL_SUGGESTIONS" desc="Title of contextual suggestions settings, which allows the user to get site suggestions based on the current website."> - Suggest related pages - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_DESCRIPTION" desc="Description of contextual suggestions, which tells the user what contextual suggestions does."> - When you scroll up, show quick links to related pages. The URLs of pages you visit are sent to Google. - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_DESCRIPTION_TOOLBAR_BUTTON" desc="Description of contextual suggestions, which tells the user that when they tap the ‘More like this’ button they will be shown links to pages related to their current page. An icon will be inserted into the string after ‘More like this’. 'More like this' should match TC ID 1418444397960583910."> - When you tap More like this <ph name="ICON"><icon> </icon></ph> in the address bar, show quick links to related pages. The URLs of pages you visit are sent to Google. - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_MESSAGE" desc="Message of contextual suggestions settings, which tells the user how to opt in contextual suggestions."> - This feature uses <ph name="BEGIN_LINK"><link></ph>sync<ph name="END_LINK"></link></ph>. - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_MESSAGE_UNIFIED_CONSENT" desc="Message of contextual suggestions settings, which tells the user how to opt in contextual suggestions. Please ensure ‘Activity and interactions’ in this message matches the ‘Activity and interactions’ in sync settings."> - To use this feature, turn on <ph name="BEGIN_LINK"><link></ph>Activity and interactions<ph name="END_LINK"></link></ph>. - </message> - <!-- Homepage preferences --> <message name="IDS_OPTIONS_HOMEPAGE_EDIT_TITLE" desc="The title of the screen that allows users to change the URL that opens when they tap on the home page button in the omnibox."> Edit home page @@ -3023,29 +3006,6 @@ Checking your internet connection </message> - <!-- Contextual suggestions strings --> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP" desc="The string displayed in an in-product help bubble when contextual suggestions are displayed for the first time. The bubble points to a toolbar button that shows suggestions related to the webpage the user is currently viewing when pressed. 'More like this' should match TC ID 1418444397960583910."> - See more like this from Google - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP_ACCESSIBILITY" desc="The string displayed in an in-product help bubble when contextual suggestions are displayed for the first time and accessibility mode is enabled. The bubble points to a toolbar button that shows suggestions related to the webpage the user is currently viewing when pressed. 'More like this' should match TC ID 1418444397960583910."> - See more like this from Google using the More Like This button - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_BUTTON_DESCRIPTION" desc="The content description for a toolbar button that shows contextual suggestions related to the current web page when tapped. The suggestions show up in an overlay sheet. This string is also the default title for that sheet (see IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_HALF for screenshot). 'More like this' is the name of the feature and is used in several other related strings."> - More like this - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_CLOSE_BUTTON_DESCRIPTION" desc="The content description for the contextual suggestions close button. Tapping the button closing the UI. 'More like this' should match TC ID 1418444397960583910."> - Close more like this - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_HALF" desc="Accessibility string read when the 'more like this' sheet is opened at half height. The sheet will occupy the bottom half the screen. 'More like this' should match TC ID 1418444397960583910."> - More like this opened at half height - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_FULL" desc="Accessibility string read when the 'more like this' sheet is opened at full height. The sheet will occupy the entire screen. 'More like this' should match TC ID 1418444397960583910."> - More like this opened at full height - </message> - <message name="IDS_CONTEXTUAL_SUGGESTIONS_SHEET_CLOSED" desc="Accessibility string read when the 'more like this' sheet is closed. 'More like this' should match TC ID 1418444397960583910."> - More like this closed - </message> - <!-- Toolbar button strings --> <message name="IDS_OPEN_TABS" desc="Text for button to enter the tab switcher and show tabs that are open on this device"> Open tabs @@ -3157,9 +3117,6 @@ <message name="IDS_MENU_CLOSE_ALL_PRIVATE_TABS" desc="Menu item for closing all open private tabs. [CHAR-LIMIT=27]"> Close private tabs </message> - <message name="IDS_MENU_SEND_FEEDBACK" desc="Menu item for sending feedback. [CHAR-LIMIT=27]"> - Send feedback - </message> <!-- Bookmarks strings --> <message name="IDS_BOOKMARKS" desc="Title of the bookmarks page, which shows a list of the user's bookmarks. [CHAR-LIMIT=18]">
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_BUTTON_DESCRIPTION.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_BUTTON_DESCRIPTION.png.sha1 deleted file mode 100644 index 18ae295..0000000 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_BUTTON_DESCRIPTION.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e180c363bbba530a91d945d39c47835d87c64115 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_CLOSE_BUTTON_DESCRIPTION.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_CLOSE_BUTTON_DESCRIPTION.png.sha1 deleted file mode 100644 index e2162bc..0000000 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_CLOSE_BUTTON_DESCRIPTION.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e9b1dec493050b4678384f62961f3274b0cb7369 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP.png.sha1 deleted file mode 100644 index a4e237d..0000000 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -df3426b60fe91981e35de68a882715da0c48095b \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP_ACCESSIBILITY.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP_ACCESSIBILITY.png.sha1 deleted file mode 100644 index ad7f62e8..0000000 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_IN_PRODUCT_HELP_ACCESSIBILITY.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -8b4de0819831b4b16c2184a7a08f783801533770 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_FULL.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_FULL.png.sha1 deleted file mode 100644 index cb775b2..0000000 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_FULL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e00c4d48416cdb05da591dc4a18189f6380f7442 \ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_HALF.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_HALF.png.sha1 deleted file mode 100644 index 6c22983a..0000000 --- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_CONTEXTUAL_SUGGESTIONS_SHEET_OPENED_HALF.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -b1ce64aec1128e5568804db165c0173f017f38e6 \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/EmptyEnabledStateMonitor.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/EmptyEnabledStateMonitor.java deleted file mode 100644 index 6edcebf..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/EmptyEnabledStateMonitor.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -/** Empty implementation for tests. */ -public class EmptyEnabledStateMonitor implements EnabledStateMonitor { - @Override - public void addObserver(Observer observer) {} - - @Override - public void removeObserver(Observer observer) {} - - @Override - public boolean getSettingsEnabled() { - return false; - } - - @Override - public boolean getEnabledState() { - return false; - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorTest.java deleted file mode 100644 index 518fb92..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/EnabledStateMonitorTest.java +++ /dev/null
@@ -1,105 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.support.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.CommandLineFlags.Add; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Restriction; -import org.chromium.chrome.browser.ChromeActivity; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.locale.LocaleManager; -import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge; -import org.chromium.chrome.test.ChromeActivityTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; -import org.chromium.components.signin.ChromeSigninController; -import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.policy.test.annotations.Policies; -import org.chromium.ui.test.util.UiRestriction; - -/** - * Tests for EnabledStateMonitor. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) -@Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@EnableFeatures(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON) -public class EnabledStateMonitorTest { - @Rule - public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = - new ChromeActivityTestRule<>(ChromeActivity.class); - - private EnabledStateMonitor mEnabledStateMonitor; - - private String mOriginalSignedInAccountName; - - @Before - public void setUp() throws Exception { - LocaleManager.setInstanceForTest(new LocaleManager() { - @Override - public boolean needToCheckForSearchEnginePromo() { - return false; - } - }); - - mActivityTestRule.startMainActivityOnBlankPage(); - TestThreadUtils.runOnUiThreadBlocking(() -> { - mOriginalSignedInAccountName = ChromeSigninController.get().getSignedInAccountName(); - ChromeSigninController.get().setSignedInAccountName("test@gmail.com"); - UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(true); - mEnabledStateMonitor = new EnabledStateMonitorImpl(); - }); - } - - @After - public void tearDown() throws Exception { - TestThreadUtils.runOnUiThreadBlocking(() -> { - ChromeSigninController.get().setSignedInAccountName(mOriginalSignedInAccountName); - }); - } - - @Test - @SmallTest - @Feature({"ContextualSuggestions"}) - @Policies.Add({ @Policies.Item(key = "ContextualSuggestionsEnabled", string = "false") }) - public void testEnterprisePolicy_Disabled() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertFalse(mEnabledStateMonitor.getEnabledState()); - Assert.assertFalse(mEnabledStateMonitor.getSettingsEnabled()); - }); - } - - @Test - @SmallTest - @Feature({"ContextualSuggestions"}) - @Policies.Add({ @Policies.Item(key = "ContextualSuggestionsEnabled", string = "true") }) - public void testEnterprisePolicy_Enabled() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertTrue(mEnabledStateMonitor.getEnabledState()); - Assert.assertTrue(mEnabledStateMonitor.getSettingsEnabled()); - }); - } - - @Test - @SmallTest - @Feature({"ContextualSuggestions"}) - @Policies.Remove({ @Policies.Item(key = "ContextualSuggestionsEnabled") }) - public void testEnterprisePolicy_DefaultEnabled() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertTrue(mEnabledStateMonitor.getEnabledState()); - Assert.assertTrue(mEnabledStateMonitor.getSettingsEnabled()); - }); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java deleted file mode 100644 index de79e786..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java +++ /dev/null
@@ -1,133 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.util.Pair; - -import org.chromium.base.Callback; -import org.chromium.base.test.util.UrlUtils; -import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsBridge.ContextualSuggestionsResult; -import org.chromium.chrome.browser.ntp.snippets.EmptySuggestionsSource; -import org.chromium.chrome.browser.ntp.snippets.KnownCategories; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.content_public.browser.WebContents; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A fake {@link ContextualSuggestionsSourceImpl} for use in testing. - */ -public class FakeContextualSuggestionsSource - extends EmptySuggestionsSource implements ContextualSuggestionsSource { - final static String TEST_TOOLBAR_TITLE = "More about capybaras"; - // There should be 6 items in the cluster list - 5 articles and one cluster title. - final static Integer TOTAL_ITEM_COUNT = 6; - final static float TEST_PEEK_CONFIDENCE = 0.75f; - final static float TEST_PEEK_TARGET_PERCENTAGE = .5f; - final static int TEST_PEEK_COUNT = 3; - final static int TEST_PEEK_DELAY_SECONDS = 2; - - private final Map<String, Bitmap> mSuggestionBitmaps = new HashMap<>(); - private final List<Pair<SnippetArticle, Callback<Bitmap>>> mPendingImageRequests = - new ArrayList<>(); - - FakeContextualSuggestionsSource() { - Bitmap capybaraBitmap = BitmapFactory.decodeFile( - UrlUtils.getIsolatedTestFilePath("chrome/test/data/android/capybara.jpg")); - Bitmap watchBitmap = BitmapFactory.decodeFile( - UrlUtils.getIsolatedTestFilePath("chrome/test/data/android/watch.jpg")); - mSuggestionBitmaps.put("id1", capybaraBitmap); - mSuggestionBitmaps.put("id3", capybaraBitmap); - mSuggestionBitmaps.put("id4", watchBitmap); - } - - @Override - public void fetchContextualSuggestionImage( - SnippetArticle suggestion, Callback<Bitmap> callback) { - mPendingImageRequests.add(new Pair<>(suggestion, callback)); - } - - @Override - public void fetchSuggestionFavicon(SnippetArticle suggestion, int minimumSizePx, - int desiredSizePx, Callback<Bitmap> callback) {} - - @Override - public void fetchSuggestions(String url, Callback<ContextualSuggestionsResult> callback) { - callback.onResult(createDummyResults()); - } - - @Override - public void reportEvent(WebContents webContents, @ContextualSuggestionsEvent int eventId) {} - - @Override - public void clearState() {} - - void runImageFetchCallbacks() { - for (Pair<SnippetArticle, Callback<Bitmap>> pair : mPendingImageRequests) { - String id = pair.first.mIdWithinCategory; - if (mSuggestionBitmaps.containsKey(id)) { - pair.second.onResult(mSuggestionBitmaps.get(id)); - } - } - mPendingImageRequests.clear(); - } - - private static ContextualSuggestionsResult createDummyResults() { - SnippetArticle suggestion1 = new SnippetArticle(KnownCategories.CONTEXTUAL, "id1", - "Capybaras also love hats", - "Lorem ipsum dolor sit amet, consectetur adipiscing " - + "elit. Nulla lacus tortor, aliquam sed tempor at, consectetur sit amet " - + "mauris. Nunc ornare vulputate erat, eget tempus magna ultricies a.", - "Capybara Central", "https://site.com/url1", 0, 0, 0, false, null, true); - SnippetArticle suggestion2 = new SnippetArticle(KnownCategories.CONTEXTUAL, "id2", - "All you ever wanted to know about the capybara and its impeccable taste in " - + "high fashion watches, hats, and other various accessories", - "Sed tincidunt ex et quam mollis vestibulum. In lobortis eget massa sed tincidunt. " - + "Aliquam augue erat, tempus at consectetur ac, sagittis pellentesque " - + "purus. Morbi aliquet nisi sed felis auctor, at bibendum leo sodales. " - + "Cras in felis a dui ultricies efficitur sed vitae magna.", - "All About Capybaras and Fashion", "https://site.com/url2", 0, 0, 0, false, null, - false); - SnippetArticle suggestion3 = - new SnippetArticle(KnownCategories.CONTEXTUAL, "id3", "Capybaras don't like ties", - "Pellentesque nec lorem nec velit convallis suscipit " - + "non eget nunc.", - "Breaking Capybara News Updates Delivered Daily", "https://site.com/url3", - 0, 0, 0, false, null, true); - SnippetArticle article4 = - new SnippetArticle(KnownCategories.CONTEXTUAL, "id4", "Fancy watches", - "Duis egestas est vitae eros consectetur vulputate. Integer " - + "tincidunt condimentum sapien, vel volutpat lorem.", - "Watch Shop", "https://site.com/url4", 0, 0, 0, false, null, true); - SnippetArticle article5 = - new SnippetArticle(KnownCategories.CONTEXTUAL, "id5", "Less fancy watches", - "Donec in luctus purus. Cras scelerisque urna ac sem congue " - + "dictum.", - "Watch Wholesalers", "https://site.com/url5", 0, 0, 0, false, null, false); - - ContextualSuggestionsCluster cluster1 = new ContextualSuggestionsCluster(""); - cluster1.getSuggestions().add(suggestion1); - cluster1.getSuggestions().add(suggestion2); - cluster1.getSuggestions().add(suggestion3); - - ContextualSuggestionsCluster cluster2 = - new ContextualSuggestionsCluster("More about watches"); - cluster2.getSuggestions().add(article4); - cluster2.getSuggestions().add(article5); - - ContextualSuggestionsResult result = new ContextualSuggestionsResult(TEST_TOOLBAR_TITLE); - result.setPeekConditions(new PeekConditions(TEST_PEEK_CONFIDENCE, - TEST_PEEK_TARGET_PERCENTAGE, TEST_PEEK_DELAY_SECONDS, TEST_PEEK_COUNT)); - result.getClusters().add(cluster1); - result.getClusters().add(cluster2); - - return result; - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeTracker.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeTracker.java deleted file mode 100644 index 3b04209..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeTracker.java +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import android.text.TextUtils; - -import org.junit.Assert; - -import org.chromium.base.Callback; -import org.chromium.base.test.util.CallbackHelper; -import org.chromium.components.feature_engagement.Tracker; - -/** - * A feature engagement {@link Tracker} for testing. - */ -class FakeTracker implements Tracker { - public CallbackHelper mDimissedCallbackHelper = new CallbackHelper(); - - private String mEnabledFeature; - - public FakeTracker(String enabledFeature) { - mEnabledFeature = enabledFeature; - } - - @Override - public void notifyEvent(String event) {} - - @Override - public boolean shouldTriggerHelpUI(String feature) { - return TextUtils.equals(mEnabledFeature, feature); - } - - @Override - public int getTriggerState(String feature) { - return 0; - } - - @Override - public void dismissed(String feature) { - Assert.assertEquals("Wrong feature dismissed.", mEnabledFeature, feature); - mDimissedCallbackHelper.notifyCalled(); - } - - @Override - public boolean isInitialized() { - return true; - } - - @Override - public void addOnInitializedCallback(Callback<Boolean> callback) { - callback.onResult(true); - } - - @Override - public boolean wouldTriggerHelpUI(String feature) { - return shouldTriggerHelpUI(feature); - } - - @Override - public DisplayLockHandle acquireDisplayLock() { - return null; - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS deleted file mode 100644 index 908f03f..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 779ad52..87788a5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -79,7 +79,6 @@ import org.chromium.chrome.test.util.FullscreenTestUtils; import org.chromium.chrome.test.util.MenuUtils; import org.chromium.chrome.test.util.OmniboxTestUtils; -import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.navigation_interception.NavigationParams; import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionPopupController; @@ -2883,7 +2882,6 @@ @Test @SmallTest @Feature({"ContextualSearch"}) - @Features.DisableFeatures({ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON}) public void testQuickActionCaptionAndImage() throws InterruptedException, TimeoutException { mPanel.getAnimationHandler().setTestingMode(true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 2553b6b..43a3475 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -86,6 +86,7 @@ import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.TabsOpenedFromExternalAppTest; import org.chromium.chrome.browser.WarmupManager; +import org.chromium.chrome.browser.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.appmenu.AppMenuHandler; import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.browserservices.Origin; @@ -238,10 +239,12 @@ // first, otherwise the UI is manipulated on a non-UI thread. TestThreadUtils.runOnUiThreadBlocking(() -> { if (getActivity() == null) return; - AppMenuHandler handler = getActivity() - .getRootUiCoordinatorForTesting() - .getAppMenuCoordinatorForTesting() - .getAppMenuHandler(); + AppMenuCoordinator coordinator = getActivity() + .getRootUiCoordinatorForTesting() + .getAppMenuCoordinatorForTesting(); + // CCT doesn't always have a menu (ex. in the media viewer). + if (coordinator == null) return; + AppMenuHandler handler = coordinator.getAppMenuHandler(); if (handler != null) handler.hideAppMenu(); }); mWebServer.shutdown(); @@ -595,7 +598,7 @@ } /** - * Test the entries in app menu for media viewer. + * Test the App Menu does not show for media viewer. */ @Test @SmallTest @@ -607,13 +610,12 @@ IntentHandler.addTrustedIntentExtras(intent); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); - openAppMenuAndAssertMenuShown(); - Menu menu = mCustomTabActivityTestRule.getMenu(); - final int expectedMenuSize = 0; - - Assert.assertNotNull("App menu is not initialized: ", menu); - assertEquals(expectedMenuSize, getActualMenuSize(menu)); - assertEquals(expectedMenuSize, getVisibleMenuSize(menu)); + PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { + getActivity().onMenuOrKeyboardAction(R.id.show_menu, false); + Assert.assertNull(getActivity() + .getRootUiCoordinatorForTesting() + .getAppMenuCoordinatorForTesting()); + }); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreferenceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreferenceTest.java deleted file mode 100644 index d3ef76a0..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/ContextualSuggestionsPreferenceTest.java +++ /dev/null
@@ -1,164 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.preferences; - -import static org.chromium.chrome.browser.ChromeFeatureList.SEARCH_ENGINE_PROMO_EXISTING_DEVICE; - -import android.support.annotation.Nullable; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.Feature; -import org.chromium.chrome.browser.contextual_suggestions.EmptyEnabledStateMonitor; -import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor; -import org.chromium.chrome.browser.dependency_injection.ChromeAppModule; -import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule; -import org.chromium.chrome.browser.test.ChromeBrowserTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.browser.Features; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -/** - * Tests for ContextualSuggestionsPreference. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@Features.DisableFeatures(SEARCH_ENGINE_PROMO_EXISTING_DEVICE) -public class ContextualSuggestionsPreferenceTest { - - private final TestRule mModuleOverridesRule = new ModuleOverridesRule() - .setOverride(ChromeAppModule.Factory.class, ChromeAppModuleForTest::new); - - @Rule - public final TestRule mOverrideModulesThenLaunchRule = - RuleChain.outerRule(mModuleOverridesRule).around(new ChromeBrowserTestRule()); - - private ContextualSuggestionsPreference mFragment; - - private FakeEnabledStateMonitor mEnabledStateMonitor = new FakeEnabledStateMonitor(); - - private ChromeSwitchPreference mSwitch; - private boolean mInitialSwitchState; - - private class FakeEnabledStateMonitor extends EmptyEnabledStateMonitor { - @Nullable - private EnabledStateMonitor.Observer mObserver; - - private boolean mEnabledInSettings; - - @Override - public void addObserver(Observer observer) { - mObserver = observer; - } - - @Override - public void removeObserver(Observer observer) { - mObserver = null; - } - - @Override - public boolean getSettingsEnabled() { - return mEnabledInSettings; - } - - @Override - public boolean getEnabledState() { - // Mirroring the behavior of EnabledStateMonitorImpl - return PrefServiceBridge.getInstance().getBoolean(Pref.CONTEXTUAL_SUGGESTIONS_ENABLED) - && mEnabledInSettings; - } - - public void setSettingsEnabled(boolean enabled) { - mEnabledInSettings = enabled; - - if (mObserver != null) { - mObserver.onSettingsStateChanged(enabled); - } - } - } - - private class ChromeAppModuleForTest extends ChromeAppModule { - @Override - public EnabledStateMonitor provideEnabledStateMonitor() { - return mEnabledStateMonitor; - } - } - - @Before - public void setUp() { - Preferences preferences = - PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), - ContextualSuggestionsPreference.class.getName()); - mFragment = (ContextualSuggestionsPreference) preferences.getFragmentForTest(); - mSwitch = (ChromeSwitchPreference) mFragment.findPreference( - ContextualSuggestionsPreference.PREF_CONTEXTUAL_SUGGESTIONS_SWITCH); - mInitialSwitchState = mSwitch.isChecked(); - } - - @After - public void tearDown() { - TestThreadUtils.runOnUiThreadBlocking(() -> setSwitchState(mInitialSwitchState)); - } - - @Test - @SmallTest - @Feature({"ContextualSuggestions"}) - public void testSwitch_Toggle() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - mEnabledStateMonitor.setSettingsEnabled(true); - - // Check initial state matches preference. - setSwitchState(true); - Assert.assertEquals(mSwitch.isChecked(), true); - Assert.assertEquals(mSwitch.isChecked(), - PrefServiceBridge.getInstance().getBoolean( - Pref.CONTEXTUAL_SUGGESTIONS_ENABLED)); - - // Toggle and check if preference matches. - PreferencesTest.clickPreference(mFragment, mSwitch); - Assert.assertEquals(mSwitch.isChecked(), false); - Assert.assertEquals(mSwitch.isChecked(), - PrefServiceBridge.getInstance().getBoolean( - Pref.CONTEXTUAL_SUGGESTIONS_ENABLED)); - - // Toggle again check if preference matches. - PreferencesTest.clickPreference(mFragment, mSwitch); - Assert.assertEquals(mSwitch.isChecked(), true); - Assert.assertEquals(mSwitch.isChecked(), - PrefServiceBridge.getInstance().getBoolean( - Pref.CONTEXTUAL_SUGGESTIONS_ENABLED)); - }); - } - - @Test - @SmallTest - @Feature({"ContextualSuggestions"}) - public void testSwitch_SettingsStateChanged() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - // Make sure switch is checked. - mEnabledStateMonitor.setSettingsEnabled(true); - setSwitchState(true); - Assert.assertTrue(mSwitch.isEnabled()); - Assert.assertTrue(mSwitch.isChecked()); - - // Simulate settings are disabled. - mEnabledStateMonitor.setSettingsEnabled(false); - Assert.assertFalse(mSwitch.isEnabled()); - Assert.assertFalse(mSwitch.isChecked()); - }); - } - - private void setSwitchState(boolean checked) { - if (mSwitch.isChecked() != checked) PreferencesTest.clickPreference(mFragment, mSwitch); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java index bca35e04..5ef802fe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcherTest.java
@@ -13,13 +13,18 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.Callback; import org.chromium.base.test.util.CallbackHelper; +import org.chromium.chrome.browser.ContentSettingsType; import org.chromium.chrome.browser.test.ChromeBrowserTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.concurrent.TimeUnit; /** @@ -164,4 +169,495 @@ }); waiter.waitForCallback(0, 1, scaleTimeout(1000), TimeUnit.MILLISECONDS); } + + class FakeWebsitePreferenceBridge extends WebsitePreferenceBridge { + public List<PermissionInfo> mPermissionInfos; + public List<ContentSettingException> mContentSettingExceptions; + public List<ChosenObjectInfo> mChosenObjectInfos; + public HashMap<String, LocalStorageInfo> mLocalStorageInfoMap; + public HashMap<String, LocalStorageInfo> mImportantLocalStorageInfoMap; + public ArrayList<StorageInfo> mStorageInfos; + + FakeWebsitePreferenceBridge() { + mPermissionInfos = new ArrayList<>(); + mContentSettingExceptions = new ArrayList<>(); + mChosenObjectInfos = new ArrayList<>(); + mLocalStorageInfoMap = new HashMap<>(); + mImportantLocalStorageInfoMap = new HashMap<>(); + mStorageInfos = new ArrayList<>(); + } + + @Override + public List<PermissionInfo> getPermissionInfo(@PermissionInfo.Type int type) { + List<PermissionInfo> result = new ArrayList<>(); + for (PermissionInfo info : mPermissionInfos) { + if (info.getType() == type) { + result.add(info); + } + } + return result; + } + + @Override + public List<ContentSettingException> getContentSettingsExceptions( + @ContentSettingsType int contentSettingsType) { + List<ContentSettingException> result = new ArrayList<>(); + for (ContentSettingException exception : mContentSettingExceptions) { + if (exception.getContentSettingType() == contentSettingsType) { + result.add(exception); + } + } + return result; + } + + @Override + public void fetchLocalStorageInfo(Callback<HashMap> callback, boolean fetchImportant) { + if (fetchImportant) { + callback.onResult(mImportantLocalStorageInfoMap); + return; + } + callback.onResult(mLocalStorageInfoMap); + } + + @Override + public void fetchStorageInfo(Callback<ArrayList> callback) { + callback.onResult(mStorageInfos); + } + + @Override + public List<ChosenObjectInfo> getChosenObjectInfo(int contentSettingsType) { + List<ChosenObjectInfo> result = new ArrayList<>(); + for (ChosenObjectInfo info : mChosenObjectInfos) { + if (info.getContentSettingsType() == contentSettingsType) { + result.add(info); + } + } + return result; + } + + public void addPermissionInfo(PermissionInfo info) { + mPermissionInfos.add(info); + } + + public void addContentSettingException(ContentSettingException exception) { + mContentSettingExceptions.add(exception); + } + + public void addLocalStorageInfoMapEntry(LocalStorageInfo info) { + if (info.isDomainImportant()) { + mImportantLocalStorageInfoMap.put(info.getOrigin(), info); + return; + } + mLocalStorageInfoMap.put(info.getOrigin(), info); + } + + public void addStorageInfo(StorageInfo info) { + mStorageInfos.add(info); + } + + public void addChosenObjectInfo(ChosenObjectInfo info) { + mChosenObjectInfos.add(info); + } + } + + @Test + @SmallTest + public void testFetchAllPreferencesForSingleOrigin() throws Exception { + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(); + FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge(); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + + // Add permission info types. + Assert.assertEquals(8, PermissionInfo.Type.NUM_ENTRIES); + String googleOrigin = "https://google.com"; + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.GEOLOCATION, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo( + new PermissionInfo(PermissionInfo.Type.MIDI, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.PROTECTED_MEDIA_IDENTIFIER, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.NOTIFICATION, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo( + new PermissionInfo(PermissionInfo.Type.CAMERA, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.MICROPHONE, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.CLIPBOARD, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo( + new PermissionInfo(PermissionInfo.Type.SENSORS, googleOrigin, googleOrigin, false)); + + // Add content setting exception types. + String preferenceSource = "preference"; + Assert.assertEquals(46, ContentSettingsType.CONTENT_SETTINGS_NUM_TYPES); + websitePreferenceBridge.addContentSettingException( + new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_COOKIES, + googleOrigin, ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException( + new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_POPUPS, + googleOrigin, ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException( + new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_ADS, + googleOrigin, ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException( + new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_JAVASCRIPT, + googleOrigin, ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException( + new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_SOUND, + googleOrigin, ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException(new ContentSettingException( + ContentSettingsType.CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, googleOrigin, + ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException(new ContentSettingException( + ContentSettingsType.CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, googleOrigin, + ContentSettingValues.DEFAULT, preferenceSource)); + websitePreferenceBridge.addContentSettingException( + new ContentSettingException(ContentSettingsType.CONTENT_SETTINGS_TYPE_AUTOPLAY, + googleOrigin, ContentSettingValues.DEFAULT, preferenceSource)); + + // Add storage info. + int storageSize = 256; + websitePreferenceBridge.addStorageInfo(new StorageInfo(googleOrigin, 0, storageSize)); + + // Add local storage info. + websitePreferenceBridge.addLocalStorageInfoMapEntry( + new LocalStorageInfo(googleOrigin, storageSize, false)); + + // Add chooser info types. + websitePreferenceBridge.addChosenObjectInfo( + new ChosenObjectInfo(ContentSettingsType.CONTENT_SETTINGS_TYPE_USB_CHOOSER_DATA, + googleOrigin, googleOrigin, "Gadget", "Object", false)); + + fetcher.fetchAllPreferences((sites) -> { + Assert.assertEquals(1, sites.size()); + Website site = sites.iterator().next(); + + Assert.assertTrue(site.getAddress().matches(googleOrigin)); + + // Check permission info types for |site|. + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.GEOLOCATION)); + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.MIDI)); + Assert.assertNotNull( + site.getPermissionInfo(PermissionInfo.Type.PROTECTED_MEDIA_IDENTIFIER)); + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.NOTIFICATION)); + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.CAMERA)); + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.MICROPHONE)); + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.CLIPBOARD)); + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.SENSORS)); + + // Check content setting exception types. + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.COOKIE)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.POPUP)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.ADS)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.JAVASCRIPT)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.SOUND)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.BACKGROUND_SYNC)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission( + ContentSettingException.Type.AUTOMATIC_DOWNLOADS)); + Assert.assertEquals(Integer.valueOf(ContentSettingValues.DEFAULT), + site.getContentSettingPermission(ContentSettingException.Type.AUTOPLAY)); + + // Check storage info. + ArrayList<StorageInfo> storageInfos = new ArrayList<>(site.getStorageInfo()); + Assert.assertEquals(1, storageInfos.size()); + + StorageInfo storageInfo = storageInfos.get(0); + Assert.assertEquals(googleOrigin, storageInfo.getHost()); + Assert.assertEquals(storageSize, storageInfo.getSize()); + + // Check local storage info. + LocalStorageInfo localStorageInfo = site.getLocalStorageInfo(); + Assert.assertEquals(googleOrigin, localStorageInfo.getOrigin()); + Assert.assertEquals(storageSize, localStorageInfo.getSize()); + Assert.assertFalse(localStorageInfo.isDomainImportant()); + + // Check chooser info types. + ArrayList<ChosenObjectInfo> chosenObjectInfos = + new ArrayList<>(site.getChosenObjectInfo()); + Assert.assertEquals(1, chosenObjectInfos.size()); + Assert.assertEquals(ContentSettingsType.CONTENT_SETTINGS_TYPE_USB_CHOOSER_DATA, + chosenObjectInfos.get(0).getContentSettingsType()); + }); + } + + @Test + @SmallTest + public void testFetchAllPreferencesForMultipleOrigins() throws Exception { + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(); + FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge(); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + + String googleOrigin = "https://google.com"; + String chromiumOrigin = "https://chromium.org"; + String exampleOrigin = "https://example.com"; + + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.GEOLOCATION, googleOrigin, googleOrigin, false)); + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.GEOLOCATION, chromiumOrigin, chromiumOrigin, false)); + + Website expectedGoogleWebsite = + new Website(WebsiteAddress.create(googleOrigin), WebsiteAddress.create(null)); + Website expectedChromiumWebsite = + new Website(WebsiteAddress.create(chromiumOrigin), WebsiteAddress.create(null)); + + fetcher.fetchAllPreferences((sites) -> { + Assert.assertEquals(2, sites.size()); + + // The order of |sites| is unknown, so check if the array contains a geolocation + // permission for each of the sites. + ArrayList<Website> siteArray = new ArrayList<>(sites); + boolean containsGoogleOriginPermission = false; + boolean containsChromiumOriginPermission = false; + for (Website site : siteArray) { + if (site.compareByAddressTo(expectedGoogleWebsite) == 0) + containsGoogleOriginPermission = true; + else if (site.compareByAddressTo(expectedChromiumWebsite) == 0) + containsChromiumOriginPermission = true; + + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.GEOLOCATION)); + } + + Assert.assertTrue(containsGoogleOriginPermission); + Assert.assertTrue(containsChromiumOriginPermission); + }); + + websitePreferenceBridge.addPermissionInfo(new PermissionInfo( + PermissionInfo.Type.GEOLOCATION, exampleOrigin, exampleOrigin, false)); + + Website expectedExampleWebsite = + new Website(WebsiteAddress.create(exampleOrigin), WebsiteAddress.create(null)); + + fetcher.fetchAllPreferences((sites) -> { + Assert.assertEquals(3, sites.size()); + + ArrayList<Website> siteArray = new ArrayList<>(sites); + boolean containsGoogleOriginPermission = false; + boolean containsChromiumOriginPermission = false; + boolean containsExampleOriginPermission = false; + for (Website site : siteArray) { + if (site.compareByAddressTo(expectedGoogleWebsite) == 0) + containsGoogleOriginPermission = true; + else if (site.compareByAddressTo(expectedChromiumWebsite) == 0) + containsChromiumOriginPermission = true; + else if (site.compareByAddressTo(expectedExampleWebsite) == 0) + containsExampleOriginPermission = true; + + Assert.assertNotNull(site.getPermissionInfo(PermissionInfo.Type.GEOLOCATION)); + } + + Assert.assertTrue(containsGoogleOriginPermission); + Assert.assertTrue(containsChromiumOriginPermission); + Assert.assertTrue(containsExampleOriginPermission); + }); + } + + public void assertContentSettingExceptionEquals( + ContentSettingException expected, ContentSettingException actual) { + Assert.assertEquals(expected.getSource(), actual.getSource()); + Assert.assertEquals(expected.getPattern(), actual.getPattern()); + Assert.assertEquals(expected.getContentSetting(), actual.getContentSetting()); + } + + @Test + @SmallTest + public void testFetchPreferencesForCategoryPermissionInfoTypes() throws Exception { + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(); + FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge(); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + + String googleOrigin = "https://google.com"; + ArrayList<Integer> permissionInfoTypes = new ArrayList<>(Arrays.asList( + PermissionInfo.Type.CAMERA, PermissionInfo.Type.CLIPBOARD, + PermissionInfo.Type.GEOLOCATION, PermissionInfo.Type.MICROPHONE, + PermissionInfo.Type.NOTIFICATION, PermissionInfo.Type.PROTECTED_MEDIA_IDENTIFIER, + PermissionInfo.Type.SENSORS)); + + for (@PermissionInfo.Type int type : permissionInfoTypes) { + PermissionInfo fakePermissionInfo = + new PermissionInfo(type, googleOrigin, googleOrigin, false); + websitePreferenceBridge.addPermissionInfo(fakePermissionInfo); + + fetcher.fetchPreferencesForCategory( + SiteSettingsCategory.createFromContentSettingsType( + PermissionInfo.getContentSettingsType(type)), + (sites) -> { + Assert.assertEquals(1, sites.size()); + + Website site = sites.iterator().next(); + Assert.assertNotNull(site.getPermissionInfo(type)); + }); + } + } + + @Test + @SmallTest + public void testFetchPreferencesForCategoryContentSettingExceptionTypes() throws Exception { + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(); + FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge(); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + + String googleOrigin = "https://google.com"; + String preferenceSource = "preference"; + ArrayList<Integer> contentSettingExceptionTypes = new ArrayList<>(Arrays.asList( + ContentSettingException.Type.ADS, ContentSettingException.Type.AUTOMATIC_DOWNLOADS, + ContentSettingException.Type.AUTOPLAY, ContentSettingException.Type.BACKGROUND_SYNC, + ContentSettingException.Type.COOKIE, ContentSettingException.Type.JAVASCRIPT, + ContentSettingException.Type.POPUP, ContentSettingException.Type.SOUND)); + + for (@ContentSettingsType int type : contentSettingExceptionTypes) { + @ContentSettingsType + int contentSettingsType = ContentSettingException.getContentSettingsType(type); + { + ContentSettingException fakeContentSettingException = + new ContentSettingException(contentSettingsType, googleOrigin, + ContentSettingValues.DEFAULT, preferenceSource); + websitePreferenceBridge.addContentSettingException(fakeContentSettingException); + + fetcher.fetchPreferencesForCategory( + SiteSettingsCategory.createFromContentSettingsType(contentSettingsType), + (sites) -> { + Assert.assertEquals(1, sites.size()); + + Website site = sites.iterator().next(); + assertContentSettingExceptionEquals(fakeContentSettingException, + site.getContentSettingException(type)); + }); + } + + // Make sure that the content setting value is updated. + { + ContentSettingException fakeContentSettingException = + new ContentSettingException(contentSettingsType, googleOrigin, + ContentSettingValues.BLOCK, preferenceSource); + websitePreferenceBridge.addContentSettingException(fakeContentSettingException); + + fetcher.fetchPreferencesForCategory( + SiteSettingsCategory.createFromContentSettingsType(contentSettingsType), + (sites) -> { + Assert.assertEquals(1, sites.size()); + + Website site = sites.iterator().next(); + assertContentSettingExceptionEquals(fakeContentSettingException, + site.getContentSettingException(type)); + }); + } + } + } + + @Test + @SmallTest + public void testFetchPreferencesForCategoryStorageInfo() throws Exception { + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(); + FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge(); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + + String googleOrigin = "https://google.com"; + String chromiumOrigin = "https://chromium.org"; + int storageSize = 256; + StorageInfo fakeStorageInfo = new StorageInfo(googleOrigin, 0, storageSize); + LocalStorageInfo fakeLocalStorageInfo = + new LocalStorageInfo(googleOrigin, storageSize, false); + LocalStorageInfo fakeImportantLocalStorageInfo = + new LocalStorageInfo(chromiumOrigin, storageSize, true); + + websitePreferenceBridge.addStorageInfo(fakeStorageInfo); + websitePreferenceBridge.addLocalStorageInfoMapEntry(fakeLocalStorageInfo); + websitePreferenceBridge.addLocalStorageInfoMapEntry(fakeImportantLocalStorageInfo); + + fetcher.fetchPreferencesForCategory( + SiteSettingsCategory.createFromType(SiteSettingsCategory.Type.USE_STORAGE), + (sites) -> { + Assert.assertEquals(1, sites.size()); + + Website site = sites.iterator().next(); + List<StorageInfo> storageInfos = site.getStorageInfo(); + Assert.assertEquals(1, storageInfos.size()); + + StorageInfo storageInfo = storageInfos.get(0); + Assert.assertEquals(fakeStorageInfo.getSize(), storageInfo.getSize()); + Assert.assertEquals(fakeStorageInfo.getHost(), storageInfo.getHost()); + + LocalStorageInfo localStorageInfo = site.getLocalStorageInfo(); + Assert.assertFalse(localStorageInfo.isDomainImportant()); + Assert.assertEquals(fakeLocalStorageInfo.getSize(), localStorageInfo.getSize()); + Assert.assertEquals( + fakeLocalStorageInfo.getOrigin(), localStorageInfo.getOrigin()); + }); + + // Test that the fetcher gets local storage info for important domains. + fetcher = new WebsitePermissionsFetcher(true); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + fetcher.fetchPreferencesForCategory( + SiteSettingsCategory.createFromType(SiteSettingsCategory.Type.USE_STORAGE), + (sites) -> { + Assert.assertEquals(2, sites.size()); + + for (Website site : sites) { + if (site.getAddress().matches(googleOrigin)) { + List<StorageInfo> storageInfos = site.getStorageInfo(); + Assert.assertEquals(1, storageInfos.size()); + + StorageInfo storageInfo = storageInfos.get(0); + Assert.assertEquals(fakeStorageInfo.getSize(), storageInfo.getSize()); + Assert.assertEquals(fakeStorageInfo.getHost(), storageInfo.getHost()); + + Assert.assertNull(site.getLocalStorageInfo()); + } else if (site.getAddress().matches(chromiumOrigin)) { + List<StorageInfo> storageInfos = site.getStorageInfo(); + Assert.assertEquals(0, storageInfos.size()); + + LocalStorageInfo localStorageInfo = site.getLocalStorageInfo(); + Assert.assertTrue(localStorageInfo.isDomainImportant()); + Assert.assertEquals(fakeImportantLocalStorageInfo.getSize(), + localStorageInfo.getSize()); + Assert.assertEquals(fakeImportantLocalStorageInfo.getOrigin(), + localStorageInfo.getOrigin()); + } else { + Assert.fail("The WebsitePermissionsFetcher should only return " + + "Website objects for the granted origins."); + } + } + }); + } + + @Test + @SmallTest + public void testFetchPreferencesForCategoryChooserDataTypes() throws Exception { + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(); + FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge(); + fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge); + + String googleOrigin = "https://google.com"; + ArrayList<Integer> chooserDataTypes = + new ArrayList<>(Arrays.asList(SiteSettingsCategory.Type.USB)); + + for (@SiteSettingsCategory.Type int type : chooserDataTypes) { + @ContentSettingsType + int chooserDataType = SiteSettingsCategory.objectChooserDataTypeFromGuard( + SiteSettingsCategory.contentSettingsType(type)); + Assert.assertNotEquals(-1, chooserDataType); + + ChosenObjectInfo fakeObjectInfo = new ChosenObjectInfo(chooserDataType, googleOrigin, + googleOrigin, "Chosen Object", "SerializedObjectData", false); + websitePreferenceBridge.addChosenObjectInfo(fakeObjectInfo); + + fetcher.fetchPreferencesForCategory( + SiteSettingsCategory.createFromType(type), (sites) -> { + Assert.assertEquals(1, sites.size()); + + List<ChosenObjectInfo> objectInfos = + new ArrayList<>(sites.iterator().next().getChosenObjectInfo()); + Assert.assertEquals(1, objectInfos.size()); + Assert.assertEquals(fakeObjectInfo, objectInfos.get(0)); + }); + } + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java index 5f1080f8..2ee8e89 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/TestBottomSheetContent.java
@@ -11,7 +11,6 @@ import android.view.View; import android.view.ViewGroup; -import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.ContentPriority; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -100,21 +99,21 @@ @Override public int getSheetContentDescriptionStringId() { - return R.string.contextual_suggestions_button_description; + return android.R.string.copy; } @Override public int getSheetHalfHeightAccessibilityStringId() { - return R.string.contextual_suggestions_sheet_opened_half; + return android.R.string.copy; } @Override public int getSheetFullHeightAccessibilityStringId() { - return R.string.contextual_suggestions_sheet_opened_full; + return android.R.string.copy; } @Override public int getSheetClosedAccessibilityStringId() { - return R.string.contextual_suggestions_sheet_closed; + return android.R.string.copy; } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImplTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImplTest.java deleted file mode 100644 index 260833e..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsSourceImplTest.java +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -import android.graphics.Bitmap; -import android.support.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -import org.chromium.base.Callback; -import org.chromium.base.task.test.BackgroundShadowAsyncTask; -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulatorTest.ShadowUrlUtilities; -import org.chromium.chrome.browser.image_fetcher.CachedImageFetcher; -import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; - -/** - * Unit tests for ContextualSuggestionsSourceImplTest. - */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE, - shadows = {ShadowUrlUtilities.class, BackgroundShadowAsyncTask.class}) -public class ContextualSuggestionsSourceImplTest { - private static final String IMAGE_URL = "http://foo.com/bar.png"; - private static final int FAVICON_DIMENSION = 100; - - ContextualSuggestionsSourceImpl mContextualSuggestionsSourceImpl; - - @Mock - ContextualSuggestionsBridge mBridge; - - @Mock - CachedImageFetcher mCachedImageFetcher; - - @Mock - Bitmap mBitmap; - - @Captor - ArgumentCaptor<Callback<Bitmap>> mCallbackCaptor; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContextualSuggestionsSourceImpl = - new ContextualSuggestionsSourceImpl(mBridge, mCachedImageFetcher); - // Answer with or without width/height. - doAnswer((InvocationOnMock invocation) -> { - mCallbackCaptor.getValue().onResult(mBitmap); - return null; - }) - .when(mCachedImageFetcher) - .fetchImage(any(), any(), mCallbackCaptor.capture()); - } - - @Test - @SmallTest - public void testFetchContextualSuggestionImage() throws Exception { - doReturn(IMAGE_URL).when(mBridge).getImageUrl(any()); - - SnippetArticle article = mock(SnippetArticle.class); - mContextualSuggestionsSourceImpl.fetchContextualSuggestionImage( - article, (Bitmap bitmap) -> { assertEquals(bitmap, mBitmap); }); - BackgroundShadowAsyncTask.runBackgroundTasks(); - ShadowLooper.runUiThreadTasks(); - } - - @Test - @SmallTest - public void testFetchContextualSuggestionImageWhenNullUrlIsReturned() throws Exception { - doReturn(null).when(mBridge).getImageUrl(any()); - - SnippetArticle article = mock(SnippetArticle.class); - mContextualSuggestionsSourceImpl.fetchContextualSuggestionImage( - article, (Bitmap bitmap) -> { assertEquals(bitmap, null); }); - BackgroundShadowAsyncTask.runBackgroundTasks(); - ShadowLooper.runUiThreadTasks(); - } - - @Test - @SmallTest - public void testFetchContextualSuggestionFavicon() throws Exception { - doReturn(IMAGE_URL).when(mBridge).getFaviconUrl(any()); - - SnippetArticle article = mock(SnippetArticle.class); - mContextualSuggestionsSourceImpl.fetchSuggestionFavicon(article, FAVICON_DIMENSION, - FAVICON_DIMENSION, (Bitmap bitmap) -> { assertEquals(bitmap, mBitmap); }); - BackgroundShadowAsyncTask.runBackgroundTasks(); - ShadowLooper.runUiThreadTasks(); - } - - @Test - @SmallTest - public void testFetchContextualSuggestionFaviconNullUrlIsReturned() throws Exception { - doReturn(null).when(mBridge).getFaviconUrl(any()); - - SnippetArticle article = mock(SnippetArticle.class); - mContextualSuggestionsSourceImpl.fetchSuggestionFavicon(article, FAVICON_DIMENSION, - FAVICON_DIMENSION, (Bitmap bitmap) -> { assertEquals(bitmap, null); }); - BackgroundShadowAsyncTask.runBackgroundTasks(); - ShadowLooper.runUiThreadTasks(); - } -} \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java deleted file mode 100644 index 4cb192d4..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java +++ /dev/null
@@ -1,533 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -import org.chromium.base.Callback; -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.contextual_suggestions.FetchHelper.Delegate; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.TabLaunchType; -import org.chromium.chrome.browser.tabmodel.TabModel; -import org.chromium.chrome.browser.tabmodel.TabModelObserver; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabSelectionType; -import org.chromium.chrome.browser.util.test.ShadowUrlUtilities; -import org.chromium.content_public.browser.RenderFrameHost; -import org.chromium.content_public.browser.WebContents; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -/** Unit tests for FetchHelper. */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE, shadows = {ShadowUrlUtilities.class}) -public final class FetchHelperTest { - private static final String STARTING_URL = "https://starting.url"; - private static final String DIFFERENT_URL = "https://different.url"; - - @Mock - private TabModelSelector mTabModelSelector; - @Mock - private TabModel mTabModel; - @Mock - private Tab mTab; - @Mock - private WebContents mWebContents; - @Mock - private RenderFrameHost mFrameHost; - @Mock - private Tab mTab2; - @Mock - private WebContents mWebContents2; - @Mock - private Delegate mDelegate; - @Captor - private ArgumentCaptor<TabObserver> mTabObserverCaptor; - @Captor - private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; - - private TabObserver getTabObserver() { - return mTabObserverCaptor.getValue(); - } - - private TabModelObserver getTabModelObserver() { - return mTabModelObserverCaptor.getValue(); - } - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - // Default tab setup. - doReturn(false).when(mTab).isIncognito(); - doReturn(false).when(mTab).isLoading(); - doReturn(77).when(mTab).getId(); - doReturn(STARTING_URL).when(mTab).getUrl(); - doReturn(mWebContents).when(mTab).getWebContents(); - // Default setup for tab 2. - doReturn(false).when(mTab2).isIncognito(); - doReturn(false).when(mTab2).isLoading(); - doReturn(88).when(mTab2).getId(); - doReturn(DIFFERENT_URL).when(mTab2).getUrl(); - doReturn(mWebContents2).when(mTab2).getWebContents(); - - // Default tab model selector setup. - List<TabModel> tabModels = new ArrayList<>(); - tabModels.add(mTabModel); - doReturn(tabModels).when(mTabModelSelector).getModels(); - doReturn(mTab).when(mTabModelSelector).getCurrentTab(); - - // Ensure Chrome feature list does not switch to native. - Map<String, Boolean> testFeatures = new HashMap<>(); - testFeatures.put(ChromeFeatureList.CONTEXTUAL_SUGGESTIONS_BUTTON, true); - ChromeFeatureList.setTestFeatures(testFeatures); - } - - @Test - public void createFetchHelper_currentTab_isIncognito() { - doReturn(true).when(mTab).isIncognito(); - FetchHelper helper = createFetchHelper(); - assertFalse(helper.isObservingTab(mTab)); - verify(mTab, times(0)).addObserver(any(TabObserver.class)); - } - - @Test - public void createFetchHelper_currentTab_null() { - doReturn(null).when(mTabModelSelector).getCurrentTab(); - FetchHelper helper = createFetchHelper(); - assertFalse(helper.isObservingTab(null)); - } - - @Test - public void createFetchHelper_observeCurrentTab() { - FetchHelper helper = createFetchHelper(); - assertTrue(helper.isObservingTab(mTab)); - assertNotNull(getTabObserver()); - } - - @Test - public void tabObserver_pageLoadStarted() { - FetchHelper helper = createFetchHelper(); - getTabObserver().onPageLoadStarted(mTab, STARTING_URL); - verify(mDelegate, times(1)).clearState(); - // Normally we would change the suffix here, but ShadowUrlUtilities don't support that now. - getTabObserver().onPageLoadStarted(mTab, DIFFERENT_URL); - verify(mDelegate, times(2)).clearState(); - } - - @Test - public void tabObserver_onUrlUpdated() { - FetchHelper helper = createFetchHelper(); - doReturn(DIFFERENT_URL).when(mTab).getUrl(); - getTabObserver().onUrlUpdated(mTab); - verify(mDelegate, times(1)).clearState(); - // Normally we would change the suffix here, but ShadowUrlUtilities don't support that now. - doReturn(STARTING_URL).when(mTab).getUrl(); - getTabObserver().onUrlUpdated(mTab); - verify(mDelegate, times(2)).clearState(); - - // Should be ignored, because URL is the same. - getTabObserver().onUrlUpdated(mTab); - verify(mDelegate, times(2)).clearState(); - - // Should be ignored, because tab is different. - doReturn(STARTING_URL).when(mTab2).getUrl(); - getTabObserver().onUrlUpdated(mTab2); - verify(mDelegate, times(2)).clearState(); - } - - @Test - public void tabObserver_didFirstVisuallyNonEmptyPaint() { - delayFetchExecutionTest((tabObserver) -> tabObserver.didFirstVisuallyNonEmptyPaint(mTab)); - } - - @Test - public void tabObserver_didFirstVisuallyNonEmptyPaint_pageLoadStarted_toSame() { - delayFetchExecutionTest_pageLoadStarted_toSame( - (tabObserver) -> tabObserver.didFirstVisuallyNonEmptyPaint(mTab)); - } - - @Test - public void tabObserver_didFirstVisuallyNonEmptyPaint_pageLoadStarted_toDifferent() { - delayFetchExecutionTest_pageLoadStarted_toDifferent( - (tabObserver) -> tabObserver.didFirstVisuallyNonEmptyPaint(mTab)); - } - - @Test - public void tabObserver_onPageLoadFinished() { - delayFetchExecutionTest( - (tabObserver) -> tabObserver.onPageLoadFinished(mTab, STARTING_URL)); - } - - @Test - public void tabObserver_onPageLoadFinished_pageLoadStarted_toSame() { - delayFetchExecutionTest_pageLoadStarted_toSame( - (tabObserver) -> tabObserver.onPageLoadFinished(mTab, STARTING_URL)); - } - - @Test - public void tabObserver_onPageLoadFinished_pageLoadStarted_toDifferent() { - delayFetchExecutionTest_pageLoadStarted_toDifferent( - (tabObserver) -> tabObserver.onPageLoadFinished(mTab, STARTING_URL)); - } - - @Test - public void tabObserver_onLoadStopped() { - delayFetchExecutionTest((tabObserver) -> tabObserver.onLoadStopped(mTab, false)); - } - - @Test - public void tabObserver_onLoadStopped_pageLoadStarted_toSame() { - delayFetchExecutionTest_pageLoadStarted_toSame( - (tabObserver) -> tabObserver.onLoadStopped(mTab, false)); - } - - @Test - public void tabObserver_onLoadStopped_pageLoadStarted_toDifferent() { - delayFetchExecutionTest_pageLoadStarted_toDifferent( - (tabObserver) -> tabObserver.onLoadStopped(mTab, false)); - } - - @Test - public void tabObserver_multipleSignals_triggersOnce() { - delayFetchExecutionTest((tabObserver) -> { - tabObserver.didFirstVisuallyNonEmptyPaint(mTab); - tabObserver.onPageLoadFinished(mTab, STARTING_URL); - tabObserver.onLoadStopped(mTab, false); - }); - } - - @Test - public void tabModelObserver_addTab_closeTab_isLoading() { - doReturn(true).when(mTab).isLoading(); - addAndcloseNonSelectedTab(() -> closeTab(mTab)); - } - - @Test - public void tabModelObserver_addTab_removeTab_isLoading() { - doReturn(true).when(mTab).isLoading(); - addAndcloseNonSelectedTab(() -> removeTab(mTab)); - } - - @Test - public void tabModelObserver_addTab_closeTab_doneLoading() { - doReturn(false).when(mTab).isLoading(); - addAndcloseNonSelectedTab(() -> closeTab(mTab)); - } - - @Test - public void tabModelObserver_addTab_removeTab_doneLoading() { - doReturn(false).when(mTab).isLoading(); - addAndcloseNonSelectedTab(() -> removeTab(mTab)); - } - - @Test - public void tabModelObserver_selectTab_fetch_selectTab_same() { - doReturn(false).when(mTab).isLoading(); - FetchHelper helper = createFetchHelper(); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents)); - runUntilFetchPossible(); - verify(mDelegate, times(1)).requestSuggestions(eq(STARTING_URL)); - selectTab(mTab); - verify(mDelegate, times(1)).requestSuggestions(eq(STARTING_URL)); - } - - @Test - public void secondTab_selected_withoutBeingAdded() { - FetchHelper helper = createFetchHelper(); - selectTab(mTab2); - verify(mTab2, times(1)).addObserver(eq(getTabObserver())); - assertTrue(helper.isObservingTab(mTab2)); - } - - @Test - public void secondTab_add_select_close_whenDoneLoading() { - FetchHelper helper = createFetchHelper(); - addTab(mTab2); - verify(mTab2, times(1)).addObserver(eq(getTabObserver())); - assertTrue(helper.isObservingTab(mTab2)); - verify(mDelegate, times(0)).clearState(); - - selectTab(mTab2); - assertTrue(helper.isObservingTab(mTab2)); - verify(mTab2, times(1)).addObserver(eq(getTabObserver())); - verify(mDelegate, times(1)).clearState(); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents2)); - - closeTab(mTab2); - assertFalse(helper.isObservingTab(mTab2)); - verify(mDelegate, times(2)).clearState(); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents2)); - verify(mDelegate, times(0)).requestSuggestions(any(String.class)); - } - - @Test - public void secondTab_select_close_whenLoading() { - doReturn(true).when(mTab2).isLoading(); - - FetchHelper helper = createFetchHelper(); - selectTab(mTab2); - assertTrue(helper.isObservingTab(mTab2)); - verify(mTab2, times(1)).addObserver(eq(getTabObserver())); - verify(mDelegate, times(1)).clearState(); - verify(mDelegate, times(0)).reportFetchDelayed(eq(mWebContents2)); - - closeTab(mTab2); - assertFalse(helper.isObservingTab(mTab2)); - verify(mDelegate, times(2)).clearState(); - verify(mDelegate, times(0)).reportFetchDelayed(eq(mWebContents2)); - verify(mDelegate, times(0)).requestSuggestions(any(String.class)); - } - - @Test - public void secondTab_add_select_fetch_close_whenDoneLoading() { - FetchHelper helper = createFetchHelper(); - addTab(mTab2); - selectTab(mTab2); - runUntilFetchPossible(); - verify(mDelegate, times(1)).requestSuggestions(eq(DIFFERENT_URL)); - - closeTab(mTab2); - verify(mDelegate, times(2)).clearState(); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents2)); - verify(mDelegate, times(1)).requestSuggestions(any(String.class)); - } - - @Test - public void secondTab_add_select_fetch_close_whenLoading() { - doReturn(true).when(mTab2).isLoading(); - FetchHelper helper = createFetchHelper(); - addTab(mTab2); - selectTab(mTab2); - runUntilFetchPossible(); - - closeTab(mTab2); - verify(mDelegate, times(2)).clearState(); - verify(mDelegate, times(0)).reportFetchDelayed(eq(mWebContents2)); - verify(mDelegate, times(0)).requestSuggestions(eq(DIFFERENT_URL)); - } - - @Test - public void switchTabs_afterFetchOfVisibleTriggered() { - doReturn(true).when(mTab).isLoading(); - FetchHelper helper = createFetchHelper(); - addTab(mTab2); - selectTab(mTab2); - runUntilFetchPossible(); - verify(mDelegate, times(1)).clearState(); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents2)); - verify(mDelegate, times(1)).requestSuggestions(eq(DIFFERENT_URL)); - - selectTab(mTab); - verify(mDelegate, times(2)).clearState(); - verify(mDelegate, times(0)).reportFetchDelayed(eq(mWebContents)); - verify(mDelegate, times(0)).requestSuggestions(eq(STARTING_URL)); - - closeTab(mTab2); - verify(mDelegate, times(2)).clearState(); - } - - @Test - public void switchTabs_afterFetchOfNotVisibleWouldHaveTriggered() { - doReturn(true).when(mTab).isLoading(); - doReturn(true).when(mTab2).isLoading(); - FetchHelper helper = createFetchHelper(); - addTab(mTab2); - - // First tab finishes load in the background. - getTabObserver().onPageLoadFinished(mTab, STARTING_URL); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents)); - - // Switching tabs, therefore the pending fetch is on a background tab. - selectTab(mTab2); - verify(mDelegate, times(1)).clearState(); - - // This should cancel/not-trigger the fetch in background. - runUntilFetchPossible(); - verify(mDelegate, times(0)).requestSuggestions(any(String.class)); - - // This time fetch is possible immediately. - selectTab(mTab); - verify(mDelegate, times(2)).clearState(); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents)); - verify(mDelegate, times(1)).requestSuggestions(eq(STARTING_URL)); - } - - @Test - public void canonicalUrl_isResolved() { - doReturn(false).when(mTab).isLoading(); - doReturn(mFrameHost).when(mWebContents).getMainFrame(); - doAnswer(new Answer<Void>() { - @Override - public Void answer(InvocationOnMock invocation) { - if (invocation.getArguments()[0] instanceof Callback) { - @SuppressWarnings("unchecked") - Callback<String> callback = (Callback<String>) invocation.getArguments()[0]; - callback.onResult(DIFFERENT_URL); - } - return null; - } - }) - .when(mFrameHost) - .getCanonicalUrlForSharing(any()); - FetchHelper helper = createFetchHelper(); - - getTabObserver().onPageLoadFinished(mTab, STARTING_URL); - verify(mFrameHost, times(0)).getCanonicalUrlForSharing(any()); - runUntilFetchPossible(); - verify(mFrameHost, times(1)).getCanonicalUrlForSharing(any()); - verify(mDelegate, times(1)).requestSuggestions(DIFFERENT_URL); - } - - @Test - public void canonicalUrl_readinessStateIsNull() { - doReturn(true).when(mTab).isLoading(); - - FetchHelper helper = createFetchHelper(); - - doReturn(mFrameHost).when(mWebContents).getMainFrame(); - doAnswer(new Answer<Void>() { - @Override - public Void answer(InvocationOnMock invocation) { - if (invocation.getArguments()[0] instanceof Callback) { - closeTab(mTab); - @SuppressWarnings("unchecked") - Callback<String> callback = (Callback<String>) invocation.getArguments()[0]; - callback.onResult(DIFFERENT_URL); - } - return null; - } - }) - .when(mFrameHost) - .getCanonicalUrlForSharing(any()); - getTabObserver().onPageLoadFinished(mTab, STARTING_URL); - runUntilFetchPossible(); - verify(mDelegate, times(0)).requestSuggestions(DIFFERENT_URL); - } - - @Test - public void getMinimumFetchDelayMillis_Default() { - assertEquals(FetchHelper.getMinimumFetchDelayMillis(), - TimeUnit.SECONDS.toMillis(FetchHelper.MINIMUM_FETCH_DELAY_SECONDS)); - } - - private void addTab(Tab tab) { - getTabModelObserver().didAddTab(tab, TabLaunchType.FROM_LINK); - } - - private void selectTab(Tab tab) { - getTabModelObserver().didSelectTab(tab, TabSelectionType.FROM_USER, 0); - } - - private void closeTab(Tab tab) { - getTabModelObserver().willCloseTab(tab, true); - } - - private void removeTab(Tab tab) { - getTabModelObserver().tabRemoved(tab); - } - - private void runUntilFetchPossible() { - ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); - } - - private FetchHelper createFetchHelper() { - FetchHelper helper = spy(new FetchHelper(mDelegate, mTabModelSelector)); - when(helper.requireCurrentPageFromSRP()).thenReturn(false); - when(helper.requireNavChainFromSRP()).thenReturn(false); - - if (mTabModelSelector.getCurrentTab() != null && !mTab.isIncognito()) { - verify(mTab, times(1)).addObserver(mTabObserverCaptor.capture()); - } - verify(mTabModel, times(1)).addObserver(mTabModelObserverCaptor.capture()); - return helper; - } - - private void delayFetchExecutionTest(Consumer<TabObserver> consumer) { - FetchHelper helper = createFetchHelper(); - verify(mTab, times(1)).addObserver(mTabObserverCaptor.capture()); - consumer.accept(getTabObserver()); - verify(mDelegate, times(0)).requestSuggestions(eq(STARTING_URL)); - verify(mDelegate, times(1)).reportFetchDelayed(eq(mWebContents)); - - runUntilFetchPossible(); - verify(mDelegate, times(1)).requestSuggestions(eq(STARTING_URL)); - } - - private void delayFetchExecutionTest_pageLoadStarted_toSame(Consumer<TabObserver> consumer) { - FetchHelper helper = createFetchHelper(); - verify(mTab, times(1)).addObserver(mTabObserverCaptor.capture()); - consumer.accept(getTabObserver()); - - mTabObserverCaptor.getValue().onPageLoadStarted(mTab, STARTING_URL); - verify(mDelegate, times(1)).clearState(); - - runUntilFetchPossible(); - verify(mDelegate, times(1)).requestSuggestions(eq(STARTING_URL)); - } - - private void delayFetchExecutionTest_pageLoadStarted_toDifferent( - Consumer<TabObserver> consumer) { - FetchHelper helper = createFetchHelper(); - verify(mTab, times(1)).addObserver(mTabObserverCaptor.capture()); - consumer.accept(getTabObserver()); - - mTabObserverCaptor.getValue().onPageLoadStarted(mTab, DIFFERENT_URL); - verify(mDelegate, times(1)).clearState(); - - // Request suggestions should not be called. - runUntilFetchPossible(); - verify(mDelegate, times(0)).requestSuggestions(eq(STARTING_URL)); - } - - private void addAndcloseNonSelectedTab(Runnable closeTabRunnable) { - // Starting with null tab so we can add one. - doReturn(null).when(mTabModelSelector).getCurrentTab(); - FetchHelper helper = createFetchHelper(); - verify(mTabModel, times(1)).addObserver(mTabModelObserverCaptor.capture()); - - addTab(mTab); - assertTrue(helper.isObservingTab(mTab)); - verify(mDelegate, times(0)).requestSuggestions(eq(STARTING_URL)); - verify(mDelegate, times(0)).reportFetchDelayed(eq(mWebContents)); - - closeTabRunnable.run(); - assertFalse(helper.isObservingTab(mTab)); - verify(mDelegate, times(0)).requestSuggestions(eq(STARTING_URL)); - verify(mDelegate, times(0)).reportFetchDelayed(eq(mWebContents)); - verify(mDelegate, times(0)).clearState(); - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/GoogleSearchRestrictionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/GoogleSearchRestrictionTest.java deleted file mode 100644 index a2fc9f7b..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/GoogleSearchRestrictionTest.java +++ /dev/null
@@ -1,388 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; - -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_public.browser.NavigationController; -import org.chromium.content_public.browser.NavigationEntry; -import org.chromium.content_public.browser.NavigationHistory; -import org.chromium.ui.base.PageTransition; - -/** Unit tests for FetchHelper#isFromGoogleSearch. */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class GoogleSearchRestrictionTest { - private static final String GOOGLE_SEARCH_URL = "https://www.google.com/search?q=foo"; - private static final String FOO_URL = "www.foo.com"; - private static final String BAR_URL = "www.bar.com"; - private static final String BAZ_URL = "www.baz.com"; - private static final String QUX_URL = "www.qux.com"; - private static final String QUUX_URL = "www.quux.com"; - - /** - * PageTransition types that are considered "accepted" when considering all navigation history. - */ - private static final int[] ACCEPTED_TRANSITIONS = new int[] { - PageTransition.LINK, PageTransition.MANUAL_SUBFRAME, PageTransition.FORM_SUBMIT}; - - /** - * PageTransition types that are rejected when considering all navigation history. - */ - private static final int[] REJECTED_TRANSITIONS = new int[] {PageTransition.TYPED, - PageTransition.AUTO_BOOKMARK, PageTransition.AUTO_SUBFRAME, PageTransition.GENERATED, - PageTransition.AUTO_TOPLEVEL, PageTransition.RELOAD, PageTransition.KEYWORD, - PageTransition.KEYWORD_GENERATED}; - - private FetchHelper mFetchHelper; - - @Before - public void setUp() { - mFetchHelper = spy(new FetchHelper(null, mock(TabModelSelector.class)) { - @Override - boolean requireCurrentPageFromSRP() { - return false; - } - - @Override - boolean requireNavChainFromSRP() { - return false; - } - }); - - doReturn(true).when(mFetchHelper).isGoogleSearchUrl(GOOGLE_SEARCH_URL); - doReturn(false).when(mFetchHelper).isGoogleSearchUrl(FOO_URL); - doReturn(false).when(mFetchHelper).isGoogleSearchUrl(BAR_URL); - doReturn(false).when(mFetchHelper).isGoogleSearchUrl(BAZ_URL); - doReturn(false).when(mFetchHelper).isGoogleSearchUrl(QUX_URL); - doReturn(false).when(mFetchHelper).isGoogleSearchUrl(QUUX_URL); - } - - @Test - public void testOneNavEntry_Link() { - NavigationController navController = createOneEntryNavController(PageTransition.LINK); - assertFalse(mFetchHelper.isFromGoogleSearch(navController, true)); - } - - @Test - public void testTwoNavEntries_Accepted_FromSRP() { - for (int i = 0; i < ACCEPTED_TRANSITIONS.length; i++) { - NavigationController navController = - createTwoEntryNavController(ACCEPTED_TRANSITIONS[i], true); - assertTrue("From SRP using " + ACCEPTED_TRANSITIONS[i] + " expected to be true.", - mFetchHelper.isFromGoogleSearch(navController, false)); - } - } - - @Test - public void testTwoNavEntries_Accepted_Masked_FromSRP() { - for (int i = 0; i < ACCEPTED_TRANSITIONS.length; i++) { - int transition = ACCEPTED_TRANSITIONS[i] | PageTransition.FORWARD_BACK - | PageTransition.IS_REDIRECT_MASK; - NavigationController navController = createTwoEntryNavController(transition, true); - assertTrue("From SRP using " + ACCEPTED_TRANSITIONS[i] + " expected to be true.", - mFetchHelper.isFromGoogleSearch(navController, false)); - } - } - - @Test - public void testTwoNavEntries_Rejected_FromSRP() { - for (int i = 0; i < REJECTED_TRANSITIONS.length; i++) { - NavigationController navController = - createTwoEntryNavController(REJECTED_TRANSITIONS[i], false); - assertFalse("From SRP using " + REJECTED_TRANSITIONS[i] + " expected to be false.", - mFetchHelper.isFromGoogleSearch(navController, false)); - } - } - - @Test - public void testTwoNavEntries_Rejected_Masked_FromSRP() { - for (int i = 0; i < REJECTED_TRANSITIONS.length; i++) { - int transition = REJECTED_TRANSITIONS[i] | PageTransition.FORWARD_BACK - | PageTransition.IS_REDIRECT_MASK; - NavigationController navController = createTwoEntryNavController(transition, false); - assertFalse("From SRP using " + REJECTED_TRANSITIONS[i] + " expected to be false.", - mFetchHelper.isFromGoogleSearch(navController, false)); - } - } - - @Test - public void testTwoNavEntries_Link_FromBar() { - NavigationController navController = - createTwoEntryNavController(PageTransition.LINK, false); - assertFalse(mFetchHelper.isFromGoogleSearch(navController, true)); - } - - @Test - public void testLongNavHistory_Link_FromGoogle_OnlyConsiderCurrent() { - NavigationController navController = - createLongNavHistory(PageTransition.LINK, PageTransition.LINK, true); - assertFalse(mFetchHelper.isFromGoogleSearch(navController, true)); - } - - @Test - public void testLongNavHistory_Link_FromBar_OnlyConsiderCurrent() { - NavigationController navController = - createLongNavHistory(PageTransition.LINK, PageTransition.LINK, false); - assertFalse(mFetchHelper.isFromGoogleSearch(navController, true)); - } - - @Test - public void testLongNavHistory_Accepted_Accepted_FromSRP_ConsiderAllHistory() { - for (int i = 0; i < ACCEPTED_TRANSITIONS.length; i++) { - NavigationController navController = - createLongNavHistory(PageTransition.LINK, ACCEPTED_TRANSITIONS[i], true); - assertTrue("From SRP using " + ACCEPTED_TRANSITIONS[i] + " expected to be true.", - mFetchHelper.isFromGoogleSearch(navController, false)); - } - } - - @Test - public void testLongNavHistory_Accepted_Rejected_FromSRP_ConsiderAllHistory() { - for (int i = 0; i < REJECTED_TRANSITIONS.length; i++) { - NavigationController navController = - createLongNavHistory(PageTransition.LINK, REJECTED_TRANSITIONS[i], true); - assertFalse("From SRP using " + REJECTED_TRANSITIONS[i] + " expected to be false.", - mFetchHelper.isFromGoogleSearch(navController, false)); - } - } - - @Test - public void testLongNavHistory_Link_FromBar_ConsiderAllHistory() { - NavigationController navController = - createLongNavHistory(PageTransition.LINK, PageTransition.LINK, false); - assertFalse(mFetchHelper.isFromGoogleSearch(navController, false)); - } - - /** - * Creates a {@link NavigationController} for a navigation history with a single entry. - * - * @param pageTransition The {@link PageTransition} type for the entry. - * @return A {@link NavigationController} with one entry. - */ - private NavigationController createOneEntryNavController(int pageTransition) { - NavigationEntry entry = new NavigationEntry( - 1, FOO_URL, FOO_URL, FOO_URL, "Foo", null, null, pageTransition, 0); - - NavigationHistory navHistory = new NavigationHistory(); - navHistory.addEntry(entry); - navHistory.setCurrentEntryIndex(0); - - return new FakeNavigationController(navHistory); - } - - /** - * Creates a {@link NavigationController} for a navigation history with two entries. - * - * @param pageTransition The {@link PageTransition} type for the current nav entry. - * @param fromSRP Whether the first entry should be a Google search results page. - * @return A {@link NavigationController} with two entries. - */ - private NavigationController createTwoEntryNavController(int pageTransition, boolean fromSRP) { - NavigationEntry firstEntry; - if (fromSRP) { - firstEntry = new NavigationEntry(0, GOOGLE_SEARCH_URL, GOOGLE_SEARCH_URL, - GOOGLE_SEARCH_URL, "foo - Google Search", null, null, PageTransition.TYPED, 0); - } else { - firstEntry = new NavigationEntry( - 0, BAR_URL, BAR_URL, BAR_URL, "bar", null, null, PageTransition.LINK, 0); - } - - NavigationEntry currentEntry = new NavigationEntry( - 1, FOO_URL, FOO_URL, FOO_URL, "Foo", null, null, pageTransition, 0); - - NavigationHistory navHistory = new NavigationHistory(); - navHistory.addEntry(firstEntry); - navHistory.addEntry(currentEntry); - navHistory.setCurrentEntryIndex(1); - - return new FakeNavigationController(navHistory); - } - - /** - * Creates {@link NavigationController} with a longer navigation history. - * - * @param previousPageTransition The {@link PageTransition} type for the nav entry before the - * current entry. - * @param currentPageTransition The {@link PageTransition} type for the current nav entry. - * @param fromSRP Whether the navigation stack should originate from a Google search results - * page. - * @return A {@link NavigationController} with multiple entries. - */ - private NavigationController createLongNavHistory( - int previousPageTransition, int currentPageTransition, boolean fromSRP) { - NavigationEntry firstEntry = new NavigationEntry( - 0, BAZ_URL, BAZ_URL, BAZ_URL, "baz", null, null, PageTransition.LINK, 0); - NavigationEntry secondEntry; - if (fromSRP) { - secondEntry = new NavigationEntry(1, GOOGLE_SEARCH_URL, GOOGLE_SEARCH_URL, - GOOGLE_SEARCH_URL, "foo - Google Search", null, null, PageTransition.LINK, 0); - } else { - secondEntry = new NavigationEntry( - 1, BAR_URL, BAR_URL, BAR_URL, "bar", null, null, PageTransition.LINK, 0); - } - - NavigationEntry thirdEntry = new NavigationEntry( - 2, FOO_URL, FOO_URL, FOO_URL, "Foo", null, null, previousPageTransition, 0); - - NavigationEntry fourthEntry = new NavigationEntry(3, QUX_URL, QUX_URL, QUX_URL, "qux", null, - null, currentPageTransition | PageTransition.FORWARD_BACK, 0); - - NavigationEntry fifthEntry = new NavigationEntry( - 4, QUUX_URL, QUUX_URL, QUUX_URL, "quux", null, null, PageTransition.TYPED, 0); - - NavigationHistory navHistory = new NavigationHistory(); - navHistory.addEntry(firstEntry); - navHistory.addEntry(secondEntry); - navHistory.addEntry(thirdEntry); - navHistory.addEntry(fourthEntry); - navHistory.addEntry(fifthEntry); - navHistory.setCurrentEntryIndex(3); - - return new FakeNavigationController(navHistory); - } - - private class FakeNavigationController implements NavigationController { - private NavigationHistory mNavHistory; - - public FakeNavigationController(NavigationHistory navHistory) { - mNavHistory = navHistory; - } - - @Override - public NavigationEntry getEntryAtIndex(int index) { - return mNavHistory.getEntryAtIndex(index); - } - - @Override - public int getLastCommittedEntryIndex() { - return mNavHistory.getCurrentEntryIndex(); - } - - // Dummy implementations. - - @Override - public boolean canGoBack() { - return false; - } - - @Override - public boolean canGoForward() { - return false; - } - - @Override - public boolean canGoToOffset(int offset) { - return false; - } - - @Override - public void goToOffset(int offset) {} - - @Override - public void goToNavigationIndex(int index) {} - - @Override - public void goBack() {} - - @Override - public void goForward() {} - - @Override - public boolean isInitialNavigation() { - return false; - } - - @Override - public void loadIfNecessary() {} - - @Override - public boolean needsReload() { - return false; - } - - @Override - public void setNeedsReload() {} - - @Override - public void reload(boolean checkForRepost) {} - - @Override - public void reloadBypassingCache(boolean checkForRepost) {} - - @Override - public void cancelPendingReload() {} - - @Override - public void continuePendingReload() {} - - @Override - public void loadUrl(LoadUrlParams params) {} - - @Override - public void clearHistory() {} - - @Override - public NavigationHistory getNavigationHistory() { - return null; - } - - @Override - public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit) { - return null; - } - - @Override - public void clearSslPreferences() {} - - @Override - public boolean getUseDesktopUserAgent() { - return false; - } - - @Override - public void setUseDesktopUserAgent(boolean override, boolean reloadOnChange) {} - - @Override - public NavigationEntry getVisibleEntry() { - return null; - } - - @Override - public NavigationEntry getPendingEntry() { - return null; - } - - @Override - public boolean removeEntryAtIndex(int index) { - return false; - } - - @Override - public String getEntryExtraData(int index, String key) { - return null; - } - - @Override - public void setEntryExtraData(int index, String key, String value) {} - - @Override - public boolean isEntryMarkedToBeSkipped(int index) { - return false; - } - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS deleted file mode 100644 index bf7da42c..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://chrome/browser/android/contextual_suggestions/OWNERS
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimerTest.java deleted file mode 100644 index 4a21ed59..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/PageViewTimerTest.java +++ /dev/null
@@ -1,412 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.contextual_suggestions; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.os.SystemClock; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -import org.chromium.base.metrics.test.ShadowRecordHistogram; -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; -import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; -import org.chromium.chrome.browser.contextual_suggestions.PageViewTimer.DurationBucket; -import org.chromium.chrome.browser.contextual_suggestions.PageViewTimer.NavigationSource; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.Tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.TabModel; -import org.chromium.chrome.browser.tabmodel.TabModelObserver; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabSelectionType; -import org.chromium.chrome.browser.util.test.ShadowUrlUtilities; -import org.chromium.content_public.browser.NavigationController; -import org.chromium.content_public.browser.NavigationEntry; -import org.chromium.content_public.browser.WebContents; - -import java.util.ArrayList; -import java.util.List; - -/** Unit tests for PageViewTimer. */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE, shadows = {ShadowRecordHistogram.class, ShadowUrlUtilities.class}) -public final class PageViewTimerTest { - private static final String STARTING_URL = "http://starting.url"; - private static final String DIFFERENT_URL = "http://different.url"; - private static final int SAMPLE_PAGE_VIEW_TIME = 5678; - private static final String PAGE_VIEW_TIME_METRIC = "ContextualSuggestions.PageViewTime"; - - @Mock - private WebContents mWebContents; - @Mock - private LayoutManagerChrome mLayoutManagerChrome; - @Mock - private NavigationController mNavigationController; - @Mock - private NavigationEntry mNavigationEntry; - @Mock - private TabModelSelector mTabModelSelector; - @Mock - private TabModel mTabModel; - @Mock - private Tab mTab; - @Mock - private Tab mTab2; - @Captor - private ArgumentCaptor<TabObserver> mTabObserverCaptor; - @Captor - private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; - @Captor - private ArgumentCaptor<EmptyOverviewModeObserver> mEmptyOverviewModeObserverCaptor; - - private PageViewTimer mTimer; - - private TabObserver getTabObserver() { - return mTabObserverCaptor.getValue(); - } - - private TabModelObserver getTabModelObserver() { - return mTabModelObserverCaptor.getValue(); - } - - private EmptyOverviewModeObserver getEmptyOverviewModeObserver() { - return mEmptyOverviewModeObserverCaptor.getValue(); - } - - @Before - public void setUp() { - ShadowRecordHistogram.reset(); - MockitoAnnotations.initMocks(this); - - // Navigation stack setup. - doReturn("https://goto.google.com/explore-on-content-viewer") - .when(mNavigationEntry) - .getReferrerUrl(); - doReturn(0).when(mNavigationController).getLastCommittedEntryIndex(); - doReturn(mNavigationEntry).when(mNavigationController).getEntryAtIndex(0); - doReturn(mNavigationController).when(mWebContents).getNavigationController(); - doReturn(mWebContents).when(mTab).getWebContents(); - - // Default tab setup. - doReturn(false).when(mTab).isIncognito(); - doReturn(true).when(mTab).isLoading(); - doReturn(77).when(mTab).getId(); - doReturn(STARTING_URL).when(mTab).getUrl(); - - // Default tab model selector setup. - List<TabModel> tabModels = new ArrayList<>(); - tabModels.add(mTabModel); - doReturn(tabModels).when(mTabModelSelector).getModels(); - doReturn(mTab).when(mTabModelSelector).getCurrentTab(); - } - - @Test - public void createPageViewTimer_withNoTab_noCrash() { - doReturn(null).when(mTabModelSelector).getCurrentTab(); - PageViewTimer timer = createPageViewTimer(); - } - - @Test - public void selectTab_didFirstVisuallyNonEmptyPaint_reported() { - selectTab_showContent_stopTimer( - showContentByDidFirstVisuallyNonEmptyPaint(mTab), stopTimerByClosingTab(mTab), 1); - } - - @Test - public void selectTab_onPageLoadFinished_close_reported() { - selectTab_showContent_stopTimer( - showContentByOnPageLoadFinished(mTab), stopTimerByClosingTab(mTab), 1); - } - - @Test - public void selectTab_onLoadStopped_close_reported() { - selectTab_showContent_stopTimer( - showContentByOnLoadStopped(mTab), stopTimerByClosingTab(mTab), 1); - } - - @Test - public void selectTab_whenLoaded_close_reported() { - doReturn(false).when(mTab).isLoading(); - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByClosingTab(mTab), 1); - } - - @Test - public void selectTab_notLoaded_close_ignored() { - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByClosingTab(mTab), 0); - } - - @Test - public void selectTab_didFirstVisuallyNonEmptyPaint_onUpdateUrl_reported() { - selectTab_showContent_stopTimer(showContentByDidFirstVisuallyNonEmptyPaint(mTab), - stopTimerByOnUpdateUrl(mTab, DIFFERENT_URL), 1); - } - - @Test - public void selectTab_onPageLoadFinished_onUpdateUrl_reported() { - selectTab_showContent_stopTimer(showContentByOnPageLoadFinished(mTab), - stopTimerByOnUpdateUrl(mTab, DIFFERENT_URL), 1); - } - - @Test - public void selectTab_onLoadStopped_onUpdateUrl_reported() { - selectTab_showContent_stopTimer( - showContentByOnLoadStopped(mTab), stopTimerByOnUpdateUrl(mTab, DIFFERENT_URL), 1); - } - - @Test - public void selectTab_whenLoaded_onUpdateUrl_reported() { - doReturn(false).when(mTab).isLoading(); - selectTab_showContent_stopTimer( - doNothingToShowContent(), stopTimerByOnUpdateUrl(mTab, DIFFERENT_URL), 1); - } - - @Test - public void selectTab_notLoaded_onUpdateUrl_ignored() { - selectTab_showContent_stopTimer( - doNothingToShowContent(), stopTimerByOnUpdateUrl(mTab, DIFFERENT_URL), 0); - } - - @Test - public void selectTab_whenLoaded_onUpdateUrlToSame_ignored() { - doReturn(false).when(mTab).isLoading(); - selectTab_showContent_stopTimer( - doNothingToShowContent(), stopTimerByOnUpdateUrl(mTab, STARTING_URL), 0); - } - - @Test - public void selectTab_whenNonHttpOrHttpsUrlLoaded_tabRemoved_ignored() { - doReturn(false).when(mTab).isLoading(); - doReturn("chrome://snippets-internals").when(mTab).getUrl(); - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByRemovingTab(mTab), 0); - } - - @Test - public void selectTab_whenLoaded_switchTabs_reported() { - doReturn(false).when(mTab).isLoading(); - selectTab_showContent_stopTimer( - doNothingToShowContent(), stopTimerBySwitchingTab(mTab, mTab2), 1); - } - - @Test - public void selectTab_notLoaded_switchTabs_ignored() { - selectTab_showContent_stopTimer( - doNothingToShowContent(), stopTimerBySwitchingTab(mTab, mTab2), 0); - } - - @Test - public void selectTab_whenLoaded_tabRemoved_reported() { - doReturn(false).when(mTab).isLoading(); - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByRemovingTab(mTab), 1); - } - - @Test - public void selectTab_notLoaded_tabRemoved_ignored() { - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByRemovingTab(mTab), 0); - } - - @Test - public void selectTab_whenLoaded_closeChrome_reported() { - doReturn(false).when(mTab).isLoading(); - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByClosingChrome(), 1); - } - - @Test - public void selectTab_notLoaded_closeChrome_reported() { - selectTab_showContent_stopTimer(doNothingToShowContent(), stopTimerByClosingChrome(), 0); - } - - @Test - public void selectTab_didFirstVisuallyNonEmptyPaint_hideShow_reported() { - selectTab_showContent_pauseTimer_resumeTimer_stopTimer( - showContentByDidFirstVisuallyNonEmptyPaint(mTab), pauseTimerByHidingTab(mTab), - resumeTimerByShowingTab(mTab), stopTimerByClosingTab(mTab), 1); - } - - @Test - public void selectTab_didFirstVisuallyNonEmptyPaint_tabSwitcherOpenClose_reported() { - selectTab_showContent_pauseTimer_resumeTimer_stopTimer( - showContentByDidFirstVisuallyNonEmptyPaint(mTab), pauseTimerByOpeningTabSwitcher(), - resumeTimerByClosingTabSwitcher(), stopTimerByClosingTab(mTab), 1); - } - - @Test - public void getNavigationSource_nullEntry() { - PageViewTimer timer = createPageViewTimer(); - doReturn(0).when(mNavigationController).getLastCommittedEntryIndex(); - doReturn(null).when(mNavigationController).getEntryAtIndex(0); - doReturn(mNavigationController).when(mWebContents).getNavigationController(); - - assertEquals(timer.getNavigationSource(mWebContents), NavigationSource.OTHER); - } - - @Test - public void getNavigationSource_nullReferrer() { - PageViewTimer timer = createPageViewTimer(); - doReturn(null).when(mNavigationEntry).getReferrerUrl(); - doReturn(0).when(mNavigationController).getLastCommittedEntryIndex(); - doReturn(mNavigationEntry).when(mNavigationController).getEntryAtIndex(0); - doReturn(mNavigationController).when(mWebContents).getNavigationController(); - - assertEquals(timer.getNavigationSource(mWebContents), NavigationSource.OTHER); - } - - @Test - public void getNavigationSource_emptyReferrer() { - PageViewTimer timer = createPageViewTimer(); - doReturn("").when(mNavigationEntry).getReferrerUrl(); - doReturn(0).when(mNavigationController).getLastCommittedEntryIndex(); - doReturn(mNavigationEntry).when(mNavigationController).getEntryAtIndex(0); - doReturn(mNavigationController).when(mWebContents).getNavigationController(); - - assertEquals(timer.getNavigationSource(mWebContents), NavigationSource.OTHER); - } - - @Test - public void getNavigationSource_ContextualSuggestion() { - PageViewTimer timer = createPageViewTimer(); - doReturn("https://goto.google.com/explore-on-content-viewer") - .when(mNavigationEntry) - .getReferrerUrl(); - doReturn(0).when(mNavigationController).getLastCommittedEntryIndex(); - doReturn(mNavigationEntry).when(mNavigationController).getEntryAtIndex(0); - doReturn(mNavigationController).when(mWebContents).getNavigationController(); - - assertEquals( - timer.getNavigationSource(mWebContents), NavigationSource.CONTEXTUAL_SUGGESTIONS); - } - - @Test - public void calculateDurationBucket_Short() { - PageViewTimer timer = createPageViewTimer(); - assertEquals(timer.calculateDurationBucket(0), DurationBucket.SHORT_CLICK); - assertEquals(timer.calculateDurationBucket(PageViewTimer.SHORT_BUCKET_THRESHOLD_MS), - DurationBucket.SHORT_CLICK); - } - - @Test - public void calculateDurationBucket_Medium() { - PageViewTimer timer = createPageViewTimer(); - assertEquals(timer.calculateDurationBucket(PageViewTimer.SHORT_BUCKET_THRESHOLD_MS + 1), - DurationBucket.MEDIUM_CLICK); - assertEquals(timer.calculateDurationBucket(PageViewTimer.MEDIUM_BUCKET_THRESHOLD_MS), - DurationBucket.MEDIUM_CLICK); - } - - @Test - public void calculateDurationBucket_Long() { - PageViewTimer timer = createPageViewTimer(); - assertEquals(timer.calculateDurationBucket(PageViewTimer.MEDIUM_BUCKET_THRESHOLD_MS + 1), - DurationBucket.LONG_CLICK); - } - - private Runnable doNothingToShowContent() { - return () -> {}; - } - - private Runnable showContentByDidFirstVisuallyNonEmptyPaint(Tab tab) { - return () -> getTabObserver().didFirstVisuallyNonEmptyPaint(tab); - } - private Runnable showContentByOnPageLoadFinished(Tab tab) { - return () -> getTabObserver().onPageLoadFinished(tab, STARTING_URL); - } - - private Runnable showContentByOnLoadStopped(Tab tab) { - return () -> getTabObserver().onLoadStopped(tab, /*toDifferentDocument=*/false); - } - - private Runnable stopTimerByClosingTab(Tab tab) { - return () -> getTabModelObserver().willCloseTab(tab, /*animate=*/false); - } - - private Runnable stopTimerByOnUpdateUrl(Tab tab, String url) { - return () -> getTabObserver().onUpdateUrl(tab, url); - } - - private Runnable stopTimerByRemovingTab(Tab tab) { - return () -> getTabModelObserver().tabRemoved(tab); - } - - private Runnable stopTimerBySwitchingTab(Tab fromTab, Tab toTab) { - return () -> switchTabs(fromTab, toTab); - } - - private Runnable stopTimerByClosingChrome() { - return () -> mTimer.destroy(); - } - - private Runnable pauseTimerByOpeningTabSwitcher() { - return () -> getEmptyOverviewModeObserver().onOverviewModeStartedShowing(false); - } - - private Runnable resumeTimerByClosingTabSwitcher() { - return () -> getEmptyOverviewModeObserver().onOverviewModeFinishedHiding(); - } - - private Runnable pauseTimerByHidingTab(Tab tab) { - return () -> getTabObserver().onHidden(tab, TabHidingType.CHANGED_TABS); - } - - private Runnable resumeTimerByShowingTab(Tab tab) { - return () -> getTabObserver().onShown(tab, TabSelectionType.FROM_USER); - } - - private void selectTab_showContent_pauseTimer_resumeTimer_stopTimer( - Runnable showContentRunnable, Runnable pauseRunnable, Runnable resumeRunnable, - Runnable stopTimerRunnable, int expectedSamples) { - int expectedTime = SAMPLE_PAGE_VIEW_TIME; - mTimer = createPageViewTimer(); - switchTabs(null, mTab); - showContentRunnable.run(); - SystemClock.sleep(SAMPLE_PAGE_VIEW_TIME); - if (pauseRunnable != null && resumeRunnable != null) { - expectedTime += SAMPLE_PAGE_VIEW_TIME; - pauseRunnable.run(); - SystemClock.sleep(SAMPLE_PAGE_VIEW_TIME); - resumeRunnable.run(); - SystemClock.sleep(SAMPLE_PAGE_VIEW_TIME); - } - stopTimerRunnable.run(); - assertEquals(expectedSamples, - ShadowRecordHistogram.getHistogramValueCountForTesting( - PAGE_VIEW_TIME_METRIC, expectedTime)); - } - - private void selectTab_showContent_stopTimer( - Runnable showContentRunnable, Runnable stopTimerRunnable, int expectedSamples) { - selectTab_showContent_pauseTimer_resumeTimer_stopTimer( - showContentRunnable, null, null, stopTimerRunnable, expectedSamples); - } - - public PageViewTimer createPageViewTimer() { - PageViewTimer timer = new PageViewTimer(mTabModelSelector, mLayoutManagerChrome); - verify(mTabModel, times(1)).addObserver(mTabModelObserverCaptor.capture()); - verify(mLayoutManagerChrome, times(1)) - .addOverviewModeObserver(mEmptyOverviewModeObserverCaptor.capture()); - return timer; - } - - private void switchTabs(Tab fromTab, Tab toTab) { - getTabModelObserver().didSelectTab(toTab, TabSelectionType.FROM_USER, 0); - if (fromTab != null) { - verify(fromTab, times(1)).removeObserver(eq(getTabObserver())); - } - if (toTab != null) { - verify(toTab, times(1)).addObserver(mTabObserverCaptor.capture()); - } - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/SuggestionsImageFetcherTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/SuggestionsImageFetcherTest.java index 2fe1d09..ba94c4f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/SuggestionsImageFetcherTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/SuggestionsImageFetcherTest.java
@@ -78,7 +78,7 @@ Callback mockCallback = mock(Callback.class); @KnownCategories - int[] categoriesWithIcon = new int[] {KnownCategories.ARTICLES, KnownCategories.CONTEXTUAL}; + int[] categoriesWithIcon = new int[] {KnownCategories.ARTICLES}; for (@KnownCategories int category : categoriesWithIcon) { SnippetArticle suggestion = createDummySuggestion(category); imageFetcher.makeFaviconRequest(suggestion, mockCallback);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java index a51f37d8..a2dc02e 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java
@@ -99,13 +99,7 @@ } @Test - public void createPageViewTimer_withNoTab_noCrash() { - doReturn(null).when(mTabModelSelector).getCurrentTab(); - PageViewObserver observer = createPageViewObserver(); - } - - @Test - public void updateUrl_currentlyNull_startReported() { + public void onUpdateUrl_currentlyNull_startReported() { PageViewObserver observer = createPageViewObserver(); updateUrl(mTab, STARTING_URL); verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN)));
diff --git a/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java b/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java index a85e58b..7d9beecb 100644 --- a/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java +++ b/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
@@ -27,4 +27,8 @@ ChromeActivity activity, NativePageHost host) { return null; } + + public static Class<?> getNoTouchActivityClass() { + return null; + } }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java index fbeac2ce..3c427ac 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
@@ -27,4 +27,8 @@ ChromeActivity activity, NativePageHost host) { return new TouchlessExploreSitesPage(activity, host); } + + public static Class<?> getNoTouchActivityClass() { + return NoTouchActivity.class; + } }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessSuggestionsBinder.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessSuggestionsBinder.java index 62ca9bc..8a030a7 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessSuggestionsBinder.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessSuggestionsBinder.java
@@ -4,14 +4,11 @@ package org.chromium.chrome.browser.touchless; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; import android.view.View; import android.widget.TextView; import org.chromium.chrome.browser.suggestions.SuggestionsBinder; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.util.ViewUtils; import org.chromium.chrome.touchless.R; /** Overrides SuggestionsBinder methods to provide touchless specific values and functionality. */ @@ -19,7 +16,7 @@ private static final String TOUCHLESS_ARTICLE_AGE_FORMAT_STRING = " %s"; public TouchlessSuggestionsBinder(View cardContainerView, SuggestionsUiDelegate uiDelegate) { - super(cardContainerView, uiDelegate, false); + super(cardContainerView, uiDelegate); } @Override
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java index c4eada2..cb518a3c 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java
@@ -180,7 +180,20 @@ } else if (DialogListItemProperties.TEXT == propertyKey) { textView.setText(model.get(DialogListItemProperties.TEXT)); } else if (DialogListItemProperties.CLICK_LISTENER == propertyKey) { - view.setOnClickListener(model.get(DialogListItemProperties.CLICK_LISTENER)); + if (!(model.get(DialogListItemProperties.CLICK_LISTENER) + instanceof ClickThrottlingListener)) { + ClickThrottlingListener listener = new ClickThrottlingListener( + model.get(DialogListItemProperties.CLICK_LISTENER)); + listener.setIsMultiClickable(model.get(DialogListItemProperties.MULTI_CLICKABLE)); + model.set(DialogListItemProperties.CLICK_LISTENER, listener); + view.setOnClickListener(listener); + } + } else if (DialogListItemProperties.MULTI_CLICKABLE == propertyKey) { + View.OnClickListener listener = model.get(DialogListItemProperties.CLICK_LISTENER); + if (listener instanceof ClickThrottlingListener) { + ((ClickThrottlingListener) listener) + .setIsMultiClickable(model.get(DialogListItemProperties.MULTI_CLICKABLE)); + } } else if (DialogListItemProperties.FOCUS_LISTENER_SET == propertyKey) { if (model.get(DialogListItemProperties.FOCUS_LISTENER_SET)) { view.setOnFocusChangeListener((v, hasFocus) -> { @@ -200,4 +213,32 @@ } } } + + /** + * This OnClickListener implementation ensures that + * {@link DialogListItemProperties.CLICK_LISTENER} is only called once for models with + * {@link DialogListItemProperties.MULTI_CLICKABLE} set to false. + */ + private static class ClickThrottlingListener implements View.OnClickListener { + private View.OnClickListener mOnClickListener; + private boolean mWasClicked; + private boolean mIsMultiClickable; + + private ClickThrottlingListener(View.OnClickListener onClickListener) { + mOnClickListener = onClickListener; + } + + private void setIsMultiClickable(boolean isMultiClickable) { + mIsMultiClickable = isMultiClickable; + } + + @Override + public void onClick(View view) { + if (mOnClickListener == null) return; + if (!mIsMultiClickable && mWasClicked) return; + + mOnClickListener.onClick(view); + mWasClicked = true; + } + } }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java index a4984ed..3514bae 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java
@@ -47,6 +47,10 @@ public static final WritableObjectPropertyKey<String> TEXT = new WritableObjectPropertyKey<>(); + /** Whether this item can be clicked more than one time. */ + public static final WritableBooleanPropertyKey MULTI_CLICKABLE = + new WritableBooleanPropertyKey(); + /** The action to be performed when the item is selected. */ public static final WritableObjectPropertyKey<OnClickListener> CLICK_LISTENER = new WritableObjectPropertyKey<>(); @@ -55,8 +59,8 @@ public static final WritableBooleanPropertyKey FOCUS_LISTENER_SET = new WritableBooleanPropertyKey(); - public static final PropertyKey[] ALL_KEYS = {ICON, TEXT, CLICK_LISTENER, - FOCUS_LISTENER_SET}; + public static final PropertyKey[] ALL_KEYS = { + ICON, TEXT, MULTI_CLICKABLE, CLICK_LISTENER, FOCUS_LISTENER_SET}; } /**
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index e6f97cd0..b0fb860 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -474,10 +474,8 @@ } if (is_android) { - deps += [ - "//chrome/browser/ui/webui/eoc_internals:mojo_bindings", - "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings", - ] + deps += + [ "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings" ] } else { deps += [ "//chrome/browser/ui/webui/app_management:mojo_bindings",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc index 858bdc2..7d510ea 100644 --- a/chrome/app/chrome_content_browser_overlay_manifest.cc +++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -70,7 +70,6 @@ #endif #if defined(OS_ANDROID) -#include "chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom.h" #include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom.h" #else #include "chrome/browser/ui/webui/app_management/app_management.mojom.h" @@ -248,7 +247,6 @@ downloads::mojom::PageHandlerFactory, feed_internals::mojom::PageHandler, #if defined(OS_ANDROID) - eoc_internals::mojom::PageHandler, explore_sites_internals::mojom::PageHandler, #else app_management::mojom::PageHandlerFactory,
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 00c28d8e..b894bd6 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -940,8 +940,6 @@ "notifications/system_notification_helper.h", "ntp_snippets/content_suggestions_service_factory.cc", "ntp_snippets/content_suggestions_service_factory.h", - "ntp_snippets/contextual_content_suggestions_service_factory.cc", - "ntp_snippets/contextual_content_suggestions_service_factory.h", "ntp_snippets/ntp_snippets_metrics.cc", "ntp_snippets/ntp_snippets_metrics.h", "ntp_tiles/chrome_custom_links_manager_factory.cc", @@ -1960,6 +1958,7 @@ "//components/rappor:rappor_recorder", "//components/renderer_context_menu", "//components/resources", + "//components/safe_browsing:public", "//components/safe_search_api", "//components/safe_search_api:safe_search_client", "//components/search", @@ -2230,10 +2229,6 @@ "android/compositor/tab_content_manager.h", "android/consent_auditor/consent_auditor_bridge.cc", "android/content/content_utils.cc", - "android/contextual_suggestions/contextual_suggestions_bridge.cc", - "android/contextual_suggestions/contextual_suggestions_bridge.h", - "android/contextual_suggestions/contextual_suggestions_prefs.cc", - "android/contextual_suggestions/contextual_suggestions_prefs.h", "android/contextualsearch/contextual_search_context.cc", "android/contextualsearch/contextual_search_context.h", "android/contextualsearch/contextual_search_delegate.cc", @@ -5124,7 +5119,6 @@ if (is_android) { deps += [ - "//chrome/browser/ui/webui/eoc_internals:mojo_bindings_js", "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings_js", "//chrome/browser/ui/webui/feed_internals:mojo_bindings_js", "//chrome/browser/ui/webui/snippets_internals:mojo_bindings_js",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 55a4d16..fce01bbb6 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -222,11 +222,6 @@ specific_include_rules = { "ash_service_registry\.cc": [ - # The following are needed for classic mode to create the WindowService. - # Once Ash runs out of process no longer needed. - "+ash/shell.h", - - # Needed for classic mode. "+ash/ash_service.h", ], "platform_util_mac.mm": [
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b5fba2a..68964c9 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -72,7 +72,6 @@ #include "components/nacl/common/nacl_switches.h" #include "components/network_session_configurator/common/network_features.h" #include "components/network_session_configurator/common/network_switches.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/ntp_snippets_constants.h" #include "components/ntp_tiles/constants.h" @@ -1990,20 +1989,6 @@ flag_descriptions::kEnableScrollAnchorSerializationDescription, kOsAll, FEATURE_VALUE_TYPE(features::kScrollAnchorSerialization)}, #if defined(OS_ANDROID) - {"contextual-suggestions-button", - flag_descriptions::kContextualSuggestionsButtonName, - flag_descriptions::kContextualSuggestionsButtonDescription, kOsAndroid, - FEATURE_VALUE_TYPE(contextual_suggestions::kContextualSuggestionsButton)}, - {"contextual-suggestions-iph-reverse-scroll", - flag_descriptions::kContextualSuggestionsIPHReverseScrollName, - flag_descriptions::kContextualSuggestionsIPHReverseScrollDescription, - kOsAndroid, - FEATURE_VALUE_TYPE( - contextual_suggestions::kContextualSuggestionsIPHReverseScroll)}, - {"contextual-suggestions-opt-out", - flag_descriptions::kContextualSuggestionsOptOutName, - flag_descriptions::kContextualSuggestionsOptOutDescription, kOsAndroid, - FEATURE_VALUE_TYPE(contextual_suggestions::kContextualSuggestionsOptOut)}, {"interest-feed-content-suggestions", flag_descriptions::kInterestFeedContentSuggestionsName, flag_descriptions::kInterestFeedContentSuggestionsDescription, kOsAndroid, @@ -3052,6 +3037,10 @@ flag_descriptions::kEnableBlinkGenPropertyTreesDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kBlinkGenPropertyTrees)}, + {"enable-display-locking", flag_descriptions::kEnableDisplayLockingName, + flag_descriptions::kEnableDisplayLockingDescription, kOsAll, + FEATURE_VALUE_TYPE(blink::features::kDisplayLocking)}, + {"enable-layout-ng", flag_descriptions::kEnableLayoutNGName, flag_descriptions::kEnableLayoutNGDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kLayoutNG)},
diff --git a/chrome/browser/accessibility/accessibility_extension_api.cc b/chrome/browser/accessibility/accessibility_extension_api.cc index 9862d5b..b4050e9 100644 --- a/chrome/browser/accessibility/accessibility_extension_api.cc +++ b/chrome/browser/accessibility/accessibility_extension_api.cc
@@ -36,13 +36,13 @@ #include "ui/events/keycodes/keyboard_codes.h" #if defined(OS_CHROMEOS) +#include "ash/public/cpp/window_tree_host_lookup.h" #include "ash/public/interfaces/accessibility_focus_ring_controller.mojom.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/event_rewriter_controller.mojom.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" -#include "services/ws/public/mojom/constants.mojom.h" -#include "services/ws/public/mojom/event_injector.mojom.h" +#include "ui/aura/window_tree_host.h" #include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -286,15 +286,11 @@ static_cast<ui::KeyboardCode>(key_data->key_code), static_cast<ui::DomCode>(0), modifiers); - ws::mojom::EventInjectorPtr event_injector_ptr; - content::ServiceManagerConnection* connection = - content::ServiceManagerConnection::GetForProcess(); - connection->GetConnector()->BindInterface(ws::mojom::kServiceName, - &event_injector_ptr); - event_injector_ptr->InjectEventNoAckNoRewriters( - display::Screen::GetScreen()->GetPrimaryDisplay().id(), - std::move(synthetic_key_event)); - + auto* host = ash::GetWindowTreeHostForDisplay( + display::Screen::GetScreen()->GetPrimaryDisplay().id()); + DCHECK(host); + // This skips rewriters. + host->DeliverEventToSink(synthetic_key_event.get()); return RespondNow(NoArguments()); } @@ -354,13 +350,15 @@ ui::EventTimeForNow(), flags, flags /* changed_button_flags */); - ws::mojom::EventInjectorPtr event_injector_ptr; - content::ServiceManagerConnection* connection = - content::ServiceManagerConnection::GetForProcess(); - connection->GetConnector()->BindInterface(ws::mojom::kServiceName, - &event_injector_ptr); - event_injector_ptr->InjectEventNoAckNoRewriters( - display.id(), std::move(synthetic_mouse_event)); + auto* host = ash::GetWindowTreeHostForDisplay(display.id()); + DCHECK(host); + // Transforming the coordinate to the root will apply the screen scale factor + // to the event's location and also the screen rotation degree. + synthetic_mouse_event->UpdateForRootTransform( + host->GetRootTransform(), + host->GetRootTransformForLocalEventCoordinates()); + // This skips rewriters. + host->DeliverEventToSink(synthetic_mouse_event.get()); return RespondNow(NoArguments()); }
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 6615312..d283da55 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -20,7 +20,6 @@ #include "components/feed/feed_feature_list.h" #include "components/invalidation/impl/invalidation_switches.h" #include "components/language/core/common/language_experiments.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" #include "components/ntp_snippets/features.h" #include "components/ntp_tiles/constants.h" #include "components/offline_pages/core/offline_page_feature.h" @@ -60,9 +59,6 @@ &autofill::features::kAutofillRefreshStyleAndroid, &autofill::features::kAutofillEnableCompanyName, &autofill_assistant::features::kAutofillAssistant, - &contextual_suggestions::kContextualSuggestionsButton, - &contextual_suggestions::kContextualSuggestionsIPHReverseScroll, - &contextual_suggestions::kContextualSuggestionsOptOut, &download::features::kDownloadAutoResumptionNative, &download::features::kUseDownloadOfflineContentProvider, &features::kAllowStartingServiceManagerOnly, @@ -179,6 +175,7 @@ &kTrustedWebActivity, &kTrustedWebActivityPostMessage, &kTrustedWebActivityNotificationDelegationEnrolment, + &kUmaBackgroundSessions, &kUsageStatsFeature, &kVideoPersistence, &kVrBrowsingFeedback, @@ -528,6 +525,10 @@ "TrustedWebActivityNotificationDelegationAutoEnrolment", base::FEATURE_ENABLED_BY_DEFAULT}; +// If enabled, keep logging and reporting UMA while chrome is backgrounded. +const base::Feature kUmaBackgroundSessions{"UMABackgroundSessions", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kUsageStatsFeature{"UsageStats", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 1118d7c..c249a17 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -110,6 +110,7 @@ extern const base::Feature kTrustedWebActivity; extern const base::Feature kTrustedWebActivityPostMessage; extern const base::Feature kTrustedWebActivityNotificationDelegationEnrolment; +extern const base::Feature kUmaBackgroundSessions; extern const base::Feature kUsageStatsFeature; extern const base::Feature kUserMediaScreenCapturing; extern const base::Feature kVideoPersistence;
diff --git a/chrome/browser/android/contextual_suggestions/OWNERS b/chrome/browser/android/contextual_suggestions/OWNERS deleted file mode 100644 index 5c3a603..0000000 --- a/chrome/browser/android/contextual_suggestions/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -fgorski@chromium.org -twellington@chromium.org - -# COMPONENT: UI>Browser>ContentSuggestions>Explore
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc deleted file mode 100644 index 0e61226..0000000 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.cc +++ /dev/null
@@ -1,205 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h" - -#include <string> -#include <utility> - -#include "base/android/callback_android.h" -#include "base/android/jni_string.h" -#include "base/bind.h" -#include "base/callback.h" -#include "chrome/browser/android/chrome_feature_list.h" -#include "chrome/browser/metrics/chrome_metrics_service_accessor.h" -#include "chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.h" -#include "chrome/browser/policy/profile_policy_connector.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_android.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "components/ntp_snippets/category.h" -#include "components/ntp_snippets/content_suggestions_service.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_service.h" -#include "components/policy/policy_constants.h" -#include "components/ukm/content/source_url_recorder.h" -#include "content/public/browser/web_contents.h" -#include "jni/ContextualSuggestionsBridge_jni.h" -#include "ui/gfx/android/java_bitmap.h" -#include "ui/gfx/image/image.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF16ToJavaString; -using base::android::ConvertUTF8ToJavaString; -using base::android::JavaParamRef; -using base::android::ScopedJavaGlobalRef; -using base::android::ScopedJavaLocalRef; - -namespace contextual_suggestions { - -// A whitelisted method to inject synthetic field trials to Chrome Metrics. -void RegisterSyntheticFieldTrials(const ContextualSuggestionsResult& result) { - for (const auto& experiment_info : result.experiment_infos) { - ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial( - experiment_info.name, experiment_info.group); - } -} - -static jlong JNI_ContextualSuggestionsBridge_Init( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jobject>& j_profile) { - Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); - ContextualContentSuggestionsService* contextual_suggestions_service = - ContextualContentSuggestionsServiceFactory::GetForProfile(profile); - - std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy = - contextual_suggestions_service->CreateProxy(); - - ContextualSuggestionsBridge* contextual_suggestions_bridge = - new ContextualSuggestionsBridge(env, std::move(service_proxy)); - return reinterpret_cast<intptr_t>(contextual_suggestions_bridge); -} - -static jboolean JNI_ContextualSuggestionsBridge_IsDisabledByEnterprisePolicy( - JNIEnv* env) { - Profile* profile = ProfileManager::GetLastUsedProfile()->GetOriginalProfile(); - if (!profile) - return false; - - if (profile->IsSupervised()) - return true; - - policy::ProfilePolicyConnector* policy_connector = - profile->GetProfilePolicyConnector(); - - const policy::PolicyMap& policies = - policy_connector->policy_service()->GetPolicies( - policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())); - const policy::PolicyMap::Entry* entry = - policies.Get(policy::key::kContextualSuggestionsEnabled); - bool is_enabled; - if (entry && entry->value && entry->value->GetAsBoolean(&is_enabled)) - return !is_enabled; - - return false; -} - -ContextualSuggestionsBridge::ContextualSuggestionsBridge( - JNIEnv* env, - std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy) - : service_proxy_(std::move(service_proxy)), weak_ptr_factory_(this) {} - -ContextualSuggestionsBridge::~ContextualSuggestionsBridge() {} - -void ContextualSuggestionsBridge::Destroy(JNIEnv* env, - const JavaParamRef<jobject>& obj) { - service_proxy_->FlushMetrics(); - delete this; -} - -void ContextualSuggestionsBridge::FetchSuggestions( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jstring>& j_url, - const JavaParamRef<jobject>& j_callback) { - GURL url(ConvertJavaStringToUTF8(env, j_url)); - service_proxy_->FetchContextualSuggestions( - url, base::BindOnce(&ContextualSuggestionsBridge::OnSuggestionsAvailable, - weak_ptr_factory_.GetWeakPtr(), - ScopedJavaGlobalRef<jobject>(j_callback))); -} - -base::android::ScopedJavaLocalRef<jstring> -ContextualSuggestionsBridge::GetImageUrl( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jstring>& j_suggestion_id) { - std::string suggestion_id(ConvertJavaStringToUTF8(env, j_suggestion_id)); - std::string image_url = - service_proxy_->GetContextualSuggestionImageUrl(suggestion_id); - return image_url.empty() ? nullptr : ConvertUTF8ToJavaString(env, image_url); -} - -base::android::ScopedJavaLocalRef<jstring> -ContextualSuggestionsBridge::GetFaviconUrl( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jstring>& j_suggestion_id) { - std::string suggestion_id(ConvertJavaStringToUTF8(env, j_suggestion_id)); - std::string favicon_url = - service_proxy_->GetContextualSuggestionFaviconUrl(suggestion_id); - return favicon_url.empty() ? nullptr - : ConvertUTF8ToJavaString(env, favicon_url); -} - -void ContextualSuggestionsBridge::ClearState(JNIEnv* env, - const JavaParamRef<jobject>& obj) { - service_proxy_->ClearState(); -} - -void ContextualSuggestionsBridge::ReportEvent( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jobject>& j_web_contents, - jint j_event_id) { - content::WebContents* web_contents = - content::WebContents::FromJavaWebContents(j_web_contents); - - ukm::SourceId ukm_source_id = - ukm::GetSourceIdForWebContentsDocument(web_contents); - - contextual_suggestions::ContextualSuggestionsEvent event = - static_cast<contextual_suggestions::ContextualSuggestionsEvent>( - j_event_id); - - service_proxy_->ReportEvent( - ukm_source_id, web_contents->GetLastCommittedURL().spec(), event); -} - -void ContextualSuggestionsBridge::OnSuggestionsAvailable( - ScopedJavaGlobalRef<jobject> j_callback, - ContextualSuggestionsResult result) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> j_result = - Java_ContextualSuggestionsBridge_createContextualSuggestionsResult( - env, ConvertUTF8ToJavaString(env, result.peek_text)); - Java_ContextualSuggestionsBridge_setPeekConditionsOnResult( - env, j_result, result.peek_conditions.confidence, - result.peek_conditions.page_scroll_percentage, - result.peek_conditions.minimum_seconds_on_page, - result.peek_conditions.maximum_number_of_peeks); - for (auto& cluster : result.clusters) { - Java_ContextualSuggestionsBridge_addNewClusterToResult( - env, j_result, ConvertUTF8ToJavaString(env, cluster.title)); - for (auto& suggestion : cluster.suggestions) { - Java_ContextualSuggestionsBridge_addSuggestionToLastCluster( - env, j_result, ConvertUTF8ToJavaString(env, suggestion.id), - ConvertUTF8ToJavaString(env, suggestion.title), - ConvertUTF8ToJavaString(env, suggestion.snippet), - ConvertUTF8ToJavaString(env, suggestion.publisher_name), - ConvertUTF8ToJavaString(env, suggestion.url.spec()), - !suggestion.image_id.empty()); - } - } - - RegisterSyntheticFieldTrials(result); - - RunObjectCallbackAndroid(j_callback, j_result); -} - -void ContextualSuggestionsBridge::OnImageFetched( - ScopedJavaGlobalRef<jobject> j_callback, - const gfx::Image& image) { - ScopedJavaLocalRef<jobject> j_bitmap; - if (!image.IsEmpty()) - j_bitmap = gfx::ConvertToJavaBitmap(image.ToSkBitmap()); - - RunObjectCallbackAndroid(j_callback, j_bitmap); -} - -} // namespace contextual_suggestions
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h b/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h deleted file mode 100644 index a9ce466..0000000 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_bridge.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_BRIDGE_H_ -#define CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_BRIDGE_H_ - -#include <memory> - -#include "base/android/scoped_java_ref.h" -#include "base/memory/weak_ptr.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" - -namespace gfx { -class Image; -} // namespace gfx - -namespace contextual_suggestions { - -class ContextualContentSuggestionsServiceProxy; - -// Class implementing native side of ContextualSuggestionsBrigde.java. -class ContextualSuggestionsBridge { - public: - ContextualSuggestionsBridge( - JNIEnv* env, - std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy); - - // Deletes the bridge. - void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - - // Fetches suggestions for a gives |j_url| and passes results to Java side - // using |j_callback|. - void FetchSuggestions(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_url, - const base::android::JavaParamRef<jobject>& j_callback); - - // Fetches an image corresponding to suggestion with |j_suggestion_id| and - // passes results to Java side using |j_callback|. - void FetchSuggestionImage( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_suggestion_id, - const base::android::JavaParamRef<jobject>& j_callback); - - // Gets the image URL for the given |suggestion_id|. - base::android::ScopedJavaLocalRef<jstring> GetImageUrl( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_suggestion_id); - - // Gets the favicon URL for the given |suggestion_id|. - base::android::ScopedJavaLocalRef<jstring> GetFaviconUrl( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_suggestion_id); - - // Requests the backend to clear state related to this bridge. - void ClearState(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - - // Reports an event happening in UI (for the purpose of metrics collection). - void ReportEvent(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jobject>& j_web_contents, - jint j_event_id); - - private: - ~ContextualSuggestionsBridge(); - - void OnSuggestionsAvailable( - base::android::ScopedJavaGlobalRef<jobject> j_callback, - ContextualSuggestionsResult result); - - void OnImageFetched(base::android::ScopedJavaGlobalRef<jobject> j_callback, - const gfx::Image& image); - - // Proxy to contextual content suggestions service used for fetching - // suggestions and images. - std::unique_ptr<ContextualContentSuggestionsServiceProxy> service_proxy_; - - base::WeakPtrFactory<ContextualSuggestionsBridge> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsBridge); -}; - -} // namespace contextual_suggestions - -#endif // CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_BRIDGE_H_
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.cc b/chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.cc deleted file mode 100644 index cb61f65..0000000 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h" - -#include "components/prefs/pref_registry_simple.h" - -namespace contextual_suggestions { - -namespace prefs { - -const char kContextualSuggestionsEnabled[] = "contextual_suggestions.enabled"; - -} // namespace prefs - -// static -void ContextualSuggestionsPrefs::RegisterProfilePrefs( - PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kContextualSuggestionsEnabled, true); -} - -} // namespace contextual_suggestions
diff --git a/chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h b/chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h deleted file mode 100644 index 16d1ed06..0000000 --- a/chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_PREFS_H_ -#define CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_PREFS_H_ - -class PrefRegistrySimple; - -namespace contextual_suggestions { - -namespace prefs { - -// True if contextual suggestions is enabled. -extern const char kContextualSuggestionsEnabled[]; - -} // namespace prefs - -class ContextualSuggestionsPrefs { - public: - static void RegisterProfilePrefs(PrefRegistrySimple* registry); -}; - -} // namespace contextual_suggestions - -#endif // CHROME_BROWSER_ANDROID_CONTEXTUAL_SUGGESTIONS_CONTEXTUAL_SUGGESTIONS_PREFS_H_
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc index 8869765..5826d97 100644 --- a/chrome/browser/android/metrics/uma_session_stats.cc +++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -12,6 +12,8 @@ #include "base/metrics/user_metrics.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" +#include "build/build_config.h" +#include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/android/metrics/android_profile_session_durations_service.h" #include "chrome/browser/android/metrics/android_profile_session_durations_service_factory.h" #include "chrome/browser/browser_process.h" @@ -90,8 +92,11 @@ DCHECK(g_browser_process); // Tell the metrics services they were cleanly shutdown. metrics::MetricsService* metrics = g_browser_process->metrics_service(); - if (metrics) - metrics->OnAppEnterBackground(); + if (metrics) { + const bool keep_reporting = + base::FeatureList::IsEnabled(chrome::android::kUmaBackgroundSessions); + metrics->OnAppEnterBackground(keep_reporting); + } ukm::UkmService* ukm_service = g_browser_process->GetMetricsServicesManager()->GetUkmService(); if (ukm_service)
diff --git a/chrome/browser/android/preferences/prefs.h b/chrome/browser/android/preferences/prefs.h index 55d7149..5c58b0f4 100644 --- a/chrome/browser/android/preferences/prefs.h +++ b/chrome/browser/android/preferences/prefs.h
@@ -8,7 +8,6 @@ #include <cstddef> #include "build/build_config.h" -#include "chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h" #include "chrome/common/pref_names.h" #include "components/autofill/core/common/autofill_prefs.h" #include "components/dom_distiller/core/pref_names.h" @@ -25,7 +24,6 @@ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.preferences enum Pref { ALLOW_DELETING_BROWSER_HISTORY, - CONTEXTUAL_SUGGESTIONS_ENABLED, INCOGNITO_MODE_AVAILABILITY, NTP_ARTICLES_SECTION_ENABLED, NTP_ARTICLES_LIST_VISIBLE, @@ -47,7 +45,6 @@ // Remember to update prefs_unittest.cc as well. const char* const kPrefsExposedToJava[] = { prefs::kAllowDeletingBrowserHistory, - contextual_suggestions::prefs::kContextualSuggestionsEnabled, prefs::kIncognitoModeAvailability, #if BUILDFLAG(ENABLE_FEED_IN_CHROME)
diff --git a/chrome/browser/android/preferences/prefs_unittest.cc b/chrome/browser/android/preferences/prefs_unittest.cc index 870724be..c590bf2 100644 --- a/chrome/browser/android/preferences/prefs_unittest.cc +++ b/chrome/browser/android/preferences/prefs_unittest.cc
@@ -30,8 +30,6 @@ EXPECT_EQ(prefs::kAllowDeletingBrowserHistory, GetPrefName(ALLOW_DELETING_BROWSER_HISTORY)); - EXPECT_EQ(contextual_suggestions::prefs::kContextualSuggestionsEnabled, - GetPrefName(CONTEXTUAL_SUGGESTIONS_ENABLED)); EXPECT_EQ(prefs::kIncognitoModeAvailability, GetPrefName(INCOGNITO_MODE_AVAILABILITY));
diff --git a/chrome/browser/android/vr/ui_module_factory.cc b/chrome/browser/android/vr/ui_module_factory.cc index 5dad8ea..025b45d 100644 --- a/chrome/browser/android/vr/ui_module_factory.cc +++ b/chrome/browser/android/vr/ui_module_factory.cc
@@ -8,13 +8,13 @@ #include <utility> +#include "base/android/bundle_utils.h" #include "base/memory/ptr_util.h" -#include "chrome/browser/vr/ui_interface.h" - #include "chrome/browser/vr/audio_delegate.h" #include "chrome/browser/vr/content_input_delegate.h" #include "chrome/browser/vr/keyboard_delegate.h" #include "chrome/browser/vr/text_input_delegate.h" +#include "chrome/browser/vr/ui_interface.h" namespace vr { @@ -32,20 +32,14 @@ std::unique_ptr<AudioDelegate> audio_delegate, const UiInitialState& ui_initial_state) { DCHECK(ui_library_handle_ == nullptr); - - // TODO(http://crbug.com/874584): Programmatically determine the name of the - // library instead of trying both here. - ui_library_handle_ = dlopen("libvr_ui_module_lib.so", RTLD_LOCAL | RTLD_NOW); - if (!ui_library_handle_) { - ui_library_handle_ = - dlopen("libvr_ui_monochrome_module_lib.so", RTLD_LOCAL | RTLD_NOW); - } - CHECK(ui_library_handle_ != nullptr) + ui_library_handle_ = + base::android::BundleUtils::DlOpenModuleLibraryPartition("vr"); + DCHECK(ui_library_handle_ != nullptr) << "Could not open VR UI library:" << dlerror(); CreateUiFunction* create_ui = reinterpret_cast<CreateUiFunction*>( dlsym(ui_library_handle_, "CreateUi")); - CHECK(create_ui != nullptr); + DCHECK(create_ui != nullptr); std::unique_ptr<UiInterface> ui = base::WrapUnique( create_ui(browser, content_input_forwarder, std::move(keyboard_delegate),
diff --git a/chrome/browser/ash_service_registry.cc b/chrome/browser/ash_service_registry.cc index 8faaa127..e19a480 100644 --- a/chrome/browser/ash_service_registry.cc +++ b/chrome/browser/ash_service_registry.cc
@@ -5,86 +5,20 @@ #include "chrome/browser/ash_service_registry.h" #include "ash/ash_service.h" -#include "ash/public/cpp/window_properties.h" #include "ash/public/interfaces/constants.mojom.h" -#include "ash/public/interfaces/window_properties.mojom.h" -#include "base/bind.h" -#include "base/stl_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "build/build_config.h" #include "chrome/browser/chromeos/prefs/pref_connector_service.h" -#include "chrome/grit/generated_resources.h" #include "content/public/common/service_manager_connection.h" -#include "services/ws/public/mojom/constants.mojom.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/ui_base_features.h" - -using content::ContentBrowserClient; namespace ash_service_registry { -namespace { - -struct Service { - const char* name; - int display_name_id; // Resource ID for the display name. -}; - -// Services unique to mash. Note that the non-mash case also has an Ash service, -// it's just handled differently (see HandleServiceRequest()). -constexpr Service kMashServices[] = { - {ash::mojom::kServiceName, IDS_ASH_ASH_SERVICE_NAME}, - {ws::mojom::kServiceName, IDS_ASH_UI_SERVICE_NAME}, -}; - -void RegisterOutOfProcessServicesImpl( - const Service* services, - size_t num_services, - ContentBrowserClient::OutOfProcessServiceMap* services_map) { - for (size_t i = 0; i < num_services; ++i) { - const Service& service = services[i]; - (*services_map)[service.name] = - ContentBrowserClient::OutOfProcessServiceInfo(base::BindRepeating( - &l10n_util::GetStringUTF16, service.display_name_id)); - } -} - -} // namespace - -void RegisterOutOfProcessServices( - ContentBrowserClient::OutOfProcessServiceMap* services) { - if (features::IsMultiProcessMash()) { - RegisterOutOfProcessServicesImpl(kMashServices, base::size(kMashServices), - services); - } -} std::unique_ptr<service_manager::Service> HandleServiceRequest( const std::string& service_name, service_manager::mojom::ServiceRequest request) { - if (!features::IsMultiProcessMash() && - service_name == ash::mojom::kServiceName) { - return std::make_unique<ash::AshService>(std::move(request)); - } if (service_name == ash::mojom::kPrefConnectorServiceName) return std::make_unique<AshPrefConnector>(std::move(request)); - - return nullptr; -} - -bool IsAshRelatedServiceName(const std::string& name) { - for (const Service& service : kMashServices) { - if (name == service.name) - return true; - } - return false; -} - -bool ShouldTerminateOnServiceQuit(const std::string& name) { - // Some services going down are treated as catastrophic failures, usually - // because both the browser and the service cache data about each other's - // state that is not rebuilt when the service restarts. - return name == ws::mojom::kServiceName || name == ash::mojom::kServiceName; + return service_name == ash::mojom::kServiceName + ? std::make_unique<ash::AshService>(std::move(request)) + : nullptr; } } // namespace ash_service_registry
diff --git a/chrome/browser/ash_service_registry.h b/chrome/browser/ash_service_registry.h index 0c94057..58e7e25 100644 --- a/chrome/browser/ash_service_registry.h +++ b/chrome/browser/ash_service_registry.h
@@ -9,27 +9,13 @@ #include "content/public/browser/content_browser_client.h" -namespace service_manager { -class Service; -} - namespace ash_service_registry { -// Registers the set of Ash related services that run out of process. -void RegisterOutOfProcessServices( - content::ContentBrowserClient::OutOfProcessServiceMap* services); - // Handles an incoming ServiceRequest to run a service in the browser process. std::unique_ptr<service_manager::Service> HandleServiceRequest( const std::string& service_name, service_manager::mojom::ServiceRequest request); -// Returns true if |name| identifies an Ash related service. -bool IsAshRelatedServiceName(const std::string& name); - -// Returns true if the browser should exit when service |name| quits. -bool ShouldTerminateOnServiceQuit(const std::string& name); - } // namespace ash_service_registry #endif // CHROME_BROWSER_ASH_SERVICE_REGISTRY_H_
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 5b5cc5b..fcda1981 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -111,6 +111,7 @@ #include "components/previews/core/previews_experiments.h" #include "components/rappor/public/rappor_utils.h" #include "components/rappor/rappor_service_impl.h" +#include "components/safe_browsing/safe_browsing_service_interface.h" #include "components/sessions/core/session_id_generator.h" #include "components/signin/core/browser/account_consistency_method.h" #include "components/subresource_filter/content/browser/ruleset_service.h" @@ -1315,9 +1316,19 @@ // Set this flag to true so that we don't retry indefinitely to // create the service class if there was an error. created_safe_browsing_service_ = true; - safe_browsing_service_ = - safe_browsing::SafeBrowsingService::CreateSafeBrowsingService(); - safe_browsing_service_->Initialize(); + + // The factory can be overridden in tests. + if (!safe_browsing::SafeBrowsingServiceInterface::HasFactory()) { + safe_browsing::SafeBrowsingServiceInterface::RegisterFactory( + safe_browsing::GetSafeBrowsingServiceFactory()); + } + + // TODO(crbug/925153): Port consumers of the |safe_browsing_service_| to use + // the interface in components/safe_browsing, and remove this cast. + safe_browsing_service_ = static_cast<safe_browsing::SafeBrowsingService*>( + safe_browsing::SafeBrowsingServiceInterface::CreateSafeBrowsingService()); + if (safe_browsing_service_) + safe_browsing_service_->Initialize(); } void BrowserProcessImpl::CreateSubresourceFilterRulesetService() {
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_chromeos.cc index b86954c..65334bee 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_chromeos.cc
@@ -11,7 +11,6 @@ #include "base/logging.h" #include "base/time/default_tick_clock.h" #include "base/time/tick_clock.h" -#include "chrome/browser/ash_service_registry.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/chrome_service_name.h" #include "chrome/browser/chromeos/login/session/chrome_session_manager.h"
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index cd555b0..8ca0591 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -78,13 +78,13 @@ <include name="IDR_DISCARDS_WEBUI_GRAPH_DUMP_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\performance_manager\webui_graph_dump.mojom-lite.js" compress="gzip" use_base_dir="false" type="BINDATA" /> </if> <if expr="is_win or is_macosx or (is_linux and not is_chromeos)"> - <include name="IDR_BROWSER_SWITCHER_APP_HTML" file="resources\browser_switcher\app.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_BROWSER_SWITCHER_APP_JS" file="resources\browser_switcher\app.js" compress="gzip" type="BINDATA" /> - <include name="IDR_BROWSER_SWITCHER_BROWSER_SWITCHER_PROXY_HTML" file="resources\browser_switcher\browser_switcher_proxy.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_BROWSER_SWITCHER_BROWSER_SWITCHER_PROXY_JS" file="resources\browser_switcher\browser_switcher_proxy.js" compress="gzip" type="BINDATA" /> - <include name="IDR_BROWSER_SWITCHER_BROWSER_SWITCH_HTML" file="resources\browser_switcher\browser_switcher.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_BROWSER_SWITCHER_INTERNALS_HTML" file="resources\browser_switcher\internals\browser_switcher_internals.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_BROWSER_SWITCHER_INTERNALS_JS" file="resources\browser_switcher\internals\browser_switcher_internals.js" compress="gzip" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_APP_HTML" file="resources\browser_switch\app.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_APP_JS" file="resources\browser_switch\app.js" compress="gzip" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_PROXY_HTML" file="resources\browser_switch\browser_switch_proxy.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_PROXY_JS" file="resources\browser_switch\browser_switch_proxy.js" compress="gzip" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_HTML" file="resources\browser_switch\browser_switch.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_INTERNALS_HTML" file="resources\browser_switch\internals\browser_switch_internals.html" compress="gzip" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_BROWSER_SWITCH_INTERNALS_JS" file="resources\browser_switch\internals\browser_switch_internals.js" compress="gzip" type="BINDATA" /> </if> <if expr="is_win"> <include name="IDR_ABOUT_CONFLICTS_HTML" file="resources\conflicts\about_conflicts.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> @@ -191,10 +191,6 @@ </if> <include name="IDR_FEEDBACK_MANIFEST" file="resources\feedback\manifest.json" type="BINDATA" /> <if expr="is_android"> - <include name="IDR_EOC_INTERNALS_HTML" file="resources\eoc_internals\eoc_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" /> - <include name="IDR_EOC_INTERNALS_CSS" file="resources\eoc_internals\eoc_internals.css" compress="gzip" type="BINDATA" /> - <include name="IDR_EOC_INTERNALS_JS" file="resources\eoc_internals\eoc_internals.js" compress="gzip" type="BINDATA" /> - <include name="IDR_EOC_INTERNALS_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\ui\webui\eoc_internals\eoc_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" compress="gzip" /> <include name="IDR_EXPLORE_SITES_INTERNALS_HTML" file="resources\explore_sites_internals\explore_sites_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" /> <include name="IDR_EXPLORE_SITES_INTERNALS_CSS" file="resources\explore_sites_internals\explore_sites_internals.css" compress="gzip" type="BINDATA" /> <include name="IDR_EXPLORE_SITES_INTERNALS_JS" file="resources\explore_sites_internals\explore_sites_internals.js" compress="gzip" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 1bea7ae2..23e9af6 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -319,8 +319,11 @@ {content::BrowserThread::IO})); browser_process_->SetSystemRequestContext( system_request_context_getter_.get()); + // TODO(crbug/925153): Port consumers of the |sb_service| to use the + // interface in components/safe_browsing, and remove this cast. scoped_refptr<safe_browsing::SafeBrowsingService> sb_service = - safe_browsing::SafeBrowsingService::CreateSafeBrowsingService(); + static_cast<safe_browsing::SafeBrowsingService*>( + safe_browsing::SafeBrowsingService::CreateSafeBrowsingService()); browser_process_->SetSafeBrowsingService(sb_service.get()); sb_service->Initialize(); base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 22172ab..d630c0e 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -196,6 +196,7 @@ #include "ui/base/resource/resource_bundle.h" #if defined(OS_ANDROID) +#include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/metrics/thread_watcher_android.h" #include "ui/base/resource/resource_bundle_android.h" #else @@ -1300,6 +1301,12 @@ #if !defined(OS_ANDROID) // Now that the file thread has been started, start recording. StartMetricsRecording(); +#else + // When kUmaBackgroundSessions is enabled, start metrics recording for every + // Chrome start. Otherwise, recording is only started when Chrome becomes + // foregrounded. + if (base::FeatureList::IsEnabled(chrome::android::kUmaBackgroundSessions)) + StartMetricsRecording(); #endif // !defined(OS_ANDROID) if (!base::debug::BeingDebugged()) {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c5b8794..804e81f 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2320,32 +2320,13 @@ const service_manager::Identity& identity, base::CommandLine* command_line) { #if defined(OS_CHROMEOS) - bool copy_switches = false; - if (identity.name() == ash::mojom::kServiceName) { - copy_switches = true; - command_line->AppendSwitch(switches::kMessageLoopTypeUi); - } - if (ash_service_registry::IsAshRelatedServiceName(identity.name())) { - // Ash services also need command line flags, as some flags are used to - // configure the compositor. - copy_switches = true; - command_line->AppendSwitchASCII(switches::kMashServiceName, - identity.name()); - } if (identity.name() == viz::mojom::kVizServiceName) { -#if defined(USE_OZONE) if (ui::OzonePlatform::EnsureInstance()->GetMessageLoopTypeForGpu() == base::MessageLoop::TYPE_UI) { command_line->AppendSwitch(switches::kMessageLoopTypeUi); } -#endif content::GpuDataManager::GetInstance()->AppendGpuCommandLine(command_line); } - // TODO(crbug.com/906954): whitelist flags to copy. - if (copy_switches) { - for (const auto& sw : base::CommandLine::ForCurrentProcess()->GetSwitches()) - command_line->AppendSwitchNative(sw.first, sw.second); - } #endif #if defined(OS_MACOSX) @@ -4039,8 +4020,6 @@ &l10n_util::GetStringUTF16, IDS_UTILITY_PROCESS_UNZIP_NAME); #if defined(OS_CHROMEOS) - ash_service_registry::RegisterOutOfProcessServices(services); - (*services)[chromeos::ime::mojom::kServiceName] = base::BindRepeating( &l10n_util::GetStringUTF16, IDS_UTILITY_PROCESS_IME_SERVICE_NAME); #endif @@ -4129,14 +4108,6 @@ #endif } -bool ChromeContentBrowserClient::ShouldTerminateOnServiceQuit( - const service_manager::Identity& id) { -#if defined(OS_CHROMEOS) - return ash_service_registry::ShouldTerminateOnServiceQuit(id.name()); -#endif - return false; -} - base::Optional<service_manager::Manifest> ChromeContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) { if (name == content::mojom::kBrowserServiceName)
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 77163e4..3419194 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -423,8 +423,6 @@ void HandleServiceRequest( const std::string& service_name, service_manager::mojom::ServiceRequest request) override; - bool ShouldTerminateOnServiceQuit( - const service_manager::Identity& id) override; base::Optional<service_manager::Manifest> GetServiceManifestOverlay( base::StringPiece name) override; std::vector<service_manager::Manifest> GetExtraServiceManifests() override;
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index f1f986b3..33a0b422 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -52,12 +52,6 @@ #include "chrome/test/base/search_test_utils.h" #endif -#if defined(OS_CHROMEOS) -#include "ash/public/interfaces/constants.mojom.h" -#include "content/public/common/service_names.mojom.h" -#include "services/ws/public/mojom/constants.mojom.h" -#endif - using content::BrowsingDataFilterBuilder; using testing::_; using ChromeContentBrowserClientTest = testing::Test; @@ -504,32 +498,3 @@ EXPECT_EQ(metadata.architecture, ""); EXPECT_EQ(metadata.model, ""); } - -#if defined(OS_CHROMEOS) - -TEST(ChromeContentBrowserClientTest, ShouldTerminateOnServiceQuit) { - const struct { - std::string service_name; - bool expect_terminate; - } kTestCases[] = { - // Don't terminate for invalid service names. - {"x", false}, - {"unknown-name", false}, - // Don't terminate for some well-known browser services. - {content::mojom::kBrowserServiceName, false}, - {content::mojom::kGpuServiceName, false}, - {content::mojom::kRendererServiceName, false}, - // Do terminate for some mash-specific cases. - {ws::mojom::kServiceName, true}, - {ash::mojom::kServiceName, true}, - }; - ChromeContentBrowserClient client; - for (const auto& test : kTestCases) { - service_manager::Identity id(test.service_name, base::Token{1, 2}, - base::Token{}, base::Token{3, 4}); - EXPECT_EQ(test.expect_terminate, client.ShouldTerminateOnServiceQuit(id)) - << "for service name " << test.service_name; - } -} - -#endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 5dcc9fb..9b46a352 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1828,6 +1828,7 @@ "printing/printer_event_tracker_factory.cc", "printing/printer_event_tracker_factory.h", "printing/printer_info.h", + "printing/printer_installation_manager.h", "printing/printer_metrics_provider.cc", "printing/printer_metrics_provider.h", "printing/printers_map.cc",
diff --git a/chrome/browser/chromeos/printing/cups_printers_manager.h b/chrome/browser/chromeos/printing/cups_printers_manager.h index 16a6cb0..c549f55 100644 --- a/chrome/browser/chromeos/printing/cups_printers_manager.h +++ b/chrome/browser/chromeos/printing/cups_printers_manager.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "chrome/browser/chromeos/printing/printer_event_tracker.h" +#include "chrome/browser/chromeos/printing/printer_installation_manager.h" #include "chromeos/printing/printer_configuration.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_service.h" @@ -29,7 +30,8 @@ // Top level manager of available CUPS printers in ChromeOS. All functions // in this class must be called from a sequenced context. -class CupsPrintersManager : public KeyedService { +class CupsPrintersManager : public PrinterInstallationManager, + public KeyedService { public: class Observer { public: @@ -85,11 +87,11 @@ // Parameter |is_automatic| should be set to true if the printer was // saved automatically (without requesting additional information // from the user). - virtual void PrinterInstalled(const Printer& printer, bool is_automatic) = 0; + void PrinterInstalled(const Printer& printer, bool is_automatic) override = 0; // Returns true if |printer| is currently installed in CUPS with this // configuration. - virtual bool IsPrinterInstalled(const Printer& printer) const = 0; + bool IsPrinterInstalled(const Printer& printer) const override = 0; // Look for a printer with the given id in any class. Returns a copy of the // printer if found, base::nullopt if not found.
diff --git a/chrome/browser/chromeos/printing/cups_printers_manager_factory.cc b/chrome/browser/chromeos/printing/cups_printers_manager_factory.cc index 9e7066fe..176a353 100644 --- a/chrome/browser/chromeos/printing/cups_printers_manager_factory.cc +++ b/chrome/browser/chromeos/printing/cups_printers_manager_factory.cc
@@ -4,23 +4,19 @@ #include "chrome/browser/chromeos/printing/cups_printers_manager_factory.h" +#include "base/memory/singleton.h" #include "chrome/browser/chromeos/printing/cups_printers_manager.h" #include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" namespace chromeos { -namespace { - -static base::LazyInstance<CupsPrintersManagerFactory>::Leaky::DestructorAtExit - g_cups_printers_manager_factory = LAZY_INSTANCE_INITIALIZER; - -} // namespace // static CupsPrintersManagerFactory* CupsPrintersManagerFactory::GetInstance() { - return g_cups_printers_manager_factory.Pointer(); + return base::Singleton<CupsPrintersManagerFactory>::get(); } // static @@ -30,11 +26,6 @@ GetInstance()->GetServiceForBrowserContext(context, true)); } -content::BrowserContext* CupsPrintersManagerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return chrome::GetBrowserContextRedirectedInIncognito(context); -} - CupsPrintersManagerFactory::CupsPrintersManagerFactory() : BrowserContextKeyedServiceFactory( "CupsPrintersManagerFactory", @@ -46,8 +37,27 @@ KeyedService* CupsPrintersManagerFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { + // We do not need an instance of CupsPrintersManager on the lockscreen. + if (ProfileHelper::IsLockScreenAppProfile( + Profile::FromBrowserContext(context)) || + ProfileHelper::IsSigninProfile(Profile::FromBrowserContext(context))) { + return nullptr; + } return CupsPrintersManager::Create(Profile::FromBrowserContext(context)) .release(); } +content::BrowserContext* CupsPrintersManagerFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextRedirectedInIncognito(context); +} + +bool CupsPrintersManagerFactory::ServiceIsCreatedWithBrowserContext() const { + return true; +} + +bool CupsPrintersManagerFactory::ServiceIsNULLWhileTesting() const { + return true; +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/cups_printers_manager_factory.h b/chrome/browser/chromeos/printing/cups_printers_manager_factory.h index 1e11042..ae5ae98 100644 --- a/chrome/browser/chromeos/printing/cups_printers_manager_factory.h +++ b/chrome/browser/chromeos/printing/cups_printers_manager_factory.h
@@ -5,13 +5,17 @@ #ifndef CHROME_BROWSER_CHROMEOS_PRINTING_CUPS_PRINTERS_MANAGER_FACTORY_H_ #define CHROME_BROWSER_CHROMEOS_PRINTING_CUPS_PRINTERS_MANAGER_FACTORY_H_ -#include "base/lazy_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" namespace content { class BrowserContext; } +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} + namespace chromeos { class CupsPrintersManager; @@ -22,18 +26,19 @@ static CupsPrintersManager* GetForBrowserContext( content::BrowserContext* context); - protected: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - private: - friend struct base::LazyInstanceTraitsBase<CupsPrintersManagerFactory>; + friend struct base::DefaultSingletonTraits<CupsPrintersManagerFactory>; CupsPrintersManagerFactory(); ~CupsPrintersManagerFactory() override; + // BrowserContextKeyedServiceFactory overrides: KeyedService* BuildServiceInstanceFor( content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; + bool ServiceIsNULLWhileTesting() const override; DISALLOW_COPY_AND_ASSIGN(CupsPrintersManagerFactory); };
diff --git a/chrome/browser/chromeos/printing/printer_installation_manager.h b/chrome/browser/chromeos/printing/printer_installation_manager.h new file mode 100644 index 0000000..c91d6575 --- /dev/null +++ b/chrome/browser/chromeos/printing/printer_installation_manager.h
@@ -0,0 +1,31 @@ +// 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_CHROMEOS_PRINTING_PRINTER_INSTALLATION_MANAGER_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTER_INSTALLATION_MANAGER_H_ + +namespace chromeos { + +class Printer; + +// Interface that exposes methods for tracking the installation of a printer. +class PrinterInstallationManager { + public: + virtual ~PrinterInstallationManager() = default; + + // Record that the given printers has been installed in CUPS for usage. If + // |printer| is not a saved or enterprise printer, this will have the + // side effect of moving |printer| into the saved class. + // Parameter |is_automatic| should be set to true if the printer was + // saved automatically (without requesting additional information + // from the user). + virtual void PrinterInstalled(const Printer& printer, bool is_automatic) = 0; + + // Returns true if |printer| is currently installed in CUPS with this + // configuration. + virtual bool IsPrinterInstalled(const Printer& printer) const = 0; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_PRINTER_INSTALLATION_MANAGER_H_
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index e10c172..bf07ce2 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -91,6 +91,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/proto/csd.pb.h" +#include "components/safe_browsing/safe_browsing_service_interface.h" #include "components/security_state/core/security_state.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -1166,7 +1167,8 @@ TestSafeBrowsingServiceFactory() : fake_safe_browsing_service_(nullptr) {} ~TestSafeBrowsingServiceFactory() override {} - safe_browsing::SafeBrowsingService* CreateSafeBrowsingService() override { + safe_browsing::SafeBrowsingServiceInterface* CreateSafeBrowsingService() + override { DCHECK(!fake_safe_browsing_service_); fake_safe_browsing_service_ = new FakeSafeBrowsingService(); return fake_safe_browsing_service_.get(); @@ -1186,13 +1188,13 @@ : test_safe_browsing_factory_(new TestSafeBrowsingServiceFactory()) {} void SetUp() override { - safe_browsing::SafeBrowsingService::RegisterFactory( + safe_browsing::SafeBrowsingServiceInterface::RegisterFactory( test_safe_browsing_factory_.get()); DownloadTest::SetUp(); } void TearDown() override { - safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); + safe_browsing::SafeBrowsingServiceInterface::RegisterFactory(nullptr); DownloadTest::TearDown(); }
diff --git a/chrome/browser/download/download_manager_utils.cc b/chrome/browser/download/download_manager_utils.cc index 7f696829..8164615 100644 --- a/chrome/browser/download/download_manager_utils.cc +++ b/chrome/browser/download/download_manager_utils.cc
@@ -6,8 +6,11 @@ #include "base/bind.h" #include "build/build_config.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/transition_manager/full_browser_transition_manager.h" #include "components/download/public/common/in_progress_download_manager.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/download_request_utils.h" #if defined(OS_ANDROID) @@ -20,6 +23,16 @@ bool IgnoreOriginSecurityCheck(const GURL& url) { return true; } + +// Some ChromeOS browser tests doesn't initialize DownloadManager when profile +// is created, and cause the download request to fail. This method helps us +// ensure that the DownloadManager will be created after profile creation. +void GetDownloadManagerOnProfileCreation(Profile* profile) { + content::DownloadManager* manager = + content::BrowserContext::GetDownloadManager(profile); + DCHECK(manager); +} + } // namespace download::InProgressDownloadManager* @@ -39,3 +52,15 @@ base::BindRepeating(&IgnoreOriginSecurityCheck), base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe)); } + +void DownloadManagerUtils::InitializeSimpleDownloadManager( + SimpleFactoryKey* key) { +#if defined(OS_ANDROID) + if (!g_browser_process) { + DownloadManagerService::GetInstance()->CreateInProgressDownloadManager(); + return; + } +#endif + FullBrowserTransitionManager::Get()->RegisterCallbackOnProfileCreation( + key, base::BindOnce(&GetDownloadManagerOnProfileCreation)); +}
diff --git a/chrome/browser/download/download_manager_utils.h b/chrome/browser/download/download_manager_utils.h index 460b66a..68623c7c 100644 --- a/chrome/browser/download/download_manager_utils.h +++ b/chrome/browser/download/download_manager_utils.h
@@ -8,6 +8,7 @@ #include "base/macros.h" class Profile; +class SimpleFactoryKey; namespace download { class InProgressDownloadManager; @@ -18,6 +19,11 @@ // Creates an InProgressDownloadManager from a profile. static download::InProgressDownloadManager* RetrieveInProgressDownloadManager( Profile* profile); + + // Initializes the SimpleDownloadManager that is associated with |key| whenver + // possible. + static void InitializeSimpleDownloadManager(SimpleFactoryKey* key); + private: DISALLOW_COPY_AND_ASSIGN(DownloadManagerUtils); };
diff --git a/chrome/browser/download/download_service_factory.cc b/chrome/browser/download/download_service_factory.cc index d0e92416..75be1500 100644 --- a/chrome/browser/download/download_service_factory.cc +++ b/chrome/browser/download/download_service_factory.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/background_fetch/background_fetch_download_client.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h" #include "chrome/browser/download/deferred_client_wrapper.h" +#include "chrome/browser/download/download_manager_utils.h" #include "chrome/browser/download/download_task_scheduler_impl.h" #include "chrome/browser/download/simple_download_manager_coordinator_factory.h" #include "chrome/browser/net/system_network_context_manager.h" @@ -60,9 +61,6 @@ #if defined(CHROMEOS) std::unique_ptr<download::Client> CreatePluginVmImageDownloadClient( Profile* profile) { - content::DownloadManager* manager = - content::BrowserContext::GetDownloadManager(profile); - DCHECK(manager); return std::make_unique<plugin_vm::PluginVmImageDownloadClient>(profile); } #endif @@ -191,6 +189,12 @@ #else task_scheduler = std::make_unique<DownloadTaskSchedulerImpl>(context); #endif + // Some tests doesn't initialize DownloadManager when profile is created, + // and cause the download service to fail. Call + // InitializeSimpleDownloadManager() to initialize the DownloadManager + // whenever profile becomes available. + DownloadManagerUtils::InitializeSimpleDownloadManager( + profile->GetProfileKey()); return download::BuildDownloadService( profile->GetProfileKey(), profile->GetPrefs(), std::move(clients), content::GetNetworkConnectionTracker(),
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 101825e..322f00f 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -977,6 +977,7 @@ configs += [ "//build/config/linux/dbus" ] } deps += [ + "//ash", "//ash/public/cpp", "//chrome/browser/resources/chromeos/camera:chrome_camera_app", "//chromeos",
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc index 31f807a..bb187fb 100644 --- a/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -777,7 +777,7 @@ return ext; } - const std::string& GetPrimaryAccountId() { + std::string GetPrimaryAccountId() { return identity_test_env()->identity_manager()->GetPrimaryAccountId(); }
diff --git a/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chrome/browser/extensions/api/management/management_api_browsertest.cc index c06d409..16f29ac9 100644 --- a/chrome/browser/extensions/api/management/management_api_browsertest.cc +++ b/chrome/browser/extensions/api/management/management_api_browsertest.cc
@@ -36,7 +36,7 @@ #endif namespace keys = extension_management_api_constants; -namespace util = extension_function_test_utils; +namespace test_utils = extension_function_test_utils; namespace extensions { @@ -179,19 +179,17 @@ new ManagementCreateAppShortcutFunction()); create_shortcut_function->set_user_gesture(true); ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true); - util::RunFunctionAndReturnSingleResult( + test_utils::RunFunctionAndReturnSingleResult( create_shortcut_function.get(), - base::StringPrintf("[\"%s\"]", app_id.c_str()), - browser()); + base::StringPrintf("[\"%s\"]", app_id.c_str()), browser()); create_shortcut_function = new ManagementCreateAppShortcutFunction(); create_shortcut_function->set_user_gesture(true); ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(false); EXPECT_TRUE(base::MatchPattern( - util::RunFunctionAndReturnError( + test_utils::RunFunctionAndReturnError( create_shortcut_function.get(), - base::StringPrintf("[\"%s\"]", app_id.c_str()), - browser()), + base::StringPrintf("[\"%s\"]", app_id.c_str()), browser()), keys::kCreateShortcutCanceledError)); } @@ -209,7 +207,8 @@ scoped_refptr<ManagementGetAllFunction> function = new ManagementGetAllFunction(); std::unique_ptr<base::Value> result( - util::RunFunctionAndReturnSingleResult(function.get(), "[]", browser())); + test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]", + browser())); base::ListValue* list; ASSERT_TRUE(result->GetAsList(&list)); EXPECT_EQ(1U, list->GetSize()); @@ -218,8 +217,8 @@ ASSERT_TRUE(CrashEnabledExtension(extension->id())); function = new ManagementGetAllFunction(); - result.reset(util::RunFunctionAndReturnSingleResult( - function.get(), "[]", browser())); + result.reset(test_utils::RunFunctionAndReturnSingleResult(function.get(), + "[]", browser())); ASSERT_TRUE(result->GetAsList(&list)); EXPECT_EQ(1U, list->GetSize()); } @@ -271,7 +270,7 @@ function->set_user_gesture(true); function->SetRenderFrameHost(browser()->tab_strip_model()-> GetActiveWebContents()->GetMainFrame()); - bool response = util::RunFunction( + bool response = test_utils::RunFunction( function.get(), base::StringPrintf("[\"%s\", %s]", kId, enabled_string), browser(), api_test_utils::NONE); if (expected_error.empty()) { @@ -294,8 +293,9 @@ DisabledReason) { scoped_refptr<ManagementGetFunction> function = new ManagementGetFunction(); - std::unique_ptr<base::Value> result(util::RunFunctionAndReturnSingleResult( - function.get(), base::StringPrintf("[\"%s\"]", kId), browser())); + std::unique_ptr<base::Value> result( + test_utils::RunFunctionAndReturnSingleResult( + function.get(), base::StringPrintf("[\"%s\"]", kId), browser())); ASSERT_TRUE(result.get() != NULL); ASSERT_TRUE(result->is_dict()); base::DictionaryValue* dict =
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index d46189d..29cdc5a 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
@@ -41,8 +41,6 @@ using base::Value; namespace extensions { -namespace util = settings_test_util; - namespace { // To save typing ValueStore::DEFAULTS everywhere. @@ -213,8 +211,8 @@ ValueStore* AddExtensionAndGetStorage( const std::string& id, Manifest::Type type) { scoped_refptr<const Extension> extension = - util::AddExtensionWithId(profile_.get(), id, type); - return util::GetStorage(extension, frontend_.get()); + settings_test_util::AddExtensionWithId(profile_.get(), id, type); + return settings_test_util::GetStorage(extension, frontend_.get()); } // Gets the syncer::SyncableService for the given sync type. @@ -1425,7 +1423,7 @@ static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) { // Sync storage should still run out after ~100K; the unlimitedStorage // permission can't apply to sync. - std::unique_ptr<base::Value> kilobyte = util::CreateKilobyte(); + std::unique_ptr<base::Value> kilobyte = settings_test_util::CreateKilobyte(); for (int i = 0; i < 100; ++i) { sync_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), *kilobyte); } @@ -1437,7 +1435,7 @@ static void UnlimitedLocalStorageTestCallback(ValueStore* local_storage) { // Local storage should never run out. - std::unique_ptr<base::Value> megabyte = util::CreateMegabyte(); + std::unique_ptr<base::Value> megabyte = settings_test_util::CreateMegabyte(); for (int i = 0; i < 7; ++i) { local_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), *megabyte); @@ -1463,7 +1461,7 @@ std::set<std::string> permissions; permissions.insert("unlimitedStorage"); scoped_refptr<const Extension> extension = - util::AddExtensionWithIdAndPermissions( + settings_test_util::AddExtensionWithIdAndPermissions( profile_.get(), id, Manifest::TYPE_EXTENSION, permissions); frontend_->RunWithStorage(extension,
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index f77b22f..e47eea5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -431,21 +431,6 @@ "expiry_milestone": 76 }, { - "name": "contextual-suggestions-button", - "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS" ], - "expiry_milestone": 74 - }, - { - "name": "contextual-suggestions-iph-reverse-scroll", - "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS" ], - "expiry_milestone": 74 - }, - { - "name": "contextual-suggestions-opt-out", - "owners": [ "//chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/OWNERS" ], - "expiry_milestone": 74 - }, - { "name": "cookies-without-same-site-must-be-secure", "owners": [ "chlily", "morlovich" ], "expiry_milestone": 80 @@ -1010,6 +995,11 @@ "expiry_milestone": -1 }, { + "name": "enable-display-locking", + "owners": [ "//third_party/blink/renderer/core/display_lock/OWNERS" ], + "expiry_milestone": 80 + }, + { "name": "enable-downloads-location-change", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -1925,8 +1915,9 @@ }, { "name": "enable-zero-copy", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "ccameron", "chrome-gpu@google.com" ], + // This flag is commonly used when asking users to help gather debug info. + "expiry_milestone": -1 }, { "name": "enable-zero-state-app-reinstall-suggestions", @@ -2037,8 +2028,8 @@ }, { "name": "force-color-profile", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "ccameron" ], + "expiry_milestone": 81 }, { "name": "force-effective-connection-type", @@ -2345,8 +2336,8 @@ }, { "name": "newblue", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "sonnysasaka" ], + "expiry_milestone": 81 }, { "name": "no-credit-card-abort",
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 5eb802c..e0b487f 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -51,6 +51,7 @@ "enable-virtual-keyboard", "enable-web-authentication-testing-api", "enable-webgl-draft-extensions", + "enable-zero-copy", "extensions-on-chrome-urls", "force-effective-connection-type", "force-show-update-menu-badge",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8202b61..662fedc 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -268,21 +268,6 @@ "Renders a border around composited Render Layers to help debug and study " "layer compositing."; -const char kContextualSuggestionsButtonName[] = "Contextual Suggestions Button"; -const char kContextualSuggestionsButtonDescription[] = - "If enabled, shows a button to trigger contextual suggestions."; - -const char kContextualSuggestionsIPHReverseScrollName[] = - "Contextual Suggestions IPH Reverse Scroll"; -const char kContextualSuggestionsIPHReverseScrollDescription[] = - "Require a reverse scroll before showing in-product help for contextual " - "suggestions."; - -const char kContextualSuggestionsOptOutName[] = - "Contextual Suggestions Opt-out"; -const char kContextualSuggestionsOptOutDescription[] = - "If enabled, allows the user to opt out of contextual suggestions."; - extern const char kCookiesWithoutSameSiteMustBeSecureName[] = "Cookies without SameSite must be secure"; extern const char kCookiesWithoutSameSiteMustBeSecureDescription[] = @@ -643,6 +628,11 @@ "Enable a new compositing mode where Blink generates the compositor " "property trees."; +const char kEnableDisplayLockingName[] = "Enable Display Locking"; +const char kEnableDisplayLockingDescription[] = + "Enable Display Locking JavaScript API. The syntax and the APIs exposed " + "are experimental and may change."; + const char kEnableLayoutNGName[] = "Enable LayoutNG"; const char kEnableLayoutNGDescription[] = "Enable Blink's next generation layout engine.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c357d8d..f21cf57 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -197,15 +197,6 @@ extern const char kCompositedLayerBordersName[]; extern const char kCompositedLayerBordersDescription[]; -extern const char kContextualSuggestionsButtonName[]; -extern const char kContextualSuggestionsButtonDescription[]; - -extern const char kContextualSuggestionsIPHReverseScrollName[]; -extern const char kContextualSuggestionsIPHReverseScrollDescription[]; - -extern const char kContextualSuggestionsOptOutName[]; -extern const char kContextualSuggestionsOptOutDescription[]; - extern const char kCookiesWithoutSameSiteMustBeSecureName[]; extern const char kCookiesWithoutSameSiteMustBeSecureDescription[]; @@ -401,6 +392,9 @@ extern const char kEnableBlinkGenPropertyTreesName[]; extern const char kEnableBlinkGenPropertyTreesDescription[]; +extern const char kEnableDisplayLockingName[]; +extern const char kEnableDisplayLockingDescription[]; + extern const char kEnableLayoutNGName[]; extern const char kEnableLayoutNGDescription[];
diff --git a/chrome/browser/lifetime/application_lifetime_aura.cc b/chrome/browser/lifetime/application_lifetime_aura.cc index bc6d8b90..c0a2ae1 100644 --- a/chrome/browser/lifetime/application_lifetime_aura.cc +++ b/chrome/browser/lifetime/application_lifetime_aura.cc
@@ -12,11 +12,10 @@ #include "chrome/common/chrome_switches.h" #include "ui/aura/client/capture_client.h" #include "ui/aura/window_event_dispatcher.h" -#include "ui/views/mus/mus_client.h" #include "ui/views/widget/widget.h" #if defined(OS_CHROMEOS) -#include "ash/shell.h" // mash-ok +#include "ash/shell.h" #else #include "chrome/browser/notifications/notification_ui_manager.h" #endif @@ -28,15 +27,11 @@ // and windows created by Ash (launcher, background, etc). #if defined(OS_CHROMEOS) - // This is a no-op in mash, as shutting down the client will dismiss any of - // the open menus. This check was originally here to work around an x11-ism, - // but has the nice side effect of making this a no-op in mash. When we turn - // mash on eventually, this can go away. crbug.com/723876 if (ash::Shell::HasInstance()) { // Releasing the capture will close any menus that might be open: // http://crbug.com/134472 - aura::client::GetCaptureClient(ash::Shell::GetPrimaryRootWindow())-> - SetCapture(NULL); + aura::client::GetCaptureClient(ash::Shell::GetPrimaryRootWindow()) + ->SetCapture(nullptr); } #else // This clears existing notifications from the message center and their @@ -47,10 +42,6 @@ views::Widget::CloseAllSecondaryWidgets(); - views::MusClient* const mus_client = views::MusClient::Get(); - if (mus_client) - mus_client->CloseAllWidgets(); - #if defined(OS_CHROMEOS) if (!base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableZeroBrowsersOpenForTests)) {
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc index 532b159..877925a 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -23,6 +23,7 @@ #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" +#include "content/public/common/network_service_util.h" #include "content/public/test/test_utils.h" #include "extensions/buildflags/buildflags.h" #include "net/dns/mock_host_resolver.h" @@ -147,7 +148,8 @@ EXPECT_EQ(samples->TotalCount(), count * number_of_processes) << name; } - if (count != 0 && value_restriction == ValueRestriction::ABOVE_ZERO) + if (count != 0 && number_of_processes != 0 && + value_restriction == ValueRestriction::ABOVE_ZERO) EXPECT_GT(samples->sum(), 0u) << name; // As a sanity check, no memory stat should exceed 4 GB. @@ -251,16 +253,21 @@ } if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + int number_of_ns_processes = + content::IsOutOfProcessNetworkService() ? 1 : 0; CheckMemoryMetric("Memory.NetworkService.ResidentSet", histogram_tester, - count_for_resident_set, ValueRestriction::ABOVE_ZERO, 1); + count_for_resident_set, ValueRestriction::ABOVE_ZERO, + number_of_ns_processes); CheckMemoryMetric("Memory.NetworkService.PrivateMemoryFootprint", - histogram_tester, count, ValueRestriction::ABOVE_ZERO, 1); + histogram_tester, count, ValueRestriction::ABOVE_ZERO, + number_of_ns_processes); // Shared memory footprint can be below 1 MB, which is reported as zero. CheckMemoryMetric("Memory.NetworkService.SharedMemoryFootprint", - histogram_tester, count, ValueRestriction::NONE, 1); + histogram_tester, count, ValueRestriction::NONE, + number_of_ns_processes); CheckMemoryMetric("Memory.NetworkService.PrivateSwapFootprint", histogram_tester, count_for_private_swap_footprint, - ValueRestriction::NONE, 1); + ValueRestriction::NONE, number_of_ns_processes); } CheckMemoryMetric("Memory.Total.ResidentSet", histogram_tester,
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index f39d808..87cad38 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -171,7 +171,22 @@ auto suggestions_fetcher = std::make_unique<RemoteSuggestionsFetcherImpl>( identity_manager, url_loader_factory, pref_service, language_histogram, base::Bind( - &data_decoder::SafeJsonParser::Parse, + // TODO(crbug.com/959749): Remove this adaptor once SafeJsonParser API + // has been updated to pass the base::Value by value. + [](service_manager::Connector* connector, const std::string& json, + const ntp_snippets::SuccessCallback& success_callback, + const ntp_snippets::ErrorCallback& error_callback) { + data_decoder::SafeJsonParser::Parse( + connector, json, + base::Bind( + [](const ntp_snippets::SuccessCallback& callback, + std::unique_ptr<base::Value> value) { + callback.Run( + base::Value::FromUniquePtrValue(std::move(value))); + }, + success_callback), + error_callback); + }, content::ServiceManagerConnection::GetForProcess()->GetConnector()), GetFetchEndpoint(), api_key, user_classifier);
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index cedf4ce..639f6988 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -74,7 +74,6 @@ #include "ppapi/buildflags/buildflags.h" #if defined(OS_ANDROID) -#include "chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h" #include "chrome/browser/search/contextual_search_policy_handler_android.h" #endif @@ -823,9 +822,6 @@ { key::kAuthAndroidNegotiateAccountType, prefs::kAuthAndroidNegotiateAccountType, base::Value::Type::STRING }, - { key::kContextualSuggestionsEnabled, - contextual_suggestions::prefs::kContextualSuggestionsEnabled, - base::Value::Type::BOOLEAN }, #endif // defined(OS_ANDROID) #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 2dc73bf..83f3d59 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -197,7 +197,6 @@ #if defined(OS_ANDROID) #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h" -#include "chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h" #include "chrome/browser/android/explore_sites/history_statistics_reporter.h" #include "chrome/browser/android/ntp/recent_tabs_page_prefs.h" #include "chrome/browser/android/oom_intervention/oom_intervention_decider.h" @@ -790,8 +789,6 @@ #if defined(OS_ANDROID) cdm::MediaDrmStorageImpl::RegisterProfilePrefs(registry); MediaDrmOriginIdManager::RegisterProfilePrefs(registry); - contextual_suggestions::ContextualSuggestionsPrefs::RegisterProfilePrefs( - registry); explore_sites::HistoryStatisticsReporter::RegisterPrefs(registry); ntp_snippets::ClickBasedCategoryRanker::RegisterProfilePrefs(registry); OomInterventionDecider::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index b85b48d2..33ce6a8e 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -419,6 +419,11 @@ NOTREACHED() << "The Push API shouldn't have sent messages upstream"; } +void PushMessagingServiceImpl::OnMessageDecryptionFailed( + const std::string& app_id, + const std::string& message_id, + const std::string& error_message) {} + // GetEndpoint method ---------------------------------------------------------- GURL PushMessagingServiceImpl::GetEndpoint(bool standard_protocol) const {
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.h b/chrome/browser/push_messaging/push_messaging_service_impl.h index 3feb01e..3cbc3947 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.h +++ b/chrome/browser/push_messaging/push_messaging_service_impl.h
@@ -79,6 +79,9 @@ const gcm::GCMClient::SendErrorDetails& send_error_details) override; void OnSendAcknowledged(const std::string& app_id, const std::string& message_id) override; + void OnMessageDecryptionFailed(const std::string& app_id, + const std::string& message_id, + const std::string& error_message) override; bool CanHandle(const std::string& app_id) const override; // content::PushMessagingService implementation:
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 076c24d..96809ace 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -67,6 +67,7 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/exclusive_access/keyboard_lock_controller.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" +#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h" #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" @@ -1169,16 +1170,19 @@ } } #endif // !defined(OS_CHROMEOS) - if (browser && send_tab_to_self::ShouldOfferFeatureForLink( browser->tab_strip_model()->GetActiveWebContents(), params_.link_url)) { send_tab_to_self::RecordSendTabToSelfClickResult( send_tab_to_self::kLinkMenu, SendTabToSelfClickResult::kShowItem); menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); - menu_model_.AddItemWithStringIdAndIcon(IDC_CONTENT_LINK_SEND_TAB_TO_SELF, - IDS_LINK_MENU_SEND_TAB_TO_SELF, - *send_tab_to_self::GetImageSkia()); + send_tab_to_self_sub_menu_model_ = + std::make_unique<send_tab_to_self::SendTabToSelfSubMenuModel>( + GetProfile()); + menu_model_.AddSubMenuWithStringIdAndIcon( + IDC_CONTENT_LINK_SEND_TAB_TO_SELF, IDS_LINK_MENU_SEND_TAB_TO_SELF, + send_tab_to_self_sub_menu_model_.get(), + *send_tab_to_self::GetImageSkia()); } menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); @@ -1374,16 +1378,19 @@ IDS_CONTENT_CONTEXT_SAVEPAGEAS); menu_model_.AddItemWithStringId(IDC_PRINT, IDS_CONTENT_CONTEXT_PRINT); AppendMediaRouterItem(); - if (GetBrowser() && send_tab_to_self::ShouldOfferFeature( GetBrowser()->tab_strip_model()->GetActiveWebContents())) { send_tab_to_self::RecordSendTabToSelfClickResult( send_tab_to_self::kContentMenu, SendTabToSelfClickResult::kShowItem); menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); - menu_model_.AddItemWithStringIdAndIcon(IDC_SEND_TAB_TO_SELF, - IDS_CONTEXT_MENU_SEND_TAB_TO_SELF, - *send_tab_to_self::GetImageSkia()); + send_tab_to_self_sub_menu_model_ = + std::make_unique<send_tab_to_self::SendTabToSelfSubMenuModel>( + GetProfile()); + menu_model_.AddSubMenuWithStringIdAndIcon( + IDC_SEND_TAB_TO_SELF, IDS_CONTEXT_MENU_SEND_TAB_TO_SELF, + send_tab_to_self_sub_menu_model_.get(), + *send_tab_to_self::GetImageSkia()); menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); } if (TranslateService::IsTranslatableURL(params_.page_url)) {
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h index 4c80f2e..1030b81d 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -57,6 +57,10 @@ struct WebPluginAction; } +namespace send_tab_to_self { +class SendTabToSelfSubMenuModel; +} + class RenderViewContextMenu : public RenderViewContextMenuBase { public: RenderViewContextMenu(content::RenderFrameHost* render_frame_host, @@ -278,6 +282,10 @@ // |source_web_contents_|. content::WebContents* const embedder_web_contents_; + // Send tab to self submenu. + std::unique_ptr<send_tab_to_self::SendTabToSelfSubMenuModel> + send_tab_to_self_sub_menu_model_; + DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu); };
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index 8fe598c..ccfd3ee 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -47,7 +47,6 @@ } if (is_android) { deps += [ - "eoc_internals:closure_compile", "explore_sites_internals:closure_compile", "feed_internals:closure_compile", "offline_pages:closure_compile", @@ -59,7 +58,7 @@ deps += [ "app_management:closure_compile" ] } if (is_win || is_mac || is_desktop_linux) { - deps += [ "browser_switcher:closure_compile" ] + deps += [ "browser_switch:closure_compile" ] } } }
diff --git a/chrome/browser/resources/browser_switcher/BUILD.gn b/chrome/browser/resources/browser_switch/BUILD.gn similarity index 79% rename from chrome/browser/resources/browser_switcher/BUILD.gn rename to chrome/browser/resources/browser_switch/BUILD.gn index 8e1af835..17c4dc37 100644 --- a/chrome/browser/resources/browser_switcher/BUILD.gn +++ b/chrome/browser/resources/browser_switch/BUILD.gn
@@ -7,8 +7,8 @@ js_type_check("closure_compile") { deps = [ ":app", - ":browser_switcher_proxy", - "internals:browser_switcher_internals", + ":browser_switch_proxy", + "internals:browser_switch_internals", ] } @@ -19,7 +19,7 @@ ] } -js_library("browser_switcher_proxy") { +js_library("browser_switch_proxy") { deps = [ "//ui/webui/resources/js:cr", ]
diff --git a/chrome/browser/resources/browser_switcher/OWNERS b/chrome/browser/resources/browser_switch/OWNERS similarity index 100% rename from chrome/browser/resources/browser_switcher/OWNERS rename to chrome/browser/resources/browser_switch/OWNERS
diff --git a/chrome/browser/resources/browser_switcher/app.html b/chrome/browser/resources/browser_switch/app.html similarity index 92% rename from chrome/browser/resources/browser_switcher/app.html rename to chrome/browser/resources/browser_switch/app.html index 13df0aa..93b4c21d 100644 --- a/chrome/browser/resources/browser_switcher/app.html +++ b/chrome/browser/resources/browser_switch/app.html
@@ -3,9 +3,9 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="browser_switcher_proxy.html"> +<link rel="import" href="browser_switch_proxy.html"> -<dom-module id="browser-switcher-app"> +<dom-module id="browser-switch-app"> <template> <style> :host {
diff --git a/chrome/browser/resources/browser_switcher/app.js b/chrome/browser/resources/browser_switch/app.js similarity index 97% rename from chrome/browser/resources/browser_switcher/app.js rename to chrome/browser/resources/browser_switch/app.js index 6613847..f8979c8 100644 --- a/chrome/browser/resources/browser_switcher/app.js +++ b/chrome/browser/resources/browser_switch/app.js
@@ -16,7 +16,7 @@ }; Polymer({ - is: 'browser-switcher-app', + is: 'browser-switch-app', behaviors: [I18nBehavior], @@ -141,6 +141,6 @@ } function getProxy() { - return browser_switcher.BrowserSwitcherProxyImpl.getInstance(); + return browser_switch.BrowserSwitchProxyImpl.getInstance(); } })();
diff --git a/chrome/browser/resources/browser_switcher/browser_switcher.html b/chrome/browser/resources/browser_switch/browser_switch.html similarity index 93% rename from chrome/browser/resources/browser_switcher/browser_switcher.html rename to chrome/browser/resources/browser_switch/browser_switch.html index f49fd1b..9b61a63d 100644 --- a/chrome/browser/resources/browser_switcher/browser_switcher.html +++ b/chrome/browser/resources/browser_switch/browser_switch.html
@@ -21,7 +21,7 @@ </head> <body> - <browser-switcher-app></browser-switcher-app> + <browser-switch-app></browser-switch-app> <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
diff --git a/chrome/browser/resources/browser_switch/browser_switch_proxy.html b/chrome/browser/resources/browser_switch/browser_switch_proxy.html new file mode 100644 index 0000000..4dd11cd --- /dev/null +++ b/chrome/browser/resources/browser_switch/browser_switch_proxy.html
@@ -0,0 +1,2 @@ +<link rel="import" href="chrome://resources/html/cr.html"> +<script src="browser_switch_proxy.js"></script>
diff --git a/chrome/browser/resources/browser_switcher/browser_switcher_proxy.js b/chrome/browser/resources/browser_switch/browser_switch_proxy.js similarity index 69% rename from chrome/browser/resources/browser_switcher/browser_switcher_proxy.js rename to chrome/browser/resources/browser_switch/browser_switch_proxy.js index 3611939..dd35bff2 100644 --- a/chrome/browser/resources/browser_switcher/browser_switcher_proxy.js +++ b/chrome/browser/resources/browser_switch/browser_switch_proxy.js
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('browser_switcher', function() { +cr.define('browser_switch', function() { /** @interface */ - class BrowserSwitcherProxy { + class BrowserSwitchProxy { /** * @param {string} url URL to open in alternative browser. * @return {Promise} A promise that can fail if unable to launch. It will @@ -15,8 +15,8 @@ gotoNewTabPage() {} } - /** @implements {browser_switcher.BrowserSwitcherProxy} */ - class BrowserSwitcherProxyImpl { + /** @implements {browser_switch.BrowserSwitchProxy} */ + class BrowserSwitchProxyImpl { /** @override */ launchAlternativeBrowserAndCloseTab(url) { return cr.sendWithPromise('launchAlternativeBrowserAndCloseTab', url); @@ -28,10 +28,10 @@ } } - cr.addSingletonGetter(BrowserSwitcherProxyImpl); + cr.addSingletonGetter(BrowserSwitchProxyImpl); return { - BrowserSwitcherProxy: BrowserSwitcherProxy, - BrowserSwitcherProxyImpl: BrowserSwitcherProxyImpl + BrowserSwitchProxy: BrowserSwitchProxy, + BrowserSwitchProxyImpl: BrowserSwitchProxyImpl }; });
diff --git a/chrome/browser/resources/browser_switcher/internals/BUILD.gn b/chrome/browser/resources/browser_switch/internals/BUILD.gn similarity index 82% rename from chrome/browser/resources/browser_switcher/internals/BUILD.gn rename to chrome/browser/resources/browser_switch/internals/BUILD.gn index 6d3279dc..a5bdb49 100644 --- a/chrome/browser/resources/browser_switcher/internals/BUILD.gn +++ b/chrome/browser/resources/browser_switch/internals/BUILD.gn
@@ -6,11 +6,11 @@ js_type_check("closure_compile") { deps = [ - ":browser_switcher_internals", + ":browser_switch_internals", ] } -js_library("browser_switcher_internals") { +js_library("browser_switch_internals") { deps = [ "//ui/webui/resources/js:cr", "//ui/webui/resources/js:util",
diff --git a/chrome/browser/resources/browser_switcher/internals/browser_switcher_internals.html b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.html similarity index 94% rename from chrome/browser/resources/browser_switcher/internals/browser_switcher_internals.html rename to chrome/browser/resources/browser_switch/internals/browser_switch_internals.html index 6ac61de0..7ea804b6 100644 --- a/chrome/browser/resources/browser_switcher/internals/browser_switcher_internals.html +++ b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.html
@@ -64,6 +64,6 @@ </tr> </template> - <script src="/internals/browser_switcher_internals.js"></script> + <script src="/internals/browser_switch_internals.js"></script> </body> </html>
diff --git a/chrome/browser/resources/browser_switcher/internals/browser_switcher_internals.js b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.js similarity index 100% rename from chrome/browser/resources/browser_switcher/internals/browser_switcher_internals.js rename to chrome/browser/resources/browser_switch/internals/browser_switch_internals.js
diff --git a/chrome/browser/resources/browser_switcher/browser_switcher_proxy.html b/chrome/browser/resources/browser_switcher/browser_switcher_proxy.html deleted file mode 100644 index 7671198a..0000000 --- a/chrome/browser/resources/browser_switcher/browser_switcher_proxy.html +++ /dev/null
@@ -1,2 +0,0 @@ -<link rel="import" href="chrome://resources/html/cr.html"> -<script src="browser_switcher_proxy.js"></script>
diff --git a/chrome/browser/resources/eoc_internals/OWNERS b/chrome/browser/resources/eoc_internals/OWNERS deleted file mode 100644 index 7e6bf66..0000000 --- a/chrome/browser/resources/eoc_internals/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://components/ntp_snippets/OWNERS \ No newline at end of file
diff --git a/chrome/browser/resources/eoc_internals/eoc_internals.css b/chrome/browser/resources/eoc_internals/eoc_internals.css deleted file mode 100644 index f5b56ac8..0000000 --- a/chrome/browser/resources/eoc_internals/eoc_internals.css +++ /dev/null
@@ -1,29 +0,0 @@ -/* Copyright 2018 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -.details { - width: 100%; -} - -.details td { - min-width: 100px; -} - -.details tr:nth-child(odd) { - background: rgb(239, 243, 255); -} - -#suggestion-result { - border-bottom: 1px solid black; - padding-bottom: 5px; -} - -#metric-event { - border-bottom: 1px solid black; - padding-bottom: 5px; -} - -#cached-suggestions>div { - margin-bottom: 5px; -}
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.js b/chrome/browser/resources/local_ntp/custom_backgrounds.js index 4bcf716b..0a06fa4b 100644 --- a/chrome/browser/resources/local_ntp/custom_backgrounds.js +++ b/chrome/browser/resources/local_ntp/custom_backgrounds.js
@@ -75,7 +75,10 @@ ATTR2: 'attr2', ATTRIBUTIONS: 'custom-bg-attr', BACK_CIRCLE: 'bg-sel-back-circle', + BACKGROUNDS_BUTTON: 'backgrounds-button', + BACKGROUNDS_MENU: 'backgrounds-menu', CANCEL: 'bg-sel-footer-cancel', + COLORS_BUTTON: 'colors-button', CUSTOMIZATION_MENU: 'customization-menu', CUSTOM_LINKS_RESTORE_DEFAULT: 'custom-links-restore-default', CUSTOM_LINKS_RESTORE_DEFAULT_TEXT: 'custom-links-restore-default-text', @@ -94,6 +97,7 @@ OPTIONS_TITLE: 'edit-bg-title', RESTORE_DEFAULT: 'edit-bg-restore-default', RESTORE_DEFAULT_TEXT: 'edit-bg-restore-default-text', + SHORTCUTS_BUTTON: 'shortcuts-button', UPLOAD_IMAGE: 'edit-bg-upload-image', UPLOAD_IMAGE_TEXT: 'edit-bg-upload-image-text', TILES: 'bg-sel-tiles', @@ -119,6 +123,7 @@ IMAGE_DIALOG: 'is-img-sel', OPTION: 'bg-option', OPTION_DISABLED: 'bg-option-disabled', // The menu option is disabled. + MENU_SHOWN: 'menu-shown', MOUSE_NAV: 'using-mouse-nav', SELECTED_BORDER: 'selected-border', SELECTED_CHECK: 'selected-check', @@ -157,6 +162,11 @@ customBackgrounds.delayedHideNotification = -1; customBackgrounds.NOTIFICATION_TIMEOUT = 10000; +/* Were the background tiles already created. + * @type {bool} + */ +customBackgrounds.builtTiles = false; + /* Tile that was selected by the user. * @type {HTMLElement} */ @@ -189,6 +199,7 @@ */ customBackgrounds.hideCustomLinkNotification = null; + /** * Sets the visibility of the settings menu and individual options depending on * their respective features. @@ -366,8 +377,16 @@ * collection data from. */ customBackgrounds.showCollectionSelectionDialog = function(collectionsSource) { - const tileContainer = $(customBackgrounds.IDS.TILES); - const menu = $(customBackgrounds.IDS.MENU); + const tileContainer = configData.richerPicker ? + $(customBackgrounds.IDS.BACKGROUNDS_MENU) : + $(customBackgrounds.IDS.TILES); + if (configData.richerPicker && customBackgrounds.builtTiles) { + return; + } + customBackgrounds.builtTiles = true; + const menu = configData.richerPicker ? + $(customBackgrounds.IDS.CUSTOMIZATION_MENU) : + $(customBackgrounds.IDS.MENU); if (collectionsSource != customBackgrounds.SOURCES.CHROME_BACKGROUNDS) { console.log( 'showCollectionSelectionDialog() called with invalid source=' + @@ -724,6 +743,12 @@ collScript.id = 'ntp-collection-loader'; collScript.src = 'chrome-search://local-ntp/ntp-background-collections.js?' + 'collection_type=background'; + collScript.onload = function() { + if (configData.richerPicker) { + customBackgrounds.showCollectionSelectionDialog( + customBackgrounds.SOURCES.CHROME_BACKGROUNDS); + } + }; document.body.appendChild(collScript); }; @@ -796,6 +821,9 @@ // Edit gear icon interaction events. const editBackgroundInteraction = function() { if (configData.richerPicker) { + $(customBackgrounds.IDS.BACKGROUNDS_MENU) + .classList.toggle(customBackgrounds.CLASSES.MENU_SHOWN, true); + customBackgrounds.loadChromeBackgrounds(); $(customBackgrounds.IDS.CUSTOMIZATION_MENU).showModal(); } else { editDialog.showModal(); @@ -1181,6 +1209,21 @@ } } }; + + $(customBackgrounds.IDS.BACKGROUNDS_BUTTON).onclick = function() { + $(customBackgrounds.IDS.BACKGROUNDS_MENU) + .classList.toggle(customBackgrounds.CLASSES.MENU_SHOWN, true); + }; + + $(customBackgrounds.IDS.SHORTCUTS_BUTTON).onclick = function() { + $(customBackgrounds.IDS.BACKGROUNDS_MENU) + .classList.toggle(customBackgrounds.CLASSES.MENU_SHOWN, false); + }; + + $(customBackgrounds.IDS.COLORS_BUTTON).onclick = function() { + $(customBackgrounds.IDS.BACKGROUNDS_MENU) + .classList.toggle(customBackgrounds.CLASSES.MENU_SHOWN, false); + }; }; customBackgrounds.handleError = function(errors) {
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css index 69a8481..b444402 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.css +++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -856,8 +856,10 @@ } #menu-nav-panel { + display: inline-block; height: 384px; left: 0; + vertical-align: top; width: 192px; } @@ -920,12 +922,8 @@ user-select: none; } -#menu-header { - font-size: 16px; - height: 80px; -} - #menu-title { + font-size: 16px; height: 48px; line-height: 48px; margin-bottom: 8px; @@ -958,3 +956,65 @@ line-height: 32px; margin-inline-end: 8px; } + +#menu-contents { + display: inline-block; + height: 384px; + margin-inline-start: 20px; + position: relative; + width: 584px; +} + +.menu-panel { + height: 100%; + left: 0; + overflow-y: scroll; + position: absolute; + top: 0; + visibility: hidden; + width: 100%; +} + +#backgrounds-menu .bg-sel-tile-bg { + border-radius: 4px; + height: 176px; + margin-bottom: 45px; + margin-inline-end: 8px; + margin-inline-start: 0; + width: 176px; +} + +#backgrounds-menu .bg-sel-tile { + background-position: center; + border-radius: 4px; +} + +#backgrounds-menu .bg-sel-tile-title { + background-color: unset; + color: rgb(var(--GG700-rgb)); + font-size: 13px; + height: 30px; + margin-bottom: -28px; + padding: 8px 0 24px 0; +} + +#backgrounds-default.bg-sel-tile-bg { + background-color: white; + border: 1px solid black; + height: 174px; + margin-inline-end: 6px + width: 174px; +} + +#backgrounds-upload.bg-sel-tile-bg { + background-color: white; + border: 1px solid black; + height: 174px; + margin-inline-end: 6px; + vertical-align: top; + width: 174px; +} + +.menu-shown { + visibility: visible; +}
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html index 9615ac8d..000706a1 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.html +++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -170,27 +170,33 @@ </dialog> <dialog id="customization-menu" class="customize-dialog"> - <div id="menu-header"> - <div id="menu-title">$i18n{customizeMenuTitle}</div> - </div> + <div id="menu-title">$i18n{customizeMenuTitle}</div> <div id="menu-nav-panel"> - <div class="menu-option" tabindex="0"> + <div id="backgrounds-button" class="menu-option" tabindex="0"> <div class="menu-option-icon-wrapper"> - <div class="menu-option-icon" id="backgrounds-icon"></div> + <div ids="backgrounds-icon" class="menu-option-icon"></div> </div> - <div class="menu-option-label" id="backgrounds-button">$i18n{backgroundsOption}</div> + <div class="menu-option-label">$i18n{backgroundsOption}</div> </div> - <div class="menu-option" tabindex="0"> + <div id="shortcuts-button" class="menu-option" tabindex="0"> <div class="menu-option-icon-wrapper"> - <div class="menu-option-icon" id="shortcuts-icon"></div> + <div ids="shortcuts-icon" class="menu-option-icon"></div> </div> - <div class="menu-option-label" id="shortcuts-button">$i18n{shortcutsOption}</div> + <div class="menu-option-label">$i18n{shortcutsOption}</div> </div> - <div class="menu-option" tabindex="0"> + <div id="colors-button" class="menu-option" tabindex="0"> <div class="menu-option-icon-wrapper"> - <div class="menu-option-icon" id="colors-icon"></div> + <div id="colors-icon" class="menu-option-icon"></div> </div> - <div class="menu-option-label" id="colors-button">$i18n{colorsOption}</div> + <div class="menu-option-label">$i18n{colorsOption}</div> + </div> + </div> + <div id="menu-contents"> + <div id="backgrounds-menu" class="menu-panel"> + <div id="backgrounds-upload" class="bg-sel-tile-bg">Upload an image</div> + <div id="backgrounds-default" class="bg-sel-tile-bg"> + <div class="bg-sel-tile-title">Default</div> + </div> </div> </div> <div id="menu-footer">
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index bfc4178..ba9e7be 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -188,10 +188,14 @@ StringProvider sync_password_hash_provider = base::BindLambdaForTesting([=] { return sync_password_hash; }); + // TODO(crbug/925153): Port consumers of the SafeBrowsingService + // to use the interface in components/safe_browsing, and remove this + // cast. return std::make_unique<MockChromePasswordProtectionService>( profile(), content_setting_map_, new SafeBrowsingUIManager( - SafeBrowsingService::CreateSafeBrowsingService()), + static_cast<safe_browsing::SafeBrowsingService*>( + SafeBrowsingService::CreateSafeBrowsingService())), sync_password_hash_provider); }
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index 73920ad..249b859 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -284,7 +284,10 @@ csd_service_.reset(new StrictMock<MockClientSideDetectionService>()); database_manager_ = new StrictMock<MockSafeBrowsingDatabaseManager>(); ui_manager_ = new StrictMock<MockSafeBrowsingUIManager>( - SafeBrowsingService::CreateSafeBrowsingService()); + // TODO(crbug/925153): Port consumers of the SafeBrowsingService to + // use the interface in components/safe_browsing, and remove this cast. + static_cast<safe_browsing::SafeBrowsingService*>( + SafeBrowsingService::CreateSafeBrowsingService())); csd_host_ = ClientSideDetectionHost::Create(web_contents()); csd_host_->set_client_side_detection_service(csd_service_.get());
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index d7141a4..b1dd14d0 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -13,9 +13,9 @@ #include "base/bind_helpers.h" #include "base/callback.h" #include "base/command_line.h" -#include "base/lazy_instance.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" #include "base/path_service.h" #include "base/strings/string_util.h" #include "base/task/post_task.h" @@ -100,28 +100,6 @@ #endif // static -SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL; - -// The default SafeBrowsingServiceFactory. Global, made a singleton so we -// don't leak it. -class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { - public: - SafeBrowsingService* CreateSafeBrowsingService() override { - return new SafeBrowsingService(); - } - - private: - friend struct base::LazyInstanceTraitsBase<SafeBrowsingServiceFactoryImpl>; - - SafeBrowsingServiceFactoryImpl() {} - - DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl); -}; - -static base::LazyInstance<SafeBrowsingServiceFactoryImpl>::Leaky - g_safe_browsing_service_factory_impl = LAZY_INSTANCE_INITIALIZER; - -// static base::FilePath SafeBrowsingService::GetCookieFilePathForTesting() { return base::FilePath(SafeBrowsingService::GetBaseFilename().value() + safe_browsing::kCookiesFile); @@ -135,13 +113,6 @@ return path.Append(safe_browsing::kSafeBrowsingBaseFilename); } -// static -SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() { - if (!factory_) - factory_ = g_safe_browsing_service_factory_impl.Pointer(); - return factory_->CreateSafeBrowsingService(); -} - SafeBrowsingService::SafeBrowsingService() : services_delegate_(ServicesDelegate::Create(this)), estimated_extended_reporting_by_prefs_(SBER_LEVEL_OFF), @@ -592,4 +563,27 @@ return params; } +// The default SafeBrowsingServiceFactory. Global, made a singleton so we +// don't leak it. +class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { + public: + // TODO(crbug/925153): Once callers of this function are no longer downcasting + // it to the SafeBrowsingService, we can make this a scoped_refptr. + SafeBrowsingServiceInterface* CreateSafeBrowsingService() override { + return new SafeBrowsingService(); + } + + private: + friend class base::NoDestructor<SafeBrowsingServiceFactoryImpl>; + + SafeBrowsingServiceFactoryImpl() {} + + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl); +}; + +SafeBrowsingServiceFactory* GetSafeBrowsingServiceFactory() { + static base::NoDestructor<SafeBrowsingServiceFactoryImpl> factory; + return factory.get(); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h index 70ca47ae..9f0fc34 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -23,6 +23,7 @@ #include "chrome/browser/safe_browsing/services_delegate.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/db/util.h" +#include "components/safe_browsing/safe_browsing_service_interface.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -82,24 +83,13 @@ // the heavylifting of safebrowsing service. Both of these managers stay // alive until SafeBrowsingService is destroyed, however, they are disabled // permanently when Shutdown method is called. -class SafeBrowsingService : public base::RefCountedThreadSafe< - SafeBrowsingService, - content::BrowserThread::DeleteOnUIThread>, +class SafeBrowsingService : public SafeBrowsingServiceInterface, public content::NotificationObserver { public: - // Makes the passed |factory| the factory used to instanciate - // a SafeBrowsingService. Useful for tests. - static void RegisterFactory(SafeBrowsingServiceFactory* factory) { - factory_ = factory; - } - static base::FilePath GetCookieFilePathForTesting(); static base::FilePath GetBaseFilename(); - // Create an instance of the safe browsing service. - static SafeBrowsingService* CreateSafeBrowsingService(); - // Called on the UI thread to initialize the service. void Initialize(); @@ -289,11 +279,6 @@ // use. network::mojom::NetworkContextParamsPtr CreateNetworkContextParams(); - // The factory used to instantiate a SafeBrowsingService object. - // Useful for tests, so they can provide their own implementation of - // SafeBrowsingService. - static SafeBrowsingServiceFactory* factory_; - // The SafeBrowsingURLRequestContextGetter used to access // |url_request_context_|. Accessed on UI thread. // This is only valid if the network service is disabled. @@ -358,16 +343,7 @@ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService); }; -// Factory for creating SafeBrowsingService. Useful for tests. -class SafeBrowsingServiceFactory { - public: - SafeBrowsingServiceFactory() {} - virtual ~SafeBrowsingServiceFactory() {} - virtual SafeBrowsingService* CreateSafeBrowsingService() = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactory); -}; +SafeBrowsingServiceFactory* GetSafeBrowsingServiceFactory(); } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc index 2dca865d..b235300 100644 --- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc +++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -59,8 +60,12 @@ {content::BrowserThread::IO})); browser_process_->SetSystemRequestContext( system_request_context_getter_.get()); - sb_service_ = - safe_browsing::SafeBrowsingService::CreateSafeBrowsingService(); + safe_browsing::SafeBrowsingServiceInterface::RegisterFactory( + GetSafeBrowsingServiceFactory()); + // TODO(crbug/925153): Port consumers of the |sb_service_| to use + // the interface in components/safe_browsing, and remove this cast. + sb_service_ = static_cast<SafeBrowsingService*>( + safe_browsing::SafeBrowsingService::CreateSafeBrowsingService()); browser_process_->SetSafeBrowsingService(sb_service_.get()); sb_service_->Initialize(); base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc index 74092965..2bf2c366 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -353,6 +353,9 @@ custodian.display_name); profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail, custodian.email); + profile_->GetPrefs()->SetString( + prefs::kSupervisedUserCustodianObfuscatedGaiaId, + custodian.obfuscated_gaia_id); profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianProfileURL, custodian.profile_url); profile_->GetPrefs()->SetString( @@ -367,6 +370,9 @@ profile_->GetPrefs()->SetString(prefs::kSupervisedUserSecondCustodianEmail, custodian.email); profile_->GetPrefs()->SetString( + prefs::kSupervisedUserSecondCustodianObfuscatedGaiaId, + custodian.obfuscated_gaia_id); + profile_->GetPrefs()->SetString( prefs::kSupervisedUserSecondCustodianProfileURL, custodian.profile_url); profile_->GetPrefs()->SetString(
diff --git a/chrome/browser/supervised_user/supervised_user_pref_store.cc b/chrome/browser/supervised_user/supervised_user_pref_store.cc index 0b3a481d..ea022f8 100644 --- a/chrome/browser/supervised_user/supervised_user_pref_store.cc +++ b/chrome/browser/supervised_user/supervised_user_pref_store.cc
@@ -23,10 +23,6 @@ #include "components/prefs/pref_value_map.h" #include "components/signin/core/browser/signin_pref_names.h" -#if defined(OS_ANDROID) -#include "chrome/browser/android/contextual_suggestions/contextual_suggestions_prefs.h" -#endif - namespace { struct SupervisedUserSettingsPrefMappingEntry { @@ -137,11 +133,6 @@ prefs_->SetBoolean(prefs::kSigninAllowed, false); prefs_->SetBoolean(ntp_snippets::prefs::kEnableSnippets, false); -#if defined(OS_ANDROID) - prefs_->SetBoolean( - contextual_suggestions::prefs::kContextualSuggestionsEnabled, false); -#endif - // Copy supervised user settings to prefs. for (const auto& entry : kSupervisedUserSettingsPrefMapping) { const base::Value* value = NULL;
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index 8d9e817..076001e0 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -268,6 +268,11 @@ return email; } +std::string SupervisedUserService::GetCustodianObfuscatedGaiaId() const { + return profile_->GetPrefs()->GetString( + prefs::kSupervisedUserCustodianObfuscatedGaiaId); +} + std::string SupervisedUserService::GetCustodianName() const { std::string name = profile_->GetPrefs()->GetString( prefs::kSupervisedUserCustodianName); @@ -291,6 +296,11 @@ prefs::kSupervisedUserSecondCustodianEmail); } +std::string SupervisedUserService::GetSecondCustodianObfuscatedGaiaId() const { + return profile_->GetPrefs()->GetString( + prefs::kSupervisedUserSecondCustodianObfuscatedGaiaId); +} + std::string SupervisedUserService::GetSecondCustodianName() const { std::string name = profile_->GetPrefs()->GetString( prefs::kSupervisedUserSecondCustodianName);
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h index bdc6e46..b9b37fa 100644 --- a/chrome/browser/supervised_user/supervised_user_service.h +++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -134,6 +134,9 @@ // Returns the email address of the custodian. std::string GetCustodianEmailAddress() const; + // Returns the obfuscated GAIA id of the custodian. + std::string GetCustodianObfuscatedGaiaId() const; + // Returns the name of the custodian, or the email address if the name is // empty. std::string GetCustodianName() const; @@ -142,8 +145,12 @@ // if there is no second custodian. std::string GetSecondCustodianEmailAddress() const; + // Returns the obfuscated GAIA id of the second custodian or the empty + // string if there is no second custodian. + std::string GetSecondCustodianObfuscatedGaiaId() const; + // Returns the name of the second custodian, or the email address if the name - // is empty, or the empty string is there is no second custodian. + // is empty, or the empty string if there is no second custodian. std::string GetSecondCustodianName() const; // Returns a message saying that extensions can only be modified by the
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 9c351c71..a878ef7 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -477,6 +477,7 @@ "//components/security_interstitials/core", "//components/security_state/content", "//components/security_state/core", + "//components/send_tab_to_self", "//components/sessions", "//components/signin/core/browser", "//components/signin/core/browser:signin_buildflags", @@ -572,7 +573,6 @@ if (is_android) { deps += [ - "//chrome/browser/ui/webui/eoc_internals:mojo_bindings", "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings", "//chrome/browser/ui/webui/snippets_internals:mojo_bindings", ] @@ -730,10 +730,6 @@ "android/view_android_helper.h", "browser_otr_state_android.cc", "screen_capture_notification_ui_stub.cc", - "webui/eoc_internals/eoc_internals_page_handler.cc", - "webui/eoc_internals/eoc_internals_page_handler.h", - "webui/eoc_internals/eoc_internals_ui.cc", - "webui/eoc_internals/eoc_internals_ui.h", "webui/explore_sites_internals/explore_sites_internals_page_handler.cc", "webui/explore_sites_internals/explore_sites_internals_page_handler.h", "webui/explore_sites_internals/explore_sites_internals_ui.cc", @@ -998,6 +994,8 @@ "search/search_ipc_router_policy_impl.h", "search/search_tab_helper.cc", "search/search_tab_helper.h", + "send_tab_to_self/send_tab_to_self_sub_menu_model.cc", + "send_tab_to_self/send_tab_to_self_sub_menu_model.h", "serial/serial_chooser.cc", "serial/serial_chooser.h", "serial/serial_chooser_controller.cc", @@ -1537,6 +1535,10 @@ "webui/chromeos/account_manager_welcome_dialog.h", "webui/chromeos/account_manager_welcome_ui.cc", "webui/chromeos/account_manager_welcome_ui.h", + "webui/chromeos/add_supervision/add_supervision_handler.cc", + "webui/chromeos/add_supervision/add_supervision_handler.h", + "webui/chromeos/add_supervision/add_supervision_handler_utils.cc", + "webui/chromeos/add_supervision/add_supervision_handler_utils.h", "webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc", "webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h", "webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.cc", @@ -1792,6 +1794,7 @@ "//ash/public/cpp/resources:ash_public_unscaled_resources", "//ash/public/cpp/vector_icons", "//chrome/browser/chromeos", + "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings", "//chromeos", "//chromeos/assistant:buildflags", "//chromeos/audio", @@ -1927,8 +1930,8 @@ "views/profiles/user_manager_view.h", "webui/app_launcher_page_ui.cc", "webui/app_launcher_page_ui.h", - "webui/browser_switcher/browser_switch_ui.cc", - "webui/browser_switcher/browser_switch_ui.h", + "webui/browser_switch/browser_switch_ui.cc", + "webui/browser_switch/browser_switch_ui.h", "webui/profile_helper.cc", "webui/profile_helper.h", "webui/settings/settings_default_browser_handler.cc",
diff --git a/chrome/browser/ui/ash/DEPS b/chrome/browser/ui/ash/DEPS index 257cddd3..0cad75d0 100644 --- a/chrome/browser/ui/ash/DEPS +++ b/chrome/browser/ui/ash/DEPS
@@ -57,4 +57,8 @@ "tab_scrubber\.cc": [ "+ash/shell.h", ], + "screen_rotation_interactive_uitest\.cc": [ + "+ash/rotator/screen_rotation_animator.h", + "+ash/rotator/screen_rotation_animator_observer.h", + ], }
diff --git a/chrome/browser/ui/ash/ash_shell_init.cc b/chrome/browser/ui/ash/ash_shell_init.cc index abd7a88..d383c4d 100644 --- a/chrome/browser/ui/ash/ash_shell_init.cc +++ b/chrome/browser/ui/ash/ash_shell_init.cc
@@ -14,21 +14,17 @@ #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_ui_factory.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "content/public/browser/context_factory.h" -#include "content/public/browser/gpu_interface_provider_factory.h" #include "content/public/common/service_manager_connection.h" #include "ui/aura/window_tree_host.h" -#include "ui/base/ui_base_features.h" namespace { -void CreateClassicShell() { +void CreateShell() { ash::ShellInitParams shell_init_params; shell_init_params.delegate = std::make_unique<ChromeShellDelegate>(); shell_init_params.context_factory = content::GetContextFactory(); shell_init_params.context_factory_private = content::GetContextFactoryPrivate(); - shell_init_params.gpu_interface_provider = - content::CreateGpuInterfaceProvider(); shell_init_params.connector = content::ServiceManagerConnection::GetForProcess()->GetConnector(); DCHECK(shell_init_params.connector); @@ -39,10 +35,8 @@ shell_init_params.initial_display_prefs = ash::DisplayPrefs::GetInitialDisplayPrefsFromPrefService( g_browser_process->local_state()); - if (!features::IsUsingWindowService()) { - shell_init_params.keyboard_ui_factory = - std::make_unique<ChromeKeyboardUIFactory>(); - } + shell_init_params.keyboard_ui_factory = + std::make_unique<ChromeKeyboardUIFactory>(); shell_init_params.dbus_bus = chromeos::DBusThreadManager::Get()->GetSystemBus(); @@ -53,13 +47,13 @@ // static void AshShellInit::RegisterDisplayPrefs(PrefRegistrySimple* registry) { - // Note: For CLASSIC/MUS, DisplayPrefs must be registered here so that - // the initial display prefs can be passed synchronously to ash::Shell. + // DisplayPrefs must be registered here so that the initial display prefs can + // be passed synchronously to ash::Shell. ash::DisplayPrefs::RegisterLocalStatePrefs(registry); } AshShellInit::AshShellInit() { - CreateClassicShell(); + CreateShell(); ash::Shell::GetPrimaryRootWindow()->GetHost()->Show(); }
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index 69c70667..1e36234 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -64,15 +64,11 @@ #include "content/public/common/service_manager_connection.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/ws/public/mojom/constants.mojom.h" #include "services/ws/public/mojom/user_activity_monitor.mojom.h" #include "ui/aura/mus/property_converter.h" -#include "ui/aura/mus/user_activity_forwarder.h" #include "ui/aura/mus/window_tree_client.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ui_base_features.h" -#include "ui/base/user_activity/user_activity_detector.h" -#include "ui/views/mus/mus_client.h" #if BUILDFLAG(ENABLE_WAYLAND_SERVER) #include "chrome/browser/exo_parts.h" @@ -147,40 +143,6 @@ tablet_mode_client_.reset(); } -void ChromeBrowserMainExtraPartsAsh::ServiceManagerConnectionStarted( - content::ServiceManagerConnection* connection) { - if (features::IsMultiProcessMash()) { - // Mash and SingleProcessMash cannot be enabled simultaneously. - DCHECK(!features::IsSingleProcessMash()); - - // ash::Shell will not be created because ash is running out-of-process. - ash::Shell::SetIsBrowserProcessWithMash(); - } - - if (features::IsUsingWindowService()) { - // Start up the window service and the ash system UI service. - // NOTE: ash::Shell is still created below for SingleProcessMash. - connection->GetConnector()->WarmService( - service_manager::ServiceFilter::ByName(ws::mojom::kServiceName)); - connection->GetConnector()->WarmService( - service_manager::ServiceFilter::ByName(ash::mojom::kServiceName)); - - views::MusClient::InitParams params; - params.connector = connection->GetConnector(); - params.io_task_runner = base::CreateSingleThreadTaskRunnerWithTraits( - {content::BrowserThread::IO}); - // WMState has already been created, so don't have MusClient create it. - params.create_wm_state = false; - params.running_in_ws_process = features::IsSingleProcessMash(); - mus_client_ = std::make_unique<views::MusClient>(params); - // Register ash-specific window properties with Chrome's property converter. - // Values of registered properties will be transported between the services. - ash::RegisterWindowProperties(mus_client_->property_converter()); - mus_client_->SetMusPropertyMirror( - std::make_unique<ash::MusPropertyMirrorAsh>()); - } -} - void ChromeBrowserMainExtraPartsAsh::PreProfileInit() { // IME driver must be available at login screen, so initialize before profile. IMEDriverMus::Register(); @@ -190,21 +152,7 @@ std::make_unique<NetworkConnectDelegateChromeOS>(); chromeos::NetworkConnect::Initialize(network_connect_delegate_.get()); - if (!features::IsMultiProcessMash()) { - ash_shell_init_ = std::make_unique<AshShellInit>(); - } else { - // Enterprise support in the browser can monitor user activity. Connect to - // the UI service to monitor activity. The ash process has its own monitor. - // TODO(jamescook): Figure out if we need this for SingleProcessMash. - // https://crbug.com/626899 - user_activity_detector_ = std::make_unique<ui::UserActivityDetector>(); - ws::mojom::UserActivityMonitorPtr user_activity_monitor; - content::ServiceManagerConnection::GetForProcess() - ->GetConnector() - ->BindInterface(ws::mojom::kServiceName, &user_activity_monitor); - user_activity_forwarder_ = std::make_unique<aura::UserActivityForwarder>( - std::move(user_activity_monitor), user_activity_detector_.get()); - } + ash_shell_init_ = std::make_unique<AshShellInit>(); if (ui_devtools::UiDevToolsServer::IsUiDevToolsEnabled( ui_devtools::switches::kEnableUiDevTools)) { @@ -344,10 +292,6 @@ app_list_client_.reset(); ash_shell_init_.reset(); - // WindowTreeClient needs to do some shutdown while the IO thread is alive. - if (mus_client_) - mus_client_->window_tree_client()->OnEarlyShutdown(); - chromeos::NetworkConnect::Shutdown(); network_connect_delegate_.reset(); }
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h index 02699b79..11904b21 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
@@ -11,10 +11,6 @@ #include "chrome/browser/chrome_browser_main_extra_parts.h" #include "chrome/common/buildflags.h" -namespace aura { -class UserActivityForwarder; -} - namespace chromeos { class NetworkPortalNotificationController; } @@ -23,14 +19,6 @@ class DisplaySettingsHandler; } -namespace ui { -class UserActivityDetector; -} - -namespace views { -class MusClient; -} - class AccessibilityControllerClient; class AppListClientImpl; class AshShellInit; @@ -66,8 +54,6 @@ ~ChromeBrowserMainExtraPartsAsh() override; // Overridden from ChromeBrowserMainExtraParts: - void ServiceManagerConnectionStarted( - content::ServiceManagerConnection* connection) override; void PreProfileInit() override; void PostProfileInit() override; void PostBrowserStart() override; @@ -84,10 +70,6 @@ // Initialized in PreProfileInit if ash config != MASH: std::unique_ptr<AshShellInit> ash_shell_init_; - // Initialized in PreProfileInit if ash config == MASH: - std::unique_ptr<aura::UserActivityForwarder> user_activity_forwarder_; - std::unique_ptr<ui::UserActivityDetector> user_activity_detector_; - // Initialized in PreProfileInit in all configs after Shell init: std::unique_ptr<AccessibilityControllerClient> accessibility_controller_client_; @@ -124,9 +106,6 @@ std::unique_ptr<MobileDataNotifications> mobile_data_notifications_; std::unique_ptr<NightLightClient> night_light_client_; - // Created for mash (both in single and multi-process). - std::unique_ptr<views::MusClient> mus_client_; - DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsAsh); };
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 8e483c4f..745c6918 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
@@ -248,7 +248,6 @@ return; // TODO(msw): Set shelf item types earlier to avoid ShelfWindowWatcher races. - // (maybe use Widget::InitParams::mus_properties in cash too crbug.com/750334) window->SetProperty<int>(ash::kShelfItemTypeKey, ash::TYPE_APP); // Create controller if we have task info.
diff --git a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc index 46dc99b..b81fd03 100644 --- a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
@@ -167,7 +167,6 @@ window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize())); // TODO(msw): Set shelf item types earlier to avoid ShelfWindowWatcher races. - // (maybe use Widget::InitParams::mus_properties in cash too crbug.com/750334) window->SetProperty<int>(ash::kShelfItemTypeKey, ash::TYPE_APP); // Windows created by IME extension should be treated the same way as the
diff --git a/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc index 8578b72f..ddb402d 100644 --- a/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc
@@ -24,7 +24,6 @@ #include "ash/wm/tablet_mode/tablet_mode_window_manager.h" #include "ash/wm/window_state.h" #include "ash/wm/wm_event.h" -#include "ash/ws/window_lookup.h" #include "base/bind.h" #include "base/compiler_specific.h" #include "base/logging.h"
diff --git a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc new file mode 100644 index 0000000..87d9b02f --- /dev/null +++ b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
@@ -0,0 +1,123 @@ +// 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 "ash/public/cpp/ash_pref_names.h" +#include "ash/public/cpp/shell_window_ids.h" +#include "ash/rotator/screen_rotation_animator.h" +#include "ash/rotator/screen_rotation_animator_observer.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/ash/tablet_mode_client_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/interactive_test_utils.h" +#include "chrome/test/base/perf/performance_test.h" +#include "ui/aura/window.h" +#include "ui/base/test/ui_controls.h" + +// Test overview enter/exit animations with following conditions +// int: number of windows : 2, 8 +// bool: the tab content (chrome://blank, chrome://newtab) +class ScreenRotationTest + : public UIPerformanceTest, + public testing::WithParamInterface<::testing::tuple<int, bool>> { + public: + ScreenRotationTest() = default; + ~ScreenRotationTest() override = default; + + // UIPerformanceTest: + void SetUpOnMainThread() override { + UIPerformanceTest::SetUpOnMainThread(); + test::SetAndWaitForTabletMode(true); + auto* pref = browser()->profile()->GetPrefs(); + pref->SetBoolean( + ash::prefs::kDisplayRotationAcceleratorDialogHasBeenAccepted, true); + + int additional_browsers = std::get<0>(GetParam()) - 1; + ntp_page_ = std::get<1>(GetParam()); + + GURL ntp_url("chrome://newtab"); + // The default is blank page. + if (ntp_page_) + ui_test_utils::NavigateToURL(browser(), ntp_url); + + for (int i = additional_browsers; i > 0; i--) { + Browser* new_browser = CreateBrowser(browser()->profile()); + if (ntp_page_) + ui_test_utils::NavigateToURL(new_browser, ntp_url); + } + + float cost_per_browser = ntp_page_ ? 0.5 : 0.1; + int wait_seconds = (base::SysInfo::IsRunningOnChromeOS() ? 5 : 0) + + additional_browsers * cost_per_browser; + base::RunLoop run_loop; + + base::PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromSeconds(wait_seconds)); + run_loop.Run(); + } + + // UIPerformanceTest: + std::vector<std::string> GetUMAHistogramNames() const override { + return {"Ash.Rotation.AnimationSmoothness"}; + } + + bool ntp_page() const { return ntp_page_; } + + private: + bool ntp_page_ = false; + + DISALLOW_COPY_AND_ASSIGN(ScreenRotationTest); +}; + +class ScreenRotationWaiter : public ash::ScreenRotationAnimatorObserver { + public: + explicit ScreenRotationWaiter(aura::Window* root_window) + : animator_(ash::ScreenRotationAnimator::GetForRootWindow(root_window)) { + animator_->AddObserver(this); + } + ~ScreenRotationWaiter() override { animator_->RemoveObserver(this); } + + // ash::ScreenRotationAnimationObserver: + void OnScreenCopiedBeforeRotation() override {} + void OnScreenRotationAnimationFinished(ash::ScreenRotationAnimator* animator, + bool canceled) override { + run_loop_.Quit(); + } + + void Wait() { run_loop_.Run(); } + + private: + base::RunLoop run_loop_; + ash::ScreenRotationAnimator* animator_; + + DISALLOW_COPY_AND_ASSIGN(ScreenRotationWaiter); +}; + +IN_PROC_BROWSER_TEST_P(ScreenRotationTest, RotateInTable) { + // Browser window is used just to identify display. + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + gfx::NativeWindow browser_window = + browser_view->GetWidget()->GetNativeWindow(); + + ScreenRotationWaiter waiter(browser_window->GetRootWindow()); + + ui_controls::SendKeyPress(browser_window, ui::VKEY_BROWSER_REFRESH, + /*control=*/true, + /*shift=*/true, + /*alt=*/false, + /*command=*/false); + waiter.Wait(); +} + +// TODO(oshma): Support split screen in tablet mode. +// TODO(oshma): Support overview mode. + +INSTANTIATE_TEST_SUITE_P(, + ScreenRotationTest, + ::testing::Combine(::testing::Values(2, 8), + /*blank=*/testing::Bool()));
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.cc b/chrome/browser/ui/ash/wallpaper_controller_client.cc index 9f1280b..026caed 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client.cc
@@ -530,11 +530,11 @@ void WallpaperControllerClient::OnReadyToSetWallpaper() { // Apply device customization. - namespace util = chromeos::customization_wallpaper_util; - if (util::ShouldUseCustomizedDefaultWallpaper()) { + namespace customization_util = chromeos::customization_wallpaper_util; + if (customization_util::ShouldUseCustomizedDefaultWallpaper()) { base::FilePath customized_default_small_path; base::FilePath customized_default_large_path; - if (util::GetCustomizedDefaultWallpaperPaths( + if (customization_util::GetCustomizedDefaultWallpaperPaths( &customized_default_small_path, &customized_default_large_path)) { wallpaper_controller_->SetCustomizedDefaultWallpaperPaths( customized_default_small_path, customized_default_large_path);
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.cc b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.cc new file mode 100644 index 0000000..0e7deaf --- /dev/null +++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.cc
@@ -0,0 +1,59 @@ +// 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/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h" + +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" +#include "chrome/grit/generated_resources.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" +#include "components/send_tab_to_self/send_tab_to_self_sync_service.h" +#include "components/send_tab_to_self/target_device_info.h" + +namespace send_tab_to_self { + +SendTabToSelfSubMenuModel::SendTabToSelfSubMenuModel(Profile* profile) + : ui::SimpleMenuModel(this) { + Build(profile); +} + +SendTabToSelfSubMenuModel::~SendTabToSelfSubMenuModel() {} + +bool SendTabToSelfSubMenuModel::IsCommandIdEnabled(int command_id) const { + // Only valid device names are shown, so all items are enabled. + return true; +} + +void SendTabToSelfSubMenuModel::ExecuteCommand(int command_id, + int event_flags) { + // TODO(crbug/959060): handle click action. + if (command_id == IDC_SEND_TAB_TO_SELF) { + NOTIMPLEMENTED(); + } else if (command_id == IDC_CONTENT_LINK_SEND_TAB_TO_SELF) { + NOTIMPLEMENTED(); + } + return; +} + +void SendTabToSelfSubMenuModel::Build(Profile* profile) { + send_tab_to_self::SendTabToSelfSyncService* service = + SendTabToSelfSyncServiceFactory::GetForProfile(profile); + DCHECK(service); + send_tab_to_self::SendTabToSelfModel* model = + service->GetSendTabToSelfModel(); + DCHECK(model); + std::map<std::string, send_tab_to_self::TargetDeviceInfo> map = + model->GetTargetDeviceNameToCacheInfoMap(); + if (!map.empty()) { + for (const auto& item : map) { + AddItem(IDC_SEND_TAB_TO_SELF, base::UTF8ToUTF16(item.first)); + } + } + return; +} + +} // namespace send_tab_to_self
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h new file mode 100644 index 0000000..82f64a5 --- /dev/null +++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h
@@ -0,0 +1,37 @@ +// 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_UI_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SUB_MENU_MODEL_H_ +#define CHROME_BROWSER_UI_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SUB_MENU_MODEL_H_ + +// This is the secondary menu model of send tab to self context menu item. This +// menu contains the imformation of valid devices, getting form +// SendTabToSelfModel. Every item of this menu is a valid device. + +#include "base/macros.h" +#include "ui/base/models/simple_menu_model.h" + +class Profile; + +namespace send_tab_to_self { + +class SendTabToSelfSubMenuModel : public ui::SimpleMenuModel, + public ui::SimpleMenuModel::Delegate { + public: + explicit SendTabToSelfSubMenuModel(Profile* profile); + ~SendTabToSelfSubMenuModel() override; + + // Overridden from ui::SimpleMenuModel::Delegate: + bool IsCommandIdEnabled(int command_id) const override; + void ExecuteCommand(int command_id, int event_flags) override; + + private: + void Build(Profile* profile); + + DISALLOW_COPY_AND_ASSIGN(SendTabToSelfSubMenuModel); +}; + +} // namespace send_tab_to_self + +#endif // CHROME_BROWSER_UI_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SUB_MENU_MODEL_H_
diff --git a/chrome/browser/ui/tabs/tab_menu_model.cc b/chrome/browser/ui/tabs/tab_menu_model.cc index b0a93f8..c647cde 100644 --- a/chrome/browser/ui/tabs/tab_menu_model.cc +++ b/chrome/browser/ui/tabs/tab_menu_model.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.h" #include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" -#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h" #include "chrome/browser/ui/tabs/existing_tab_group_sub_menu_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" @@ -82,16 +82,20 @@ IDS_TAB_CXMENU_SOUND_MUTE_SITE, num_affected_tabs) : l10n_util::GetPluralStringFUTF16( IDS_TAB_CXMENU_SOUND_UNMUTE_SITE, num_affected_tabs)); - if (send_tab_to_self::ShouldOfferFeature( tab_strip->GetWebContentsAt(index))) { send_tab_to_self::RecordSendTabToSelfClickResult( send_tab_to_self::kTabMenu, SendTabToSelfClickResult::kShowItem); AddSeparator(ui::NORMAL_SEPARATOR); - AddItemWithStringIdAndIcon(TabStripModel::CommandSendTabToSelf, - IDS_CONTEXT_MENU_SEND_TAB_TO_SELF, - *send_tab_to_self::GetImageSkia()); + send_tab_to_self_sub_menu_model_ = + std::make_unique<send_tab_to_self::SendTabToSelfSubMenuModel>( + tab_strip->profile()); + AddSubMenuWithStringIdAndIcon(TabStripModel::CommandSendTabToSelf, + IDS_CONTEXT_MENU_SEND_TAB_TO_SELF, + send_tab_to_self_sub_menu_model_.get(), + *send_tab_to_self::GetImageSkia()); } + AddSeparator(ui::NORMAL_SEPARATOR); AddItem(TabStripModel::CommandCloseTab, l10n_util::GetPluralStringFUTF16(IDS_TAB_CXMENU_CLOSETAB,
diff --git a/chrome/browser/ui/tabs/tab_menu_model.h b/chrome/browser/ui/tabs/tab_menu_model.h index fd7c13a..dd80b59 100644 --- a/chrome/browser/ui/tabs/tab_menu_model.h +++ b/chrome/browser/ui/tabs/tab_menu_model.h
@@ -10,6 +10,10 @@ class TabStripModel; +namespace send_tab_to_self { +class SendTabToSelfSubMenuModel; +} + // A menu model that builds the contents of the tab context menu. To make sure // the menu reflects the real state of the tab a new TabMenuModel should be // created each time the menu is shown. @@ -25,6 +29,10 @@ std::unique_ptr<ui::SimpleMenuModel> add_to_existing_group_submenu_; + // Send tab to self submenu. + std::unique_ptr<send_tab_to_self::SendTabToSelfSubMenuModel> + send_tab_to_self_sub_menu_model_; + DISALLOW_COPY_AND_ASSIGN(TabMenuModel); };
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index dba8515..95197ac 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -33,13 +33,7 @@ #include "chrome/common/extensions/extension_constants.h" #include "components/session_manager/core/session_manager.h" #include "extensions/common/constants.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/window_manager.mojom.h" #include "ui/aura/client/aura_constants.h" -#include "ui/aura/mus/property_converter.h" -#include "ui/aura/mus/window_mus.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/aura/mus/window_tree_host_mus.h" #include "ui/aura/window.h" #include "ui/base/hit_test.h" #include "ui/base/models/simple_menu_model.h" @@ -51,7 +45,6 @@ #include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/webview/webview.h" -#include "ui/views/mus/mus_client.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/coordinate_conversion.h" @@ -148,27 +141,6 @@ DCHECK_EQ(ui::SHOW_STATE_DEFAULT, init_params->show_state); init_params->show_state = ui::SHOW_STATE_MAXIMIZED; } - - if (HasFrameColor()) { - init_params - ->mus_properties[ws::mojom::WindowManager::kFrameActiveColor_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int64_t>(ActiveFrameColor())); - init_params->mus_properties - [ws::mojom::WindowManager::kFrameInactiveColor_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int64_t>(InactiveFrameColor())); - } - init_params - ->mus_properties[ws::mojom::WindowManager::kShelfItemType_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int64_t>(ash::TYPE_APP)); - init_params - ->mus_properties[ws::mojom::WindowManager::kWindowTitleShown_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(static_cast<int64_t>(false)); - init_params->mus_properties[ash::mojom::kAppType_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int64_t>(ash::AppType::CHROME_APP)); } views::NonClientFrameView*
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index bcf011c..a7734a6e 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -71,6 +71,21 @@ autofill::AutofillPopupBaseView::GetCornerRadius(); } +// Builds a column set for |layout| used in the autofill dropdown. +void BuildColumnSet(views::GridLayout* layout) { + views::ColumnSet* column_set = layout->AddColumnSet(0); + const int column_divider = ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_RELATED_LABEL_HORIZONTAL_LIST); + + column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, + views::GridLayout::kFixedSize, + views::GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(views::GridLayout::kFixedSize, column_divider); + column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, + views::GridLayout::kFixedSize, + views::GridLayout::USE_PREF, 0, 0); +} + } // namespace namespace autofill { @@ -180,7 +195,6 @@ int GetPrimaryTextStyle() override; gfx::Font::Weight GetPrimaryTextWeight() const override; std::unique_ptr<views::View> CreateSubtextLabel() override; - std::unique_ptr<views::View> CreateDescriptionLabel() override; AutofillPopupSuggestionView(AutofillPopupViewNativeViews* popup_view, int line_number, int frontend_id); @@ -370,7 +384,7 @@ views::BoxLayout::kHorizontal, gfx::Insets(0, GetHorizontalMargin()))); layout_manager->set_cross_axis_alignment( - views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_STRETCH); + views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER); const gfx::ImageSkia icon = controller->layout_model().GetIconImage(line_number_); @@ -383,36 +397,32 @@ auto lower_value_label = CreateSubtextLabel(); auto value_label = CreateValueLabel(); + auto description_label = CreateDescriptionLabel(); + + std::unique_ptr<views::View> all_labels = std::make_unique<views::View>(); + views::GridLayout* grid_layout = all_labels->SetLayoutManager( + std::make_unique<views::GridLayout>(all_labels.get())); + BuildColumnSet(grid_layout); + grid_layout->StartRow(0, 0); + grid_layout->AddView(value_label.release()); + if (description_label) + grid_layout->AddView(description_label.release()); + else + grid_layout->SkipColumns(1); const int kStandardRowHeight = views::MenuConfig::instance().touchable_menu_height; - - if (!lower_value_label) { - layout_manager->set_minimum_cross_axis_size(kStandardRowHeight); - AddChildView(std::move(value_label)); - } else { + if (lower_value_label) { layout_manager->set_minimum_cross_axis_size( kStandardRowHeight + kAutofillPopupAdditionalDoubleRowHeight); - auto values_container = std::make_unique<views::View>(); - auto* vertical_layout = - values_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), - kAdjacentLabelsVerticalSpacing)); - vertical_layout->set_main_axis_alignment( - views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER); - vertical_layout->set_cross_axis_alignment( - views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); - values_container->AddChildView(std::move(value_label)); - values_container->AddChildView(std::move(lower_value_label)); - AddChildView(std::move(values_container)); + grid_layout->StartRowWithPadding(0, 0, 0, kAdjacentLabelsVerticalSpacing); + grid_layout->AddView(lower_value_label.release()); + grid_layout->SkipColumns(1); + } else { + layout_manager->set_minimum_cross_axis_size(kStandardRowHeight); } - auto description_label = CreateDescriptionLabel(); - if (description_label) { - AddSpacerWithSize(AutofillPopupBaseView::kValueLabelPadding, - /*resize=*/true, layout_manager); - AddChildView(std::move(description_label)); - } + AddChildView(std::move(all_labels)); } void AutofillPopupItemView::RefreshStyle() { @@ -448,9 +458,7 @@ } std::unique_ptr<views::View> AutofillPopupItemView::CreateDescriptionLabel() { - base::string16 text = - popup_view_->controller()->GetElidedLabelAt(line_number_); - return text.empty() ? nullptr : CreateSecondaryLabel(text); + return nullptr; } std::unique_ptr<views::Label> AutofillPopupItemView::CreateSecondaryLabel( @@ -524,11 +532,6 @@ SetFocusBehavior(FocusBehavior::ALWAYS); } -std::unique_ptr<views::View> -AutofillPopupSuggestionView::CreateDescriptionLabel() { - return nullptr; -} - std::unique_ptr<views::View> AutofillPopupSuggestionView::CreateSubtextLabel() { base::string16 label_text = popup_view_->controller()->GetSuggestionAt(line_number_).additional_label; @@ -560,38 +563,23 @@ } std::unique_ptr<views::View> PasswordPopupSuggestionView::CreateSubtextLabel() { - base::string16 text_to_use; - if (!origin_.empty()) { - // Always use the origin if it's available. - text_to_use = origin_; - } else { - // Otherwise, the masked password can be used. - text_to_use = masked_password_; - } - - if (text_to_use.empty()) - return nullptr; - - auto label = CreateSecondaryLabel(text_to_use); - label->SetElideBehavior(gfx::ELIDE_HEAD); - return std::make_unique<ConstrainedWidthView>(std::move(label), - kAutofillPopupUsernameMaxWidth); -} - -std::unique_ptr<views::View> -PasswordPopupSuggestionView::CreateDescriptionLabel() { - // When no origin text is available, the masked password will be used in the - // subtext label, so it should not be reused here. - if (origin_.empty() || masked_password_.empty()) { - return nullptr; - } - auto label = CreateSecondaryLabel(masked_password_); label->SetElideBehavior(gfx::TRUNCATE); return std::make_unique<ConstrainedWidthView>(std::move(label), kAutofillPopupPasswordMaxWidth); } +std::unique_ptr<views::View> +PasswordPopupSuggestionView::CreateDescriptionLabel() { + if (origin_.empty()) + return nullptr; + + auto label = CreateSecondaryLabel(origin_); + label->SetElideBehavior(gfx::ELIDE_HEAD); + return std::make_unique<ConstrainedWidthView>(std::move(label), + kAutofillPopupUsernameMaxWidth); +} + gfx::Font::Weight PasswordPopupSuggestionView::GetPrimaryTextWeight() const { return gfx::Font::Weight::NORMAL; } @@ -662,11 +650,6 @@ AddSpacerWithSize(AutofillPopupBaseView::kValueLabelPadding, /*resize=*/true, layout_manager); - auto description_label = CreateDescriptionLabel(); - if (description_label) { - AddChildView(std::move(description_label)); - } - if (!icon.isNull() && !use_leading_icon) { AddSpacerWithSize(GetHorizontalMargin(), /*resize=*/false, layout_manager); AddIcon(icon);
diff --git a/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc b/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc index f78f613..c4a5cc9 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc
@@ -7,10 +7,7 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/window_manager.mojom.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/ui_base_features.h" #include "ui/chromeos/devicetype_utils.h" #include "ui/display/screen.h" #include "ui/strings/grit/ui_strings.h" @@ -32,20 +29,8 @@ // static void CrostiniAppRestartView::Show(const ash::ShelfID& id, int64_t display_id) { CrostiniAppRestartView* view = new CrostiniAppRestartView(id, display_id); - if (features::IsUsingWindowService()) { - // TODO(mash): Simplify specifying |display_id| via CreateDialogWidget, etc. - views::Widget* widget = new views::Widget; - views::Widget::InitParams params = - views::DialogDelegate::GetDialogWidgetInitParams(view, nullptr, nullptr, - gfx::Rect()); - params.mus_properties[ws::mojom::WindowManager::kDisplayId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(display_id); - widget->Init(params); - } else { - // TODO(timzheng): Remove this after single process mash is enabled. - views::DialogDelegate::CreateDialogWidget( - view, GetNativeWindowFromDisplayId(display_id), nullptr); - } + views::DialogDelegate::CreateDialogWidget( + view, GetNativeWindowFromDisplayId(display_id), nullptr); view->GetWidget()->Show(); chrome::RecordDialogCreation(chrome::DialogIdentifier::CROSTINI_APP_RESTART); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index c2dbad9..e6020bcc 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" #include "chrome/browser/ui/omnibox/clipboard_utils.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" +#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -66,6 +67,7 @@ #include "ui/gfx/font_list.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/presentation_feedback.h" #include "ui/gfx/selection_model.h" #include "ui/gfx/text_elider.h" #include "ui/gfx/text_utils.h" @@ -449,9 +451,25 @@ void OmniboxViewViews::OnPaint(gfx::Canvas* canvas) { if (latency_histogram_state_ == CHAR_TYPED) { DCHECK(!insert_char_time_.is_null()); + auto now = base::TimeTicks::Now(); UMA_HISTOGRAM_TIMES("Omnibox.CharTypedToRepaintLatency.ToPaint", - base::TimeTicks::Now() - insert_char_time_); + now - insert_char_time_); latency_histogram_state_ = ON_PAINT_CALLED; + GetWidget()->GetCompositor()->RequestPresentationTimeForNextFrame( + base::BindOnce( + [](base::TimeTicks insert_timestamp, + base::TimeTicks paint_timestamp, + const gfx::PresentationFeedback& feedback) { + if (feedback.flags & gfx::PresentationFeedback::kFailure) + return; + UMA_HISTOGRAM_TIMES( + "Omnibox.CharTypedToRepaintLatency.PaintToPresent", + feedback.timestamp - paint_timestamp); + UMA_HISTOGRAM_TIMES( + "Omnibox.CharTypedToRepaintLatency.InsertToPresent", + feedback.timestamp - insert_timestamp); + }, + insert_char_time_, now)); } { @@ -1731,10 +1749,13 @@ // Add a separator if this is not the first item. if (index) menu_contents->InsertSeparatorAt(index++, ui::NORMAL_SEPARATOR); - menu_contents->InsertItemWithStringIdAt(index, IDC_SEND_TAB_TO_SELF, - IDS_CONTEXT_MENU_SEND_TAB_TO_SELF); - menu_contents->SetIcon(index, - gfx::Image(*send_tab_to_self::GetImageSkia())); + send_tab_to_self_sub_menu_model_ = + std::make_unique<send_tab_to_self::SendTabToSelfSubMenuModel>( + location_bar_view_->profile()); + menu_contents->AddSubMenuWithStringIdAndIcon( + IDC_SEND_TAB_TO_SELF, IDS_CONTEXT_MENU_SEND_TAB_TO_SELF, + send_tab_to_self_sub_menu_model_.get(), + *send_tab_to_self::GetImageSkia()); menu_contents->InsertSeparatorAt(++index, ui::NORMAL_SEPARATOR); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index 6718177..2a028e9 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -40,6 +40,10 @@ class RenderText; } +namespace send_tab_to_self { +class SendTabToSelfSubMenuModel; +} + namespace ui { class OSExchangeData; } // namespace ui @@ -363,6 +367,10 @@ ScopedObserver<TemplateURLService, TemplateURLServiceObserver> scoped_template_url_service_observer_; + // Send tab to self submenu. + std::unique_ptr<send_tab_to_self::SendTabToSelfSubMenuModel> + send_tab_to_self_sub_menu_model_; + DISALLOW_COPY_AND_ASSIGN(OmniboxViewViews); };
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc index 9feef564..c7edef7 100644 --- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc +++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -30,13 +30,7 @@ #endif #if defined(OS_CHROMEOS) -#include "ash/shell.h" // mash-ok -#include "mojo/public/cpp/bindings/type_converter.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/window_manager.mojom.h" -#include "ui/base/ui_base_features.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" +#include "ash/shell.h" #endif namespace { @@ -209,14 +203,7 @@ // TODO(sergeyu): The notification bar must be shown on the monitor that's // being captured. Make sure it's always the case. Currently we always capture // the primary monitor. - if (!features::IsUsingWindowService()) { - params.context = ash::Shell::GetPrimaryRootWindow(); - } else { - const display::Display primary_display = - display::Screen::GetScreen()->GetPrimaryDisplay(); - params.mus_properties[ws::mojom::WindowManager::kDisplayId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(primary_display.id()); - } + params.context = ash::Shell::GetPrimaryRootWindow(); #endif widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc index 04c58fc..dec9744 100644 --- a/chrome/browser/ui/views/status_bubble_views.cc +++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -46,8 +46,6 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/window_properties.h" -#include "ash/public/interfaces/window_properties.mojom.h" -#include "services/ws/public/cpp/property_type_converters.h" #include "ui/aura/window.h" #endif @@ -689,10 +687,6 @@ params.parent = frame->GetNativeView(); params.context = frame->GetNativeWindow(); params.name = "StatusBubble"; -#if defined(OS_CHROMEOS) - params.mus_properties[ash::mojom::kHideInOverview_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(true); -#endif popup_->Init(params); // We do our own animation and don't want any from the system. popup_->SetVisibilityChangedAnimationsEnabled(false);
diff --git a/chrome/browser/ui/views/tabs/window_finder_chromeos.cc b/chrome/browser/ui/views/tabs/window_finder_chromeos.cc index f73302e..d52f0267 100644 --- a/chrome/browser/ui/views/tabs/window_finder_chromeos.cc +++ b/chrome/browser/ui/views/tabs/window_finder_chromeos.cc
@@ -4,20 +4,16 @@ #include "chrome/browser/ui/views/tabs/window_finder.h" -#include "ash/wm/window_finder.h" // mash-ok -#include "ui/aura/mus/topmost_window_tracker.h" -#include "ui/aura/mus/window_tree_client.h" +#include "ash/wm/window_finder.h" #include "ui/aura/window.h" -#include "ui/base/ui_base_features.h" -#include "ui/views/mus/mus_client.h" namespace { // The class to be used by ash to find an eligible chrome window that we can // attach the dragged tabs into. -class WindowFinderClassic : public WindowFinder { +class AshWindowFinder : public WindowFinder { public: - WindowFinderClassic() {} + AshWindowFinder() = default; gfx::NativeWindow GetLocalProcessWindowAtPoint( const gfx::Point& screen_point, @@ -26,45 +22,7 @@ } private: - DISALLOW_COPY_AND_ASSIGN(WindowFinderClassic); -}; - -// The class to be used by mash to find an eligible chrome window that we can -// attach the dragged tabs into. -class WindowFinderMus : public WindowFinder { - public: - WindowFinderMus(TabDragController::EventSource event_source, - gfx::NativeWindow window) { - ws::mojom::MoveLoopSource source = - (event_source == TabDragController::EVENT_SOURCE_MOUSE) - ? ws::mojom::MoveLoopSource::MOUSE - : ws::mojom::MoveLoopSource::TOUCH; - tracker_ = views::MusClient::Get() - ->window_tree_client() - ->StartObservingTopmostWindow(source, window); - } - - gfx::NativeWindow GetLocalProcessWindowAtPoint( - const gfx::Point& screen_point, - const std::set<gfx::NativeWindow>& ignore) override { - DCHECK_LE(ignore.size(), 1u); - aura::Window* window = tracker_->GetTopmost(); - if (ignore.find(window) != ignore.end()) - window = tracker_->GetSecondTopmost(); - if (ignore.find(window) != ignore.end()) - window = nullptr; - if (!window) - return nullptr; - views::Widget* widget = views::Widget::GetWidgetForNativeView(window); - if (!widget) - return nullptr; - return widget->GetNativeWindow(); - } - - private: - std::unique_ptr<aura::TopmostWindowTracker> tracker_; - - DISALLOW_COPY_AND_ASSIGN(WindowFinderMus); + DISALLOW_COPY_AND_ASSIGN(AshWindowFinder); }; } // namespace @@ -72,9 +30,7 @@ std::unique_ptr<WindowFinder> WindowFinder::Create( TabDragController::EventSource source, gfx::NativeWindow window) { - if (features::IsUsingWindowService()) - return std::make_unique<WindowFinderMus>(source, window); - return std::make_unique<WindowFinderClassic>(); + return std::make_unique<AshWindowFinder>(); } gfx::NativeWindow WindowFinder::GetLocalProcessWindowAtPoint(
diff --git a/chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc b/chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc index ac0d181..36a8e45e 100644 --- a/chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc +++ b/chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc
@@ -19,11 +19,9 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power/power_policy_controller.h" #include "chromeos/network/network_handler.h" -#include "content/public/browser/gpu_interface_provider_factory.h" #include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "ui/aura/env.h" #include "ui/aura/window_tree_host.h" -#include "ui/base/ui_base_features.h" #include "ui/display/display_switches.h" #include "ui/wm/core/wm_state.h" @@ -63,18 +61,12 @@ chromeos::CrasAudioHandler::InitializeForTesting(); chromeos::NetworkHandler::Initialize(); - env_ = aura::Env::CreateInstance(features::IsSingleProcessMash() - ? aura::Env::Mode::MUS - : aura::Env::Mode::LOCAL); + env_ = aura::Env::CreateInstance(); ash::ShellInitParams init_params; init_params.delegate = std::make_unique<ash::TestShellDelegate>(); init_params.context_factory = context_factory; init_params.context_factory_private = context_factory_private; - init_params.gpu_interface_provider = content::CreateGpuInterfaceProvider(); - if (!features::IsUsingWindowService()) { - init_params.keyboard_ui_factory = - std::make_unique<ChromeKeyboardUIFactory>(); - } + init_params.keyboard_ui_factory = std::make_unique<ChromeKeyboardUIFactory>(); base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kHostWindowBounds, "0+0-1280x800"); ash::Shell::CreateInstance(std::move(init_params));
diff --git a/chrome/browser/ui/views/touch_selection_menu_chromeos.cc b/chrome/browser/ui/views/touch_selection_menu_chromeos.cc index 9fed934..ffc9d189 100644 --- a/chrome/browser/ui/views/touch_selection_menu_chromeos.cc +++ b/chrome/browser/ui/views/touch_selection_menu_chromeos.cc
@@ -12,9 +12,6 @@ #include "chrome/browser/ui/views/touch_selection_menu_runner_chromeos.h" #include "components/arc/arc_service_manager.h" #include "components/arc/session/arc_bridge_service.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/window_manager.mojom.h" -#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/gfx/image/image_skia.h" @@ -33,10 +30,7 @@ ui::TouchSelectionMenuClient* client, aura::Window* context, arc::mojom::TextSelectionActionPtr action) - : views::TouchSelectionMenuViews( - owner, - client, - features::IsUsingWindowService() ? nullptr : context), + : views::TouchSelectionMenuViews(owner, client, context), action_(std::move(action)), display_id_( display::Screen::GetScreen()->GetDisplayNearestWindow(context).id()) { @@ -99,8 +93,6 @@ views::Widget* widget) const { ash_util::SetupWidgetInitParamsForContainer( params, ash::kShellWindowId_SettingBubbleContainer); - params->mus_properties[ws::mojom::WindowManager::kDisplayId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(display_id_); } TouchSelectionMenuChromeOS::~TouchSelectionMenuChromeOS() = default;
diff --git a/chrome/browser/ui/webui/browser_switcher/OWNERS b/chrome/browser/ui/webui/browser_switch/OWNERS similarity index 100% rename from chrome/browser/ui/webui/browser_switcher/OWNERS rename to chrome/browser/ui/webui/browser_switch/OWNERS
diff --git a/chrome/browser/ui/webui/browser_switcher/browser_switch_ui.cc b/chrome/browser/ui/webui/browser_switch/browser_switch_ui.cc similarity index 89% rename from chrome/browser/ui/webui/browser_switcher/browser_switch_ui.cc rename to chrome/browser/ui/webui/browser_switch/browser_switch_ui.cc index ef8dfacd..b0b0457 100644 --- a/chrome/browser/ui/webui/browser_switcher/browser_switch_ui.cc +++ b/chrome/browser/ui/webui/browser_switch/browser_switch_ui.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/ui/webui/browser_switcher/browser_switch_ui.h" +#include "chrome/browser/ui/webui/browser_switch/browser_switch_ui.h" #include <memory> @@ -131,23 +131,22 @@ IDS_ABOUT_BROWSER_SWITCH_PROTOCOL_ERROR); source->AddLocalizedString("title", IDS_ABOUT_BROWSER_SWITCH_TITLE); - source->AddResourcePath("app.html", IDR_BROWSER_SWITCHER_APP_HTML); - source->AddResourcePath("app.js", IDR_BROWSER_SWITCHER_APP_JS); - source->AddResourcePath("browser_switch.html", - IDR_BROWSER_SWITCHER_BROWSER_SWITCH_HTML); - source->AddResourcePath("browser_switcher_proxy.html", - IDR_BROWSER_SWITCHER_BROWSER_SWITCHER_PROXY_HTML); - source->AddResourcePath("browser_switcher_proxy.js", - IDR_BROWSER_SWITCHER_BROWSER_SWITCHER_PROXY_JS); - source->SetDefaultResource(IDR_BROWSER_SWITCHER_BROWSER_SWITCH_HTML); + source->AddResourcePath("app.html", IDR_BROWSER_SWITCH_APP_HTML); + source->AddResourcePath("app.js", IDR_BROWSER_SWITCH_APP_JS); + source->AddResourcePath("browser_switch.html", IDR_BROWSER_SWITCH_HTML); + source->AddResourcePath("browser_switch_proxy.html", + IDR_BROWSER_SWITCH_PROXY_HTML); + source->AddResourcePath("browser_switch_proxy.js", + IDR_BROWSER_SWITCH_PROXY_JS); + source->SetDefaultResource(IDR_BROWSER_SWITCH_HTML); // Setup chrome://browser-switch/internals debug UI. - source->AddResourcePath("internals/browser_switcher_internals.js", - IDR_BROWSER_SWITCHER_INTERNALS_JS); - source->AddResourcePath("internals/browser_switcher_internals.html", - IDR_BROWSER_SWITCHER_INTERNALS_HTML); - source->AddResourcePath("internals/", IDR_BROWSER_SWITCHER_INTERNALS_HTML); - source->AddResourcePath("internals", IDR_BROWSER_SWITCHER_INTERNALS_HTML); + source->AddResourcePath("internals/browser_switch_internals.js", + IDR_BROWSER_SWITCH_INTERNALS_JS); + source->AddResourcePath("internals/browser_switch_internals.html", + IDR_BROWSER_SWITCH_INTERNALS_HTML); + source->AddResourcePath("internals/", IDR_BROWSER_SWITCH_INTERNALS_HTML); + source->AddResourcePath("internals", IDR_BROWSER_SWITCH_INTERNALS_HTML); source->SetJsonPath("strings.js");
diff --git a/chrome/browser/ui/webui/browser_switcher/browser_switch_ui.h b/chrome/browser/ui/webui/browser_switch/browser_switch_ui.h similarity index 66% rename from chrome/browser/ui/webui/browser_switcher/browser_switch_ui.h rename to chrome/browser/ui/webui/browser_switch/browser_switch_ui.h index 25464bb84..ee9dc5c 100644 --- a/chrome/browser/ui/webui/browser_switcher/browser_switch_ui.h +++ b/chrome/browser/ui/webui/browser_switch/browser_switch_ui.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_BROWSER_SWITCHER_BROWSER_SWITCH_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_BROWSER_SWITCHER_BROWSER_SWITCH_UI_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_BROWSER_SWITCH_BROWSER_SWITCH_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_BROWSER_SWITCH_BROWSER_SWITCH_UI_H_ #include "base/macros.h" #include "content/public/browser/web_ui_controller.h" @@ -16,4 +16,4 @@ DISALLOW_COPY_AND_ASSIGN(BrowserSwitchUI); }; -#endif // CHROME_BROWSER_UI_WEBUI_BROWSER_SWITCHER_BROWSER_SWITCH_UI_H_ +#endif // CHROME_BROWSER_UI_WEBUI_BROWSER_SWITCH_BROWSER_SWITCH_UI_H_
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index c89eb5b..563b0888 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -119,7 +119,6 @@ #endif #if defined(OS_ANDROID) -#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h" #include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals_ui.h" #include "chrome/browser/ui/webui/offline/offline_internals_ui.h" #include "chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h" @@ -187,7 +186,7 @@ #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) #include "chrome/browser/ui/sync/sync_promo_ui.h" -#include "chrome/browser/ui/webui/browser_switcher/browser_switch_ui.h" +#include "chrome/browser/ui/webui/browser_switch/browser_switch_ui.h" #include "chrome/browser/ui/webui/signin/inline_login_ui.h" #include "chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h" #include "chrome/browser/ui/webui/signin/signin_error_ui.h" @@ -557,9 +556,6 @@ #endif // !defined(OFFICIAL_BUILD) #endif // defined(OS_CHROMEOS) #if defined(OS_ANDROID) - if (url.host_piece() == chrome::kChromeUIEocInternalsHost && - !profile->IsOffTheRecord()) - return &NewWebUI<EocInternalsUI>; if (url.host_piece() == chrome::kChromeUIExploreSitesInternalsHost && !profile->IsOffTheRecord()) return &NewWebUI<explore_sites::ExploreSitesInternalsUI>;
diff --git a/chrome/browser/ui/webui/eoc_internals/BUILD.gn b/chrome/browser/ui/webui/chromeos/add_supervision/BUILD.gn similarity index 68% rename from chrome/browser/ui/webui/eoc_internals/BUILD.gn rename to chrome/browser/ui/webui/chromeos/add_supervision/BUILD.gn index b00810f..54b63f6b 100644 --- a/chrome/browser/ui/webui/eoc_internals/BUILD.gn +++ b/chrome/browser/ui/webui/chromeos/add_supervision/BUILD.gn
@@ -1,4 +1,4 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. +# 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. @@ -6,6 +6,6 @@ mojom("mojo_bindings") { sources = [ - "eoc_internals.mojom", + "add_supervision.mojom", ] }
diff --git a/chrome/browser/ui/webui/eoc_internals/OWNERS b/chrome/browser/ui/webui/chromeos/add_supervision/OWNERS similarity index 65% rename from chrome/browser/ui/webui/eoc_internals/OWNERS rename to chrome/browser/ui/webui/chromeos/add_supervision/OWNERS index 2d4c4676..08850f4 100644 --- a/chrome/browser/ui/webui/eoc_internals/OWNERS +++ b/chrome/browser/ui/webui/chromeos/add_supervision/OWNERS
@@ -1,4 +1,2 @@ -file://components/ntp_snippets/OWNERS - per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom new file mode 100644 index 0000000..784434c --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom
@@ -0,0 +1,26 @@ +// 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. + +module add_supervision.mojom; + +enum OAuthTokenFetchStatus { + OK = 0, + ERROR = 1 +}; + +// Interface that supports integration between the AddSupervision WebUI and +// ChromeOS. +interface AddSupervisionHandler { + // Triggers a logout from the current login session. + LogOut() => (); + + // Returns an array of package names of installed ARC apps. + GetInstalledArcApps() => (array<string> package_names); + + // Uninstalls the ARC apps specified by the list of package names. + UninstallArcApps(array<string> package_names) => (); + + // Returns the oauth token to be passed to the server. + GetOAuthToken() => (OAuthTokenFetchStatus status, string oauth_token); +};
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.cc new file mode 100644 index 0000000..ec4ebe0 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.cc
@@ -0,0 +1,165 @@ +// 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/ui/webui/chromeos/add_supervision/add_supervision_handler.h" + +#include <utility> + +#include "base/stl_util.h" +#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/lifetime/application_lifetime.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.h" +#include "chrome/services/app_service/public/cpp/app_registry_cache.h" +#include "chrome/services/app_service/public/cpp/app_service_proxy.h" +#include "content/public/browser/web_ui.h" +#include "google_apis/gaia/gaia_constants.h" +#include "services/identity/public/cpp/access_token_fetcher.h" +#include "services/identity/public/cpp/identity_manager.h" + +namespace { + +// Returns the Arc package name for the specified app_id, which must +// be the AppID of an ARC app. TODO(danan): this functionality is +// also needed by KioskNext, so find a way to share the same code. +std::string AppIdToArcPackageName(const std::string& app_id, Profile* profile) { + ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile); + + // This should never return null, since we use the primary user profile + // which should have ARC prefs. + DCHECK(arc_prefs) << "Unable to retrieve ArcAppListPrefs"; + + std::unique_ptr<ArcAppListPrefs::AppInfo> arc_info = + arc_prefs->GetApp(app_id); + + if (!arc_info) { + DLOG(ERROR) << "Couldn't retrieve ARC package name for AppID: " << app_id; + return std::string(); + } + return std::move(arc_info)->package_name; +} + +std::string ArcPackageNameToAppId(const std::string& package_name, + Profile* profile) { + ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile); + + // This should never return null, since we use the primary user profile + // which should have ARC prefs. + DCHECK(arc_prefs) << "Unable to retrieve ArcAppListPrefs"; + + return arc_prefs->GetAppIdByPackageName(package_name); +} + +// TODO(danan): This method should be removed once the stickyness +// attribute is available via the App Service instead. This function +// will crash if app_id isn't installed. +// (https://crbug.com/948408). +bool IsArcAppSticky(const std::string& app_id, Profile* profile) { + ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile); + + // This should never return null, since we use the primary user profile + // which should have arc prefs. + DCHECK(arc_prefs) << "Unable to retrieve ArcAppListPrefs"; + + std::unique_ptr<ArcAppListPrefs::AppInfo> arc_info = + arc_prefs->GetApp(app_id); + + DCHECK(arc_info) << "Couldn't retrieve ARC package name for AppID: " + << app_id; + return arc_info->sticky; +} + +} // namespace + +AddSupervisionHandler::AddSupervisionHandler( + add_supervision::mojom::AddSupervisionHandlerRequest request, + content::WebUI* web_ui) + : binding_(this, std::move(request)), + web_ui_(web_ui), + identity_manager_( + IdentityManagerFactory::GetForProfile(Profile::FromWebUI(web_ui))) {} + +AddSupervisionHandler::~AddSupervisionHandler() = default; + +void AddSupervisionHandler::LogOut(LogOutCallback callback) { + chrome::AttemptUserExit(); +} + +void AddSupervisionHandler::GetInstalledArcApps( + GetInstalledArcAppsCallback callback) { + Profile* profile = Profile::FromWebUI(web_ui_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile); + + std::vector<std::string> installed_arc_apps; + + proxy->AppRegistryCache().ForEachApp([&installed_arc_apps, profile]( + const apps::AppUpdate& update) { + // We don't include "sticky" ARC apps because they are system-required + // apps that should not be offered for uninstallation. + if (ShouldIncludeAppUpdate(update) && + !IsArcAppSticky(update.AppId(), profile)) { + std::string package_name = AppIdToArcPackageName(update.AppId(), profile); + if (!package_name.empty()) + installed_arc_apps.push_back(package_name); + } + }); + + std::move(callback).Run(installed_arc_apps); +} + +void AddSupervisionHandler::UninstallArcApps( + const std::vector<std::string>& package_names, + UninstallArcAppsCallback callback) { + Profile* profile = Profile::FromWebUI(web_ui_); + apps::AppServiceProxy* proxy = + apps::AppServiceProxyFactory::GetForProfile(profile); + + for (const std::string& package_name : package_names) { + proxy->AppRegistryCache().ForOneApp( + ArcPackageNameToAppId(package_name, profile), + [proxy, package_names, profile](const apps::AppUpdate& update) { + // We don't include "sticky" ARC apps because they are + // system-required apps that should not be uninstalled. + if (ShouldIncludeAppUpdate(update) && + !IsArcAppSticky(update.AppId(), profile)) { + proxy->Uninstall(update.AppId()); + } + }); + } + + std::move(callback).Run(); +} + +void AddSupervisionHandler::GetOAuthToken(GetOAuthTokenCallback callback) { + identity::ScopeSet scopes; + scopes.insert(GaiaConstants::kKidFamilyOAuth2Scope); + + oauth2_access_token_fetcher_ = + identity_manager_->CreateAccessTokenFetcherForAccount( + identity_manager_->GetPrimaryAccountId(), "add_supervision", scopes, + base::BindOnce(&AddSupervisionHandler::OnAccessTokenFetchComplete, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)), + identity::AccessTokenFetcher::Mode::kImmediate); +} + +void AddSupervisionHandler::OnAccessTokenFetchComplete( + GetOAuthTokenCallback callback, + GoogleServiceAuthError error, + identity::AccessTokenInfo access_token_info) { + oauth2_access_token_fetcher_.reset(); + if (error.state() != GoogleServiceAuthError::NONE) { + DLOG(ERROR) << "AddSupervisionHandler: OAuth2 token request failed. " + << error.state() << ": " << error.ToString(); + + std::move(callback).Run( + add_supervision::mojom::OAuthTokenFetchStatus::ERROR, ""); + + } else { + std::move(callback).Run(add_supervision::mojom::OAuthTokenFetchStatus::OK, + access_token_info.token); + } +}
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.h b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.h new file mode 100644 index 0000000..6f58d04 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.h
@@ -0,0 +1,63 @@ +// 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_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_HANDLER_H_ + +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace content { +class WebUI; +} // namespace content + +namespace identity { +class AccessTokenFetcher; +struct AccessTokenInfo; +class IdentityManager; +} // namespace identity + +class GoogleServiceAuthError; + +class AddSupervisionHandler + : public add_supervision::mojom::AddSupervisionHandler { + public: + AddSupervisionHandler( + add_supervision::mojom::AddSupervisionHandlerRequest request, + content::WebUI* web_ui); + ~AddSupervisionHandler() override; + + // add_supervision::mojom::AddSupervisionHandler overrides: + void LogOut(LogOutCallback callback) override; + void GetInstalledArcApps(GetInstalledArcAppsCallback callback) override; + void UninstallArcApps(const std::vector<std::string>& apps, + UninstallArcAppsCallback callback) override; + void GetOAuthToken(GetOAuthTokenCallback callback) override; + + private: + void OnAccessTokenFetchComplete(GetOAuthTokenCallback callback, + GoogleServiceAuthError error, + identity::AccessTokenInfo access_token_info); + + mojo::Binding<add_supervision::mojom::AddSupervisionHandler> binding_; + + // The AddSupervisionUI that this AddSupervisionHandler belongs to. + content::WebUI* web_ui_; + + // Used to fetch OAuth2 access tokens. + identity::IdentityManager* identity_manager_; + std::unique_ptr<identity::AccessTokenFetcher> oauth2_access_token_fetcher_; + + base::WeakPtrFactory<AddSupervisionHandler> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(AddSupervisionHandler); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.cc new file mode 100644 index 0000000..c5775d23 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.cc
@@ -0,0 +1,15 @@ +// 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/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.h" + +#include "chrome/services/app_service/public/cpp/app_update.h" +#include "chrome/services/app_service/public/mojom/types.mojom.h" + +bool ShouldIncludeAppUpdate(const apps::AppUpdate& app_update) { + // TODO(danan): update this to only return sticky = true arc apps when that + // attribute is available via the App Service (https://crbug.com/948408). + + return app_update.AppType() == apps::mojom::AppType::kArc; +}
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.h b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.h new file mode 100644 index 0000000..9f8c8383 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.h
@@ -0,0 +1,20 @@ +// 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_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_HANDLER_UTILS_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_HANDLER_UTILS_H_ + +#include <string> + +#include "chrome/browser/profiles/profile.h" + +namespace apps { +class AppUpdate; +} // namespace apps + +// Returns true if the app indicated by the specified AppUpdate should be +// returned to clients or uninstalled. +bool ShouldIncludeAppUpdate(const apps::AppUpdate& app_update); + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_HANDLER_UTILS_H_
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils_unittest.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils_unittest.cc new file mode 100644 index 0000000..6236a41f --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils_unittest.cc
@@ -0,0 +1,24 @@ +// 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/ui/webui/chromeos/add_supervision/add_supervision_handler_utils.h" +#include "chrome/services/app_service/public/cpp/app_update.h" +#include "testing/gtest/include/gtest/gtest.h" + +using AddSupervisionHandlerUtilsTest = testing::Test; + +// Tests that only the right apps are returned via the API. +TEST_F(AddSupervisionHandlerUtilsTest, TestShouldIncludeAppUpdate) { + // Return ARC apps. + apps::mojom::App arc_state; + arc_state.app_type = apps::mojom::AppType::kArc; + apps::AppUpdate arc_update(&arc_state, nullptr /* delta */); + EXPECT_TRUE(ShouldIncludeAppUpdate(arc_update)); + + // Don't return non-ARC apps. + apps::mojom::App non_arc_state; + non_arc_state.app_type = apps::mojom::AppType::kBuiltIn; + apps::AppUpdate non_arc_update(&non_arc_state, nullptr /* delta */); + EXPECT_FALSE(ShouldIncludeAppUpdate(non_arc_update)); +}
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom b/chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom deleted file mode 100644 index 0feaff1d..0000000 --- a/chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module eoc_internals.mojom; - -// Distillation of results from a server request for page suggestions. -struct SuggestionResult { - // The URL of the page that the suggestions are for. - string url; - - // The conditions under which the peek was displayed. - PeekConditions peek_conditions; - - // The suggestions for the page. - array<Suggestion> suggestions; -}; - -// Tracks the server-defined parameters for when to show the peek bar. -struct PeekConditions { - // A measure of confidence that auto-peek should be enabled for this response - // in the range [0, 1]. - float confidence; - - // The percentage of the page that the user scrolls required for an auto - // peek to occur. - float page_scroll_percentage; - - // The minimum time (seconds) the user spends on the page required for - // auto peek. - float minimum_seconds_on_page; - - // The maximum number of auto peeks that we can show for this page. - int64 maximum_number_of_peeks; -}; - -// Models a single suggestion. -struct Suggestion { - // The URL for the suggestion. - string url; - - // Title displayed in the suggestion sheet. - string title; - - // Name of the publisher. - string publisher_name; - - // Text snippet displayed on the sheet. - string snippet; - - // The ID of the image displayed for this suggestion. - string image_id; - - // The ID of the favicon for the suggested URL. - string favicon_image_id; -}; - -// Metrics event that was constructed for a page. -struct MetricEvent { - // The URL which the metrics event is for. - string url; - - // Did the sheet peek show. - bool sheet_peeked; - - // Was the toolbar button shown. - bool button_shown; - - // If the peek was closed without being opened. - bool sheet_opened; - - // If the sheet was opened from the peek. - bool sheet_closed; - - // If any suggestion was clicked on from the sheet. - bool any_suggestion_taken; - - // If any suggestion was downloaded from the sheet. - bool any_suggestion_downloaded; -}; - -// Browser interface for the page. Consists of calls for data and hooks for -// interactivity. -interface PageHandler { - // Get a key/value mapping of properties. - GetProperties() => (map<string, string> properties); - - // Change the triggering time to the given duration. - SetTriggerTime(int64 seconds); - - // Get cached metrics. - GetCachedMetricEvents() => (array<MetricEvent> metrics); - - // Clear the cached metrics. - ClearCachedMetricEvents() => (); - - // Get the cached suggestion results. - GetCachedSuggestionResults() => (array<SuggestionResult> results); - - // Clear the cached suggestions. - ClearCachedSuggestionResults() => (); -};
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.cc b/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.cc deleted file mode 100644 index 6c810e3..0000000 --- a/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.cc +++ /dev/null
@@ -1,154 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h" - -#include <string> -#include <vector> - -#include "base/containers/flat_map.h" -#include "chrome/browser/android/chrome_feature_list.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_cache.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetch.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" - -using contextual_suggestions::ContextualContentSuggestionsService; -using contextual_suggestions::ContextualSuggestionsCache; -using contextual_suggestions::ContextualSuggestionsDebuggingReporter; -using contextual_suggestions::ContextualSuggestionsFetch; -using contextual_suggestions::ContextualSuggestionsResult; - -namespace { -bool AreChromeFlagsSetup() { - return base::FeatureList::IsEnabled( - contextual_suggestions::kContextualSuggestionsButton); -} - -std::string GetAreChromeFlagsSetupString() { - return AreChromeFlagsSetup() ? "true" : "false"; -} -} // namespace - -EocInternalsPageHandler::EocInternalsPageHandler( - eoc_internals::mojom::PageHandlerRequest request, - ContextualContentSuggestionsService* contextual_content_suggestions_service) - : binding_(this, std::move(request)), - contextual_content_suggestions_service_( - contextual_content_suggestions_service) {} - -EocInternalsPageHandler::~EocInternalsPageHandler() {} - -void EocInternalsPageHandler::GetProperties(GetPropertiesCallback callback) { - base::flat_map<std::string, std::string> properties; - // TODO(wylieb): Find the actual time when it's moved to c++ and configurable, - // see b/838748 for more details. - // TODO(wylieb): Instead of having a map<string, string>, move this to a mojo - // struct and populate the fields to html in javascript. - properties["time-to-trigger"] = "2"; - properties["chrome-flags-setup"] = GetAreChromeFlagsSetupString(); - properties["fetch-endpoint-url"] = - ContextualSuggestionsFetch::GetFetchEndpoint(); - std::move(callback).Run(properties); -} - -void EocInternalsPageHandler::SetTriggerTime(int64_t seconds) { - // TODO(wylieb): Implement this when updating triggering time manually is - // supported. -} - -void EocInternalsPageHandler::GetCachedMetricEvents( - GetCachedMetricEventsCallback callback) { - std::vector<eoc_internals::mojom::MetricEventPtr> metric_events; - if (contextual_content_suggestions_service_ == nullptr) { - std::move(callback).Run(std::move(metric_events)); - return; - } - - ContextualSuggestionsDebuggingReporter* debugging_reporter = - contextual_content_suggestions_service_->GetDebuggingReporter(); - // Events will be ordered from oldest -> newest. - // TODO(wylieb): Consider storing a timestamp along with metric events so that - // clear ordering and sorting can be used. - for (auto debug_event : debugging_reporter->GetEvents()) { - auto metric_event = eoc_internals::mojom::MetricEvent::New(); - metric_event->url = debug_event.url; - metric_event->sheet_peeked = debug_event.sheet_peeked; - metric_event->button_shown = debug_event.button_shown; - metric_event->sheet_opened = debug_event.sheet_opened; - metric_event->sheet_closed = debug_event.sheet_closed; - metric_event->any_suggestion_taken = debug_event.any_suggestion_taken; - metric_event->any_suggestion_downloaded = - debug_event.any_suggestion_downloaded; - metric_events.push_back(std::move(metric_event)); - } - std::move(callback).Run(std::move(metric_events)); -} - -void EocInternalsPageHandler::ClearCachedMetricEvents( - ClearCachedMetricEventsCallback callback) { - if (!AreChromeFlagsSetup()) { - std::move(callback).Run(); - return; - } - - contextual_content_suggestions_service_->GetDebuggingReporter() - ->ClearEvents(); - std::move(callback).Run(); -} - -void EocInternalsPageHandler::GetCachedSuggestionResults( - GetCachedSuggestionResultsCallback callback) { - std::vector<eoc_internals::mojom::SuggestionResultPtr> suggestion_results; - if (contextual_content_suggestions_service_ == nullptr) { - std::move(callback).Run(std::move(suggestion_results)); - return; - } - - base::flat_map<GURL, ContextualSuggestionsResult> result_map = - contextual_content_suggestions_service_ - ->GetAllCachedResultsForDebugging(); - - for (auto iter = result_map.begin(); iter != result_map.end(); iter++) { - auto suggestion_result = eoc_internals::mojom::SuggestionResult::New(); - suggestion_result->url = iter->first.spec(); - - auto peek_conditions = eoc_internals::mojom::PeekConditions::New(); - peek_conditions->confidence = iter->second.peek_conditions.confidence; - peek_conditions->page_scroll_percentage = - iter->second.peek_conditions.page_scroll_percentage; - peek_conditions->minimum_seconds_on_page = - iter->second.peek_conditions.minimum_seconds_on_page; - peek_conditions->maximum_number_of_peeks = - iter->second.peek_conditions.maximum_number_of_peeks; - suggestion_result->peek_conditions = std::move(peek_conditions); - - for (const auto& cluster : iter->second.clusters) { - for (const auto& contextual_suggestion : cluster.suggestions) { - auto suggestion = eoc_internals::mojom::Suggestion::New(); - suggestion->url = contextual_suggestion.url.spec(); - suggestion->title = contextual_suggestion.title; - suggestion->publisher_name = contextual_suggestion.publisher_name; - suggestion->snippet = contextual_suggestion.snippet; - suggestion->image_id = contextual_suggestion.image_id; - suggestion->favicon_image_id = contextual_suggestion.favicon_image_id; - suggestion_result->suggestions.push_back(std::move(suggestion)); - } - } - - suggestion_results.push_back(std::move(suggestion_result)); - } - - std::move(callback).Run(std::move(suggestion_results)); -} - -void EocInternalsPageHandler::ClearCachedSuggestionResults( - ClearCachedSuggestionResultsCallback callback) { - if (!AreChromeFlagsSetup()) { - std::move(callback).Run(); - return; - } - - contextual_content_suggestions_service_->ClearCachedResultsForDebugging(); - std::move(callback).Run(); -}
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h b/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h deleted file mode 100644 index e852c44e..0000000 --- a/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_PAGE_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_PAGE_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" -#include "mojo/public/cpp/bindings/binding.h" - -// Concrete implementation of eoc_internals::mojom::PageHandler. -class EocInternalsPageHandler : public eoc_internals::mojom::PageHandler { - public: - EocInternalsPageHandler( - eoc_internals::mojom::PageHandlerRequest request, - contextual_suggestions::ContextualContentSuggestionsService* - contextual_content_suggestions_service); - ~EocInternalsPageHandler() override; - - private: - // eoc_internals::mojom::EocInternalsPageHandler - void GetProperties(GetPropertiesCallback) override; - void SetTriggerTime(int64_t seconds) override; - void GetCachedMetricEvents(GetCachedMetricEventsCallback) override; - void ClearCachedMetricEvents(ClearCachedMetricEventsCallback) override; - void GetCachedSuggestionResults(GetCachedSuggestionResultsCallback) override; - void ClearCachedSuggestionResults( - ClearCachedSuggestionResultsCallback) override; - - mojo::Binding<eoc_internals::mojom::PageHandler> binding_; - contextual_suggestions::ContextualContentSuggestionsService* - contextual_content_suggestions_service_; - - DISALLOW_COPY_AND_ASSIGN(EocInternalsPageHandler); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_PAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h b/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h deleted file mode 100644 index 3650cf0..0000000 --- a/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_UI_H_ - -#include <memory> - -#include "base/macros.h" -#include "chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom.h" -#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h" -#include "ui/webui/mojo_web_ui_controller.h" - -// UI controller for chrome://eoc-internals, hooks up a concrete implementation -// of eoc_internals::mojom::PageHandler to requests for that page handler -// that will come from the frontend. -class EocInternalsUI : public ui::MojoWebUIController { - public: - explicit EocInternalsUI(content::WebUI* web_ui); - ~EocInternalsUI() override; - - private: - void BindEocInternalsPageHandler( - eoc_internals::mojom::PageHandlerRequest request); - - std::unique_ptr<EocInternalsPageHandler> page_handler_; - contextual_suggestions::ContextualContentSuggestionsService* - contextual_content_suggestions_service_; - - DISALLOW_COPY_AND_ASSIGN(EocInternalsUI); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_UI_H_
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc index 122663b..0ca2cad8 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
@@ -41,10 +41,12 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/printing/cups_printers_manager_factory.h" #include "chrome/common/pref_names.h" #include "chromeos/components/account_manager/account_manager.h" #include "chromeos/components/account_manager/account_manager_factory.h" #include "chromeos/constants/chromeos_switches.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/prefs/pref_service.h" #endif @@ -351,6 +353,16 @@ void SetUpOnMainThread() override { WebUIBrowserTest::SetUpOnMainThread(); +#if defined(OS_CHROMEOS) + // On Chrome OS, we need to stub out CupsPrintersManager, because the + // profile setup instatiates a ZeroConfPrinterDetector, which in turn sets + // |g_service_discovery_client| with a real instance. This causes a DCHECK + // during TestServiceDiscoveryClient construction. + chromeos::CupsPrintersManagerFactory::GetInstance()->SetTestingFactory( + ProfileManager::GetActiveUserProfile(), + BrowserContextKeyedServiceFactory::TestingFactory()); +#endif + test_service_discovery_client_ = new TestServiceDiscoveryClient(); test_service_discovery_client_->Start(); EXPECT_CALL(
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc index 88b20d9..1ba34ee 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -101,7 +101,6 @@ namespace { // Shorten identifiers to improve line wrapping. -using util = WindowSizerTestUtil; const int kDesktopBorderSize = WindowSizer::kDesktopBorderSize; const int kMaximumWindowWidth = WindowSizer::kMaximumWindowWidth; const int kWindowTilePixels = WindowSizer::kWindowTilePixels; @@ -128,9 +127,9 @@ TEST_F(WindowSizerAshTest, DefaultSizeCase) { { // 4:3 monitor case, 1024x768, no taskbar gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ( gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 1024 - kDesktopBorderSize * 2, 768 - kDesktopBorderSize), @@ -139,9 +138,9 @@ { // 4:3 monitor case, 1024x768, taskbar on bottom gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_bottom_work_area, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 1024 - kDesktopBorderSize * 2, taskbar_bottom_work_area.height() - kDesktopBorderSize), @@ -150,9 +149,9 @@ { // 4:3 monitor case, 1024x768, taskbar on right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_right_work_area, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ( gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, taskbar_right_work_area.width() - kDesktopBorderSize * 2, @@ -162,9 +161,9 @@ { // 4:3 monitor case, 1024x768, taskbar on left gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_left_work_area, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kDesktopBorderSize, kDesktopBorderSize, taskbar_left_work_area.width() - kDesktopBorderSize * 2, @@ -174,9 +173,9 @@ { // 4:3 monitor case, 1024x768, taskbar on top gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_top_work_area, gfx::Rect(), gfx::Rect(), gfx::Rect(), + DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kDesktopBorderSize, taskbar_top_work_area.y() + kDesktopBorderSize, 1024 - kDesktopBorderSize * 2, @@ -186,9 +185,9 @@ { // 4:3 monitor case, 1280x1024 gfx::Rect window_bounds; - util::GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect((1280 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1024 - kDesktopBorderSize), window_bounds); @@ -196,9 +195,9 @@ { // 4:3 monitor case, 1600x1200 gfx::Rect window_bounds; - util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect((1600 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1200 - kDesktopBorderSize), window_bounds); @@ -206,9 +205,9 @@ { // 16:10 monitor case, 1680x1050 gfx::Rect window_bounds; - util::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect((1680 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1050 - kDesktopBorderSize), window_bounds); @@ -216,9 +215,9 @@ { // 16:10 monitor case, 1920x1200 gfx::Rect window_bounds; - util::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect((1920 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1200 - kDesktopBorderSize), window_bounds); @@ -230,7 +229,7 @@ TEST_F(WindowSizerAshTest, LastWindowBoundsCase) { { // normal, in the middle of the screen somewhere. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -242,7 +241,7 @@ { // taskbar on top. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, taskbar_top_work_area, gfx::Rect(), gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -256,7 +255,7 @@ { // Too small to satisify the minimum visibility condition. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -270,7 +269,7 @@ { // Normal. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -284,7 +283,7 @@ TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) { { // taskbar on left. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, taskbar_left_work_area, gfx::Rect(), gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -297,9 +296,9 @@ { // offset would put the new window offscreen at the bottom but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 728, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(10, 728, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400).ToString(), window_bounds.ToString()); } @@ -307,9 +306,9 @@ { // offset would put the new window offscreen at the bottom and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 729, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(10, 729, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738 /* not 739 */, 500, @@ -320,9 +319,9 @@ { // offset would put the new window offscreen at the right but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(984, 10, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(984, 10, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400).ToString(), window_bounds.ToString()); } @@ -330,9 +329,9 @@ { // offset would put the new window offscreen at the right and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 10, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(985, 10, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 10 + kWindowTilePixels, 500, @@ -343,9 +342,9 @@ { // offset would put the new window offscreen at the bottom right and the // minimum visibility condition is satisified by relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 729, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(985, 729, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, @@ -356,7 +355,8 @@ // Test the placement of newly created windows. TEST_F(WindowSizerAshTest, PlaceNewWindows) { - // Create a browser to pass into the util::GetWindowBounds function. + // Create a browser to pass into the WindowSizerTestUtil::GetWindowBounds + // function. Browser::CreateParams native_params(&profile_, true); auto browser = CreateWindowlessBrowser(native_params); @@ -380,28 +380,28 @@ Browser::CreateParams params_popup(Browser::TYPE_POPUP, &profile_, true); auto new_popup = CreateWindowlessBrowser(params_popup); gfx::Rect window_bounds; - util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), - gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, - PERSISTED, new_popup.get(), gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(50, 100, 300, 150), + bottom_s1600x1200, PERSISTED, new_popup.get(), gfx::Rect(), + &window_bounds); EXPECT_EQ("50,100 300x150", window_bounds.ToString()); } browser_window->Hide(); { // If a window is there but not shown the persisted default should be used. gfx::Rect window_bounds; - util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), - gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, - PERSISTED, browser.get(), gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(50, 100, 300, 150), + bottom_s1600x1200, PERSISTED, browser.get(), gfx::Rect(), + &window_bounds); EXPECT_EQ("50,100 300x150", window_bounds.ToString()); } { // If a window is there but not shown the default should be returned. gfx::Rect window_bounds; - util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), - bottom_s1600x1200, DEFAULT, browser.get(), - gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), bottom_s1600x1200, + DEFAULT, browser.get(), gfx::Rect(), &window_bounds); // Note: We need to also take the defaults maximum width into account here // since that might get used if the resolution is too big. EXPECT_EQ( @@ -682,7 +682,8 @@ } TEST_F(WindowSizerAshTest, DefaultStateBecomesMaximized) { - // Create a browser to pass into the util::GetWindowBounds function. + // Create a browser to pass into the WindowSizerTestUtil::GetWindowBounds + // function. Browser::CreateParams native_params(&profile_, true); auto browser = CreateWindowlessBrowser(native_params);
diff --git a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc index 91343898..3f1a075 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
@@ -24,8 +24,6 @@ namespace { -using util = WindowSizerTestUtil; - class TestScreen : public display::ScreenBase { public: TestScreen() : previous_screen_(display::Screen::GetScreen()) { @@ -135,27 +133,27 @@ gfx::Rect initial_bounds(-470, 50, 500, 400); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } { // off the left and the minimum visibility condition is satisfied by // relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-471, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 50, 500, 400).ToString(), window_bounds.ToString()); } { // off the top gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -370, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, -370, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,0 500x400", window_bounds.ToString()); } @@ -164,18 +162,18 @@ gfx::Rect initial_bounds(994, 50, 500, 400); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } { // off the right and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(995, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 50, 500, 400).ToString(), window_bounds.ToString()); } @@ -185,27 +183,27 @@ gfx::Rect initial_bounds(50, 738, 500, 400); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } { // off the bottom and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, 739, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 738 /* not 739 */, 500, 400).ToString(), window_bounds.ToString()); } { // off the topleft gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, -371, 500, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-471, -371, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 0, 500, 400).ToString(), window_bounds.ToString()); } @@ -213,9 +211,9 @@ { // off the topright and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, -371, 500, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(995, -371, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 0, 500, 400).ToString(), window_bounds.ToString()); } @@ -223,9 +221,9 @@ { // off the bottomleft and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 739, 500, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-471, 739, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 738 /* not 739 */, 500, @@ -236,9 +234,9 @@ { // off the bottomright and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(995, 739, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, @@ -248,68 +246,68 @@ { // entirely off left gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-700, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -700 */, 50, 500, 400).ToString(), window_bounds.ToString()); } { // entirely off left (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), left_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-700, 50, 500, 400), + left_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("0,50 500x400", window_bounds.ToString()); } { // entirely off top gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, -500, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,0 500x400", window_bounds.ToString()); } { // entirely off top (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), top_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, -500, 500, 400), + top_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,0 500x400", window_bounds.ToString()); } { // entirely off right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(1200, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 1200 */, 50, 500, 400).ToString(), window_bounds.ToString()); } { // entirely off right (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), right_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(1200, 50, 500, 400), + right_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("524,50 500x400", window_bounds.ToString()); } { // entirely off bottom gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, 800, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 738 /* not 800 */, 500, 400).ToString(), window_bounds.ToString()); } { // entirely off bottom (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), bottom_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, 800, 500, 400), + bottom_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,368 500x400", window_bounds.ToString()); } } @@ -320,7 +318,7 @@ TEST(WindowSizerTestCommon, AdjustFitSize) { { // Check that the window gets resized to the screen. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(-10, -10, 1024 + 20, 768 + 20), &window_bounds); EXPECT_EQ("0,0 1024x768", window_bounds.ToString()); @@ -328,9 +326,9 @@ { // Check that a window which hangs out of the screen get moved back in. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, - gfx::Rect(1020, 700, 100, 100), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(1020, 700, 100, 100), &window_bounds); EXPECT_EQ("924,668 100x100", window_bounds.ToString()); } }
diff --git a/chrome/browser/ui/window_sizer/window_sizer_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_unittest.cc index f6d5b39..1a29a1a 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_unittest.cc
@@ -9,7 +9,6 @@ #include "testing/gtest/include/gtest/gtest.h" namespace { -using util = WindowSizerTestUtil; const int kWindowTilePixels = WindowSizer::kWindowTilePixels; } @@ -18,9 +17,9 @@ TEST(WindowSizerTest, DefaultSizeCase) { { // 4:3 monitor case, 1024x768, no taskbar gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 1024 - kWindowTilePixels * 2, 768 - kWindowTilePixels * 2), @@ -29,9 +28,9 @@ { // 4:3 monitor case, 1024x768, taskbar on bottom gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_bottom_work_area, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 1024 - kWindowTilePixels * 2, (taskbar_bottom_work_area.height() - @@ -41,9 +40,9 @@ { // 4:3 monitor case, 1024x768, taskbar on right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_right_work_area, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, taskbar_right_work_area.width() - kWindowTilePixels*2, 768 - kWindowTilePixels * 2), @@ -52,9 +51,9 @@ { // 4:3 monitor case, 1024x768, taskbar on left gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_left_work_area, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kWindowTilePixels, kWindowTilePixels, taskbar_left_work_area.width() - kWindowTilePixels * 2, @@ -65,9 +64,9 @@ { // 4:3 monitor case, 1024x768, taskbar on top gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, taskbar_top_work_area, gfx::Rect(), gfx::Rect(), gfx::Rect(), + DEFAULT, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, taskbar_top_work_area.y() + kWindowTilePixels, 1024 - kWindowTilePixels * 2, @@ -77,9 +76,9 @@ { // 4:3 monitor case, 1280x1024 gfx::Rect window_bounds; - util::GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, WindowSizer::kWindowMaxDefaultWidth, 1024 - kWindowTilePixels * 2), @@ -88,9 +87,9 @@ { // 4:3 monitor case, 1600x1200 gfx::Rect window_bounds; - util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, WindowSizer::kWindowMaxDefaultWidth, 1200 - kWindowTilePixels * 2), @@ -109,9 +108,9 @@ window_width / 2 - static_cast<int>(kWindowTilePixels * 1.5); #endif // defined(OS_MACOSX) gfx::Rect window_bounds; - util::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, expected_window_width, 1050 - kWindowTilePixels * 2), window_bounds); @@ -129,9 +128,9 @@ window_width / 2 - static_cast<int>(kWindowTilePixels * 1.5); #endif // defined(OS_MACOSX) gfx::Rect window_bounds; - util::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, expected_window_width, 1200 - kWindowTilePixels * 2), window_bounds); @@ -143,7 +142,7 @@ TEST(WindowSizerTest, LastWindowBoundsCase) { { // normal, in the middle of the screen somewhere. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -153,7 +152,7 @@ { // taskbar on top. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, taskbar_top_work_area, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -165,7 +164,7 @@ { // Too small to satisify the minimum visibility condition. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -179,7 +178,7 @@ { // Normal. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -194,9 +193,9 @@ gfx::Rect initial_bounds(kWindowTilePixels, kWindowTilePixels, 500, 400); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -204,9 +203,9 @@ gfx::Rect initial_bounds(0, 0, 1024, 768); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -214,9 +213,9 @@ gfx::Rect initial_bounds(-600, 10, 500, 400); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -224,9 +223,9 @@ gfx::Rect initial_bounds(-1024, 0, 1024, 768); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + WindowSizerTestUtil::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, + initial_bounds, gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -236,9 +235,9 @@ gfx::Rect initial_bounds(1074, 50, 600, 500); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, NULL, - gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), initial_bounds, + right_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -248,9 +247,9 @@ gfx::Rect initial_bounds(1274, 50, 600, 500); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, NULL, - gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), initial_bounds, + right_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("1224,50 600x500", window_bounds.ToString()); } @@ -260,15 +259,15 @@ gfx::Rect initial_bounds(1274, 50, 900, 700); gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, NULL, - gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), initial_bounds, + right_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("1024,0 800x600", window_bounds.ToString()); } { // width and height too small gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); @@ -283,7 +282,7 @@ // be moved higher than the menubar. (Perhaps the user changed // resolution to something smaller before relaunching Chrome?) gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, p1024x768, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 30, 5000), gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); @@ -303,7 +302,7 @@ { // taskbar on left. The new window overlaps slightly with the taskbar, so // it is moved to be flush with the left edge of the work area. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, taskbar_left_work_area, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -313,9 +312,9 @@ { // offset would put the new window offscreen at the bottom gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 729, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(10, 729, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 0 /* not 729 + kWindowTilePixels */, 500, 400), @@ -324,9 +323,9 @@ { // offset would put the new window offscreen at the right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 10, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(985, 10, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/, 10 + kWindowTilePixels, 500, 400), @@ -335,9 +334,9 @@ { // offset would put the new window offscreen at the bottom right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 729, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(985, 729, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/, 0 /* not 729 + kWindowTilePixels*/, 500, 400), @@ -348,141 +347,141 @@ TEST(WindowSizerTest, PersistedWindowOffscreenWithAggressiveRepositioning) { { // off the left gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-471, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -471 */, 50, 500, 400), window_bounds); } { // off the top gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -370, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, -370, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); } { // off the right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(995, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 995 */, 50, 500, 400), window_bounds); } { // off the bottom gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, 739, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0 /* not 739 */, 500, 400), window_bounds); } { // off the topleft gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, -371, 500, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-471, -371, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not -371 */, 500, 400), window_bounds); } { // off the topright gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, -371, 500, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(995, -371, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not -371 */, 500, 400), window_bounds); } { // off the bottomleft gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 739, 500, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-471, 739, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not 739 */, 500, 400), window_bounds); } { // off the bottomright gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(995, 739, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not 739 */, 500, 400), window_bounds); } { // entirely off left gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-700, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -700 */, 50, 500, 400), window_bounds); } { // entirely off left (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), left_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-700, 50, 500, 400), + left_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0, 50, 500, 400), window_bounds); } { // entirely off top gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, -500, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); } { // entirely off top (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), top_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, -500, 500, 400), + top_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); } { // entirely off right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(1200, 50, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 1200 */, 50, 500, 400), window_bounds); } { // entirely off right (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), right_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(1200, 50, 500, 400), + right_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(524 /* not 1200 */, 50, 500, 400), window_bounds); } { // entirely off bottom gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, 800, 500, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0 /* not 800 */, 500, 400), window_bounds); } { // entirely off bottom (monitor was detached since last run) gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), bottom_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(50, 800, 500, 400), + bottom_s1024x768, PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 368 /* not 800 */, 500, 400), window_bounds); } { // wider than the screen. off both the left and right gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-100, 50, 2000, 400), gfx::Rect(), - PERSISTED, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(-100, 50, 2000, 400), + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -100 */, 50, 2000, 400), window_bounds); } } @@ -490,7 +489,7 @@ TEST(WindowSizerTest, LastWindowOffscreenWithNonAggressiveRepositioning) { { // taskbar on left. gfx::Rect window_bounds; - util::GetWindowBounds( + WindowSizerTestUtil::GetWindowBounds( p1024x768, taskbar_left_work_area, gfx::Rect(), gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); @@ -503,9 +502,9 @@ { // offset would put the new window offscreen at the bottom but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 728, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(10, 728, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400), window_bounds); } @@ -513,9 +512,9 @@ { // offset would put the new window offscreen at the bottom and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 729, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(10, 729, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738 /* not 739 */, 500, 400), window_bounds); } @@ -523,18 +522,18 @@ { // offset would put the new window offscreen at the right but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(984, 10, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(984, 10, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400), window_bounds); } { // offset would put the new window offscreen at the right and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 10, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(985, 10, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 10 + kWindowTilePixels, 500, 400), window_bounds); } @@ -542,9 +541,9 @@ { // offset would put the new window offscreen at the bottom right and the // minimum visibility condition is satisified by relocation. gfx::Rect window_bounds; - util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 729, 500, 400), gfx::Rect(), - LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); + WindowSizerTestUtil::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(985, 729, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400), window_bounds); }
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index 208f37e..64b08dbd 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -901,10 +901,10 @@ #if defined(OS_ANDROID) extern "C" { - // This symbol is retrieved from the VR feature module library via dlsym(), // where it's bare address is type-cast to a CreateUiFunction pointer and -// executed. Any changes to the arguments here must be mirrored in that type. +// executed. The forward declaration here ensures that the signatures match. +CreateUiFunction CreateUi; __attribute__((visibility("default"))) UiInterface* CreateUi( UiBrowserInterface* browser, PlatformInputHandler* content_input_forwarder, @@ -916,7 +916,7 @@ std::move(text_input_delegate), std::move(audio_delegate), ui_initial_state); } -} +} // extern "C" #endif // defined(OS_ANDROID } // namespace vr
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index cd58b7d7..1314a3a9 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -135,6 +135,12 @@ // starts a session. const char kSupervisedUserCustodianName[] = "profile.managed.custodian_name"; +// Stores the obfuscated gaia id associated with the google account of the +// custodian of the supervised user, updated (if possible) each time the +// supervised user starts a session. +const char kSupervisedUserCustodianObfuscatedGaiaId[] = + "profile.managed.custodian_obfuscated_gaia_id"; + // Stores the URL of the profile image associated with the google account of the // custodian of the supervised user. const char kSupervisedUserCustodianProfileImageURL[] = @@ -170,6 +176,12 @@ const char kSupervisedUserSecondCustodianName[] = "profile.managed.second_custodian_name"; +// Stores the obfuscated gaia id associated with the google account of the +// secondary custodian of the supervised user, updated (if possible) each time +// the supervised user starts a session. +const char kSupervisedUserSecondCustodianObfuscatedGaiaId[] = + "profile.managed.second_custodian_obfuscated_gaia_id"; + // Stores the URL of the profile image associated with the google account of the // secondary custodian of the supervised user. const char kSupervisedUserSecondCustodianProfileImageURL[] =
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 12c52e5..70feb8a 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -45,6 +45,7 @@ extern const char kSupervisedUserApprovedExtensions[]; extern const char kSupervisedUserCustodianEmail[]; extern const char kSupervisedUserCustodianName[]; +extern const char kSupervisedUserCustodianObfuscatedGaiaId[]; extern const char kSupervisedUserCustodianProfileImageURL[]; extern const char kSupervisedUserCustodianProfileURL[]; extern const char kSupervisedUserManualHosts[]; @@ -52,6 +53,7 @@ extern const char kSupervisedUserSafeSites[]; extern const char kSupervisedUserSecondCustodianEmail[]; extern const char kSupervisedUserSecondCustodianName[]; +extern const char kSupervisedUserSecondCustodianObfuscatedGaiaId[]; extern const char kSupervisedUserSecondCustodianProfileImageURL[]; extern const char kSupervisedUserSecondCustodianProfileURL[]; extern const char kSupervisedUserSharedSettings[];
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index b347b2c..7dbe0b9 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -168,7 +168,6 @@ const char kChromeUIWelcomeWin10URL[] = "chrome://welcome-win10/"; #if defined(OS_ANDROID) -const char kChromeUIEocInternalsHost[] = "eoc-internals"; const char kChromeUIExploreSitesInternalsHost[] = "explore-sites-internals"; const char kChromeUIJavaCrashURL[] = "chrome://java-crash/"; const char kChromeUINativeBookmarksURL[] = "chrome-native://bookmarks/"; @@ -482,7 +481,6 @@ kChromeUIUberHost, #endif #if defined(OS_ANDROID) - kChromeUIEocInternalsHost, kChromeUIExploreSitesInternalsHost, kChromeUIOfflineInternalsHost, kChromeUISnippetsInternalsHost,
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index 756a7fd..9799ae6 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -170,7 +170,6 @@ #if defined(OS_ANDROID) extern const char kChromeUIExploreSitesInternalsHost[]; -extern const char kChromeUIEocInternalsHost[]; extern const char kChromeUIJavaCrashURL[]; extern const char kChromeUINativeBookmarksURL[]; extern const char kChromeUINativeExploreURL[];
diff --git a/chrome/installer/mac/BUILD.gn b/chrome/installer/mac/BUILD.gn index d55edb8..760cb9e 100644 --- a/chrome/installer/mac/BUILD.gn +++ b/chrome/installer/mac/BUILD.gn
@@ -162,6 +162,7 @@ group("mac_signing_tests") { data = _mac_signing_sources + [ + "signing/commands_test.py", "signing/config.py.in", "signing/model_test.py", "signing/modification_test.py",
diff --git a/chrome/installer/mac/signing/commands.py b/chrome/installer/mac/signing/commands.py index 8ef95bf..a190c41 100644 --- a/chrome/installer/mac/signing/commands.py +++ b/chrome/installer/mac/signing/commands.py
@@ -29,6 +29,11 @@ os.mkdir(at) +def write_file(path, contents): + with open(path, 'w') as f: + f.write(contents) + + def run_command(args, **kwargs): print('Running command: {}'.format(args)) subprocess.check_call(args, **kwargs)
diff --git a/chrome/installer/mac/signing/commands_test.py b/chrome/installer/mac/signing/commands_test.py new file mode 100644 index 0000000..eab0501 --- /dev/null +++ b/chrome/installer/mac/signing/commands_test.py
@@ -0,0 +1,67 @@ +# 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 os +import tempfile +import shutil +import unittest + +from . import commands + + +class TestCommands(unittest.TestCase): + + def setUp(self): + self.tempdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tempdir) + + def test_file_exists(self): + path = os.path.join(self.tempdir, 'exists.txt') + + self.assertFalse(commands.file_exists(path)) + + open(path, 'w').close() + self.assertTrue(commands.file_exists(path)) + + os.unlink(path) + self.assertFalse(commands.file_exists(path)) + + def test_move_file(self): + orig_path = os.path.join(self.tempdir, 'file.txt') + new_path = os.path.join(self.tempdir, 'renamed.txt') + + commands.write_file(orig_path, 'moo') + + self.assertTrue(commands.file_exists(orig_path)) + self.assertFalse(commands.file_exists(new_path)) + + commands.move_file(orig_path, new_path) + + self.assertFalse(commands.file_exists(orig_path)) + self.assertTrue(commands.file_exists(new_path)) + + def test_write_file(self): + path = os.path.join(self.tempdir, 'file.txt') + + data1 = 'hello world this is a test' + commands.write_file(path, data1) + + with open(path, 'r') as f: + self.assertEqual(data1, f.read()) + + data2 = 'moo' + commands.write_file(path, data2) + + with open(path, 'r') as f: + self.assertEqual(data2, f.read()) + + def test_run_command(self): + path = os.path.join(self.tempdir, 'touch.txt') + self.assertFalse(commands.file_exists(path)) + + commands.run_command(['touch', path]) + + self.assertTrue(commands.file_exists(path))
diff --git a/chrome/installer/mac/signing/model.py b/chrome/installer/mac/signing/model.py index 6903d7cf..ac851a14 100644 --- a/chrome/installer/mac/signing/model.py +++ b/chrome/installer/mac/signing/model.py
@@ -131,6 +131,8 @@ branding_code=None, app_name_fragment=None, dmg_name_fragment=None, + product_dirname=None, + creator_code=None, channel_customize=False): """Creates a new Distribution object. All arguments are optional. @@ -144,6 +146,13 @@ dmg_name_fragment: If present, this is appended to the |config.CodeSignConfig.dmg_basename| to help differentiate different |branding_code|s. + product_dirname: If present, this string value is set in the app's + Info.plist with the key "CrProductDirName". This key influences + the browser's default user-data-dir location. + creator_code: If present, this will set a new macOS creator code + in the Info.plist "CFBundleSignature" key and in the PkgInfo + file. If this is not specified, the original values from the + build products will be kept. channel_customize: If True, then the product will be modified in several ways: - The |channel| will be appended to the @@ -155,6 +164,8 @@ self.branding_code = branding_code self.app_name_fragment = app_name_fragment self.dmg_name_fragment = dmg_name_fragment + self.product_dirname = product_dirname + self.creator_code = creator_code self.channel_customize = channel_customize def to_config(self, base_config):
diff --git a/chrome/installer/mac/signing/modification.py b/chrome/installer/mac/signing/modification.py index 02cabfc..05a8acb 100644 --- a/chrome/installer/mac/signing/modification.py +++ b/chrome/installer/mac/signing/modification.py
@@ -61,6 +61,12 @@ elif _KS_CHANNEL_ID in app_plist: del app_plist[_KS_CHANNEL_ID] + if dist.product_dirname: + app_plist['CrProductDirName'] = dist.product_dirname + + if dist.creator_code: + app_plist['CFBundleSignature'] = dist.creator_code + # See build/mac/tweak_info_plist.py and # chrome/browser/mac/keystone_glue.mm. keys_to_remove = set() @@ -186,6 +192,11 @@ _modify_plists(paths, dist, config) _process_entitlements(paths, dist, config) + if dist.creator_code: + pkg_info_file = os.path.join(paths.work, config.app_dir, 'Contents', + 'PkgInfo') + commands.write_file(pkg_info_file, 'APPL{}'.format(dist.creator_code)) + if dist.channel_customize: _replace_icons(paths, dist, config) _rename_enterprise_manifest(paths, dist, config)
diff --git a/chrome/installer/mac/signing/modification_test.py b/chrome/installer/mac/signing/modification_test.py index 9d94f973..44549fd9 100644 --- a/chrome/installer/mac/signing/modification_test.py +++ b/chrome/installer/mac/signing/modification_test.py
@@ -38,10 +38,11 @@ @mock.patch('signing.commands.plistlib', **{'readPlist.side_effect': plist_read}) -@mock.patch.multiple('signing.commands', **{ - m: mock.DEFAULT - for m in ('copy_files', 'move_file', 'make_dir', 'run_command') -}) +@mock.patch.multiple( + 'signing.commands', **{ + m: mock.DEFAULT for m in ('copy_files', 'move_file', 'make_dir', + 'write_file', 'run_command') + }) class TestModification(unittest.TestCase): def setUp(self): @@ -67,6 +68,7 @@ '$I/Product Packaging/app-entitlements.plist', '$W/app-entitlements.plist') self.assertEqual(0, kwargs['move_file'].call_count) + self.assertEqual(0, kwargs['write_file'].call_count) def test_distribution_with_brand(self, plistlib, **kwargs): dist = model.Distribution(branding_code='MOO') @@ -110,6 +112,52 @@ '$I/Product Packaging/app-entitlements.plist', '$W/app-entitlements.plist') self.assertEqual(0, kwargs['move_file'].call_count) + self.assertEqual(0, kwargs['write_file'].call_count) + + def test_distribution_with_product_dirname(self, plistlib, **kwargs): + dist = model.Distribution(product_dirname='Farmland/Cows') + config = dist.to_config(self.config) + + modification.customize_distribution(self.paths, dist, config) + + self.assertEqual(1, plistlib.writePlist.call_count) + plistlib.writePlist.assert_called_with( + { + 'CFBundleIdentifier': config.base_bundle_id, + 'KSProductID': 'test.ksproduct', + 'CrProductDirName': 'Farmland/Cows' + }, + '$W/App Product.app/Contents/Info.plist', + ) + + kwargs['copy_files'].assert_called_once_with( + '$I/Product Packaging/app-entitlements.plist', + '$W/app-entitlements.plist') + self.assertEqual(0, kwargs['move_file'].call_count) + self.assertEqual(0, kwargs['write_file'].call_count) + + def test_distribution_with_creator_code(self, plistlib, **kwargs): + dist = model.Distribution(creator_code='Mooo') + config = dist.to_config(self.config) + + modification.customize_distribution(self.paths, dist, config) + + self.assertEqual(1, plistlib.writePlist.call_count) + plistlib.writePlist.assert_called_with( + { + 'CFBundleIdentifier': config.base_bundle_id, + 'KSProductID': 'test.ksproduct', + 'CFBundleSignature': 'Mooo' + }, + '$W/App Product.app/Contents/Info.plist', + ) + + kwargs['copy_files'].assert_called_once_with( + '$I/Product Packaging/app-entitlements.plist', + '$W/app-entitlements.plist') + kwargs['write_file'].assert_called_once_with( + '$W/App Product.app/Contents/PkgInfo', 'APPLMooo') + self.assertEqual(0, kwargs['move_file'].call_count) def test_distribution_with_brand_and_channel(self, plistlib, **kwargs): dist = model.Distribution(channel='beta', branding_code='RAWR') @@ -133,11 +181,14 @@ '$I/Product Packaging/app-entitlements.plist', '$W/app-entitlements.plist') self.assertEqual(0, kwargs['move_file'].call_count) + self.assertEqual(0, kwargs['write_file'].call_count) def test_customize_channel(self, plistlib, **kwargs): dist = model.Distribution( channel='canary', app_name_fragment='Canary', + product_dirname='Acme/Product Canary', + creator_code='Mooo', channel_customize=True) config = dist.to_config(self.config) @@ -169,6 +220,8 @@ '$I/Product Packaging/document_canary.icns', '$W/App Product Canary.app/Contents/Resources/document.icns') ]) + kwargs['write_file'].assert_called_once_with( + '$W/App Product Canary.app/Contents/PkgInfo', 'APPLMooo') self.assertEqual(4, plistlib.writePlist.call_count) plistlib.writePlist.assert_has_calls([ @@ -182,7 +235,9 @@ 'CFBundleExecutable': config.app_product, 'KSProductID': 'test.ksproduct.canary', 'KSChannelID': 'canary', - 'KSChannelID-full': 'canary-full' + 'KSChannelID-full': 'canary-full', + 'CrProductDirName': 'Acme/Product Canary', + 'CFBundleSignature': 'Mooo' }, '$W/App Product Canary.app/Contents/Info.plist'), mock.call({ 'com.apple.application-identifier':
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 545e8597..565b002 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -514,9 +514,6 @@ ] data_deps += [ - # Needed for --run-in-mash, which triggers launching chrome. - # TODO(sky): this seems wrong, figure a better way to get resources. - "//ash:ash_service_resources", "//chrome", "//ui/keyboard:resources", "//ui/file_manager:unit_test_data", @@ -3087,7 +3084,10 @@ ] } if (is_chromeos) { - sources += [ "../renderer/chromeos_delayed_callback_group_unittest.cc" ] + sources += [ + "../browser/ui/webui/chromeos/add_supervision/add_supervision_handler_utils_unittest.cc", + "../renderer/chromeos_delayed_callback_group_unittest.cc", + ] } configs += [ "//build/config:precompiled_headers" ] @@ -5293,6 +5293,7 @@ "../browser/ui/ash/launcher_drag_interactive_uitest.cc", "../browser/ui/ash/overview_animations_interactive_uitest.cc", "../browser/ui/ash/overview_window_drag_interactive_uitest.cc", + "../browser/ui/ash/screen_rotation_interactive_uitest.cc", "../browser/ui/ash/split_view_interactive_uitest.cc", "base/perf/drag_event_generator.cc", "base/perf/drag_event_generator.h",
diff --git a/chrome/test/data/local_ntp/custom_backgrounds_browsertest.js b/chrome/test/data/local_ntp/custom_backgrounds_browsertest.js index 40b25b5e..3b589fac 100644 --- a/chrome/test/data/local_ntp/custom_backgrounds_browsertest.js +++ b/chrome/test/data/local_ntp/custom_backgrounds_browsertest.js
@@ -360,9 +360,10 @@ assertTrue(elementIsVisible($('bg-sel-menu'))); assertTrue($('bg-sel-menu').classList.contains('is-col-sel')); assertTrue( - document.getElementsByClassName('bg-sel-tile').length == coll.length); + $('bg-sel-menu').getElementsByClassName('bg-sel-tile').length == + coll.length); assertTrue( - document.getElementsByClassName('bg-sel-tile-title').length == + $('bg-sel-menu').getElementsByClassName('bg-sel-tile-title').length == coll.length); assertFalse(elementIsVisible($('bg-sel-back'))); assertTrue(elementIsVisible($('bg-sel-footer-cancel'))); @@ -377,7 +378,8 @@ assertTrue(elementIsVisible($('bg-sel-menu'))); assertTrue($('bg-sel-menu').classList.contains('is-img-sel')); assertTrue( - document.getElementsByClassName('bg-sel-tile').length == collImg.length); + $('bg-sel-menu').getElementsByClassName('bg-sel-tile').length == + collImg.length); assertTrue(elementIsVisible($('bg-sel-back'))); assertTrue(elementIsVisible($('bg-sel-footer-cancel'))); assertTrue(elementIsVisible($('bg-sel-footer-done')));
diff --git a/chrome/test/data/local_ntp/local_ntp_browsertest.html b/chrome/test/data/local_ntp/local_ntp_browsertest.html index be92322..94d85f24 100644 --- a/chrome/test/data/local_ntp/local_ntp_browsertest.html +++ b/chrome/test/data/local_ntp/local_ntp_browsertest.html
@@ -156,34 +156,40 @@ </dialog> <dialog id="customization-menu" class="customize-dialog"> - <div id="menu-header"> - <div id="menu-title">$i18n{customizeMenuTitle}</div> - </div> + <div id="menu-title">$i18n{customizeMenuTitle}</div> <div id="menu-nav-panel"> - <div class="menu-option" tabindex="0"> + <div id="backgrounds-button" class="menu-option" tabindex="0"> <div class="menu-option-icon-wrapper"> - <div class="menu-option-icon" id="backgrounds-icon"></div> + <div ids="backgrounds-icon" class="menu-option-icon"></div> </div> - <div class="menu-option-label" id="backgrounds-button">$i18n{backgroundsOption}</div> + <div class="menu-option-label">$i18n{backgroundsOption}</div> </div> - <div class="menu-option" tabindex="0"> + <div id="shortcuts-button" class="menu-option" tabindex="0"> <div class="menu-option-icon-wrapper"> - <div class="menu-option-icon" id="shortcuts-icon"></div> + <div ids="shortcuts-icon" class="menu-option-icon"></div> </div> - <div class="menu-option-label" id="shortcuts-button">$i18n{shortcutsOption}</div> + <div class="menu-option-label">$i18n{shortcutsOption}</div> </div> - <div class="menu-option" tabindex="0"> + <div id="colors-button" class="menu-option" tabindex="0"> <div class="menu-option-icon-wrapper"> - <div class="menu-option-icon" id="colors-icon"></div> + <div id="colors-icon" class="menu-option-icon"></div> </div> - <div class="menu-option-label" id="colors-button">$i18n{colorsOption}</div> + <div class="menu-option-label">$i18n{colorsOption}</div> + </div> + </div> + <div id="menu-contents"> + <div id="backgrounds-menu" class="menu-panel"> + <div id="backgrounds-upload" class="bg-sel-tile-bg">Upload an image</div> + <div id="backgrounds-default" class="bg-sel-tile-bg"> + <div class="bg-sel-tile-title">Default</div> + </div> </div> </div> <div id="menu-footer"> - <button id="menu-cancel" class="bg-sel-footer-button paper secondary - ripple">$i18n{cancelButton}</button> - <button id="menu-done" class="bg-sel-footer-button paper primary ripple" - >$i18n{doneButton}</button> + <button id="menu-cancel" class="bg-sel-footer-button paper secondary + ripple">$i18n{cancelButton}</button> + <button id="menu-done" class="bg-sel-footer-button paper primary ripple" + disabled>$i18n{doneButton}</button> </div> </dialog>
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 25974f1..5e227cd 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -145,17 +145,11 @@ } if (is_chromeos) { - sources += [ - "mash_service_factory.cc", - "mash_service_factory.h", - ] deps += [ - "//ash", "//chrome/services/file_util:lib", "//chromeos/assistant:buildflags", "//chromeos/services/ime:lib", "//chromeos/services/ime/public/mojom", - "//services/ws/public/mojom", ] if (enable_cros_libassistant) {
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index 38bcd16..58b869b 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -47,17 +47,7 @@ "+services/network/public", "+services/network/url_request_context_builder_mojo.h", "+services/proxy_resolver", - "+services/ws/public", "+skia/ext", "+third_party/libxml", "+third_party/zlib/google", ] - -specific_include_rules = { - "mash_service_factory.cc": [ - "+ash/ash_service.h", - "+ash/public/interfaces", - "+ash/window_manager_service.h", - "+services/ws/public", - ], -}
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 7d9694f..97f4a0bf 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -71,7 +71,6 @@ #endif #if defined(OS_CHROMEOS) -#include "chrome/utility/mash_service_factory.h" #include "chromeos/assistant/buildflags.h" // nogncheck #include "chromeos/services/ime/ime_service.h" #include "chromeos/services/ime/public/mojom/constants.mojom.h" @@ -167,10 +166,6 @@ #if BUILDFLAG(ENABLE_PRINT_PREVIEW) && defined(OS_WIN) printing_handler_ = std::make_unique<printing::PrintingHandler>(); #endif - -#if defined(OS_CHROMEOS) - mash_service_factory_ = std::make_unique<MashServiceFactory>(); -#endif } ChromeContentUtilityClient::~ChromeContentUtilityClient() = default; @@ -346,11 +341,8 @@ } #endif - return mash_service_factory_->HandleServiceRequest(service_name, - std::move(request)); -#else // defined(OS_CHROMEOS) - return nullptr; #endif // defined(OS_CHROMEOS) + return nullptr; } std::unique_ptr<service_manager::Service>
diff --git a/chrome/utility/chrome_content_utility_client.h b/chrome/utility/chrome_content_utility_client.h index bff5ba9..bf6f8fb 100644 --- a/chrome/utility/chrome_content_utility_client.h +++ b/chrome/utility/chrome_content_utility_client.h
@@ -13,8 +13,6 @@ #include "content/public/utility/content_utility_client.h" #include "printing/buildflags/buildflags.h" -class MashServiceFactory; - namespace printing { class PrintingHandler; } @@ -56,11 +54,6 @@ // True if the utility process runs with elevated privileges. bool utility_process_running_elevated_; -#if defined(OS_CHROMEOS) - // Must be owned by utility main thread. - std::unique_ptr<MashServiceFactory> mash_service_factory_; -#endif - DISALLOW_COPY_AND_ASSIGN(ChromeContentUtilityClient); };
diff --git a/chrome/utility/mash_service_factory.cc b/chrome/utility/mash_service_factory.cc deleted file mode 100644 index 2f69842..0000000 --- a/chrome/utility/mash_service_factory.cc +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/utility/mash_service_factory.h" - -#include <memory> - -#include "ash/ash_service.h" -#include "ash/public/interfaces/constants.mojom.h" -#include "base/bind.h" -#include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "build/build_config.h" - -namespace { - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class MashService { - kAsh = 0, - kAutoclickDeprecated = 1, // Deleted Aug 2018, https://crbug.com/876115 - kQuickLaunchDeprecated = 2, // Deleted Feb 2019. - kShortcutViewerDeprecated = 3, // Deleted May 2019, https://crbug.com/958073 - kTapVisualizerDeprecated = 4, // Deleted May 2019. - kFontDeprecated = 5, // Font Service is not in use for mash, but run - // in-process in the browser - // process. https://crbug.com/862553 - kMaxValue = kFontDeprecated, -}; - -// Wrapper function so we only have one copy of histogram macro generated code. -void RecordMashServiceLaunch(MashService service) { - UMA_HISTOGRAM_ENUMERATION("Launch.MashService", service); -} - -std::unique_ptr<service_manager::Service> CreateAshService( - service_manager::mojom::ServiceRequest request) { - RecordMashServiceLaunch(MashService::kAsh); - logging::SetLogPrefix("ash"); - return std::make_unique<ash::AshService>(std::move(request)); -} - -} // namespace - -MashServiceFactory::MashServiceFactory() = default; - -MashServiceFactory::~MashServiceFactory() = default; - -std::unique_ptr<service_manager::Service> -MashServiceFactory::HandleServiceRequest( - const std::string& service_name, - service_manager::mojom::ServiceRequest request) { - if (service_name == ash::mojom::kServiceName) - return CreateAshService(std::move(request)); - - return nullptr; -}
diff --git a/chrome/utility/mash_service_factory.h b/chrome/utility/mash_service_factory.h deleted file mode 100644 index b5763f1..0000000 --- a/chrome/utility/mash_service_factory.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_UTILITY_MASH_SERVICE_FACTORY_H_ -#define CHROME_UTILITY_MASH_SERVICE_FACTORY_H_ - -#include "content/public/utility/content_utility_client.h" -#include "services/service_manager/public/mojom/service.mojom.h" - -namespace service_manager { -class Service; -} - -// Lives on the utility process main thread. -class MashServiceFactory { - public: - MashServiceFactory(); - ~MashServiceFactory(); - - // Handles an incoming service request for this utility process. Returns - // null if the named service is unknown or cannot be created. - std::unique_ptr<service_manager::Service> HandleServiceRequest( - const std::string& service_name, - service_manager::mojom::ServiceRequest request); - - private: - DISALLOW_COPY_AND_ASSIGN(MashServiceFactory); -}; - -#endif // CHROME_UTILITY_MASH_SERVICE_FACTORY_H_
diff --git a/chromecast/common/cast_url_loader_throttle.cc b/chromecast/common/cast_url_loader_throttle.cc index 5321772..b2cb7743 100644 --- a/chromecast/common/cast_url_loader_throttle.cc +++ b/chromecast/common/cast_url_loader_throttle.cc
@@ -38,6 +38,11 @@ } } +bool CastURLLoaderThrottle::makes_unsafe_redirect() const { + // Yes, this makes cross-scheme redirects. + return true; +} + void CastURLLoaderThrottle::ResumeRequest(int error, net::HttpRequestHeaders headers) { DCHECK(deferred_);
diff --git a/chromecast/common/cast_url_loader_throttle.h b/chromecast/common/cast_url_loader_throttle.h index 7dc9b26c..79a3709 100644 --- a/chromecast/common/cast_url_loader_throttle.h +++ b/chromecast/common/cast_url_loader_throttle.h
@@ -39,6 +39,7 @@ void DetachFromCurrentSequence() override; void WillStartRequest(network::ResourceRequest* request, bool* defer) override; + bool makes_unsafe_redirect() const override; void ResumeRequest(int error, net::HttpRequestHeaders headers);
diff --git a/chromeos/network/BUILD.gn b/chromeos/network/BUILD.gn index b04dd1e..433859c 100644 --- a/chromeos/network/BUILD.gn +++ b/chromeos/network/BUILD.gn
@@ -63,8 +63,9 @@ "managed_network_configuration_handler_impl.h", "managed_state.cc", "managed_state.h", - "network_activation_handler.cc", "network_activation_handler.h", + "network_activation_handler_impl.cc", + "network_activation_handler_impl.h", "network_cert_loader.cc", "network_cert_loader.h", "network_cert_migrator.cc", @@ -181,6 +182,8 @@ "//testing/gtest", ] sources = [ + "fake_network_activation_handler.cc", + "fake_network_activation_handler.h", "fake_network_device_handler.cc", "fake_network_device_handler.h", "mock_managed_network_configuration_handler.cc",
diff --git a/chromeos/network/cellular_metrics_logger.cc b/chromeos/network/cellular_metrics_logger.cc index 2ef9be4e..a79c9e4e 100644 --- a/chromeos/network/cellular_metrics_logger.cc +++ b/chromeos/network/cellular_metrics_logger.cc
@@ -6,6 +6,7 @@ #include "base/metrics/histogram_macros.h" #include "base/task/post_task.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state_handler.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -17,6 +18,10 @@ base::TimeDelta::FromSeconds(15); // static +const base::TimeDelta CellularMetricsLogger::kDisconnectRequestTimeout = + base::TimeDelta::FromSeconds(5); + +// static CellularMetricsLogger::ActivationState CellularMetricsLogger::ActivationStateToEnum(const std::string& state) { if (state == shill::kActivationStateActivated) @@ -42,10 +47,23 @@ user_type == LoginState::LoggedInUserType::LOGGED_IN_USER_REGULAR; } -CellularMetricsLogger::ConnectingNetworkInfo::ConnectingNetworkInfo( +// static +void CellularMetricsLogger::LogCellularDisconnectionsHistogram( + ConnectionState connection_state) { + UMA_HISTOGRAM_ENUMERATION("Network.Cellular.Connection.Disconnections", + connection_state); +} + +CellularMetricsLogger::ConnectionInfo::ConnectionInfo( const std::string& network_guid, - base::TimeTicks start_time) - : network_guid(network_guid), start_time(start_time) {} + bool is_connected) + : network_guid(network_guid), is_connected(is_connected) {} + +CellularMetricsLogger::ConnectionInfo::ConnectionInfo( + const std::string& network_guid) + : network_guid(network_guid) {} + +CellularMetricsLogger::ConnectionInfo::~ConnectionInfo() = default; CellularMetricsLogger::CellularMetricsLogger() = default; @@ -53,21 +71,33 @@ if (network_state_handler_) OnShuttingDown(); - if (initialized_ && LoginState::IsInitialized()) - LoginState::Get()->RemoveObserver(this); + if (initialized_) { + if (LoginState::IsInitialized()) + LoginState::Get()->RemoveObserver(this); + + if (network_connection_handler_) + network_connection_handler_->RemoveObserver(this); + } } -void CellularMetricsLogger::Init(NetworkStateHandler* network_state_handler) { +void CellularMetricsLogger::Init( + NetworkStateHandler* network_state_handler, + NetworkConnectionHandler* network_connection_handler) { network_state_handler_ = network_state_handler; network_state_handler_->AddObserver(this, FROM_HERE); + if (network_connection_handler) { + network_connection_handler_ = network_connection_handler; + network_connection_handler_->AddObserver(this); + } + if (LoginState::IsInitialized()) LoginState::Get()->AddObserver(this); - // Devices may already be present before this method is called. - // Make sure that cellular availability is updated and initialization - // timer is started properly. + // Devices and networks may already be present before this method is called. + // Make sure that lists and timers are initialized properly. DeviceListChanged(); + NetworkListChanged(); initialized_ = true; } @@ -90,9 +120,37 @@ } } +void CellularMetricsLogger::NetworkListChanged() { + base::flat_map<std::string, std::unique_ptr<ConnectionInfo>> + old_connection_info_map; + // Clear |guid_to_connection_info_map| so that only new and existing + // networks are added back to it. + old_connection_info_map.swap(guid_to_connection_info_map_); + + NetworkStateHandler::NetworkStateList network_list; + network_state_handler_->GetVisibleNetworkListByType( + NetworkTypePattern::Cellular(), &network_list); + + // Check the current cellular networks list and copy existing connection info + // from old map to new map or create new ones if it does not exist. + for (const auto* network : network_list) { + const std::string& guid = network->guid(); + auto old_connection_info_map_iter = old_connection_info_map.find(guid); + if (old_connection_info_map_iter != old_connection_info_map.end()) { + guid_to_connection_info_map_.insert_or_assign( + guid, std::move(old_connection_info_map_iter->second)); + continue; + } + + guid_to_connection_info_map_.insert_or_assign( + guid, + std::make_unique<ConnectionInfo>(guid, network->IsConnectedState())); + } +} + void CellularMetricsLogger::OnInitializationTimeout() { - LogActivationState(); - LogCellularUsageCount(); + CheckForActivationStateMetric(); + CheckForCellularUsageCountMetric(); } void CellularMetricsLogger::LoggedInStateChanged() { @@ -102,53 +160,113 @@ // This flag enures that activation state is only logged once when // the user logs in. is_activation_state_logged_ = false; - LogActivationState(); + CheckForActivationStateMetric(); } void CellularMetricsLogger::NetworkConnectionStateChanged( const NetworkState* network) { DCHECK(network_state_handler_); - LogTimeToConnected(network); - LogCellularUsageCount(); -} + CheckForCellularUsageCountMetric(); -void CellularMetricsLogger::LogTimeToConnected(const NetworkState* network) { if (network->type().empty() || !network->Matches(NetworkTypePattern::Cellular())) { return; } + CheckForTimeToConnectedMetric(network); + CheckForConnectionStateMetric(network); +} + +void CellularMetricsLogger::CheckForTimeToConnectedMetric( + const NetworkState* network) { if (network->activation_state() != shill::kActivationStateActivated) return; - if (network->IsConnectingState()) { - if (!connecting_network_info_.has_value()) - connecting_network_info_.emplace(network->guid(), base::TimeTicks::Now()); - - return; - } - // We could be receiving a connection state change for a network different // from the one observed when the start time was recorded. Make sure that we - // only log the time to connected of the corresponding network. - if (!connecting_network_info_.has_value() || - network->guid() != connecting_network_info_->network_guid) { + // only look up time to connected of the corresponding network. + ConnectionInfo* connection_info = + GetConnectionInfoForCellularNetwork(network->guid()); + + if (network->IsConnectingState()) { + if (!connection_info->last_connect_start_time.has_value()) + connection_info->last_connect_start_time = base::TimeTicks::Now(); + return; } + if (!connection_info->last_connect_start_time.has_value()) + return; + if (network->IsConnectedState()) { UMA_HISTOGRAM_MEDIUM_TIMES( "Network.Cellular.Connection.TimeToConnected", - base::TimeTicks::Now() - connecting_network_info_->start_time); + base::TimeTicks::Now() - *connection_info->last_connect_start_time); } // This is hit when the network is no longer in connecting state, - // successfully connected or otherwise. Reset the connecting info + // successfully connected or otherwise. Reset the connect start_time // so that it is not used for further connection state changes. - connecting_network_info_.reset(); + connection_info->last_connect_start_time.reset(); } -void CellularMetricsLogger::LogActivationState() { +void CellularMetricsLogger::DisconnectRequested( + const std::string& service_path) { + const NetworkState* network = + network_state_handler_->GetNetworkState(service_path); + if (!network->Matches(NetworkTypePattern::Cellular())) + return; + + ConnectionInfo* connection_info = + GetConnectionInfoForCellularNetwork(network->guid()); + + // A disconnect request could fail and result in no cellular connection state + // change. Save the request time so that only disconnections that do not + // correspond to a request received within |kDisconnectRequestTimeout| are + // tracked. + connection_info->last_disconnect_request_time = base::TimeTicks::Now(); +} + +void CellularMetricsLogger::CheckForConnectionStateMetric( + const NetworkState* network) { + ConnectionInfo* connection_info = + GetConnectionInfoForCellularNetwork(network->guid()); + + bool new_is_connected = network->IsConnectedState(); + if (connection_info->is_connected == new_is_connected) + return; + base::Optional<bool> old_is_connected = connection_info->is_connected; + connection_info->is_connected = new_is_connected; + + if (new_is_connected) { + LogCellularDisconnectionsHistogram(ConnectionState::kConnected); + connection_info->last_disconnect_request_time.reset(); + return; + } + + // If the previous connection state is nullopt then this is a new connection + // info entry and a disconnection did not really occur. Skip logging the + // metric in this case. + if (!old_is_connected.has_value()) + return; + + base::Optional<base::TimeDelta> time_since_disconnect_requested; + if (connection_info->last_disconnect_request_time) { + time_since_disconnect_requested = + base::TimeTicks::Now() - *connection_info->last_disconnect_request_time; + } + + // If the disconnect occurred in less than |kDisconnectRequestTimeout| + // from the last disconnect request time then treat it as a user + // initiated disconnect and skip histogram log. + if (time_since_disconnect_requested && + time_since_disconnect_requested < kDisconnectRequestTimeout) { + return; + } + LogCellularDisconnectionsHistogram(ConnectionState::kDisconnected); +} + +void CellularMetricsLogger::CheckForActivationStateMetric() { if (!is_cellular_available_ || is_activation_state_logged_ || !CellularMetricsLogger::IsLoggedInUserOwnerOrRegular()) return; @@ -167,7 +285,7 @@ is_activation_state_logged_ = true; } -void CellularMetricsLogger::LogCellularUsageCount() { +void CellularMetricsLogger::CheckForCellularUsageCountMetric() { if (!is_cellular_available_) return; @@ -207,6 +325,26 @@ UMA_HISTOGRAM_ENUMERATION("Network.Cellular.Usage.Count", usage); } +CellularMetricsLogger::ConnectionInfo* +CellularMetricsLogger::GetConnectionInfoForCellularNetwork( + const std::string& cellular_network_guid) { + auto it = guid_to_connection_info_map_.find(cellular_network_guid); + + ConnectionInfo* connection_info; + if (it == guid_to_connection_info_map_.end()) { + // We could get connection events in some cases before network + // list change event. Insert new network into the list. + auto insert_result = guid_to_connection_info_map_.insert_or_assign( + cellular_network_guid, + std::make_unique<ConnectionInfo>(cellular_network_guid)); + connection_info = insert_result.first->second.get(); + } else { + connection_info = it->second.get(); + } + + return connection_info; +} + void CellularMetricsLogger::OnShuttingDown() { network_state_handler_->RemoveObserver(this, FROM_HERE); network_state_handler_ = nullptr;
diff --git a/chromeos/network/cellular_metrics_logger.h b/chromeos/network/cellular_metrics_logger.h index f77e880..d936f05 100644 --- a/chromeos/network/cellular_metrics_logger.h +++ b/chromeos/network/cellular_metrics_logger.h
@@ -6,11 +6,13 @@ #define CHROMEOS_NETWORK_CELLULAR_METRICS_LOGGER_H_ #include "base/component_export.h" +#include "base/containers/flat_map.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/optional.h" #include "base/timer/timer.h" #include "chromeos/login/login_state/login_state.h" +#include "chromeos/network/network_connection_observer.h" #include "chromeos/network/network_state_handler_observer.h" namespace chromeos { @@ -18,31 +20,42 @@ class NetworkStateHandler; class NetworkState; class CellularMetricsLoggerTest; +class NetworkConnectionHandler; // Class for tracking cellular network related metrics. // -// This class adds observers on network state and logs histograms -// when relevant cellular network events are triggered. +// This class adds observers on network state and makes the following +// measurements on cellular networks: +// 1. Time to connected. +// 2. Connected states and non-user initiated disconnections. +// 3. Activation status at login. +// 4. Cellular network usage type. // // Note: This class does not start logging metrics until Init() is // invoked. class COMPONENT_EXPORT(CHROMEOS_NETWORK) CellularMetricsLogger : public NetworkStateHandlerObserver, - public LoginState::Observer { + public LoginState::Observer, + public NetworkConnectionObserver { public: CellularMetricsLogger(); ~CellularMetricsLogger() override; - void Init(NetworkStateHandler* network_state_handler); + void Init(NetworkStateHandler* network_state_handler, + NetworkConnectionHandler* network_connection_handler); // LoginState::Observer: void LoggedInStateChanged() override; // NetworkStateHandlerObserver:: void DeviceListChanged() override; + void NetworkListChanged() override; void NetworkConnectionStateChanged(const NetworkState* network) override; void OnShuttingDown() override; + // NetworkConnectionObserver:: + void DisconnectRequested(const std::string& service_path) override; + private: friend class CellularMetricsLoggerTest; FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest, CellularUsageCountTest); @@ -52,17 +65,26 @@ CellularActivationStateAtLoginTest); FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest, CellularTimeToConnectedTest); + FRIEND_TEST_ALL_PREFIXES(CellularMetricsLoggerTest, + CellularDisconnectionsTest); // The amount of time after cellular device is added to device list, // after which cellular device is considered initialized. static const base::TimeDelta kInitializationTimeout; - // Stores information about cellular network that is in the connecting state. - struct ConnectingNetworkInfo { - ConnectingNetworkInfo(const std::string& network_guid, - base::TimeTicks start_time); - std::string network_guid; - base::TimeTicks start_time; + // The amount of time after a disconnect request within which any + // disconnections are considered user initiated. + static const base::TimeDelta kDisconnectRequestTimeout; + + // Stores connection related information for a cellular network. + struct ConnectionInfo { + ConnectionInfo(const std::string& network_guid); + ConnectionInfo(const std::string& network_guid, bool is_connected); + ~ConnectionInfo(); + const std::string network_guid; + base::Optional<bool> is_connected; + base::Optional<base::TimeTicks> last_disconnect_request_time; + base::Optional<base::TimeTicks> last_connect_start_time; }; // Usage type for cellular network. These values are persisted to logs. @@ -77,7 +99,7 @@ // Activation state for cellular network. // These values are persisted to logs. Entries should not be renumbered - // and numberic values should never be reused. + // and numeric values should never be reused. enum class ActivationState { kActivated = 0, kActivating = 1, @@ -87,25 +109,46 @@ kMaxValue = kUnknown }; + // Cellular connection state. These values are persisted to logs. + // Entries should not be renumbered and numberic values should + // never be reused. + enum class ConnectionState { + kConnected = 0, + kDisconnected = 1, + kMaxValue = kDisconnected + }; + // Convert shill activation state string to ActivationState enum. static ActivationState ActivationStateToEnum(const std::string& state); // Checks whether the current logged in user type is an owner or regular. static bool IsLoggedInUserOwnerOrRegular(); + // Helper method to save cellular disconnections histogram. + static void LogCellularDisconnectionsHistogram( + ConnectionState connection_state); + void OnInitializationTimeout(); // Tracks cellular network connection state and logs time to connected. - void LogTimeToConnected(const NetworkState* network); + void CheckForTimeToConnectedMetric(const NetworkState* network); - // Logs the activation state of cellular network if available and + // Tracks cellular network connected states and non user initiated + // disconnections. + void CheckForConnectionStateMetric(const NetworkState* network); + + // Tracks the activation state of cellular network if available and // if |log_activation_state_| is true. - void LogActivationState(); + void CheckForActivationStateMetric(); // This checks the state of connected networks and logs // cellular network usage histogram. Histogram is only logged // when usage state changes. - void LogCellularUsageCount(); + void CheckForCellularUsageCountMetric(); + + // Returns the ConnectionInfo for given |cellular_network_guid|. + ConnectionInfo* GetConnectionInfoForCellularNetwork( + const std::string& cellular_network_guid); // Tracks the last cellular network usage state. base::Optional<CellularUsage> last_cellular_usage_; @@ -115,6 +158,8 @@ NetworkStateHandler* network_state_handler_ = nullptr; + NetworkConnectionHandler* network_connection_handler_ = nullptr; + // A timer to wait for cellular initialization. This is useful // to avoid tracking intermediate states when cellular network is // starting up. @@ -124,9 +169,9 @@ // session. bool is_activation_state_logged_ = false; - // Stores info about cellular network in when it is in - // connecting state. - base::Optional<ConnectingNetworkInfo> connecting_network_info_; + // Stores connection information for all cellular networks. + base::flat_map<std::string, std::unique_ptr<ConnectionInfo>> + guid_to_connection_info_map_; bool initialized_ = false;
diff --git a/chromeos/network/cellular_metrics_logger_unittest.cc b/chromeos/network/cellular_metrics_logger_unittest.cc index 96da7f4..18c3c40 100644 --- a/chromeos/network/cellular_metrics_logger_unittest.cc +++ b/chromeos/network/cellular_metrics_logger_unittest.cc
@@ -21,6 +21,7 @@ const char kTestCellularDevicePath[] = "/device/wwan0"; const char kTestCellularServicePath[] = "/service/cellular0"; +const char kTestCellularServicePath2[] = "/service/cellular1"; const char kTestEthServicePath[] = "/service/eth0"; const char kUsageCountHistogram[] = "Network.Cellular.Usage.Count"; @@ -28,6 +29,8 @@ "Network.Cellular.Activation.StatusAtLogin"; const char kTimeToConnectedHistogram[] = "Network.Cellular.Connection.TimeToConnected"; +const char kDisconnectionsHistogram[] = + "Network.Cellular.Connection.Disconnections"; } // namespace @@ -43,15 +46,16 @@ void SetUp() override { LoginState::Initialize(); - network_metrics_logger_.reset(new CellularMetricsLogger()); - network_metrics_logger_->Init( - network_state_test_helper_.network_state_handler()); + cellular_metrics_logger_.reset(new CellularMetricsLogger()); + cellular_metrics_logger_->Init( + network_state_test_helper_.network_state_handler(), + /* network_connection_handler */ nullptr); } void TearDown() override { network_state_test_helper_.ClearDevices(); network_state_test_helper_.ClearServices(); - network_metrics_logger_.reset(); + cellular_metrics_logger_.reset(); LoginState::Shutdown(); } @@ -75,11 +79,17 @@ service_test->AddService(kTestCellularServicePath, "test_guid0", "test_cellular", shill::kTypeCellular, shill::kStateIdle, true); + service_test->AddService(kTestCellularServicePath2, "test_guid1", + "test_cellular_2", shill::kTypeCellular, + shill::kStateIdle, true); base::RunLoop().RunUntilIdle(); - service_client_test()->SetServiceProperty( + service_test->SetServiceProperty( kTestCellularServicePath, shill::kActivationStateProperty, base::Value(shill::kActivationStateNotActivated)); + service_test->SetServiceProperty( + kTestCellularServicePath2, shill::kActivationStateProperty, + base::Value(shill::kActivationStateNotActivated)); base::RunLoop().RunUntilIdle(); } @@ -100,10 +110,14 @@ return network_state_test_helper_.service_test(); } + CellularMetricsLogger* cellular_metrics_logger() const { + return cellular_metrics_logger_.get(); + } + private: NetworkStateTestHelper network_state_test_helper_{ false /* use_default_devices_and_services */}; - std::unique_ptr<CellularMetricsLogger> network_metrics_logger_; + std::unique_ptr<CellularMetricsLogger> cellular_metrics_logger_; DISALLOW_COPY_AND_ASSIGN(CellularMetricsLoggerTest); }; @@ -270,19 +284,86 @@ base::RunLoop().RunUntilIdle(); histogram_tester.ExpectTotalCount(kTimeToConnectedHistogram, 0); - // Should log connection time when activated. + // Set cellular networks to activated state and connecting state. service_client_test()->SetServiceProperty( kTestCellularServicePath, shill::kActivationStateProperty, base::Value(shill::kActivationStateActivated)); service_client_test()->SetServiceProperty( + kTestCellularServicePath2, shill::kActivationStateProperty, + base::Value(shill::kActivationStateActivated)); + service_client_test()->SetServiceProperty( kTestCellularServicePath, shill::kStateProperty, kAssocStateValue); + service_client_test()->SetServiceProperty( + kTestCellularServicePath2, shill::kStateProperty, kAssocStateValue); base::RunLoop().RunUntilIdle(); + + // Should log first network's connection time independently. scoped_task_environment_.FastForwardBy(kTestConnectionTime); service_client_test()->SetServiceProperty( kTestCellularServicePath, shill::kStateProperty, kOnlineStateValue); base::RunLoop().RunUntilIdle(); histogram_tester.ExpectTimeBucketCount(kTimeToConnectedHistogram, kTestConnectionTime, 1); + + // Should log second network's connection time independently. + scoped_task_environment_.FastForwardBy(kTestConnectionTime); + service_client_test()->SetServiceProperty( + kTestCellularServicePath2, shill::kStateProperty, kOnlineStateValue); + base::RunLoop().RunUntilIdle(); + histogram_tester.ExpectTimeBucketCount(kTimeToConnectedHistogram, + 2 * kTestConnectionTime, 1); +} + +TEST_F(CellularMetricsLoggerTest, CellularDisconnectionsTest) { + InitCellular(); + base::HistogramTester histogram_tester; + base::Value kOnlineStateValue(shill::kStateOnline); + base::Value kIdleStateValue(shill::kStateIdle); + + // Should log connected state. + service_client_test()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, kOnlineStateValue); + base::RunLoop().RunUntilIdle(); + histogram_tester.ExpectBucketCount( + kDisconnectionsHistogram, + CellularMetricsLogger::ConnectionState::kConnected, 1); + + // Should not log user initiated disconnections. + cellular_metrics_logger()->DisconnectRequested(kTestCellularServicePath); + scoped_task_environment_.FastForwardBy( + CellularMetricsLogger::kDisconnectRequestTimeout / 2); + service_client_test()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, kIdleStateValue); + base::RunLoop().RunUntilIdle(); + histogram_tester.ExpectBucketCount( + kDisconnectionsHistogram, + CellularMetricsLogger::ConnectionState::kDisconnected, 0); + + // Should log non user initiated disconnects. + service_client_test()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, kOnlineStateValue); + base::RunLoop().RunUntilIdle(); + service_client_test()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, kIdleStateValue); + base::RunLoop().RunUntilIdle(); + histogram_tester.ExpectBucketCount( + kDisconnectionsHistogram, + CellularMetricsLogger::ConnectionState::kDisconnected, 1); + + // Should log non user initiated disconnects when a previous + // disconnect request timed out. + service_client_test()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, kOnlineStateValue); + base::RunLoop().RunUntilIdle(); + cellular_metrics_logger()->DisconnectRequested(kTestCellularServicePath); + scoped_task_environment_.FastForwardBy( + CellularMetricsLogger::kDisconnectRequestTimeout * 2); + service_client_test()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, kIdleStateValue); + base::RunLoop().RunUntilIdle(); + histogram_tester.ExpectBucketCount( + kDisconnectionsHistogram, + CellularMetricsLogger::ConnectionState::kDisconnected, 2); } } // namespace chromeos
diff --git a/chromeos/network/fake_network_activation_handler.cc b/chromeos/network/fake_network_activation_handler.cc new file mode 100644 index 0000000..adb75e5 --- /dev/null +++ b/chromeos/network/fake_network_activation_handler.cc
@@ -0,0 +1,66 @@ +// 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 "chromeos/network/fake_network_activation_handler.h" + +#include "base/callback.h" +#include "base/values.h" + +namespace chromeos { + +FakeNetworkActivationHandler::ActivationParams::ActivationParams( + const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) + : service_path_(service_path), + carrier_(carrier), + success_callback_(success_callback), + error_callback_(error_callback) {} + +FakeNetworkActivationHandler::ActivationParams::ActivationParams( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) + : service_path_(service_path), + success_callback_(success_callback), + error_callback_(error_callback) {} + +FakeNetworkActivationHandler::ActivationParams::ActivationParams( + const ActivationParams& other) = default; + +FakeNetworkActivationHandler::ActivationParams::~ActivationParams() = default; + +void FakeNetworkActivationHandler::ActivationParams::InvokeSuccessCallback() { + success_callback_.Run(); +} + +void FakeNetworkActivationHandler::ActivationParams::InvokeErrorCallback( + const std::string& error_name, + std::unique_ptr<base::DictionaryValue> error_data) { + error_callback_.Run(error_name, std::move(error_data)); +} + +FakeNetworkActivationHandler::FakeNetworkActivationHandler() = default; + +FakeNetworkActivationHandler::~FakeNetworkActivationHandler() = default; + +void FakeNetworkActivationHandler::Activate( + const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + activate_calls_.emplace_back(service_path, carrier, success_callback, + error_callback); +} + +void FakeNetworkActivationHandler::CompleteActivation( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + complete_activation_calls_.emplace_back(service_path, success_callback, + error_callback); +} + +} // namespace chromeos
diff --git a/chromeos/network/fake_network_activation_handler.h b/chromeos/network/fake_network_activation_handler.h new file mode 100644 index 0000000..2bc77ab49 --- /dev/null +++ b/chromeos/network/fake_network_activation_handler.h
@@ -0,0 +1,78 @@ +// 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 CHROMEOS_NETWORK_FAKE_NETWORK_ACTIVATION_HANDLER_H_ +#define CHROMEOS_NETWORK_FAKE_NETWORK_ACTIVATION_HANDLER_H_ + +#include <string> + +#include "base/component_export.h" +#include "base/macros.h" +#include "chromeos/network/network_activation_handler.h" +#include "chromeos/network/network_handler_callbacks.h" + +namespace chromeos { + +// Fake NetworkActivationHandler implementation for tests. +class COMPONENT_EXPORT(CHROMEOS_NETWORK) FakeNetworkActivationHandler + : public NetworkActivationHandler { + public: + FakeNetworkActivationHandler(); + ~FakeNetworkActivationHandler() override; + + class ActivationParams { + public: + // For Activate() calls. + ActivationParams(const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + + // For CompleteActivation() calls. + ActivationParams(const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + + ActivationParams(const ActivationParams& other); + ~ActivationParams(); + + const std::string& service_path() const { return service_path_; } + const std::string& carrier() const { return *carrier_; } + + void InvokeSuccessCallback(); + void InvokeErrorCallback(const std::string& error_name, + std::unique_ptr<base::DictionaryValue> error_data); + + private: + std::string service_path_; + base::Optional<std::string> carrier_; + base::Closure success_callback_; + network_handler::ErrorCallback error_callback_; + }; + + std::vector<ActivationParams>& activate_calls() { return activate_calls_; } + std::vector<ActivationParams>& complete_activation_calls() { + return complete_activation_calls_; + } + + private: + // NetworkActivationHandler: + void Activate(const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) override; + void CompleteActivation( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) override; + + std::vector<ActivationParams> activate_calls_; + std::vector<ActivationParams> complete_activation_calls_; + + DISALLOW_COPY_AND_ASSIGN(FakeNetworkActivationHandler); +}; + +} // namespace chromeos + +#endif // CHROMEOS_NETWORK_FAKE_NETWORK_ACTIVATION_HANDLER_H_
diff --git a/chromeos/network/network_activation_handler.cc b/chromeos/network/network_activation_handler.cc deleted file mode 100644 index fd28870a..0000000 --- a/chromeos/network/network_activation_handler.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/network/network_activation_handler.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "chromeos/dbus/shill/shill_service_client.h" -#include "chromeos/network/network_event_log.h" -#include "chromeos/network/network_handler.h" -#include "dbus/object_proxy.h" - -namespace chromeos { - -// static -const char NetworkActivationHandler::kErrorShillError[] = "shill-error"; - -NetworkActivationHandler::NetworkActivationHandler() = default; -NetworkActivationHandler::~NetworkActivationHandler() = default; - -void NetworkActivationHandler::Activate( - const std::string& service_path, - const std::string& carrier, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback) { - NET_LOG_USER("ActivateNetwork", service_path); - CallShillActivate(service_path, carrier, success_callback, error_callback); -} - -void NetworkActivationHandler::CompleteActivation( - const std::string& service_path, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback) { - NET_LOG_USER("CompleteActivation", service_path); - CallShillCompleteActivation(service_path, success_callback, error_callback); -} - -void NetworkActivationHandler::CallShillActivate( - const std::string& service_path, - const std::string& carrier, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback) { - NET_LOG_USER("Activation Request", service_path + ": '" + carrier + "'"); - ShillServiceClient::Get()->ActivateCellularModem( - dbus::ObjectPath(service_path), carrier, - base::Bind(&NetworkActivationHandler::HandleShillSuccess, AsWeakPtr(), - service_path, success_callback), - base::Bind(&network_handler::ShillErrorCallbackFunction, kErrorShillError, - service_path, error_callback)); -} - -void NetworkActivationHandler::CallShillCompleteActivation( - const std::string& service_path, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback) { - NET_LOG_USER("CompleteActivation Request", service_path); - ShillServiceClient::Get()->CompleteCellularActivation( - dbus::ObjectPath(service_path), - base::Bind(&NetworkActivationHandler::HandleShillSuccess, AsWeakPtr(), - service_path, success_callback), - base::Bind(&network_handler::ShillErrorCallbackFunction, kErrorShillError, - service_path, error_callback)); -} - -void NetworkActivationHandler::HandleShillSuccess( - const std::string& service_path, - const base::Closure& success_callback) { - if (!success_callback.is_null()) - success_callback.Run(); -} - -} // namespace chromeos
diff --git a/chromeos/network/network_activation_handler.h b/chromeos/network/network_activation_handler.h index 55a26f1d..4e985ff 100644 --- a/chromeos/network/network_activation_handler.h +++ b/chromeos/network/network_activation_handler.h
@@ -9,23 +9,15 @@ #include "base/component_export.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "chromeos/network/network_handler_callbacks.h" namespace chromeos { // The NetworkActivationHandler class allows making service specific // calls required for activation on mobile networks. -class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkActivationHandler - : public base::SupportsWeakPtr<NetworkActivationHandler> { +class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkActivationHandler { public: - // Constants for |error_name| from |error_callback|. - // TODO(gauravsh): Merge various error constants from Network*Handlers into - // a single place. crbug.com/272554 - static const char kErrorNotFound[]; - static const char kErrorShillError[]; - - virtual ~NetworkActivationHandler(); + virtual ~NetworkActivationHandler() = default; // ActivateNetwork() will start an asynchronous activation attempt. // |carrier| may be empty or may specify a carrier to activate. @@ -33,10 +25,11 @@ // On failure, |error_callback| will be called with |error_name| one of: // kErrorNotFound if no network matching |service_path| is found. // kErrorShillError if a DBus or Shill error occurred. - void Activate(const std::string& service_path, - const std::string& carrier, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback); + virtual void Activate( + const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) = 0; // CompleteActivation() will start an asynchronous activation completion // attempt. @@ -44,32 +37,15 @@ // On failure, |error_callback| will be called with |error_name| one of: // kErrorNotFound if no network matching |service_path| is found. // kErrorShillError if a DBus or Shill error occurred. - void CompleteActivation(const std::string& service_path, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback); - - private: - friend class NetworkHandler; - - NetworkActivationHandler(); - - // Calls Shill.Service.ActivateCellularModem asynchronously. - void CallShillActivate(const std::string& service_path, - const std::string& carrier, - const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback); - - // Calls Shill.Service.CompleteCellularActivation asynchronously. - void CallShillCompleteActivation( + virtual void CompleteActivation( const std::string& service_path, const base::Closure& success_callback, - const network_handler::ErrorCallback& error_callback); + const network_handler::ErrorCallback& error_callback) = 0; - // Handle success from Shill.Service.ActivateCellularModem or - // Shill.Service.CompleteCellularActivation. - void HandleShillSuccess(const std::string& service_path, - const base::Closure& success_callback); + protected: + NetworkActivationHandler() = default; + private: DISALLOW_COPY_AND_ASSIGN(NetworkActivationHandler); };
diff --git a/chromeos/network/network_activation_handler_impl.cc b/chromeos/network/network_activation_handler_impl.cc new file mode 100644 index 0000000..242ec15b --- /dev/null +++ b/chromeos/network/network_activation_handler_impl.cc
@@ -0,0 +1,60 @@ +// 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 "chromeos/network/network_activation_handler_impl.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "chromeos/dbus/shill/shill_service_client.h" +#include "chromeos/network/network_event_log.h" +#include "chromeos/network/network_handler.h" +#include "dbus/object_proxy.h" + +namespace chromeos { + +namespace { + +const char kErrorShillError[] = "shill-error"; + +} // namespace + +NetworkActivationHandlerImpl::NetworkActivationHandlerImpl() = default; + +NetworkActivationHandlerImpl::~NetworkActivationHandlerImpl() = default; + +void NetworkActivationHandlerImpl::Activate( + const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + NET_LOG_USER("ActivateNetwork", service_path + ": '" + carrier + "'"); + ShillServiceClient::Get()->ActivateCellularModem( + dbus::ObjectPath(service_path), carrier, + base::Bind(&NetworkActivationHandlerImpl::HandleShillSuccess, AsWeakPtr(), + service_path, success_callback), + base::Bind(&network_handler::ShillErrorCallbackFunction, kErrorShillError, + service_path, error_callback)); +} + +void NetworkActivationHandlerImpl::CompleteActivation( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + NET_LOG_USER("CompleteActivation", service_path); + ShillServiceClient::Get()->CompleteCellularActivation( + dbus::ObjectPath(service_path), + base::Bind(&NetworkActivationHandlerImpl::HandleShillSuccess, AsWeakPtr(), + service_path, success_callback), + base::Bind(&network_handler::ShillErrorCallbackFunction, kErrorShillError, + service_path, error_callback)); +} + +void NetworkActivationHandlerImpl::HandleShillSuccess( + const std::string& service_path, + const base::Closure& success_callback) { + if (!success_callback.is_null()) + success_callback.Run(); +} + +} // namespace chromeos
diff --git a/chromeos/network/network_activation_handler_impl.h b/chromeos/network/network_activation_handler_impl.h new file mode 100644 index 0000000..ae77ff3b --- /dev/null +++ b/chromeos/network/network_activation_handler_impl.h
@@ -0,0 +1,52 @@ +// 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 CHROMEOS_NETWORK_NETWORK_ACTIVATION_HANDLER_IMPL_H_ +#define CHROMEOS_NETWORK_NETWORK_ACTIVATION_HANDLER_IMPL_H_ + +#include <string> + +#include "base/component_export.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/network/network_activation_handler.h" +#include "chromeos/network/network_handler_callbacks.h" + +namespace chromeos { + +// The NetworkActivationHandlerImpl class allows making service specific +// calls required for activation on mobile networks. +class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkActivationHandlerImpl + : public NetworkActivationHandler, + public base::SupportsWeakPtr<NetworkActivationHandlerImpl> { + public: + ~NetworkActivationHandlerImpl() override; + + private: + // NetworkActivationHandler: + void Activate(const std::string& service_path, + const std::string& carrier, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) override; + void CompleteActivation( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) override; + + private: + friend class NetworkHandler; + + NetworkActivationHandlerImpl(); + + // Handle success from Shill.Service.ActivateCellularModem or + // Shill.Service.CompleteCellularActivation. + void HandleShillSuccess(const std::string& service_path, + const base::Closure& success_callback); + + DISALLOW_COPY_AND_ASSIGN(NetworkActivationHandlerImpl); +}; + +} // namespace chromeos + +#endif // CHROMEOS_NETWORK_NETWORK_ACTIVATION_HANDLER_IMPL_H_
diff --git a/chromeos/network/network_handler.cc b/chromeos/network/network_handler.cc index 130ae7f..9ef82cfe 100644 --- a/chromeos/network/network_handler.cc +++ b/chromeos/network/network_handler.cc
@@ -10,7 +10,7 @@ #include "chromeos/network/client_cert_resolver.h" #include "chromeos/network/geolocation_handler.h" #include "chromeos/network/managed_network_configuration_handler_impl.h" -#include "chromeos/network/network_activation_handler.h" +#include "chromeos/network/network_activation_handler_impl.h" #include "chromeos/network/network_cert_loader.h" #include "chromeos/network/network_cert_migrator.h" #include "chromeos/network/network_certificate_handler.h" @@ -44,7 +44,7 @@ network_certificate_handler_.reset(new NetworkCertificateHandler()); client_cert_resolver_.reset(new ClientCertResolver()); } - network_activation_handler_.reset(new NetworkActivationHandler()); + network_activation_handler_.reset(new NetworkActivationHandlerImpl()); network_connection_handler_.reset(new NetworkConnectionHandlerImpl()); cellular_metrics_logger_.reset(new CellularMetricsLogger()); network_sms_handler_.reset(new NetworkSmsHandler()); @@ -69,7 +69,8 @@ network_state_handler_.get(), network_configuration_handler_.get(), managed_network_configuration_handler_.get()); - cellular_metrics_logger_->Init(network_state_handler_.get()); + cellular_metrics_logger_->Init(network_state_handler_.get(), + network_connection_handler_.get()); if (network_cert_migrator_) network_cert_migrator_->Init(network_state_handler_.get()); if (client_cert_resolver_) {
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc index 3afc5c8..0515f96 100644 --- a/components/autofill/core/browser/autofill_metrics.cc +++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -820,6 +820,12 @@ } // static +void AutofillMetrics::LogLocalCardMigrationDecisionMetric( + LocalCardMigrationDecisionMetric metric) { + UMA_HISTOGRAM_ENUMERATION("Autofill.LocalCardMigrationDecision", metric); +} + +// static void AutofillMetrics::LogLocalCardMigrationBubbleOfferMetric( LocalCardMigrationBubbleOfferMetric metric, bool is_reshow) {
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h index 3688ad1..0e0d1d1 100644 --- a/components/autofill/core/browser/autofill_metrics.h +++ b/components/autofill/core/browser/autofill_metrics.h
@@ -476,6 +476,28 @@ NUM_SCAN_CREDIT_CARD_PROMPT_METRICS, }; + // Metrics to record the decision on whether to offer local card migration. + enum class LocalCardMigrationDecisionMetric { + // All the required conditions are satisfied and main prompt is shown. + OFFERED = 0, + // Migration not offered because user uses new card. + NOT_OFFERED_USE_NEW_CARD = 1, + // Migration not offered because failed migration prerequisites. + NOT_OFFERED_FAILED_PREREQUISITES = 2, + // The Autofill StrikeDatabase decided not to allow offering migration + // because max strike count was reached. + NOT_OFFERED_REACHED_MAX_STRIKE_COUNT = 3, + // Migration not offered because no migratable cards. + NOT_OFFERED_NO_MIGRATABLE_CARDS = 4, + // Met the migration requirements but the request to Payments for upload + // details failed. + NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED = 5, + // Abandoned the migration because no supported local cards were left after + // filtering out unsupported cards. + NOT_OFFERED_NO_SUPPORTED_CARDS = 6, + kMaxValue = NOT_OFFERED_NO_SUPPORTED_CARDS, + }; + // Metrics to track events when local credit card migration is offered. enum LocalCardMigrationBubbleOfferMetric { // The bubble is requested due to a credit card being used or @@ -940,6 +962,8 @@ static void LogManageCardsPromptMetric(ManageCardsPromptMetric metric, bool is_uploading); static void LogScanCreditCardPromptMetric(ScanCreditCardPromptMetric metric); + static void LogLocalCardMigrationDecisionMetric( + LocalCardMigrationDecisionMetric metric); static void LogLocalCardMigrationBubbleOfferMetric( LocalCardMigrationBubbleOfferMetric metric, bool is_reshow);
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager.cc b/components/autofill/core/browser/payments/local_card_migration_manager.cc index 9103db1..14eb58e 100644 --- a/components/autofill/core/browser/payments/local_card_migration_manager.cc +++ b/components/autofill/core/browser/payments/local_card_migration_manager.cc
@@ -71,11 +71,18 @@ AutofillMetrics::LocalCardMigrationOrigin::UseOfServerCard; break; default: + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_USE_NEW_CARD); return false; } - if (!IsCreditCardMigrationEnabled()) + if (!IsCreditCardMigrationEnabled()) { + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_FAILED_PREREQUISITES); return false; + } // Don't show the prompt if max strike count was reached. if (base::FeatureList::IsEnabled( @@ -91,6 +98,9 @@ AutofillMetrics::SaveTypeMetric::SERVER); break; } + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_REACHED_MAX_STRIKE_COUNT); return false; } else if (prefs::IsLocalCardMigrationPromptPreviouslyCancelled( client_->GetPrefs())) { @@ -105,12 +115,19 @@ // of Upstream if there are other local cards to migrate as well. If the form // was submitted with a server card, offer migration if ANY local cards can be // migrated. - return (imported_credit_card_record_type == - FormDataImporter::ImportedCreditCardRecordType::LOCAL_CARD && - migratable_credit_cards_.size() > 1) || - (imported_credit_card_record_type == - FormDataImporter::ImportedCreditCardRecordType::SERVER_CARD && - !migratable_credit_cards_.empty()); + if ((imported_credit_card_record_type == + FormDataImporter::ImportedCreditCardRecordType::LOCAL_CARD && + migratable_credit_cards_.size() > 1) || + (imported_credit_card_record_type == + FormDataImporter::ImportedCreditCardRecordType::SERVER_CARD && + !migratable_credit_cards_.empty())) { + return true; + } else { + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_NO_MIGRATABLE_CARDS); + return false; + } } void LocalCardMigrationManager::AttemptToOfferLocalCardMigration( @@ -223,9 +240,12 @@ // Filter the migratable credit cards with |supported_card_bin_ranges_|. FilterOutUnsupportedLocalCards(); // Abandon the migration if no supported card left. - // TODO(crbug.com/954367): Log a metric here. - if (migratable_credit_cards_.empty()) + if (migratable_credit_cards_.empty()) { + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_NO_SUPPORTED_CARDS); return; + } client_->ShowLocalCardMigrationDialog(base::BindOnce( &LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog, weak_ptr_factory_.GetWeakPtr())); @@ -238,6 +258,12 @@ client_->LoadRiskData(base::BindRepeating( &LocalCardMigrationManager::OnDidGetMigrationRiskData, weak_ptr_factory_.GetWeakPtr())); + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric::OFFERED); + } else { + AutofillMetrics::LogLocalCardMigrationDecisionMetric( + AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED); } }
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager.h b/components/autofill/core/browser/payments/local_card_migration_manager.h index 1126f97b..1ef71bf 100644 --- a/components/autofill/core/browser/payments/local_card_migration_manager.h +++ b/components/autofill/core/browser/payments/local_card_migration_manager.h
@@ -126,6 +126,11 @@ // Fetch all migratable credit cards and store in |migratable_credit_cards_|. void GetMigratableCreditCards(); + // For testing. + void SetAppLocaleForTesting(const std::string& app_locale) { + app_locale_ = app_locale; + } + protected: // Callback after successfully getting the legal documents. On success, // displays the offer-to-migrate dialog, which the user can accept or not.
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc index 5ded259..7ca5804 100644 --- a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc +++ b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
@@ -163,6 +163,92 @@ payments_client_->SetSaveResultForCardsMigration(std::move(save_result)); } + // Verify that the correct histogram entry (and only that) was logged. + void ExpectUniqueLocalCardMigrationDecision( + const base::HistogramTester& histogram_tester, + AutofillMetrics::LocalCardMigrationDecisionMetric metric) { + histogram_tester.ExpectUniqueSample("Autofill.LocalCardMigrationDecision", + metric, 1); + } + + void UseNewCardWithLocalCardsOnFile() { + // Set the billing_customer_number to designate existence of a Payments + // account. + personal_data_.SetPaymentsCustomerData( + std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); + + // Add a local credit card (but it will not match what we will enter below). + AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "1", "guid1"); + // Add another local credit card (but it will not match what we will enter + // below). + AddLocalCreditCard(personal_data_, "Flo Master", "4444333322221111", "11", + test::NextYear().c_str(), "1", "guid2"); + + // Set up our credit card form data. + FormData credit_card_form; + test::CreateTestCreditCardFormData(&credit_card_form, true, false); + FormsSeen(std::vector<FormData>(1, credit_card_form)); + + // Edit the data, and submit. + EditCreditCardFrom(credit_card_form, "Flo Master", "5555555555554444", "11", + test::NextYear().c_str(), "123"); + FormSubmitted(credit_card_form); + } + + void UseLocalCardWithOtherLocalCardsOnFile() { + // Set the billing_customer_number to designate existence of a Payments + // account. + personal_data_.SetPaymentsCustomerData( + std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); + + // Add a local credit card whose |TypeAndLastFourDigits| matches what we + // will enter below. + AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "1", "guid1"); + // Add another local credit card. + AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11", + test::NextYear().c_str(), "1", "guid2"); + + // Set up our credit card form data. + FormData credit_card_form; + test::CreateTestCreditCardFormData(&credit_card_form, true, false); + FormsSeen(std::vector<FormData>(1, credit_card_form)); + + // Edit the data, and submit. + EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "123"); + FormSubmitted(credit_card_form); + } + + void UseLocalCardWithInvalidLocalCardsOnFile() { + // Set the billing_customer_number to designate existence of a Payments + // account. + personal_data_.SetPaymentsCustomerData( + std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); + + // Add a local credit card whose |TypeAndLastFourDigits| matches what we + // will enter below. + AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "1", "guid1"); + // Add other invalid local credit cards(invalid card number or expired), so + // it will not trigger migration. + AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111112", "11", + test::NextYear().c_str(), "1", "guid2"); + AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11", + test::LastYear().c_str(), "1", "guid3"); + + // Set up our credit card form data. + FormData credit_card_form; + test::CreateTestCreditCardFormData(&credit_card_form, true, false); + FormsSeen(std::vector<FormData>(1, credit_card_form)); + + // Edit the data, and submit. + EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "123"); + FormSubmitted(credit_card_form); + } + protected: base::test::ScopedTaskEnvironment scoped_task_environment_; ukm::TestAutoSetUkmRecorder test_ukm_recorder_; @@ -1305,4 +1391,161 @@ EXPECT_TRUE(local_card_migration_manager_->IntermediatePromptWasShown()); } +// All migration requirements are met but GetUploadDetails rpc fails. Verified +// that the intermediate prompt was not shown. +TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_GetUploadDetailsFails) { + // Anything other than "en-US" will cause GetUploadDetails to return a failure + // response. + local_card_migration_manager_->SetAppLocaleForTesting("pt-BR"); + + UseLocalCardWithOtherLocalCardsOnFile(); + + EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown()); +} + +// Use new card when submit so migration was not offered. Verify the migration +// decision metic is logged as new card used. +TEST_F(LocalCardMigrationManagerTest, LogMigrationDecisionMetric_UseNewCard) { + base::HistogramTester histogram_tester; + UseNewCardWithLocalCardsOnFile(); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_USE_NEW_CARD); +} + +// Use one local card with more valid local cards available but billing customer +// number is blank, will not trigger migration. Verify the migration decision +// metic is logged as failed enablement prerequisites. +TEST_F(LocalCardMigrationManagerTest, + LogMigrationDecisionMetric_FailedEnablementPrerequisites) { + base::HistogramTester histogram_tester; + // Add a local credit card whose |TypeAndLastFourDigits| matches what we will + // enter below. + AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "1", "guid1"); + // Add another local credit card. + AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11", + test::NextYear().c_str(), "1", "guid2"); + + // Set up our credit card form data. + FormData credit_card_form; + test::CreateTestCreditCardFormData(&credit_card_form, true, false); + FormsSeen(std::vector<FormData>(1, credit_card_form)); + + // Edit the data, and submit. + EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "123"); + FormSubmitted(credit_card_form); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_FAILED_PREREQUISITES); +} + +// All migration requirements are met but max strikes reached. Verify the +// migration decision metic is logged as max strikes reached. +TEST_F(LocalCardMigrationManagerTest, + LogMigrationDecisionMetric_MaxStrikesReached) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillLocalCardMigrationUsesStrikeSystemV2); + + LocalCardMigrationStrikeDatabase local_card_migration_strike_database = + LocalCardMigrationStrikeDatabase(strike_database_); + local_card_migration_strike_database.AddStrikes( + local_card_migration_strike_database.GetMaxStrikesLimit()); + + EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), + local_card_migration_strike_database.GetMaxStrikesLimit()); + + base::HistogramTester histogram_tester; + UseLocalCardWithOtherLocalCardsOnFile(); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_REACHED_MAX_STRIKE_COUNT); +} + +// Use one local card with invalid local card so migration was not offered. +// Verify the migration decision metic is logged as no migratable cards. +TEST_F(LocalCardMigrationManagerTest, + LogMigrationDecisionMetric_NoMigratableCards) { + base::HistogramTester histogram_tester; + UseLocalCardWithInvalidLocalCardsOnFile(); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_NO_MIGRATABLE_CARDS); +} + +// All migration requirements are met but GetUploadDetails rpc fails. Verify the +// migration decision metic is logged as get upload details failed. +TEST_F(LocalCardMigrationManagerTest, + LogMigrationDecisionMetric_GetUploadDetailsFails) { + // Anything other than "en-US" will cause GetUploadDetails to return a failure + // response. + local_card_migration_manager_->SetAppLocaleForTesting("pt-BR"); + + base::HistogramTester histogram_tester; + UseLocalCardWithOtherLocalCardsOnFile(); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED); +} + +// Use one unsupported local card with more unsupported local cards will not +// trigger migration. Verify the migration decision metic is logged as no +// supported cards. +TEST_F(LocalCardMigrationManagerTest, + LogMigrationDecisionMetric_NoSupportedCards) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillDoNotMigrateUnsupportedLocalCards); + + // Set the billing_customer_number to designate existence of a Payments + // account. + personal_data_.SetPaymentsCustomerData( + std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); + + // Add a local credit card whose |TypeAndLastFourDigits| matches what we will + // enter below. + AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "1", "guid1"); + // Add another local credit card. + AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11", + test::NextYear().c_str(), "1", "guid2"); + + base::HistogramTester histogram_tester; + // Set up our credit card form data. + FormData credit_card_form; + test::CreateTestCreditCardFormData(&credit_card_form, true, false); + FormsSeen(std::vector<FormData>(1, credit_card_form)); + + // Set up the supported card bin ranges so that there are no supported cards. + std::vector<std::pair<int, int>> supported_card_bin_ranges{ + std::make_pair(34, 34), std::make_pair(300, 305)}; + payments_client_->SetSupportedBINRanges(supported_card_bin_ranges); + + // Edit the data, and submit. + EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11", + test::NextYear().c_str(), "123"); + FormSubmitted(credit_card_form); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, AutofillMetrics::LocalCardMigrationDecisionMetric:: + NOT_OFFERED_NO_SUPPORTED_CARDS); +} + +// All migration requirements are met and migration was offered. Verify the +// migration decision metic is logged as migration offered. +TEST_F(LocalCardMigrationManagerTest, + LogMigrationDecisionMetric_MigrationOffered) { + base::HistogramTester histogram_tester; + UseLocalCardWithOtherLocalCardsOnFile(); + + ExpectUniqueLocalCardMigrationDecision( + histogram_tester, + AutofillMetrics::LocalCardMigrationDecisionMetric::OFFERED); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/payments/test_local_card_migration_manager.cc b/components/autofill/core/browser/payments/test_local_card_migration_manager.cc index 49cb4d1..8db754d 100644 --- a/components/autofill/core/browser/payments/test_local_card_migration_manager.cc +++ b/components/autofill/core/browser/payments/test_local_card_migration_manager.cc
@@ -75,10 +75,10 @@ std::vector<std::pair<int, int>> supported_bin_ranges) { if (result == AutofillClient::SUCCESS) { local_card_migration_was_triggered_ = true; - LocalCardMigrationManager::OnDidGetUploadDetails( - is_from_settings_page, result, context_token, std::move(legal_message), - supported_bin_ranges); } + LocalCardMigrationManager::OnDidGetUploadDetails( + is_from_settings_page, result, context_token, std::move(legal_message), + supported_bin_ranges); } } // namespace autofill
diff --git a/components/gcm_driver/fake_gcm_app_handler.cc b/components/gcm_driver/fake_gcm_app_handler.cc index 147b2a2..02983974 100644 --- a/components/gcm_driver/fake_gcm_app_handler.cc +++ b/components/gcm_driver/fake_gcm_app_handler.cc
@@ -8,12 +8,9 @@ namespace gcm { -FakeGCMAppHandler::FakeGCMAppHandler() - : received_event_(NO_EVENT) { -} +FakeGCMAppHandler::FakeGCMAppHandler() : received_event_(NO_EVENT) {} -FakeGCMAppHandler::~FakeGCMAppHandler() { -} +FakeGCMAppHandler::~FakeGCMAppHandler() = default; void FakeGCMAppHandler::WaitForNotification() { run_loop_.reset(new base::RunLoop); @@ -21,8 +18,7 @@ run_loop_.reset(); } -void FakeGCMAppHandler::ShutdownHandler() { -} +void FakeGCMAppHandler::ShutdownHandler() {} void FakeGCMAppHandler::OnStoreReset() {} @@ -65,6 +61,17 @@ run_loop_->Quit(); } +void FakeGCMAppHandler::OnMessageDecryptionFailed( + const std::string& app_id, + const std::string& message_id, + const std::string& error_message) { + ClearResults(); + received_event_ = DECRYPTION_FAILED_EVENT; + app_id_ = app_id; + if (run_loop_) + run_loop_->Quit(); +} + void FakeGCMAppHandler::ClearResults() { received_event_ = NO_EVENT; app_id_.clear();
diff --git a/components/gcm_driver/fake_gcm_app_handler.h b/components/gcm_driver/fake_gcm_app_handler.h index adfe45e6..50bc38bf 100644 --- a/components/gcm_driver/fake_gcm_app_handler.h +++ b/components/gcm_driver/fake_gcm_app_handler.h
@@ -23,7 +23,8 @@ NO_EVENT, MESSAGE_EVENT, MESSAGES_DELETED_EVENT, - SEND_ERROR_EVENT + SEND_ERROR_EVENT, + DECRYPTION_FAILED_EVENT, }; FakeGCMAppHandler(); @@ -48,6 +49,9 @@ void OnSendError( const std::string& app_id, const GCMClient::SendErrorDetails& send_error_details) override; + void OnMessageDecryptionFailed(const std::string& app_id, + const std::string& message_id, + const std::string& error_message) override; void OnSendAcknowledged(const std::string& app_id, const std::string& message_id) override;
diff --git a/components/gcm_driver/gcm_app_handler.cc b/components/gcm_driver/gcm_app_handler.cc index d7c66f3..c882799 100644 --- a/components/gcm_driver/gcm_app_handler.cc +++ b/components/gcm_driver/gcm_app_handler.cc
@@ -6,8 +6,13 @@ namespace gcm { -GCMAppHandler::GCMAppHandler() {} -GCMAppHandler::~GCMAppHandler() {} +GCMAppHandler::GCMAppHandler() = default; +GCMAppHandler::~GCMAppHandler() = default; + +void GCMAppHandler::OnMessageDecryptionFailed( + const std::string& app_id, + const std::string& message_id, + const std::string& error_message) {} bool GCMAppHandler::CanHandle(const std::string& app_id) const { return false;
diff --git a/components/gcm_driver/gcm_app_handler.h b/components/gcm_driver/gcm_app_handler.h index 934819c..676eeea8 100644 --- a/components/gcm_driver/gcm_app_handler.h +++ b/components/gcm_driver/gcm_app_handler.h
@@ -48,6 +48,14 @@ virtual void OnSendAcknowledged(const std::string& app_id, const std::string& message_id) = 0; + // Called when a GCM message has been received but decryption failed. + // |message_id| is a message identifier sent by the GCM server. + // |error_message| is human-readable description of the error, for reporting + // purposes. By default this handler does nothing. + virtual void OnMessageDecryptionFailed(const std::string& app_id, + const std::string& message_id, + const std::string& error_message); + // If no app handler has been added with the exact app_id of an incoming // event, all handlers will be asked (in arbitrary order) whether they can // handle the app_id, and the first to return true will receive the event.
diff --git a/components/gcm_driver/gcm_driver.cc b/components/gcm_driver/gcm_driver.cc index d833a27..f3cf956 100644 --- a/components/gcm_driver/gcm_driver.cc +++ b/components/gcm_driver/gcm_driver.cc
@@ -17,11 +17,9 @@ namespace gcm { -InstanceIDHandler::InstanceIDHandler() { -} +InstanceIDHandler::InstanceIDHandler() = default; -InstanceIDHandler::~InstanceIDHandler() { -} +InstanceIDHandler::~InstanceIDHandler() = default; void InstanceIDHandler::DeleteAllTokensForApp(const std::string& app_id, DeleteTokenCallback callback) { @@ -38,8 +36,7 @@ encryption_provider_.Init(store_path, blocking_task_runner); } -GCMDriver::~GCMDriver() { -} +GCMDriver::~GCMDriver() = default; void GCMDriver::Register(const std::string& app_id, const std::vector<std::string>& sender_ids, @@ -298,9 +295,16 @@ case GCMDecryptionResult::INVALID_BINARY_HEADER_PAYLOAD_LENGTH: case GCMDecryptionResult::INVALID_BINARY_HEADER_RECORD_SIZE: case GCMDecryptionResult::INVALID_BINARY_HEADER_PUBLIC_KEY_LENGTH: - case GCMDecryptionResult::INVALID_BINARY_HEADER_PUBLIC_KEY_FORMAT: + case GCMDecryptionResult::INVALID_BINARY_HEADER_PUBLIC_KEY_FORMAT: { RecordDecryptionFailure(app_id, result); + GCMAppHandler* handler = GetAppHandler(app_id); + if (handler) { + handler->OnMessageDecryptionFailed( + app_id, message.message_id, + ToGCMDecryptionResultDetailsString(result)); + } return; + } case GCMDecryptionResult::ENUM_SIZE: break; // deliberate fall-through }
diff --git a/components/gcm_driver/gcm_driver_desktop_unittest.cc b/components/gcm_driver/gcm_driver_desktop_unittest.cc index 4eeb96d..39239d8 100644 --- a/components/gcm_driver/gcm_driver_desktop_unittest.cc +++ b/components/gcm_driver/gcm_driver_desktop_unittest.cc
@@ -897,6 +897,9 @@ PumpUILoop(); PumpIOLoop(); + EXPECT_EQ(FakeGCMAppHandler::DECRYPTION_FAILED_EVENT, + gcm_app_handler()->received_event()); + GCMClient::GCMStatistics statistics = GetGCMClient()->GetStatistics(); EXPECT_TRUE(statistics.is_recording); EXPECT_EQ(
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index 9a64d7f..3e729b2 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -390,9 +390,11 @@ } #if defined(OS_ANDROID) || defined(OS_IOS) -void MetricsService::OnAppEnterBackground() { - rotation_scheduler_->Stop(); - reporting_service_.Stop(); +void MetricsService::OnAppEnterBackground(bool keep_recording_in_background) { + if (!keep_recording_in_background) { + rotation_scheduler_->Stop(); + reporting_service_.Stop(); + } MarkAppCleanShutdownAndCommit(state_manager_->clean_exit_beacon(), local_state_);
diff --git a/components/metrics/metrics_service.h b/components/metrics/metrics_service.h index a14b538..5e22fbe 100644 --- a/components/metrics/metrics_service.h +++ b/components/metrics/metrics_service.h
@@ -127,7 +127,9 @@ #if defined(OS_ANDROID) || defined(OS_IOS) // Called when the application is going into background mode. - void OnAppEnterBackground(); + // If |keep_recording_in_background| is true, UMA is still recorded and + // reported while in the background. + void OnAppEnterBackground(bool keep_recording_in_background = false); // Called when the application is coming out of background mode. void OnAppEnterForeground();
diff --git a/components/ntp_snippets/BUILD.gn b/components/ntp_snippets/BUILD.gn index e03e29eb..9855dfa 100644 --- a/components/ntp_snippets/BUILD.gn +++ b/components/ntp_snippets/BUILD.gn
@@ -33,33 +33,6 @@ "content_suggestions_provider.h", "content_suggestions_service.cc", "content_suggestions_service.h", - "contextual/contextual_content_suggestions_service.cc", - "contextual/contextual_content_suggestions_service.h", - "contextual/contextual_content_suggestions_service_proxy.cc", - "contextual/contextual_content_suggestions_service_proxy.h", - "contextual/contextual_suggestion.cc", - "contextual/contextual_suggestion.h", - "contextual/contextual_suggestions_cache.cc", - "contextual/contextual_suggestions_cache.h", - "contextual/contextual_suggestions_features.cc", - "contextual/contextual_suggestions_features.h", - "contextual/contextual_suggestions_fetch.cc", - "contextual/contextual_suggestions_fetch.h", - "contextual/contextual_suggestions_fetcher.h", - "contextual/contextual_suggestions_fetcher_impl.cc", - "contextual/contextual_suggestions_fetcher_impl.h", - "contextual/contextual_suggestions_result.cc", - "contextual/contextual_suggestions_result.h", - "contextual/reporting/contextual_suggestions_composite_reporter.cc", - "contextual/reporting/contextual_suggestions_composite_reporter.h", - "contextual/reporting/contextual_suggestions_debugging_reporter.cc", - "contextual/reporting/contextual_suggestions_debugging_reporter.h", - "contextual/reporting/contextual_suggestions_metrics_reporter.cc", - "contextual/reporting/contextual_suggestions_metrics_reporter.h", - "contextual/reporting/contextual_suggestions_reporter.cc", - "contextual/reporting/contextual_suggestions_reporter.h", - "contextual/reporting/contextual_suggestions_ukm_entry.cc", - "contextual/reporting/contextual_suggestions_ukm_entry.h", "features.cc", "features.h", "ntp_snippets_constants.cc", @@ -126,7 +99,6 @@ ] deps = [ - ":explore_protos", "//components/favicon/core", "//components/favicon_base", "//components/history/core/browser", @@ -161,19 +133,10 @@ "category_info.h", "category_status.h", "content_suggestions_service.cc", - "contextual/reporting/contextual_suggestions_reporter.h", ] } } -proto_library("explore_protos") { - sources = [ - "contextual/proto/chrome_search_api_request_context.proto", - "contextual/proto/get_pivots_request.proto", - "contextual/proto/get_pivots_response.proto", - ] -} - source_set("unit_tests") { testonly = true sources = [ @@ -182,14 +145,6 @@ "category_unittest.cc", "content_suggestions_metrics_unittest.cc", "content_suggestions_service_unittest.cc", - "contextual/contextual_content_suggestions_service_proxy_unittest.cc", - "contextual/contextual_content_suggestions_service_unittest.cc", - "contextual/contextual_suggestions_features_unittest.cc", - "contextual/contextual_suggestions_fetch_unittest.cc", - "contextual/contextual_suggestions_fetcher_impl_unittest.cc", - "contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc", - "contextual/reporting/contextual_suggestions_metrics_reporter_unittest.cc", - "contextual/reporting/contextual_suggestions_ukm_entry_unittest.cc", "features_unittest.cc", "reading_list/reading_list_suggestions_provider_unittest.cc", "remote/cached_image_fetcher_unittest.cc", @@ -209,7 +164,6 @@ ] deps = [ - ":explore_protos", ":ntp_snippets", ":test_support", "//base", @@ -250,8 +204,6 @@ "category_rankers/fake_category_ranker.h", "category_rankers/mock_category_ranker.cc", "category_rankers/mock_category_ranker.h", - "contextual/contextual_suggestions_test_utils.cc", - "contextual/contextual_suggestions_test_utils.h", "fake_content_suggestions_provider_observer.cc", "fake_content_suggestions_provider_observer.h", "mock_content_suggestions_provider.cc",
diff --git a/components/ntp_snippets/category.h b/components/ntp_snippets/category.h index 882cce3..53baaed 100644 --- a/components/ntp_snippets/category.h +++ b/components/ntp_snippets/category.h
@@ -37,9 +37,6 @@ // Pages from the user reading list. READING_LIST, - // Contextual suggestion. - CONTEXTUAL, - // ****************** INSERT NEW LOCAL CATEGORIES HERE! ****************** // Existing categories are persisted and they must never be removed. This may // happen implicitly, e.g. when an older version without some local category
diff --git a/components/ntp_snippets/category_rankers/constant_category_ranker.cc b/components/ntp_snippets/category_rankers/constant_category_ranker.cc index 6ddd284..01f22116 100644 --- a/components/ntp_snippets/category_rankers/constant_category_ranker.cc +++ b/components/ntp_snippets/category_rankers/constant_category_ranker.cc
@@ -12,9 +12,7 @@ namespace ntp_snippets { namespace { -// All categories must be present. An exception is -// KnownCategories::CONTEXTUAL because it is not handled by -// ContentSuggestionsService. +// All categories must be present. constexpr KnownCategories kKnownCategoriesDefaultOrder[] = { KnownCategories::READING_LIST, KnownCategories::ARTICLES, @@ -115,7 +113,7 @@ std::vector<KnownCategories> ConstantCategoryRanker::GetKnownCategoriesDefaultOrder() { static_assert( - static_cast<size_t>(KnownCategories::LOCAL_CATEGORIES_COUNT) == 7, + static_cast<size_t>(KnownCategories::LOCAL_CATEGORIES_COUNT) == 6, "Number of local categories has changed, please update " "ConstantCategoryRanker::kKnownCategoriesDefaultOrder to list all " "local KnownCategories for all orders.");
diff --git a/components/ntp_snippets/content_suggestions_metrics.cc b/components/ntp_snippets/content_suggestions_metrics.cc index b55533e..b4e8d01 100644 --- a/components/ntp_snippets/content_suggestions_metrics.cc +++ b/components/ntp_snippets/content_suggestions_metrics.cc
@@ -108,8 +108,6 @@ return HistogramCategories::ARTICLES; case KnownCategories::READING_LIST: return HistogramCategories::READING_LIST; - case KnownCategories::CONTEXTUAL: - return HistogramCategories::CONTEXTUAL; case KnownCategories::BOOKMARKS_DEPRECATED: return HistogramCategories::BOOKMARKS_DEPRECATED; case KnownCategories::DOWNLOADS_DEPRECATED:
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc deleted file mode 100644 index 3a88cdca..0000000 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" - -#include <iterator> -#include <memory> -#include <set> -#include <utility> - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" -#include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" - -namespace contextual_suggestions { - -using ntp_snippets::ContentSuggestion; -using ntp_snippets::RemoteSuggestionsDatabase; - -namespace { -bool IsEligibleURL(const GURL& url) { - return url.is_valid() && url.SchemeIsHTTPOrHTTPS() && !url.HostIsIPAddress(); -} - -} // namespace - -ContextualContentSuggestionsService::ContextualContentSuggestionsService( - std::unique_ptr<ContextualSuggestionsFetcher> - contextual_suggestions_fetcher, - std::unique_ptr<ContextualSuggestionsReporterProvider> reporter_provider) - : fetch_cache_(kFetchCacheCapacity), - contextual_suggestions_fetcher_( - std::move(contextual_suggestions_fetcher)), - reporter_provider_(std::move(reporter_provider)) {} - -ContextualContentSuggestionsService::~ContextualContentSuggestionsService() = - default; - -void ContextualContentSuggestionsService::FetchContextualSuggestionClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) { - // TODO(pnoland): Also check that the url is safe. - ContextualSuggestionsResult result; - if (IsEligibleURL(url) && !fetch_cache_.GetSuggestionsResult(url, &result)) { - FetchClustersCallback internal_callback = base::BindOnce( - &ContextualContentSuggestionsService::FetchDone, base::Unretained(this), - url, std::move(callback), metrics_callback); - contextual_suggestions_fetcher_->FetchContextualSuggestionsClusters( - url, std::move(internal_callback), metrics_callback); - } else if (result.peek_conditions.confidence < GetMinimumConfidence()) { - BelowConfidenceThresholdFetchDone(std::move(callback), metrics_callback); - } else { - std::move(callback).Run(result); - } -} - -void ContextualContentSuggestionsService::FetchDone( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback, - ContextualSuggestionsResult result) { - // We still want to cache low confidence results so that we avoid doing - // unnecessary fetches. - if (result.clusters.size() > 0) { - fetch_cache_.AddSuggestionsResult(url, result); - } - - if (result.peek_conditions.confidence < GetMinimumConfidence()) { - BelowConfidenceThresholdFetchDone(std::move(callback), metrics_callback); - return; - } - - std::move(callback).Run(result); -} - -ContextualSuggestionsDebuggingReporter* -ContextualContentSuggestionsService::GetDebuggingReporter() { - return reporter_provider_->GetDebuggingReporter(); -} - -base::flat_map<GURL, ContextualSuggestionsResult> -ContextualContentSuggestionsService::GetAllCachedResultsForDebugging() { - return fetch_cache_.GetAllCachedResultsForDebugging(); -} - -void ContextualContentSuggestionsService::ClearCachedResultsForDebugging() { - fetch_cache_.Clear(); -} - -std::unique_ptr< - contextual_suggestions::ContextualContentSuggestionsServiceProxy> -ContextualContentSuggestionsService::CreateProxy() { - return std::make_unique< - contextual_suggestions::ContextualContentSuggestionsServiceProxy>( - this, reporter_provider_->CreateReporter()); -} - -void ContextualContentSuggestionsService::BelowConfidenceThresholdFetchDone( - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) { - metrics_callback.Run(contextual_suggestions::FETCH_BELOW_THRESHOLD); - std::move(callback).Run(ContextualSuggestionsResult("", {}, PeekConditions(), - ServerExperimentInfos())); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service.h b/components/ntp_snippets/contextual/contextual_content_suggestions_service.h deleted file mode 100644 index de7dcde..0000000 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service.h +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_H_ - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/optional.h" -#include "components/keyed_service/core/keyed_service.h" -#include "components/ntp_snippets/callbacks.h" -#include "components/ntp_snippets/content_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_cache.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -namespace contextual_suggestions { - -static constexpr int kFetchCacheCapacity = 10; - -class ContextualContentSuggestionsServiceProxy; - -// Retrieves contextual suggestions for a given URL using caching. -class ContextualContentSuggestionsService : public KeyedService { - public: - ContextualContentSuggestionsService( - std::unique_ptr<ContextualSuggestionsFetcher> - contextual_suggestions_fetcher, - std::unique_ptr< - contextual_suggestions::ContextualSuggestionsReporterProvider> - reporter_provider); - ~ContextualContentSuggestionsService() override; - - // Asynchronously fetches contextual suggestions for the given URL. - virtual void FetchContextualSuggestionClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback); - - void FetchDone(const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback, - ContextualSuggestionsResult result); - - // Used to surface metrics events via chrome://eoc-internals. - ContextualSuggestionsDebuggingReporter* GetDebuggingReporter(); - - // Expose cached results for debugging. - base::flat_map<GURL, ContextualSuggestionsResult> - GetAllCachedResultsForDebugging(); - - // Clear the cached results for debugging. - void ClearCachedResultsForDebugging(); - - std::unique_ptr<ContextualContentSuggestionsServiceProxy> CreateProxy(); - - private: - void BelowConfidenceThresholdFetchDone( - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback); - - // Cache of contextual suggestions fetch results, keyed by the context url. - ContextualSuggestionsCache fetch_cache_; - - // Performs actual network request to fetch contextual suggestions. - std::unique_ptr<ContextualSuggestionsFetcher> contextual_suggestions_fetcher_; - - std::unique_ptr<contextual_suggestions::ContextualSuggestionsReporterProvider> - reporter_provider_; - - DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsService); -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_H_
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.cc deleted file mode 100644 index 1329c359..0000000 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.cc +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" - -#include <utility> - -#include "base/bind.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "ui/gfx/image/image.h" -#include "url/gurl.h" - -namespace contextual_suggestions { - -namespace { -// TODO(pnoland): check if this is the correct base URL for all images. -static constexpr char kImageURLFormat[] = - "http://www.google.com/images?q=tbn:%s"; - -GURL ImageUrlFromId(const std::string& image_id) { - return GURL(base::StringPrintf(kImageURLFormat, image_id.c_str())); -} -} // namespace - -ContextualContentSuggestionsServiceProxy:: - ContextualContentSuggestionsServiceProxy( - ContextualContentSuggestionsService* service, - std::unique_ptr<ContextualSuggestionsReporter> reporter) - : service_(service), - reporter_(std::move(reporter)), - last_ukm_source_id_(ukm::kInvalidSourceId), - weak_ptr_factory_(this) {} - -ContextualContentSuggestionsServiceProxy:: - ~ContextualContentSuggestionsServiceProxy() {} - -void ContextualContentSuggestionsServiceProxy::FetchContextualSuggestions( - const GURL& url, - FetchClustersCallback callback) { - service_->FetchContextualSuggestionClusters( - url, - base::BindOnce( - &ContextualContentSuggestionsServiceProxy::CacheSuggestions, - weak_ptr_factory_.GetWeakPtr(), std::move(callback)), - base::BindRepeating( - &ContextualContentSuggestionsServiceProxy::ReportEvent, - weak_ptr_factory_.GetWeakPtr(), last_ukm_source_id_, url.spec())); -} - -std::string -ContextualContentSuggestionsServiceProxy::GetContextualSuggestionImageUrl( - const std::string& suggestion_id) { - auto suggestion_iter = suggestions_.find(suggestion_id); - if (suggestion_iter == suggestions_.end()) { - DVLOG(1) << "Unkown suggestion ID: " << suggestion_id; - return ""; - } - - std::string& image_id = suggestion_iter->second.image_id; - return ImageUrlFromId(image_id).spec(); -} - -std::string -ContextualContentSuggestionsServiceProxy::GetContextualSuggestionFaviconUrl( - const std::string& suggestion_id) { - auto suggestion_iter = suggestions_.find(suggestion_id); - if (suggestion_iter == suggestions_.end()) { - DVLOG(1) << "Unkown suggestion ID: " << suggestion_id; - return ""; - } - - return suggestion_iter->second.favicon_image_url; -} - -void ContextualContentSuggestionsServiceProxy::ClearState() { - suggestions_.clear(); - weak_ptr_factory_.InvalidateWeakPtrs(); -} - -void ContextualContentSuggestionsServiceProxy::ReportEvent( - ukm::SourceId ukm_source_id, - const std::string& url, - ContextualSuggestionsEvent event) { - // TODO(pnoland): investigate how we can get into this state(one known - // example is if we switch tabs and there's no committed navigation in the new - // tab) and prevent it from happening. Replace the early return with a DCHECK - // once this is done. - if (ukm_source_id == ukm::kInvalidSourceId) { - return; - } - - // Flush the previous page (if any) and setup the new page. - if (ukm_source_id != last_ukm_source_id_) { - if (last_ukm_source_id_ != ukm::kInvalidSourceId) - reporter_->Flush(); - last_ukm_source_id_ = ukm_source_id; - reporter_->SetupForPage(url, ukm_source_id); - } - - reporter_->RecordEvent(event); -} - -void ContextualContentSuggestionsServiceProxy::FlushMetrics() { - if (last_ukm_source_id_ != ukm::kInvalidSourceId) - reporter_->Flush(); - last_ukm_source_id_ = ukm::kInvalidSourceId; -} - -void ContextualContentSuggestionsServiceProxy::CacheSuggestions( - FetchClustersCallback callback, - ContextualSuggestionsResult result) { - suggestions_.clear(); - for (auto& cluster : result.clusters) { - for (auto& suggestion : cluster.suggestions) { - suggestions_.emplace(std::make_pair(suggestion.id, suggestion)); - } - } - std::move(callback).Run(std::move(result)); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h deleted file mode 100644 index 19828d79..0000000 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_PROXY_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_PROXY_H_ - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" - -class GURL; - -namespace contextual_suggestions { - -// Class providing access to the Contextual Content Suggestions Service and -// caching the list of current suggestions shown in a tab. It is owned by a UI -// object. There could be multiple instances of serivce proxy. Either can be -// torn down with a part of UI that owns it, which doesn't affect other proxies. -class ContextualContentSuggestionsServiceProxy { - public: - ContextualContentSuggestionsServiceProxy( - ContextualContentSuggestionsService* service, - std::unique_ptr<ContextualSuggestionsReporter> reporter); - ~ContextualContentSuggestionsServiceProxy(); - - // Fetches contextual suggestions for a given |url|. - void FetchContextualSuggestions(const GURL& url, - FetchClustersCallback callback); - - // Get the URL for the given suggestion id. - std::string GetContextualSuggestionImageUrl(const std::string& suggestion_id); - - // Get the URL for the given suggestion id. - std::string GetContextualSuggestionFaviconUrl( - const std::string& suggestion_id); - - // Clears the state of the proxy. - void ClearState(); - - // Reports user interface event to the service. - void ReportEvent(ukm::SourceId, - const std::string& url, - ContextualSuggestionsEvent event); - - // Ensures that all metrics are properly flushed. - void FlushMetrics(); - - private: - void CacheSuggestions(FetchClustersCallback callback, - ContextualSuggestionsResult result); - // Pointer to the service. - ContextualContentSuggestionsService* service_; - // Cache of contextual suggestions. - std::map<std::string, ContextualSuggestion> suggestions_; - - // Sink for reporting metrics for this proxy. - std::unique_ptr<contextual_suggestions::ContextualSuggestionsReporter> - reporter_; - - // The most recent SourceId in use by metrics_reporter_, or - // ukm::kInvalidSourceId. - ukm::SourceId last_ukm_source_id_; - - // Weak pointer factory to cancel pending callbacks. - base::WeakPtrFactory<ContextualContentSuggestionsServiceProxy> - weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsServiceProxy); -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_CONTENT_SUGGESTIONS_SERVICE_PROXY_H_
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy_unittest.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy_unittest.cc deleted file mode 100644 index ca36b2e..0000000 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy_unittest.cc +++ /dev/null
@@ -1,124 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service_proxy.h" - -#include <memory> -#include <string> -#include <utility> - -#include "base/bind.h" -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_test_utils.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "components/ntp_snippets/remote/remote_suggestions_database.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::IsEmpty; -using testing::Pointee; - -namespace contextual_suggestions { - -namespace { - -static constexpr char kTestPeekText[] = "Test peek test"; -static constexpr char kValidFromUrl[] = "http://some.url"; - -static constexpr char kImageId[] = "id"; -// Keep the string after tbn: in sync with the above constant for image id. -static constexpr char kImageUrl[] = "http://www.google.com/images?q=tbn:id"; -static constexpr char kFaviconUrl[] = "http://google.com/cats.fav"; - -class FakeContextualContentSuggestionsService - : public ContextualContentSuggestionsService { - public: - FakeContextualContentSuggestionsService(); - ~FakeContextualContentSuggestionsService() override; - - void FetchContextualSuggestionClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) override { - clusters_callback_ = std::move(callback); - } - - void RunClustersCallback(ContextualSuggestionsResult result) { - std::move(clusters_callback_).Run(std::move(result)); - } - - private: - FetchClustersCallback clusters_callback_; -}; - -FakeContextualContentSuggestionsService:: - FakeContextualContentSuggestionsService() - : ContextualContentSuggestionsService(nullptr, nullptr) {} - -FakeContextualContentSuggestionsService:: - ~FakeContextualContentSuggestionsService() {} -} // namespace - -class ContextualContentSuggestionsServiceProxyTest : public testing::Test { - public: - void SetUp() override; - - FakeContextualContentSuggestionsService* service() { return service_.get(); } - - ContextualContentSuggestionsServiceProxy* proxy() { return proxy_.get(); } - - private: - std::unique_ptr<FakeContextualContentSuggestionsService> service_; - std::unique_ptr<ContextualContentSuggestionsServiceProxy> proxy_; -}; - -void ContextualContentSuggestionsServiceProxyTest::SetUp() { - service_ = std::make_unique<FakeContextualContentSuggestionsService>(); - auto metrics_reporter = - std::make_unique<ContextualSuggestionsMetricsReporter>(); - proxy_ = std::make_unique<ContextualContentSuggestionsServiceProxy>( - service_.get(), std::move(metrics_reporter)); -} - -TEST_F(ContextualContentSuggestionsServiceProxyTest, - FetchSuggestionsWhenEmpty) { - MockClustersCallback mock_cluster_callback; - - proxy()->FetchContextualSuggestions(GURL(kValidFromUrl), - mock_cluster_callback.ToOnceCallback()); - service()->RunClustersCallback( - ContextualSuggestionsResult(kTestPeekText, std::vector<Cluster>(), - PeekConditions(), ServerExperimentInfos())); - - EXPECT_TRUE(mock_cluster_callback.has_run); -} - -TEST_F(ContextualContentSuggestionsServiceProxyTest, GetImageUrl) { - auto suggestion = SuggestionBuilder(GURL(kValidFromUrl)) - .ImageId(kImageId) - .FaviconImageUrl(kFaviconUrl) - .Build(); - auto cluster = - ClusterBuilder(kValidFromUrl).AddSuggestion(suggestion).Build(); - MockClustersCallback mock_cluster_callback; - - proxy()->FetchContextualSuggestions(GURL(kValidFromUrl), - mock_cluster_callback.ToOnceCallback()); - service()->RunClustersCallback(ContextualSuggestionsResult( - kTestPeekText, std::vector<Cluster>({cluster}), PeekConditions(), - ServerExperimentInfos())); - - EXPECT_EQ(kImageUrl, proxy()->GetContextualSuggestionImageUrl(suggestion.id)); - EXPECT_EQ(kFaviconUrl, - proxy()->GetContextualSuggestionFaviconUrl(suggestion.id)); - - // Id not found. - EXPECT_EQ("", proxy()->GetContextualSuggestionImageUrl("")); - EXPECT_EQ("", proxy()->GetContextualSuggestionFaviconUrl("")); -} - -// TODO(fgorski): More tests will be added, once we have the suggestions -// restructured. - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc b/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc deleted file mode 100644 index ae4ea73..0000000 --- a/components/ntp_snippets/contextual/contextual_content_suggestions_service_unittest.cc +++ /dev/null
@@ -1,288 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_content_suggestions_service.h" - -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/strings/string_number_conversions.h" -#include "base/test/mock_callback.h" -#include "base/test/scoped_task_environment.h" -#include "components/ntp_snippets/category_info.h" -#include "components/ntp_snippets/content_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_test_utils.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" -#include "components/ntp_snippets/remote/json_to_categories.h" -#include "components/ntp_snippets/remote/request_throttler.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/testing_pref_service.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ntp_snippets::Category; -using ntp_snippets::ContentSuggestion; -using ntp_snippets::KnownCategories; -using ntp_snippets::RequestThrottler; - -using testing::_; -using testing::AllOf; -using testing::ElementsAre; -using testing::IsEmpty; -using testing::Mock; -using testing::Pointee; -using testing::Property; - -namespace contextual_suggestions { - -namespace { - -// Always fetches the result that was set by SetFakeResponse. -class FakeContextualSuggestionsFetcher : public ContextualSuggestionsFetcher { - public: - void FetchContextualSuggestionsClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) override { - ContextualSuggestionsResult result; - result.peek_text = "peek text"; - result.clusters = std::move(fake_suggestions_); - result.peek_conditions = peek_conditions_; - std::move(callback).Run(std::move(result)); - fake_suggestions_.clear(); - } - - void SetFakeResponse(std::vector<Cluster> fake_suggestions, - PeekConditions peek_conditions = PeekConditions()) { - fake_suggestions_ = std::move(fake_suggestions); - peek_conditions_ = peek_conditions; - } - - private: - std::vector<Cluster> fake_suggestions_; - PeekConditions peek_conditions_; -}; - -} // namespace - -class ContextualContentSuggestionsServiceTest : public testing::Test { - public: - ContextualContentSuggestionsServiceTest() { - RequestThrottler::RegisterProfilePrefs(pref_service_.registry()); - std::unique_ptr<FakeContextualSuggestionsFetcher> fetcher = - std::make_unique<FakeContextualSuggestionsFetcher>(); - fetcher_ = fetcher.get(); - auto debugging_reporter = std::make_unique< - contextual_suggestions::ContextualSuggestionsDebuggingReporter>(); - auto reporter_provider = std::make_unique< - contextual_suggestions::ContextualSuggestionsReporterProvider>( - std::move(debugging_reporter)); - source_ = std::make_unique<ContextualContentSuggestionsService>( - std::move(fetcher), - std::move(reporter_provider)); - } - - FakeContextualSuggestionsFetcher* fetcher() { return fetcher_; } - ContextualContentSuggestionsService* source() { return source_.get(); } - - private: - FakeContextualSuggestionsFetcher* fetcher_; - base::test::ScopedTaskEnvironment scoped_task_environment_; - TestingPrefServiceSimple pref_service_; - std::unique_ptr<ContextualContentSuggestionsService> source_; - - DISALLOW_COPY_AND_ASSIGN(ContextualContentSuggestionsServiceTest); -}; - -TEST_F(ContextualContentSuggestionsServiceTest, - ShouldFetchContextualSuggestionsClusters) { - MockClustersCallback mock_callback; - std::vector<Cluster> clusters; - GURL context_url("http://www.from.url"); - - clusters.emplace_back(ClusterBuilder("Title") - .AddSuggestion(SuggestionBuilder(context_url) - .Title("Title1") - .PublisherName("from.url") - .Snippet("Summary") - .ImageId("abc") - .Build()) - .Build()); - - fetcher()->SetFakeResponse(std::move(clusters)); - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - base::RunLoop().RunUntilIdle(); - - EXPECT_TRUE(mock_callback.has_run); -} - -TEST_F(ContextualContentSuggestionsServiceTest, ShouldRejectInvalidUrls) { - std::vector<Cluster> clusters; - for (GURL invalid_url : - {GURL("htp:/"), GURL("www.foobar"), GURL("http://127.0.0.1/"), - GURL("file://some.file"), GURL("chrome://settings"), GURL("")}) { - MockClustersCallback mock_callback; - source()->FetchContextualSuggestionClusters( - invalid_url, - base::BindOnce(&MockClustersCallback::Done, - base::Unretained(&mock_callback)), - base::DoNothing()); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(mock_callback.has_run); - EXPECT_EQ(mock_callback.response_peek_text, ""); - EXPECT_EQ(mock_callback.response_clusters.size(), 0u); - } -} - -TEST_F(ContextualContentSuggestionsServiceTest, - ShouldNotReportLowConfidenceResults) { - MockClustersCallback mock_callback; - std::vector<Cluster> clusters; - GURL context_url("http://www.from.url"); - - clusters.emplace_back(ClusterBuilder("Title") - .AddSuggestion(SuggestionBuilder(context_url) - .Title("Title1") - .PublisherName("from.url") - .Snippet("Summary") - .ImageId("abc") - .Build()) - .Build()); - - PeekConditions peek_conditions; - peek_conditions.confidence = 0.5; - - fetcher()->SetFakeResponse(std::move(clusters), peek_conditions); - - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - base::RunLoop().RunUntilIdle(); - - EXPECT_TRUE(mock_callback.has_run); - EXPECT_EQ(mock_callback.response_clusters.size(), 0u); - EXPECT_EQ(mock_callback.response_peek_text, std::string()); -} - -TEST_F(ContextualContentSuggestionsServiceTest, ShouldCacheResults) { - MockClustersCallback mock_callback; - MockClustersCallback mock_callback2; - std::vector<Cluster> clusters; - GURL context_url("http://www.from.url"); - - clusters.emplace_back(ClusterBuilder("Title") - .AddSuggestion(SuggestionBuilder(context_url) - .Title("Title1") - .PublisherName("from.url") - .Snippet("Summary") - .ImageId("abc") - .Build()) - .Build()); - fetcher()->SetFakeResponse(clusters); - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - base::RunLoop().RunUntilIdle(); - - EXPECT_TRUE(mock_callback.has_run); - - // The correct result should be present even though we haven't set the fake - // response. - source()->FetchContextualSuggestionClusters( - context_url, mock_callback2.ToOnceCallback(), base::DoNothing()); - EXPECT_TRUE(mock_callback2.has_run); - ExpectResponsesMatch( - mock_callback2, - ContextualSuggestionsResult("peek text", clusters, PeekConditions(), - ServerExperimentInfos())); -} - -TEST_F(ContextualContentSuggestionsServiceTest, ShouldEvictOldCachedResults) { - std::vector<Cluster> clusters; - clusters.emplace_back( - ClusterBuilder("Title") - .AddSuggestion(SuggestionBuilder(GURL("http://foobar.com")) - .Title("Title1") - .PublisherName("from.url") - .Snippet("Summary") - .ImageId("abc") - .Build()) - .Build()); - - for (int i = 0; i < kFetchCacheCapacity + 1; i++) { - MockClustersCallback mock_callback; - GURL context_url("http://www.from.url/" + base::NumberToString(i)); - - fetcher()->SetFakeResponse(clusters); - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - base::RunLoop().RunUntilIdle(); - - ExpectResponsesMatch( - mock_callback, - ContextualSuggestionsResult("peek text", clusters, PeekConditions(), - ServerExperimentInfos())); - } - - // Urls numbered kFetchCacheCapacity through 1 should be cached still; 0 - // should have been evicted. - for (int i = kFetchCacheCapacity; i > 0; i--) { - GURL context_url("http://www.from.url/" + base::NumberToString(i)); - MockClustersCallback mock_callback; - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - ExpectResponsesMatch( - mock_callback, - ContextualSuggestionsResult("peek text", clusters, PeekConditions(), - ServerExperimentInfos())); - } - - GURL context_url("http://www.from.url/0"); - MockClustersCallback mock_callback; - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - EXPECT_EQ(mock_callback.response_clusters.size(), 0u); -} - -TEST_F(ContextualContentSuggestionsServiceTest, - ShouldNotReturnCachedLowConfidenceResults) { - MockClustersCallback mock_callback; - MockClustersCallback mock_callback2; - std::vector<Cluster> clusters; - GURL context_url("http://www.from.url"); - - clusters.emplace_back(ClusterBuilder("Title") - .AddSuggestion(SuggestionBuilder(context_url) - .Title("Title1") - .PublisherName("from.url") - .Snippet("Summary") - .ImageId("abc") - .Build()) - .Build()); - PeekConditions peek_conditions; - peek_conditions.confidence = 0; - fetcher()->SetFakeResponse(clusters, peek_conditions); - source()->FetchContextualSuggestionClusters( - context_url, mock_callback.ToOnceCallback(), base::DoNothing()); - base::RunLoop().RunUntilIdle(); - - EXPECT_TRUE(mock_callback.has_run); - ExpectResponsesMatch(mock_callback, ContextualSuggestionsResult()); - - // The cached result we get back should be empty, since its confidence is - // below the threshold. - source()->FetchContextualSuggestionClusters( - context_url, mock_callback2.ToOnceCallback(), base::DoNothing()); - EXPECT_TRUE(mock_callback2.has_run); - ExpectResponsesMatch(mock_callback2, ContextualSuggestionsResult()); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestion.cc b/components/ntp_snippets/contextual/contextual_suggestion.cc deleted file mode 100644 index d71dcb3..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestion.cc +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> -#include <utility> - -#include "components/ntp_snippets/contextual/contextual_suggestion.h" - -namespace contextual_suggestions { - -ContextualSuggestion::ContextualSuggestion() = default; - -ContextualSuggestion::ContextualSuggestion(const ContextualSuggestion& other) = - default; - -// MSVC doesn't support defaulted move constructors, so we have to define it -// ourselves. -ContextualSuggestion::ContextualSuggestion( - ContextualSuggestion&& other) noexcept - : id(std::move(other.id)), - title(std::move(other.title)), - url(std::move(other.url)), - publisher_name(std::move(other.publisher_name)), - snippet(std::move(other.snippet)), - image_id(std::move(other.image_id)), - favicon_image_id(std::move(other.favicon_image_id)), - favicon_image_url(std::move(other.favicon_image_url)) {} - -ContextualSuggestion::~ContextualSuggestion() = default; - -ContextualSuggestion& ContextualSuggestion::operator=( - const ContextualSuggestion&) = default; - -SuggestionBuilder::SuggestionBuilder(const GURL& url) { - suggestion_.url = url; - suggestion_.id = url.spec(); -} - -SuggestionBuilder& SuggestionBuilder::Title(const std::string& title) { - suggestion_.title = title; - return *this; -} - -SuggestionBuilder& SuggestionBuilder::PublisherName( - const std::string& publisher_name) { - suggestion_.publisher_name = publisher_name; - return *this; -} - -SuggestionBuilder& SuggestionBuilder::Snippet(const std::string& snippet) { - suggestion_.snippet = snippet; - return *this; -} - -SuggestionBuilder& SuggestionBuilder::ImageId(const std::string& image_id) { - suggestion_.image_id = image_id; - return *this; -} - -SuggestionBuilder& SuggestionBuilder::FaviconImageId( - const std::string& favicon_image_id) { - suggestion_.favicon_image_id = favicon_image_id; - return *this; -} - -SuggestionBuilder& SuggestionBuilder::FaviconImageUrl( - const std::string& favicon_image_url) { - suggestion_.favicon_image_url = favicon_image_url; - return *this; -} - -ContextualSuggestion SuggestionBuilder::Build() { - return std::move(suggestion_); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestion.h b/components/ntp_snippets/contextual/contextual_suggestion.h deleted file mode 100644 index 28f4b51..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestion.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTION_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTION_H_ - -#include <string> - -#include "url/gurl.h" - -namespace contextual_suggestions { - -// Struct containing the data for a single contextual content suggestion. -struct ContextualSuggestion { - ContextualSuggestion(); - ContextualSuggestion(const ContextualSuggestion&); - ContextualSuggestion(ContextualSuggestion&&) noexcept; - ~ContextualSuggestion(); - - ContextualSuggestion& operator=(const ContextualSuggestion&); - - // The ID identifying the suggestion. - std::string id; - - // Title of the suggestion. - std::string title; - - // The URL of the suggested page. - GURL url; - - // The name of the content's publisher. - std::string publisher_name; - - // Summary or relevant extract from the content. - std::string snippet; - - // Identifier of the image to display alongside the suggestion. This id can - // be used to construct a URL to the image. - std::string image_id; - - // As above, but for identifying the favicon for the site the suggestion - // resides on. - std::string favicon_image_id; - - // The favicon URL for the suggestion. - std::string favicon_image_url; -}; - -// Allows compact, precise construction of a ContextualSuggestion. Its main -// purpose is to avoid using a confusing 6 param helper whose argument -// order has to be guessed at. -class SuggestionBuilder { - public: - explicit SuggestionBuilder(const GURL& url); - - SuggestionBuilder& Title(const std::string& title); - SuggestionBuilder& PublisherName(const std::string& publisher_name); - SuggestionBuilder& Snippet(const std::string& snippet); - SuggestionBuilder& ImageId(const std::string& image_id); - SuggestionBuilder& FaviconImageId(const std::string& favicon_image_id); - SuggestionBuilder& FaviconImageUrl(const std::string& favicon_image_url); - ContextualSuggestion Build(); - - private: - ContextualSuggestion suggestion_; -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTION_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_cache.cc b/components/ntp_snippets/contextual/contextual_suggestions_cache.cc deleted file mode 100644 index 07b282d..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_cache.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_cache.h" - -namespace contextual_suggestions { - -ContextualSuggestionsCache::ContextualSuggestionsCache(size_t capacity) - : cache_(capacity) {} -ContextualSuggestionsCache::~ContextualSuggestionsCache() = default; - -base::flat_map<GURL, ContextualSuggestionsResult> -ContextualSuggestionsCache::GetAllCachedResultsForDebugging() { - return base::flat_map<GURL, ContextualSuggestionsResult>(cache_.begin(), - cache_.end()); -} - -bool ContextualSuggestionsCache::GetSuggestionsResult( - const GURL& url, - ContextualSuggestionsResult* result) { - auto cache_iter = cache_.Get(url); - if (cache_iter == cache_.end()) { - return false; - } - - *result = cache_iter->second; - return true; -} - -void ContextualSuggestionsCache::AddSuggestionsResult( - const GURL& url, - ContextualSuggestionsResult result) { - cache_.Put(url, result); -} - -void ContextualSuggestionsCache::Clear() { - cache_.Clear(); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_cache.h b/components/ntp_snippets/contextual/contextual_suggestions_cache.h deleted file mode 100644 index b1639bd..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_cache.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_CACHE_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_CACHE_H_ - -#include "base/containers/flat_map.h" -#include "base/containers/mru_cache.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" -#include "url/gurl.h" - -namespace contextual_suggestions { - -// Wrapper for an LRU cache of ContextualSuggestionResult objects, keyed by -// context URL. -class ContextualSuggestionsCache { - public: - explicit ContextualSuggestionsCache(size_t capacity); - ~ContextualSuggestionsCache(); - - // Attempts to find a result for |url| in this cache, returning true and - // putting the result into |result| if successful. - bool GetSuggestionsResult(const GURL& url, - ContextualSuggestionsResult* result); - // Adds |result| to this cache for the key |url|, overwriting any previous - // value associated with |url| and potentially evicting the oldest item in the - // cache. - void AddSuggestionsResult(const GURL& url, - ContextualSuggestionsResult result); - // Removes all items from the cache. - void Clear(); - - // Returns all suggestion results for debugging purposes. - base::flat_map<GURL, ContextualSuggestionsResult> - GetAllCachedResultsForDebugging(); - - private: - base::MRUCache<GURL, ContextualSuggestionsResult> cache_; -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_CACHE_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_features.cc b/components/ntp_snippets/contextual/contextual_suggestions_features.cc deleted file mode 100644 index 7de6afd..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_features.cc +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/metrics/field_trial_params.h" - -namespace contextual_suggestions { - -const base::Feature kContextualSuggestionsButton{ - "ContextualSuggestionsButton", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kContextualSuggestionsIPHReverseScroll{ - "ContextualSuggestionsIPHReverseScroll", base::FEATURE_ENABLED_BY_DEFAULT}; - -const base::Feature kContextualSuggestionsOptOut{ - "ContextualSuggestionsOptOut", base::FEATURE_DISABLED_BY_DEFAULT}; - -// Default minimum confidence value for contextual suggestions. -static constexpr double kMinimumConfidenceDefault = .75; - -// Provides ability to customize the minimum confidence parameter. -base::FeatureParam<double> kContextualSuggestionsMinimumConfidenceParam{ - &kContextualSuggestionsButton, "minimum_confidence", - kMinimumConfidenceDefault}; - -double GetMinimumConfidence() { - double minimum_confidence = - kContextualSuggestionsMinimumConfidenceParam.Get(); - LOG_IF(ERROR, minimum_confidence < 0.0 || minimum_confidence > 1.0) - << "Specified minimum confidence outside of allowed range."; - return std::max(0.0, std::min(minimum_confidence, 1.0)); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_features.h b/components/ntp_snippets/contextual/contextual_suggestions_features.h deleted file mode 100644 index ba02a6bc..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_features.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FEATURES_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FEATURES_H_ - -#include "base/feature_list.h" - -namespace contextual_suggestions { - -extern const base::Feature kContextualSuggestionsButton; -extern const base::Feature kContextualSuggestionsIPHReverseScroll; -extern const base::Feature kContextualSuggestionsOptOut; - -// Returns the minimum confidence threshold for showing contextual suggestions. -// The value will be in range [0.0, 1.0] (inclusive). -double GetMinimumConfidence(); - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FEATURES_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_features_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_features_unittest.cc deleted file mode 100644 index bbd151cd..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_features_unittest.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" - -#include <map> -#include <string> - -#include "base/test/scoped_feature_list.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace contextual_suggestions { - -TEST(ContextualSuggestionsFeaturesTest, GetMinimumConfidence_DefaultValue) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kContextualSuggestionsButton); - EXPECT_EQ(0.75, GetMinimumConfidence()); -} - -TEST(ContextualSuggestionsFeaturesTest, GetMinimumConfidence_ParamValue) { - base::test::ScopedFeatureList feature_list; - std::map<std::string, std::string> parameters; - parameters["minimum_confidence"] = "0.6"; - feature_list.InitAndEnableFeatureWithParameters(kContextualSuggestionsButton, - parameters); - EXPECT_EQ(0.6, GetMinimumConfidence()); -} - -TEST(ContextualSuggestionsFeaturesTest, GetMinimumConfidence_Minimum) { - base::test::ScopedFeatureList feature_list; - std::map<std::string, std::string> parameters; - parameters["minimum_confidence"] = "-0.6"; - feature_list.InitAndEnableFeatureWithParameters(kContextualSuggestionsButton, - parameters); - EXPECT_EQ(0.0, GetMinimumConfidence()); -} - -TEST(ContextualSuggestionsFeaturesTest, GetMinimumConfidence_Maximum) { - base::test::ScopedFeatureList feature_list; - std::map<std::string, std::string> parameters; - parameters["minimum_confidence"] = "1.6"; - feature_list.InitAndEnableFeatureWithParameters(kContextualSuggestionsButton, - parameters); - EXPECT_EQ(1.0, GetMinimumConfidence()); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc deleted file mode 100644 index 5ac6cb4..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc +++ /dev/null
@@ -1,371 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <vector> - -#include "components/ntp_snippets/contextual/contextual_suggestions_fetch.h" - -#include "base/base64.h" -#include "base/base64url.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/metrics/field_trial_params.h" -#include "base/metrics/histogram_functions.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "components/ntp_snippets/contextual/contextual_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" -#include "components/ntp_snippets/contextual/proto/chrome_search_api_request_context.pb.h" -#include "components/ntp_snippets/contextual/proto/get_pivots_request.pb.h" -#include "components/ntp_snippets/contextual/proto/get_pivots_response.pb.h" -#include "components/variations/net/variations_http_headers.h" -#include "net/base/escape.h" -#include "net/base/load_flags.h" -#include "net/http/http_request_headers.h" -#include "net/http/http_status_code.h" -#include "services/network/public/cpp/resource_request.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/simple_url_loader.h" -#include "third_party/protobuf/src/google/protobuf/io/coded_stream.h" - -using base::Base64Encode; - -namespace contextual_suggestions { - -namespace { - -static constexpr char kFetchEndpointUrlKey[] = - "contextual-suggestions-fetch-endpoint"; -static constexpr char kDefaultFetchEndpointUrl[] = "https://www.google.com"; -static constexpr char kFetchEndpointServicePath[] = - "/httpservice/web/ExploreService/GetPivots/"; - -static constexpr int kNumberOfSuggestionsToFetch = 10; -static constexpr int kMinNumberOfClusters = 1; -static constexpr int kMaxNumberOfClusters = 5; - -// Wrapper for net::UnescapeForHTML that also handles utf8<->16 conversion. -std::string Unescape(const std::string& encoded_text) { - return base::UTF16ToUTF8( - net::UnescapeForHTML(base::UTF8ToUTF16(encoded_text))); -} - -// Converts |item| to a ContextualSuggestion, un-escaping any HTML entities -// encountered. -ContextualSuggestion ItemToSuggestion(const PivotItem& item) { - PivotDocument document = item.document(); - - std::string favicon_url; - if (document.favicon_image().source_data().has_raster()) { - favicon_url = - document.favicon_image().source_data().raster().url().raw_url(); - } - - return SuggestionBuilder(GURL(document.url().raw_url())) - .Title(Unescape(document.title())) - .Snippet(Unescape(document.summary())) - .PublisherName(Unescape(document.site_name())) - .ImageId(document.image().id().encrypted_docid()) - .FaviconImageId(document.favicon_image().id().encrypted_docid()) - .FaviconImageUrl(favicon_url) - .Build(); -} - -Cluster PivotToCluster(const PivotCluster& pivot) { - ClusterBuilder cluster_builder(pivot.label().label()); - for (PivotItem item : pivot.item()) { - cluster_builder.AddSuggestion(ItemToSuggestion(item)); - } - - return cluster_builder.Build(); -} - -PeekConditions GetPeekConditionsFromResponse( - const GetPivotsResponse& response_proto) { - AutoPeekConditions proto_conditions = - response_proto.pivots().auto_peek_conditions(); - PeekConditions peek_conditions; - - peek_conditions.confidence = proto_conditions.confidence(); - peek_conditions.page_scroll_percentage = - proto_conditions.page_scroll_percentage(); - peek_conditions.minimum_seconds_on_page = - proto_conditions.minimum_seconds_on_page(); - peek_conditions.maximum_number_of_peeks = - proto_conditions.maximum_number_of_peeks(); - return peek_conditions; -} - -std::vector<Cluster> GetClustersFromResponse( - const GetPivotsResponse& response_proto) { - std::vector<Cluster> clusters; - Pivots pivots = response_proto.pivots(); - - if (pivots.item_size() > 0) { - // If the first item is a cluster, we can assume they all are. - if (pivots.item()[0].has_cluster()) { - clusters.reserve(response_proto.pivots().item_size()); - for (auto item : response_proto.pivots().item()) { - if (item.has_cluster()) { - PivotCluster pivot_cluster = item.cluster(); - clusters.emplace_back(PivotToCluster(pivot_cluster)); - } - } - } else if (pivots.item()[0].has_document()) { - Cluster single_cluster; - for (auto item : pivots.item()) { - single_cluster.suggestions.emplace_back(ItemToSuggestion(item)); - } - clusters.emplace_back(std::move(single_cluster)); - } - } - - return clusters; -} - -std::string GetPeekTextFromResponse(const GetPivotsResponse& response_proto) { - return response_proto.pivots().peek_text().text(); -} - -const std::string SerializedPivotsRequest(const std::string& url, - const std::string& bcp_language) { - GetPivotsRequest pivot_request; - - SearchApiRequestContext* search_context = pivot_request.mutable_context(); - search_context->mutable_localization_context()->set_language_code( - bcp_language); - - GetPivotsQuery* query = pivot_request.mutable_query(); - query->add_context()->set_url(url); - - PivotDocumentParams* params = query->mutable_document_params(); - params->set_enabled(true); - params->set_num(kNumberOfSuggestionsToFetch); - params->set_enable_images(true); - params->set_image_aspect_ratio(PivotDocumentParams::SQUARE); - - PivotClusteringParams* cluster_params = query->mutable_clustering_params(); - cluster_params->set_enabled(true); - cluster_params->set_min(kMinNumberOfClusters); - cluster_params->set_max(kMaxNumberOfClusters); - - query->mutable_peek_text_params()->set_enabled(true); - - return pivot_request.SerializeAsString(); -} - -ServerExperimentInfos GetServerExperimentInfosFromResponse( - const GetPivotsResponse& response_proto) { - ServerExperimentInfos field_trials; - for (auto experiment_info : response_proto.pivots().experiment_info()) { - std::string trial_name = experiment_info.experiment_group_name(); - std::string group_name = experiment_info.experiment_arm_name(); - if (!trial_name.empty() && !group_name.empty()) - field_trials.emplace_back(std::move(trial_name), std::move(group_name)); - } - - return field_trials; -} - -ContextualSuggestionsResult ResultFromResponse( - const GetPivotsResponse& response_proto) { - return ContextualSuggestionsResult( - GetPeekTextFromResponse(response_proto), - GetClustersFromResponse(response_proto), - GetPeekConditionsFromResponse(response_proto), - GetServerExperimentInfosFromResponse(response_proto)); -} - -} // namespace - -ContextualSuggestionsFetch::ContextualSuggestionsFetch( - const GURL& url, - const std::string& bcp_language_code) - : url_(url), bcp_language_code_(bcp_language_code) {} - -ContextualSuggestionsFetch::~ContextualSuggestionsFetch() = default; - -// static -const std::string ContextualSuggestionsFetch::GetFetchEndpoint() { - std::string fetch_endpoint; - if (base::CommandLine::ForCurrentProcess()->HasSwitch(kFetchEndpointUrlKey)) { - fetch_endpoint = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - kFetchEndpointUrlKey); - } else { - fetch_endpoint = base::GetFieldTrialParamValueByFeature( - kContextualSuggestionsButton, kFetchEndpointUrlKey); - } - - if (!base::StartsWith(fetch_endpoint, "https://", - base::CompareCase::INSENSITIVE_ASCII)) { - fetch_endpoint = kDefaultFetchEndpointUrl; - } - - fetch_endpoint.append(kFetchEndpointServicePath); - - return fetch_endpoint; -} - -void ContextualSuggestionsFetch::Start( - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback, - const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory) { - request_completed_callback_ = std::move(callback); - url_loader_ = MakeURLLoader(); - url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - loader_factory.get(), - base::BindOnce(&ContextualSuggestionsFetch::OnURLLoaderComplete, - base::Unretained(this), std::move(metrics_callback))); -} - -std::unique_ptr<network::SimpleURLLoader> -ContextualSuggestionsFetch::MakeURLLoader() const { - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("ntp_contextual_suggestions_fetch", - R"( - semantics { - sender: "Contextual Suggestions Fetch" - description: - "Chromium can show contextual suggestions that are related to the " - "currently visited page." - trigger: - "Triggered when a page is visited and stayed on for more than a " - "few seconds." - data: - "The URL of the current tab and the ui language." - destination: GOOGLE_OWNED_SERVICE - } - policy { - cookies_allowed: NO - setting: - "This feature can be disabled by turning off the " - "'Suggest related pages' in Chrome for Android settings" - policy_exception_justification: "Not implemented. The feature is " - "currently Android-only and disabled for all enterprise users. " - "A policy will be added before enabling for enterprise users." - })"); - - auto resource_request = MakeResourceRequest(); - - auto simple_loader = network::SimpleURLLoader::Create( - std::move(resource_request), traffic_annotation); - simple_loader->SetAllowHttpErrorResults(true); - return simple_loader; -} - -std::unique_ptr<network::ResourceRequest> -ContextualSuggestionsFetch::MakeResourceRequestForTesting() const { - return MakeResourceRequest(); -} - -std::unique_ptr<network::ResourceRequest> -ContextualSuggestionsFetch::MakeResourceRequest() const { - auto resource_request = std::make_unique<network::ResourceRequest>(); - - resource_request->url = GURL(GetFetchEndpoint()); - resource_request->method = "GET"; - AppendHeaders(resource_request.get()); - resource_request->load_flags = net::LOAD_BYPASS_CACHE; - resource_request->allow_credentials = false; - - return resource_request; -} - -void ContextualSuggestionsFetch::AppendHeaders( - network::ResourceRequest* resource_request) const { - net::HttpRequestHeaders headers; - std::string serialized_request_body = - SerializedPivotsRequest(url_.spec(), bcp_language_code_); - std::string base64_encoded_body; - base::Base64UrlEncode(serialized_request_body, - base::Base64UrlEncodePolicy::INCLUDE_PADDING, - &base64_encoded_body); - headers.SetHeader("X-Protobuffer-Request-Payload", base64_encoded_body); - variations::AppendVariationsHeader( - resource_request->url, variations::InIncognito::kNo, - variations::SignedIn::kNo, resource_request); - - UMA_HISTOGRAM_COUNTS_1M( - "ContextualSuggestions.FetchRequestProtoSizeKB", - static_cast<int>(base64_encoded_body.length() / 1024)); - - resource_request->headers = headers; -} - -void ContextualSuggestionsFetch::OnURLLoaderComplete( - ReportFetchMetricsCallback metrics_callback, - std::unique_ptr<std::string> result) { - ContextualSuggestionsResult suggestions_result; - - if (result) { - int32_t response_code = - url_loader_->ResponseInfo()->headers->response_code(); - if (response_code == net::HTTP_OK) { - // The response comes in the format (length, bytes) where length is a - // varint32 encoded int. Rather than hand-rolling logic to skip the - // length(which we don't actually need), we use EncodedInputStream to - // skip past it, then parse the remainder of the stream. - google::protobuf::io::CodedInputStream coded_stream( - reinterpret_cast<const uint8_t*>(result->data()), result->length()); - uint32_t response_size; - if (coded_stream.ReadVarint32(&response_size) && response_size != 0) { - GetPivotsResponse response_proto; - if (response_proto.MergePartialFromCodedStream(&coded_stream)) { - suggestions_result = ResultFromResponse(response_proto); - } - } - } - } - - ReportFetchMetrics(suggestions_result.clusters.size(), - std::move(metrics_callback)); - std::move(request_completed_callback_).Run(std::move(suggestions_result)); -} - -void ContextualSuggestionsFetch::ReportFetchMetrics( - size_t clusters_size, - ReportFetchMetricsCallback metrics_callback) { - int32_t error_code = url_loader_->NetError(); - int32_t response_code = 0; - - base::UmaHistogramSparse("ContextualSuggestions.FetchErrorCode", error_code); - if (error_code == net::OK) { - const network::ResourceResponseHead* response_info = - url_loader_->ResponseInfo(); - response_code = response_info->headers->response_code(); - if (response_code > 0) { - base::UmaHistogramSparse("ContextualSuggestions.FetchResponseCode", - response_code); - - UMA_HISTOGRAM_COUNTS_1M("ContextualSuggestions.FetchResponseNetworkBytes", - response_info->encoded_data_length); - } - - base::TimeDelta latency_delta = - response_info->response_time - response_info->request_time; - UMA_HISTOGRAM_COUNTS_1M("ContextualSuggestions.FetchLatencyMilliseconds", - latency_delta.InMilliseconds()); - } - - ContextualSuggestionsEvent event; - if (error_code != net::OK) { - event = FETCH_ERROR; - } else if (response_code == net::HTTP_SERVICE_UNAVAILABLE) { - event = FETCH_SERVER_BUSY; - } else if (response_code != net::HTTP_OK) { - event = FETCH_ERROR; - } else if (clusters_size == 0) { - event = FETCH_EMPTY; - } else { - event = FETCH_COMPLETED; - } - - std::move(metrics_callback).Run(event); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetch.h b/components/ntp_snippets/contextual/contextual_suggestions_fetch.h deleted file mode 100644 index 15f371a4e0..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetch.h +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCH_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCH_H_ - -#include <memory> -#include <string> -#include <utility> - -#include "base/callback.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "net/base/load_flags.h" -#include "url/gurl.h" - -namespace network { -struct ResourceRequest; -class SimpleURLLoader; -class SharedURLLoaderFactory; -} // namespace network - -namespace contextual_suggestions { - -// A fetch of contextual suggestions. This encapsulates the request-response -// lifecycle. It is also responsible for building and serializing the request -// body protos and parsing the response body protos. -class ContextualSuggestionsFetch { - public: - ContextualSuggestionsFetch(const GURL& url, const std::string& bcp_language); - ~ContextualSuggestionsFetch(); - - // Get the url used to fetch suggestions. - static const std::string GetFetchEndpoint(); - - // Start fetching suggestions using |loader_factory| to construct a - // URLLoader, and calling |callback| when finished. - void Start( - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback, - const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory); - - // Methods for testing. - std::unique_ptr<network::ResourceRequest> MakeResourceRequestForTesting() - const; - - private: - std::unique_ptr<network::SimpleURLLoader> MakeURLLoader() const; - std::unique_ptr<network::ResourceRequest> MakeResourceRequest() const; - void AppendHeaders(network::ResourceRequest*) const; - void OnURLLoaderComplete(ReportFetchMetricsCallback metrics_callback, - std::unique_ptr<std::string> result); - void ReportFetchMetrics(size_t clusters_size, - ReportFetchMetricsCallback metrics_callback); - - // The url for which we're fetching suggestions. - const GURL url_; - - // Identifier for the spoken language in BCP47 format. - const std::string bcp_language_code_; - - // The loader for downloading the suggestions. Only non-null if a fetch is - // currently ongoing. - std::unique_ptr<network::SimpleURLLoader> url_loader_; - - // The callback to notify when results are available. - FetchClustersCallback request_completed_callback_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsFetch); -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCH_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc deleted file mode 100644 index ee17787..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_fetch.h" - -#include <map> -#include <string> - -#include "base/command_line.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_features.h" -#include "components/variations/net/variations_http_headers.h" -#include "components/variations/variations_http_header_provider.h" -#include "services/network/public/cpp/resource_request.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace contextual_suggestions { - -namespace { - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_Default) { - EXPECT_EQ("https://www.google.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_CommandLine_MissingValue) { - auto* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII("contextual-suggestions-fetch-endpoint", ""); - EXPECT_EQ("https://www.google.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_CommandLine_NonHTTPS) { - auto* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII("contextual-suggestions-fetch-endpoint", - "http://test.com"); - EXPECT_EQ("https://www.google.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_CommandLine_ProperEndpoint) { - auto* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII("contextual-suggestions-fetch-endpoint", - "https://test.com"); - EXPECT_EQ("https://test.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_Feature_NoParameter) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(kContextualSuggestionsButton); - EXPECT_EQ("https://www.google.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_Feature_EmptyParameter) { - base::test::ScopedFeatureList feature_list; - std::map<std::string, std::string> parameters; - parameters["contextual-suggestions-fetch-endpoint"] = ""; - feature_list.InitAndEnableFeatureWithParameters(kContextualSuggestionsButton, - parameters); - EXPECT_EQ("https://www.google.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_Feature_NonHTTPS) { - base::test::ScopedFeatureList feature_list; - std::map<std::string, std::string> parameters; - parameters["contextual-suggestions-fetch-endpoint"] = "http://test.com"; - feature_list.InitAndEnableFeatureWithParameters(kContextualSuggestionsButton, - parameters); - EXPECT_EQ("https://www.google.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, GetFetchEndpoint_Feature_WithParameter) { - base::test::ScopedFeatureList feature_list; - std::map<std::string, std::string> parameters; - parameters["contextual-suggestions-fetch-endpoint"] = "https://test.com"; - feature_list.InitAndEnableFeatureWithParameters(kContextualSuggestionsButton, - parameters); - EXPECT_EQ("https://test.com/httpservice/web/ExploreService/GetPivots/", - ContextualSuggestionsFetch::GetFetchEndpoint()); -} - -TEST(ContextualSuggestionsFetch, MakeResourceRequest_VariationsHeader) { - variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting(); - scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( - new base::TestSimpleTaskRunner()); - base::ThreadTaskRunnerHandle handle(test_task_runner); - EXPECT_EQ(variations::VariationsHttpHeaderProvider::ForceIdsResult::SUCCESS, - variations::VariationsHttpHeaderProvider::GetInstance() - ->ForceVariationIds({"12345"}, "")); - - ContextualSuggestionsFetch fetch(GURL("http://test.com"), "en-US"); - std::unique_ptr<network::ResourceRequest> resource_request = - fetch.MakeResourceRequestForTesting(); - - EXPECT_TRUE(variations::HasVariationsHeader(*resource_request)); -} - -TEST(ContextualSuggestionsFetch, - MakeResourceRequest_VariationsHeader_NonGoogleEndpoint) { - variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting(); - auto* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII("contextual-suggestions-fetch-endpoint", - "https://nongoogleendpoint.com"); - scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( - new base::TestSimpleTaskRunner()); - base::ThreadTaskRunnerHandle handle(test_task_runner); - EXPECT_EQ(variations::VariationsHttpHeaderProvider::ForceIdsResult::SUCCESS, - variations::VariationsHttpHeaderProvider::GetInstance() - ->ForceVariationIds({"12345"}, "")); - - ContextualSuggestionsFetch fetch(GURL("http://test.com"), "en-US"); - std::unique_ptr<network::ResourceRequest> resource_request = - fetch.MakeResourceRequestForTesting(); - - EXPECT_FALSE(variations::HasVariationsHeader(*resource_request)); -} - -} // namespace - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher.h b/components/ntp_snippets/contextual/contextual_suggestions_fetcher.h deleted file mode 100644 index f0b536d..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCHER_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCHER_H_ - -#include "components/ntp_snippets/contextual/contextual_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" - -using contextual_suggestions::FetchClustersCallback; -using contextual_suggestions::ReportFetchMetricsCallback; - -namespace contextual_suggestions { - -// Fetches contextual suggestions from the server. -class ContextualSuggestionsFetcher { - public: - - virtual ~ContextualSuggestionsFetcher() = default; - - // Fetch clusters of suggestions for |url|, calling back to |callback| when - // complete. - virtual void FetchContextualSuggestionsClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) = 0; -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCHER_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc deleted file mode 100644 index be21e89..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <utility> - -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h" - -#include "base/bind.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" - -namespace contextual_suggestions { - -ContextualSuggestionsFetcherImpl::ContextualSuggestionsFetcherImpl( - const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory, - const std::string& application_language_code) - : loader_factory_(loader_factory), - bcp_language_code_(application_language_code) {} - -ContextualSuggestionsFetcherImpl::~ContextualSuggestionsFetcherImpl() = default; - -void ContextualSuggestionsFetcherImpl::FetchContextualSuggestionsClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) { - auto fetch = - std::make_unique<ContextualSuggestionsFetch>(url, bcp_language_code_); - ContextualSuggestionsFetch* fetch_unowned = fetch.get(); - pending_requests_.emplace(std::move(fetch)); - - FetchClustersCallback internal_callback = base::BindOnce( - &ContextualSuggestionsFetcherImpl::FetchFinished, base::Unretained(this), - fetch_unowned, std::move(callback)); - fetch_unowned->Start(std::move(internal_callback), - std::move(metrics_callback), loader_factory_); -} - -void ContextualSuggestionsFetcherImpl::FetchFinished( - ContextualSuggestionsFetch* fetch, - FetchClustersCallback callback, - ContextualSuggestionsResult result) { - auto fetch_iterator = pending_requests_.find(fetch); - CHECK(fetch_iterator != pending_requests_.end()); - pending_requests_.erase(fetch_iterator); - - std::move(callback).Run(std::move(result)); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h deleted file mode 100644 index 3eccc9d..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCHER_IMPL_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCHER_IMPL_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/containers/flat_set.h" -#include "base/containers/unique_ptr_adapters.h" -#include "components/ntp_snippets/contextual/contextual_suggestion.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetch.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher.h" - -namespace network { -class SharedURLLoaderFactory; -} // namespace network - -using contextual_suggestions::Cluster; -using contextual_suggestions::ContextualSuggestionsFetch; -using contextual_suggestions::ContextualSuggestionsResult; - -namespace contextual_suggestions { - -class ContextualSuggestionsFetcherImpl : public ContextualSuggestionsFetcher { - public: - ContextualSuggestionsFetcherImpl( - const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory, - const std::string& application_language_code); - ~ContextualSuggestionsFetcherImpl() override; - - // ContextualSuggestionsFetcher implementation. - void FetchContextualSuggestionsClusters( - const GURL& url, - FetchClustersCallback callback, - ReportFetchMetricsCallback metrics_callback) override; - - private: - void FetchFinished(ContextualSuggestionsFetch* fetch, - FetchClustersCallback callback, - ContextualSuggestionsResult result); - - const scoped_refptr<network::SharedURLLoaderFactory> loader_factory_; - /// BCP47 formatted language code to use. - const std::string bcp_language_code_; - - // Stores requests that are inflight. - base::flat_set<std::unique_ptr<ContextualSuggestionsFetch>, - base::UniquePtrComparator> - pending_requests_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsFetcherImpl); -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_FETCHER_IMPL_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc deleted file mode 100644 index 8d4b9411..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc +++ /dev/null
@@ -1,542 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h" - -#include <utility> -#include <vector> - -#include "base/base64.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/run_loop.h" -#include "base/strings/string_number_conversions.h" -#include "base/test/bind_test_util.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_task_environment.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_test_utils.h" -#include "components/ntp_snippets/contextual/proto/chrome_search_api_request_context.pb.h" -#include "components/ntp_snippets/contextual/proto/get_pivots_request.pb.h" -#include "components/ntp_snippets/contextual/proto/get_pivots_response.pb.h" -#include "net/http/http_status_code.h" -#include "services/network/public/cpp/url_loader_completion_status.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace contextual_suggestions { - -using contextual_suggestions::AutoPeekConditions; -using contextual_suggestions::ClusterBuilder; -using contextual_suggestions::ContextualSuggestionsEvent; -using contextual_suggestions::ExploreContext; -using contextual_suggestions::GetPivotsQuery; -using contextual_suggestions::GetPivotsRequest; -using contextual_suggestions::GetPivotsResponse; -using contextual_suggestions::ImageId; -using contextual_suggestions::MockClustersCallback; -using contextual_suggestions::MockMetricsCallback; -using contextual_suggestions::PeekConditions; -using contextual_suggestions::PivotCluster; -using contextual_suggestions::PivotClusteringParams; -using contextual_suggestions::PivotDocument; -using contextual_suggestions::PivotDocumentParams; -using contextual_suggestions::PivotItem; -using contextual_suggestions::Pivots; -using network::SharedURLLoaderFactory; -using network::TestURLLoaderFactory; -using testing::ElementsAre; - -namespace { - -Cluster DefaultCluster() { - return ClusterBuilder("Articles") - .AddSuggestion(SuggestionBuilder(GURL("http://www.foobar.com")) - .Title("Title") - .PublisherName("cnn.com") - .Snippet("Summary") - .ImageId("abcdef") - .Build()) - .Build(); -} - -// Returns a single cluster with a single suggestion with preset values. -std::vector<Cluster> DefaultClusters() { - std::vector<Cluster> clusters; - - clusters.emplace_back(DefaultCluster()); - return clusters; -} - -void PopulateDocument(PivotDocument* document, - const ContextualSuggestion& suggestion) { - document->mutable_url()->set_raw_url(suggestion.url.spec()); - document->set_title(suggestion.title); - document->set_summary(suggestion.snippet); - document->set_site_name(suggestion.publisher_name); - - ImageId* image_id = document->mutable_image()->mutable_id(); - image_id->set_encrypted_docid(suggestion.image_id); -} - -void PopulatePeekConditions(AutoPeekConditions* proto_conditions, - const PeekConditions& peek_conditions) { - proto_conditions->set_confidence(peek_conditions.confidence); - proto_conditions->set_page_scroll_percentage( - peek_conditions.page_scroll_percentage); - proto_conditions->set_minimum_seconds_on_page( - peek_conditions.minimum_seconds_on_page); - proto_conditions->set_maximum_number_of_peeks( - peek_conditions.maximum_number_of_peeks); -} - -// Populates a GetPivotsResponse proto using |peek_text| and |clusters| and -// returns that proto as a serialized string. -std::string SerializedResponseProto( - const std::string& peek_text, - std::vector<Cluster> clusters, - PeekConditions peek_conditions = PeekConditions(), - ServerExperimentInfos experiment_infos = ServerExperimentInfos()) { - GetPivotsResponse response_proto; - Pivots* pivots = response_proto.mutable_pivots(); - PopulatePeekConditions(pivots->mutable_auto_peek_conditions(), - peek_conditions); - pivots->mutable_peek_text()->set_text(peek_text); - - for (const auto& cluster : clusters) { - PivotItem* root_item = pivots->add_item(); - PivotCluster* pivot_cluster = root_item->mutable_cluster(); - pivot_cluster->mutable_label()->set_label(cluster.title); - for (const ContextualSuggestion& suggestion : cluster.suggestions) { - PopulateDocument(pivot_cluster->add_item()->mutable_document(), - suggestion); - } - } - - for (const auto& experiment_info : experiment_infos) { - ExperimentInfo* experiment = pivots->add_experiment_info(); - experiment->set_experiment_group_name(experiment_info.name); - experiment->set_experiment_arm_name(experiment_info.group); - } - - // The fetch parsing logic expects the response to come as (length, bytes) - // where length is varint32 encoded, but ignores the actual length read. - // " " is a valid varint32(32) so this works for now. - // TODO(pnoland): Use a CodedOutputStream to prepend the actual size so that - // we're not relying on implementation details. - return " " + response_proto.SerializeAsString(); -} - -// Populates a GetPivotsResponse proto with a single, flat list of suggestions -// from |single_cluster| and returns that proto as a serialized string. -std::string SerializedResponseProto(const std::string& peek_text, - Cluster single_cluster) { - GetPivotsResponse response_proto; - Pivots* pivots = response_proto.mutable_pivots(); - pivots->mutable_peek_text()->set_text(peek_text); - - for (const ContextualSuggestion& suggestion : single_cluster.suggestions) { - PopulateDocument(pivots->add_item()->mutable_document(), suggestion); - } - - // See explanation above for why we prepend " ". - return " " + response_proto.SerializeAsString(); -} - -} // namespace - -class ContextualSuggestionsFetcherTest : public testing::Test { - public: - ContextualSuggestionsFetcherTest() { - shared_url_loader_factory_ = - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - &test_factory_); - fetcher_ = std::make_unique<ContextualSuggestionsFetcherImpl>( - shared_url_loader_factory_, "en"); - } - - ~ContextualSuggestionsFetcherTest() override {} - - void SetFakeResponse(const std::string& response_data, - net::HttpStatusCode response_code = net::HTTP_OK, - network::URLLoaderCompletionStatus status = - network::URLLoaderCompletionStatus()) { - GURL fetch_url(ContextualSuggestionsFetch::GetFetchEndpoint()); - network::ResourceResponseHead head; - if (response_code >= 0) { - head.headers = base::MakeRefCounted<net::HttpResponseHeaders>( - "HTTP/1.1 " + base::NumberToString(response_code)); - status.decoded_body_length = response_data.length(); - } - - test_factory_.AddResponse(fetch_url, head, response_data, status); - } - - void SendAndAwaitResponse( - const GURL& context_url, - MockClustersCallback* callback, - MockMetricsCallback* mock_metrics_callback = nullptr) { - ReportFetchMetricsCallback metrics_callback = - mock_metrics_callback - ? base::BindRepeating(&MockMetricsCallback::Report, - base::Unretained(mock_metrics_callback)) - : base::DoNothing(); - fetcher().FetchContextualSuggestionsClusters( - context_url, callback->ToOnceCallback(), metrics_callback); - base::RunLoop().RunUntilIdle(); - } - - ContextualSuggestionsFetcher& fetcher() { return *fetcher_; } - - TestURLLoaderFactory* test_factory() { return &test_factory_; } - - private: - base::test::ScopedTaskEnvironment scoped_task_environment_; - network::TestURLLoaderFactory test_factory_; - scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; - std::unique_ptr<ContextualSuggestionsFetcherImpl> fetcher_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsFetcherTest); -}; - -TEST_F(ContextualSuggestionsFetcherTest, SingleSuggestionResponse) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - SetFakeResponse(SerializedResponseProto("Peek Text", DefaultClusters())); - - SendAndAwaitResponse(GURL("http://www.article.com"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("Peek Text", DefaultClusters(), - PeekConditions(), ServerExperimentInfos())); - EXPECT_EQ(metrics_callback.events, - std::vector<ContextualSuggestionsEvent>( - {contextual_suggestions::FETCH_COMPLETED})); -} - -TEST_F(ContextualSuggestionsFetcherTest, - MultipleSuggestionMultipleClusterResponse) { - std::vector<Cluster> clusters; - std::vector<Cluster> clusters_copy; - base::HistogramTester histogram_tester; - - ClusterBuilder cluster1_builder("Category 1"); - cluster1_builder - .AddSuggestion(SuggestionBuilder(GURL("http://www.test.com")) - .Title("Title1") - .PublisherName("test.com") - .Snippet("Summary 1") - .ImageId("abc") - .Build()) - .AddSuggestion(SuggestionBuilder(GURL("http://www.foobar.com")) - .Title("Title2") - .PublisherName("foobar.com") - .Snippet("Summary 2") - .ImageId("def") - .Build()); - - ClusterBuilder cluster2_builder("Category 2"); - cluster2_builder - .AddSuggestion(SuggestionBuilder(GURL("http://www.barbaz.com")) - .Title("Title3") - .PublisherName("barbaz.com") - .Snippet("Summary 3") - .ImageId("ghi") - .Build()) - .AddSuggestion(SuggestionBuilder(GURL("http://www.cnn.com")) - .Title("Title4") - .PublisherName("cnn.com") - .Snippet("Summary 4") - .ImageId("jkl") - .Build()) - .AddSuggestion(SuggestionBuilder(GURL("http://www.slate.com")) - .Title("Title5") - .PublisherName("slate.com") - .Snippet("Summary 5") - .ImageId("mno") - .Build()); - ClusterBuilder c1_copy = cluster1_builder; - ClusterBuilder c2_copy = cluster2_builder; - - clusters.emplace_back(cluster1_builder.Build()); - clusters.emplace_back(cluster2_builder.Build()); - - clusters_copy.emplace_back(c1_copy.Build()); - clusters_copy.emplace_back(c2_copy.Build()); - - SetFakeResponse(SerializedResponseProto("Peek Text", std::move(clusters))); - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - - EXPECT_TRUE(callback.has_run); - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("Peek Text", std::move(clusters_copy), - PeekConditions(), ServerExperimentInfos())); - - histogram_tester.ExpectTotalCount( - "ContextualSuggestions.FetchResponseNetworkBytes", 1); - histogram_tester.ExpectTotalCount( - "ContextualSuggestions.FetchLatencyMilliseconds", 1); -} - -TEST_F(ContextualSuggestionsFetcherTest, FlatResponse) { - SetFakeResponse(SerializedResponseProto("Peek Text", DefaultCluster())); - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - - EXPECT_TRUE(callback.has_run); - // There's no title for the flat/unclustered response case, since there's no - // PivotCluster to copy it from. So we clear the expected title. - std::vector<Cluster> expected_clusters = DefaultClusters(); - expected_clusters[0].title = ""; - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("Peek Text", std::move(expected_clusters), - PeekConditions(), ServerExperimentInfos())); -} - -TEST_F(ContextualSuggestionsFetcherTest, PeekConditionsAreParsed) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - PeekConditions peek_conditions; - peek_conditions.confidence = 0.7; - peek_conditions.page_scroll_percentage = 35.0; - peek_conditions.minimum_seconds_on_page = 4.5; - peek_conditions.maximum_number_of_peeks = 5.0; - - SetFakeResponse( - SerializedResponseProto("Peek Text", DefaultClusters(), peek_conditions)); - - SendAndAwaitResponse(GURL("http://www.article.com"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("Peek Text", DefaultClusters(), - peek_conditions, ServerExperimentInfos())); -} - -TEST_F(ContextualSuggestionsFetcherTest, ServerExperimentInfosAreParsed) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - ServerExperimentInfos experiment_infos; - experiment_infos.emplace_back("trial1", "group1"); - experiment_infos.emplace_back("trial2", "group2"); - SetFakeResponse(SerializedResponseProto("Peek Text", DefaultClusters(), - PeekConditions(), experiment_infos)); - - SendAndAwaitResponse(GURL("http://www.article.com"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("Peek Text", DefaultClusters(), - PeekConditions(), experiment_infos)); - EXPECT_EQ(metrics_callback.events, - std::vector<ContextualSuggestionsEvent>( - {contextual_suggestions::FETCH_COMPLETED})); -} - -TEST_F(ContextualSuggestionsFetcherTest, HtmlEntitiesAreUnescaped) { - ClusterBuilder cluster_builder("Category 1"); - cluster_builder.AddSuggestion(SuggestionBuilder(GURL("http://www.test.com")) - .Title(""foobar"") - .PublisherName("test.com") - .Snippet("'barbaz'") - .ImageId("abc") - .Build()); - ClusterBuilder builder_copy = cluster_builder; - SetFakeResponse( - SerializedResponseProto("Peek Text", cluster_builder.Build())); - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - - EXPECT_TRUE(callback.has_run); - std::vector<Cluster> expected_clusters; - expected_clusters.emplace_back(builder_copy.Build()); - // Clear the title since it's a flat response. - expected_clusters[0].title = ""; - // Adjust the expected title and snippet to manually unescape the html - // entities we added. - expected_clusters[0].suggestions[0].title = "\"foobar\""; - expected_clusters[0].suggestions[0].snippet = "\'barbaz\'"; - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("Peek Text", std::move(expected_clusters), - PeekConditions(), ServerExperimentInfos())); -} - -TEST_F(ContextualSuggestionsFetcherTest, RequestHeaderSetCorrectly) { - net::HttpRequestHeaders headers; - base::RunLoop interceptor_run_loop; - base::HistogramTester histogram_tester; - - test_factory()->SetInterceptor( - base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - headers = request.headers; - interceptor_run_loop.Quit(); - })); - SetFakeResponse(SerializedResponseProto("Peek Text", DefaultClusters())); - - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - - interceptor_run_loop.Run(); - - std::string protobuf_header; - ASSERT_TRUE( - headers.GetHeader("X-Protobuffer-Request-Payload", &protobuf_header)); - - std::string decoded_header_value; - base::Base64Decode(protobuf_header, &decoded_header_value); - GetPivotsRequest request; - ASSERT_TRUE(request.ParseFromString(decoded_header_value)); - - EXPECT_EQ(request.context().localization_context().language_code(), "en"); - EXPECT_EQ(request.query().context()[0].url(), "http://www.article.com/"); - EXPECT_TRUE(request.query().document_params().enabled()); - EXPECT_EQ(request.query().document_params().num(), 10); - EXPECT_TRUE(request.query().document_params().enable_images()); - EXPECT_TRUE(request.query().clustering_params().enabled()); - EXPECT_TRUE(request.query().peek_text_params().enabled()); - - histogram_tester.ExpectTotalCount( - "ContextualSuggestions.FetchRequestProtoSizeKB", 1); -} - -TEST_F(ContextualSuggestionsFetcherTest, CredentialsExcluded) { - network::ResourceRequest last_resource_request; - - test_factory()->SetInterceptor( - base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - last_resource_request = request; - })); - - SetFakeResponse(SerializedResponseProto("Peek Text", DefaultClusters())); - - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - EXPECT_FALSE(last_resource_request.allow_credentials); -} - -TEST_F(ContextualSuggestionsFetcherTest, ProtocolError) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - base::HistogramTester histogram_tester; - - SetFakeResponse("", net::HTTP_NOT_FOUND); - SendAndAwaitResponse(GURL("http://www.article.com"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - EXPECT_EQ(callback.response_clusters.size(), 0u); - EXPECT_THAT( - histogram_tester.GetAllSamples("ContextualSuggestions.FetchResponseCode"), - ElementsAre(base::Bucket(/*min=*/net::HTTP_NOT_FOUND, /*count=*/1))); - EXPECT_EQ(metrics_callback.events, - std::vector<ContextualSuggestionsEvent>( - {contextual_suggestions::FETCH_ERROR})); -} - -TEST_F(ContextualSuggestionsFetcherTest, ServerUnavailable) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - base::HistogramTester histogram_tester; - - SetFakeResponse("", net::HTTP_SERVICE_UNAVAILABLE); - SendAndAwaitResponse(GURL("http://www.article.com"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - EXPECT_EQ(callback.response_clusters.size(), 0u); - EXPECT_THAT( - histogram_tester.GetAllSamples("ContextualSuggestions.FetchResponseCode"), - ElementsAre(base::Bucket(/*min=*/net::HTTP_SERVICE_UNAVAILABLE, - /*count=*/1))); - EXPECT_EQ(metrics_callback.events, - std::vector<ContextualSuggestionsEvent>( - {contextual_suggestions::FETCH_SERVER_BUSY})); -} - -TEST_F(ContextualSuggestionsFetcherTest, NetworkError) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - base::HistogramTester histogram_tester; - - SetFakeResponse( - "", net::HTTP_OK, - network::URLLoaderCompletionStatus(net::ERR_CERT_COMMON_NAME_INVALID)); - SendAndAwaitResponse(GURL("http://www.article.com"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - EXPECT_EQ(callback.response_clusters.size(), 0u); - EXPECT_THAT( - histogram_tester.GetAllSamples("ContextualSuggestions.FetchErrorCode"), - ElementsAre(base::Bucket( - /*min=*/net::ERR_CERT_COMMON_NAME_INVALID, /*count=*/1))); - - EXPECT_EQ(metrics_callback.events, - std::vector<ContextualSuggestionsEvent>( - {contextual_suggestions::FETCH_ERROR})); -} - -TEST_F(ContextualSuggestionsFetcherTest, EmptyResponse) { - MockClustersCallback callback; - MockMetricsCallback metrics_callback; - SetFakeResponse(SerializedResponseProto("", Cluster())); - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback, - &metrics_callback); - - EXPECT_TRUE(callback.has_run); - EXPECT_EQ(callback.response_clusters.size(), 0u); - - EXPECT_EQ(metrics_callback.events, - std::vector<ContextualSuggestionsEvent>( - {contextual_suggestions::FETCH_EMPTY})); -} - -TEST_F(ContextualSuggestionsFetcherTest, ResponseWithUnsetFields) { - GetPivotsResponse response; - Pivots* pivots = response.mutable_pivots(); - pivots->add_item()->mutable_document(); - pivots->add_item(); - - SetFakeResponse(" " + response.SerializeAsString()); - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - - std::vector<Cluster> expected_clusters; - expected_clusters.emplace_back( - ClusterBuilder("") - .AddSuggestion(SuggestionBuilder(GURL()).Build()) - .AddSuggestion(SuggestionBuilder(GURL()).Build()) - .Build()); - - EXPECT_TRUE(callback.has_run); - EXPECT_EQ(callback.response_clusters.size(), 1u); - ExpectResponsesMatch( - std::move(callback), - ContextualSuggestionsResult("", std::move(expected_clusters), - PeekConditions(), ServerExperimentInfos())); -} - -TEST_F(ContextualSuggestionsFetcherTest, CorruptResponse) { - SetFakeResponse("unparseable proto string"); - MockClustersCallback callback; - SendAndAwaitResponse(GURL("http://www.article.com/"), &callback); - - EXPECT_TRUE(callback.has_run); - EXPECT_EQ(callback.response_clusters.size(), 0u); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_result.cc b/components/ntp_snippets/contextual/contextual_suggestions_result.cc deleted file mode 100644 index 1033fb5c..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_result.cc +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" - -#include "components/ntp_snippets/contextual/contextual_suggestion.h" - -namespace contextual_suggestions { - -PeekConditions::PeekConditions() - : confidence(1.0), - page_scroll_percentage(0.0), - minimum_seconds_on_page(0.0), - maximum_number_of_peeks(0.0) {} - -Cluster::Cluster() = default; - -Cluster::Cluster(const Cluster& other) = default; - -// MSVC doesn't support defaulted move constructors, so we have to define it -// ourselves. -Cluster::Cluster(Cluster&& other) noexcept - : title(std::move(other.title)), - suggestions(std::move(other.suggestions)) {} - -Cluster::~Cluster() = default; - -Cluster& Cluster::operator=(const Cluster&) = default; - -ClusterBuilder::ClusterBuilder(const std::string& title) { - cluster_.title = title; -} - -ClusterBuilder::ClusterBuilder(const ClusterBuilder& other) { - cluster_.title = other.cluster_.title; - for (const auto& suggestion : other.cluster_.suggestions) { - AddSuggestion(SuggestionBuilder(suggestion.url) - .Title(suggestion.title) - .PublisherName(suggestion.publisher_name) - .Snippet(suggestion.snippet) - .ImageId(suggestion.image_id) - .FaviconImageId(suggestion.favicon_image_id) - .FaviconImageUrl(suggestion.favicon_image_url) - .Build()); - } -} - -ClusterBuilder& ClusterBuilder::AddSuggestion(ContextualSuggestion suggestion) { - cluster_.suggestions.emplace_back(std::move(suggestion)); - return *this; -} - -Cluster ClusterBuilder::Build() { - return std::move(cluster_); -} - -ServerExperimentInfo::ServerExperimentInfo() = default; - -ServerExperimentInfo::ServerExperimentInfo(std::string name, std::string group) - : name(name), group(group) {} - -ServerExperimentInfo::ServerExperimentInfo(const ServerExperimentInfo& other) = - default; - -ServerExperimentInfo::ServerExperimentInfo( - ServerExperimentInfo&& other) noexcept - : name(std::move(other.name)), group(std::move(other.group)) {} - -ServerExperimentInfo::~ServerExperimentInfo() = default; - -ServerExperimentInfo& ServerExperimentInfo::operator=( - ServerExperimentInfo&& other) = default; - -ServerExperimentInfo& ServerExperimentInfo::operator=( - const ServerExperimentInfo& other) = default; - -ContextualSuggestionsResult::ContextualSuggestionsResult() = default; - -ContextualSuggestionsResult::ContextualSuggestionsResult( - std::string peek_text, - std::vector<Cluster> clusters, - PeekConditions peek_conditions, - ServerExperimentInfos experiment_infos) - : clusters(clusters), - peek_text(peek_text), - peek_conditions(peek_conditions), - experiment_infos(std::move(experiment_infos)) {} - -ContextualSuggestionsResult::ContextualSuggestionsResult( - const ContextualSuggestionsResult& other) = default; - -// MSVC doesn't support defaulted move constructors, so we have to define it -// ourselves. -ContextualSuggestionsResult::ContextualSuggestionsResult( - ContextualSuggestionsResult&& other) noexcept - : clusters(std::move(other.clusters)), - peek_text(std::move(other.peek_text)), - peek_conditions(std::move(other.peek_conditions)), - experiment_infos(std::move(other.experiment_infos)) {} - -ContextualSuggestionsResult::~ContextualSuggestionsResult() = default; - -ContextualSuggestionsResult& ContextualSuggestionsResult::operator=( - ContextualSuggestionsResult&& other) = default; - -ContextualSuggestionsResult& ContextualSuggestionsResult::operator=( - const ContextualSuggestionsResult& other) = default; - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_result.h b/components/ntp_snippets/contextual/contextual_suggestions_result.h deleted file mode 100644 index b140c31..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_result.h +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_RESULT_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_RESULT_H_ - -#include "components/ntp_snippets/contextual/contextual_suggestion.h" - -#include <string> -#include <utility> -#include <vector> - -#include "base/containers/flat_map.h" - -namespace contextual_suggestions { - -// Encapsulates conditions under which to show or "peek" the contextual -// suggestions UI. -struct PeekConditions { - PeekConditions(); - // A measure of confidence that auto-peek should be enabled for this response - // in the range [0, 1]. - float confidence = 1.0; - - // The percentage of the page that the user scrolls required for an auto - // peek to occur. - float page_scroll_percentage; - - // The minimum time (seconds) the user spends on the page required for - // auto peek. - float minimum_seconds_on_page; - - // The maximum number of auto peeks that we can show for this page. - uint64_t maximum_number_of_peeks; -}; - -// A structure representing a suggestion cluster. -struct Cluster { - Cluster(); - Cluster(const Cluster&); - Cluster(Cluster&&) noexcept; - ~Cluster(); - - Cluster& operator=(const Cluster&); - - std::string title; - std::vector<ContextualSuggestion> suggestions; -}; - -// Allows concise construction of a cluster. -class ClusterBuilder { - public: - explicit ClusterBuilder(const std::string& title); - - // Allow copying for ease of validation when testing. - ClusterBuilder(const ClusterBuilder& other); - ClusterBuilder& AddSuggestion(ContextualSuggestion suggestion); - Cluster Build(); - - private: - Cluster cluster_; -}; - -// Synthetic field trials driven by the server. -struct ServerExperimentInfo { - ServerExperimentInfo(); - ServerExperimentInfo(std::string name, std::string group); - ServerExperimentInfo(const ServerExperimentInfo&); - ServerExperimentInfo(ServerExperimentInfo&&) noexcept; - ~ServerExperimentInfo(); - - ServerExperimentInfo& operator=(ServerExperimentInfo&&); - ServerExperimentInfo& operator=(const ServerExperimentInfo&); - - std::string name; - std::string group; -}; - -using ServerExperimentInfos = std::vector<ServerExperimentInfo>; - -// Struct that holds the data from a ContextualSuggestions response that we care -// about for UI purposes. -struct ContextualSuggestionsResult { - ContextualSuggestionsResult(); - ContextualSuggestionsResult(std::string peek_text, - std::vector<Cluster> clusters, - PeekConditions peek_conditions, - ServerExperimentInfos experiment_infos); - ContextualSuggestionsResult(const ContextualSuggestionsResult&); - ContextualSuggestionsResult(ContextualSuggestionsResult&&) noexcept; - ~ContextualSuggestionsResult(); - - ContextualSuggestionsResult& operator=(ContextualSuggestionsResult&&); - ContextualSuggestionsResult& operator=(const ContextualSuggestionsResult&); - - std::vector<Cluster> clusters; - std::string peek_text; - PeekConditions peek_conditions; - ServerExperimentInfos experiment_infos; -}; - -using FetchClustersCallback = - base::OnceCallback<void(ContextualSuggestionsResult result)>; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_RESULT_H_
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_test_utils.cc b/components/ntp_snippets/contextual/contextual_suggestions_test_utils.cc deleted file mode 100644 index bfccb0ff..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_test_utils.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/contextual_suggestions_test_utils.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace contextual_suggestions { - -MockClustersCallback::MockClustersCallback() = default; -MockClustersCallback::MockClustersCallback(const MockClustersCallback& other) = - default; -MockClustersCallback::~MockClustersCallback() = default; - -void MockClustersCallback::Done(ContextualSuggestionsResult result) { - EXPECT_FALSE(has_run); - has_run = true; - response_peek_text = result.peek_text; - response_clusters = std::move(result.clusters); - peek_conditions = result.peek_conditions; - experiment_infos = result.experiment_infos; -} - -FetchClustersCallback MockClustersCallback::ToOnceCallback() { - return base::BindOnce(&MockClustersCallback::Done, base::Unretained(this)); -} - -MockMetricsCallback::MockMetricsCallback() = default; -MockMetricsCallback::~MockMetricsCallback() = default; - -void MockMetricsCallback::Report(ContextualSuggestionsEvent event) { - events.push_back(event); -} - -void ExpectSuggestionsMatch(const ContextualSuggestion& actual, - const ContextualSuggestion& expected) { - EXPECT_EQ(actual.id, expected.id); - EXPECT_EQ(actual.title, expected.title); - EXPECT_EQ(actual.url, expected.url); - EXPECT_EQ(actual.snippet, expected.snippet); - EXPECT_EQ(actual.publisher_name, expected.publisher_name); - EXPECT_EQ(actual.image_id, expected.image_id); - EXPECT_EQ(actual.favicon_image_id, expected.favicon_image_id); -} - -void ExpectClustersMatch(const Cluster& actual, const Cluster& expected) { - EXPECT_EQ(actual.title, expected.title); - ASSERT_EQ(actual.suggestions.size(), expected.suggestions.size()); - for (size_t i = 0; i < actual.suggestions.size(); ++i) { - ExpectSuggestionsMatch(std::move(actual.suggestions[i]), - std::move(expected.suggestions[i])); - } -} - -void ExpectPeekConditionsMatch(const PeekConditions& actual, - const PeekConditions& expected) { - EXPECT_EQ(actual.confidence, expected.confidence); - EXPECT_EQ(actual.page_scroll_percentage, expected.page_scroll_percentage); - EXPECT_EQ(actual.minimum_seconds_on_page, expected.minimum_seconds_on_page); - EXPECT_EQ(actual.maximum_number_of_peeks, expected.maximum_number_of_peeks); -} - -void ExpectServerExperimentInfosMatch(const ServerExperimentInfos& actual, - const ServerExperimentInfos& expected) { - ASSERT_EQ(expected.size(), actual.size()); - for (size_t i = 0; i < actual.size(); ++i) { - EXPECT_EQ(expected[i].name, actual[i].name); - EXPECT_EQ(expected[i].group, actual[i].group); - } -} - -void ExpectResponsesMatch(const MockClustersCallback& callback, - const ContextualSuggestionsResult& expected_result) { - EXPECT_EQ(callback.response_peek_text, expected_result.peek_text); - ExpectPeekConditionsMatch(callback.peek_conditions, - expected_result.peek_conditions); - ASSERT_EQ(callback.response_clusters.size(), expected_result.clusters.size()); - for (size_t i = 0; i < callback.response_clusters.size(); ++i) { - ExpectClustersMatch(std::move(callback.response_clusters[i]), - std::move(expected_result.clusters[i])); - } - ExpectServerExperimentInfosMatch(callback.experiment_infos, - expected_result.experiment_infos); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_test_utils.h b/components/ntp_snippets/contextual/contextual_suggestions_test_utils.h deleted file mode 100644 index bc41475..0000000 --- a/components/ntp_snippets/contextual/contextual_suggestions_test_utils.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_TEST_UTILS_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_TEST_UTILS_H_ - -#include "base/bind.h" -#include "components/ntp_snippets/contextual/contextual_suggestions_result.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace contextual_suggestions { - -// ClustersCallback implementation for testing purposes that expects to be -// called only once, and remembers the results of that call in public members. -class MockClustersCallback { - public: - MockClustersCallback(); - MockClustersCallback(const MockClustersCallback&); - ~MockClustersCallback(); - - void Done(ContextualSuggestionsResult result); - FetchClustersCallback ToOnceCallback(); - - bool has_run = false; - std::string response_peek_text; - std::vector<Cluster> response_clusters; - PeekConditions peek_conditions; - ServerExperimentInfos experiment_infos; -}; - -class MockMetricsCallback { - public: - MockMetricsCallback(); - ~MockMetricsCallback(); - - void Report(ContextualSuggestionsEvent event); - - std::vector<ContextualSuggestionsEvent> events; -}; - -void ExpectSuggestionsMatch(const ContextualSuggestion& actual, - const ContextualSuggestion& expected); -void ExpectClustersMatch(const Cluster& actual, const Cluster& expected); -void ExpectPeekConditionsMatch(const PeekConditions& actual, - const PeekConditions& expected); - -// Expect that the individual data members saved in |callback| match the -// corresponding data in |expected_result|. -void ExpectResponsesMatch(const MockClustersCallback& callback, - const ContextualSuggestionsResult& expected_result); - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_CONTEXTUAL_SUGGESTIONS_TEST_UTILS_H_
diff --git a/components/ntp_snippets/contextual/proto/chrome_search_api_request_context.proto b/components/ntp_snippets/contextual/proto/chrome_search_api_request_context.proto deleted file mode 100644 index 7cf84cd..0000000 --- a/components/ntp_snippets/contextual/proto/chrome_search_api_request_context.proto +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package contextual_suggestions; - -message SearchApiRequestContext { - optional SearchApiClientContext client_context = 2; - optional LocalizationContext localization_context = 4; - optional CookieRequestContext cookie_context = 3; -} - -message SearchApiClientContext { - optional ClientId client_id = 1; -} - -message ClientId { - enum ClientType { - UNKNOWN_CLIENT_TYPE = 0; - ANDROID_CHROME = 79; - } - optional ClientType client_type = 1; -} - -message LocalizationContext { - optional string language_code = 1; - optional string country_code = 2; - optional string search_domain = 4; - optional string spoken_language = 7; -} - -message CookieRequestContext { - optional string nid = 1; -}
diff --git a/components/ntp_snippets/contextual/proto/get_pivots_request.proto b/components/ntp_snippets/contextual/proto/get_pivots_request.proto deleted file mode 100644 index 48cb0c5..0000000 --- a/components/ntp_snippets/contextual/proto/get_pivots_request.proto +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package contextual_suggestions; - -import "chrome_search_api_request_context.proto"; - -message GetPivotsRequest { - // Context common to the search API. - optional SearchApiRequestContext context = 1; - - // Request fields specific to the Pivots request. - optional GetPivotsQuery query = 2; -} - -message GetPivotsQuery { - // A historical chain of the user's past exploration to date, sorted from - // most recent to least recent (reverse chronological order). A context is - // usually a document and some related data (eg. salient terms and/or query - // that generated that doc). - repeated ExploreContext context = 1; - - // Parameters related to pivot documents. - optional PivotDocumentParams document_params = 2; - - // Parameters related to clustering pivot items (documents, queries, - // questions, etc.). - optional PivotClusteringParams clustering_params = 6; - - // Parameters related to peek text. - optional PivotPeekTextParams peek_text_params = 7; -} - -// One piece of historical context in the user's exploration session. -message ExploreContext { - // If specified, the (possibly uncanonicalized) document the user visited. - optional string url = 1; -} - -message PivotDocumentParams { - // If true, compute pivot documents. - optional bool enabled = 1 [default = false]; - - // How many documents should we return? - optional int32 num = 2 [default = 5]; - - // If we have fewer documents than this to return, then don't return any. - optional int32 min_documents = 6 [default = 3]; - - // If true, return images for documents. - optional bool enable_images = 3 [default = false]; - - // When images are returned, what aspect ratio should be used. - enum ImageAspectRatio { - // Allow the server to select. This will typically return a thumbnail in - // the same aspect ratio as the original image. - ASPECT_RATIO_UNSPECIFIED = 0; - // Crop to a square image. - SQUARE = 1; - } - optional ImageAspectRatio image_aspect_ratio = 4 - [default = ASPECT_RATIO_UNSPECIFIED]; -} - -// Parameters for clustering pivot items (documents, queries, questions, etc). -message PivotClusteringParams { - // Whether or not to group PivotItems on similar topics into clusters. - optional bool enabled = 1; - - // Minimum number of clusters we should return. - optional int32 min = 2; - - // Maximum number of clusters we should return. - optional int32 max = 3; -} - -// Parameters related to the peek text. -message PivotPeekTextParams { - // Whether or not to return peek text. - optional bool enabled = 1 [default = false]; -} \ No newline at end of file
diff --git a/components/ntp_snippets/contextual/proto/get_pivots_response.proto b/components/ntp_snippets/contextual/proto/get_pivots_response.proto deleted file mode 100644 index 79c85485..0000000 --- a/components/ntp_snippets/contextual/proto/get_pivots_response.proto +++ /dev/null
@@ -1,160 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package contextual_suggestions; - -message GetPivotsResponse { - // The suggested followups. - optional Pivots pivots = 2; -} - -// Container for all explore on content data. -message Pivots { - // Items related to the user's context. - repeated PivotItem item = 1; - - // The conditions under which auto-peek should be enabled. - optional AutoPeekConditions auto_peek_conditions = 3; - - // The text to present to the user in the peek. - optional PeekText peek_text = 4; - - // Information about experiments running on this request. - repeated ExperimentInfo experiment_info = 5; -} - -// One related response. -message PivotItem { - oneof kind { - PivotDocument document = 1; - PivotCluster cluster = 6; - } -} - -// A document related to the source data. -message PivotDocument { - // A link to the document. - optional Url url = 1; - - // An image that may be shown next to the document. - optional Image image = 2; - - // Title of this document. - optional string title = 3; - - // Snippet summary of this document. - optional string summary = 4; - - // Human-readable version of the source site's name (e.g. "CNN" instead of - // "cnn.com"). - optional string site_name = 5; - - // A favicon image, usually related to the site. - optional Image favicon_image = 6; -} - -// A cluster of responses related to the source data. The cluster optionally has -// a label. -message PivotCluster { - // Label for the cluster. - optional ClusterLabel label = 1; - - // Ranked items that belong to this cluster. - repeated PivotItem item = 2; - - // Number of items to show to the user before they expand. - optional int32 num_items_to_display_pre_expansion = 3 [default = 1]; -} - -// The label for a cluster of followup items. -message ClusterLabel { - // Label to display to the user. - optional string label = 1; -} - -message AutoPeekConditions { - // A measure of confidence that auto-peek should be enabled for this response - // in the range [0, 1]. In general, if the value is 1.0, auto-peek should be - // enabled; if 0.0, it shouldn’t; and intermediate values are left to the - // client to decide. - optional float confidence = 1 [default = 1.0]; - - // The percentage of the page that the user scrolls required for an auto - // peek to occur. Value should be a decimal between 0 and 1.0. - // 1.0 represents the entire page's length. - optional float page_scroll_percentage = 2 [default = 0.0]; - - // The minimum time (seconds) the user spends on the page required for - // auto peek. - optional float minimum_seconds_on_page = 3 [default = 0.0]; - - // The maximum number of auto peeks that we can show for this page. - // If set to 0, we will never auto peek. Service can set this to a very - // large number to effectively have unlimited auto peeks. - optional uint64 maximum_number_of_peeks = 4 [default = 0]; -} - -message PeekText { - // Text to display to the user. - optional string text = 1; -} - -message Url { - optional string raw_url = 1; -} - -message Image { - // The identity of this image. - optional ImageId id = 1; - - // The underlying source data that encodes the image. - optional ImageSource source_data = 2; -} - -message ImageId { - // The encrypted document ID of the image, which is a base64-encoded string - // that can be used to generate image URLs of the form: - // - // "http://www.google.com/images?q=tbn:<encrypted doc id>" - // - // For example, the image: - // - // "http://www.google.com/images?q=tbn:e-AB_0zkH08qtM - // - // ... has an encrypted doc ID of "e-AB_0zkH08qtM". - optional string encrypted_docid = 1; -} - -// Represents the underlying encoding / source data for an image. -message ImageSource { - // The raster image representation. - optional RasterImage raster = 1; -} - -// A representation of an image as a collection of pixels at a specific size. -message RasterImage { - // A URL at which the image may be retrieved. The format of the image - // is determined by the "Content-Type" of the HTTP response for the URL. - optional Url url = 2; -} - -// Synthetic experiment IDs, which Chrome may log in UMA. -message ExperimentInfo { - // Name of experiment. A single live-experiment will have one - // experiment_group_name, and two or more experiment_arm_name's. - // - // This corresponds to an experiment group in GWS, and a field trial in Chrome - // Variations. - optional string experiment_group_name = 1; - - // Name of experiment arm. - // - // This corresponds to an experiment arm in GWS, and a field trial group in - // Chrome Variations. - optional string experiment_arm_name = 2; -}
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.cc deleted file mode 100644 index fcad5d8..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h" - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h" - -namespace contextual_suggestions { - -ContextualSuggestionsCompositeReporter:: - ContextualSuggestionsCompositeReporter() = default; - -ContextualSuggestionsCompositeReporter:: - ~ContextualSuggestionsCompositeReporter() = default; - -void ContextualSuggestionsCompositeReporter::SetupForPage( - const std::string& url, - ukm::SourceId source_id) { - for (ContextualSuggestionsReporter* reporter : raw_reporters_) - reporter->SetupForPage(url, source_id); -} - -void ContextualSuggestionsCompositeReporter::RecordEvent( - ContextualSuggestionsEvent event) { - for (ContextualSuggestionsReporter* reporter : raw_reporters_) - reporter->RecordEvent(event); -} - -void ContextualSuggestionsCompositeReporter::Flush() { - for (ContextualSuggestionsReporter* reporter : raw_reporters_) - reporter->Flush(); -} - -void ContextualSuggestionsCompositeReporter::AddOwnedReporter( - std::unique_ptr<ContextualSuggestionsReporter> reporter) { - // It's possible the raw pointer has already been added. This case will - // be taken care of by the set used to store the raw pointers. - // This allows for the composite reporter to retroactively take ownership - // after a raw pointer has already been added. - ContextualSuggestionsReporter* raw_reporter = reporter.get(); - owned_reporters_.insert(std::move(reporter)); - AddRawReporter(raw_reporter); -} - -void ContextualSuggestionsCompositeReporter::AddRawReporter( - ContextualSuggestionsReporter* reporter) { - CHECK(reporter); - raw_reporters_.insert(reporter); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h b/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h deleted file mode 100644 index 340a23d..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_COMPOSITE_REPORTER_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_COMPOSITE_REPORTER_H_ - -#include <memory> -#include <set> - -#include "base/macros.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -namespace contextual_suggestions { - -// Reporter specialized for reporting to many different reporters. -// This is an add-only collection of reporters because right now reporters live -// as long as the service, or a proxy owning the composite. Therefore everything -// is torn down together. -class ContextualSuggestionsCompositeReporter - : public ContextualSuggestionsReporter { - public: - ContextualSuggestionsCompositeReporter(); - ~ContextualSuggestionsCompositeReporter() override; - - // ContextualSuggestionsReporter - void SetupForPage(const std::string& url, - ukm::SourceId source_id) override; - void RecordEvent(ContextualSuggestionsEvent event) override; - void Flush() override; - - // Composite pattern. - // Add a reporter which will be cleaned up with this. Use this if you want the - // reporter to be destroyed with the composite reporter. - void AddOwnedReporter( - std::unique_ptr<ContextualSuggestionsReporter> reporter); - // Add an unmanaged reporter. Use this if you want to manage the lifetime of - // this reporter yourself. - void AddRawReporter(ContextualSuggestionsReporter* reporter); - - private: - // List of owned reporters. - std::set<std::unique_ptr<ContextualSuggestionsReporter>> owned_reporters_; - - // List of all reporters that get the events. - std::set<ContextualSuggestionsReporter*> raw_reporters_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsCompositeReporter); -}; -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_COMPOSITE_REPORTER_H_
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc deleted file mode 100644 index ba332a2..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h" - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace contextual_suggestions { - -static const std::string kTestUrl = "https://foo.com"; -static const ukm::SourceId kSourceId = 1; - -class TestReporter : public ContextualSuggestionsReporter { - public: - TestReporter() = default; - ~TestReporter() override { reporter_destroy_count_++; } - - /* ContextualSuggestionsReporter */ - - void SetupForPage(const std::string& url, - ukm::SourceId source_id) override { - this->url_ = url; - this->source_id_ = source_id; - called_setup_for_page_count_++; - } - - void RecordEvent(ContextualSuggestionsEvent event) override { - called_record_event_count_++; - } - - void Flush() override { called_flush_count_++; } - - /* Accessors */ - std::string GetUrl() { return url_; } - ukm::SourceId GetSourceId() { return source_id_; } - int GetNSetupForPage() { return called_setup_for_page_count_; } - int GetNRecordEvent() { return called_record_event_count_; } - int GetNFlush() { return called_flush_count_; } - - /* Static variables*/ - static int GetReporterDestroyCount() { return reporter_destroy_count_; } - static void ResetReporterDestroyCount() { reporter_destroy_count_ = 0; } - - private: - static int reporter_destroy_count_; - - std::string url_; - ukm::SourceId source_id_; - int called_setup_for_page_count_ = 0; - int called_record_event_count_ = 0; - int called_flush_count_ = 0; -}; - -int TestReporter::reporter_destroy_count_ = 0; - -TEST(ContextualSuggestionsCompositeReporterTest, AddAndReportUnique) { - std::unique_ptr<ContextualSuggestionsCompositeReporter> composite_reporter = - std::make_unique<ContextualSuggestionsCompositeReporter>(); - - std::vector<TestReporter*> reporters; - for (int i = 0; i < 10; i++) { - auto reporter = std::make_unique<TestReporter>(); - reporters.push_back(reporter.get()); - composite_reporter->AddOwnedReporter(std::move(reporter)); - } - - composite_reporter->SetupForPage(kTestUrl, kSourceId); - composite_reporter->RecordEvent(ContextualSuggestionsEvent::FETCH_REQUESTED); - composite_reporter->Flush(); - - for (TestReporter* reporter : reporters) { - EXPECT_EQ(1, reporter->GetNSetupForPage()); - EXPECT_EQ(1, reporter->GetNRecordEvent()); - EXPECT_EQ(1, reporter->GetNFlush()); - } - - EXPECT_EQ(kTestUrl, reporters.front()->GetUrl()); - EXPECT_EQ(kSourceId, reporters.front()->GetSourceId()); -} - -TEST(ContextualSuggestionsCompositeReporterTest, AddAndReportRaw) { - std::unique_ptr<ContextualSuggestionsCompositeReporter> composite_reporter = - std::make_unique<ContextualSuggestionsCompositeReporter>(); - - std::vector<std::unique_ptr<TestReporter>> reporters; - for (int i = 0; i < 10; i++) { - auto reporter = std::make_unique<TestReporter>(); - composite_reporter->AddRawReporter(reporter.get()); - reporters.push_back(std::move(reporter)); - } - - composite_reporter->SetupForPage(kTestUrl, kSourceId); - composite_reporter->RecordEvent(ContextualSuggestionsEvent::FETCH_REQUESTED); - composite_reporter->Flush(); - - for (auto& reporter : reporters) { - EXPECT_EQ(1, reporter->GetNSetupForPage()); - EXPECT_EQ(1, reporter->GetNRecordEvent()); - EXPECT_EQ(1, reporter->GetNFlush()); - } - - EXPECT_EQ(kTestUrl, reporters.front()->GetUrl()); - EXPECT_EQ(kSourceId, reporters.front()->GetSourceId()); -} - -TEST(ContextualSuggestionsCompositeReporterTest, CheckOwnedDeleted) { - TestReporter::ResetReporterDestroyCount(); - std::unique_ptr<ContextualSuggestionsCompositeReporter> composite_reporter = - std::make_unique<ContextualSuggestionsCompositeReporter>(); - - auto reporter = std::make_unique<TestReporter>(); - composite_reporter->AddOwnedReporter(std::make_unique<TestReporter>()); - composite_reporter->AddOwnedReporter(std::make_unique<TestReporter>()); - composite_reporter->AddRawReporter(reporter.get()); - composite_reporter.reset(nullptr); - - EXPECT_EQ(2, TestReporter::GetReporterDestroyCount()); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc deleted file mode 100644 index a41894e..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.cc +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h" - -#include <algorithm> - -#include "base/stl_util.h" - -namespace { -static constexpr int CACHE_SIZE = 5; -} // namespace - -namespace contextual_suggestions { - -ContextualSuggestionsDebuggingReporter:: - ContextualSuggestionsDebuggingReporter() = default; - -ContextualSuggestionsDebuggingReporter:: - ~ContextualSuggestionsDebuggingReporter() = default; - -const std::vector<ContextualSuggestionsDebuggingEvent>& -ContextualSuggestionsDebuggingReporter::GetEvents() const { - return events_; -} - -void ContextualSuggestionsDebuggingReporter::ClearEvents() { - events_.clear(); -} - -void ContextualSuggestionsDebuggingReporter::SetupForPage( - const std::string& url, - ukm::SourceId source_id) { - current_event_ = ContextualSuggestionsDebuggingEvent(); - current_event_.url = url; -} - -void ContextualSuggestionsDebuggingReporter::RecordEvent( - ContextualSuggestionsEvent event) { - switch (event) { - case FETCH_DELAYED: - case FETCH_REQUESTED: - case FETCH_ERROR: - case FETCH_SERVER_BUSY: - case FETCH_BELOW_THRESHOLD: - case FETCH_EMPTY: - case FETCH_COMPLETED: - case UI_PEEK_REVERSE_SCROLL: - current_event_.sheet_peeked = true; - return; - case UI_BUTTON_SHOWN: - current_event_.button_shown = true; - return; - case UI_OPENED: - current_event_.sheet_opened = true; - return; - case UI_DISMISSED_WITHOUT_OPEN: - case UI_DISMISSED_AFTER_OPEN: - current_event_.sheet_closed = true; - return; - case SUGGESTION_DOWNLOADED: - current_event_.any_suggestion_downloaded = true; - return; - case SUGGESTION_CLICKED: - current_event_.any_suggestion_taken = true; - return; - case UI_CLOSED_OBSOLETE: - NOTREACHED() << "Obsolete event, do not use!"; - return; - default: - NOTREACHED() << "Unexpected event, not correctly handled!"; - return; - } -} - -void ContextualSuggestionsDebuggingReporter::Flush() { - // Check if we've already sent an event with this url to the cache. If so, - // remove it before adding another one. - const std::string current_url = current_event_.url; - base::EraseIf(events_, - [current_url](ContextualSuggestionsDebuggingEvent event) { - return current_url == event.url; - }); - events_.push_back(current_event_); - - // If the cache is too large, then remove the least recently used. - if (events_.size() > CACHE_SIZE) - events_.erase(events_.begin()); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h b/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h deleted file mode 100644 index 8d813f1..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_DEBUGGING_REPORTER_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_DEBUGGING_REPORTER_H_ - -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/macros.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -namespace contextual_suggestions { - -// Models the events being reported to the debugging reporter. -// TODO(wylieb): Timestamp events as they happen. -struct ContextualSuggestionsDebuggingEvent { - // Name of the url. - std::string url; - - // Whether any suggestion was downloaded. - bool any_suggestion_downloaded = false; - - // Whether any suggestion was taken. - bool any_suggestion_taken = false; - - // Whether the sheet was closed. - bool sheet_closed = false; - - // Whether the sheet was ever opened. - bool sheet_opened = false; - - // Whether the sheet ever peeked. - bool sheet_peeked = false; - - // Whether the button has even been shown. - bool button_shown = false; -}; - -// Reporter specialized for caching information for debugging purposes. -class ContextualSuggestionsDebuggingReporter - : public ContextualSuggestionsReporter { - public: - ContextualSuggestionsDebuggingReporter(); - ~ContextualSuggestionsDebuggingReporter() override; - - // Get all events currently in the buffer. - const std::vector<ContextualSuggestionsDebuggingEvent>& GetEvents() const; - - // Clear the debugging cache of events. - void ClearEvents(); - - // ContextualSuggestionsReporter - void SetupForPage(const std::string& url, - ukm::SourceId source_id) override; - void RecordEvent( - contextual_suggestions::ContextualSuggestionsEvent event) override; - void Flush() override; - - private: - std::vector<ContextualSuggestionsDebuggingEvent> events_; - ContextualSuggestionsDebuggingEvent current_event_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsDebuggingReporter); -}; -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_DEBUGGING_REPORTER_H_
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.cc deleted file mode 100644 index b111040..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.cc +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" - -#include <string> - -#include "base/metrics/histogram_macros.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h" -#include "services/metrics/public/cpp/ukm_recorder.h" - -namespace contextual_suggestions { - -ContextualSuggestionsMetricsReporter::ContextualSuggestionsMetricsReporter() - : sheet_peeked_(false), - button_shown_(false), - sheet_opened_(false), - sheet_closed_(false), - any_suggestion_downloaded_(false), - any_suggestion_taken_(false), - ukm_entry_(nullptr) {} - -ContextualSuggestionsMetricsReporter::~ContextualSuggestionsMetricsReporter() { - DCHECK(!ukm_entry_) << "Flush should be called before destruction!"; -} - -void ContextualSuggestionsMetricsReporter::SetupForPage( - const std::string& url, - ukm::SourceId source_id) { - DCHECK(!ukm_entry_) << "Flush should be called before SetupForPage!"; - DCHECK(source_id != ukm::kInvalidSourceId); - ukm_entry_.reset(new ContextualSuggestionsUkmEntry(source_id)); -} - -void ContextualSuggestionsMetricsReporter::RecordEvent( - ContextualSuggestionsEvent event) { - DCHECK(ukm_entry_) - << "Page not set up. Did you forget to call SetupForPage or Flush?"; - ukm_entry_->RecordEventMetrics(event); - RecordUmaMetrics(event); -} - -void ContextualSuggestionsMetricsReporter::Flush() { - ResetUma(); - if (ukm_entry_) { - ukm_entry_->Flush(); - ukm_entry_.reset(); - } -} - -void ContextualSuggestionsMetricsReporter::RecordUmaMetrics( - ContextualSuggestionsEvent event) { - switch (event) { - case FETCH_DELAYED: - case FETCH_REQUESTED: - case FETCH_ERROR: - case FETCH_SERVER_BUSY: - case FETCH_BELOW_THRESHOLD: - case FETCH_EMPTY: - case FETCH_COMPLETED: - break; - case UI_PEEK_REVERSE_SCROLL: - if (sheet_peeked_) - return; - sheet_peeked_ = true; - break; - case UI_BUTTON_SHOWN: - if (button_shown_) - return; - button_shown_ = true; - break; - case UI_OPENED: - if (sheet_opened_) - return; - sheet_opened_ = true; - break; - case UI_DISMISSED_WITHOUT_OPEN: - case UI_DISMISSED_AFTER_OPEN: - if (sheet_closed_) - return; - sheet_closed_ = true; - break; - case SUGGESTION_DOWNLOADED: - if (any_suggestion_downloaded_) - return; - any_suggestion_downloaded_ = true; - break; - case SUGGESTION_CLICKED: - if (any_suggestion_taken_) - return; - any_suggestion_taken_ = true; - break; - case UI_CLOSED_OBSOLETE: - NOTREACHED() << "Obsolete event, do not use!"; - return; - default: - NOTREACHED() << "Unexpected event, not correctly handled!"; - return; - } - UMA_HISTOGRAM_ENUMERATION("ContextualSuggestions.Events", event); -} - -void ContextualSuggestionsMetricsReporter::ResetUma() { - sheet_peeked_ = false; - button_shown_ = false; - sheet_opened_ = false; - sheet_closed_ = false; - any_suggestion_downloaded_ = false; - any_suggestion_taken_ = false; -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h b/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h deleted file mode 100644 index 7dffdce..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_METRICS_REPORTER_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_METRICS_REPORTER_H_ - -#include <memory> - -#include "base/callback.h" -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -namespace contextual_suggestions { - -class ContextualSuggestionsUkmEntry; - -FORWARD_DECLARE_TEST(ContextualSuggestionsMetricsReporterTest, BaseTest); - -// Reporter specialized for UKM/UMA metrics reporting. -class ContextualSuggestionsMetricsReporter - : public ContextualSuggestionsReporter { - public: - ContextualSuggestionsMetricsReporter(); - ~ContextualSuggestionsMetricsReporter() override; - - // ContextualSuggestionsReporter - void SetupForPage(const std::string& url, - ukm::SourceId source_id) override; - void RecordEvent(ContextualSuggestionsEvent event) override; - void Flush() override; - - private: - FRIEND_TEST_ALL_PREFIXES(ContextualSuggestionsMetricsReporterTest, BaseTest); - - // Records UMA metrics for this event. - void RecordUmaMetrics(ContextualSuggestionsEvent event); - - // Reset UMA metrics. - void ResetUma(); - - // Internal UMA state data. - // Whether the sheet ever peeked. - bool sheet_peeked_; - // Whether the button was ever shown. - bool button_shown_; - // Whether the sheet was ever opened. - bool sheet_opened_; - // Whether the sheet was closed. - bool sheet_closed_; - // Whether any suggestion was downloaded. - bool any_suggestion_downloaded_; - // Whether any suggestion was taken. - bool any_suggestion_taken_; - - // The current UKM entry. - std::unique_ptr<ContextualSuggestionsUkmEntry> ukm_entry_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsMetricsReporter); -}; - -using ReportFetchMetricsCallback = base::RepeatingCallback<void( - contextual_suggestions::ContextualSuggestionsEvent event)>; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_METRICS_REPORTER_H_
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter_unittest.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter_unittest.cc deleted file mode 100644 index 162693e..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter_unittest.cc +++ /dev/null
@@ -1,248 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" - -#include "base/macros.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_task_environment.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h" -#include "components/ukm/test_ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -using ukm::TestUkmRecorder; -using ukm::builders::ContextualSuggestions; - -namespace contextual_suggestions { - -namespace { -const char kEventsHistogramName[] = "ContextualSuggestions.Events"; -const char kTestNavigationUrl[] = "https://foo.com"; -const int kUninitialized = 0; -const int kFetchDelayed = 1; -const int kFetchRequested = 2; -const int kFetchError = 3; -const int kFetchServerBusy = 4; -const int kFetchBelowThreshold = 5; -const int kFetchEmpty = 6; -const int kFetchCompleted = 7; -const int kUiPeekReverseScroll = 8; -const int kUiOpened = 9; -const int kUiClosedObsolete = 10; -const int kSuggestionDownloaded = 11; -const int kSuggestionClicked = 12; -const int kUiDismissedWithoutOpen = 13; -const int kUiDismissedAfterOpen = 14; -const int kUiButtonShown = 15; -} // namespace - -class ContextualSuggestionsMetricsReporterTest : public ::testing::Test { - protected: - ContextualSuggestionsMetricsReporterTest() = default; - - TestUkmRecorder* GetTestUkmRecorder() { return &test_ukm_recorder_; } - - ukm::SourceId GetSourceId(); - - ContextualSuggestionsMetricsReporter& GetReporter() { return reporter_; } - - protected: - void ExpectMultipleEventsCountOnce(ContextualSuggestionsEvent event); - - private: - // The reporter under test. - ContextualSuggestionsMetricsReporter reporter_; - - // Sets up the task scheduling/task-runner environment for each test. - base::test::ScopedTaskEnvironment scoped_task_environment_; - - // Sets itself as the global UkmRecorder on construction. - ukm::TestAutoSetUkmRecorder test_ukm_recorder_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsMetricsReporterTest); -}; - -ukm::SourceId ContextualSuggestionsMetricsReporterTest::GetSourceId() { - ukm::SourceId source_id = ukm::UkmRecorder::GetNewSourceID(); - test_ukm_recorder_.UpdateSourceURL(source_id, GURL(kTestNavigationUrl)); - return source_id; -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, BaseTest) { - base::HistogramTester histogram_tester; - GetReporter().SetupForPage(kTestNavigationUrl, GetSourceId()); - GetReporter().RecordEvent(FETCH_REQUESTED); - GetReporter().RecordEvent(FETCH_COMPLETED); - GetReporter().RecordEvent(UI_PEEK_REVERSE_SCROLL); - GetReporter().RecordEvent(UI_OPENED); - GetReporter().RecordEvent(SUGGESTION_DOWNLOADED); - GetReporter().RecordEvent(SUGGESTION_CLICKED); - // Flush data to write to UKM. - GetReporter().Flush(); - // Check that we wrote something to UKM. Details of UKM reporting are tested - // in a different test suite. - TestUkmRecorder* test_ukm_recorder = GetTestUkmRecorder(); - std::vector<const ukm::mojom::UkmEntry*> entry_vector = - test_ukm_recorder->GetEntriesByName(ContextualSuggestions::kEntryName); - EXPECT_EQ(1U, entry_vector.size()); - const ukm::mojom::UkmEntry* first_entry = entry_vector[0]; - EXPECT_TRUE(test_ukm_recorder->EntryHasMetric( - first_entry, ContextualSuggestions::kFetchStateName)); - EXPECT_EQ(static_cast<int64_t>(FetchState::COMPLETED), - *(test_ukm_recorder->GetEntryMetric( - first_entry, ContextualSuggestions::kFetchStateName))); - // Test that the expected histogram events were written. - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUninitialized, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchDelayed, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchRequested, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchError, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchServerBusy, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchBelowThreshold, - 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchEmpty, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchCompleted, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUiPeekReverseScroll, - 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUiOpened, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUiClosedObsolete, - 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, - kSuggestionDownloaded, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kSuggestionClicked, - 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, - kUiDismissedWithoutOpen, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, - kUiDismissedAfterOpen, 0); -} - -void ContextualSuggestionsMetricsReporterTest::ExpectMultipleEventsCountOnce( - ContextualSuggestionsEvent event) { - std::unique_ptr<base::HistogramTester> histogram_tester = - std::make_unique<base::HistogramTester>(); - GetReporter().SetupForPage(kTestNavigationUrl, GetSourceId()); - // Always report a single FETCH_DELAYED event so we ensure there's a - // histogram (otherwise the ExpectBucketCount may crash). - GetReporter().RecordEvent(FETCH_DELAYED); - int event_index = static_cast<int>(event); - histogram_tester->ExpectBucketCount(kEventsHistogramName, event_index, 0); - // Peek the UI, which starts the timer, expected by all the other UI or - // suggestion events. - GetReporter().RecordEvent(UI_PEEK_REVERSE_SCROLL); - // Report the event that we want to test multiple times. - GetReporter().RecordEvent(event); - GetReporter().RecordEvent(event); - histogram_tester->ExpectBucketCount(kEventsHistogramName, event_index, 1); - GetReporter().Flush(); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, UiPeekReverseScrollTest) { - ExpectMultipleEventsCountOnce(UI_PEEK_REVERSE_SCROLL); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, UiOpenedTest) { - ExpectMultipleEventsCountOnce(UI_OPENED); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, UiDismissedWithoutOpenTest) { - ExpectMultipleEventsCountOnce(UI_DISMISSED_WITHOUT_OPEN); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, UiDismissedAfterOpenTest) { - ExpectMultipleEventsCountOnce(UI_DISMISSED_AFTER_OPEN); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, SuggestionDownloadedTest) { - ExpectMultipleEventsCountOnce(SUGGESTION_DOWNLOADED); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, SuggestionClickedTest) { - ExpectMultipleEventsCountOnce(SUGGESTION_CLICKED); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, MultipleEventsTest) { - std::unique_ptr<base::HistogramTester> histogram_tester = - std::make_unique<base::HistogramTester>(); - GetReporter().SetupForPage(kTestNavigationUrl, GetSourceId()); - // Test multiple cycles of FETCH_REQUESTED, FETCH_COMPLETED. - GetReporter().RecordEvent(FETCH_REQUESTED); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchRequested, 1); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchCompleted, 0); - GetReporter().RecordEvent(FETCH_COMPLETED); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchRequested, 1); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchCompleted, 1); - GetReporter().RecordEvent(FETCH_REQUESTED); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchRequested, 2); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchCompleted, 1); - GetReporter().RecordEvent(FETCH_COMPLETED); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchRequested, 2); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kFetchCompleted, 2); - GetReporter().Flush(); -} - -// Test that might catch enum reordering that's not done right. -TEST_F(ContextualSuggestionsMetricsReporterTest, EnumNotReorderedTest) { - std::unique_ptr<base::HistogramTester> histogram_tester = - std::make_unique<base::HistogramTester>(); - GetReporter().SetupForPage(kTestNavigationUrl, GetSourceId()); - // Peek the UI, which starts the timer, expected by all the other UI or - // suggestion events. - GetReporter().RecordEvent(UI_PEEK_REVERSE_SCROLL); - // The current last legal event. - GetReporter().RecordEvent(SUGGESTION_CLICKED); - histogram_tester->ExpectBucketCount(kEventsHistogramName, kSuggestionClicked, - 1); - GetReporter().Flush(); -} - -TEST_F(ContextualSuggestionsMetricsReporterTest, ButtonTest) { - base::HistogramTester histogram_tester; - GetReporter().SetupForPage(kTestNavigationUrl, GetSourceId()); - GetReporter().RecordEvent(FETCH_REQUESTED); - GetReporter().RecordEvent(FETCH_COMPLETED); - GetReporter().RecordEvent(UI_BUTTON_SHOWN); - GetReporter().RecordEvent(UI_OPENED); - GetReporter().RecordEvent(SUGGESTION_DOWNLOADED); - GetReporter().RecordEvent(SUGGESTION_CLICKED); - // Flush data to write to UKM. - GetReporter().Flush(); - // Check that we wrote something to UKM. Details of UKM reporting are tested - // in a different test suite. - TestUkmRecorder* test_ukm_recorder = GetTestUkmRecorder(); - std::vector<const ukm::mojom::UkmEntry*> entry_vector = - test_ukm_recorder->GetEntriesByName(ContextualSuggestions::kEntryName); - EXPECT_EQ(1U, entry_vector.size()); - const ukm::mojom::UkmEntry* first_entry = entry_vector[0]; - EXPECT_TRUE(test_ukm_recorder->EntryHasMetric( - first_entry, ContextualSuggestions::kFetchStateName)); - EXPECT_EQ(static_cast<int64_t>(FetchState::COMPLETED), - *(test_ukm_recorder->GetEntryMetric( - first_entry, ContextualSuggestions::kFetchStateName))); - // Test that the expected histogram events were written. - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUninitialized, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchDelayed, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchRequested, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchError, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchServerBusy, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchBelowThreshold, - 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchEmpty, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kFetchCompleted, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUiButtonShown, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUiOpened, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kUiClosedObsolete, - 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, - kSuggestionDownloaded, 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, kSuggestionClicked, - 1); - histogram_tester.ExpectBucketCount(kEventsHistogramName, - kUiDismissedWithoutOpen, 0); - histogram_tester.ExpectBucketCount(kEventsHistogramName, - kUiDismissedAfterOpen, 0); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc deleted file mode 100644 index 018c2eb5..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h" - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" - -namespace contextual_suggestions { - -ContextualSuggestionsReporterProvider::ContextualSuggestionsReporterProvider( - std::unique_ptr<ContextualSuggestionsDebuggingReporter> debugging_reporter) - : debugging_reporter_(std::move(debugging_reporter)) {} - -ContextualSuggestionsReporterProvider:: - ~ContextualSuggestionsReporterProvider() = default; - -std::unique_ptr<ContextualSuggestionsReporter> -ContextualSuggestionsReporterProvider::CreateReporter() { - std::unique_ptr<ContextualSuggestionsCompositeReporter> reporter = - std::make_unique<ContextualSuggestionsCompositeReporter>(); - reporter->AddOwnedReporter( - std::make_unique<ContextualSuggestionsMetricsReporter>()); - reporter->AddRawReporter(debugging_reporter_.get()); - return reporter; -} - -ContextualSuggestionsDebuggingReporter* -ContextualSuggestionsReporterProvider::GetDebuggingReporter() { - return debugging_reporter_.get(); -} - -ContextualSuggestionsReporter::ContextualSuggestionsReporter() = default; -ContextualSuggestionsReporter::~ContextualSuggestionsReporter() = default; - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h b/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h deleted file mode 100644 index 2f72c4e..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h +++ /dev/null
@@ -1,150 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_REPORTER_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_REPORTER_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -namespace contextual_suggestions { - -class ContextualSuggestionsDebuggingReporter; -class ContextualSuggestionsReporter; - -// Class producing |ContextualSuggestionsReporter| instances. It enables -// classes like |ContextualContentSuggestionService| to produce metrics -// reporters when needed, e.g. creation of service proxy, without knowing how to -// initialize them. -class ContextualSuggestionsReporterProvider { - public: - explicit ContextualSuggestionsReporterProvider( - std::unique_ptr<ContextualSuggestionsDebuggingReporter> - debugging_reporter); - virtual ~ContextualSuggestionsReporterProvider(); - - virtual std::unique_ptr<ContextualSuggestionsReporter> CreateReporter(); - - virtual ContextualSuggestionsDebuggingReporter* GetDebuggingReporter(); - - private: - // The debugging reporter is shared between instances of top-level reporter. - // Since multiple objects need a reference to this, it's kept as a unique - // pointer, and the raw pointer is given out to sub reporters. - std::unique_ptr<ContextualSuggestionsDebuggingReporter> debugging_reporter_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsReporterProvider); -}; - -// NOTE: because this is used for UMA reporting, these values should not be -// changed or reused; new values should be appended immediately before the -// EVENT_MAX value. Make sure to update the histogram enum -// (ContextualSuggestions.Event in enums.xml) accordingly! -// A Java counterpart will be generated for this enum. -// GENERATED_JAVA_ENUM_PACKAGE: ( -// org.chromium.chrome.browser.contextual_suggestions) -enum ContextualSuggestionsEvent { - // Indicates that this state is not initialized. - // Should never be intentionally recorded, just used as a default value. - UNINITIALIZED = 0, - // Records that fetching suggestions has been delayed on the client side. - FETCH_DELAYED = 1, - // The fetch request has been made but a response has not yet been received. - FETCH_REQUESTED = 2, - // The fetch response has been received, but there was some error. - FETCH_ERROR = 3, - // The fetch response indicates that the server was too busy to return any - // suggestions. - FETCH_SERVER_BUSY = 4, - // The fetch response includes suggestions but they were all below the - // confidence threshold needed to show them to the user. - FETCH_BELOW_THRESHOLD = 5, - // The fetch response has been received and parsed, but there were no - // suggestions. - FETCH_EMPTY = 6, - // The fetch response has been received and there are suggestions to show. - FETCH_COMPLETED = 7, - // The UI was shown in the "peeking bar" state, triggered by a reverse-scroll. - // If new gestures are added to trigger the peeking sheet then a new event - // should be added to this list. - UI_PEEK_REVERSE_SCROLL = 8, - // The UI sheet was opened. - UI_OPENED = 9, - // The UI was closed. General event for closed/dismissed, now obsolete. - UI_CLOSED_OBSOLETE = 10, - // A suggestion was downloaded. - SUGGESTION_DOWNLOADED = 11, - // A suggestion was taken, either with a click, or opened in a separate tab. - SUGGESTION_CLICKED = 12, - // The UI was dismissed without ever being opened. This means the sheet was - // closed while peeked before ever being expanded. - UI_DISMISSED_WITHOUT_OPEN = 13, - // The UI was dismissed after having been opened. This means the sheet was - // closed from any position after it was expanded at least once. - UI_DISMISSED_AFTER_OPEN = 14, - // The UI button was shown to the user. - UI_BUTTON_SHOWN = 15, - // Special name that marks the maximum value in an Enum used for UMA. - // https://cs.chromium.org/chromium/src/tools/metrics/histograms/README.md. - kMaxValue = UI_BUTTON_SHOWN, -}; - -// Tracks various metrics based on reports of events that take place -// within the Contextual Suggestions component. -// -// For example: -// Java UI -> ContextualSuggestionsBridge#reportEvent( -// /* web_contents */, @ContextualSuggestionsEvent int eventId) -> native -// -> ContextualContentSuggestionsService#reportEvent( -// ukm::GetSourceIdForWebContentsDocument(web_contents), eventId)) -> -// if(!reporter) { -// ContextualSuggestionsReporter* reporter = -// new ContextualSuggestionsMetricsReporter(); -// } -// std::string url; -// ukm::SourceId source_id_for_web_contents; -// reporter->SetupForPage(url, source_id_for_web_contents); -// reporter->RecordEvent(FETCH_REQUESTED); -// ... -// -// if (!my_results) -// reporter->RecordEvent(FETCH_ERROR); -// else if (my_result.size() == 0) -// reporter->RecordEvent(FETCH_EMPTY); -// else -// reporter->RecordEvent(FETCH_COMPLETED); -// ... -// When the UI shows: -// reporter->RecordEvent(UI_PEEK_SHOWN); -// Make sure data is flushed when leaving the page: -// reporter->Flush(); -class ContextualSuggestionsReporter { - public: - ContextualSuggestionsReporter(); - virtual ~ContextualSuggestionsReporter(); - - // Sets up the page with the given |source_id| for event reporting. - // All subsequent RecordEvent calls will apply to this page - virtual void SetupForPage(const std::string& url, - ukm::SourceId source_id) = 0; - - // Reports that an event occurred for the current page. - // Some data is not written immediately, but will be written when |Reset| is - // called. - virtual void RecordEvent(ContextualSuggestionsEvent event) = 0; - - // Flushes all data staged using |RecordEvent|. - // This is required before a subsequent call to |SetupForPage|, and can be - // called multiple times. - virtual void Flush() = 0; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsReporter); -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_REPORTER_H_
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.cc deleted file mode 100644 index ed6303d..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.cc +++ /dev/null
@@ -1,145 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h" - -#include <algorithm> - -#include "base/timer/elapsed_timer.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "services/metrics/public/cpp/metrics_utils.h" -#include "services/metrics/public/cpp/ukm_builders.h" - -namespace contextual_suggestions { - -namespace { -// Spacing between buckets for the duration in milliseconds. -// The values recorded will be the min of the bucket in a power of 2 range. -// E.g. 1100 => 1024 since 1024 <= 1100 < 2048. -const double kShowDurationBucketSpacing = 2.0; -const int64_t kMinShowDuration = 1; -} // namespace - -ContextualSuggestionsUkmEntry::ContextualSuggestionsUkmEntry( - ukm::SourceId source_id) - : fetch_state_(FetchState::NOT_STARTED), - trigger_event_(TriggerEvent::NEVER_SHOWN), - closed_from_peek_(false), - was_sheet_opened_(false), - any_suggestion_taken_(false), - any_suggestion_downloaded_(false), - show_duration_exponential_bucket_(0), - show_duration_timer_(nullptr), - source_id_(source_id) {} - -ContextualSuggestionsUkmEntry::~ContextualSuggestionsUkmEntry() {} - -void ContextualSuggestionsUkmEntry::RecordEventMetrics( - ContextualSuggestionsEvent event) { - switch (event) { - case UNINITIALIZED: - NOTREACHED() << "An uninitialized event value was sent!"; - break; - case FETCH_DELAYED: - fetch_state_ = FetchState::DELAYED; - break; - case FETCH_REQUESTED: - fetch_state_ = FetchState::REQUESTED; - break; - case FETCH_ERROR: - fetch_state_ = FetchState::ERROR_RESULT; - break; - case FETCH_SERVER_BUSY: - fetch_state_ = FetchState::SERVER_BUSY; - break; - case FETCH_BELOW_THRESHOLD: - fetch_state_ = FetchState::BELOW_THRESHOLD; - break; - case FETCH_EMPTY: - fetch_state_ = FetchState::EMPTY; - break; - case FETCH_COMPLETED: - fetch_state_ = FetchState::COMPLETED; - break; - case UI_PEEK_REVERSE_SCROLL: - trigger_event_ = TriggerEvent::REVERSE_SCROLL; - StartTimerIfNeeded(); - break; - case UI_BUTTON_SHOWN: - trigger_event_ = TriggerEvent::TOOLBAR_BUTTON; - StartTimerIfNeeded(); - break; - case UI_OPENED: - was_sheet_opened_ = true; - StartTimerIfNeeded(); - break; - case UI_CLOSED_OBSOLETE: - NOTREACHED(); - break; - case SUGGESTION_DOWNLOADED: - any_suggestion_downloaded_ = true; - StopTimerIfNeeded(); - break; - case SUGGESTION_CLICKED: - any_suggestion_taken_ = true; - StopTimerIfNeeded(); - break; - case UI_DISMISSED_WITHOUT_OPEN: - closed_from_peek_ = true; - StopTimerIfNeeded(); - break; - case UI_DISMISSED_AFTER_OPEN: - StopTimerIfNeeded(); - break; - } -} - -void ContextualSuggestionsUkmEntry::Flush() { - if (source_id_ == ukm::kInvalidSourceId) - return; - - if (show_duration_timer_) - StopTimerIfNeeded(); - - // Keep these writes alphabetical by setter name (matching ukm.xml ordering). - ukm::builders::ContextualSuggestions builder(source_id_); - builder.SetAnyDownloaded(any_suggestion_downloaded_) - .SetAnySuggestionTaken(any_suggestion_taken_) - .SetClosedFromPeek(closed_from_peek_) - .SetEverOpened(was_sheet_opened_) - .SetFetchState(static_cast<int64_t>(fetch_state_)) - .SetShowDurationBucketMin(show_duration_exponential_bucket_) - .SetTriggerEvent(static_cast<int64_t>(trigger_event_)) - .Record(ukm::UkmRecorder::Get()); - - source_id_ = ukm::kInvalidSourceId; -} - -void ContextualSuggestionsUkmEntry::StartTimerIfNeeded() { - // If the timer is already running, don't restart it. - if (show_duration_timer_) - return; - - show_duration_timer_.reset(new base::ElapsedTimer()); -} - -void ContextualSuggestionsUkmEntry::StopTimerIfNeeded() { - // We should either have a timer or a computed duration from the timer. - DCHECK(show_duration_timer_ || show_duration_exponential_bucket_ > 0); - - // If we've already computed the duration, or there's no timer to stop, then - // there's nothing to do. - if (show_duration_exponential_bucket_ > 0 || !show_duration_timer_) - return; - - show_duration_exponential_bucket_ = ukm::GetExponentialBucketMin( - show_duration_timer_->Elapsed().InMillisecondsRoundedUp(), - kShowDurationBucketSpacing); - // Ensure a positive value. - show_duration_exponential_bucket_ = - std::max(kMinShowDuration, show_duration_exponential_bucket_); - show_duration_timer_.reset(); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h b/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h deleted file mode 100644 index ffc2e405..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_UKM_ENTRY_H_ -#define COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_UKM_ENTRY_H_ - -#include "base/gtest_prod_util.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "services/metrics/public/cpp/ukm_source_id.h" - -namespace base { -class ElapsedTimer; -} - -namespace contextual_suggestions { - -FORWARD_DECLARE_TEST(ContextualSuggestionsUkmEntryTest, BinaryOrderTest); - -// The state of the Fetcher request. -// This value is written to the "FetchState" UKM metric. -enum class FetchState { - NOT_STARTED, - DELAYED, - REQUESTED, - ERROR_RESULT, - SERVER_BUSY, - BELOW_THRESHOLD, - EMPTY, - COMPLETED, -}; - -// The way that the sheet UI was triggered. -// This value is written to the "TriggerEvent" UKM metric. -enum class TriggerEvent { - NEVER_SHOWN, - REVERSE_SCROLL, - TOOLBAR_BUTTON, -}; - -// Writes a single UKM entry that describes the latest state of the event stream -// monitored through |RecordEventMetrics|. -class ContextualSuggestionsUkmEntry { - public: - // Sets up recording of a UKM entry for the given |source_id|. - explicit ContextualSuggestionsUkmEntry(ukm::SourceId source_id); - ~ContextualSuggestionsUkmEntry(); - - // Updates tracked metrics for the given |event|. - void RecordEventMetrics(ContextualSuggestionsEvent event); - - // Writes the latest data tracked into a single UKM entry. - void Flush(); - - private: - FRIEND_TEST_ALL_PREFIXES(ContextualSuggestionsUkmEntryTest, BinaryOrderTest); - - // Starts the elapsed timer if not already started. - void StartTimerIfNeeded(); - - // Stops the elapsed timer if not already stopped. - void StopTimerIfNeeded(); - - // Internal state trackers. - FetchState fetch_state_; - TriggerEvent trigger_event_; - bool closed_from_peek_; - bool was_sheet_opened_; - bool any_suggestion_taken_; - bool any_suggestion_downloaded_; - - // The minimum exponential bucket of the duration in milliseconds that the - // sheet was viewed before taking action. A value of 0 means not yet - // computed. - int64_t show_duration_exponential_bucket_; - - // Simple timer for how long the sheet is showing. - std::unique_ptr<base::ElapsedTimer> show_duration_timer_; - - // The UKM identifier for the current URL / page in use. - ukm::SourceId source_id_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsUkmEntry); -}; - -} // namespace contextual_suggestions - -#endif // COMPONENTS_NTP_SNIPPETS_CONTEXTUAL_REPORTING_CONTEXTUAL_SUGGESTIONS_UKM_ENTRY_H_
diff --git a/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry_unittest.cc b/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry_unittest.cc deleted file mode 100644 index 171005d..0000000 --- a/components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry_unittest.cc +++ /dev/null
@@ -1,128 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_ukm_entry.h" -#include "base/macros.h" -#include "base/test/scoped_task_environment.h" -#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h" -#include "components/ukm/test_ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ukm::TestUkmRecorder; -using ukm::builders::ContextualSuggestions; - -namespace contextual_suggestions { - -const int NO_ENTRY = -1; - -class ContextualSuggestionsUkmEntryTest : public ::testing::Test { - protected: - ContextualSuggestionsUkmEntryTest() = default; - - void SetUp() override; - - // The entry under test. - std::unique_ptr<ContextualSuggestionsUkmEntry> ukm_entry_; - - TestUkmRecorder* GetTestUkmRecorder() { return &test_ukm_recorder_; } - - const ukm::mojom::UkmEntry* FirstEntry(); - bool HasEntryMetric(const char* metric_name); - int GetEntryMetric(const char* metric_name); - - private: - // Sets up the task scheduling/task-runner environment for each test. - base::test::ScopedTaskEnvironment scoped_task_environment_; - - // Sets itself as the global UkmRecorder on construction. - ukm::TestAutoSetUkmRecorder test_ukm_recorder_; - - DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsUkmEntryTest); -}; - -void ContextualSuggestionsUkmEntryTest::SetUp() { - ukm_entry_.reset( - new ContextualSuggestionsUkmEntry(ukm::UkmRecorder::GetNewSourceID())); -} - -const ukm::mojom::UkmEntry* ContextualSuggestionsUkmEntryTest::FirstEntry() { - TestUkmRecorder* recorder = GetTestUkmRecorder(); - std::vector<const ukm::mojom::UkmEntry*> entry_vector = - recorder->GetEntriesByName(ContextualSuggestions::kEntryName); - EXPECT_EQ(1U, entry_vector.size()); - return entry_vector[0]; -} - -bool ContextualSuggestionsUkmEntryTest::HasEntryMetric( - const char* metric_name) { - TestUkmRecorder* recorder = GetTestUkmRecorder(); - return recorder->EntryHasMetric(FirstEntry(), metric_name); -} - -int ContextualSuggestionsUkmEntryTest::GetEntryMetric(const char* metric_name) { - TestUkmRecorder* recorder = GetTestUkmRecorder(); - const ukm::mojom::UkmEntry* first_entry = FirstEntry(); - if (!recorder->EntryHasMetric(first_entry, metric_name)) - return NO_ENTRY; - - return (int)*(recorder->GetEntryMetric(first_entry, metric_name)); -} - -TEST_F(ContextualSuggestionsUkmEntryTest, BaseTest) { - ukm_entry_->Flush(); - // Deleting the entry should write default values for everything. - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kAnyDownloadedName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kAnySuggestionTakenName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kClosedFromPeekName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kEverOpenedName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kFetchStateName)); - EXPECT_EQ(0, - GetEntryMetric(ContextualSuggestions::kShowDurationBucketMinName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kTriggerEventName)); -} - -TEST_F(ContextualSuggestionsUkmEntryTest, ExpectedOperationTest) { - ukm_entry_->RecordEventMetrics(FETCH_DELAYED); - ukm_entry_->RecordEventMetrics(FETCH_REQUESTED); - ukm_entry_->RecordEventMetrics(FETCH_COMPLETED); - ukm_entry_->RecordEventMetrics(UI_PEEK_REVERSE_SCROLL); - ukm_entry_->RecordEventMetrics(UI_OPENED); - ukm_entry_->RecordEventMetrics(SUGGESTION_DOWNLOADED); - ukm_entry_->RecordEventMetrics(SUGGESTION_DOWNLOADED); - ukm_entry_->RecordEventMetrics(SUGGESTION_CLICKED); - ukm_entry_->Flush(); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kAnyDownloadedName)); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kAnySuggestionTakenName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kClosedFromPeekName)); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kEverOpenedName)); - EXPECT_EQ(static_cast<int64_t>(FetchState::COMPLETED), - GetEntryMetric(ContextualSuggestions::kFetchStateName)); - EXPECT_LT(0, - GetEntryMetric(ContextualSuggestions::kShowDurationBucketMinName)); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kTriggerEventName)); -} - -TEST_F(ContextualSuggestionsUkmEntryTest, ExpectedOperationButtonTest) { - ukm_entry_->RecordEventMetrics(FETCH_DELAYED); - ukm_entry_->RecordEventMetrics(FETCH_REQUESTED); - ukm_entry_->RecordEventMetrics(FETCH_COMPLETED); - ukm_entry_->RecordEventMetrics(UI_BUTTON_SHOWN); - ukm_entry_->RecordEventMetrics(UI_OPENED); - ukm_entry_->RecordEventMetrics(SUGGESTION_DOWNLOADED); - ukm_entry_->RecordEventMetrics(SUGGESTION_DOWNLOADED); - ukm_entry_->RecordEventMetrics(SUGGESTION_CLICKED); - ukm_entry_->Flush(); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kAnyDownloadedName)); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kAnySuggestionTakenName)); - EXPECT_EQ(0, GetEntryMetric(ContextualSuggestions::kClosedFromPeekName)); - EXPECT_EQ(1, GetEntryMetric(ContextualSuggestions::kEverOpenedName)); - EXPECT_EQ(static_cast<int64_t>(FetchState::COMPLETED), - GetEntryMetric(ContextualSuggestions::kFetchStateName)); - EXPECT_LT(0, - GetEntryMetric(ContextualSuggestions::kShowDurationBucketMinName)); - EXPECT_EQ(2, GetEntryMetric(ContextualSuggestions::kTriggerEventName)); -} - -} // namespace contextual_suggestions
diff --git a/components/ntp_snippets/remote/json_request.cc b/components/ntp_snippets/remote/json_request.cc index 3077d5a..32778de 100644 --- a/components/ntp_snippets/remote/json_request.cc +++ b/components/ntp_snippets/remote/json_request.cc
@@ -174,14 +174,14 @@ net_error == net::OK ? response_code : net_error); if (net_error != net::OK) { std::move(request_completed_callback_) - .Run(/*result=*/nullptr, FetchResult::URL_REQUEST_STATUS_ERROR, + .Run(/*result=*/base::Value(), FetchResult::URL_REQUEST_STATUS_ERROR, /*error_details=*/base::StringPrintf(" %d", net_error)); } else if (response_code / 100 != 2) { FetchResult result = response_code == net::HTTP_UNAUTHORIZED ? FetchResult::HTTP_ERROR_UNAUTHORIZED : FetchResult::HTTP_ERROR; std::move(request_completed_callback_) - .Run(/*result=*/nullptr, result, + .Run(/*result=*/base::Value(), result, /*error_details=*/base::StringPrintf(" %d", response_code)); } else { last_response_string_ = std::move(*response_body); @@ -192,7 +192,7 @@ } } -void JsonRequest::OnJsonParsed(std::unique_ptr<base::Value> result) { +void JsonRequest::OnJsonParsed(base::Value result) { std::move(request_completed_callback_) .Run(std::move(result), FetchResult::SUCCESS, /*error_details=*/std::string()); @@ -202,7 +202,7 @@ LOG(WARNING) << "Received invalid JSON (" << error << "): " << last_response_string_; std::move(request_completed_callback_) - .Run(/*result=*/nullptr, FetchResult::JSON_PARSE_ERROR, + .Run(/*result=*/base::Value(), FetchResult::JSON_PARSE_ERROR, /*error_details=*/base::StringPrintf(" (error %s)", error.c_str())); }
diff --git a/components/ntp_snippets/remote/json_request.h b/components/ntp_snippets/remote/json_request.h index e454961..7f2cbfb 100644 --- a/components/ntp_snippets/remote/json_request.h +++ b/components/ntp_snippets/remote/json_request.h
@@ -59,7 +59,7 @@ // A client can expect error_details only, if there was any error during the // fetching or parsing. In successful cases, it will be an empty string. using CompletedCallback = - base::OnceCallback<void(std::unique_ptr<base::Value> result, + base::OnceCallback<void(base::Value result, FetchResult result_code, const std::string& error_details)>; @@ -153,7 +153,7 @@ void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body); void ParseJsonResponse(); - void OnJsonParsed(std::unique_ptr<base::Value> result); + void OnJsonParsed(base::Value result); void OnJsonError(const std::string& error); // The loader for downloading the snippets. Only non-null if a load is
diff --git a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc index 256ce45..9aee75b 100644 --- a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
@@ -345,7 +345,7 @@ SnippetsAvailableCallback callback, bool is_authenticated, std::string access_token, - std::unique_ptr<base::Value> result, + base::Value result, FetchResult status_code, const std::string& error_details) { DCHECK(request); @@ -356,14 +356,14 @@ UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime", request->GetFetchDuration()); - if (!result) { + if (result.is_none()) { FetchFinished(OptionalFetchedCategories(), std::move(callback), status_code, error_details, is_authenticated, access_token); return; } FetchedCategoriesVector categories; - if (!JsonToCategories(*result, &categories, fetch_time)) { + if (!JsonToCategories(result, &categories, fetch_time)) { LOG(WARNING) << "Received invalid snippets: " << last_fetch_json_; FetchFinished(OptionalFetchedCategories(), std::move(callback), FetchResult::INVALID_SNIPPET_CONTENT_ERROR, std::string(),
diff --git a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h index a7553fd..4511d2fd 100644 --- a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h +++ b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
@@ -92,7 +92,7 @@ SnippetsAvailableCallback callback, bool is_authenticated, std::string access_token, - std::unique_ptr<base::Value> result, + base::Value result, internal::FetchResult status_code, const std::string& error_details); void FetchFinished(OptionalFetchedCategories categories,
diff --git a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc index 121b464..04f78c9 100644 --- a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
@@ -151,9 +151,9 @@ const SuccessCallback& success_callback, const ErrorCallback& error_callback) { base::JSONReader json_reader; - std::unique_ptr<base::Value> value = json_reader.ReadToValueDeprecated(json); + base::Optional<base::Value> value = json_reader.ReadToValue(json); if (value) { - success_callback.Run(std::move(value)); + success_callback.Run(std::move(*value)); } else { error_callback.Run(json_reader.GetErrorMessage()); }
diff --git a/components/ntp_snippets/remote/request_params.h b/components/ntp_snippets/remote/request_params.h index f555756..1066644f 100644 --- a/components/ntp_snippets/remote/request_params.h +++ b/components/ntp_snippets/remote/request_params.h
@@ -41,8 +41,7 @@ }; // Callbacks for JSON parsing to allow injecting platform-dependent code. -using SuccessCallback = - base::Callback<void(std::unique_ptr<base::Value> result)>; +using SuccessCallback = base::Callback<void(base::Value result)>; using ErrorCallback = base::Callback<void(const std::string& error)>; using ParseJSONCallback = base::Callback<void(const std::string& raw_json_string,
diff --git a/components/password_manager/core/browser/login_database_posix.cc b/components/password_manager/core/browser/login_database_posix.cc index 7ac5ad95..241c2d5 100644 --- a/components/password_manager/core/browser/login_database_posix.cc +++ b/components/password_manager/core/browser/login_database_posix.cc
@@ -2,13 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/metrics/histogram_macros.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "components/os_crypt/os_crypt.h" #include "components/password_manager/core/browser/login_database.h" -#include "base/strings/utf_string_conversions.h" -#include "components/os_crypt/os_crypt.h" - namespace password_manager { +namespace { + +enum class PasswordDecryptionResult { + kFailed = 0, + kSucceeded = 1, + kSucceededBySkipping = 2, + kSucceededByIgnoringFailure = 3, + kMaxValue = kSucceededByIgnoringFailure +}; + +void RecordPasswordDecryptionResult(PasswordDecryptionResult result) { + UMA_HISTOGRAM_ENUMERATION("PasswordManager.StoreDecryptionResult", result); +} + +} // namespace + LoginDatabase::EncryptionResult LoginDatabase::EncryptedString( const base::string16& plain_text, std::string* cipher_text) const { @@ -25,14 +42,42 @@ LoginDatabase::EncryptionResult LoginDatabase::DecryptedString( const std::string& cipher_text, base::string16* plain_text) const { - if (!use_encryption_) { +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) + // On Android and ChromeOS, we have a mix of obfuscated and plain-text + // passwords. Obfuscated passwords always start with "v10", therefore anything + // else is plain-text. + // TODO(crbug.com/960322): Remove this when there isn't a mix of plain-text + // and obfuscated passwords. + bool use_encryption = use_encryption_ && (cipher_text.find("v10", 0) == 0); +#else + bool use_encryption = use_encryption_; +#endif + + if (!use_encryption) { *plain_text = base::UTF8ToUTF16(cipher_text); + RecordPasswordDecryptionResult( + PasswordDecryptionResult::kSucceededBySkipping); return ENCRYPTION_RESULT_SUCCESS; } - return OSCrypt::DecryptString16(cipher_text, plain_text) - ? ENCRYPTION_RESULT_SUCCESS - : ENCRYPTION_RESULT_SERVICE_FAILURE; + bool decryption_success = OSCrypt::DecryptString16(cipher_text, plain_text); +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) + // If decryption failed, we assume it was because the value was actually a + // plain-text password which started with "v10". + // TODO(crbug.com/960322): Remove this when there isn't a mix of plain-text + // and obfuscated passwords. + if (!decryption_success) { + *plain_text = base::UTF8ToUTF16(cipher_text); + RecordPasswordDecryptionResult( + PasswordDecryptionResult::kSucceededByIgnoringFailure); + return ENCRYPTION_RESULT_SUCCESS; + } +#endif + RecordPasswordDecryptionResult(decryption_success + ? PasswordDecryptionResult::kSucceeded + : PasswordDecryptionResult::kFailed); + return decryption_success ? ENCRYPTION_RESULT_SUCCESS + : ENCRYPTION_RESULT_SERVICE_FAILURE; } } // namespace password_manager
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc index 6dcaef25..a62b732d 100644 --- a/components/password_manager/core/browser/login_database_unittest.cc +++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -42,8 +42,11 @@ using autofill::ValueElementPair; using autofill::ValueElementVector; using base::ASCIIToUTF16; +using base::UTF16ToASCII; using ::testing::Eq; +using ::testing::Ne; using ::testing::Pointee; +using ::testing::SizeIs; using ::testing::UnorderedElementsAre; namespace password_manager { @@ -88,20 +91,24 @@ // Helper functions to read the value of the first column of an executed // statement if we know its type. You must implement a specialization for // every column type you use. -template<class T> struct must_be_specialized { +template <class T> +struct must_be_specialized { static const bool is_specialized = false; }; -template<class T> T GetFirstColumn(const sql::Statement& s) { +template <class T> +T GetFirstColumn(const sql::Statement& s) { static_assert(must_be_specialized<T>::is_specialized, "Implement a specialization."); } -template<> int64_t GetFirstColumn(const sql::Statement& s) { +template <> +int64_t GetFirstColumn(const sql::Statement& s) { return s.ColumnInt64(0); } -template<> std::string GetFirstColumn(const sql::Statement& s) { +template <> +std::string GetFirstColumn(const sql::Statement& s) { return s.ColumnString(0); } @@ -1465,27 +1472,22 @@ "PasswordManager.TotalAccounts.UserCreated.WithoutCustomPassphrase", 9, 1); histogram_tester.ExpectBucketCount( - "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase", - 1, + "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase", 1, 2); histogram_tester.ExpectBucketCount( "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase", 2, 3); histogram_tester.ExpectBucketCount( "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase", - 0, - 1); + 0, 1); histogram_tester.ExpectBucketCount( "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase", - 1, - 1); + 1, 1); histogram_tester.ExpectBucketCount( "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase", - 3, - 1); + 3, 1); histogram_tester.ExpectUniqueSample( - "PasswordManager.TotalAccounts.AutoGenerated.WithoutCustomPassphrase", - 2, + "PasswordManager.TotalAccounts.AutoGenerated.WithoutCustomPassphrase", 2, 1); histogram_tester.ExpectUniqueSample( "PasswordManager.TotalAccountsHiRes.WithScheme.Android", 2, 1); @@ -1502,20 +1504,14 @@ 1, 2); histogram_tester.ExpectBucketCount( "PasswordManager.TimesPasswordUsed.AutoGenerated.WithoutCustomPassphrase", - 2, - 1); + 2, 1); histogram_tester.ExpectBucketCount( "PasswordManager.TimesPasswordUsed.AutoGenerated.WithoutCustomPassphrase", - 4, - 1); + 4, 1); histogram_tester.ExpectUniqueSample( - "PasswordManager.EmptyUsernames.CountInDatabase", - 3, - 1); + "PasswordManager.EmptyUsernames.CountInDatabase", 3, 1); histogram_tester.ExpectUniqueSample( - "PasswordManager.EmptyUsernames.WithoutCorrespondingNonempty", - 1, - 1); + "PasswordManager.EmptyUsernames.WithoutCorrespondingNonempty", 1, 1); histogram_tester.ExpectUniqueSample("PasswordManager.InaccessiblePasswords", 0, 1); } @@ -1847,6 +1843,57 @@ } #endif // defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) +// On Android and ChromeOS there is a mix of plain-text and obfuscated +// passwords. Verify that they can both be accessed. Obfuscated passwords start +// with "v10". Some password values also start with "v10". Test that both are +// accessible (this doesn't work for any plain-text value). +TEST_F(LoginDatabaseTest, HandleObfuscationMix) { + const char k_obfuscated_pw[] = "v10pass1"; + const char k_plain_text_pw1[] = "v10pass2"; + const char k_plain_text_pw2[] = "v11pass3"; + + base::FilePath file = temp_dir_.GetPath().AppendASCII("TestUnencryptedDB"); + { + LoginDatabase db(file); + ASSERT_TRUE(db.Init()); + // Add obfuscated (new) entries. + PasswordForm password_form; + GenerateExamplePasswordForm(&password_form); + password_form.password_value = ASCIIToUTF16(k_obfuscated_pw); + EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form)); + // Add plain-text (old) entries. + db.disable_encryption(); + GenerateExamplePasswordForm(&password_form); + password_form.username_value = ASCIIToUTF16("other_username"); + password_form.password_value = ASCIIToUTF16(k_plain_text_pw1); + EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form)); + GenerateExamplePasswordForm(&password_form); + password_form.username_value = ASCIIToUTF16("other_username2"); + password_form.password_value = ASCIIToUTF16(k_plain_text_pw2); + EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form)); + } + + std::vector<std::unique_ptr<autofill::PasswordForm>> forms; + { + LoginDatabase db(file); + ASSERT_TRUE(db.Init()); + ASSERT_TRUE(db.GetAutofillableLogins(&forms)); + } + + // On disk, unobfuscated passwords are as-is, while obfuscated passwords have + // been changed (obfuscated). + EXPECT_THAT(GetColumnValuesFromDatabase<std::string>(file, "password_value"), + UnorderedElementsAre(Ne(k_obfuscated_pw), k_plain_text_pw1, + k_plain_text_pw2)); + // LoginDatabase serves the original values. + ASSERT_THAT(forms, SizeIs(3)); + EXPECT_EQ(k_obfuscated_pw, UTF16ToASCII(forms[0]->password_value)); + EXPECT_EQ(k_plain_text_pw1, UTF16ToASCII(forms[1]->password_value)); + EXPECT_EQ(k_plain_text_pw2, UTF16ToASCII(forms[2]->password_value)); +} +#endif // defined(OS_ANDROID) || defined(OS_CHROMEOS) + // If the database initialisation fails, the initialisation transaction should // roll back without crashing. TEST(LoginDatabaseFailureTest, Init_NoCrashOnFailedRollback) {
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index a0334a00..a4ead927 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -247,6 +247,7 @@ UMA_HISTOGRAM_ENUMERATION("PasswordManager.DynamicFormChanges", *form_changes_bitmask_, static_cast<uint32_t>(kMaxFormDifferencesValue)); + ukm_entry_builder_.SetDynamicFormChanges(*form_changes_bitmask_); } if (submit_result_ == kSubmitResultPassed && filling_assistance_) {
diff --git a/components/previews/content/previews_optimization_guide_unittest.cc b/components/previews/content/previews_optimization_guide_unittest.cc index 32de544..cba9bbe 100644 --- a/components/previews/content/previews_optimization_guide_unittest.cc +++ b/components/previews/content/previews_optimization_guide_unittest.cc
@@ -1721,9 +1721,6 @@ base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_list; scoped_list.InitAndEnableFeature(features::kOptimizationHintsFetching); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII("optimization_guide_service_url", - "https://hintsserver.com"); guide()->SetHintsFetcherForTesting( BuildTestHintsFetcher(HintsFetcherEndState::kFetchSuccessWithHints));
diff --git a/components/previews/core/previews_switches.cc b/components/previews/core/previews_switches.cc index b0b0fa55..de80525b 100644 --- a/components/previews/core/previews_switches.cc +++ b/components/previews/core/previews_switches.cc
@@ -40,12 +40,12 @@ // Overrides the Optimization Guide Service URL that the HintsFetcher will // request remote hints from. -const char kOptimizationGuideServiceURL[] = "optimization_guide_service_url"; +const char kOptimizationGuideServiceURL[] = "optimization-guide-service-url"; // Overrides the Optimization Guide Service API Key for remote requests to be // made. const char kOptimizationGuideServiceAPIKey[] = - "optimization_guide_service_api_key"; + "optimization-guide-service-api-key"; // Purges the hint cache store on startup, so that it's guaranteed to be using // fresh data.
diff --git a/components/safe_browsing/BUILD.gn b/components/safe_browsing/BUILD.gn index 616b933..a435efc 100644 --- a/components/safe_browsing/BUILD.gn +++ b/components/safe_browsing/BUILD.gn
@@ -87,3 +87,15 @@ "//base:base", ] } + +source_set("public") { + sources = [ + "safe_browsing_service_interface.cc", + "safe_browsing_service_interface.h", + ] + + deps = [ + "//base:base", + "//content/public/browser", + ] +}
diff --git a/components/safe_browsing/safe_browsing_service_interface.cc b/components/safe_browsing/safe_browsing_service_interface.cc new file mode 100644 index 0000000..a16d3e6a --- /dev/null +++ b/components/safe_browsing/safe_browsing_service_interface.cc
@@ -0,0 +1,17 @@ +// 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/safe_browsing/safe_browsing_service_interface.h" + +namespace safe_browsing { + +SafeBrowsingServiceInterface* +SafeBrowsingServiceInterface::CreateSafeBrowsingService() { + return factory_ ? factory_->CreateSafeBrowsingService() : nullptr; +} + +// static +SafeBrowsingServiceFactory* SafeBrowsingServiceInterface::factory_ = nullptr; + +} // namespace safe_browsing
diff --git a/components/safe_browsing/safe_browsing_service_interface.h b/components/safe_browsing/safe_browsing_service_interface.h new file mode 100644 index 0000000..4f216ccb --- /dev/null +++ b/components/safe_browsing/safe_browsing_service_interface.h
@@ -0,0 +1,67 @@ +// 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_SAFE_BROWSING_SAFE_BROWSING_SERVICE_INTERFACE_H_ +#define COMPONENTS_SAFE_BROWSING_SAFE_BROWSING_SERVICE_INTERFACE_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "content/public/browser/browser_thread.h" + +namespace safe_browsing { + +class SafeBrowsingServiceFactory; + +// This interface will provide methods for checking the safety of URLs and +// downloads with Safe Browsing. +class SafeBrowsingServiceInterface + : public base::RefCountedThreadSafe< + SafeBrowsingServiceInterface, + content::BrowserThread::DeleteOnUIThread> { + public: + // Makes the passed |factory| the factory used to instantiate + // a SafeBrowsingServiceInterface. Useful for tests. + static void RegisterFactory(SafeBrowsingServiceFactory* factory) { + factory_ = factory; + } + + static bool HasFactory() { return (factory_ != nullptr); } + + // Create an instance of the safe browsing service. + static SafeBrowsingServiceInterface* CreateSafeBrowsingService(); + + protected: + SafeBrowsingServiceInterface() {} + virtual ~SafeBrowsingServiceInterface() {} + + private: + friend struct content::BrowserThread::DeleteOnThread< + content::BrowserThread::UI>; + friend class base::DeleteHelper<SafeBrowsingServiceInterface>; + + // The factory used to instantiate a SafeBrowsingServiceInterface object. + // Useful for tests, so they can provide their own implementation of + // SafeBrowsingServiceInterface. + static SafeBrowsingServiceFactory* factory_; + + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceInterface); +}; + +// Factory for creating SafeBrowsingServiceInterface. Useful for tests. +class SafeBrowsingServiceFactory { + public: + SafeBrowsingServiceFactory() {} + virtual ~SafeBrowsingServiceFactory() {} + + // TODO(crbug/925153): Once callers of this function are no longer downcasting + // it to the SafeBrowsingService, we can make this a scoped_refptr. + virtual SafeBrowsingServiceInterface* CreateSafeBrowsingService() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactory); +}; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_SAFE_BROWSING_SERVICE_INTERFACE_H_
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.cc b/components/send_tab_to_self/send_tab_to_self_bridge.cc index ddd3ce2..1cb0c73 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge.cc +++ b/components/send_tab_to_self/send_tab_to_self_bridge.cc
@@ -581,14 +581,9 @@ target_device_name_to_cache_info_.clear(); for (const auto& device : all_devices) { - // If the current device is considered expired for our purposes, stop here - // since the next devices in the vector are at least as expired than this - // one. - if (clock_->Now() - - change_processor()->GetEntityModificationTime(device->guid()) > - kDeviceExpiration) { - break; - } + // TODO(crbug/959487) If the current device is considered expired for our + // purposes, stop here since the next devices in the vector are at least + // as expired than this one. // TODO(crbug.com/957716): Dedupe older versions of this device as well. // Don't include this device. @@ -604,9 +599,9 @@ // Only keep one device per device name. We only keep the first occurrence // which is the most recent. - TargetDeviceInfo device_info_for_ui(device->guid(), device->device_type()); + TargetDeviceInfo target_device_info(device->guid(), device->device_type()); target_device_name_to_cache_info_.emplace(device->client_name(), - device_info_for_ui); + target_device_info); oldest_device_cache_guid_ = device->guid(); } }
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc index cca6bb7..66ef5214 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc +++ b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
@@ -703,11 +703,11 @@ ON_CALL(*processor(), GetEntityModificationTime(kOlderGuid)) .WillByDefault(Return(clock()->Now() - base::TimeDelta::FromDays(5))); - TargetDeviceInfo device_info_for_ui(kRecentGuid, + TargetDeviceInfo target_device_info(kRecentGuid, sync_pb::SyncEnums_DeviceType_TYPE_LINUX); EXPECT_THAT(bridge()->GetTargetDeviceNameToCacheInfoMap(), - ElementsAre(Pair("device_name", device_info_for_ui))); + ElementsAre(Pair("device_name", target_device_info))); } // Tests that only devices that have the send tab to self receiving feature @@ -734,16 +734,17 @@ ON_CALL(*processor(), GetEntityModificationTime("disabled_guid")) .WillByDefault(Return(clock()->Now() - base::TimeDelta::FromDays(1))); - TargetDeviceInfo device_info_for_ui("enabled_guid", + TargetDeviceInfo target_device_info("enabled_guid", sync_pb::SyncEnums_DeviceType_TYPE_LINUX); EXPECT_THAT(bridge()->GetTargetDeviceNameToCacheInfoMap(), - ElementsAre(Pair("enabled_device_name", device_info_for_ui))); + ElementsAre(Pair("enabled_device_name", target_device_info))); } +// TODO(crbug/959487): // Tests that only devices that are not expired are returned. TEST_F(SendTabToSelfBridgeTest, - GetTargetDeviceNameToCacheInfoMap_NoExpiredDevices) { + DISABLED_GetTargetDeviceNameToCacheInfoMap_NoExpiredDevices) { InitializeBridge(); syncer::DeviceInfo expired_device( @@ -764,11 +765,11 @@ ON_CALL(*processor(), GetEntityModificationTime("valid_guid")) .WillByDefault(Return(clock()->Now() - base::TimeDelta::FromDays(1))); - TargetDeviceInfo device_info_for_ui("valid_guid", + TargetDeviceInfo target_device_info("valid_guid", sync_pb::SyncEnums_DeviceType_TYPE_LINUX); EXPECT_THAT(bridge()->GetTargetDeviceNameToCacheInfoMap(), - ElementsAre(Pair("valid_device_name", device_info_for_ui))); + ElementsAre(Pair("valid_device_name", target_device_info))); } // Tests that the local device is not returned. @@ -794,16 +795,17 @@ ON_CALL(*processor(), GetEntityModificationTime("other_guid")) .WillByDefault(Return(clock()->Now() - base::TimeDelta::FromDays(1))); - TargetDeviceInfo device_info_for_ui("other_guid", + TargetDeviceInfo target_device_info("other_guid", sync_pb::SyncEnums_DeviceType_TYPE_LINUX); EXPECT_THAT(bridge()->GetTargetDeviceNameToCacheInfoMap(), - ElementsAre(Pair("other_device_name", device_info_for_ui))); + ElementsAre(Pair("other_device_name", target_device_info))); } +// TODO(crbug/959487): // Tests that the local device is not returned. TEST_F(SendTabToSelfBridgeTest, - GetTargetDeviceNameToCacheInfoMap_Updated_DeviceExpired) { + DISABLED_GetTargetDeviceNameToCacheInfoMap_Updated_DeviceExpired) { InitializeBridge(); // Set a device that is about to expire and a more recent device.
diff --git a/components/signin/core/browser/account_info.cc b/components/signin/core/browser/account_info.cc index c089abf4..3c164ea3 100644 --- a/components/signin/core/browser/account_info.cc +++ b/components/signin/core/browser/account_info.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "components/signin/core/browser/account_info.h" +#include "google_apis/gaia/gaia_auth_util.h" namespace { @@ -103,6 +104,21 @@ return modified; } +bool operator==(const CoreAccountInfo& l, const CoreAccountInfo& r) { + return l.account_id == r.account_id && l.gaia == r.gaia && + gaia::AreEmailsSame(l.email, r.email) && + l.is_under_advanced_protection == r.is_under_advanced_protection; +} +bool operator!=(const CoreAccountInfo& l, const CoreAccountInfo& r) { + return !(l == r); +} + +std::ostream& operator<<(std::ostream& os, const CoreAccountInfo& account) { + os << "account_id: " << account.account_id << ", gaia: " << account.gaia + << ", email: " << account.email << ", adv_prot: " << std::boolalpha + << account.is_under_advanced_protection; + return os; +} AccountId AccountIdFromAccountInfo(const CoreAccountInfo& account_info) { if (account_info.email.empty() || account_info.gaia.empty())
diff --git a/components/signin/core/browser/account_info.h b/components/signin/core/browser/account_info.h index fa581f0..884d918 100644 --- a/components/signin/core/browser/account_info.h +++ b/components/signin/core/browser/account_info.h
@@ -70,6 +70,10 @@ bool UpdateWith(const AccountInfo& other); }; +bool operator==(const CoreAccountInfo& l, const CoreAccountInfo& r); +bool operator!=(const CoreAccountInfo& l, const CoreAccountInfo& r); +std::ostream& operator<<(std::ostream& os, const CoreAccountInfo& account); + // Returns AccountID populated from |account_info|. AccountId AccountIdFromAccountInfo(const CoreAccountInfo& account_info);
diff --git a/components/signin/core/browser/signin_manager_base.cc b/components/signin/core/browser/signin_manager_base.cc index e4af936..c0c9d276 100644 --- a/components/signin/core/browser/signin_manager_base.cc +++ b/components/signin/core/browser/signin_manager_base.cc
@@ -218,10 +218,17 @@ // Commit authenticated account info immediately so that it does not get lost // if Chrome crashes before the next commit interval. client_->GetPrefs()->CommitPendingWrite(); + + if (observer_) { + observer_->AuthenticatedAccountSet(info); + } } void SigninManagerBase::ClearAuthenticatedAccountId() { authenticated_account_id_.clear(); + if (observer_) { + observer_->AuthenticatedAccountCleared(); + } } bool SigninManagerBase::IsAuthenticated() const {
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h index 6d04878..fd388ec84 100644 --- a/components/signin/core/browser/signin_manager_base.h +++ b/components/signin/core/browser/signin_manager_base.h
@@ -53,6 +53,14 @@ // Called when the currently signed-in user for a user has been signed out. virtual void GoogleSignedOut(const AccountInfo& account_info) {} + // Called during the signin as soon as + // SigninManagerBase::authenticated_account_id_ is set. + virtual void AuthenticatedAccountSet(const AccountInfo& account_info) {} + + // Called during the signout as soon as + // SigninManagerBase::authenticated_account_id_ is cleared. + virtual void AuthenticatedAccountCleared() {} + protected: virtual ~Observer() {}
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc index a5a38f8..53292ae7 100644 --- a/components/viz/service/main/viz_main_impl.cc +++ b/components/viz/service/main/viz_main_impl.cc
@@ -262,7 +262,8 @@ gpu_service_->share_group(), format, gpu_service_->gpu_feature_info(), gpu_service_->gpu_channel_manager()->gpu_preferences(), gpu_service_->shared_image_manager(), - gpu_service_->gpu_channel_manager()->program_cache()); + gpu_service_->gpu_channel_manager()->program_cache(), + gpu_service_->GetContextState()); viz_compositor_thread_runner_->CreateFrameSinkManager( std::move(params), task_executor_.get(), gpu_service_.get());
diff --git a/components/viz/test/test_gpu_service_holder.cc b/components/viz/test/test_gpu_service_holder.cc index 479af56..5dbef35be 100644 --- a/components/viz/test/test_gpu_service_holder.cc +++ b/components/viz/test/test_gpu_service_holder.cc
@@ -103,7 +103,8 @@ gpu_service_->gpu_feature_info(), gpu_service_->gpu_channel_manager()->gpu_preferences(), gpu_service_->shared_image_manager(), - gpu_service_->gpu_channel_manager()->program_cache()); + gpu_service_->gpu_channel_manager()->program_cache(), + gpu_service_->GetContextState()); completion->Signal(); }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index dcb8773..79d85fc 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -229,6 +229,7 @@ public_deps = [ ":accessibility_buildflags", + "//base/util/type-safety", "//ipc", "//media/mojo/interfaces:remoting", "//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings",
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc index 9228b53..3430ab1 100644 --- a/content/browser/background_fetch/background_fetch_data_manager.cc +++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -24,6 +24,7 @@ #include "content/browser/background_fetch/storage/mark_request_complete_task.h" #include "content/browser/background_fetch/storage/match_requests_task.h" #include "content/browser/background_fetch/storage/start_next_pending_request_task.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/cache_storage/cache_storage_manager.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/storage_partition_impl.h"
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 758d955..655bfae7 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -38,7 +38,6 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/content_service_delegate_impl.h" #include "content/browser/download/download_manager_impl.h" -#include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/media/browser_feature_provider.h" #include "content/browser/permissions/permission_controller_impl.h" @@ -50,6 +49,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/indexed_db_context.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/shared_cors_origin_access_list.h" #include "content/public/browser/site_instance.h" @@ -224,7 +224,7 @@ } void SaveSessionStateOnIndexedDBThread( - scoped_refptr<IndexedDBContextImpl> indexed_db_context) { + scoped_refptr<IndexedDBContext> indexed_db_context) { indexed_db_context->SetForceKeepSessionState(); } @@ -614,15 +614,13 @@ storage_partition->GetDOMStorageContext()); dom_storage_context_proxy->SetForceKeepSessionState(); - IndexedDBContextImpl* indexed_db_context_impl = - static_cast<IndexedDBContextImpl*>( - storage_partition->GetIndexedDBContext()); + scoped_refptr<IndexedDBContext> indexed_db_context = + storage_partition->GetIndexedDBContext(); // No task runner in unit tests. - if (indexed_db_context_impl->TaskRunner()) { - indexed_db_context_impl->TaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&SaveSessionStateOnIndexedDBThread, - base::WrapRefCounted(indexed_db_context_impl))); + if (indexed_db_context->TaskRunner()) { + indexed_db_context->TaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&SaveSessionStateOnIndexedDBThread, + std::move(indexed_db_context))); } }
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index 4dd0d73..380ca88f 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -110,8 +110,14 @@ file_path = enumerator.Next()) { if (!GetFileInfo(file_path, &info)) return false; - if (index_last_modified < info.last_modified) + if (index_last_modified < info.last_modified) { +#if defined(OS_FUCHSIA) + // TODO(crbug.com/760687): Extra logging for bot debugging. + LOG(ERROR) << "index_last_modified: " << index_last_modified + << " info.last_modified: " << info.last_modified; +#endif // OS_FUCHSIA return false; + } } return true; @@ -1504,14 +1510,9 @@ } } -// TODO(crbug.com/760687): Flaky on Fuchsia. -#if defined(OS_FUCHSIA) -#define MAYBE_GetAllOriginsUsageWithOldIndex \ - DISABLED_GetAllOriginsUsageWithOldIndex -#else -#define MAYBE_GetAllOriginsUsageWithOldIndex GetAllOriginsUsageWithOldIndex -#endif -TEST_F(CacheStorageManagerTest, MAYBE_GetAllOriginsUsageWithOldIndex) { +// TODO(crbug.com/760687): Flaky on Fuchsia. Temporarily enabled with extra +// logging to help debug. +TEST_F(CacheStorageManagerTest, GetAllOriginsUsageWithOldIndex) { // Write a single value (V1) to the cache. const GURL kFooURL = origin1_.GetURL().Resolve("foo"); const std::string kCacheName = "foo";
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 34e104f..84ff5fc 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/strings/string_split.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "content/browser/cache_storage/cache_storage_context_impl.h" #include "content/browser/indexed_db/indexed_db_context_impl.h"
diff --git a/content/browser/download/save_types.h b/content/browser/download/save_types.h index 20c8089..77fdf8c 100644 --- a/content/browser/download/save_types.h +++ b/content/browser/download/save_types.h
@@ -13,16 +13,16 @@ #include <vector> #include "base/files/file_path.h" -#include "gpu/command_buffer/common/id_type.h" +#include "base/util/type-safety/id_type.h" #include "url/gurl.h" namespace content { class SavePackage; -using SavePackageId = gpu::IdType32<SavePackage>; +using SavePackageId = util::IdType32<SavePackage>; class SaveItem; -using SaveItemId = gpu::IdType32<SaveItem>; +using SaveItemId = util::IdType32<SaveItem>; // Map from save_item_id into final file path. using FinalNamesMap =
diff --git a/content/browser/frame_host/frame_tree_browsertest.cc b/content/browser/frame_host/frame_tree_browsertest.cc index c7fcb2d..0be281e1 100644 --- a/content/browser/frame_host/frame_tree_browsertest.cc +++ b/content/browser/frame_host/frame_tree_browsertest.cc
@@ -1300,9 +1300,7 @@ }; IN_PROC_BROWSER_TEST_F(TransferUserActivationFrameTreeBrowserTest, - PostMessageTransferActivation) { - // TODO(lanwei): Also test transferring user activation in the frame trees - // for the same origin case a(b,b). crbug.com/928838. + PostMessageTransferActivationCrossOrigin) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(b,c)")); EXPECT_TRUE(NavigateToURL(shell(), main_url)); @@ -1378,6 +1376,71 @@ EXPECT_TRUE(child2->HasBeenActivated()); EXPECT_TRUE(child2->HasTransientUserActivation()); } + +IN_PROC_BROWSER_TEST_F(TransferUserActivationFrameTreeBrowserTest, + PostMessageTransferActivationSameOrigin) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(b))")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + WebContentsImpl* contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + FrameTreeNode* root = contents->GetFrameTree()->root(); + FrameTreeNode* child1 = root->child_at(0); + FrameTreeNode* child2 = child1->child_at(0); + EXPECT_FALSE(root->HasBeenActivated()); + EXPECT_FALSE(root->HasTransientUserActivation()); + EXPECT_FALSE(child1->HasBeenActivated()); + EXPECT_FALSE(child1->HasTransientUserActivation()); + EXPECT_FALSE(child2->HasBeenActivated()); + EXPECT_FALSE(child2->HasTransientUserActivation()); + + // Activate the root frame and transfer the user activation state from root + // to child1. + std::string message_event_listener = + "window.addEventListener('message', function(event) {\n" + " domAutomationController.send('done-' + event.data);\n" + "});"; + EXPECT_TRUE(ExecuteScript(shell(), "")); + EXPECT_TRUE(ExecuteScriptWithoutUserGesture(child1->current_frame_host(), + message_event_listener)); + DOMMessageQueue msg_queue; + std::string actual_test_reply; + EXPECT_TRUE(ExecuteScriptWithoutUserGesture( + shell(), + "window.frames[0].postMessage('Hello', " + "{targetOrigin: '*', transferUserActivation: true})")); + while (msg_queue.WaitForMessage(&actual_test_reply)) { + if (actual_test_reply == "\"done-Hello\"") + break; + } + EXPECT_FALSE(root->HasBeenActivated()); + EXPECT_FALSE(root->HasTransientUserActivation()); + EXPECT_TRUE(child1->HasBeenActivated()); + EXPECT_TRUE(child1->HasTransientUserActivation()); + EXPECT_FALSE(child2->HasBeenActivated()); + EXPECT_FALSE(child2->HasTransientUserActivation()); + + // Post a message from child1 to its child child2 in the same origin with + // |transferUserActivation| true to transfer the user activation state from + // one node to its child node in the frame tree. + EXPECT_TRUE(ExecuteScriptWithoutUserGesture(child2->current_frame_host(), + message_event_listener)); + EXPECT_TRUE(ExecuteScriptWithoutUserGesture( + child1->current_frame_host(), + "window.frames[0].postMessage('Hey', " + "{targetOrigin: '*', transferUserActivation: true})")); + while (msg_queue.WaitForMessage(&actual_test_reply)) { + if (actual_test_reply == "\"done-Hey\"") + break; + } + EXPECT_FALSE(root->HasBeenActivated()); + EXPECT_FALSE(root->HasTransientUserActivation()); + EXPECT_FALSE(child1->HasBeenActivated()); + EXPECT_FALSE(child1->HasTransientUserActivation()); + EXPECT_TRUE(child2->HasBeenActivated()); + EXPECT_TRUE(child2->HasTransientUserActivation()); +} #endif } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 605e95d..99da116d 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1462,6 +1462,8 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_RequestOverlayRoutingToken, OnRequestOverlayRoutingToken) IPC_MESSAGE_HANDLER(FrameHostMsg_ShowCreatedWindow, OnShowCreatedWindow) + IPC_MESSAGE_HANDLER(FrameHostMsg_TransferUserActivationFrom, + OnTransferUserActivationFrom) IPC_END_MESSAGE_MAP() // No further actions here, since we may have been deleted. @@ -3659,6 +3661,16 @@ disposition, initial_rect, user_gesture); } +void RenderFrameHostImpl::OnTransferUserActivationFrom( + int32_t source_routing_id) { + RenderFrameHostImpl* source_rfh = + RenderFrameHostImpl::FromID(GetProcess()->GetID(), source_routing_id); + if (source_rfh && + source_rfh->frame_tree_node()->HasTransientUserActivation()) { + frame_tree_node()->TransferUserActivationFrom(source_rfh); + } +} + void RenderFrameHostImpl::CreateNewWindow( mojom::CreateNewWindowParamsPtr params, CreateNewWindowCallback callback) {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 792fb596..ed3656c2 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1142,6 +1142,7 @@ blink::WebScrollGranularity granularity); void OnFrameDidCallFocus(); void OnRenderFallbackContentInParentProcess(); + void OnTransferUserActivationFrom(int32_t source_routing_id); #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) void OnShowPopup(const FrameHostMsg_ShowPopup_Params& params);
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc index a0b478f..d65b970 100644 --- a/content/browser/indexed_db/database_impl.cc +++ b/content/browser/indexed_db/database_impl.cc
@@ -176,30 +176,38 @@ key_only, callbacks); } -void DatabaseImpl::GetAll( - int64_t transaction_id, - int64_t object_store_id, - int64_t index_id, - const IndexedDBKeyRange& key_range, - bool key_only, - int64_t max_count, - blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info) { +void DatabaseImpl::GetAll(int64_t transaction_id, + int64_t object_store_id, + int64_t index_id, + const IndexedDBKeyRange& key_range, + bool key_only, + int64_t max_count, + blink::mojom::IDBDatabase::GetAllCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - scoped_refptr<IndexedDBCallbacks> callbacks( - new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_, - std::move(callbacks_info), idb_runner_)); - if (!connection_->IsConnected()) + if (!connection_->IsConnected()) { + IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + "Unknown error"); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); return; + } IndexedDBTransaction* transaction = connection_->GetTransaction(transaction_id); - if (!transaction) + if (!transaction) { + IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + "Unknown error"); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); return; + } connection_->database()->GetAll( - transaction, object_store_id, index_id, + dispatcher_host_->AsWeakPtr(), transaction, object_store_id, index_id, std::make_unique<IndexedDBKeyRange>(key_range), key_only, max_count, - std::move(callbacks)); + std::move(callback)); } void DatabaseImpl::SetIndexKeys(
diff --git a/content/browser/indexed_db/database_impl.h b/content/browser/indexed_db/database_impl.h index 8a3e3a1..e1bb417 100644 --- a/content/browser/indexed_db/database_impl.h +++ b/content/browser/indexed_db/database_impl.h
@@ -66,7 +66,7 @@ const blink::IndexedDBKeyRange& key_range, bool key_only, int64_t max_count, - blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks) override; + blink::mojom::IDBDatabase::GetAllCallback callback) override; void SetIndexKeys( int64_t transaction_id, int64_t object_store_id,
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index 7fd762f..db2ffe0 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -30,6 +30,7 @@ #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_data_format_version.h" #include "content/browser/indexed_db/indexed_db_database_error.h" +#include "content/browser/indexed_db/indexed_db_factory.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" #include "content/browser/indexed_db/indexed_db_leveldb_operations.h" #include "content/browser/indexed_db/indexed_db_metadata_coding.h" @@ -2051,11 +2052,11 @@ } IndexedDBBackingStore::Cursor::Cursor( - scoped_refptr<IndexedDBBackingStore> backing_store, + IndexedDBBackingStore* backing_store, IndexedDBBackingStore::Transaction* transaction, int64_t database_id, const CursorOptions& cursor_options) - : backing_store_(backing_store.get()), + : backing_store_(backing_store), transaction_(transaction), database_id_(database_id), cursor_options_(cursor_options) {} @@ -2312,7 +2313,7 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { public: ObjectStoreKeyCursorImpl( - scoped_refptr<IndexedDBBackingStore> backing_store, + IndexedDBBackingStore* backing_store, IndexedDBBackingStore::Transaction* transaction, int64_t database_id, const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) @@ -2389,7 +2390,7 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { public: ObjectStoreCursorImpl( - scoped_refptr<IndexedDBBackingStore> backing_store, + IndexedDBBackingStore* backing_store, IndexedDBBackingStore::Transaction* transaction, int64_t database_id, const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) @@ -2463,7 +2464,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { public: IndexKeyCursorImpl( - scoped_refptr<IndexedDBBackingStore> backing_store, + IndexedDBBackingStore* backing_store, IndexedDBBackingStore::Transaction* transaction, int64_t database_id, const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) @@ -2580,7 +2581,7 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor { public: IndexCursorImpl( - scoped_refptr<IndexedDBBackingStore> backing_store, + IndexedDBBackingStore* backing_store, IndexedDBBackingStore::Transaction* transaction, int64_t database_id, const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h index a7e9864..d6926df6 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.h +++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -342,7 +342,7 @@ virtual bool LoadCurrentRow(leveldb::Status* s) = 0; protected: - Cursor(scoped_refptr<IndexedDBBackingStore> backing_store, + Cursor(IndexedDBBackingStore* backing_store, Transaction* transaction, int64_t database_id, const CursorOptions& cursor_options);
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index 60b09d2..324f1da5 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -206,7 +206,8 @@ idb_context_ = base::MakeRefCounted<IndexedDBContextImpl>( temp_dir_.GetPath(), special_storage_policy_, quota_manager_proxy_, - indexed_db::GetDefaultLevelDBFactory()); + indexed_db::GetDefaultLevelDBFactory(), + base::DefaultClock::GetInstance()); CreateFactoryAndBackingStore();
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index f72738f..302521c 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -29,6 +29,7 @@ #include "content/browser/browser_main_loop.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" +#include "content/browser/indexed_db/indexed_db_factory.h" #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index d70d360..73f8a6d 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -68,7 +68,6 @@ if (file_path.Extension() == indexed_db::kLevelDBExtension && file_path.RemoveExtension().Extension() == indexed_db::kIndexedDBExtension) { - // TODO(dmurph): Unittest this. std::string origin_id = file_path.BaseName() .RemoveExtension() .RemoveExtension() @@ -86,7 +85,8 @@ const base::FilePath& data_path, scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy, scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, - indexed_db::LevelDBFactory* leveldb_factory) + indexed_db::LevelDBFactory* leveldb_factory, + base::Clock* clock) : force_keep_session_state_(false), special_storage_policy_(special_storage_policy), quota_manager_proxy_(quota_manager_proxy), @@ -95,7 +95,8 @@ base::TaskPriority::USER_VISIBLE, // BLOCK_SHUTDOWN to support clearing session-only storage. base::TaskShutdownBehavior::BLOCK_SHUTDOWN})), - leveldb_factory_(leveldb_factory) { + leveldb_factory_(leveldb_factory), + clock_(clock) { IDB_TRACE("init"); if (!data_path.empty()) data_path_ = data_path.Append(kIndexedDBDirectory); @@ -446,6 +447,10 @@ origin_size_map_.clear(); } +void IndexedDBContextImpl::SetForceKeepSessionState() { + force_keep_session_state_ = true; +} + void IndexedDBContextImpl::ConnectionOpened(const Origin& origin, IndexedDBConnection* connection) { DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index 8d371c90..e7ba177 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -18,7 +18,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "content/browser/browser_main_loop.h" -#include "content/browser/indexed_db/indexed_db_factory.h" +#include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/public/browser/indexed_db_context.h" #include "storage/browser/quota/quota_manager_proxy.h" @@ -26,6 +26,7 @@ #include "url/origin.h" namespace base { +class Clock; class ListValue; class FilePath; class SequencedTaskRunner; @@ -36,8 +37,8 @@ } namespace content { - class IndexedDBConnection; +class IndexedDBFactory; class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext { public: @@ -73,15 +74,14 @@ const base::FilePath& data_path, scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy, scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, - indexed_db::LevelDBFactory* leveldb_factory); + indexed_db::LevelDBFactory* leveldb_factory, + base::Clock* clock); IndexedDBFactory* GetIDBFactory(); // Called by StoragePartitionImpl to clear session-only data. void Shutdown(); - // Disables the exit-time deletion of session-only data. - void SetForceKeepSessionState() { force_keep_session_state_ = true; } int64_t GetOriginDiskUsage(const url::Origin& origin); @@ -94,6 +94,7 @@ base::FilePath GetFilePathForTesting( const url::Origin& origin) const override; void ResetCachesForTesting() override; + void SetForceKeepSessionState() override; // Methods called by IndexedDBDispatcherHost for quota support. void ConnectionOpened(const url::Origin& origin, IndexedDBConnection* db); @@ -126,6 +127,7 @@ std::vector<base::FilePath> GetStoragePaths(const url::Origin& origin) const; base::FilePath data_path() const { return data_path_; } + bool IsInMemoryContext() const { return data_path_.empty(); } size_t GetConnectionCount(const url::Origin& origin); int GetOriginBlobFileCount(const url::Origin& origin); @@ -192,6 +194,7 @@ std::map<url::Origin, int64_t> origin_size_map_; base::ObserverList<Observer>::Unchecked observers_; indexed_db::LevelDBFactory* leveldb_factory_; + base::Clock* clock_; DISALLOW_COPY_AND_ASSIGN(IndexedDBContextImpl); };
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 0023c4e..b8efc69 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -922,24 +922,33 @@ } } -void IndexedDBDatabase::GetAll(IndexedDBTransaction* transaction, - int64_t object_store_id, - int64_t index_id, - std::unique_ptr<IndexedDBKeyRange> key_range, - bool key_only, - int64_t max_count, - scoped_refptr<IndexedDBCallbacks> callbacks) { +void IndexedDBDatabase::GetAll( + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, + IndexedDBTransaction* transaction, + int64_t object_store_id, + int64_t index_id, + std::unique_ptr<IndexedDBKeyRange> key_range, + bool key_only, + int64_t max_count, + blink::mojom::IDBDatabase::GetAllCallback callback) { DCHECK(transaction); IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction->id()); - if (!ValidateObjectStoreId(object_store_id)) + if (!ValidateObjectStoreId(object_store_id)) { + IndexedDBDatabaseError error = + CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + "Unknown error", transaction); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); return; + } transaction->ScheduleTask(base::BindOnce( - &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id, - std::move(key_range), + &IndexedDBDatabase::GetAllOperation, this, std::move(dispatcher_host), + object_store_id, index_id, std::move(key_range), key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, - max_count, callbacks)); + max_count, std::move(callback))); } void IndexedDBDatabase::Get(IndexedDBTransaction* transaction, @@ -1089,12 +1098,13 @@ "kIDBMaxMessageOverhead is more than INT32_MAX"); Status IndexedDBDatabase::GetAllOperation( + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, int64_t object_store_id, int64_t index_id, std::unique_ptr<IndexedDBKeyRange> key_range, indexed_db::CursorType cursor_type, int64_t max_count, - scoped_refptr<IndexedDBCallbacks> callbacks, + blink::mojom::IDBDatabase::GetAllCallback callback, IndexedDBTransaction* transaction) { IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id()); @@ -1106,6 +1116,15 @@ metadata_.object_stores[object_store_id]; Status s = Status::OK(); + if (!dispatcher_host) { + IndexedDBDatabaseError error = + CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + "Unknown error", transaction); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); + return s; + } std::unique_ptr<IndexedDBBackingStore::Cursor> cursor; @@ -1139,6 +1158,12 @@ if (!s.ok()) { DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); + IndexedDBDatabaseError error = + CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + "Corruption detected, unable to continue", transaction); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); return s; } @@ -1147,7 +1172,9 @@ if (!cursor) { // Doesn't matter if key or value array here - will be empty array when it // hits JavaScript. - callbacks->OnSuccessArray(&found_values); + std::vector<blink::mojom::IDBReturnValuePtr> mojo_found_values; + std::move(callback).Run(blink::mojom::IDBDatabaseGetAllResult::NewValues( + std::move(mojo_found_values))); return s; } @@ -1165,8 +1192,15 @@ cursor_valid = cursor->FirstSeek(&s); did_first_seek = true; } - if (!s.ok()) + if (!s.ok()) { + IndexedDBDatabaseError error = + CreateError(blink::kWebIDBDatabaseExceptionUnknownError, + "Seek failure, unable to continue", transaction); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); return s; + } if (!cursor_valid) break; @@ -1190,9 +1224,12 @@ else response_size += return_value.SizeEstimate(); if (response_size > GetUsableMessageSizeInBytes()) { - callbacks->OnError( + IndexedDBDatabaseError error = CreateError(blink::kWebIDBDatabaseExceptionUnknownError, - "Maximum IPC message size exceeded.", transaction)); + "Maximum IPC message size exceeded.", transaction); + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewErrorResult( + blink::mojom::IDBError::New(error.code(), error.message()))); return s; } @@ -1205,10 +1242,33 @@ if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { // IndexedDBKey already supports an array of values so we can leverage this // to return an array of keys - no need to create our own array of keys. - callbacks->OnSuccess(IndexedDBKey(std::move(found_keys))); - } else { - callbacks->OnSuccessArray(&found_values); + std::move(callback).Run(blink::mojom::IDBDatabaseGetAllResult::NewKey( + IndexedDBKey(std::move(found_keys)))); + return s; } + + std::vector<blink::mojom::IDBReturnValuePtr> mojo_values; + mojo_values.reserve(found_values.size()); + for (size_t i = 0; i < found_values.size(); ++i) { + mojo_values.push_back( + IndexedDBReturnValue::ConvertReturnValue(&found_values[i])); + } + + std::vector<IndexedDBCallbacks::IndexedDBValueBlob> value_blobs; + for (size_t i = 0; i < mojo_values.size(); ++i) { + IndexedDBCallbacks::IndexedDBValueBlob::GetIndexedDBValueBlobs( + &value_blobs, found_values[i].blob_info, + &mojo_values[i]->value->blob_or_file_info); + } + + if (!IndexedDBCallbacks::CreateAllBlobs( + dispatcher_host->blob_storage_context(), + dispatcher_host->context()->TaskRunner(), std::move(value_blobs))) { + return s; + } + + std::move(callback).Run( + blink::mojom::IDBDatabaseGetAllResult::NewValues(std::move(mojo_values))); return s; }
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index 5622190..01423ec 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -161,13 +161,14 @@ std::unique_ptr<blink::IndexedDBKeyRange> key_range, bool key_only, scoped_refptr<IndexedDBCallbacks> callbacks); - void GetAll(IndexedDBTransaction* transaction, + void GetAll(base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, + IndexedDBTransaction* transaction, int64_t object_store_id, int64_t index_id, std::unique_ptr<blink::IndexedDBKeyRange> key_range, bool key_only, int64_t max_count, - scoped_refptr<IndexedDBCallbacks> callbacks); + blink::mojom::IDBDatabase::GetAllCallback callback); void Put(IndexedDBTransaction* transaction, int64_t object_store_id, IndexedDBValue* value, @@ -248,12 +249,13 @@ scoped_refptr<IndexedDBCallbacks> callbacks, IndexedDBTransaction* transaction); leveldb::Status GetAllOperation( + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, int64_t object_store_id, int64_t index_id, std::unique_ptr<blink::IndexedDBKeyRange> key_range, indexed_db::CursorType cursor_type, int64_t max_count, - scoped_refptr<IndexedDBCallbacks> callbacks, + blink::mojom::IDBDatabase::GetAllCallback callback, IndexedDBTransaction* transaction); struct PutOperationParams; leveldb::Status PutOperation(std::unique_ptr<PutOperationParams> params,
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc index ec7304f..52257a1 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -18,6 +18,7 @@ #include "content/browser/indexed_db/indexed_db_connection.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_database_callbacks.h" +#include "content/browser/indexed_db/indexed_db_factory_impl.h" #include "content/browser/indexed_db/indexed_db_pending_connection.h" #include "content/browser/indexed_db/transaction_impl.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc index 684cae99..545b31e 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
@@ -16,6 +16,7 @@ #include "base/test/bind_test_util.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread.h" +#include "base/time/default_clock.h" #include "content/browser/indexed_db/indexed_db_callbacks.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_database_callbacks.h" @@ -183,7 +184,8 @@ CreateAndReturnTempDir(&temp_dir_), special_storage_policy_, quota_manager_->proxy(), - indexed_db::GetDefaultLevelDBFactory())), + indexed_db::GetDefaultLevelDBFactory(), + base::DefaultClock::GetInstance())), host_(new IndexedDBDispatcherHost( kFakeProcessId, context_impl_,
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc index c31a0dd..965068f8 100644 --- a/content/browser/indexed_db/indexed_db_factory_unittest.cc +++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -97,7 +97,8 @@ CreateAndReturnTempDir(&temp_dir_), /*special_storage_policy=*/nullptr, quota_manager_proxy_.get(), - indexed_db::GetDefaultLevelDBFactory())) {} + indexed_db::GetDefaultLevelDBFactory(), + base::DefaultClock::GetInstance())) {} void TearDown() override { quota_manager_proxy_->SimulateQuotaManagerDestroyed();
diff --git a/content/browser/indexed_db/indexed_db_pre_close_task_queue.h b/content/browser/indexed_db/indexed_db_pre_close_task_queue.h index 988a941..59ec133 100644 --- a/content/browser/indexed_db/indexed_db_pre_close_task_queue.h +++ b/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
@@ -26,7 +26,7 @@ // Holds a queue of PreCloseTask's to be run after an IndexedDBBackingStore no // longer has any connections. // -// There is a special IndexedDBMetadata fetcher task that runs beofre all the +// There is a special IndexedDBMetadata fetcher task that runs before all the // other tasks, and whose output is passed to each task before they start. // // Owned by IndexedDBBackingStore.
diff --git a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc index be0d471c..0b44567 100644 --- a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc +++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -16,6 +16,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/default_clock.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_quota_client.h" #include "content/browser/indexed_db/leveldb/leveldb_env.h" @@ -58,7 +59,8 @@ idb_context_ = new IndexedDBContextImpl( browser_context_->GetPath(), browser_context_->GetSpecialStoragePolicy(), quota_manager->proxy(), - indexed_db::GetDefaultLevelDBFactory()); + indexed_db::GetDefaultLevelDBFactory(), + base::DefaultClock::GetInstance()); base::RunLoop().RunUntilIdle(); setup_temp_dir(); }
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index 77b9706..53f0fe8d 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/test/bind_test_util.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "base/time/default_clock.h" #include "content/browser/indexed_db/indexed_db_connection.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_factory_impl.h" @@ -89,7 +90,8 @@ CreateAndReturnTempDir(&temp_dir_), /*special_storage_policy=*/special_storage_policy_.get(), quota_manager_proxy_.get(), - indexed_db::GetDefaultLevelDBFactory())) { + indexed_db::GetDefaultLevelDBFactory(), + base::DefaultClock::GetInstance())) { special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL()); } ~IndexedDBTest() override {
diff --git a/content/browser/isolation_context.h b/content/browser/isolation_context.h index e91a20b..82f69d0 100644 --- a/content/browser/isolation_context.h +++ b/content/browser/isolation_context.h
@@ -6,14 +6,14 @@ #define CONTENT_BROWSER_ISOLATION_CONTEXT_H_ #include "base/optional.h" +#include "base/util/type-safety/id_type.h" #include "content/common/content_export.h" #include "content/public/browser/browser_or_resource_context.h" -#include "gpu/command_buffer/common/id_type.h" namespace content { class BrowsingInstance; -using BrowsingInstanceId = gpu::IdType32<BrowsingInstance>; +using BrowsingInstanceId = util::IdType32<BrowsingInstance>; // This class is used to specify the context in which process model decisions // need to be made. For example, dynamically added isolated origins only take
diff --git a/content/browser/loader/prefetch_browsertest_base.cc b/content/browser/loader/prefetch_browsertest_base.cc index 5ccd9aa..e39eafd 100644 --- a/content/browser/loader/prefetch_browsertest_base.cc +++ b/content/browser/loader/prefetch_browsertest_base.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "content/browser/loader/prefetch_url_loader_service.h" #include "content/browser/storage_partition_impl.h"
diff --git a/content/browser/service_worker/fake_service_worker.cc b/content/browser/service_worker/fake_service_worker.cc index a0ccd64..199ab56 100644 --- a/content/browser/service_worker/fake_service_worker.cc +++ b/content/browser/service_worker/fake_service_worker.cc
@@ -36,7 +36,8 @@ void FakeServiceWorker::InitializeGlobalScope( blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host, - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) { + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info, + blink::mojom::FetchHandlerExistence fetch_handler_existence) { host_.Bind(std::move(service_worker_host)); // Enable callers to use these endpoints without us actually binding them @@ -58,6 +59,8 @@ registration_info_ = std::move(registration_info); if (quit_closure_for_initialize_global_scope_) std::move(quit_closure_for_initialize_global_scope_).Run(); + + fetch_handler_existence_ = fetch_handler_existence; } void FakeServiceWorker::DispatchInstallEvent(
diff --git a/content/browser/service_worker/fake_service_worker.h b/content/browser/service_worker/fake_service_worker.h index 16f80f48..ddf80fd 100644 --- a/content/browser/service_worker/fake_service_worker.h +++ b/content/browser/service_worker/fake_service_worker.h
@@ -20,6 +20,8 @@ // by default the lifetime is tied to the Mojo connection. class FakeServiceWorker : public blink::mojom::ServiceWorker { public: + using FetchHandlerExistence = blink::mojom::FetchHandlerExistence; + // |helper| must outlive this instance. explicit FakeServiceWorker(EmbeddedWorkerTestHelper* helper); @@ -36,12 +38,16 @@ bool is_zero_idle_timer_delay() const { return is_zero_idle_timer_delay_; } + FetchHandlerExistence fetch_handler_existence() const { + return fetch_handler_existence_; + } + protected: // blink::mojom::ServiceWorker overrides: void InitializeGlobalScope( blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host, - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) - override; + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info, + FetchHandlerExistence fetch_handler_existence) override; void DispatchInstallEvent(DispatchInstallEventCallback callback) override; void DispatchActivateEvent(DispatchActivateEventCallback callback) override; void DispatchBackgroundFetchAbortEvent( @@ -112,6 +118,8 @@ blink::mojom::ServiceWorkerHostAssociatedPtr host_; blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info_; + FetchHandlerExistence fetch_handler_existence_ = + FetchHandlerExistence::UNKNOWN; base::OnceClosure quit_closure_for_initialize_global_scope_; mojo::Binding<blink::mojom::ServiceWorker> binding_;
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 6be30b2..dd17346 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -22,6 +22,7 @@ #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_process_manager.h" #include "content/browser/service_worker/service_worker_quota_client.h"
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index ba36f0a..18155b1c 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -2150,7 +2150,8 @@ service_worker_ptr_->InitializeGlobalScope( std::move(service_worker_host_), provider_host_->CreateServiceWorkerRegistrationObjectInfo( - std::move(registration))); + std::move(registration)), + fetch_handler_existence_); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 7e346b38..eb0c076 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -121,6 +121,7 @@ base::OnceCallback<void(blink::ServiceWorkerStatusCode)>; using SimpleEventCallback = base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus)>; + using FetchHandlerExistence = blink::mojom::FetchHandlerExistence; // Current version status; some of the status (e.g. INSTALLED and ACTIVATED) // should be persisted unlike running status. @@ -141,13 +142,6 @@ // timed out. }; - // Whether the version has fetch handlers or not. - enum class FetchHandlerExistence { - UNKNOWN, // This version is a new version and not installed yet. - EXISTS, - DOES_NOT_EXIST, - }; - class Observer { public: virtual void OnRunningStateChanged(ServiceWorkerVersion* version) {}
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc index 0c49e59..cc10f39 100644 --- a/content/browser/service_worker/service_worker_version_unittest.cc +++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -114,6 +114,8 @@ class ServiceWorkerVersionTest : public testing::Test { protected: + using FetchHandlerExistence = blink::mojom::FetchHandlerExistence; + struct RunningStateListener : public ServiceWorkerVersion::Observer { RunningStateListener() : last_status(EmbeddedWorkerStatus::STOPPED) {} ~RunningStateListener() override {} @@ -161,7 +163,10 @@ version_->script_cache_map()->SetResources(records); version_->SetMainScriptHttpResponseInfo( EmbeddedWorkerTestHelper::CreateHttpResponseInfo()); - version_->set_fetch_handler_existence(GetFetchHandlerExistence()); + if (GetFetchHandlerExistence() != + ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN) { + version_->set_fetch_handler_existence(GetFetchHandlerExistence()); + } // Make the registration findable via storage functions. base::Optional<blink::ServiceWorkerStatusCode> status; @@ -1598,5 +1603,24 @@ histogram_tester_.ExpectTotalCount(kStartHintPrecision, 2); } +TEST_F(ServiceWorkerVersionTest, InstalledFetchEventHandlerExists) { + auto* service_worker = + helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get()); + StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN); + service_worker->RunUntilInitializeGlobalScope(); + EXPECT_EQ(FetchHandlerExistence::EXISTS, + service_worker->fetch_handler_existence()); +} + +TEST_F(ServiceWorkerVersionNoFetchHandlerTest, + InstalledFetchEventHandlerDoesNotExist) { + auto* service_worker = + helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get()); + StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN); + service_worker->RunUntilInitializeGlobalScope(); + EXPECT_EQ(FetchHandlerExistence::DOES_NOT_EXIST, + service_worker->fetch_handler_existence()); +} + } // namespace service_worker_version_unittest } // namespace content
diff --git a/content/browser/speech/audio_encoder_fuzzer.cc b/content/browser/speech/audio_encoder_fuzzer.cc new file mode 100644 index 0000000..bd05b40 --- /dev/null +++ b/content/browser/speech/audio_encoder_fuzzer.cc
@@ -0,0 +1,43 @@ +// 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 <stddef.h> +#include <stdint.h> + +#include "base/test/fuzzed_data_provider.h" +#include "content/browser/speech/audio_encoder.h" + +using content::AudioChunk; + +// Copied from speech_recognition_engine.cc. +const int kDefaultConfigSampleRate = 8000; +const int kDefaultConfigBitsPerSample = 16; +const int kAudioSampleRate = 16000; +const int kAudioPacketIntervalMs = 100; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + base::FuzzedDataProvider provider(data, size); + content::AudioEncoder encoder(kDefaultConfigSampleRate, + kDefaultConfigBitsPerSample); + + while (provider.remaining_bytes()) { + std::string chunk_str = + provider.ConsumeRandomLengthString(provider.remaining_bytes()); + scoped_refptr<AudioChunk> chunk = + new AudioChunk(reinterpret_cast<const uint8_t*>(chunk_str.data()), + chunk_str.size(), kDefaultConfigBitsPerSample / 8); + encoder.Encode(*chunk); + } + + size_t sample_count = kAudioSampleRate * kAudioPacketIntervalMs / 1000; + scoped_refptr<AudioChunk> dummy_chunk = new AudioChunk( + sample_count * sizeof(int16_t), kDefaultConfigBitsPerSample / 8); + encoder.Encode(*dummy_chunk.get()); + encoder.Flush(); + scoped_refptr<AudioChunk> encoded_data(encoder.GetEncodedDataAndClear()); + encoded_data->AsString(); + encoder.GetMimeType(); + encoder.GetBitsPerSample(); + return 0; +}
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 3e112d9..51dcd0b 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -23,6 +23,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/syslog_logging.h" #include "base/task/post_task.h" +#include "base/time/default_clock.h" #include "build/build_config.h" #include "components/variations/net/variations_http_headers.h" #include "content/browser/background_fetch/background_fetch_context.h" @@ -672,7 +673,8 @@ base::FilePath path = in_memory ? base::FilePath() : partition_path; partition->indexed_db_context_ = new IndexedDBContextImpl( path, context->GetSpecialStoragePolicy(), quota_manager_proxy, - indexed_db::GetDefaultLevelDBFactory()); + indexed_db::GetDefaultLevelDBFactory(), + base::DefaultClock::GetInstance()); partition->cache_storage_context_ = new CacheStorageContextImpl(context); partition->cache_storage_context_->Init(
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc index db629ba..dfe2495 100644 --- a/content/browser/worker_host/dedicated_worker_host.cc +++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "content/browser/appcache/appcache_navigation_handle.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/interface_provider_filtering.h" #include "content/browser/renderer_interface_binders.h"
diff --git a/content/browser/worker_host/shared_worker_connector_impl.cc b/content/browser/worker_host/shared_worker_connector_impl.cc index 4b410f13..fb9aa3bb 100644 --- a/content/browser/worker_host/shared_worker_connector_impl.cc +++ b/content/browser/worker_host/shared_worker_connector_impl.cc
@@ -5,6 +5,7 @@ #include "content/browser/worker_host/shared_worker_connector_impl.h" #include "base/memory/ptr_util.h" +#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/worker_host/shared_worker_service_impl.h" #include "content/public/browser/browser_context.h" @@ -12,6 +13,7 @@ #include "content/public/browser/render_process_host.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "third_party/blink/public/common/messaging/message_port_channel.h" +#include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h" #include "third_party/blink/public/mojom/worker/shared_worker_info.mojom.h" namespace content {
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 189fe02..ff1c458 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -493,6 +493,9 @@ if (!base::FeatureList::IsEnabled(features::kSmsReceiver)) WebRuntimeFeatures::EnableSmsReceiver(false); + + WebRuntimeFeatures::EnableDisplayLocking( + base::FeatureList::IsEnabled(blink::features::kDisplayLocking)); } } // namespace
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index aa3530d..99460d5a 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -1648,6 +1648,13 @@ int /* offset (from current) of history item to get */, bool /* has_user_gesture */) +// Sent to the browser process to transfer the user activation state from the +// source frame to the frame sending this IPC. The browser will update the user +// activation state of the frames in the frame tree in the non-source and +// non-target renderer processes. +IPC_MESSAGE_ROUTED1(FrameHostMsg_TransferUserActivationFrom, + int /* source_routing_id */) + #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) // Message to show/hide a popup menu using native controls.
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc index bc99b8d8..de3cff5 100644 --- a/content/common/throttling_url_loader.cc +++ b/content/common/throttling_url_loader.cc
@@ -327,7 +327,8 @@ << "ThrottlingURLLoader doesn't support multiple throttles " "changing the URL."; if (original_url.SchemeIsHTTPOrHTTPS() && - !url_request->url.SchemeIsHTTPOrHTTPS()) { + !url_request->url.SchemeIsHTTPOrHTTPS() && + !throttle->makes_unsafe_redirect()) { NOTREACHED() << "A URLLoaderThrottle can't redirect from http(s) to " << "a non http(s) scheme."; } else {
diff --git a/content/public/browser/indexed_db_context.h b/content/public/browser/indexed_db_context.h index 6e42ec2f..36bc0d3 100644 --- a/content/public/browser/indexed_db_context.h +++ b/content/public/browser/indexed_db_context.h
@@ -28,6 +28,8 @@ // Represents the per-BrowserContext IndexedDB data. // Call these methods only via the exposed TaskRunner. +// Refcounted because this class is used throughout the codebase on different +// threads. class IndexedDBContext : public base::RefCountedThreadSafe<IndexedDBContext> { public: // Only call the below methods by posting to this TaskRunner. @@ -51,6 +53,9 @@ // Forget the origins/sizes read from disk. virtual void ResetCachesForTesting() = 0; + // Disables the exit-time deletion of session-only data. + virtual void SetForceKeepSessionState() = 0; + protected: friend class base::RefCountedThreadSafe<IndexedDBContext>; virtual ~IndexedDBContext() {}
diff --git a/content/public/common/url_loader_throttle.cc b/content/public/common/url_loader_throttle.cc index 22af426..6c8489a 100644 --- a/content/public/common/url_loader_throttle.cc +++ b/content/public/common/url_loader_throttle.cc
@@ -60,6 +60,10 @@ const network::URLLoaderCompletionStatus& status, bool* defer) {} +bool URLLoaderThrottle::makes_unsafe_redirect() const { + return false; +} + URLLoaderThrottle::URLLoaderThrottle() {} } // namespace content
diff --git a/content/public/common/url_loader_throttle.h b/content/public/common/url_loader_throttle.h index 6ca56381..35fc259 100644 --- a/content/public/common/url_loader_throttle.h +++ b/content/public/common/url_loader_throttle.h
@@ -167,6 +167,11 @@ const network::URLLoaderCompletionStatus& status, bool* defer); + // Must return true if the throttle may make cross-scheme redirects + // (which is usually considered unsafe, so allowed only if the setting + // is made very explicitly). + virtual bool makes_unsafe_redirect() const; + void set_delegate(Delegate* delegate) { delegate_ = delegate; } protected:
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 02b00c6..439c15c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -7545,4 +7545,16 @@ } } +void RenderFrameImpl::TransferUserActivationFrom( + blink::WebLocalFrame* source_frame) { + int32_t source_routing_id = MSG_ROUTING_NONE; + if (source_frame) { + RenderFrameImpl* source_render_frame = + RenderFrameImpl::FromWebFrame(source_frame); + source_routing_id = source_render_frame->GetRoutingID(); + Send(new FrameHostMsg_TransferUserActivationFrom(routing_id_, + source_routing_id)); + } +} + } // namespace content
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 68a33ffe..e63b99d1 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -984,6 +984,8 @@ void DidCancelResponse(int request_id); void DidReceiveTransferSizeUpdate(int request_id, int received_data_length); + void TransferUserActivationFrom(blink::WebLocalFrame* source_frame) override; + // Used in tests to override DocumentInterfaceBroker's methods void SetDocumentInterfaceBrokerForTesting( blink::mojom::DocumentInterfaceBrokerPtr test_broker);
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index b9bbb49e..fe68bc85 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -697,6 +697,9 @@ int event_id, blink::mojom::ServiceWorkerEventStatus status) { DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); + proxy_->SetFetchHandlerExistence(proxy_->HasFetchEventHandler() + ? FetchHandlerExistence::EXISTS + : FetchHandlerExistence::DOES_NOT_EXIST); if (!context_) return; TRACE_EVENT_WITH_FLOW1("ServiceWorker", @@ -1442,7 +1445,8 @@ void ServiceWorkerContextClient::InitializeGlobalScope( blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host, - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) { + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info, + FetchHandlerExistence fetch_handler_existence) { DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); // Connect to the blink::mojom::ServiceWorkerHost. proxy_->BindServiceWorkerHost(service_worker_host.PassHandle()); @@ -1453,6 +1457,7 @@ DCHECK(registration_info->request.is_pending()); proxy_->SetRegistration( registration_info.To<blink::WebServiceWorkerRegistrationObjectInfo>()); + proxy_->SetFetchHandlerExistence(fetch_handler_existence); proxy_->ReadyToEvaluateScript(); }
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 440ebcfb..ddf79ccb 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -258,6 +258,8 @@ DispatchOrQueueFetchEvent_NotRequestedTermination); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextClientTest, TaskInServiceWorker); + using FetchHandlerExistence = blink::mojom::FetchHandlerExistence; + static void ToWebServiceWorkerRequestForFetchEvent( blink::mojom::FetchAPIRequestPtr request, const std::string& client_id, @@ -268,8 +270,8 @@ // Implements blink::mojom::ServiceWorker. void InitializeGlobalScope( blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host, - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) - override; + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info, + FetchHandlerExistence fetch_hander_existence) override; void DispatchInstallEvent( DispatchInstallEventCallback callback) override; void DispatchActivateEvent(DispatchActivateEventCallback callback) override;
diff --git a/content/renderer/service_worker/service_worker_context_client_unittest.cc b/content/renderer/service_worker/service_worker_context_client_unittest.cc index e3b62ea..fde53aa 100644 --- a/content/renderer/service_worker/service_worker_context_client_unittest.cc +++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -103,6 +103,10 @@ std::make_unique<blink::WebServiceWorkerRegistrationObjectInfo>( std::move(info)); } + void SetFetchHandlerExistence( + FetchHandlerExistence fetch_handler_existence) override { + fetch_handler_existence_ = fetch_handler_existence; + } void ReadyToEvaluateScript() override {} bool HasFetchEventHandler() override { return false; } void DispatchFetchEvent(int fetch_event_id, @@ -210,11 +214,17 @@ return fetch_events_; } + FetchHandlerExistence fetch_handler_existence() const { + return fetch_handler_existence_; + } + private: std::unique_ptr<blink::WebServiceWorkerRegistrationObjectInfo> registration_object_info_; std::vector<std::pair<int /* event_id */, blink::WebServiceWorkerRequest>> fetch_events_; + FetchHandlerExistence fetch_handler_existence_ = + FetchHandlerExistence::UNKNOWN; }; base::RepeatingClosure CreateCallbackWithCalledFlag(bool* out_is_called) { @@ -261,6 +271,8 @@ ServiceWorkerContextClientTest() = default; protected: + using FetchHandlerExistence = blink::mojom::FetchHandlerExistence; + void SetUp() override { task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); message_loop_.SetTaskRunner(task_runner_); @@ -287,7 +299,9 @@ // |out_pipes->embedded_worker_instance_client|. ServiceWorkerContextClient* CreateContextClient( ContextClientPipes* out_pipes, - blink::WebServiceWorkerContextProxy* proxy) { + blink::WebServiceWorkerContextProxy* proxy, + FetchHandlerExistence fetch_handler_existence = + FetchHandlerExistence::DOES_NOT_EXIST) { EmbeddedWorkerInstanceClientImpl* embedded_worker_instance_client = new EmbeddedWorkerInstanceClientImpl( mojo::MakeRequest(&out_pipes->embedded_worker_instance_client)); @@ -341,7 +355,8 @@ mojo::MakeRequest(®istration_info->host_ptr_info); registration_info->request = mojo::MakeRequest(&out_pipes->registration); out_pipes->service_worker->InitializeGlobalScope( - std::move(service_worker_host), std::move(registration_info)); + std::move(service_worker_host), std::move(registration_info), + fetch_handler_existence); task_runner()->RunUntilIdle(); return context_client_raw; } @@ -641,4 +656,12 @@ context_client->DidEndTask(task_id); } +TEST_F(ServiceWorkerContextClientTest, InstalledFetchEventHandler) { + ContextClientPipes pipes; + MockWebServiceWorkerContextProxy mock_proxy; + CreateContextClient(&pipes, &mock_proxy, FetchHandlerExistence::EXISTS); + EXPECT_EQ(FetchHandlerExistence::EXISTS, + mock_proxy.fetch_handler_existence()); +} + } // namespace content
diff --git a/content/test/fuzzer/BUILD.gn b/content/test/fuzzer/BUILD.gn index 6c1cab8..47d513e 100644 --- a/content/test/fuzzer/BUILD.gn +++ b/content/test/fuzzer/BUILD.gn
@@ -251,3 +251,20 @@ ] } } + +fuzzer_test("speech_audio_encoder_fuzzer") { + sources = [ + "../../browser/speech/audio_buffer.cc", + "../../browser/speech/audio_buffer.h", + "../../browser/speech/audio_encoder.cc", + "../../browser/speech/audio_encoder.h", + "../../browser/speech/audio_encoder_fuzzer.cc", + "//base/test/fuzzed_data_provider.h", + "//content/common/content_export.h", + ] + + deps = [ + "//base", + "//third_party/flac", + ] +}
diff --git a/content/test/fuzzer/OWNERS b/content/test/fuzzer/OWNERS index 7ab46b14c..054ad6e 100644 --- a/content/test/fuzzer/OWNERS +++ b/content/test/fuzzer/OWNERS
@@ -1,2 +1,3 @@ mmoroz@chromium.org ochang@chromium.org +metzman@chromium.org
diff --git a/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py b/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py index f6fcbceb..60d31ec 100644 --- a/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py +++ b/content/test/gpu/gpu_tests/cloud_storage_integration_test_base.py
@@ -422,6 +422,9 @@ def ToHex(self, num): return hex(int(num)) + def ToHexOrNone(self, num): + return 'None' if num == None else self.ToHex(num) + def _UploadTestResultToSkiaGold(self, image_name, screenshot, tab, page, is_check_mode=True, build_id_args=None): @@ -437,8 +440,8 @@ ref_img_params = self.GetReferenceImageParameters(tab, page) # All values need to be strings, otherwise goldctl fails. gpu_keys = { - 'vendor_id': self.ToHex(ref_img_params.vendor_id), - 'device_id': self.ToHex(ref_img_params.device_id), + 'vendor_id': self.ToHexOrNone(ref_img_params.vendor_id), + 'device_id': self.ToHexOrNone(ref_img_params.device_id), 'vendor_string': str(ref_img_params.vendor_string), 'device_string': str(ref_img_params.device_string), 'msaa': str(ref_img_params.msaa),
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 9665e88..66787f1 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -383,6 +383,7 @@ crbug.com/794339 [ linux amd passthrough ] conformance/renderbuffers/depth-renderbuffer-initialization.html [ Failure ] crbug.com/794339 [ linux amd passthrough ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ Failure ] crbug.com/906066 [ linux amd passthrough ] conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html [ Failure ] +crbug.com/960808 [ linux amd passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ] # The following two tests only fail on Linux/Intel with Mesa 18.0.5, # not on Mesa 17.1.4 with the same Intel HD 630 GPU.
diff --git a/extensions/browser/api/storage/storage_frontend_unittest.cc b/extensions/browser/api/storage/storage_frontend_unittest.cc index eb204de..3da66c8 100644 --- a/extensions/browser/api/storage/storage_frontend_unittest.cc +++ b/extensions/browser/api/storage/storage_frontend_unittest.cc
@@ -24,7 +24,6 @@ namespace extensions { namespace settings = settings_namespace; -namespace util = settings_test_util; namespace { @@ -84,10 +83,11 @@ TEST_F(ExtensionSettingsFrontendTest, SettingsPreservedAcrossReconstruction) { const std::string id = "ext"; scoped_refptr<const Extension> extension = - util::AddExtensionWithId(browser_context(), id, Manifest::TYPE_EXTENSION); + settings_test_util::AddExtensionWithId(browser_context(), id, + Manifest::TYPE_EXTENSION); - ValueStore* storage = - util::GetStorage(extension, settings::LOCAL, frontend_.get()); + ValueStore* storage = settings_test_util::GetStorage( + extension, settings::LOCAL, frontend_.get()); // The correctness of Get/Set/Remove/Clear is tested elsewhere so no need to // be too rigorous. @@ -104,7 +104,8 @@ } ResetFrontend(); - storage = util::GetStorage(extension, settings::LOCAL, frontend_.get()); + storage = settings_test_util::GetStorage(extension, settings::LOCAL, + frontend_.get()); { ValueStore::ReadResult result = storage->Get(); @@ -115,11 +116,12 @@ TEST_F(ExtensionSettingsFrontendTest, SettingsClearedOnUninstall) { const std::string id = "ext"; - scoped_refptr<const Extension> extension = util::AddExtensionWithId( - browser_context(), id, Manifest::TYPE_LEGACY_PACKAGED_APP); + scoped_refptr<const Extension> extension = + settings_test_util::AddExtensionWithId( + browser_context(), id, Manifest::TYPE_LEGACY_PACKAGED_APP); - ValueStore* storage = - util::GetStorage(extension, settings::LOCAL, frontend_.get()); + ValueStore* storage = settings_test_util::GetStorage( + extension, settings::LOCAL, frontend_.get()); { base::Value bar("bar"); @@ -132,7 +134,8 @@ content::RunAllTasksUntilIdle(); // The storage area may no longer be valid post-uninstall, so re-request. - storage = util::GetStorage(extension, settings::LOCAL, frontend_.get()); + storage = settings_test_util::GetStorage(extension, settings::LOCAL, + frontend_.get()); { ValueStore::ReadResult result = storage->Get(); ASSERT_TRUE(result.status().ok()); @@ -143,10 +146,11 @@ TEST_F(ExtensionSettingsFrontendTest, LeveldbDatabaseDeletedFromDiskOnClear) { const std::string id = "ext"; scoped_refptr<const Extension> extension = - util::AddExtensionWithId(browser_context(), id, Manifest::TYPE_EXTENSION); + settings_test_util::AddExtensionWithId(browser_context(), id, + Manifest::TYPE_EXTENSION); - ValueStore* storage = - util::GetStorage(extension, settings::LOCAL, frontend_.get()); + ValueStore* storage = settings_test_util::GetStorage( + extension, settings::LOCAL, frontend_.get()); { base::Value bar("bar"); @@ -176,15 +180,16 @@ DISABLED_QuotaLimitsEnforcedCorrectlyForSyncAndLocal) { const std::string id = "ext"; scoped_refptr<const Extension> extension = - util::AddExtensionWithId(browser_context(), id, Manifest::TYPE_EXTENSION); + settings_test_util::AddExtensionWithId(browser_context(), id, + Manifest::TYPE_EXTENSION); - ValueStore* sync_storage = - util::GetStorage(extension, settings::SYNC, frontend_.get()); - ValueStore* local_storage = - util::GetStorage(extension, settings::LOCAL, frontend_.get()); + ValueStore* sync_storage = settings_test_util::GetStorage( + extension, settings::SYNC, frontend_.get()); + ValueStore* local_storage = settings_test_util::GetStorage( + extension, settings::LOCAL, frontend_.get()); // Sync storage should run out after ~100K. - std::unique_ptr<base::Value> kilobyte = util::CreateKilobyte(); + std::unique_ptr<base::Value> kilobyte = settings_test_util::CreateKilobyte(); for (int i = 0; i < 100; ++i) { sync_storage->Set(DEFAULTS, base::NumberToString(i), *kilobyte); } @@ -201,7 +206,7 @@ local_storage->Set(DEFAULTS, "WontError", *kilobyte).status().ok()); // Local storage should run out after ~5MB. - std::unique_ptr<base::Value> megabyte = util::CreateMegabyte(); + std::unique_ptr<base::Value> megabyte = settings_test_util::CreateMegabyte(); for (int i = 0; i < 5; ++i) { local_storage->Set(DEFAULTS, base::NumberToString(i), *megabyte); }
diff --git a/google_apis/gaia/gaia_constants.cc b/google_apis/gaia/gaia_constants.cc index d3d0cd9..2be7414 100644 --- a/google_apis/gaia/gaia_constants.cc +++ b/google_apis/gaia/gaia_constants.cc
@@ -41,6 +41,11 @@ // OAuth2 scope for access to the Chrome Sync APIs for managed profiles. const char kChromeSyncSupervisedOAuth2Scope[] = "https://www.googleapis.com/auth/chromesync_playpen"; + +// OAuth2 scope for access to Google Family Link kid scope. +const char kKidFamilyOAuth2Scope[] = + "https://www.googleapis.com/auth/kid.family"; + // OAuth2 scope for access to Google Talk APIs (XMPP). const char kGoogleTalkOAuth2Scope[] = "https://www.googleapis.com/auth/googletalk";
diff --git a/google_apis/gaia/gaia_constants.h b/google_apis/gaia/gaia_constants.h index 4786ac88..42e8076 100644 --- a/google_apis/gaia/gaia_constants.h +++ b/google_apis/gaia/gaia_constants.h
@@ -26,6 +26,7 @@ extern const char kAnyApiOAuth2Scope[]; extern const char kChromeSyncOAuth2Scope[]; extern const char kChromeSyncSupervisedOAuth2Scope[]; +extern const char kKidFamilyOAuth2Scope[]; extern const char kGoogleTalkOAuth2Scope[]; extern const char kGoogleUserInfoEmail[]; extern const char kGoogleUserInfoProfile[];
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 307e1cb..19ef376 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -292,10 +292,12 @@ "//testing/gmock", "//testing/gtest", "//third_party/angle:translator", + "//third_party/libyuv", "//ui/gfx", "//ui/gfx:test_support", "//ui/gfx/geometry", "//ui/gl", + "//ui/gl:test_support", "//ui/gl/init", ] @@ -361,7 +363,6 @@ "command_buffer/common/gles2_cmd_format_test_autogen.h", "command_buffer/common/gles2_cmd_utils_unittest.cc", "command_buffer/common/id_allocator_test.cc", - "command_buffer/common/id_type_unittest.cc", "command_buffer/common/raster_cmd_format_test.cc", "command_buffer/common/raster_cmd_format_test_autogen.h", "command_buffer/common/unittest_main.cc",
diff --git a/gpu/command_buffer/common/BUILD.gn b/gpu/command_buffer/common/BUILD.gn index 260d231..16b7de08 100644 --- a/gpu/command_buffer/common/BUILD.gn +++ b/gpu/command_buffer/common/BUILD.gn
@@ -82,7 +82,6 @@ "gpu_memory_buffer_support.h", "id_allocator.cc", "id_allocator.h", - "id_type.h", "mailbox.cc", "mailbox.h", "mailbox_holder.cc", @@ -107,6 +106,7 @@ configs += [ "//gpu:gpu_implementation" ] public_deps = [ + "//base/util/type-safety", "//mojo/public/cpp/system", "//ui/gfx:memory_buffer", "//ui/gfx/geometry",
diff --git a/gpu/command_buffer/common/command_buffer_id.h b/gpu/command_buffer/common/command_buffer_id.h index 99b5bb862..26a2995 100644 --- a/gpu/command_buffer/common/command_buffer_id.h +++ b/gpu/command_buffer/common/command_buffer_id.h
@@ -5,12 +5,12 @@ #ifndef GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_ID_H_ #define GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_ID_H_ -#include "gpu/command_buffer/common/id_type.h" +#include "base/util/type-safety/id_type.h" namespace gpu { class CommandBuffer; -using CommandBufferId = gpu::IdTypeU64<CommandBuffer>; +using CommandBufferId = util::IdTypeU64<CommandBuffer>; } // namespace gpu
diff --git a/gpu/command_buffer/common/discardable_handle.h b/gpu/command_buffer/common/discardable_handle.h index 33f2d85..33eda35 100644 --- a/gpu/command_buffer/common/discardable_handle.h +++ b/gpu/command_buffer/common/discardable_handle.h
@@ -6,7 +6,7 @@ #define GPU_COMMAND_BUFFER_COMMON_DISCARDABLE_HANDLE_H_ #include "base/memory/ref_counted.h" -#include "gpu/command_buffer/common/id_type.h" +#include "base/util/type-safety/id_type.h" #include "gpu/gpu_export.h" namespace gpu { @@ -83,7 +83,7 @@ // handle (via the constructor), and can Lock an existing handle. class GPU_EXPORT ClientDiscardableHandle : public DiscardableHandleBase { public: - using Id = IdType32<ClientDiscardableHandle>; + using Id = util::IdType32<ClientDiscardableHandle>; ClientDiscardableHandle(); // Constructs an invalid handle. ClientDiscardableHandle(scoped_refptr<Buffer> buffer,
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index ffe8b4b0..1bf32ca 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -79,6 +79,7 @@ ] public_deps = [ + "//base/util/type-safety", "//gpu/command_buffer/common:common_sources", "//url:url", ] @@ -282,6 +283,7 @@ include_dirs = [ "//third_party/mesa_headers" ] public_deps = [ + "//base/util/type-safety", "//cc/paint", "//gpu/command_buffer/common", "//gpu/command_buffer/common:gles2_sources",
diff --git a/gpu/command_buffer/service/sequence_id.h b/gpu/command_buffer/service/sequence_id.h index a2302c2..7f8db99 100644 --- a/gpu/command_buffer/service/sequence_id.h +++ b/gpu/command_buffer/service/sequence_id.h
@@ -5,12 +5,12 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_SEQUENCE_ID_H_ #define GPU_COMMAND_BUFFER_SERVICE_SEQUENCE_ID_H_ -#include "gpu/command_buffer/common/id_type.h" +#include "base/util/type-safety/id_type.h" namespace gpu { class SyncPointOrderData; -using SequenceId = gpu::IdTypeU32<SyncPointOrderData>; +using SequenceId = util::IdTypeU32<SyncPointOrderData>; } // namespace gpu
diff --git a/gpu/command_buffer/tests/DEPS b/gpu/command_buffer/tests/DEPS new file mode 100644 index 0000000..54f5844e --- /dev/null +++ b/gpu/command_buffer/tests/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+third_party/libyuv", +]
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc index faaaeacb7..6d277cb28 100644 --- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc +++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -21,10 +21,12 @@ #include "gpu/command_buffer/tests/gl_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/libyuv/include/libyuv.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/half_float.h" #include "ui/gl/gl_image.h" +#include "ui/gl/test/gl_image_test_support.h" #if defined(OS_LINUX) #include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h" @@ -116,83 +118,6 @@ ); // clang-format on -void SetRow(gfx::BufferFormat format, - uint8_t* buffer, - int width, - uint8_t pixel[4]) { - switch (format) { - case gfx::BufferFormat::R_8: - for (int i = 0; i < width; ++i) - buffer[i] = pixel[0]; - return; - case gfx::BufferFormat::BGR_565: - for (int i = 0; i < width * 2; i += 2) { - *reinterpret_cast<uint16_t*>(&buffer[i]) = - ((pixel[2] >> 3) << 11) | ((pixel[1] >> 2) << 5) | (pixel[0] >> 3); - } - return; - case gfx::BufferFormat::RGBA_4444: - for (int i = 0; i < width * 2; i += 2) { - buffer[i + 0] = (pixel[1] << 4) | (pixel[0] & 0xf); - buffer[i + 1] = (pixel[3] << 4) | (pixel[2] & 0xf); - } - return; - case gfx::BufferFormat::RGBA_8888: - case gfx::BufferFormat::RGBX_8888: - for (int i = 0; i < width * 4; i += 4) { - buffer[i + 0] = pixel[0]; - buffer[i + 1] = pixel[1]; - buffer[i + 2] = pixel[2]; - buffer[i + 3] = pixel[3]; - } - return; - case gfx::BufferFormat::BGRA_8888: - for (int i = 0; i < width * 4; i += 4) { - buffer[i + 0] = pixel[2]; - buffer[i + 1] = pixel[1]; - buffer[i + 2] = pixel[0]; - buffer[i + 3] = pixel[3]; - } - return; - case gfx::BufferFormat::RGBA_F16: { - float float_pixel[4] = { - pixel[0] / 255.f, pixel[1] / 255.f, pixel[2] / 255.f, - pixel[3] / 255.f, - }; - uint16_t half_float_pixel[4]; - gfx::FloatToHalfFloat(float_pixel, half_float_pixel, 4); - uint16_t* half_float_buffer = reinterpret_cast<uint16_t*>(buffer); - for (int i = 0; i < width * 4; i += 4) { - half_float_buffer[i + 0] = half_float_pixel[0]; - half_float_buffer[i + 1] = half_float_pixel[1]; - half_float_buffer[i + 2] = half_float_pixel[2]; - half_float_buffer[i + 3] = half_float_pixel[3]; - } - return; - } - case gfx::BufferFormat::RGBX_1010102: - for (int x = 0; x < width; ++x) { - *reinterpret_cast<uint32_t*>(&buffer[x * 4]) = - 0x3 << 30 | // Alpha channel is unused - ((pixel[2] << 2) | (pixel[2] >> 6)) << 20 | // B - ((pixel[1] << 2) | (pixel[1] >> 6)) << 10 | // G - ((pixel[0] << 2) | (pixel[0] >> 6)); // R - } - return; - case gfx::BufferFormat::BGRX_8888: - case gfx::BufferFormat::BGRX_1010102: - case gfx::BufferFormat::R_16: - case gfx::BufferFormat::RG_88: - case gfx::BufferFormat::UYVY_422: - case gfx::BufferFormat::YVU_420: - case gfx::BufferFormat::YUV_420_BIPLANAR: - NOTREACHED(); - return; - } - - NOTREACHED(); -} - GLenum InternalFormat(gfx::BufferFormat format) { switch (format) { case gfx::BufferFormat::R_8: @@ -208,16 +133,16 @@ case gfx::BufferFormat::RGBA_8888: return GL_RGBA; case gfx::BufferFormat::BGRA_8888: + case gfx::BufferFormat::BGRX_1010102: return GL_BGRA_EXT; case gfx::BufferFormat::RGBA_F16: return GL_RGBA; case gfx::BufferFormat::BGRX_8888: - case gfx::BufferFormat::BGRX_1010102: case gfx::BufferFormat::RGBX_8888: case gfx::BufferFormat::UYVY_422: case gfx::BufferFormat::YVU_420: case gfx::BufferFormat::YUV_420_BIPLANAR: - NOTREACHED(); + NOTREACHED() << gfx::BufferFormatToString(format); return 0; } @@ -225,28 +150,135 @@ return 0; } +uint32_t BufferFormatToFourCC(gfx::BufferFormat format) { + switch (format) { + case gfx::BufferFormat::BGR_565: + return libyuv::FOURCC_ANY; // libyuv::FOURCC_RGBP has wrong endianness. + case gfx::BufferFormat::RGBA_4444: + return libyuv::FOURCC_ANY; // libyuv::FOURCC_R444 has wrong endianness. + case gfx::BufferFormat::RGBA_8888: + return libyuv::FOURCC_ABGR; + case gfx::BufferFormat::BGRA_8888: + return libyuv::FOURCC_ARGB; + case gfx::BufferFormat::RGBX_1010102: + return libyuv::FOURCC_AB30; + case gfx::BufferFormat::BGRX_1010102: + return libyuv::FOURCC_AR30; + case gfx::BufferFormat::YUV_420_BIPLANAR: + return libyuv::FOURCC_NV12; + case gfx::BufferFormat::YVU_420: + return libyuv::FOURCC_YV12; + case gfx::BufferFormat::R_8: + case gfx::BufferFormat::R_16: + case gfx::BufferFormat::RG_88: + case gfx::BufferFormat::RGBA_F16: + case gfx::BufferFormat::BGRX_8888: + case gfx::BufferFormat::RGBX_8888: + case gfx::BufferFormat::UYVY_422: + return libyuv::FOURCC_ANY; + } + NOTREACHED(); + return libyuv::FOURCC_ANY; +} + } // namespace +// Verifies that the read-back colour after map-write-unmap is the original. +TEST_P(GpuMemoryBufferTest, MapUnmap) { + const gfx::BufferFormat buffer_format = GetParam(); + const uint32_t libyuv_fourcc = BufferFormatToFourCC(buffer_format); + if (libyuv_fourcc == static_cast<uint32_t>(libyuv::FOURCC_ANY)) { + LOG(WARNING) << gfx::BufferFormatToString(buffer_format) + << " not supported, skipping test"; + return; + } + + std::unique_ptr<gfx::GpuMemoryBuffer> buffer(gl_.CreateGpuMemoryBuffer( + gfx::Size(kImageWidth, kImageHeight), buffer_format)); + + ASSERT_TRUE(buffer->Map()); + ASSERT_NE(nullptr, buffer->memory(0)); + ASSERT_NE(0, buffer->stride(0)); + constexpr uint8_t color_rgba[] = {127u, 0u, 0u, 255u}; + constexpr uint8_t color_bgra[] = {0u, 0u, 127u, 255u}; + + const size_t num_planes = NumberOfPlanesForBufferFormat(buffer_format); + for (size_t plane = 0; plane < num_planes; ++plane) { + gl::GLImageTestSupport::SetBufferDataToColor( + kImageWidth, kImageHeight, buffer->stride(plane), plane, buffer_format, + color_rgba, static_cast<uint8_t*>(buffer->memory(plane))); + } + buffer->Unmap(); + + ASSERT_TRUE(buffer->Map()); + ASSERT_NE(nullptr, buffer->memory(0)); + ASSERT_NE(0, buffer->stride(0)); + const uint8_t* data = static_cast<uint8_t*>(buffer->memory(0)); + const int stride = buffer->stride(0); + // libyuv defines the formats as word-order. + uint8_t argb[kImageWidth * kImageHeight * 4] = {}; + const int result = libyuv::ConvertToARGB( + data, stride * kImageWidth, argb, kImageWidth /* dst_stride_argb */, + 0 /* crop_x */, 0 /* crop_y */, kImageWidth, kImageHeight, + kImageWidth /* rop_width */, kImageHeight /* crop_height */, + libyuv::kRotate0, libyuv_fourcc); + + constexpr int max_error = 2; + ASSERT_EQ(result, 0) << gfx::BufferFormatToString(buffer_format); + int bad_count = 0; + for (int y = 0; y < kImageHeight; ++y) { + for (int x = 0; x < kImageWidth; ++x) { + int offset = y * kImageWidth + x * 4; + for (int c = 0; c < 4; ++c) { + // |argb| in word order is read as B, G, R, A on little endian . + const uint8_t actual = argb[offset + c]; + const uint8_t expected = color_bgra[c]; + EXPECT_NEAR(expected, actual, max_error) + << " at " << x << ", " << y << " channel " << c; + bad_count += std::abs(actual - expected) > max_error; + // Exit early just so we don't spam the log but we print enough to + // hopefully make it easy to diagnose the issue. + ASSERT_LE(bad_count, 4); + } + } + } + buffer->Unmap(); +} + // An end to end test that tests the whole GpuMemoryBuffer lifecycle. TEST_P(GpuMemoryBufferTest, Lifecycle) { - if (GetParam() == gfx::BufferFormat::R_8 && + const gfx::BufferFormat buffer_format = GetParam(); + + if (buffer_format == gfx::BufferFormat::R_8 && !gl_.GetCapabilities().texture_rg) { LOG(WARNING) << "texture_rg not supported. Skipping test."; return; } - if (GetParam() == gfx::BufferFormat::RGBA_F16 && + if (buffer_format == gfx::BufferFormat::RGBA_F16 && !gl_.GetCapabilities().texture_half_float_linear) { LOG(WARNING) << "texture_half_float_linear not supported. Skipping test."; return; } - if (GetParam() == gfx::BufferFormat::RGBX_1010102 && + if (buffer_format == gfx::BufferFormat::RGBX_1010102 && !gl_.GetCapabilities().image_xb30) { LOG(WARNING) << "image_xb30 not supported. Skipping test."; return; } + if (buffer_format == gfx::BufferFormat::BGRX_1010102 && + !gl_.GetCapabilities().image_xr30) { + LOG(WARNING) << "image_xr30 not supported. Skipping test."; + return; + } + + if (buffer_format == gfx::BufferFormat::YVU_420 || + buffer_format == gfx::BufferFormat::YUV_420_BIPLANAR) { + LOG(WARNING) << "GLImageMemory doesn't support YUV formats, skipping test."; + return; + } + GLuint texture_id = 0; glGenTextures(1, &texture_id); ASSERT_NE(0u, texture_id); @@ -258,27 +290,26 @@ // Create the gpu memory buffer. std::unique_ptr<gfx::GpuMemoryBuffer> buffer(gl_.CreateGpuMemoryBuffer( - gfx::Size(kImageWidth, kImageHeight), GetParam())); + gfx::Size(kImageWidth, kImageHeight), buffer_format)); // Map buffer for writing. ASSERT_TRUE(buffer->Map()); ASSERT_NE(nullptr, buffer->memory(0)); ASSERT_NE(0, buffer->stride(0)); - uint8_t pixel[] = {255u, 0u, 0u, 255u}; + constexpr uint8_t pixel[] = {255u, 0u, 0u, 255u}; - // Assign a value to each pixel. - for (int y = 0; y < kImageHeight; ++y) { - SetRow(GetParam(), - static_cast<uint8_t*>(buffer->memory(0)) + y * buffer->stride(0), - kImageWidth, pixel); + const size_t num_planes = NumberOfPlanesForBufferFormat(buffer_format); + for (size_t plane = 0; plane < num_planes; ++plane) { + gl::GLImageTestSupport::SetBufferDataToColor( + kImageWidth, kImageHeight, buffer->stride(plane), plane, buffer_format, + pixel, static_cast<uint8_t*>(buffer->memory(0))); } - // Unmap the buffer. buffer->Unmap(); // Create the image. This should add the image ID to the ImageManager. GLuint image_id = glCreateImageCHROMIUM(buffer->AsClientBuffer(), kImageWidth, kImageHeight, - InternalFormat(GetParam())); + InternalFormat(buffer_format)); ASSERT_NE(0u, image_id); ASSERT_TRUE(gl_.decoder()->GetImageManagerForTest()->LookupImage(image_id) != nullptr); @@ -350,10 +381,9 @@ std::unique_ptr<uint8_t[]> pixels(new uint8_t[buffer_size]); - // Assign a value to each pixel. - for (int y = 0; y < size.height(); ++y) { - SetRow(format, pixels.get() + y * stride, size.width(), pixel); - } + gl::GLImageTestSupport::SetBufferDataToColor(kImageWidth, kImageHeight, + stride, 0 /* plane */, format, + pixel, pixels.get()); // A real use case would be to export a VAAPI surface as dmabuf fds. But for // simplicity the test gets them from a GL texture. @@ -439,15 +469,19 @@ } #endif // defined(OS_LINUX) -INSTANTIATE_TEST_SUITE_P(GpuMemoryBufferTests, - GpuMemoryBufferTest, - ::testing::Values(gfx::BufferFormat::R_8, - gfx::BufferFormat::BGR_565, - gfx::BufferFormat::RGBA_4444, - gfx::BufferFormat::RGBA_8888, - gfx::BufferFormat::RGBX_1010102, - gfx::BufferFormat::BGRA_8888, - gfx::BufferFormat::RGBA_F16)); +INSTANTIATE_TEST_SUITE_P( + GpuMemoryBufferTests, + GpuMemoryBufferTest, + ::testing::Values(gfx::BufferFormat::R_8, + gfx::BufferFormat::BGR_565, + gfx::BufferFormat::RGBA_4444, + gfx::BufferFormat::RGBA_8888, + gfx::BufferFormat::RGBX_1010102, + gfx::BufferFormat::BGRX_1010102, + gfx::BufferFormat::BGRA_8888, + gfx::BufferFormat::RGBA_F16, + gfx::BufferFormat::YVU_420, + gfx::BufferFormat::YUV_420_BIPLANAR)); } // namespace gles2 } // namespace gpu
diff --git a/gpu/ipc/command_buffer_task_executor.cc b/gpu/ipc/command_buffer_task_executor.cc index fb1b239e..9bdab66 100644 --- a/gpu/ipc/command_buffer_task_executor.cc +++ b/gpu/ipc/command_buffer_task_executor.cc
@@ -21,7 +21,8 @@ scoped_refptr<gl::GLShareGroup> share_group, gl::GLSurfaceFormat share_group_surface_format, SharedImageManager* shared_image_manager, - gles2::ProgramCache* program_cache) + gles2::ProgramCache* program_cache, + scoped_refptr<SharedContextState> shared_context_state) : gpu_preferences_(gpu_preferences), gpu_feature_info_(gpu_feature_info), sync_point_manager_(sync_point_manager), @@ -30,7 +31,8 @@ share_group_surface_format_(share_group_surface_format), program_cache_(program_cache), shader_translator_cache_(gpu_preferences_), - shared_image_manager_(shared_image_manager) { + shared_image_manager_(shared_image_manager), + shared_context_state_(std::move(shared_context_state)) { DCHECK(mailbox_manager_); DCHECK(shared_image_manager_); }
diff --git a/gpu/ipc/command_buffer_task_executor.h b/gpu/ipc/command_buffer_task_executor.h index f39f02d..8b2dac2 100644 --- a/gpu/ipc/command_buffer_task_executor.h +++ b/gpu/ipc/command_buffer_task_executor.h
@@ -18,6 +18,7 @@ #include "gpu/command_buffer/service/sequence_id.h" #include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/shader_translator_cache.h" +#include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_image_manager.h" #include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_preferences.h" @@ -66,14 +67,16 @@ virtual void ContinueTask(base::OnceClosure task) = 0; }; - CommandBufferTaskExecutor(const GpuPreferences& gpu_preferences, - const GpuFeatureInfo& gpu_feature_info, - SyncPointManager* sync_point_manager, - MailboxManager* mailbox_manager, - scoped_refptr<gl::GLShareGroup> share_group, - gl::GLSurfaceFormat share_group_surface_format, - SharedImageManager* shared_image_manager, - gles2::ProgramCache* program_cache); + CommandBufferTaskExecutor( + const GpuPreferences& gpu_preferences, + const GpuFeatureInfo& gpu_feature_info, + SyncPointManager* sync_point_manager, + MailboxManager* mailbox_manager, + scoped_refptr<gl::GLShareGroup> share_group, + gl::GLSurfaceFormat share_group_surface_format, + SharedImageManager* shared_image_manager, + gles2::ProgramCache* program_cache, + scoped_refptr<SharedContextState> shared_context_state); virtual ~CommandBufferTaskExecutor(); // Always use virtualized GL contexts if this returns true. @@ -119,6 +122,10 @@ } SharedImageManager* shared_image_manager() { return shared_image_manager_; } + scoped_refptr<SharedContextState> shared_context_state() { + return shared_context_state_; + } + // These methods construct accessed fields if not already initialized. scoped_refptr<gl::GLShareGroup> share_group(); gles2::Outputter* outputter(); @@ -140,6 +147,7 @@ gles2::ShaderTranslatorCache shader_translator_cache_; gles2::FramebufferCompletenessCache framebuffer_completeness_cache_; SharedImageManager* shared_image_manager_; + const scoped_refptr<SharedContextState> shared_context_state_; // No-op default initialization is used in in-process mode. GpuProcessActivityFlags activity_flags_;
diff --git a/gpu/ipc/common/gpu_command_buffer_traits.h b/gpu/ipc/common/gpu_command_buffer_traits.h index 1dc4008..5b1ff5c 100644 --- a/gpu/ipc/common/gpu_command_buffer_traits.h +++ b/gpu/ipc/common/gpu_command_buffer_traits.h
@@ -5,7 +5,6 @@ #ifndef GPU_IPC_COMMON_GPU_COMMAND_BUFFER_TRAITS_H_ #define GPU_IPC_COMMON_GPU_COMMAND_BUFFER_TRAITS_H_ -#include "gpu/command_buffer/common/id_type.h" #include "gpu/gpu_export.h" #include "gpu/ipc/common/gpu_command_buffer_traits_multi.h" #include "ipc/ipc_message_utils.h" @@ -60,26 +59,6 @@ static void Log(const param_type& p, std::string* l); }; -template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> -struct ParamTraits<gpu::IdType<TypeMarker, WrappedType, kInvalidValue>> { - using param_type = gpu::IdType<TypeMarker, WrappedType, kInvalidValue>; - static void Write(base::Pickle* m, const param_type& p) { - WriteParam(m, p.GetUnsafeValue()); - } - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r) { - WrappedType value; - if (!ReadParam(m, iter, &value)) - return false; - *r = param_type::FromUnsafeValue(value); - return true; - } - static void Log(const param_type& p, std::string* l) { - LogParam(p.GetUnsafeValue(), l); - } -}; - } // namespace IPC #endif // GPU_IPC_COMMON_GPU_COMMAND_BUFFER_TRAITS_H_
diff --git a/gpu/ipc/gpu_in_process_thread_service.cc b/gpu/ipc/gpu_in_process_thread_service.cc index 2c20bb02..9f85b62 100644 --- a/gpu/ipc/gpu_in_process_thread_service.cc +++ b/gpu/ipc/gpu_in_process_thread_service.cc
@@ -61,7 +61,8 @@ const GpuFeatureInfo& gpu_feature_info, const GpuPreferences& gpu_preferences, SharedImageManager* shared_image_manager, - gles2::ProgramCache* program_cache) + gles2::ProgramCache* program_cache, + scoped_refptr<SharedContextState> shared_context_state) : CommandBufferTaskExecutor(gpu_preferences, gpu_feature_info, sync_point_manager, @@ -69,7 +70,8 @@ share_group, share_group_surface_format, shared_image_manager, - program_cache), + program_cache, + std::move(shared_context_state)), task_runner_(task_runner), scheduler_(scheduler) {}
diff --git a/gpu/ipc/gpu_in_process_thread_service.h b/gpu/ipc/gpu_in_process_thread_service.h index 98a0f88..39775b7 100644 --- a/gpu/ipc/gpu_in_process_thread_service.h +++ b/gpu/ipc/gpu_in_process_thread_service.h
@@ -37,7 +37,8 @@ const GpuFeatureInfo& gpu_feature_info, const GpuPreferences& gpu_preferences, SharedImageManager* shared_image_manager, - gles2::ProgramCache* program_cache); + gles2::ProgramCache* program_cache, + scoped_refptr<SharedContextState> shared_context_state); ~GpuInProcessThreadService() override; // CommandBufferTaskExecutor implementation.
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index d8086e8..c1e240e3 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -556,6 +556,8 @@ gl_share_group_ = task_executor_->share_group(); } + context_state_ = task_executor_->shared_context_state(); + if (params.attribs.context_type == CONTEXT_TYPE_WEBGPU) { if (!task_executor_->gpu_preferences().enable_webgpu) { DLOG(ERROR) << "ContextResult::kFatalFailure: WebGPU not enabled"; @@ -610,20 +612,30 @@ if (params.attribs.enable_raster_interface && !params.attribs.enable_gles2_interface) { - context_state_ = base::MakeRefCounted<SharedContextState>( - gl_share_group_, surface_, real_context, use_virtualized_gl_context_, - base::DoNothing()); - context_state_->InitializeGL(task_executor_->gpu_preferences(), - context_group_->feature_info()); - gr_shader_cache_ = params.gr_shader_cache; - context_state_->InitializeGrContext(workarounds, params.gr_shader_cache, - params.activity_flags); + if (!context_state_) { + context_state_ = base::MakeRefCounted<SharedContextState>( + gl_share_group_, surface_, real_context, + use_virtualized_gl_context_, base::DoNothing()); + context_state_->InitializeGL(task_executor_->gpu_preferences(), + context_group_->feature_info()); + gr_shader_cache_ = params.gr_shader_cache; + context_state_->InitializeGrContext(workarounds, params.gr_shader_cache, + params.activity_flags); + } + + if (!context_state_->MakeCurrent(nullptr)) { + DestroyOnGpuThread(); + LOG(ERROR) << "Failed to make context current."; + return ContextResult::kTransientFailure; + } if (base::ThreadTaskRunnerHandle::IsSet()) { gr_cache_controller_.emplace(context_state_.get(), base::ThreadTaskRunnerHandle::Get()); } + context_ = context_state_->context(); + decoder_.reset(raster::RasterDecoder::Create( this, command_buffer_.get(), task_executor_->outputter(), task_executor_->gpu_feature_info(), task_executor_->gpu_preferences(), @@ -633,12 +645,7 @@ decoder_.reset(gles2::GLES2Decoder::Create(this, command_buffer_.get(), task_executor_->outputter(), context_group_.get())); - } - - if (use_virtualized_gl_context_) { - if (context_state_) { - context_ = context_state_->context(); - } else { + if (use_virtualized_gl_context_) { context_ = base::MakeRefCounted<GLContextVirtual>( gl_share_group_.get(), real_context.get(), decoder_->AsWeakPtr()); if (!context_->Initialize(surface_.get(), @@ -652,18 +659,18 @@ "Failed to initialize virtual GL context."; return gpu::ContextResult::kFatalFailure; } - } - if (!context_->MakeCurrent(surface_.get())) { - DestroyOnGpuThread(); - // The caller should retry making a context, but this one won't work. - LOG(ERROR) << "ContextResult::kTransientFailure: " - "Could not make context current."; - return gpu::ContextResult::kTransientFailure; + if (!context_->MakeCurrent(surface_.get())) { + DestroyOnGpuThread(); + // The caller should retry making a context, but this one won't work. + LOG(ERROR) << "ContextResult::kTransientFailure: " + "Could not make context current."; + return gpu::ContextResult::kTransientFailure; + } + } else { + context_ = real_context; + DCHECK(context_->IsCurrent(surface_.get())); } - } else { - context_ = real_context; - DCHECK(context_->IsCurrent(surface_.get())); } if (!context_group_->has_program_cache() &&
diff --git a/gpu/ipc/in_process_gpu_thread_holder.cc b/gpu/ipc/in_process_gpu_thread_holder.cc index f2fd2a0..3b9c6aea 100644 --- a/gpu/ipc/in_process_gpu_thread_holder.cc +++ b/gpu/ipc/in_process_gpu_thread_holder.cc
@@ -73,7 +73,7 @@ task_executor_ = std::make_unique<GpuInProcessThreadService>( task_runner(), scheduler_.get(), sync_point_manager_.get(), mailbox_manager_.get(), nullptr, gl::GLSurfaceFormat(), gpu_feature_info_, - gpu_preferences_, shared_image_manager_.get(), nullptr); + gpu_preferences_, shared_image_manager_.get(), nullptr, nullptr); completion->Signal(); }
diff --git a/ios/chrome/app/tests_fake_hook.mm b/ios/chrome/app/tests_fake_hook.mm index b502b62..a65067f9 100644 --- a/ios/chrome/app/tests_fake_hook.mm +++ b/ios/chrome/app/tests_fake_hook.mm
@@ -16,9 +16,6 @@ bool DisableContentSuggestions() { return false; } -bool DisableContextualSearch() { - return false; -} bool DisableFirstRun() { return false; }
diff --git a/ios/chrome/app/tests_hook.h b/ios/chrome/app/tests_hook.h index e92cafa1..ab4ac8a 100644 --- a/ios/chrome/app/tests_hook.h +++ b/ios/chrome/app/tests_hook.h
@@ -16,10 +16,6 @@ // run unimpeded. bool DisableContentSuggestions(); -// Returns true if contextual search should be disabled to allow other tests -// to run unimpeded. -bool DisableContextualSearch(); - // Returns true if the first_run path should be disabled to allow other tests to // run unimpeded. bool DisableFirstRun();
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc index 41531914..b62de6c 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc
@@ -72,9 +72,7 @@ base::Optional<base::Value> value = json_reader.ReadToValue(json); if (value) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(success_callback, - base::Value::ToUniquePtrValue(std::move(*value)))); + FROM_HERE, base::BindOnce(success_callback, std::move(*value))); } else { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE,
diff --git a/ios/chrome/browser/ui/settings/autofill/BUILD.gn b/ios/chrome/browser/ui/settings/autofill/BUILD.gn index d838673..bd79bcd 100644 --- a/ios/chrome/browser/ui/settings/autofill/BUILD.gn +++ b/ios/chrome/browser/ui/settings/autofill/BUILD.gn
@@ -33,6 +33,7 @@ "//ios/chrome/browser/ui/autofill/cells", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/settings:settings_root", + "//ios/chrome/browser/ui/settings/autofill/cells", "//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view/cells",
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm index bce50dff..891779b 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm
@@ -18,7 +18,7 @@ #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/ui/settings/autofill/autofill_credit_card_edit_table_view_controller.h" -#import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" +#import "ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #include "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm index 2e614db..cda761a 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.mm
@@ -16,7 +16,7 @@ #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.h" -#import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" +#import "ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
diff --git a/ios/chrome/browser/ui/settings/autofill/cells/BUILD.gn b/ios/chrome/browser/ui/settings/autofill/cells/BUILD.gn new file mode 100644 index 0000000..5ce2403 --- /dev/null +++ b/ios/chrome/browser/ui/settings/autofill/cells/BUILD.gn
@@ -0,0 +1,16 @@ +# 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. + +source_set("cells") { + sources = [ + "autofill_data_item.h", + "autofill_data_item.mm", + ] + + deps = [ + "//ios/chrome/browser/ui/table_view/cells", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +}
diff --git a/ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.h b/ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.h new file mode 100644 index 0000000..4b282ce --- /dev/null +++ b/ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_AUTOFILL_CELLS_AUTOFILL_DATA_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_AUTOFILL_CELLS_AUTOFILL_DATA_ITEM_H_ + +#import "ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h" + +// Item for autofill profile (address) or credit card. +@interface AutofillDataItem : TableViewMultiDetailTextItem + +// Only deletable items will enter edit mode. +@property(nonatomic, assign, getter=isDeletable) BOOL deletable; + +// The GUID used by the PersonalDataManager to identify data elements (e.g. +// profiles and credit cards). +@property(nonatomic, assign) std::string GUID; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_AUTOFILL_CELLS_AUTOFILL_DATA_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.mm b/ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.mm new file mode 100644 index 0000000..7a884ec --- /dev/null +++ b/ios/chrome/browser/ui/settings/autofill/cells/autofill_data_item.mm
@@ -0,0 +1,13 @@ +// 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/browser/ui/settings/autofill/cells/autofill_data_item.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation AutofillDataItem + +@end
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn index 6decd0d..c440a845 100644 --- a/ios/chrome/browser/ui/settings/cells/BUILD.gn +++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -6,8 +6,6 @@ sources = [ "account_sign_in_item.h", "account_sign_in_item.mm", - "autofill_data_item.h", - "autofill_data_item.mm", "byo_textfield_item.h", "byo_textfield_item.mm", "clear_browsing_data_constants.h", @@ -78,7 +76,6 @@ source_set("unit_tests") { testonly = true sources = [ - "autofill_data_item_unittest.mm", "byo_textfield_item_unittest.mm", "clear_browsing_data_item_unittest.mm", "copied_to_chrome_item_unittest.mm",
diff --git a/ios/chrome/browser/ui/settings/cells/autofill_data_item.h b/ios/chrome/browser/ui/settings/cells/autofill_data_item.h deleted file mode 100644 index d84d67ad..0000000 --- a/ios/chrome/browser/ui/settings/cells/autofill_data_item.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_AUTOFILL_DATA_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_AUTOFILL_DATA_ITEM_H_ - -#include <string> - -#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" - -// Item for autofill profile (address) or credit card. -@interface AutofillDataItem : TableViewItem - -// Only deletable items will enter edit mode. -@property(nonatomic, assign, getter=isDeletable) BOOL deletable; - -// The GUID used by the PersonalDataManager to identify data elements (e.g. -// profiles and credit cards). -@property(nonatomic, assign) std::string GUID; - -@property(nonatomic, copy) NSString* text; -@property(nonatomic, copy) NSString* leadingDetailText; -@property(nonatomic, copy) NSString* trailingDetailText; - -@end - -// Cell for autofill data with two leading text labels and one trailing text -// label. -@interface AutofillDataCell : TableViewCell - -@property(nonatomic, readonly, strong) UILabel* textLabel; -@property(nonatomic, readonly, strong) UILabel* leadingDetailTextLabel; -@property(nonatomic, readonly, strong) UILabel* trailingDetailTextLabel; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_AUTOFILL_DATA_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/autofill_data_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/autofill_data_item_unittest.mm deleted file mode 100644 index cc24b768..0000000 --- a/ios/chrome/browser/ui/settings/cells/autofill_data_item_unittest.mm +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" - -#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using AutofillDataItemTest = PlatformTest; - -// Tests that the UILabels are set properly after a call to |configureCell:|. -TEST_F(AutofillDataItemTest, TextLabels) { - AutofillDataItem* item = [[AutofillDataItem alloc] initWithType:0]; - NSString* mainText = @"Main text"; - NSString* leadingDetailText = @"Leading detail text"; - NSString* trailingDetailText = @"Trailing detail text"; - - item.text = mainText; - item.leadingDetailText = leadingDetailText; - item.trailingDetailText = trailingDetailText; - item.accessoryType = UITableViewCellAccessoryCheckmark; - - id cell = [[[item cellClass] alloc] init]; - ASSERT_TRUE([cell isMemberOfClass:[AutofillDataCell class]]); - - AutofillDataCell* autofillDataCell = cell; - EXPECT_FALSE(autofillDataCell.textLabel.text); - EXPECT_FALSE(autofillDataCell.leadingDetailTextLabel.text); - EXPECT_FALSE(autofillDataCell.trailingDetailTextLabel.text); - EXPECT_EQ(UITableViewCellAccessoryNone, autofillDataCell.accessoryType); - - [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]]; - EXPECT_NSEQ(mainText, autofillDataCell.textLabel.text); - EXPECT_NSEQ(leadingDetailText, autofillDataCell.leadingDetailTextLabel.text); - EXPECT_NSEQ(trailingDetailText, - autofillDataCell.trailingDetailTextLabel.text); - EXPECT_EQ(UITableViewCellAccessoryCheckmark, autofillDataCell.accessoryType); -}
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm index b4698482..5995f293 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
@@ -505,10 +505,20 @@ } - (void)updateToolbarButtons { - // Enabling the Clear Browsing Data button only when at least 1 cells are - // selected. - self.clearBrowsingDataBarButton.enabled = - ([[self.tableView indexPathsForSelectedRows] count] > 0); + self.clearBrowsingDataBarButton.enabled = [self hasDataTypeItemsSelected]; +} + +- (BOOL)hasDataTypeItemsSelected { + // Returns YES iff at least 1 data type cell is selected. + NSArray* dataTypeItems = [self.tableViewModel + itemsInSectionWithIdentifier:SectionIdentifierDataTypes]; + for (TableViewClearBrowsingDataItem* dataTypeItem in dataTypeItems) { + DCHECK([dataTypeItem isKindOfClass:[TableViewClearBrowsingDataItem class]]); + if (dataTypeItem.checked) { + return YES; + } + } + return NO; } @end
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm index a87565f..e6b9cde 100644 --- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -11,7 +11,6 @@ #import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" #import "ios/chrome/browser/ui/settings/cells/account_sign_in_item.h" -#import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" @@ -20,6 +19,7 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_image_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_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_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h" @@ -62,6 +62,7 @@ ItemTypeTextSettingsDetail, ItemTypeLinkFooter, ItemTypeDetailText, + ItemTypeMultiDetailText, ItemTypeAccountSignInItem, ItemTypeSettingsSwitch1, ItemTypeSettingsSwitch2, @@ -265,6 +266,33 @@ [model addItem:textEditItemBothIcons toSectionWithIdentifier:SectionIdentifierText]; + TableViewMultiDetailTextItem* tableViewMultiDetailTextItem = + [[TableViewMultiDetailTextItem alloc] + initWithType:ItemTypeMultiDetailText]; + tableViewMultiDetailTextItem.text = @"Main Text"; + tableViewMultiDetailTextItem.trailingDetailText = @"Trailing Detail Text"; + [model addItem:tableViewMultiDetailTextItem + toSectionWithIdentifier:SectionIdentifierText]; + + tableViewMultiDetailTextItem = [[TableViewMultiDetailTextItem alloc] + initWithType:ItemTypeMultiDetailText]; + tableViewMultiDetailTextItem.text = @"Main Text"; + tableViewMultiDetailTextItem.leadingDetailText = @"Leading Detail Text"; + tableViewMultiDetailTextItem.accessoryType = + UITableViewCellAccessoryDisclosureIndicator; + [model addItem:tableViewMultiDetailTextItem + toSectionWithIdentifier:SectionIdentifierText]; + + tableViewMultiDetailTextItem = [[TableViewMultiDetailTextItem alloc] + initWithType:ItemTypeMultiDetailText]; + tableViewMultiDetailTextItem.text = @"Main Text"; + tableViewMultiDetailTextItem.leadingDetailText = @"Leading Detail Text"; + tableViewMultiDetailTextItem.trailingDetailText = @"Trailing Detail Text"; + tableViewMultiDetailTextItem.accessoryType = + UITableViewCellAccessoryDisclosureIndicator; + [model addItem:tableViewMultiDetailTextItem + toSectionWithIdentifier:SectionIdentifierText]; + // SectionIdentifierSettings. TableViewTextHeaderFooterItem* settingsHeader = [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeTextHeader]; @@ -326,32 +354,6 @@ [model setHeader:autofillHeader forSectionWithIdentifier:SectionIdentifierAutofill]; - AutofillDataItem* autofillItemWithMainLeading = - [[AutofillDataItem alloc] initWithType:ItemTypeAutofillData]; - autofillItemWithMainLeading.text = @"Main Text"; - autofillItemWithMainLeading.trailingDetailText = @"Trailing Detail Text"; - [model addItem:autofillItemWithMainLeading - toSectionWithIdentifier:SectionIdentifierAutofill]; - - AutofillDataItem* autofillItemWithLeading = - [[AutofillDataItem alloc] initWithType:ItemTypeAutofillData]; - autofillItemWithLeading.text = @"Main Text"; - autofillItemWithLeading.leadingDetailText = @"Leading Detail Text"; - autofillItemWithLeading.accessoryType = - UITableViewCellAccessoryDisclosureIndicator; - [model addItem:autofillItemWithLeading - toSectionWithIdentifier:SectionIdentifierAutofill]; - - AutofillDataItem* autofillItemWithAllTexts = - [[AutofillDataItem alloc] initWithType:ItemTypeAutofillData]; - autofillItemWithAllTexts.text = @"Main Text"; - autofillItemWithAllTexts.leadingDetailText = @"Leading Detail Text"; - autofillItemWithAllTexts.trailingDetailText = @"Trailing Detail Text"; - autofillItemWithAllTexts.accessoryType = - UITableViewCellAccessoryDisclosureIndicator; - [model addItem:autofillItemWithAllTexts - toSectionWithIdentifier:SectionIdentifierAutofill]; - CopiedToChromeItem* copiedToChrome = [[CopiedToChromeItem alloc] initWithType:ItemTypeAutofillData]; [model addItem:copiedToChrome
diff --git a/ios/chrome/browser/ui/table_view/cells/BUILD.gn b/ios/chrome/browser/ui/table_view/cells/BUILD.gn index a559b47..024e579 100644 --- a/ios/chrome/browser/ui/table_view/cells/BUILD.gn +++ b/ios/chrome/browser/ui/table_view/cells/BUILD.gn
@@ -24,6 +24,8 @@ "table_view_item.mm", "table_view_link_header_footer_item.h", "table_view_link_header_footer_item.mm", + "table_view_multi_detail_text_item.h", + "table_view_multi_detail_text_item.mm", "table_view_text_button_item.h", "table_view_text_button_item.mm", "table_view_text_edit_item.h", @@ -70,6 +72,7 @@ "table_view_header_footer_item_unittest.mm", "table_view_image_item_unittest.mm", "table_view_item_unittest.mm", + "table_view_multi_detail_text_item_unittest.mm", "table_view_text_button_item_unittest.mm", "table_view_text_edit_item_unittest.mm", "table_view_text_header_footer_item_unittest.mm",
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h new file mode 100644 index 0000000..22d06d7 --- /dev/null +++ b/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h
@@ -0,0 +1,36 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_MULTI_DETAIL_TEXT_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_MULTI_DETAIL_TEXT_ITEM_H_ + +#include <string> + +#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" + +// TableViewMultiDetailTextItem contains the model data for a +// TableViewMultiDetailTextCell. +@interface TableViewMultiDetailTextItem : TableViewItem + +// Main text to be displayed. +@property(nonatomic, copy) NSString* text; +// Leading detail text to be displayed. +@property(nonatomic, copy) NSString* leadingDetailText; +// Trailing detail text to be displayed. +@property(nonatomic, copy) NSString* trailingDetailText; + +@end + +// TableViewCell that displays two leading text labels on top of each other and +// one trailing text label. The leading text labels are displayed on an +// unlimited number of lines. +@interface TableViewMultiDetailTextCell : TableViewCell + +@property(nonatomic, readonly, strong) UILabel* textLabel; +@property(nonatomic, readonly, strong) UILabel* leadingDetailTextLabel; +@property(nonatomic, readonly, strong) UILabel* trailingDetailTextLabel; + +@end + +#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_TABLE_VIEW_MULTI_DETAIL_TEXT_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/autofill_data_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.mm similarity index 90% rename from ios/chrome/browser/ui/settings/cells/autofill_data_item.mm rename to ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.mm index a08af56..87229ffc 100644 --- a/ios/chrome/browser/ui/settings/cells/autofill_data_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.mm
@@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h" -#import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" @@ -18,19 +17,19 @@ const CGFloat kCompressionResistanceAdditionalPriority = 1; } // namespace -@implementation AutofillDataItem +@implementation TableViewMultiDetailTextItem - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; if (self) { - self.cellClass = [AutofillDataCell class]; + self.cellClass = [TableViewMultiDetailTextCell class]; } return self; } #pragma mark - TableViewItem -- (void)configureCell:(AutofillDataCell*)cell +- (void)configureCell:(TableViewMultiDetailTextCell*)cell withStyler:(ChromeTableViewStyler*)styler { [super configureCell:cell withStyler:styler]; cell.textLabel.text = self.text; @@ -40,13 +39,13 @@ @end -#pragma mark - AutofillDataCell +#pragma mark - TableViewMultiDetailTextCell -@interface AutofillDataCell () +@interface TableViewMultiDetailTextCell () @property(nonatomic, strong) UIStackView* mainLabelsContainer; @end -@implementation AutofillDataCell +@implementation TableViewMultiDetailTextCell @synthesize textLabel = _textLabel; @@ -98,12 +97,12 @@ [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; _leadingDetailTextLabel.adjustsFontForContentSizeCategory = YES; _leadingDetailTextLabel.textColor = - UIColorFromRGB(kSettingsCellsDetailTextColor); + UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); _trailingDetailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; _trailingDetailTextLabel.textColor = - UIColorFromRGB(kSettingsCellsDetailTextColor); + UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); } // Sets constraints on subviews.
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item_unittest.mm b/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item_unittest.mm new file mode 100644 index 0000000..acd8568 --- /dev/null +++ b/ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item_unittest.mm
@@ -0,0 +1,49 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h" + +#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "testing/gtest_mac.h" +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using TableViewMultiDetailTextItemTest = PlatformTest; + +// Tests that the UILabels are set properly after a call to |configureCell:|. +TEST_F(TableViewMultiDetailTextItemTest, TextLabels) { + TableViewMultiDetailTextItem* item = + [[TableViewMultiDetailTextItem alloc] initWithType:0]; + NSString* mainText = @"Main text"; + NSString* leadingDetailText = @"Leading detail text"; + NSString* trailingDetailText = @"Trailing detail text"; + + item.text = mainText; + item.leadingDetailText = leadingDetailText; + item.trailingDetailText = trailingDetailText; + item.accessoryType = UITableViewCellAccessoryCheckmark; + + id cell = [[[item cellClass] alloc] init]; + ASSERT_TRUE([cell isMemberOfClass:[TableViewMultiDetailTextCell class]]); + + TableViewMultiDetailTextCell* TableViewMultiDetailTextCell = cell; + EXPECT_FALSE(TableViewMultiDetailTextCell.textLabel.text); + EXPECT_FALSE(TableViewMultiDetailTextCell.leadingDetailTextLabel.text); + EXPECT_FALSE(TableViewMultiDetailTextCell.trailingDetailTextLabel.text); + EXPECT_EQ(UITableViewCellAccessoryNone, + TableViewMultiDetailTextCell.accessoryType); + + [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]]; + EXPECT_NSEQ(mainText, TableViewMultiDetailTextCell.textLabel.text); + EXPECT_NSEQ(leadingDetailText, + TableViewMultiDetailTextCell.leadingDetailTextLabel.text); + EXPECT_NSEQ(trailingDetailText, + TableViewMultiDetailTextCell.trailingDetailTextLabel.text); + EXPECT_EQ(UITableViewCellAccessoryCheckmark, + TableViewMultiDetailTextCell.accessoryType); +}
diff --git a/ios/chrome/test/earl_grey/eg_tests_hook.mm b/ios/chrome/test/earl_grey/eg_tests_hook.mm index 9479f067..57a3cee 100644 --- a/ios/chrome/test/earl_grey/eg_tests_hook.mm +++ b/ios/chrome/test/earl_grey/eg_tests_hook.mm
@@ -18,10 +18,6 @@ return true; } -bool DisableContextualSearch() { - return true; -} - bool DisableFirstRun() { return true; }
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn index cb7e4a2..92265228 100644 --- a/ipc/BUILD.gn +++ b/ipc/BUILD.gn
@@ -7,8 +7,8 @@ import("//ipc/features.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//testing/test.gni") -import("//tools/ipc_fuzzer/ipc_fuzzer.gni") import("//third_party/protobuf/proto_library.gni") +import("//tools/ipc_fuzzer/ipc_fuzzer.gni") buildflag_header("ipc_buildflags") { header = "ipc_buildflags.h" @@ -88,6 +88,7 @@ ":mojom", ":native_handle_type_converters", ":param_traits", + "//base/util/type-safety", "//mojo/public/cpp/base", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system",
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index a1b58cd..4e28d4b0 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h
@@ -35,6 +35,7 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/util/type-safety/id_type.h" #include "build/build_config.h" #include "ipc/ipc_message_start.h" #include "ipc/ipc_param_traits.h" @@ -1032,6 +1033,28 @@ } }; +// base/util types ParamTraits + +template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> +struct ParamTraits<util::IdType<TypeMarker, WrappedType, kInvalidValue>> { + using param_type = util::IdType<TypeMarker, WrappedType, kInvalidValue>; + static void Write(base::Pickle* m, const param_type& p) { + WriteParam(m, p.GetUnsafeValue()); + } + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* r) { + WrappedType value; + if (!ReadParam(m, iter, &value)) + return false; + *r = param_type::FromUnsafeValue(value); + return true; + } + static void Log(const param_type& p, std::string* l) { + LogParam(p.GetUnsafeValue(), l); + } +}; + // IPC types ParamTraits ------------------------------------------------------- // A ChannelHandle is basically a platform-inspecific wrapper around the
diff --git a/media/learning/impl/learning_session_impl_unittest.cc b/media/learning/impl/learning_session_impl_unittest.cc index 2cb878a1..d69ec98 100644 --- a/media/learning/impl/learning_session_impl_unittest.cc +++ b/media/learning/impl/learning_session_impl_unittest.cc
@@ -100,6 +100,13 @@ task_1_.name = "task_1"; } + ~LearningSessionImplTest() override { + // To prevent a memory leak, reset the session. This will post destruction + // of other objects, so RunUntilIdle(). + session_.reset(); + scoped_task_environment_.RunUntilIdle(); + } + base::test::ScopedTaskEnvironment scoped_task_environment_; scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/media/learning/impl/learning_task_controller_helper_unittest.cc b/media/learning/impl/learning_task_controller_helper_unittest.cc index de756f0c..bda756f 100644 --- a/media/learning/impl/learning_task_controller_helper_unittest.cc +++ b/media/learning/impl/learning_task_controller_helper_unittest.cc
@@ -47,6 +47,13 @@ id_ = base::UnguessableToken::Create(); } + ~LearningTaskControllerHelperTest() override { + // To prevent a memory leak, reset the helper. This will post destruction + // of other objects, so RunUntilIdle(). + helper_.reset(); + scoped_task_environment_.RunUntilIdle(); + } + void CreateClient(bool include_fp) { // Create the fake feature provider, and get a pointer to it. base::SequenceBound<FakeFeatureProvider> sb_fp;
diff --git a/media/learning/impl/learning_task_controller_impl_unittest.cc b/media/learning/impl/learning_task_controller_impl_unittest.cc index e1620c0..9daec3ae 100644 --- a/media/learning/impl/learning_task_controller_impl_unittest.cc +++ b/media/learning/impl/learning_task_controller_impl_unittest.cc
@@ -108,6 +108,13 @@ task_.min_new_data_fraction = 0.1; } + ~LearningTaskControllerImplTest() override { + // To prevent a memory leak, reset the controller. This may post + // destruction of other objects, so RunUntilIdle(). + controller_.reset(); + scoped_task_environment_.RunUntilIdle(); + } + void CreateController(SequenceBoundFeatureProvider feature_provider = SequenceBoundFeatureProvider()) { std::unique_ptr<FakeDistributionReporter> reporter =
diff --git a/media/test/pipeline_integration_perftest.cc b/media/test/pipeline_integration_perftest.cc index 8c1383ee..95c2979 100644 --- a/media/test/pipeline_integration_perftest.cc +++ b/media/test/pipeline_integration_perftest.cc
@@ -81,6 +81,13 @@ RunVideoPlaybackBenchmark("bear-vp9.webm", "clockless_video_playback_vp9"); } +#if BUILDFLAG(ENABLE_AV1_DECODER) +TEST(PipelineIntegrationPerfTest, AV1PlaybackBenchmark) { + RunVideoPlaybackBenchmark("bear-av1-640x480.webm", + "clockless_video_playback_av1"); +} +#endif + #if BUILDFLAG(USE_PROPRIETARY_CODECS) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) TEST(PipelineIntegrationPerfTest, MP4PlaybackBenchmark) { RunVideoPlaybackBenchmark("bear_silent.mp4", "clockless_video_playback_mp4");
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.cc b/mojo/public/cpp/bindings/lib/validation_errors.cc index 5e03848..75c556e 100644 --- a/mojo/public/cpp/bindings/lib/validation_errors.cc +++ b/mojo/public/cpp/bindings/lib/validation_errors.cc
@@ -94,12 +94,16 @@ } } -void ReportValidationErrorForMessage( - mojo::Message* message, - ValidationError error, - const char* description) { +void ReportValidationErrorForMessage(mojo::Message* message, + ValidationError error, + const char* interface_name, + unsigned int method_ordinal, + bool is_response) { + std::string description = + base::StringPrintf("%s.%d %s", interface_name, method_ordinal, + is_response ? " response" : ""); ValidationContext validation_context(nullptr, 0, 0, 0, message, description); - ReportValidationError(&validation_context, error, description); + ReportValidationError(&validation_context, error, description.c_str()); } ScopedSuppressValidationErrorLoggingForTests
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.h b/mojo/public/cpp/bindings/lib/validation_errors.h index 9967e58..ddb9872 100644 --- a/mojo/public/cpp/bindings/lib/validation_errors.h +++ b/mojo/public/cpp/bindings/lib/validation_errors.h
@@ -87,7 +87,9 @@ COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) void ReportValidationErrorForMessage(mojo::Message* message, ValidationError error, - const char* description = nullptr); + const char* interface_name, + unsigned int method_ordinal, + bool is_response); // This class may be used by tests to suppress validation error logging. This is // not thread-safe and must only be instantiated on the main thread with no
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl index 5ce6aa11..1793ea6 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -5,7 +5,7 @@ {%- set proxy_name = interface.name ~ "Proxy" %} {%- set namespace_as_string = "%s"|format(namespace|replace(".","::")) %} -{%- macro alloc_params(struct, params, message, description) %} +{%- macro alloc_params(struct, params, message, method_number, is_response) %} mojo::internal::SerializationContext serialization_context; serialization_context.TakeHandlesFromMessage({{message}}); bool success = true; @@ -18,7 +18,7 @@ ReportValidationErrorForMessage( {{message}}, mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED, - "{{description}} deserializer"); + {{class_name}}::Name_, {{method_number}}, {{is_response}}); return false; } {%- endmacro %} @@ -304,7 +304,7 @@ message->mutable_payload()); {%- set desc = class_name~"::"~method.name~" response" %} - {{alloc_params(method.response_param_struct, "params", "message", desc)}} + {{alloc_params(method.response_param_struct, "params", "message", method.sequential_ordinal, "true")}} if (!callback_.is_null()) std::move(callback_).Run({{pass_params(method.response_parameters)}}); return true; @@ -376,7 +376,7 @@ message->mutable_payload()); {%- set desc = class_name~"::"~method.name~" response" %} - {{alloc_params(method.response_param_struct, "params", "message", desc)}} + {{alloc_params(method.response_param_struct, "params", "message", method.sequential_ordinal, "true")}} {%- for param in method.response_parameters %} *out_{{param.name}}_ = std::move(p_{{param.name}}); @@ -432,7 +432,7 @@ message->mutable_payload()); {%- set desc = class_name~"::"~method.name %} - {{alloc_params(method.param_struct, "params", "message", desc)| + {{alloc_params(method.param_struct, "params", "message", method.sequential_ordinal, "false")| indent(4)}} // A null |impl| means no implementation was bound. DCHECK(impl); @@ -494,7 +494,7 @@ message->mutable_payload()); {%- set desc = class_name~"::"~method.name %} - {{alloc_params(method.param_struct, "params", "message", desc)| + {{alloc_params(method.param_struct, "params", "message", method.sequential_ordinal, "false")| indent(4)}} {{class_name}}::{{method.name}}Callback callback = {{class_name}}_{{method.name}}_ProxyToResponder::CreateCallback(
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py index 709dd22..fe4fce2 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -111,6 +111,8 @@ for method in interface.methods: if method.ordinal is None: method.ordinal = next_ordinal + # this field is never scrambled + method.sequential_ordinal = next_ordinal next_ordinal = method.ordinal + 1 if method.min_version is not None:
diff --git a/net/base/features.cc b/net/base/features.cc index d47871b..adadfe71 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -7,6 +7,11 @@ namespace net { namespace features { +// Toggles the `Accept-Language` HTTP request header, which +// https://github.com/WICG/lang-client-hint proposes that we deprecate. +const base::Feature kAcceptLanguageHeader{"AcceptLanguageHeader", + base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kCapRefererHeaderLength = { "CapRefererHeaderLength", base::FEATURE_DISABLED_BY_DEFAULT}; const base::FeatureParam<int> kMaxRefererHeaderLength = {
diff --git a/net/base/features.h b/net/base/features.h index e733bc5..d8d320a 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -12,6 +12,10 @@ namespace net { namespace features { +// Toggles the `Accept-Language` HTTP request header, which +// https://github.com/WICG/lang-client-hint proposes that we deprecate. +NET_EXPORT extern const base::Feature kAcceptLanguageHeader; + // Caps the length of the `referer` header to 4k, which should be enough for // anyone. NET_EXPORT extern const base::Feature kCapRefererHeaderLength;
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc index f9bbdd9..366894c 100644 --- a/net/quic/crypto/proof_verifier_chromium.cc +++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -606,6 +606,8 @@ quic::QuicAsyncStatus ProofVerifierChromium::VerifyCertChain( const std::string& hostname, const std::vector<std::string>& certs, + const std::string& ocsp_response, + const std::string& cert_sct, const quic::ProofVerifyContext* verify_context, std::string* error_details, std::unique_ptr<quic::ProofVerifyDetails>* verify_details, @@ -614,6 +616,7 @@ *error_details = "Missing context"; return quic::QUIC_FAILURE; } + // TODO(mattm): use |ocsp_response| and |cert_sct|. const ProofVerifyContextChromium* chromium_context = reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); std::unique_ptr<Job> job = std::make_unique<Job>(
diff --git a/net/quic/crypto/proof_verifier_chromium.h b/net/quic/crypto/proof_verifier_chromium.h index abadc17..8581056b 100644 --- a/net/quic/crypto/proof_verifier_chromium.h +++ b/net/quic/crypto/proof_verifier_chromium.h
@@ -93,6 +93,8 @@ quic::QuicAsyncStatus VerifyCertChain( const std::string& hostname, const std::vector<std::string>& certs, + const std::string& ocsp_response, + const std::string& cert_sct, const quic::ProofVerifyContext* verify_context, std::string* error_details, std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
diff --git a/net/quic/crypto/proof_verifier_chromium_test.cc b/net/quic/crypto/proof_verifier_chromium_test.cc index 7d60c11..f1c498f 100644 --- a/net/quic/crypto/proof_verifier_chromium_test.cc +++ b/net/quic/crypto/proof_verifier_chromium_test.cc
@@ -1004,8 +1004,9 @@ std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); quic::QuicAsyncStatus status = proof_verifier.VerifyCertChain( - kTestHostname, certs_, verify_context_.get(), &error_details_, &details_, - std::move(callback)); + kTestHostname, certs_, /*ocsp_response=*/std::string(), + /*cert_sct=*/std::string(), verify_context_.get(), &error_details_, + &details_, std::move(callback)); ASSERT_EQ(quic::QUIC_SUCCESS, status); ASSERT_TRUE(details_.get());
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index 61ab684..9b1f589 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -264,6 +264,7 @@ verify_callback_->Cancel(); } + // TODO(mattm): pass |ocsp_response| and |cert_sct|. // Starts verification of certs cached in the |crypto_config|. quic::QuicAsyncStatus Run(quic::QuicCryptoClientConfig* crypto_config, CompletionOnceCallback callback) { @@ -273,7 +274,9 @@ auto* verify_callback_ptr = verify_callback.get(); quic::QuicAsyncStatus status = crypto_config->proof_verifier()->VerifyCertChain( - server_id_.host(), cached->certs(), verify_context_.get(), + server_id_.host(), cached->certs(), + /*ocsp_response=*/std::string(), + /*cert_sct=*/std::string(), verify_context_.get(), &verify_error_details_, &verify_details_, std::move(verify_callback)); if (status == quic::QUIC_PENDING) {
diff --git a/net/tools/quic/quic_simple_client_bin.cc b/net/tools/quic/quic_simple_client_bin.cc index 7faa33ac..eb6eb3e 100644 --- a/net/tools/quic/quic_simple_client_bin.cc +++ b/net/tools/quic/quic_simple_client_bin.cc
@@ -123,6 +123,8 @@ quic::QuicAsyncStatus VerifyCertChain( const std::string& hostname, const std::vector<std::string>& certs, + const std::string& ocsp_response, + const std::string& cert_sct, const quic::ProofVerifyContext* verify_context, std::string* error_details, std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 1412493..fc50628 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -607,7 +607,8 @@ // specified. std::string accept_language = http_user_agent_settings_->GetAcceptLanguage(); - if (!accept_language.empty()) { + if (base::FeatureList::IsEnabled(features::kAcceptLanguageHeader) && + !accept_language.empty()) { request_info_.extra_headers.SetHeaderIfMissing( HttpRequestHeaders::kAcceptLanguage, accept_language);
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index f86be86..7cd8f393 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -66,6 +66,14 @@ token_service_->AddObserver(this); account_tracker_service_->AddObserver(this); gaia_cookie_manager_service_->AddObserver(this); + + // Seed the primary account with any state that |signin_manager_| loaded from + // prefs. + if (signin_manager_->IsAuthenticated()) { + CoreAccountInfo account = signin_manager_->GetAuthenticatedAccountInfo(); + DCHECK(!account.account_id.empty()); + primary_account_ = std::move(account); + } } IdentityManager::~IdentityManager() { @@ -81,16 +89,30 @@ gaia_cookie_manager_service_->RemoveObserver(this); } +// TODO(862619) change return type to base::Optional<CoreAccountInfo> CoreAccountInfo IdentityManager::GetPrimaryAccountInfo() const { - return signin_manager_->GetAuthenticatedAccountInfo(); + DCHECK_EQ(primary_account_.has_value(), signin_manager_->IsAuthenticated()); + auto result = primary_account_.value_or(CoreAccountInfo()); + DCHECK_EQ(result.account_id, signin_manager_->GetAuthenticatedAccountId()); +#if DCHECK_IS_ON() + CoreAccountInfo signin_manager_account = + signin_manager_->GetAuthenticatedAccountInfo(); + if (!signin_manager_account.account_id.empty()) { + DCHECK_EQ(signin_manager_account, result) + << "If signin_manager_'s account is set (account has a refresh token), " + "primary_account_ must have the same value."; + } +#endif + return result; } -const std::string& IdentityManager::GetPrimaryAccountId() const { - return signin_manager_->GetAuthenticatedAccountId(); +std::string IdentityManager::GetPrimaryAccountId() const { + return GetPrimaryAccountInfo().account_id; } bool IdentityManager::HasPrimaryAccount() const { - return signin_manager_->IsAuthenticated(); + DCHECK_EQ(primary_account_.has_value(), signin_manager_->IsAuthenticated()); + return primary_account_.has_value(); } std::vector<CoreAccountInfo> IdentityManager::GetAccountsWithRefreshTokens() @@ -339,7 +361,7 @@ // TODO(https://crbug.com/944012): Unify the firing of this observer // notification between ChromeOS and other platforms. - FireOnPrimaryAccountSetNotification(GetPrimaryAccountInfo()); + FireOnPrimaryAccountSetNotification(primary_account_.value()); } #endif @@ -471,6 +493,14 @@ observer.OnPrimaryAccountCleared(account_info); } } +void IdentityManager::AuthenticatedAccountSet(const AccountInfo& account_info) { + DCHECK(signin_manager_->IsAuthenticated()); + primary_account_ = account_info; +} +void IdentityManager::AuthenticatedAccountCleared() { + DCHECK(!signin_manager_->IsAuthenticated()); + primary_account_.reset(); +} void IdentityManager::OnRefreshTokenAvailable(const std::string& account_id) { CoreAccountInfo account_info = @@ -569,6 +599,9 @@ } void IdentityManager::OnAccountUpdated(const AccountInfo& info) { + if (primary_account_ && primary_account_->account_id == info.account_id) { + primary_account_ = info; + } for (auto& observer : observer_list_) { observer.OnExtendedAccountInfoUpdated(info); }
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index ce490af..b6f9c8d1 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -204,21 +204,14 @@ // Provides access to the core information of the user's primary account. // Returns an empty struct if no such info is available, either because there - // is no primary account or because the extended information for the primary - // account has been removed (this happens when the refresh token is revoked, - // for example). + // is no primary account yet or because the user signed out. CoreAccountInfo GetPrimaryAccountInfo() const; - // Provides access to the account ID of the user's primary account. Note that - // this may return a valid string even in cases where GetPrimaryAccountInfo() - // returns an empty struct, as the extended information for the primary - // account is removed on certain events (e.g., when its refresh token is - // revoked). - const std::string& GetPrimaryAccountId() const; + // Provides access to the account ID of the user's primary account. Simple + // convenience wrapper over GetPrimaryAccountInfo().account_id. + std::string GetPrimaryAccountId() const; - // Returns whether the primary account is available. Simple convenience - // wrapper over checking whether GetPrimaryAccountId() returns a non-empty - // string. + // Returns whether the user's primary account is available. bool HasPrimaryAccount() const; // Provides the information of all accounts that have refresh tokens. @@ -530,6 +523,10 @@ // order to drive its behavior. // TODO(https://crbug.com/943135): Find a better way to accomplish this. friend IdentityManagerTest; + FRIEND_TEST_ALL_PREFIXES(IdentityManagerTest, + PrimaryAccountInfoAfterSigninAndAccountRemoval); + FRIEND_TEST_ALL_PREFIXES(IdentityManagerTest, + PrimaryAccountInfoAfterSigninAndRefreshTokenRemoval); FRIEND_TEST_ALL_PREFIXES(IdentityManagerTest, RemoveAccessTokenFromCache); FRIEND_TEST_ALL_PREFIXES(IdentityManagerTest, CreateAccessTokenFetcherWithCustomURLLoaderFactory); @@ -592,6 +589,8 @@ // SigninManagerBase::Observer: void GoogleSigninSucceeded(const AccountInfo& account_info) override; void GoogleSignedOut(const AccountInfo& account_info) override; + void AuthenticatedAccountSet(const AccountInfo& account_info) override; + void AuthenticatedAccountCleared() override; // OAuth2TokenService::Observer: void OnRefreshTokenAvailable(const std::string& account_id) override; @@ -658,6 +657,8 @@ base::ObserverList<DiagnosticsObserver, true>::Unchecked diagnostics_observer_list_; + base::Optional<CoreAccountInfo> primary_account_; + DISALLOW_COPY_AND_ASSIGN(IdentityManager); };
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 49d3405..abe3516 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -440,24 +440,27 @@ EXPECT_EQ(primary_account_id, primary_account_info.account_id); } -// Test that the primary account's ID remains tracked by the IdentityManager -// after signing in even after having removed the account without signing out. -TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSigninAndAccountRemoval) { +// Test that the primary account's core info remains tracked by the +// IdentityManager after signing in even after having removed the refresh token +// without signing out. +TEST_F(IdentityManagerTest, + PrimaryAccountInfoAfterSigninAndRefreshTokenRemoval) { ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT); // First ensure that the user is signed in from the POV of the // IdentityManager. SetPrimaryAccount(identity_manager(), kTestEmail); - // Remove the account from the AccountTrackerService and check that - // the returned AccountInfo won't have a valid ID anymore, even if - // the IdentityManager is still storing the primary account's ID. - account_tracker()->RemoveAccount(kTestGaiaId); + identity_manager()->account_fetcher_service_->EnableAccountRemovalForTest(); + // Revoke the primary's account credentials from the token service and + // check that the returned CoreAccountInfo is still valid since the + // identity_manager stores it. + token_service()->RevokeCredentials(identity_manager()->GetPrimaryAccountId()); CoreAccountInfo primary_account_info = identity_manager()->GetPrimaryAccountInfo(); - EXPECT_EQ("", primary_account_info.gaia); - EXPECT_EQ("", primary_account_info.email); - EXPECT_EQ("", primary_account_info.account_id); + EXPECT_EQ(kTestGaiaId, primary_account_info.gaia); + EXPECT_EQ(kTestEmail, primary_account_info.email); + EXPECT_EQ(kTestGaiaId, primary_account_info.account_id); std::string primary_account_id = identity_manager()->GetPrimaryAccountId(); EXPECT_EQ(primary_account_id, kTestGaiaId);
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 28af9a1f..b5771b7e 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -677,15 +677,11 @@ void NetworkContext::CreateURLLoaderFactory( mojom::URLLoaderFactoryRequest request, mojom::URLLoaderFactoryParamsPtr params) { - scoped_refptr<ResourceSchedulerClient> resource_scheduler_client; - if (params->process_id != mojom::kBrowserProcessId) { - // Zero process ID means it's from the browser process and we don't want - // to throttle the requests. - resource_scheduler_client = base::MakeRefCounted<ResourceSchedulerClient>( - params->process_id, ++current_resource_scheduler_client_id_, - resource_scheduler_.get(), - url_request_context_->network_quality_estimator()); - } + scoped_refptr<ResourceSchedulerClient> resource_scheduler_client = + base::MakeRefCounted<ResourceSchedulerClient>( + params->process_id, ++current_resource_scheduler_client_id_, + resource_scheduler_.get(), + url_request_context_->network_quality_estimator()); CreateURLLoaderFactory(std::move(request), std::move(params), std::move(resource_scheduler_client)); }
diff --git a/services/network/resource_scheduler.cc b/services/network/resource_scheduler.cc index bfc7818b..72ef082 100644 --- a/services/network/resource_scheduler.cc +++ b/services/network/resource_scheduler.cc
@@ -34,6 +34,7 @@ #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/network_context.mojom.h" #include "url/scheme_host_port.h" namespace network { @@ -362,10 +363,12 @@ // Each client represents a tab. class ResourceScheduler::Client : public net::EffectiveConnectionTypeObserver { public: - Client(net::NetworkQualityEstimator* network_quality_estimator, + Client(bool is_browser_client, + net::NetworkQualityEstimator* network_quality_estimator, ResourceScheduler* resource_scheduler, const base::TickClock* tick_clock) - : in_flight_delayable_count_(0), + : is_browser_client_(is_browser_client), + in_flight_delayable_count_(0), total_layout_blocking_count_(0), num_skipped_scans_due_to_scheduled_start_(0), network_quality_estimator_(network_quality_estimator), @@ -801,6 +804,10 @@ ShouldStartReqResult ShouldStartRequest( ScheduledResourceRequestImpl* request) const { + // Currently, browser initiated requests are not throttled. + if (is_browser_client_) + return START_REQUEST; + if (!resource_scheduler_->enabled()) return START_REQUEST; @@ -989,6 +996,10 @@ // is enabled. RequestQueue pending_requests_; RequestSet in_flight_requests_; + + // True if |this| client is created for browser initiated requests. + const bool is_browser_client_; + // The number of delayable in-flight requests. size_t in_flight_delayable_count_; // The number of layout-blocking in-flight requests. @@ -1096,7 +1107,8 @@ DCHECK(!base::ContainsKey(client_map_, client_id)); client_map_[client_id] = - std::make_unique<Client>(network_quality_estimator, this, tick_clock_); + std::make_unique<Client>(child_id == mojom::kBrowserProcessId, + network_quality_estimator, this, tick_clock_); } void ResourceScheduler::OnClientDeleted(int child_id, int route_id) {
diff --git a/services/network/resource_scheduler_unittest.cc b/services/network/resource_scheduler_unittest.cc index e2a06e6..519990c 100644 --- a/services/network/resource_scheduler_unittest.cc +++ b/services/network/resource_scheduler_unittest.cc
@@ -36,6 +36,7 @@ #include "net/url_request/url_request.h" #include "net/url_request/url_request_test_util.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/network_context.mojom.h" #include "services/network/resource_scheduler_params_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -85,6 +86,8 @@ const int kRouteId2 = 67; const int kBackgroundChildId = 35; const int kBackgroundRouteId = 43; +const int kBrowserChildId = mojom::kBrowserProcessId; +const int kBrowserRouteId = 1; const size_t kMaxNumDelayableRequestsPerHostPerClient = 6; @@ -182,6 +185,8 @@ &network_quality_estimator_); scheduler_->OnClientCreated(kBackgroundChildId, kBackgroundRouteId, &network_quality_estimator_); + scheduler_->OnClientCreated(kBrowserChildId, kBrowserRouteId, + &network_quality_estimator_); } ResourceSchedulerParamsManager FixedParamsManager( @@ -205,6 +210,7 @@ if (scheduler_) { scheduler_->OnClientDeleted(kChildId, kRouteId); scheduler_->OnClientDeleted(kBackgroundChildId, kBackgroundRouteId); + scheduler_->OnClientDeleted(kBrowserChildId, kBrowserRouteId); } } @@ -251,6 +257,13 @@ kBackgroundRouteId); } + std::unique_ptr<TestRequest> NewBrowserRequest( + const char* url, + net::RequestPriority priority) { + return NewRequestWithChildAndRoute(url, priority, kBrowserChildId, + kBrowserRouteId); + } + std::unique_ptr<TestRequest> NewSyncRequest(const char* url, net::RequestPriority priority) { return NewSyncRequestWithChildAndRoute(url, priority, kChildId, kRouteId); @@ -689,6 +702,35 @@ EXPECT_TRUE(idle->started()); } +// Verify that browser requests are not throttled by the resource scheduler. +TEST_F(ResourceSchedulerTest, LowerPriorityBrowserRequestsNotThrottled) { + SetMaxDelayableRequests(1); + // Dummies to enforce scheduling. + std::unique_ptr<TestRequest> high( + NewBrowserRequest("http://host/high", net::HIGHEST)); + std::unique_ptr<TestRequest> low( + NewBrowserRequest("http://host/low", net::LOWEST)); + + std::unique_ptr<TestRequest> request( + NewBrowserRequest("http://host/req", net::LOWEST)); + std::unique_ptr<TestRequest> idle( + NewBrowserRequest("http://host/idle", net::IDLE)); + EXPECT_TRUE(request->started()); + EXPECT_TRUE(idle->started()); + + const int kDefaultMaxNumDelayableRequestsPerClient = + 10; // Should match the .cc. + + // Create more requests than kDefaultMaxNumDelayableRequestsPerClient. All + // requests should be started immediately. + std::vector<std::unique_ptr<TestRequest>> lows; + for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient + 1; ++i) { + string url = "http://host" + base::NumberToString(i) + "/low"; + lows.push_back(NewBrowserRequest(url.c_str(), net::LOWEST)); + EXPECT_TRUE(lows.back()->started()); + } +} + TEST_F(ResourceSchedulerTest, ReprioritizedRequestGoesToBackOfQueue) { // Dummies to enforce scheduling. SetMaxDelayableRequests(1);
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 83f1bde..5b576c76 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -766,6 +766,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -3356,6 +3399,50 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "KTU84Z", + "device_type": "flo", + "os": "Android" + } + ], + "expiration": 10800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -5969,6 +6056,50 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY48I", + "device_type": "hammerhead", + "os": "Android" + } + ], + "expiration": 10800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -8582,6 +8713,54 @@ }, { "args": [ + "--enable-features=NetworkService,NetworkServiceInProcess", + "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter", + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "network_service_webview_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "name": "network_service_webview_instrumentation_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY48I", + "device_type": "hammerhead", + "os": "Android" + } + ], + "expiration": 10800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "shards": 20 + }, + "test": "webview_instrumentation_test_apk" + }, + { + "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], @@ -8770,6 +8949,50 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY49B", + "device_type": "flo", + "os": "Android" + } + ], + "expiration": 10800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -11425,6 +11648,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -13981,6 +14247,53 @@ }, { "args": [ + "--enable-features=NetworkService,NetworkServiceInProcess", + "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter", + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "network_service_webview_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "name": "network_service_webview_instrumentation_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "shards": 20 + }, + "test": "webview_instrumentation_test_apk" + }, + { + "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices" ], @@ -14168,6 +14481,50 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MRA58Z", + "device_type": "flo", + "os": "Android" + } + ], + "expiration": 10800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -18832,6 +19189,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -21520,6 +21920,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
diff --git a/testing/buildbot/chromium.chrome.json b/testing/buildbot/chromium.chrome.json index 253f7e6..1753530 100644 --- a/testing/buildbot/chromium.chrome.json +++ b/testing/buildbot/chromium.chrome.json
@@ -153,6 +153,23 @@ } ] }, + "test": "base_util_unittests" + }, + { + "experiment_percentage": 100, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04", + "pool": "chrome.tests" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index cd60a9e..a61afa9 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -722,6 +722,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -2311,6 +2326,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index 195cb080..5be3748 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -91,6 +91,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -1435,6 +1450,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -3032,6 +3063,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -4557,6 +4604,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -7224,6 +7314,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -9776,6 +9909,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -11154,6 +11302,24 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -12729,6 +12895,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -14066,6 +14247,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -15421,6 +15617,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -16759,6 +16970,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -18114,6 +18340,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -19426,6 +19667,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -20425,6 +20676,19 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -21431,6 +21695,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -22421,6 +22695,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -23432,6 +23716,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -24443,6 +24737,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -25490,6 +25794,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -27071,6 +27391,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -28652,6 +28988,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -30197,6 +30549,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -31208,6 +31570,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -32219,6 +32591,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -33230,6 +33612,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -34241,6 +34633,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -35282,6 +35684,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -36634,6 +37051,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index bfaf61d..b7baddf 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -56,6 +56,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -2421,6 +2431,16 @@ "swarming": { "can_use_on_swarming_builders": false }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": false + }, "test": "blink_common_unittests" }, { @@ -5847,6 +5867,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -6526,6 +6561,24 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--enable-blink-features=HeapConcurrentMarking" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -7319,6 +7372,24 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--enable-blink-features=HeapUnifiedGarbageCollection" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -8103,6 +8174,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -8885,6 +8971,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -10468,6 +10570,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -12022,6 +12140,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -13661,6 +13794,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -19141,6 +19290,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -20802,6 +20966,23 @@ ], "expiration": 21600 }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.14.5" + } + ], + "expiration": 21600 + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 54ef9b40..b50ca26e 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -4640,6 +4640,58 @@ "--build-revision", "${got_revision}", "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=android-chromium", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "android", + "--build-revision", + "${got_revision}", + "--test-machine-name", "${buildername}" ], "isolate_name": "telemetry_gpu_integration_test", @@ -6331,6 +6383,59 @@ "isolated_scripts": [ { "args": [ + "pixel", + "--show-stdout", + "--browser=android-chromium", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "android", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "P", + "device_type": "walleye", + "os": "Android", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ "webgl_conformance", "--show-stdout", "--browser=android-chromium", @@ -15886,6 +15991,57 @@ "--build-revision", "${got_revision}", "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "mac", + "--build-revision", + "${got_revision}", + "--test-machine-name", "${buildername}" ], "isolate_name": "telemetry_gpu_integration_test", @@ -17401,6 +17557,59 @@ "--build-revision", "${got_revision}", "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "hidpi": "1", + "os": "Mac-10.13.6", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "mac", + "--build-revision", + "${got_revision}", + "--test-machine-name", "${buildername}" ], "isolate_name": "telemetry_gpu_integration_test", @@ -18785,7 +18994,62 @@ } ] }, - "Optional Android Release (Nexus 5X)": {}, + "Optional Android Release (Nexus 5X)": { + "isolated_scripts": [ + { + "args": [ + "pixel", + "--show-stdout", + "--browser=android-chromium", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "android", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + } + ] + }, "Optional Linux Release (Intel HD 630)": { "gtest_tests": [ { @@ -19543,6 +19807,57 @@ }, { "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "mac", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ "trace_test", "--show-stdout", "--browser=release", @@ -19742,6 +20057,59 @@ }, { "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "mac", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "hidpi": "1", + "os": "Mac-10.13.6", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ "trace_test", "--show-stdout", "--browser=release", @@ -20266,6 +20634,58 @@ }, { "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "win", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "intel-hd-630-win10-stable", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ "power", "--show-stdout", "--browser=release", @@ -20947,6 +21367,67 @@ }, { "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "win", + "--build-revision", + "${got_revision}", + "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "nvidia-quadro-p400-win10-stable", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"nvidia-quadro-p400-win10-stable\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } + }, + { + "args": [ "trace_test", "--show-stdout", "--browser=release", @@ -24475,6 +24956,58 @@ "--build-revision", "${got_revision}", "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "intel-hd-630-win10-stable", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "win", + "--build-revision", + "${got_revision}", + "--test-machine-name", "${buildername}" ], "isolate_name": "telemetry_gpu_integration_test", @@ -26544,6 +27077,67 @@ "--build-revision", "${got_revision}", "--test-machine-name", + "${buildername}", + "--use-skia-gold" + ], + "experiment_percentage": 100, + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_test", + "non_precommit_args": [ + "--upload-refimg-to-cloud-storage" + ], + "precommit_args": [ + "--download-refimg-from-cloud-storage", + "--review-patch-issue", + "${patch_issue}", + "--review-patch-set", + "${patch_set}", + "--buildbucket-build-id", + "${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "nvidia-quadro-p400-win10-stable", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ], + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"nvidia-quadro-p400-win10-stable\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", + "--dont-restore-color-profile-after-test", + "--refimg-cloud-storage-bucket", + "chromium-gpu-archive/reference-images", + "--os-type", + "win", + "--build-revision", + "${got_revision}", + "--test-machine-name", "${buildername}" ], "isolate_name": "telemetry_gpu_integration_test",
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index fa43d56..b1c22ed 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -50,6 +50,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -807,6 +822,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -2163,6 +2193,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -3807,6 +3852,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -5405,6 +5465,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -6923,6 +6998,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -8737,6 +8828,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 8f2bdac7..f6602a4 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -91,6 +91,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.10" + } + ] + }, "test": "blink_common_unittests" }, { @@ -1579,6 +1595,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.11" + } + ] + }, "test": "blink_common_unittests" }, { @@ -3067,6 +3099,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0a2e", + "os": "Mac-10.12.6" + } + ] + }, "test": "blink_common_unittests" }, { @@ -4600,6 +4648,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.13.6" + } + ] + }, "test": "blink_common_unittests" }, { @@ -6123,6 +6187,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.13.6" + } + ] + }, "test": "blink_common_unittests" }, { @@ -7615,6 +7695,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "none", + "os": "Mac-10.13.6" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 642300e..a3686805 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -142,6 +142,49 @@ "--bucket", "chromium-result-details", "--test-name", + "base_util_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "base_util_unittests" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", "blink_common_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -2754,6 +2797,24 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -4409,6 +4470,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -5823,6 +5899,24 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -7572,6 +7666,25 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -9351,6 +9464,25 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -10997,6 +11129,24 @@ } ] }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, { @@ -12509,6 +12659,19 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -13654,6 +13817,21 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index a185fa8..d9b8915 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -88,6 +88,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -1296,6 +1306,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -3077,6 +3103,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ] + }, "test": "blink_common_unittests" }, { @@ -4894,6 +4936,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, { @@ -6079,6 +6131,16 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "base_util_unittests" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index d34bf44..b6dd89f 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -268,6 +268,10 @@ "label": "//base:base_unittests", "type": "console_test_launcher", }, + "base_util_unittests": { + "label": "//base/util:base_util_unittests", + "type": "console_test_launcher", + }, "bdict_fuzzer": { "label": "//third_party/hunspell:bdict_fuzzer", "type": "fuzzer", @@ -452,6 +456,9 @@ "captured_sites_interactive_tests": { "label": "//chrome/test:captured_sites_interactive_tests", "type": "windowed_test_launcher", + "args": [ + '--disable-extensions', + ], }, "capture_unittests": { "label": "//media/capture:capture_unittests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 1c594d2..eda4f12f 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1001,6 +1001,23 @@ }, }, }, + 'network_service_webview_instrumentation_test_apk': { + # Only run these on the phone testers for now due to capacity. + 'remove_from': [ + # chromium.android + 'android-kitkat-arm-rel', + 'android-marshmallow-arm64-rel', + 'KitKat Tablet Tester', + 'Lollipop Tablet Tester', + 'Marshmallow Tablet Tester', + 'KitKat Phone Tester (dbg)', + # chromium.memory + 'Android CFI', + # chromium.clang + 'ToTAndroid', + 'ToTAndroidCFI', + ], + }, 'non_network_service_browser_tests': { 'modifications': { # chromium.chromiumos
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 3191f61..aa7abbd 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -2150,6 +2150,7 @@ 'chromium_gtests': { 'angle_unittests': {}, 'base_unittests': {}, + 'base_util_unittests': {}, 'blink_common_unittests': {}, 'blink_heap_unittests': {}, 'blink_platform_unittests': {}, @@ -3762,18 +3763,6 @@ ], 'test': 'components_browsertests', }, - 'network_service_webview_instrumentation_test_apk': { - 'swarming': { - 'shards': 20, - }, - 'args': [ - # TODO(crbug.com/882650): WebView currently does not support running network - # service OOP. - '--enable-features=NetworkService,NetworkServiceInProcess', - '--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter', - ], - 'test': 'webview_instrumentation_test_apk', - }, 'network_service_in_process_content_browsertests': { 'args': [ '--enable-features=NetworkService,NetworkServiceInProcess', @@ -3832,6 +3821,18 @@ ], 'test': 'content_shell_test_apk', }, + 'network_service_webview_instrumentation_test_apk': { + 'swarming': { + 'shards': 20, + }, + 'args': [ + # TODO(crbug.com/882650): WebView currently does not support running network + # service OOP. + '--enable-features=NetworkService,NetworkServiceInProcess', + '--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter', + ], + 'test': 'webview_instrumentation_test_apk', + }, }, 'network_service_fyi_gtests': { @@ -4715,6 +4716,11 @@ 'gpu_fyi_and_optional_non_linux_gtests', ], + 'gpu_fyi_android_webgl2_and_gold_telemetry_tests': [ + 'gpu_telemetry_tests_for_skia_gold_testing', + 'gpu_webgl2_conformance_telemetry_tests', + ], + 'gpu_fyi_linux_debug_gtests': [ 'gpu_angle_end2end_gtests', 'gpu_angle_unit_gtests', @@ -4772,6 +4778,16 @@ 'gpu_swiftshader_gtests', ], + # TODO(https://crbug.com/850107): Merge this back into + # gpu_fyi_mac_release_telemetry_tests once Gold is stabilized. + 'gpu_fyi_mac_release_gold_telemetry_tests': [ + 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', + 'gpu_webgl2_conformance_telemetry_tests', + 'gpu_webgl_conformance_telemetry_tests', + ], + 'gpu_fyi_mac_release_gtests': [ 'gpu_angle_end2end_gtests', 'gpu_angle_unit_gtests', @@ -4790,6 +4806,14 @@ 'gpu_webgl_conformance_telemetry_tests', ], + # TODO(https://crbug.com/850107): Merge this back into + # gpu_fyi_optional_telemetry_tests once Gold is stabilized. + 'gpu_fyi_optional_gold_telemetry_tests': [ + 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', + 'gpu_webgl2_conformance_telemetry_tests', + ], + 'gpu_fyi_optional_linux_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', 'gpu_telemetry_tests_for_skia_gold_testing', @@ -4878,6 +4902,22 @@ 'gpu_win_specific_gtests', ], + # TODO(https://crbug.com/850107): Merge this back into + # gpu_fyi_win_intel_release_telemetry_tests once Gold is stabilized. + 'gpu_fyi_win_intel_release_gold_telemetry_tests': [ + 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', + 'gpu_webgl2_conformance_d3d11_validating_telemetry_tests', + 'gpu_webgl2_conformance_gl_passthrough_telemetry_tests', + 'gpu_webgl2_conformance_telemetry_tests', + 'gpu_webgl_conformance_d3d9_passthrough_telemetry_tests', + 'gpu_webgl_conformance_gl_passthrough_telemetry_tests', + 'gpu_webgl_conformance_telemetry_tests', + 'gpu_webgl_conformance_vulkan_passthrough_telemetry_tests', + 'gpu_win_intel_specific_telemetry_tests', + ], + 'gpu_fyi_win_intel_release_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', 'gpu_telemetry_tests', @@ -4901,6 +4941,22 @@ 'gpu_swiftshader_gtests', ], + # TODO(https://crbug.com/850107): Merge this back into + # gpu_fyi_win_release_telemetry_tests once Gold is stabilized. + 'gpu_fyi_win_release_gold_telemetry_tests': [ + 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', + 'gpu_webgl2_conformance_gl_passthrough_telemetry_tests', + 'gpu_webgl2_conformance_telemetry_tests', + 'gpu_webgl_conformance_d3d11_validating_telemetry_tests', + 'gpu_webgl_conformance_d3d9_passthrough_telemetry_tests', + 'gpu_webgl_conformance_d3d9_validating_telemetry_tests', + 'gpu_webgl_conformance_gl_passthrough_telemetry_tests', + 'gpu_webgl_conformance_telemetry_tests', + 'gpu_webgl_conformance_vulkan_passthrough_telemetry_tests', + ], + 'gpu_fyi_win_release_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', 'gpu_telemetry_tests', @@ -4914,6 +4970,16 @@ 'gpu_webgl_conformance_vulkan_passthrough_telemetry_tests', ], + # TODO(https://crbug.com/850107): Merge this back into + # gpu_fyi_mac_release_telemetry_tests once Gold is stabilized. + 'gpu_nexus5x_gold_telemetry_tests': [ + 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', + 'gpu_webgl_conformance_gles_passthrough_telemetry_tests', + 'gpu_webgl_conformance_telemetry_tests', + ], + 'gpu_nexus5x_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', 'gpu_telemetry_tests', @@ -4923,6 +4989,7 @@ 'gpu_optional_win_intel_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', 'gpu_webgl2_conformance_telemetry_tests', 'gpu_webgl_conformance_d3d9_passthrough_telemetry_tests', 'gpu_webgl_conformance_gl_passthrough_telemetry_tests', @@ -4933,6 +5000,7 @@ 'gpu_optional_win_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', + 'gpu_telemetry_tests_for_skia_gold_testing', 'gpu_webgl2_conformance_telemetry_tests', 'gpu_webgl_conformance_d3d11_validating_telemetry_tests', 'gpu_webgl_conformance_d3d9_passthrough_telemetry_tests',
diff --git a/testing/buildbot/tryserver.chromium.linux.json b/testing/buildbot/tryserver.chromium.linux.json index 354605b..b7ee03b 100644 --- a/testing/buildbot/tryserver.chromium.linux.json +++ b/testing/buildbot/tryserver.chromium.linux.json
@@ -97,6 +97,22 @@ } ] }, + "test": "base_util_unittests" + }, + { + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ] + }, "test": "blink_common_unittests" }, {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 102cf638..95d4ef0 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2487,7 +2487,7 @@ 'test_suites': { 'gtest_tests': 'gpu_fyi_android_and_mac_gtests', 'isolated_scripts': 'gpu_angle_perf_isolated_scripts', - 'gpu_telemetry_tests': 'gpu_nexus5x_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_nexus5x_gold_telemetry_tests', 'android_webview_gpu_telemetry_tests': 'android_webview_gpu_telemetry_tests', }, }, @@ -2548,7 +2548,7 @@ 'test_suites': { # We currently only want to run the WebGL 2.0 conformance tests on # this until additional Pixel 2 capacity is added. - 'gpu_telemetry_tests': 'gpu_webgl2_conformance_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_android_webgl2_and_gold_telemetry_tests', }, }, 'Android FYI dEQP Release (Nexus 5X)': { @@ -2896,7 +2896,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_fyi_mac_release_gtests', - 'gpu_telemetry_tests': 'gpu_fyi_mac_release_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_mac_release_gold_telemetry_tests', 'isolated_scripts': 'rendering_representative_perf_tests_isolated_scripts', }, }, @@ -2930,7 +2930,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_fyi_mac_release_gtests', - 'gpu_telemetry_tests': 'gpu_fyi_mac_release_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_mac_release_gold_telemetry_tests', 'isolated_scripts': 'rendering_representative_perf_tests_isolated_scripts', }, }, @@ -2981,15 +2981,21 @@ }, # BEGIN Fake builder used as mirror targets for Optional GPU tryservers 'Optional Android Release (Nexus 5X)': { + 'browser_config': 'android-chromium', 'os_type': 'android', 'mixins': [ 'marshmallow', 'bullhead', ], - # No tests run on this bot right now; they are all running on the main - # android_n5x_swarming_rel bot. We should get the WebGL 2.0 conformance - # tests running on this bot, similarly to how they run on the optional - # desktop trybots. + # No normal tests run on this bot right now; they are all running on the + # main android_n5x_swarming_rel bot. We should get the WebGL 2.0 + # conformance tests running on this bot, similarly to how they run on + # the optional desktop trybots. + # The Gold telemetry tests are currently run here to test stability + # before rolling out to the main Android bots. + 'test_suites': { + 'gpu_telemetry_tests': 'gpu_telemetry_tests_for_skia_gold_testing', + } }, 'Optional Linux Release (Intel HD 630)': { 'os_type': 'linux', @@ -3022,7 +3028,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_fyi_mac_optional_gtests', - 'gpu_telemetry_tests': 'gpu_fyi_optional_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_optional_gold_telemetry_tests', }, }, 'Optional Mac Retina Release (AMD)': { @@ -3033,7 +3039,7 @@ ], 'test_suites': { 'gtest_tests': 'gpu_fyi_mac_optional_gtests', - 'gpu_telemetry_tests': 'gpu_fyi_optional_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_optional_gold_telemetry_tests', }, }, 'Optional Mac Retina Release (NVIDIA)': { @@ -3155,7 +3161,7 @@ 'test_suites': { 'gtest_tests': 'gpu_fyi_win_gtests', 'isolated_scripts': 'gpu_angle_and_representative_perf_fyi_isolated_scripts', - 'gpu_telemetry_tests': 'gpu_fyi_win_intel_release_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_win_intel_release_gold_telemetry_tests', }, }, 'Win10 FYI Release (NVIDIA GeForce GTX 1660)': { @@ -3181,7 +3187,7 @@ 'test_suites': { 'gtest_tests': 'gpu_fyi_win_gtests', 'isolated_scripts': 'gpu_angle_fyi_win_optional_and_representative_perf_isolated_scripts', - 'gpu_telemetry_tests': 'gpu_fyi_win_release_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_fyi_win_release_gold_telemetry_tests', }, # We keep this value enabled to provide minimal regression testing. 'use_multi_dimension_trigger_script': True,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index ae9abf43..7d3499a 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1962,28 +1962,6 @@ ] } ], - "ExploreOnContent": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "ExploreOnContent", - "params": { - "availability": "any", - "event_trigger": "name:explore_on_content_iph_trigger;comparator:==0;window:680;storage:680", - "event_used": "name:contextual_suggestions_opened;comparator:<1;window:680;storage:680", - "session_rate": "<1" - }, - "enable_features": [ - "ContextualSuggestionsButton", - "IPH_ContextualSuggestions" - ] - } - ] - } - ], "ExploreSites InitialCountries": [ { "platforms": [ @@ -4431,6 +4409,25 @@ ] } ], + "ScriptStreamingOnPreload": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ScriptStreamingOnPreload" + ] + } + ] + } + ], "SearchEnginePromo": [ { "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore index 8cf1f21..2f1abc9c 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -166,7 +166,6 @@ /nss /objenesis/lib/ /omaha/src/omaha -/openmax_dl/ /openh264/src /openscreen/src /ow2_asm/lib/
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index ca20e7e8..3b387d8 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -62,6 +62,10 @@ const base::Feature kBlinkGenPropertyTrees{"BlinkGenPropertyTrees", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enable Display Locking JavaScript APIs. +const base::Feature kDisplayLocking{"DisplayLocking", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enable applying rounded corner masks via a GL shader rather than // a mask layer. const base::Feature kFastBorderRadius{"FastBorderRadius",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index d2213d3..3ad8f922 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -26,6 +26,7 @@ BLINK_COMMON_EXPORT extern const base::Feature kImplicitRootScroller; BLINK_COMMON_EXPORT extern const base::Feature kJankTrackingSweepLine; BLINK_COMMON_EXPORT extern const base::Feature kBlinkGenPropertyTrees; +BLINK_COMMON_EXPORT extern const base::Feature kDisplayLocking; BLINK_COMMON_EXPORT extern const base::Feature kFastBorderRadius; BLINK_COMMON_EXPORT extern const base::Feature kLayoutNG; BLINK_COMMON_EXPORT extern const base::Feature kMixedContentAutoupgrade;
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index e6996e77..b07c1d7 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -302,6 +302,12 @@ Commit(int64 num_errors_handled); }; +union IDBDatabaseGetAllResult { + IDBError error_result; // |error| is reserved, so call this |error_result|. + IDBKey key; + array<IDBReturnValue> values; +}; + interface IDBDatabase { RenameObjectStore(int64 transaction_id, int64 object_store_id, @@ -330,8 +336,8 @@ int64 index_id, IDBKeyRange key_range, bool key_only, - int64 max_count, - associated IDBCallbacks callbacks); + int64 max_count) + => (IDBDatabaseGetAllResult result); SetIndexKeys(int64 transaction_id, int64 object_store_id, IDBKey primary_key,
diff --git a/third_party/blink/public/mojom/page/spatial_navigation.mojom b/third_party/blink/public/mojom/page/spatial_navigation.mojom index 5ba1859..51538fc 100644 --- a/third_party/blink/public/mojom/page/spatial_navigation.mojom +++ b/third_party/blink/public/mojom/page/spatial_navigation.mojom
@@ -14,6 +14,8 @@ // True if the currently focused element is a form element, and there is a // next form element available to move to. bool has_next_form_element; + // True if the video element has default controls and the element is focused. + bool has_default_video_controls; }; // Mojo service for browser exposing Spatial Navigation state to the browser. @@ -21,4 +23,4 @@ // Called when the Spatial Navigation state has changed. Null if Spatial // Navigation has been disabled. SpatialNavigationStateChanged(SpatialNavigationState? state); -}; \ No newline at end of file +};
diff --git a/third_party/blink/public/mojom/service_worker/service_worker.mojom b/third_party/blink/public/mojom/service_worker/service_worker.mojom index 6bf1896..f6da6ec 100644 --- a/third_party/blink/public/mojom/service_worker/service_worker.mojom +++ b/third_party/blink/public/mojom/service_worker/service_worker.mojom
@@ -114,6 +114,19 @@ ServiceWorkerObjectInfo? source_info_for_service_worker; }; +// Indicates whether a service worker has a fetch event handler. The presence +// of the fetch event handler is determined when the service worker finishes +// installing. +// TODO(crbug.com/945505): Convert enum constants to kUnknown style. +enum FetchHandlerExistence { + // The service worker has not yet finished installing. + UNKNOWN, + // The service worker finished installing and added a fetch event handler. + EXISTS, + // The service worker finished installing without a fetch event handler. + DOES_NOT_EXIST, +}; + // The number of seconds for which a 'push' event should be allowed to run. // This is not in the spec but for a Chrome-specific timeout. Each // event dispatched to service workers has a 5 minute timeout in the Chrome @@ -154,7 +167,8 @@ // service worker does not start until this message is received. InitializeGlobalScope( associated ServiceWorkerHost service_worker_host, - ServiceWorkerRegistrationObjectInfo registration_info); + ServiceWorkerRegistrationObjectInfo registration_info, + FetchHandlerExistence fetch_handler_existence); DispatchInstallEvent() => (ServiceWorkerEventStatus status, bool has_fetch_handler);
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 415b6b3..d766d0c7 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2293,6 +2293,7 @@ kV8RTCRtpReceiver_JitterBufferDelayHint_AttributeSetter = 2887, kMediaCapabilitiesDecodingInfoWithKeySystemConfig = 2888, kRevertInCustomIdent = 2889, + kUnoptimizedImagePolicies = 2890, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 6a731be..811a2cea 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -239,6 +239,7 @@ BLINK_PLATFORM_EXPORT static void EnableSkipTouchEventFilter(bool); BLINK_PLATFORM_EXPORT static void EnableStaleWhileRevalidate(bool); BLINK_PLATFORM_EXPORT static void EnableSmsReceiver(bool); + BLINK_PLATFORM_EXPORT static void EnableDisplayLocking(bool); private: WebRuntimeFeatures();
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h index af7d4c2..22a4dd3 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
@@ -35,6 +35,7 @@ #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" #include "third_party/blink/public/common/messaging/transferable_message.h" #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-shared.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-shared.h" #include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h" #include "third_party/blink/public/platform/web_canonical_cookie.h" @@ -58,12 +59,16 @@ // All methods of this class must be called on the worker thread. class WebServiceWorkerContextProxy { public: + using FetchHandlerExistence = mojom::FetchHandlerExistence; + virtual ~WebServiceWorkerContextProxy() = default; virtual void BindServiceWorkerHost( mojo::ScopedInterfaceEndpointHandle service_worker_host) = 0; virtual void SetRegistration(WebServiceWorkerRegistrationObjectInfo) = 0; + virtual void SetFetchHandlerExistence( + FetchHandlerExistence fetch_handler_existence) = 0; // Script evaluation does not start until this function is called. virtual void ReadyToEvaluateScript() = 0;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index dfc009f..870c292 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -862,6 +862,9 @@ v8::Isolate*) { return v8::Local<v8::Object>(); } + + // Transfers user activation state from |source_frame| to the current frame. + virtual void TransferUserActivationFrom(WebLocalFrame* source_frame) {} }; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc b/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc index 096a4c1..df646b2 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
@@ -170,7 +170,8 @@ // Visitor overrides. void Visit(const TraceWrapperV8Reference<v8::Value>&) final; void Visit(void*, TraceDescriptor) final; - void VisitBackingStoreStrongly(void* object, + void VisitBackingStoreStrongly(const char*, + void* object, void** object_slot, TraceDescriptor desc) final; @@ -179,12 +180,13 @@ void** object_slot, TraceDescriptor desc, WeakCallback callback) final {} - void VisitBackingStoreWeakly(void*, + void VisitBackingStoreWeakly(const char*, + void*, void**, TraceDescriptor, WeakCallback, void*) final {} - void VisitBackingStoreOnly(void*, void**) final {} + void VisitBackingStoreOnly(const char*, void*, void**) final {} void RegisterBackingStoreCallback(void**, MovingObjectCallback, void*) final { } void RegisterWeakCallback(void*, WeakCallback) final {} @@ -558,7 +560,8 @@ } } -void V8EmbedderGraphBuilder::VisitBackingStoreStrongly(void* object, +void V8EmbedderGraphBuilder::VisitBackingStoreStrongly(const char*, + void* object, void** object_slot, TraceDescriptor desc) { if (!object)
diff --git a/third_party/blink/renderer/config.gni b/third_party/blink/renderer/config.gni index cc53ed2..a90c2cdd 100644 --- a/third_party/blink/renderer/config.gni +++ b/third_party/blink/renderer/config.gni
@@ -50,15 +50,6 @@ "Please change your args.gn to use 'blink_symbol_level = 0'. " + "https://crbug.com/943869") -# Whether Android build uses OpenMAX DL FFT. Currently supported only on -# ARMv7+, ARM64, x86 or x64 without webview. -# TODO(crbug.com/917355): Remove support for openmax_dl FFT in favor -# of PFFFT -use_openmax_dl_fft = !use_webaudio_pffft && is_android && - (current_cpu == "x86" || current_cpu == "x64" || - (current_cpu == "arm" && arm_version >= 7) || - current_cpu == "arm64" || current_cpu == "mipsel") - # feature_defines_list --------------------------------------------------------- feature_defines_list = [] @@ -79,10 +70,6 @@ feature_defines_list += [ "SUPPORT_WEBGL2_COMPUTE_CONTEXT=1" ] } -if (use_openmax_dl_fft) { - feature_defines_list += [ "WTF_USE_WEBAUDIO_OPENMAX_DL_FFT=1" ] -} - if (use_webaudio_pffft) { feature_defines_list += [ "WTF_USE_WEBAUDIO_PFFFT=1" ] }
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 1834a80..01b448dd 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -39,9 +39,6 @@ config("core_include_dirs") { include_dirs = [] - if (is_android && use_openmax_dl_fft) { - include_dirs += [ "//third_party/openmax_dl" ] - } } import("//build/config/pch.gni") @@ -139,10 +136,6 @@ "//third_party/blink/renderer:config", "//third_party/blink/renderer:inside_blink", ] - - if (use_openmax_dl_fft) { - deps += [ "//third_party/openmax_dl/dl" ] - } } # Note that this is a source set rather than a group, even though it has no
diff --git a/third_party/blink/renderer/core/css/css_syntax_descriptor.cc b/third_party/blink/renderer/core/css/css_syntax_descriptor.cc index 7047533..de46461 100644 --- a/third_party/blink/renderer/core/css/css_syntax_descriptor.cc +++ b/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
@@ -17,6 +17,28 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { +namespace { + +// The 'revert' and 'default' keywords are reserved. +// +// https://drafts.csswg.org/css-cascade/#default +// https://drafts.csswg.org/css-values-4/#identifier-value +// +// TODO(crbug.com/579788): Implement 'revert'. +// TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>. +bool IsReservedIdentToken(const CSSParserToken& token) { + if (token.GetType() != kIdentToken) + return false; + return css_property_parser_helpers::IsRevertKeyword(token.Value()) || + css_property_parser_helpers::IsDefaultKeyword(token.Value()); +} + +bool CouldConsumeReservedKeyword(CSSParserTokenRange range) { + range.ConsumeWhitespace(); + if (IsReservedIdentToken(range.ConsumeIncludingWhitespace())) + return range.AtEnd(); + return false; +} const CSSValue* ConsumeSingleType(const CSSSyntaxComponent& syntax, CSSParserTokenRange& range, @@ -61,6 +83,10 @@ case CSSSyntaxType::kTransformList: return ConsumeTransformList(range, *context); case CSSSyntaxType::kCustomIdent: + // TODO(crbug.com/579788): Implement 'revert'. + // TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>. + if (IsReservedIdentToken(range.Peek())) + return nullptr; return ConsumeCustomIdent(range, *context); default: NOTREACHED(); @@ -99,6 +125,8 @@ return result; } +} // namespace + const CSSSyntaxComponent* CSSSyntaxDescriptor::Match( const CSSStyleValue& value) const { for (const CSSSyntaxComponent& component : syntax_components_) { @@ -116,6 +144,10 @@ const CSSParserContext* context, bool is_animation_tainted) const { if (IsTokenStream()) { + // TODO(crbug.com/579788): Implement 'revert'. + // TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>. + if (CouldConsumeReservedKeyword(range)) + return nullptr; return CSSVariableParser::ParseRegisteredPropertyValue( range, *context, false, is_animation_tainted); }
diff --git a/third_party/blink/renderer/core/css/css_syntax_string_parser.cc b/third_party/blink/renderer/core/css/css_syntax_string_parser.cc index 162a315..cb52408f3 100644 --- a/third_party/blink/renderer/core/css/css_syntax_string_parser.cc +++ b/third_party/blink/renderer/core/css/css_syntax_string_parser.cc
@@ -154,7 +154,11 @@ bool CSSSyntaxStringParser::ConsumeIdent(String& ident) { ident = ConsumeName(input_); - return !css_property_parser_helpers::IsCSSWideKeyword(ident); + // TODO(crbug.com/579788): Implement 'revert'. + // TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>. + return !css_property_parser_helpers::IsCSSWideKeyword(ident) && + !css_property_parser_helpers::IsRevertKeyword(ident) && + !css_property_parser_helpers::IsDefaultKeyword(ident); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc index a728cc75..3f0ceaf 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc +++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc
@@ -1742,6 +1742,16 @@ EqualIgnoringASCIICase(keyword, "unset"); } +// https://drafts.csswg.org/css-cascade/#default +bool IsRevertKeyword(StringView keyword) { + return EqualIgnoringASCIICase(keyword, "revert"); +} + +// https://drafts.csswg.org/css-values-4/#identifier-value +bool IsDefaultKeyword(StringView keyword) { + return EqualIgnoringASCIICase(keyword, "default"); +} + // https://drafts.csswg.org/css-shapes-1/#typedef-shape-box CSSIdentifierValue* ConsumeShapeBox(CSSParserTokenRange& range) { return ConsumeIdent<CSSValueID::kContentBox, CSSValueID::kPaddingBox,
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h index e3c86b0..8e0193c 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h +++ b/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h
@@ -135,6 +135,8 @@ CSSValue* ConsumeAxis(CSSParserTokenRange&); bool IsCSSWideKeyword(StringView); +bool IsRevertKeyword(StringView); +bool IsDefaultKeyword(StringView); CSSIdentifierValue* ConsumeShapeBox(CSSParserTokenRange&);
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index fcdea6f..2eb07da 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -1247,6 +1247,12 @@ return web_frame_->UsePrintingLayout(); } +void LocalFrameClientImpl::TransferUserActivationFrom( + LocalFrame* source_frame) { + web_frame_->Client()->TransferUserActivationFrom( + WebLocalFrameImpl::FromFrame(source_frame)); +} + STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kFollow, WebLocalFrameClient::CrossOriginRedirects::kFollow); STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kNavigate,
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 018ca7c..2027470 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -322,6 +322,8 @@ bool UsePrintingLayout() const override; + void TransferUserActivationFrom(LocalFrame* source_frame) override; + private: struct DocumentInterfaceBrokerForwarderTraits { using Interface = mojom::blink::DocumentInterfaceBroker;
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index 0985f8556..43784c3 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -231,6 +231,14 @@ } } + void InjectGestureScrollEvent(const blink::WebFloatSize& delta, + blink::WebScrollGranularity granularity, + cc::ElementId scrollable_area_element_id, + WebInputEvent::Type injected_type) override { + popup_->WidgetClient()->InjectGestureScrollEvent( + delta, granularity, scrollable_area_element_id, injected_type); + } + WebPagePopupImpl* popup_; };
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc b/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc index fbe06af..2e04c91 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc +++ b/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc
@@ -11,6 +11,7 @@ #include "base/metrics/histogram_macros.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/origin_trials/origin_trials.h" #include "third_party/blink/renderer/platform/json/json_values.h" @@ -110,6 +111,16 @@ feature); } + // Detect usage of UnoptimizedImagePolicies origin trial + if (feature == mojom::FeaturePolicyFeature::kOversizedImages || + feature == mojom::FeaturePolicyFeature::kUnoptimizedLossyImages || + feature == mojom::FeaturePolicyFeature::kUnoptimizedLosslessImages || + feature == + mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict) { + UseCounter::Count(execution_context, + mojom::WebFeature::kUnoptimizedImagePolicies); + } + ParsedFeaturePolicyDeclaration allowlist(feature, feature_type); // TODO(loonybear): fallback value should be parsed from the new syntax. allowlist.fallback_value = GetFallbackValueForFeature(feature);
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc b/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc index 15a9333f..0dd34da 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc +++ b/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc
@@ -755,6 +755,38 @@ EXPECT_LE(max_double_value, parsed_policy[0].values.begin()->second); } +// These declarations should each trigger the origin trial use counter. +const char* const kOriginTrialPolicyDeclarations[] = { + "unoptimized-lossy-images", "unoptimized-lossless-images", + "unoptimized-lossless-images-strict", "oversized-images", + "oversized-images; fullscreen", "fullscreen; oversized-images", + "oversized-images 'self'(2.0)", "oversized-images 'none'", + "unoptimized-lossy-images *(0.125)"}; + +TEST_F(FeaturePolicyParserTest, OriginTrialFeatureUseCounter) { + Vector<String> messages; + + // Validate that features which are not in the origin trial do not trigger + // the use counter. + { + auto dummy = std::make_unique<DummyPageHolder>(); + FeaturePolicyParser::ParseHeader("payment; fullscreen", origin_a_.get(), + &messages, &dummy->GetDocument()); + EXPECT_FALSE(UseCounter::IsCounted(dummy->GetDocument(), + WebFeature::kUnoptimizedImagePolicies)); + } + + // Validate that declarations which should trigger the use counter do. + for (const char* declaration : kOriginTrialPolicyDeclarations) { + auto dummy = std::make_unique<DummyPageHolder>(); + FeaturePolicyParser::ParseHeader(declaration, origin_a_.get(), &messages, + &dummy->GetDocument()); + EXPECT_TRUE(UseCounter::IsCounted(dummy->GetDocument(), + WebFeature::kUnoptimizedImagePolicies)) + << declaration << " should trigger the origin trial use counter."; + } +} + // Test policy mutation methods class FeaturePolicyMutationTest : public testing::Test { protected:
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc index ca77b596..a72467e 100644 --- a/third_party/blink/renderer/core/frame/dom_window.cc +++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -498,11 +498,19 @@ // Transfer user activation state in the source's renderer when // |transferUserActivation| is true. + // TODO(lanwei): we should execute the below code after the post task fires + // (for both local and remote posting messages). LocalFrame* source_frame = source->GetFrame(); if (RuntimeEnabledFeatures::UserActivationPostMessageTransferEnabled() && options->transferUserActivation() && LocalFrame::HasTransientUserActivation(source_frame)) { GetFrame()->TransferUserActivationFrom(source_frame); + + // When the source and target frames are in the same process, we need to + // update the user activation state in the browser process. For the cross + // process case, it is handled in RemoteDOMWindow. + if (IsLocalDOMWindow()) + GetFrame()->Client()->TransferUserActivationFrom(source->GetFrame()); } SchedulePostMessage(event, std::move(target), source_document);
diff --git a/third_party/blink/renderer/core/frame/frame_client.h b/third_party/blink/renderer/core/frame/frame_client.h index 5fb93df..92973e9e6 100644 --- a/third_party/blink/renderer/core/frame/frame_client.h +++ b/third_party/blink/renderer/core/frame/frame_client.h
@@ -9,6 +9,7 @@ #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { @@ -38,6 +39,9 @@ virtual base::UnguessableToken GetDevToolsFrameToken() const = 0; + // Transfers user activation state from |source_frame| to the this frame. + virtual void TransferUserActivationFrom(LocalFrame* source_frame) {} + virtual ~FrameClient() = default; virtual void Trace(blink::Visitor* visitor) {}
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h index c37935c..548ed67 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.h +++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -283,7 +283,7 @@ MessageEvent* event, scoped_refptr<UserGestureToken> token, scoped_refptr<const SecurityOrigin> intended_target_origin, - std::unique_ptr<SourceLocation>); + std::unique_ptr<SourceLocation> location); void DispatchMessageEventWithOriginCheck( const SecurityOrigin* intended_target_origin,
diff --git a/third_party/blink/renderer/core/frame/navigator_language.cc b/third_party/blink/renderer/core/frame/navigator_language.cc index 423c8873..174b1a2c 100644 --- a/third_party/blink/renderer/core/frame/navigator_language.cc +++ b/third_party/blink/renderer/core/frame/navigator_language.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/language.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -34,12 +35,21 @@ : context_(context) {} AtomicString NavigatorLanguage::language() { - return AtomicString(languages().front()); + if (RuntimeEnabledFeatures::NavigatorLanguageInInsecureContextEnabled() || + context_->IsSecureContext()) { + return AtomicString(languages().front()); + } + return AtomicString(); } const Vector<String>& NavigatorLanguage::languages() { - EnsureUpdatedLanguage(); - return languages_; + if (RuntimeEnabledFeatures::NavigatorLanguageInInsecureContextEnabled() || + context_->IsSecureContext()) { + EnsureUpdatedLanguage(); + return languages_; + } + DEFINE_STATIC_LOCAL(const Vector<String>, empty_vector, {}); + return empty_vector; } AtomicString NavigatorLanguage::SerializeLanguagesForClientHintHeader() {
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index 56c1fe2..0b79cf8c 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -4086,7 +4086,8 @@ } void HTMLMediaElement::DefaultEventHandler(Event& event) { - if (event.IsKeyboardEvent() && ShouldShowControls()) { + if (event.IsKeyboardEvent() && event.type() == event_type_names::kKeyup && + ShouldShowControls()) { // TODO(bokan): Cleanup magic numbers once https://crbug.com/949766 lands. const int key = static_cast<int>(ToKeyboardEvent(event).KeyEvent()->dom_key);
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 5c9aff8e..6d3fac4a 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -267,6 +267,7 @@ if (has_abstract_inline_text_box_) { for (NGPaintFragment* fragment : NGPaintFragment::InlineFragmentsFor(this)) NGAbstractInlineTextBox::WillDestroy(fragment); + has_abstract_inline_text_box_ = false; } first_paint_fragment_ = first_fragment; } @@ -2413,7 +2414,6 @@ auto fragments = NGPaintFragment::InlineFragmentsFor(this); if (!fragments.IsEmpty() && fragments.IsInLayoutNGInlineFormattingContext()) { - has_abstract_inline_text_box_ = true; return NGAbstractInlineTextBox::GetOrCreate(fragments.front()); } }
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h index 3587282..320eea2 100644 --- a/third_party/blink/renderer/core/layout/layout_text.h +++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -283,6 +283,12 @@ scoped_refptr<AbstractInlineTextBox> FirstAbstractInlineTextBox(); + bool HasAbstractInlineTextBox() const { + return has_abstract_inline_text_box_; + } + + void SetHasAbstractInlineTextBox() { has_abstract_inline_text_box_ = true; } + float HyphenWidth(const Font&, TextDirection); LayoutRect DebugRect() const override;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc index 0a93d493..a55d61b 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
@@ -26,12 +26,15 @@ new FragmentToNGAbstractInlineTextBoxHashMap(); } const auto it = g_abstract_inline_text_box_map_->find(&fragment); - if (it != g_abstract_inline_text_box_map_->end()) + LayoutText* const layout_text = ToLayoutText(fragment.GetLayoutObject()); + if (it != g_abstract_inline_text_box_map_->end()) { + CHECK(layout_text->HasAbstractInlineTextBox()); return it->value; - scoped_refptr<AbstractInlineTextBox> obj = - base::AdoptRef(new NGAbstractInlineTextBox( - LineLayoutText(ToLayoutText(fragment.GetLayoutObject())), fragment)); + } + scoped_refptr<AbstractInlineTextBox> obj = base::AdoptRef( + new NGAbstractInlineTextBox(LineLayoutText(layout_text), fragment)); g_abstract_inline_text_box_map_->Set(&fragment, obj); + layout_text->SetHasAbstractInlineTextBox(); return obj; }
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc index 20d9256..bededd32 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -18,6 +18,7 @@ #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/core/html/media/html_video_element.h" #include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/layout/hit_test_location.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" @@ -136,6 +137,10 @@ } } +bool IsFocused(Element* element) { + return element && element->IsFocused(); +} + } // namespace SpatialNavigationController::SpatialNavigationController(Page& page) @@ -527,6 +532,7 @@ change |= UpdateCanExitFocus(element); change |= UpdateCanSelectInterestedElement(element); change |= UpdateHasNextFormElement(element); + change |= UpdateHasDefaultVideoControls(element); if (change) OnSpatialNavigationStateChanged(); } @@ -539,7 +545,7 @@ } bool SpatialNavigationController::UpdateCanExitFocus(Element* element) { - bool can_exit_focus = element && element->IsFocused(); + bool can_exit_focus = IsFocused(element); if (can_exit_focus == spatial_navigation_state_->can_exit_focus) return false; spatial_navigation_state_->can_exit_focus = can_exit_focus; @@ -559,7 +565,7 @@ bool SpatialNavigationController::UpdateHasNextFormElement(Element* element) { bool has_next_form_element = - element && element->IsFocused() && + IsFocused(element) && page_->GetFocusController().NextFocusableElementInForm( element, kWebFocusTypeForward); if (has_next_form_element == spatial_navigation_state_->has_next_form_element) @@ -569,6 +575,20 @@ return true; } +bool SpatialNavigationController::UpdateHasDefaultVideoControls( + Element* element) { + bool has_default_video_controls = + IsFocused(element) && IsHTMLVideoElement(element) && + ToHTMLVideoElement(element)->ShouldShowControls(); + if (has_default_video_controls == + spatial_navigation_state_->has_default_video_controls) { + return false; + } + spatial_navigation_state_->has_default_video_controls = + has_default_video_controls; + return true; +} + const mojom::blink::SpatialNavigationHostPtr& SpatialNavigationController::GetSpatialNavigationHost() { if (!spatial_navigation_host_.is_bound()) {
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.h b/third_party/blink/renderer/core/page/spatial_navigation_controller.h index b1a794f..05ee39d 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.h +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.h
@@ -97,6 +97,7 @@ bool UpdateCanExitFocus(Element* element); bool UpdateCanSelectInterestedElement(Element* element); bool UpdateHasNextFormElement(Element* element); + bool UpdateHasDefaultVideoControls(Element* element); const mojom::blink::SpatialNavigationHostPtr& GetSpatialNavigationHost();
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc index 454fde5..3855338 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
@@ -106,7 +106,7 @@ mojom::blink::IDBKeyRangePtr key_range, bool key_only, int64_t max_count, - mojom::blink::IDBCallbacksAssociatedPtrInfo callbacks) override {} + mojom::blink::IDBDatabase::GetAllCallback callback) override {} void SetIndexKeys(int64_t transaction_id, int64_t object_store_id, std::unique_ptr<::blink::IDBKey> primary_key,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc index 2bf55755..99ed64c 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_dispatcher.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -87,7 +88,8 @@ const IDBKeyRange* key_range, int64_t max_count, bool key_only, - WebIDBCallbacks* callbacks) { + WebIDBCallbacks* callbacks_ptr) { + std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id, nullptr); mojom::blink::IDBKeyRangePtr key_range_ptr = @@ -95,7 +97,31 @@ callbacks->SetState(nullptr, transaction_id); database_->GetAll(transaction_id, object_store_id, index_id, std::move(key_range_ptr), key_only, max_count, - GetCallbacksProxy(base::WrapUnique(callbacks))); + WTF::Bind(&WebIDBDatabaseImpl::GetAllCallback, + WTF::Unretained(this), std::move(callbacks))); +} + +void WebIDBDatabaseImpl::GetAllCallback( + std::unique_ptr<WebIDBCallbacks> callbacks, + mojom::blink::IDBDatabaseGetAllResultPtr result) { + if (result->is_error_result()) { + callbacks->Error(result->get_error_result()->error_code, + std::move(result->get_error_result()->error_message)); + callbacks.reset(); + return; + } + + if (result->is_key()) { + callbacks->SuccessKey(std::move(result->get_key())); + callbacks.reset(); + return; + } + + if (result->is_values()) { + callbacks->SuccessArray(std::move(result->get_values())); + callbacks.reset(); + return; + } } void WebIDBDatabaseImpl::SetIndexKeys(int64_t transaction_id,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h index f1679741..9003813 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h
@@ -60,6 +60,8 @@ int64_t max_count, bool key_only, WebIDBCallbacks*) override; + void GetAllCallback(std::unique_ptr<WebIDBCallbacks> callbacks, + mojom::blink::IDBDatabaseGetAllResultPtr result); void SetIndexKeys(int64_t transaction_id, int64_t object_store_id, std::unique_ptr<IDBKey> primary_key,
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc index 40ece3a..bb5a4ce 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc
@@ -52,6 +52,8 @@ quic::QuicAsyncStatus VerifyCertChain( const std::string& hostname, const std::vector<std::string>& certs, + const std::string& ocsp_response, + const std::string& cert_sct, const quic::ProofVerifyContext* context, std::string* error_details, std::unique_ptr<quic::ProofVerifyDetails>* details,
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc index 18d5a29..1ed70eb 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc
@@ -367,6 +367,8 @@ quic::QuicAsyncStatus VerifyCertChain( const std::string& hostname, const std::vector<std::string>& certs, + const std::string& ocsp_response, + const std::string& cert_sct, const quic::ProofVerifyContext* context, std::string* error_details, std::unique_ptr<quic::ProofVerifyDetails>* details,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index ef55de12..3180109 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -536,6 +536,16 @@ GetExecutionContext(), std::move(info)); } +void ServiceWorkerGlobalScope::SetFetchHandlerExistence( + FetchHandlerExistence fetch_handler_existence) { + DCHECK(IsContextThread()); + if (fetch_handler_existence == FetchHandlerExistence::EXISTS && + base::FeatureList::IsEnabled( + features::kServiceWorkerIsolateInForeground)) { + GetThread()->GetIsolate()->IsolateInForegroundNotification(); + } +} + ServiceWorker* ServiceWorkerGlobalScope::GetOrCreateServiceWorker( WebServiceWorkerObjectInfo info) { if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId) @@ -581,11 +591,6 @@ return; } - if (base::FeatureList::IsEnabled( - features::kServiceWorkerIsolateInForeground)) { - GetThread()->GetIsolate()->IsolateInForegroundNotification(); - } - WorkerGlobalScope::EvaluateClassicScriptInternal(script_url, source_code, std::move(cached_meta_data)); }
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index abb6f36e..7bef808 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -64,6 +64,8 @@ DEFINE_WRAPPERTYPEINFO(); public: + using FetchHandlerExistence = mojom::FetchHandlerExistence; + static ServiceWorkerGlobalScope* Create( ServiceWorkerThread*, std::unique_ptr<GlobalScopeCreationParams>, @@ -138,6 +140,7 @@ void BindServiceWorkerHost(mojom::blink::ServiceWorkerHostAssociatedPtrInfo); void SetRegistration(WebServiceWorkerRegistrationObjectInfo info); + void SetFetchHandlerExistence(FetchHandlerExistence fetch_handler_existence); // Returns the ServiceWorker object described by the given info. Creates a new // object if needed, or else returns the existing one.
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc index e6a6b107..31da8c6 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -189,6 +189,11 @@ WorkerGlobalScope()->SetRegistration(std::move(info)); } +void ServiceWorkerGlobalScopeProxy::SetFetchHandlerExistence( + FetchHandlerExistence fetch_handler_existence) { + WorkerGlobalScope()->SetFetchHandlerExistence(fetch_handler_existence); +} + void ServiceWorkerGlobalScopeProxy::ReadyToEvaluateScript() { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); WorkerGlobalScope()->ReadyToEvaluateScript();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h index ae29495..c2ff4b0 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -83,6 +83,8 @@ void BindServiceWorkerHost( mojo::ScopedInterfaceEndpointHandle service_worker_host) override; void SetRegistration(WebServiceWorkerRegistrationObjectInfo info) override; + void SetFetchHandlerExistence( + FetchHandlerExistence fetch_handler_existence) override; // Must be called after the above BindServiceWorkerHost() and // SetRegistration() got called. void ReadyToEvaluateScript() override;
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 75681221..208e7f3 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -316,7 +316,6 @@ "animation/compositor_transform_operations.h", "animation/timing_function.cc", "animation/timing_function.h", - "audio/android/fft_frame_open_maxdl_android.cc", "audio/audio_array.h", "audio/audio_bus.cc", "audio/audio_bus.h", @@ -1552,10 +1551,6 @@ include_dirs += [ "//third_party/ffmpeg" ] deps += [ "//third_party/ffmpeg" ] } - if (use_openmax_dl_fft) { - include_dirs += [ "//third_party/openmax_dl" ] - deps += [ "//third_party/openmax_dl/dl" ] - } if (use_webaudio_pffft) { include_dirs += [ "//third_party/pffft/src" ] deps += [ "//third_party/pffft" ]
diff --git a/third_party/blink/renderer/platform/audio/android/fft_frame_open_maxdl_android.cc b/third_party/blink/renderer/platform/audio/android/fft_frame_open_maxdl_android.cc deleted file mode 100644 index 304295a..0000000 --- a/third_party/blink/renderer/platform/audio/android/fft_frame_open_maxdl_android.cc +++ /dev/null
@@ -1,160 +0,0 @@ -/* Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "build/build_config.h" - -#if defined(OS_ANDROID) && defined(WTF_USE_WEBAUDIO_OPENMAX_DL_FFT) - -#include "third_party/blink/renderer/platform/audio/fft_frame.h" - -#include <dl/sp/api/armSP.h> -#include <dl/sp/api/omxSP.h> -#include "third_party/blink/renderer/platform/audio/audio_array.h" -#include "third_party/blink/renderer/platform/wtf/math_extras.h" - -namespace blink { - -const unsigned kMaxFFTPow2Size = 15; - -// Normal constructor: allocates for a given fftSize. -FFTFrame::FFTFrame(unsigned fft_size) - : fft_size_(fft_size), - log2fft_size_(static_cast<unsigned>(log2(fft_size))), - real_data_(fft_size / 2), - imag_data_(fft_size / 2), - forward_context_(nullptr), - inverse_context_(nullptr), - complex_data_(fft_size) { - // We only allow power of two. - DCHECK_EQ(1UL << log2fft_size_, fft_size_); - - forward_context_ = ContextForSize(log2fft_size_); - inverse_context_ = ContextForSize(log2fft_size_); -} - -// Creates a blank/empty frame (interpolate() must later be called). -FFTFrame::FFTFrame() - : fft_size_(0), - log2fft_size_(0), - forward_context_(nullptr), - inverse_context_(nullptr) {} - -// Copy constructor. -FFTFrame::FFTFrame(const FFTFrame& frame) - : fft_size_(frame.fft_size_), - log2fft_size_(frame.log2fft_size_), - real_data_(frame.fft_size_ / 2), - imag_data_(frame.fft_size_ / 2), - forward_context_(nullptr), - inverse_context_(nullptr), - complex_data_(frame.fft_size_) { - forward_context_ = ContextForSize(log2fft_size_); - inverse_context_ = ContextForSize(log2fft_size_); - - // Copy/setup frame data. - unsigned nbytes = sizeof(float) * (fft_size_ / 2); - memcpy(RealData(), frame.RealData(), nbytes); - memcpy(ImagData(), frame.ImagData(), nbytes); -} - -void FFTFrame::Initialize() {} - -void FFTFrame::Cleanup() {} - -FFTFrame::~FFTFrame() { - if (forward_context_) - free(forward_context_); - if (inverse_context_) - free(inverse_context_); -} - -void FFTFrame::DoFFT(const float* data) { - DCHECK(forward_context_); - - if (forward_context_) { - AudioFloatArray complex_fft(fft_size_ + 2); - - omxSP_FFTFwd_RToCCS_F32(data, complex_fft.Data(), forward_context_); - - unsigned len = fft_size_ / 2; - - // Split FFT data into real and imaginary arrays. - const float* c = complex_fft.Data(); - float* real = real_data_.Data(); - float* imag = imag_data_.Data(); - for (unsigned k = 1; k < len; ++k) { - int index = 2 * k; - real[k] = c[index]; - imag[k] = c[index + 1]; - } - real[0] = c[0]; - imag[0] = c[fft_size_]; - } -} - -void FFTFrame::DoInverseFFT(float* data) { - DCHECK(inverse_context_); - - if (inverse_context_) { - AudioFloatArray fft_data_array(fft_size_ + 2); - - unsigned len = fft_size_ / 2; - - // Pack the real and imaginary data into the complex array format - float* fft_data = fft_data_array.Data(); - const float* real = real_data_.Data(); - const float* imag = imag_data_.Data(); - for (unsigned k = 1; k < len; ++k) { - int index = 2 * k; - fft_data[index] = real[k]; - fft_data[index + 1] = imag[k]; - } - fft_data[0] = real[0]; - fft_data[1] = 0; - fft_data[fft_size_] = imag[0]; - fft_data[fft_size_ + 1] = 0; - - omxSP_FFTInv_CCSToR_F32(fft_data, data, inverse_context_); - } -} - -OMXFFTSpec_R_F32* FFTFrame::ContextForSize(unsigned log2fft_size) { - DCHECK(log2fft_size); - DCHECK_LE(log2fft_size, kMaxFFTPow2Size); - int buf_size; - OMXResult status = omxSP_FFTGetBufSize_R_F32(log2fft_size, &buf_size); - - if (status == OMX_Sts_NoErr) { - OMXFFTSpec_R_F32* context = - static_cast<OMXFFTSpec_R_F32*>(malloc(buf_size)); - omxSP_FFTInit_R_F32(context, log2fft_size); - return context; - } - - return nullptr; -} - -} // namespace blink - -#endif // #if defined(OS_ANDROID) && !defined(WTF_USE_WEBAUDIO_OPENMAX_DL_FFT)
diff --git a/third_party/blink/renderer/platform/audio/audio_array.h b/third_party/blink/renderer/platform/audio/audio_array.h index 971dede5..b9da1b6 100644 --- a/third_party/blink/renderer/platform/audio/audio_array.h +++ b/third_party/blink/renderer/platform/audio/audio_array.h
@@ -62,8 +62,7 @@ CHECK_LE(n, std::numeric_limits<unsigned>::max() / sizeof(T)); uint32_t initial_size = static_cast<uint32_t>(sizeof(T) * n); -#if defined(ARCH_CPU_X86_FAMILY) || defined(WTF_USE_WEBAUDIO_FFMPEG) || \ - defined(WTF_USE_WEBAUDIO_OPENMAX_DL_FFT) +#if defined(ARCH_CPU_X86_FAMILY) || defined(WTF_USE_WEBAUDIO_FFMPEG) const unsigned kAlignment = 32; #else const unsigned kAlignment = 16;
diff --git a/third_party/blink/renderer/platform/audio/fft_frame.h b/third_party/blink/renderer/platform/audio/fft_frame.h index 37e2f74a..c402f3f7 100644 --- a/third_party/blink/renderer/platform/audio/fft_frame.h +++ b/third_party/blink/renderer/platform/audio/fft_frame.h
@@ -144,11 +144,6 @@ RDFTContext* inverse_context_; float* GetUpToDateComplexData(); AudioFloatArray complex_data_; -#elif defined(WTF_USE_WEBAUDIO_OPENMAX_DL_FFT) - static OMXFFTSpec_R_F32* ContextForSize(unsigned log2fft_size); - OMXFFTSpec_R_F32* forward_context_; - OMXFFTSpec_R_F32* inverse_context_; - AudioFloatArray complex_data_; #elif defined(WTF_USE_WEBAUDIO_PFFFT) // Create and return the setup data for an FFT (forward or ivnerse) of the // given size.
diff --git a/third_party/blink/renderer/platform/audio/fft_frame_stub.cc b/third_party/blink/renderer/platform/audio/fft_frame_stub.cc index 16c10dd..cafe57b9 100644 --- a/third_party/blink/renderer/platform/audio/fft_frame_stub.cc +++ b/third_party/blink/renderer/platform/audio/fft_frame_stub.cc
@@ -28,7 +28,6 @@ #include "build/build_config.h" #if !defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_FFMPEG) && \ - !defined(WTF_USE_WEBAUDIO_OPENMAX_DL_FFT) && \ !defined(WTF_USE_WEBAUDIO_PFFFT) #include "third_party/blink/renderer/platform/audio/fft_frame.h"
diff --git a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc index 42276eb..efd60c2 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc +++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc
@@ -191,32 +191,30 @@ base::Optional<bool> hybrid_agc_use_peaks_not_rms, base::Optional<int> hybrid_agc_saturation_margin, base::Optional<double> compression_gain_db) { - const bool use_fixed_digital_agc1 = - agc_enabled && !use_hybrid_agc && compression_gain_db.has_value(); + const bool use_fixed_digital_agc2 = agc_enabled && + !experimental_agc_enabled && + compression_gain_db.has_value(); + const bool agc1_enabled = + agc_enabled && (use_hybrid_agc || !use_fixed_digital_agc2); // Configure AGC1. - if (agc_enabled) { + if (agc1_enabled) { apm_config->gain_controller1.enabled = true; - if (use_fixed_digital_agc1) { - apm_config->gain_controller1.mode = - webrtc::AudioProcessing::Config::GainController1::Mode::kFixedDigital; - apm_config->gain_controller1.compression_gain_db = - compression_gain_db.value(); - } else { - apm_config->gain_controller1.mode = + apm_config->gain_controller1.mode = #if defined(OS_ANDROID) - webrtc::AudioProcessing::Config::GainController1::Mode::kFixedDigital; + webrtc::AudioProcessing::Config::GainController1::Mode::kFixedDigital; #else - webrtc::AudioProcessing::Config::GainController1::Mode:: - kAdaptiveAnalog; + webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog; #endif - } } // Configure AGC2. if (experimental_agc_enabled) { DCHECK(hybrid_agc_use_peaks_not_rms.has_value() && hybrid_agc_saturation_margin.has_value()); + // Experimental AGC is enabled. Hybrid AGC may or may not be enabled. Config + // AGC2 with adaptive mode and the given options, while ignoring + // |use_fixed_digital_agc2|. apm_config->gain_controller2.enabled = use_hybrid_agc; apm_config->gain_controller2.fixed_digital.gain_db = 0.f; apm_config->gain_controller2.adaptive_digital.enabled = true; @@ -231,6 +229,13 @@ apm_config->gain_controller2.adaptive_digital.extra_saturation_margin_db = hybrid_agc_saturation_margin.value(); } + } else if (use_fixed_digital_agc2) { + // Experimental AGC is disabled, thus hybrid AGC is disabled. Config AGC2 + // with fixed gain mode. + apm_config->gain_controller2.enabled = true; + apm_config->gain_controller2.fixed_digital.gain_db = + compression_gain_db.value(); + apm_config->gain_controller2.adaptive_digital.enabled = false; } }
diff --git a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc index 88bdb054..ab73a2f2 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc +++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options_test.cc
@@ -26,7 +26,7 @@ #endif // defined(OS_ANDROID) } -TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC1) { +TEST(ConfigAutomaticGainControlTest, EnableFixedDigitalAGC2) { webrtc::AudioProcessing::Config apm_config; const double compression_gain_db = 10.0; ConfigAutomaticGainControl(&apm_config, @@ -34,24 +34,32 @@ false, // |experimental_agc_enabled|. false, // |use_hybrid_agc|. base::nullopt, base::nullopt, compression_gain_db); - EXPECT_TRUE(apm_config.gain_controller1.enabled); - EXPECT_EQ( - apm_config.gain_controller1.mode, - webrtc::AudioProcessing::Config::GainController1::Mode::kFixedDigital); - EXPECT_FLOAT_EQ(apm_config.gain_controller1.compression_gain_db, + EXPECT_FALSE(apm_config.gain_controller1.enabled); + EXPECT_TRUE(apm_config.gain_controller2.enabled); + EXPECT_FALSE(apm_config.gain_controller2.adaptive_digital.enabled); + EXPECT_FLOAT_EQ(apm_config.gain_controller2.fixed_digital.gain_db, compression_gain_db); } -TEST(ConfigAutomaticGainControlTest, ConfigAGC2ForHybridAGC) { +TEST(ConfigAutomaticGainControlTest, EnableHybridAGC) { webrtc::AudioProcessing::Config apm_config; const bool use_peaks_not_rms = true; const int saturation_margin = 10; + const double compression_gain_db = 10.0; // Will test that it has no effect. ConfigAutomaticGainControl(&apm_config, true, // |agc_enabled|. true, // |experimental_agc_enabled|. true, // |use_hybrid_agc|. use_peaks_not_rms, saturation_margin, - base::nullopt); + compression_gain_db); + EXPECT_TRUE(apm_config.gain_controller1.enabled); + EXPECT_EQ( + apm_config.gain_controller1.mode, +#if defined(OS_ANDROID) + webrtc::AudioProcessing::Config::GainController1::Mode::kFixedDigital); +#else + webrtc::AudioProcessing::Config::GainController1::Mode::kAdaptiveAnalog); +#endif // defined(OS_ANDROID) EXPECT_TRUE(apm_config.gain_controller2.enabled); EXPECT_EQ(apm_config.gain_controller2.fixed_digital.gain_db, 0); EXPECT_TRUE(apm_config.gain_controller2.adaptive_digital.enabled);
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 4f2c05c..db7b4a8 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -668,4 +668,8 @@ RuntimeEnabledFeatures::SetSmsReceiverEnabled(enable); } +void WebRuntimeFeatures::EnableDisplayLocking(bool enable) { + RuntimeEnabledFeatures::SetDisplayLockingEnabled(enable); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index 7c01a9c8..1cb841d 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -194,8 +194,9 @@ return compaction_.get(); } -void ThreadHeap::RegisterMovingObjectReference(MovableReference* slot) { - Compaction()->RegisterMovingObjectReference(slot); +void ThreadHeap::RegisterMovingObjectReference(const char* name, + MovableReference* slot) { + Compaction()->RegisterMovingObjectReference(name, slot); } void ThreadHeap::RegisterMovingObjectCallback(MovableReference* slot,
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index 909642dc..f5eb272 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -222,7 +222,7 @@ // // When compaction moves the object pointed to by |*slot| to |newAddress|, // |*slot| must be updated to hold |newAddress| instead. - void RegisterMovingObjectReference(MovableReference*); + void RegisterMovingObjectReference(const char*, MovableReference*); // Register a callback to be invoked upon moving the object starting at // |reference|; see |MovingObjectCallback| documentation for details.
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.cc b/third_party/blink/renderer/platform/heap/heap_compact.cc index 03b8e19e..6981e0f 100644 --- a/third_party/blink/renderer/platform/heap/heap_compact.cc +++ b/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -40,7 +40,7 @@ relocatable_pages_.insert(page); } - void AddOrFilter(MovableReference* slot) { + void AddOrFilter(MovableReference* slot, const char* name) { MovableReference value = *slot; CHECK(value); @@ -98,6 +98,7 @@ // Add regular fixup. fixups_.insert({value, slot}); + fixup_names_.insert({slot, name}); // Check whether the slot itself resides on a page that is compacted. if (LIKELY(!relocatable_pages_.Contains(slot_page))) @@ -177,6 +178,12 @@ DebugSlotType slot_type = kNormalSlot; base::debug::Alias(&slot_type); + // TODO(918064): Remove this after getting the type of the object that + // crashes compaction. + constexpr size_t kMaxNameLen = 256; + char slot_container_name[kMaxNameLen]; + base::debug::Alias(slot_container_name); + // If the object is referenced by a slot that is contained on a compacted // area itself, check whether it can be updated already. MovableReference* slot = reinterpret_cast<MovableReference*>(it->second); @@ -187,6 +194,12 @@ if (!slot_location) { interior_it->second = to; slot_type = kInteriorSlotPreMove; + const char* name = fixup_names_.find(slot)->second; + size_t len = strlen(name); + if (len > kMaxNameLen) + len = kMaxNameLen; + strncpy(slot_container_name, name, len); + slot_container_name[len - 1] = 0; } else { LOG_HEAP_COMPACTION() << "Redirected slot: " << slot << " => " << slot_location; @@ -254,6 +267,7 @@ // // (TODO: consider in-place updating schemes.) std::unordered_map<MovableReference, MovableReference*> fixups_; + std::unordered_map<MovableReference*, const char*> fixup_names_; // Map from movable reference to callbacks that need to be invoked // when the object moves. @@ -362,13 +376,15 @@ force_for_next_gc_ = false; } -void HeapCompact::RegisterMovingObjectReference(MovableReference* slot) { +void HeapCompact::RegisterMovingObjectReference(const char* name, + MovableReference* slot) { CHECK(heap_->LookupPageForAddress(reinterpret_cast<Address>(slot))); if (!do_compact_) return; traced_slots_.insert(slot); + traced_slots_names_.insert(slot, name); } void HeapCompact::RegisterMovingObjectCallback(MovableReference* slot, @@ -438,11 +454,12 @@ last_fixup_count_for_testing_ = 0; for (auto** slot : traced_slots_) { if (*slot) { - Fixups().AddOrFilter(slot); + Fixups().AddOrFilter(slot, traced_slots_names_.find(slot)->value); last_fixup_count_for_testing_++; } } traced_slots_.clear(); + traced_slots_names_.clear(); } void HeapCompact::Finish() { @@ -463,6 +480,7 @@ last_fixup_count_for_testing_ = 0; traced_slots_.clear(); + traced_slots_names_.clear(); fixups_.reset(); do_compact_ = false; }
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.h b/third_party/blink/renderer/platform/heap/heap_compact.h index 5fe668b0..bfe408d 100644 --- a/third_party/blink/renderer/platform/heap/heap_compact.h +++ b/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/platform/heap/blink_gc.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" @@ -63,7 +64,7 @@ } // See |Heap::registerMovingObjectReference()| documentation. - void RegisterMovingObjectReference(MovableReference* slot); + void RegisterMovingObjectReference(const char* name, MovableReference* slot); // See |Heap::registerMovingObjectCallback()| documentation. void RegisterMovingObjectCallback(MovableReference*, @@ -140,6 +141,7 @@ // marking phases. The mapping between the slots and the backing stores are // created at the atomic pause phase. HashSet<MovableReference*> traced_slots_; + HashMap<MovableReference*, const char*> traced_slots_names_; // Set to |true| when a compacting sweep will go ahead. bool do_compact_ = false;
diff --git a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc index 8149cfab..88da6b2e 100644 --- a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc +++ b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -56,15 +56,17 @@ void** object_slot, TraceDescriptor desc, WeakCallback callback) final {} - void VisitBackingStoreStrongly(void* object, + void VisitBackingStoreStrongly(const char*, + void* object, void** object_slot, TraceDescriptor desc) final {} - void VisitBackingStoreWeakly(void*, + void VisitBackingStoreWeakly(const char*, + void*, void**, TraceDescriptor, WeakCallback, void*) final {} - void VisitBackingStoreOnly(void*, void**) final {} + void VisitBackingStoreOnly(const char*, void*, void**) final {} void RegisterBackingStoreCallback(void** slot, MovingObjectCallback, void* callback_data) final {}
diff --git a/third_party/blink/renderer/platform/heap/marking_verifier.h b/third_party/blink/renderer/platform/heap/marking_verifier.h index f4095b9..567227b6 100644 --- a/third_party/blink/renderer/platform/heap/marking_verifier.h +++ b/third_party/blink/renderer/platform/heap/marking_verifier.h
@@ -44,13 +44,17 @@ } // Unused overrides. - void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final {} - void VisitBackingStoreWeakly(void*, + void VisitBackingStoreStrongly(const char*, + void*, + void**, + TraceDescriptor) final {} + void VisitBackingStoreWeakly(const char*, + void*, void**, TraceDescriptor, WeakCallback, void*) final {} - void VisitBackingStoreOnly(void*, void**) final {} + void VisitBackingStoreOnly(const char*, void*, void**) final {} void RegisterBackingStoreCallback(void**, MovingObjectCallback, void*) final { } void RegisterWeakCallback(void*, WeakCallback) final {}
diff --git a/third_party/blink/renderer/platform/heap/marking_visitor.cc b/third_party/blink/renderer/platform/heap/marking_visitor.cc index 6a84d03..d5189574 100644 --- a/third_party/blink/renderer/platform/heap/marking_visitor.cc +++ b/third_party/blink/renderer/platform/heap/marking_visitor.cc
@@ -99,11 +99,12 @@ weak_callback_worklist_.Push({object, callback}); } -void MarkingVisitor::RegisterBackingStoreReference(void** slot) { +void MarkingVisitor::RegisterBackingStoreReference(const char* name, + void** slot) { if (marking_mode_ != kGlobalMarkingWithCompaction) return; Heap().RegisterMovingObjectReference( - reinterpret_cast<MovableReference*>(slot)); + name, reinterpret_cast<MovableReference*>(slot)); } void MarkingVisitor::RegisterBackingStoreCallback(void** slot,
diff --git a/third_party/blink/renderer/platform/heap/marking_visitor.h b/third_party/blink/renderer/platform/heap/marking_visitor.h index ca797f6..f15ae6f5 100644 --- a/third_party/blink/renderer/platform/heap/marking_visitor.h +++ b/third_party/blink/renderer/platform/heap/marking_visitor.h
@@ -93,22 +93,24 @@ RegisterWeakCallback(object_slot, callback); } - void VisitBackingStoreStrongly(void* object, + void VisitBackingStoreStrongly(const char* name, + void* object, void** object_slot, TraceDescriptor desc) final { - RegisterBackingStoreReference(object_slot); + RegisterBackingStoreReference(name, object_slot); if (!object) return; Visit(object, desc); } // All work is registered through RegisterWeakCallback. - void VisitBackingStoreWeakly(void* object, + void VisitBackingStoreWeakly(const char* name, + void* object, void** object_slot, TraceDescriptor desc, WeakCallback callback, void* parameter) final { - RegisterBackingStoreReference(object_slot); + RegisterBackingStoreReference(name, object_slot); if (!object) return; RegisterWeakCallback(parameter, callback); @@ -117,8 +119,10 @@ // Used to only mark the backing store when it has been registered for weak // processing. In this case, the contents are processed separately using // the corresponding traits but the backing store requires marking. - void VisitBackingStoreOnly(void* object, void** object_slot) final { - RegisterBackingStoreReference(object_slot); + void VisitBackingStoreOnly(const char* name, + void* object, + void** object_slot) final { + RegisterBackingStoreReference(name, object_slot); if (!object) return; MarkHeaderNoTracing(HeapObjectHeader::FromPayload(object)); @@ -139,7 +143,7 @@ static void WriteBarrierSlow(void*); static void TraceMarkedBackingStoreSlow(void*); - void RegisterBackingStoreReference(void** slot); + void RegisterBackingStoreReference(const char* name, void** slot); MarkingWorklist::View marking_worklist_; NotFullyConstructedWorklist::View not_fully_constructed_worklist_;
diff --git a/third_party/blink/renderer/platform/heap/visitor.h b/third_party/blink/renderer/platform/heap/visitor.h index fd95a7c..e5a757d 100644 --- a/third_party/blink/renderer/platform/heap/visitor.h +++ b/third_party/blink/renderer/platform/heap/visitor.h
@@ -120,7 +120,8 @@ static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); - VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store), + VisitBackingStoreStrongly(__PRETTY_FUNCTION__, + reinterpret_cast<void*>(backing_store), reinterpret_cast<void**>(backing_store_slot), TraceDescriptorFor(backing_store)); } @@ -134,7 +135,8 @@ static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); - VisitBackingStoreWeakly(reinterpret_cast<void*>(backing_store), + VisitBackingStoreWeakly(__PRETTY_FUNCTION__, + reinterpret_cast<void*>(backing_store), reinterpret_cast<void**>(backing_store_slot), TraceTrait<T>::GetTraceDescriptor( reinterpret_cast<void*>(backing_store)), @@ -147,7 +149,8 @@ static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); - VisitBackingStoreOnly(reinterpret_cast<void*>(backing_store), + VisitBackingStoreOnly(__PRETTY_FUNCTION__, + reinterpret_cast<void*>(backing_store), reinterpret_cast<void**>(backing_store_slot)); } @@ -217,13 +220,17 @@ virtual void VisitWeak(void*, void**, TraceDescriptor, WeakCallback) = 0; // Visitors for collection backing stores. - virtual void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) = 0; - virtual void VisitBackingStoreWeakly(void*, + virtual void VisitBackingStoreStrongly(const char*, + void*, + void**, + TraceDescriptor) = 0; + virtual void VisitBackingStoreWeakly(const char*, + void*, void**, TraceDescriptor, WeakCallback, void*) = 0; - virtual void VisitBackingStoreOnly(void*, void**) = 0; + virtual void VisitBackingStoreOnly(const char*, void*, void**) = 0; // Visits cross-component references to V8.
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index ac1e1a1..2ca0c4b 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -916,6 +916,14 @@ status: "stable", }, { + // Allows the navigator.language and navigator.languages APIs in insecure + // contexts, which https://github.com/WICG/lang-client-hint proposes that + // we deprecate. + name: "NavigatorLanguageInInsecureContext", + settable_from_internals: true, + status: "stable", + }, + { name: "NetInfoDownlinkMax", // Only Android, ChromeOS support NetInfo downlinkMax, type and ontypechange now status: {"Android": "stable", "ChromeOS": "stable"},
diff --git a/third_party/blink/renderer/platform/web_thread_supporting_gc.cc b/third_party/blink/renderer/platform/web_thread_supporting_gc.cc index 00fe3b18..8556fd86 100644 --- a/third_party/blink/renderer/platform/web_thread_supporting_gc.cc +++ b/third_party/blink/renderer/platform/web_thread_supporting_gc.cc
@@ -19,12 +19,10 @@ #if DCHECK_IS_ON() WTF::WillCreateThread(); #endif - if (!thread_) { - if (params.thread_type == WebThreadType::kAudioWorkletThread) { - thread_ = Thread::CreateWebAudioThread(); - } else { - thread_ = Thread::CreateThread(params); - } + if (params.thread_type == WebThreadType::kAudioWorkletThread) { + thread_ = Thread::CreateWebAudioThread(); + } else { + thread_ = Thread::CreateThread(params); } MemoryPressureListenerRegistry::Instance().RegisterThread(thread_.get()); }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index ab175678..873e025 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -260,6 +260,10 @@ crbug.com/955533 virtual/display-lock/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ] crbug.com/882663 http/tests/devtools/elements/highlight/highlight-display-locked.js [ Skip ] +# Render throttling +crbug.com/520170 fast/dom/timer-throttling-hidden-page.html [ Failure Pass ] +crbug.com/956354 fast/dom/timer-throttling-out-of-view-cross-origin-page.html [ Failure Pass ] + # Sheriff 2018/05/25 crbug.com/846747 http/tests/navigation/navigation-interrupted-by-fragment.html [ Pass Timeout ] crbug.com/846747 virtual/stable/http/tests/navigation/navigation-interrupted-by-fragment.html [ Pass Timeout ] @@ -1839,7 +1843,6 @@ crbug.com/522648 fast/events/touch/compositor-touch-hit-rects-iframes.html [ Crash Failure Pass ] crbug.com/522648 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects-iframes.html [ Crash Failure Pass ] crbug.com/522648 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects-iframes.html [ Skip ] -crbug.com/520170 fast/dom/timer-throttling-hidden-page.html [ Failure Pass ] crbug.com/652536 fast/events/mouse-cursor-change-after-image-load.html [ Failure Pass Crash ] crbug.com/652536 virtual/mouseevent_fractional/fast/events/mouse-cursor-change-after-image-load.html [ Failure Pass Crash ] crbug.com/520188 [ Win ] http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index c98312a..04913032 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1,5 +1,10 @@ [ { + "prefix": "disable-accept-language-header", + "base": "http/tests/navigation/language", + "args": ["--disable-features=AcceptLanguageHeader"] + }, + { "prefix": "gpu", "base": "fast/canvas", "args": ["--enable-accelerated-2d-canvas"]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 68b6c56..f62a1b3d1 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -145948,11 +145948,6 @@ {} ] ], - "css/css-properties-values-api/register-property-syntax-parsing-expected.txt": [ - [ - {} - ] - ], "css/css-properties-values-api/registered-property-computation-expected.txt": [ [ {} @@ -268375,6 +268370,12 @@ {} ] ], + "html/semantics/forms/the-input-element/time-datalist-crash.html": [ + [ + "html/semantics/forms/the-input-element/time-datalist-crash.html", + {} + ] + ], "html/semantics/forms/the-input-element/time-focus-dynamic-value-change.html": [ [ "html/semantics/forms/the-input-element/time-focus-dynamic-value-change.html", @@ -392757,12 +392758,8 @@ "5f0b7eb50c21397e0fe2995dd242fa454f78ca7c", "testharness" ], - "css/css-properties-values-api/register-property-syntax-parsing-expected.txt": [ - "9e133e5b38f5cbd7756e407f271f15943b727748", - "support" - ], "css/css-properties-values-api/register-property-syntax-parsing.html": [ - "43cff0dbe283e33d0d79763d01e5744774cf0b9f", + "8141befddd1c9b44b224e1f5334a31ff118f4a06", "testharness" ], "css/css-properties-values-api/register-property.html": [ @@ -454441,6 +454438,10 @@ "0ffec33bf531a55c9b878d2b7e5db7fa69043863", "testharness" ], + "html/semantics/forms/the-input-element/time-datalist-crash.html": [ + "2964032e35283ef4cae28af2b736fa9ba3924260", + "testharness" + ], "html/semantics/forms/the-input-element/time-expected.txt": [ "80c8abe818f7824433179193bb075846034f6f18", "support" @@ -474626,7 +474627,7 @@ "support" ], "payment-request/shipping-address-changed-manual.https.html": [ - "711ba2743601348594efd129f74f79fd89b4432a", + "78b7f17ceeb984bde8009093a56969261e44dd7c", "manual" ], "payment-request/show-method-optional-promise-rejects-manual.https.html": [ @@ -504682,7 +504683,7 @@ "testharness" ], "webrtc/RTCRtpSender-transport.https.html": [ - "e74495fec48e420bae8cae1e1481b90b9e38ec8b", + "8c0552dd68aba8c707c6cbe2c7d6f9f3c5f64f17", "testharness" ], "webrtc/RTCRtpTransceiver-direction.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt deleted file mode 100644 index 9e133e5..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt +++ /dev/null
@@ -1,158 +0,0 @@ -This is a testharness.js-based test. -Found 149 tests; 148 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS syntax:'*', initialValue:'a' is valid -PASS syntax:' * ', initialValue:'b' is valid -PASS syntax:'<length>', initialValue:'2px' is valid -PASS syntax:' <number>', initialValue:'5' is valid -PASS syntax:'<percentage> ', initialValue:'10%' is valid -PASS syntax:'<color>+', initialValue:'red' is valid -PASS syntax:' <length>+ | <percentage>', initialValue:'2px 8px' is valid -PASS syntax:' <length>+ | <color>#', initialValue:'red, blue' is valid -PASS syntax:'<length>|<percentage>|<length-percentage>', initialValue:'2px' is valid -PASS syntax:'<color> | <image> | <url> | <integer> | <angle>', initialValue:'red' is valid -PASS syntax:'<time> | <resolution> | <transform-list> | <custom-ident>', initialValue:'red' is valid -PASS syntax:' <color> -| foo', initialValue:'foo' is valid -PASS syntax:'*', initialValue:':> hello' is valid -PASS syntax:'*', initialValue:'([ brackets ]) { yay (??)}' is valid -PASS syntax:'*', initialValue:'yep 'this is valid too'' is valid -PASS syntax:'*', initialValue:'unmatched opening bracket is valid :(' is valid -PASS syntax:'*', initialValue:'"' is valid -PASS syntax:'<length>', initialValue:'0' is valid -PASS syntax:'<length>', initialValue:'10px /*:)*/' is valid -PASS syntax:'<length>', initialValue:' calc(-2px)' is valid -PASS syntax:'<length>', initialValue:'calc(2px*4 + 10px)' is valid -PASS syntax:'<length>', initialValue:'7.1e-4cm' is valid -PASS syntax:'<length>', initialValue:'calc(7in - 12px)' is valid -PASS syntax:'<length>+', initialValue:'2px 7px calc(8px)' is valid -PASS syntax:'<length>#', initialValue:'2px, 7px, calc(8px)' is valid -PASS syntax:'<percentage>', initialValue:'-9.3e3%' is valid -PASS syntax:'<length-percentage>', initialValue:'-54%' is valid -PASS syntax:'<length-percentage>', initialValue:'0' is valid -PASS syntax:'<length-percentage>', initialValue:'calc(-11px + 10.4%)' is valid -PASS syntax:'<number>', initialValue:'-109' is valid -PASS syntax:'<number>', initialValue:'2.3e4' is valid -PASS syntax:'<integer>', initialValue:'-109' is valid -PASS syntax:'<integer>', initialValue:'19' is valid -PASS syntax:'<integer>', initialValue:'calc(1)' is valid -PASS syntax:'<integer>', initialValue:'calc(1 + 2)' is valid -PASS syntax:'<integer>', initialValue:'calc(3.1415)' is valid -PASS syntax:'<integer>', initialValue:'calc(3.1415 + 3.1415)' is valid -PASS syntax:'<angle>', initialValue:'10deg' is valid -PASS syntax:'<angle>', initialValue:'20.5rad' is valid -PASS syntax:'<angle>', initialValue:'calc(50grad + 3.14159rad)' is valid -PASS syntax:'<time>', initialValue:'2s' is valid -PASS syntax:'<time>', initialValue:'calc(2s - 9ms)' is valid -PASS syntax:'<resolution>', initialValue:'10dpi' is valid -PASS syntax:'<resolution>', initialValue:'3dPpX' is valid -PASS syntax:'<resolution>', initialValue:'-5.3dpcm' is valid -PASS syntax:'<transform-function>', initialValue:'translateX(2px)' is valid -PASS syntax:'<transform-function>|<integer>', initialValue:'5' is valid -PASS syntax:'<transform-function>|<integer>', initialValue:'scale(2)' is valid -PASS syntax:'<transform-function>+', initialValue:'translateX(2px) rotate(42deg)' is valid -PASS syntax:'<transform-list>', initialValue:'scale(2)' is valid -PASS syntax:'<transform-list>', initialValue:'translateX(2px) rotate(20deg)' is valid -PASS syntax:'<color>', initialValue:'rgb(12, 34, 56)' is valid -PASS syntax:'<color>', initialValue:'lightgoldenrodyellow' is valid -PASS syntax:'<image>', initialValue:'url(a)' is valid -PASS syntax:'<image>', initialValue:'linear-gradient(yellow, blue)' is valid -PASS syntax:'<url>', initialValue:'url(a)' is valid -PASS syntax:'banana', initialValue:'banana' is valid -PASS syntax:'bAnAnA', initialValue:'bAnAnA' is valid -PASS syntax:'ba-na-nya', initialValue:'ba-na-nya' is valid -PASS syntax:'banana', initialValue:'banan\61' is valid -PASS syntax:'banan\61', initialValue:'banana' is valid -PASS syntax:'<custom-ident>', initialValue:'banan\61' is valid -PASS syntax:'big | bigger | BIGGER', initialValue:'bigger' is valid -PASS syntax:'foo+|bar', initialValue:'foo foo foo' is valid -PASS syntax:'default', initialValue:'default' is valid -PASS syntax:'banana ', initialValue:'banana' is valid -PASS syntax:' -banana\r -', initialValue:'banana' is valid -PASS syntax:'ba -| na\r|nya', initialValue:'nya' is valid -PASS syntax:'null', initialValue:'null' is valid -PASS syntax:'undefined', initialValue:'undefined' is valid -PASS syntax:'array', initialValue:'array' is valid -PASS syntax:'\1F914', initialValue:'🤔' is valid -PASS syntax:'hmm\1F914', initialValue:'hmm🤔' is valid -PASS syntax:'\1F914hmm', initialValue:'🤔hmm' is valid -PASS syntax:'\1F914 hmm', initialValue:'🤔hmm' is valid -PASS syntax:'\1F914\1F914', initialValue:'🤔🤔' is valid -PASS syntax:'banana,nya', initialValue:'banana' is invalid -PASS syntax:'<\6c ength>', initialValue:'10px' is invalid -PASS syntax:'<banana>', initialValue:'banana' is invalid -PASS syntax:'<Number>', initialValue:'10' is invalid -PASS syntax:'<length', initialValue:'10px' is invalid -PASS syntax:'<LENGTH>', initialValue:'10px' is invalid -PASS syntax:'< length>', initialValue:'10px' is invalid -PASS syntax:'<length >', initialValue:'10px' is invalid -PASS syntax:'<length> +', initialValue:'10px' is invalid -PASS syntax:'<transform-list>+', initialValue:'scale(2)' is invalid -PASS syntax:'<transform-list>#', initialValue:'scale(2)' is invalid -PASS syntax:'<length>++', initialValue:'10px' is invalid -PASS syntax:'<length>##', initialValue:'10px' is invalid -PASS syntax:'<length>+#', initialValue:'10px' is invalid -PASS syntax:'<length>#+', initialValue:'10px' is invalid -PASS syntax:'<length> | *', initialValue:'10px' is invalid -PASS syntax:'*|banana', initialValue:'banana' is invalid -PASS syntax:'|banana', initialValue:'banana' is invalid -PASS syntax:'*+', initialValue:'banana' is invalid -PASS syntax:'|', initialValue:'banana' is invalid -PASS syntax:' |', initialValue:'banana' is invalid -PASS syntax:'||', initialValue:'banana' is invalid -PASS syntax:'initial', initialValue:'initial' is invalid -PASS syntax:'inherit', initialValue:'inherit' is invalid -PASS syntax:'unset', initialValue:'unset' is invalid -PASS syntax:'<length>|initial', initialValue:'10px' is invalid -PASS syntax:'<length>|INHERIT', initialValue:'10px' is invalid -PASS syntax:'<percentage>|unsEt', initialValue:'2%' is invalid -PASS syntax:'*', initialValue:'initial' is invalid -PASS syntax:'*', initialValue:'inherit' is invalid -PASS syntax:'*', initialValue:'unset' is invalid -FAIL syntax:'*', initialValue:'revert' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw -PASS syntax:'<custom-ident>', initialValue:'initial' is invalid -PASS syntax:'<custom-ident>+', initialValue:'foo inherit bar' is invalid -PASS syntax:'*', initialValue:')' is invalid -PASS syntax:'*', initialValue:'([)]' is invalid -PASS syntax:'*', initialValue:'whee!' is invalid -PASS syntax:'*', initialValue:'" -' is invalid -PASS syntax:'*', initialValue:'url(moo '')' is invalid -PASS syntax:'*', initialValue:'semi;colon' is invalid -PASS syntax:'*', initialValue:'var(invalid var ref)' is invalid -PASS syntax:'*', initialValue:'var(--foo)' is invalid -PASS syntax:'banana', initialValue:'bAnAnA' is invalid -PASS syntax:'<length>', initialValue:'var(--moo)' is invalid -PASS syntax:'<length>', initialValue:'10' is invalid -PASS syntax:'<length>', initialValue:'10%' is invalid -PASS syntax:'<length>', initialValue:'calc(5px + 10%)' is invalid -PASS syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is invalid -PASS syntax:'<length>', initialValue:'10em' is invalid -PASS syntax:'<length>', initialValue:'10vmin' is invalid -PASS syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid -PASS syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid -PASS syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid -PASS syntax:'<length>+', initialValue:'10px calc(20px + 4rem)' is invalid -PASS syntax:'<length>+', initialValue:'' is invalid -PASS syntax:'<length>#', initialValue:'' is invalid -PASS syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid -PASS syntax:'<length>', initialValue:'10px;' is invalid -PASS syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid -PASS syntax:'<percentage>', initialValue:'0' is invalid -PASS syntax:'<integer>', initialValue:'1.0' is invalid -PASS syntax:'<integer>', initialValue:'1e0' is invalid -PASS syntax:'<number>|foo', initialValue:'foo var(--foo, bla)' is invalid -PASS syntax:'<angle>', initialValue:'0' is invalid -PASS syntax:'<angle>', initialValue:'10%' is invalid -PASS syntax:'<time>', initialValue:'2px' is invalid -PASS syntax:'<resolution>', initialValue:'10' is invalid -PASS syntax:'<transform-function>', initialValue:'scale()' is invalid -PASS syntax:'<transform-list>', initialValue:'scale()' is invalid -PASS syntax:'<transform-list>+', initialValue:'translateX(2px) rotate(20deg)' is invalid -PASS syntax:'<color>', initialValue:'fancy-looking' is invalid -PASS syntax:'<image>', initialValue:'banana.png' is invalid -PASS syntax:'<url>', initialValue:'banana.png' is invalid -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html index 43cff0db..94013c6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html
@@ -93,7 +93,6 @@ assert_valid("<custom-ident>", "banan\\61"); assert_valid("big | bigger | BIGGER", "bigger"); assert_valid("foo+|bar", "foo foo foo"); -assert_valid("default", "default"); assert_valid("banana\t", "banana"); assert_valid("\nbanana\r\n", "banana"); @@ -137,17 +136,30 @@ assert_invalid("initial", "initial"); assert_invalid("inherit", "inherit"); assert_invalid("unset", "unset"); +assert_invalid("revert", "revert"); +assert_invalid("default", "default"); assert_invalid("<length>|initial", "10px"); assert_invalid("<length>|INHERIT", "10px"); assert_invalid("<percentage>|unsEt", "2%"); +assert_invalid("<color>|REVert", "red"); +assert_invalid("<integer>|deFAUlt", "1"); // Invalid initialValue assert_invalid("*", "initial"); assert_invalid("*", "inherit"); assert_invalid("*", "unset"); assert_invalid("*", "revert"); +assert_invalid("*", "default"); assert_invalid("<custom-ident>", "initial"); +assert_invalid("<custom-ident>", "inherit"); +assert_invalid("<custom-ident>", "unset"); +assert_invalid("<custom-ident>", "revert"); +assert_invalid("<custom-ident>", "default"); +assert_invalid("<custom-ident>+", "foo initial bar"); assert_invalid("<custom-ident>+", "foo inherit bar"); +assert_invalid("<custom-ident>+", "foo unset bar"); +assert_invalid("<custom-ident>+", "foo revert bar"); +assert_invalid("<custom-ident>+", "foo default bar"); assert_invalid("*", ")"); assert_invalid("*", "([)]");
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/shipping-address-changed-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/shipping-address-changed-manual.https.html index 711ba27..78b7f17 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/shipping-address-changed-manual.https.html +++ b/third_party/blink/web_tests/external/wpt/payment-request/shipping-address-changed-manual.https.html
@@ -63,10 +63,14 @@ }); request.show().catch(err => err); const results = await Promise.all([listenerPromise, handlerPromise]); - assert_true( - results.every(obj => obj instanceof PaymentAddress), - "Expected instances of PaymentAddress" - ); + results.forEach(obj => { + assert_true(obj instanceof PaymentAddress, + "Expected instance of PaymentAddress"); + assert_equals(obj.organization, "", "organization should be redacted"); + assert_equals(obj.phone, "", "phone should be redacted"); + assert_equals(obj.recipient, "", "recipient should be redacted"); + assert_equals(obj.addressLine.length, 0, "addressLine should be redacted"); + }); await request.abort(); }); done();
diff --git a/third_party/blink/web_tests/fast/forms/select-popup/popup-menu-scrollbar-button-scrolls.html b/third_party/blink/web_tests/fast/forms/select-popup/popup-menu-scrollbar-button-scrolls.html new file mode 100644 index 0000000..aca1142 --- /dev/null +++ b/third_party/blink/web_tests/fast/forms/select-popup/popup-menu-scrollbar-button-scrolls.html
@@ -0,0 +1,77 @@ +<!DOCTYPE html> +<html> +<head> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../resources/common.js"></script> +<script src="../resources/picker-common.js"></script> +</head> +<body> +<select id="menu"> + <option>option1</option> + <option>option2</option> + <option>option3</option> + <option>option4</option> + <option>option5</option> + <option>option6</option> + <option>option7</option> + <option>option8</option> + <option>option9</option> + <option>option10</option> + <option>option11</option> + <option>option12</option> + <option>option13</option> + <option>option14</option> + <option>option15</option> + <option>option16</option> + <option>option17</option> + <option>option18</option> + <option>option19</option> + <option>option20</option> + <option>option21</option> + <option>option22</option> + <option>option23</option> + <option>option24</option> + <option>option25</option> + <option>option26</option> + <option>option27</option> + <option>option28</option> +</select> +<script> +internals.settings.setMockScrollbarsEnabled(true); +internals.settings.setScrollAnimatorEnabled(false); + +let test = async_test(function(test) { + openPicker(menu, test.step_func(testScrollbarScroll), + test.unreached_func('Picker failed to open')); +}, "Scrollbar clicks in a popup must scroll"); + +function testScrollbarScroll() { + let picker = internals.pagePopupWindow.global.picker; + let scrollEvents = 0; + + // Click on the scrollbar forward button, and then validate with + // a pixel test that the scrollbar/scrollable area scrolled. + // + // Note: when there is an active popup, eventSender's events are sent with + // coordinates relative to the popup itself, so we don't need to take the + // outer select element's position into account. + let selectElement = internals.pagePopupWindow.global.picker._selectElement; + let innerSelectRect = selectElement.getBoundingClientRect(); + let scrollbarX = innerSelectRect.x + innerSelectRect.width - 5; + let scrollbarY = innerSelectRect.y + innerSelectRect.height - 10; + eventSender.mouseMoveTo(scrollbarX, scrollbarY); + eventSender.mouseDown(); + eventSender.mouseUp(); + requestAnimationFrame(test.step_func(function() { + requestAnimationFrame(test.step_func(function() { + assert_greater_than(selectElement.scrollTop, 0); + test.done(); + })); + })); +} + +</script> +</body> +</html> +
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/resources/mock-snav-service.js b/third_party/blink/web_tests/fast/spatial-navigation/resources/mock-snav-service.js index b0c445b..d475a8e7 100644 --- a/third_party/blink/web_tests/fast/spatial-navigation/resources/mock-snav-service.js +++ b/third_party/blink/web_tests/fast/spatial-navigation/resources/mock-snav-service.js
@@ -5,6 +5,7 @@ this.canExitFocus = false; this.canSelectElement = false; this.hasNextFormElement = false; + this.hasDefaultVideoControls = false; this.callback = null; this.bindingSet_ = new mojo.BindingSet(blink.mojom.SpatialNavigationHost); this.interceptor_ = new MojoInterfaceInterceptor( @@ -18,6 +19,7 @@ this.canExitFocus = state.canExitFocus; this.canSelectElement = state.canSelectElement; this.hasNextFormElement = state.hasNextFormElement; + this.hasDefaultVideoControls = state.hasDefaultVideoControls; if (this.callback) { this.callback(); }
diff --git a/third_party/blink/web_tests/http/tests/navigation/language/accept-language-header-expected.txt b/third_party/blink/web_tests/http/tests/navigation/language/accept-language-header-expected.txt new file mode 100644 index 0000000..080b8300 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/language/accept-language-header-expected.txt
@@ -0,0 +1,4 @@ +Tests the default Accept-Language header + +HTTP Accept-Language header should be: en-us,en +
diff --git a/third_party/blink/web_tests/http/tests/navigation/language/accept-language-header.php b/third_party/blink/web_tests/http/tests/navigation/language/accept-language-header.php new file mode 100644 index 0000000..604d33b --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/language/accept-language-header.php
@@ -0,0 +1,13 @@ +<html> +<body> +<p>Tests the default Accept-Language header</p> +<script> + if (window.testRunner) { + testRunner.dumpAsText(); + } + + let accept_language = '<?php echo $_SERVER['HTTP_ACCEPT_LANGUAGE']; ?>'; + document.write("HTTP Accept-Language header should be: " + accept_language + "<br>"); +</script> +</body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/navigation/navigator-language-in-insecure-context-disabled-expected.txt b/third_party/blink/web_tests/http/tests/navigation/navigator-language-in-insecure-context-disabled-expected.txt new file mode 100644 index 0000000..8dc6ddbb --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/navigator-language-in-insecure-context-disabled-expected.txt
@@ -0,0 +1,11 @@ +Test navigator.language and navigator.languages in insecure context. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + +FAIL navigator.language should be en-US. Was . +FAIL navigator.languages.length should be 1. Was 0. +FAIL navigator.languages[0] should be en-US (of type string). Was undefined (of type undefined). +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/blink/web_tests/http/tests/navigation/navigator-language-in-insecure-context-disabled.html b/third_party/blink/web_tests/http/tests/navigation/navigator-language-in-insecure-context-disabled.html new file mode 100644 index 0000000..d5504bd --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/navigator-language-in-insecure-context-disabled.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script src="/resources/get-host-info.js"></script> +<script> +let file_pathname = window.location.pathname; +let folder_pathname = file_pathname.substring(0, file_pathname.lastIndexOf('/')); +window.location = get_host_info().UNAUTHENTICATED_ORIGIN + folder_pathname + '/resources/navigator-language-in-insecure-context-disabled-helper.html'; +</script>
diff --git a/third_party/blink/web_tests/http/tests/navigation/resources/navigator-language-in-insecure-context-disabled-helper.html b/third_party/blink/web_tests/http/tests/navigation/resources/navigator-language-in-insecure-context-disabled-helper.html new file mode 100644 index 0000000..d898bb1 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/resources/navigator-language-in-insecure-context-disabled-helper.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script src="/js-test-resources/js-test.js"></script> +<script src="/resources/get-host-info.js"></script> +<script> +if (window.internals) + internals.runtimeFlags.navigatorLanguageInInsecureContextEnabled = false; +let is_secure_context = window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN; +let is_secure_text = is_secure_context ? "secure" : "insecure"; +description('Test navigator.language and navigator.languages in ' + is_secure_text + ' context.') +window.jsTestIsAsync = true; +shouldBe('navigator.language', '"en-US"'); +shouldBe('navigator.languages.length', '1'); +shouldBe('navigator.languages[0]', '"en-US"'); +finishJSTest(); +</script>
diff --git a/third_party/blink/web_tests/plugins/embed-attributes-setting.html b/third_party/blink/web_tests/plugins/embed-attributes-setting.html index 157361a..7c6ae40c 100644 --- a/third_party/blink/web_tests/plugins/embed-attributes-setting.html +++ b/third_party/blink/web_tests/plugins/embed-attributes-setting.html
@@ -35,6 +35,9 @@ embed = document.getElementById('embed'); print("[Embed is element specified in markup]"); + if (window.internals) + internals.updateLayoutAndRunPostLayoutTasks(); + embed.align = 1; embed.height = 1; embed.name = 1; @@ -48,15 +51,24 @@ shouldBe("embed.getAttribute('type')", 1); shouldBe("typeof embed.postMessage", "function"); + if (window.internals) + internals.updateLayoutAndRunPostLayoutTasks(); + print("----------"); embed = document.createElement('embed'); print("[Embed is dynamically created element with only type specified]"); + if (window.internals) + internals.updateLayoutAndRunPostLayoutTasks(); + embed.style.visibility = "hidden"; embed.type = "application/x-blink-test-plugin"; document.body.appendChild(embed); shouldBe("typeof embed.postMessage", "function"); + + if (window.internals) + internals.updateLayoutAndRunPostLayoutTasks(); } </script> </head>
diff --git a/third_party/blink/web_tests/virtual/disable-accept-language-header/README.md b/third_party/blink/web_tests/virtual/disable-accept-language-header/README.md new file mode 100644 index 0000000..e9c59b9 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-accept-language-header/README.md
@@ -0,0 +1 @@ +# This suite runs tests with --disable-features=AcceptLanguageHeader
diff --git a/third_party/blink/web_tests/virtual/disable-accept-language-header/http/tests/navigation/language/accept-language-header-expected.txt b/third_party/blink/web_tests/virtual/disable-accept-language-header/http/tests/navigation/language/accept-language-header-expected.txt new file mode 100644 index 0000000..a1d8c918 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-accept-language-header/http/tests/navigation/language/accept-language-header-expected.txt
@@ -0,0 +1,4 @@ +Tests the default Accept-Language header + +HTTP Accept-Language header should be: +
diff --git a/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-form-state-on-click.html b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-form-state-on-click.html index 09564259..b089f44e 100644 --- a/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-form-state-on-click.html +++ b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-form-state-on-click.html
@@ -33,7 +33,7 @@ first, "'first' should not yet be focused."); assert_false(mockSnavService.canExitFocus, - "Should be able to exit focus."); + "Nothing focused, should not be able to exit focus."); assert_true(mockSnavService.canSelectElement, "Should be able to select element."); assert_false(mockSnavService.hasNextFormElement,
diff --git a/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-video-on-click.html b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-video-on-click.html new file mode 100644 index 0000000..51736d89 --- /dev/null +++ b/third_party/blink/web_tests/virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-video-on-click.html
@@ -0,0 +1,63 @@ +<!DOCTYPE html> +<script src="../../../../../resources/testharness.js"></script> +<script src="../../../../../resources/testharnessreport.js"></script> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/third_party/blink/public/mojom/page/spatial_navigation.mojom.js"></script> +<script src="../../../../../fast/spatial-navigation/resources/mock-snav-service.js"></script> +<script src="../../../../../fast/spatial-navigation/resources/snav-testharness.js"></script> + +<video id="first" controls></video> + +<script> + async_test((t) => { + let first = document.getElementById("first"); + + mockSnavService.callback = notCalled; + + async function runTest() { + await snav.rAF(); + + snav.triggerMove('Down'); + await snavCallback(); + assert_equals(window.internals.interestedElement, + first, + "'first' should be interested."); + assert_not_equals(document.activeElement, + first, + "'first' should not yet be focused."); + assert_false(mockSnavService.canExitFocus, + "We haven't yet focused, so we should not be able to exit."); + assert_true(mockSnavService.canSelectElement, + "Should be able to select element."); + assert_false(mockSnavService.hasDefaultVideoControls, + "Nothing is focused, no default controls"); + + eventSender.keyDown('Enter'); + await snavCallback(); + assert_true(mockSnavService.canExitFocus, + "Should be able to exit focus."); + assert_true(mockSnavService.canSelectElement, + "Should be able to select element."); + assert_true(mockSnavService.hasDefaultVideoControls, + "Nothing first uses default controls"); + assert_equals(window.internals.interestedElement, + first, + "'first' should be interested."); + assert_equals(document.activeElement, + first, + "'first' should be focused."); + t.done(); + }; + + t.step_timeout(() => { + runTest(); + }, 0); + + function notCalled() { + t.step_timeout(() => { + assert_false(true, "Should not be called"); + }, 0); + }; + + }, 'Spat Nav state updates correctly when clicking on video elements.'); +</script>
diff --git a/third_party/dav1d/README.chromium b/third_party/dav1d/README.chromium index 9a3515d..33fb265 100644 --- a/third_party/dav1d/README.chromium +++ b/third_party/dav1d/README.chromium
@@ -1,7 +1,7 @@ Name: dav1d is an AV1 decoder :) Short Name: dav1d URL: https://code.videolan.org/videolan/dav1d -Version: 589e96a1f2cff8e803c79eec48509fa4a792f1d9 +Version: d400361524ce739db30d552a9e54809d812710c6 License: 2-Clause BSD License File: LICENSE Security Critical: yes
diff --git a/third_party/dav1d/dav1d_generated.gni b/third_party/dav1d/dav1d_generated.gni index b0c1ebb..cbf11b1 100644 --- a/third_party/dav1d/dav1d_generated.gni +++ b/third_party/dav1d/dav1d_generated.gni
@@ -40,6 +40,7 @@ "libdav1d/src/arm/64/loopfilter.S", "libdav1d/src/arm/64/looprestoration.S", "libdav1d/src/arm/64/mc.S", + "libdav1d/src/arm/64/msac.S", "libdav1d/src/arm/64/util.S", ]
diff --git a/third_party/jsoncpp/BUILD.gn b/third_party/jsoncpp/BUILD.gn index cf40895..739f54f 100644 --- a/third_party/jsoncpp/BUILD.gn +++ b/third_party/jsoncpp/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//testing/libfuzzer/fuzzer_test.gni") + config("jsoncpp_config") { include_dirs = [ "overrides/include", @@ -33,3 +35,13 @@ include_dirs = [ "source/src/lib_json" ] } + +fuzzer_test("jsoncpp_fuzzer") { + sources = [ + "fuzzers/json_fuzzer.cc", + ] + deps = [ + ":jsoncpp", + ] + dict = "//testing/libfuzzer/fuzzers/dicts/json.dict" +}
diff --git a/third_party/jsoncpp/fuzzers/json_fuzzer.cc b/third_party/jsoncpp/fuzzers/json_fuzzer.cc new file mode 100644 index 0000000..c587567 --- /dev/null +++ b/third_party/jsoncpp/fuzzers/json_fuzzer.cc
@@ -0,0 +1,74 @@ +// 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. +// +// JsonCpp fuzzing wrapper to help with automated fuzz testing. + +#include <stdint.h> +#include <climits> +#include <cstdio> +#include <memory> +#include "third_party/jsoncpp/source/include/json/json.h" + +// JsonCpp has a few different parsing options. The code below makes sure that +// the most intersting variants are tested. +enum { + kFeatureSetAll = 0, + kFeatureSetDefault = 1, + kFeatureSetStrict = 2, + kFeatureSetLast +}; +const int kSizeOfFeatureSet = kFeatureSetLast; + +namespace { +struct Common { + Json::Features features[kSizeOfFeatureSet]; +}; +} // namespace + +static Common* Initialize() { + static Common common; + common.features[kFeatureSetAll].allowComments_ = true; + common.features[kFeatureSetAll].strictRoot_ = false; + + common.features[kFeatureSetStrict] = Json::Features::strictMode(); + + return &common; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + static Common* common = Initialize(); + + for (int i = 0; i < kSizeOfFeatureSet; ++i) { + // Parse Json. + Json::Reader reader(common->features[i]); + Json::Value root; + bool res = reader.parse(reinterpret_cast<const char*>(data), + reinterpret_cast<const char*>(data + size), root, + /*collectComments=*/true); + if (!res) { + continue; + } + + // Write and re-read json. + Json::FastWriter writer; + std::string output_json = writer.write(root); + + Json::Value root_again; + res = reader.parse(output_json, root_again, /*collectComments=*/true); + if (!res) { + continue; + } + + // Run equality test. + // Note: This actually causes the Json::Value tree to be traversed and all + // the values to be dereferenced (until two of them are found not equal), + // which is great for detecting memory corruption bugs when compiled with + // AddressSanitizer. The result of the comparison is ignored, as it is + // expected that both the original and the re-read version will differ from + // time to time (e.g. due to floating point accuracy loss). + (void)(root == root_again); + } + + return 0; +}
diff --git a/tools/checklicenses/checklicenses.py b/tools/checklicenses/checklicenses.py index e670c68..0d455fc 100755 --- a/tools/checklicenses/checklicenses.py +++ b/tools/checklicenses/checklicenses.py
@@ -456,9 +456,6 @@ 'third_party/openh264/src': [ 'UNKNOWN', ], - 'third_party/openmax_dl/dl' : [ - 'Khronos Group', - ], 'third_party/boringssl': [ # There are some files in BoringSSL which came from OpenSSL and have no # license in them. We don't wish to add the license header ourselves
diff --git a/tools/ipc_fuzzer/fuzzer/BUILD.gn b/tools/ipc_fuzzer/fuzzer/BUILD.gn index a1363d1..cb39a9a3 100644 --- a/tools/ipc_fuzzer/fuzzer/BUILD.gn +++ b/tools/ipc_fuzzer/fuzzer/BUILD.gn
@@ -19,6 +19,7 @@ "rand_util.h", ] deps = [ + "//base/util/type-safety", "//tools/ipc_fuzzer/message_lib:ipc_message_lib", ] public_deps = [
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc index 12d284e5..2ccefca2 100644 --- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc +++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -15,6 +15,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/unguessable_token.h" +#include "base/util/type-safety/id_type.h" #include "base/values.h" #include "build/build_config.h" #include "ipc/ipc_message.h" @@ -947,8 +948,8 @@ }; template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> -struct FuzzTraits<gpu::IdType<TypeMarker, WrappedType, kInvalidValue>> { - using param_type = gpu::IdType<TypeMarker, WrappedType, kInvalidValue>; +struct FuzzTraits<util::IdType<TypeMarker, WrappedType, kInvalidValue>> { + using param_type = util::IdType<TypeMarker, WrappedType, kInvalidValue>; static bool Fuzz(param_type* id, Fuzzer* fuzzer) { WrappedType raw_value = id->GetUnsafeValue(); if (!FuzzParam(&raw_value, fuzzer))
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 6ca8802..e519e41 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -4531,6 +4531,7 @@ </action> <action name="ContextualSuggestions"> + <obsolete>This feature was deprecated in M74</obsolete> <owner>huayinz@chromium.org</owner> <owner>twellington@chromium.com</owner> <owner>wylieb@chromium.com</owner> @@ -4538,6 +4539,7 @@ </action> <action name="ContextualSuggestions.ContextMenu"> + <obsolete>This feature was deprecated in M74</obsolete> <owner>huayinz@chromium.org</owner> <owner>twellington@chromium.com</owner> <description> @@ -4547,6 +4549,7 @@ </action> <action name="ContextualSuggestions.Preference.Disabled"> + <obsolete>This feature was deprecated in M74</obsolete> <owner>huayinz@chromium.org</owner> <owner>twellington@chromium.org</owner> <description> @@ -4556,6 +4559,7 @@ </action> <action name="ContextualSuggestions.Preference.Enabled"> + <obsolete>This feature was deprecated in M74</obsolete> <owner>huayinz@chromium.org</owner> <owner>twellington@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 9d18ed2..7fffad1c 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3823,6 +3823,16 @@ <int value="3" label="User navigated away from page while bubble hidden"/> </enum> +<enum name="AutofillLocalCardMigrationDecisionMetric"> + <int value="0" label="Migration offered"/> + <int value="1" label="User used new card"/> + <int value="2" label="Failed enablement prerequisites"/> + <int value="3" label="Reached max strikes"/> + <int value="4" label="No migratable cards"/> + <int value="5" label="Get upload details RPC failed"/> + <int value="6" label="All cards are unsupported"/> +</enum> + <enum name="AutofillLocalCardMigrationDialogOffer"> <int value="0" label="Shown"/> <int value="1" label="Not shown due to legal message being invalid"/> @@ -9624,12 +9634,18 @@ </enum> <enum name="ContextualSuggestions.ClickDuration"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <int value="0" label="Short (<4 seconds)"/> <int value="1" label="Medium (4-180 seconds)"/> <int value="2" label="Long (>180 seconds)"/> </enum> <enum name="ContextualSuggestions.Event"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <int value="0" label="Uninitialized"/> <int value="1" label="Fetch delayed"/> <int value="2" label="Fetch requested"/> @@ -23149,6 +23165,7 @@ label="V8RTCRtpReceiver_JitterBufferDelayHint_AttributeSetter"/> <int value="2888" label="MediaCapabilitiesDecodingInfoWithKeySystemConfig"/> <int value="2889" label="RevertInCustomIdent"/> + <int value="2890" label="UnoptimizedImagePolicies"/> </enum> <enum name="FeaturePolicyFeature"> @@ -34174,6 +34191,7 @@ <int value="313253630" label="AutofillRefreshStyleAndroid:enabled"/> <int value="313303258" label="WebPaymentsModifiers:disabled"/> <int value="316182183" label="MediaDocumentDownloadButton:disabled"/> + <int value="317432596" label="DisplayLocking:disabled"/> <int value="319683583" label="ContentSuggestionsDebugLog:enabled"/> <int value="320121752" label="DelegateOverscrollSwipes:disabled"/> <int value="323605372" label="ui-disable-compositor-animation-timelines"/> @@ -35143,6 +35161,7 @@ <int value="1803470125" label="SyncUSSSessions:enabled"/> <int value="1807374811" label="CCTModuleCache:enabled"/> <int value="1809940714" label="SpeculativeLaunchServiceWorker:disabled"/> + <int value="1810258949" label="DisplayLocking:enabled"/> <int value="1810311887" label="WebAssemblyThreads:enabled"/> <int value="1812368073" label="enable-new-app-list-mixer"/> <int value="1814671708" label="disable-password-manager-reauthentication"/> @@ -40555,6 +40574,11 @@ <int value="4" label="Unknown"/> </enum> +<enum name="NetworkCellularConnectionState"> + <int value="0" label="Connected"/> + <int value="1" label="Disconnected"/> +</enum> + <enum name="NetworkCellularOutOfCreditsReason"> <int value="0" label="Connect-Disconnect Loop"/> <int value="1" label="TX-Queue Congestion"/> @@ -43575,6 +43599,13 @@ <int value="5" label="Weak signature algorithm"/> </enum> +<enum name="PasswordDecryptionResult"> + <int value="0" label="Failed"/> + <int value="1" label="Succeeded"/> + <int value="2" label="Succeeded by skipping"/> + <int value="3" label="Succeeded by ignoring failure"/> +</enum> + <enum name="PasswordDropdownSelectedOption"> <int value="0" label="Password"/> <int value="1" label="Manage passwords"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f1a347e..4f531cc 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -322,7 +322,7 @@ </histogram> <histogram name="Accessibility.CrosSwitchAccessAfterChromeVox" - enum="BooleanEnabled"> + enum="BooleanEnabled" expires_after="M78"> <owner>anastasi@google.com</owner> <owner>dtseng@chromium.org</owner> <summary> @@ -1109,7 +1109,8 @@ </summary> </histogram> -<histogram name="AnchorElementMetrics.Clicked.RatioInIframe_InIframe" units="%"> +<histogram name="AnchorElementMetrics.Clicked.RatioInIframe_InIframe" units="%" + expires_after="M78"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> <summary> @@ -1130,7 +1131,8 @@ </summary> </histogram> -<histogram name="AnchorElementMetrics.Clicked.RatioRootHeight" units="%"> +<histogram name="AnchorElementMetrics.Clicked.RatioRootHeight" units="%" + expires_after="M78"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> <summary> @@ -1166,7 +1168,7 @@ <histogram name="AnchorElementMetrics.Clicked.RatioUrlIncremented_NotIncremented" - units="%"> + units="%" expires_after="M78"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> <summary> @@ -1179,7 +1181,7 @@ <histogram name="AnchorElementMetrics.Clicked.RatioUrlIncremented_UrlIncremented" - units="%"> + units="%" expires_after="M78"> <owner>chelu@chromium.org</owner> <owner>tbansal@chromium.org</owner> <summary> @@ -2194,7 +2196,7 @@ </summary> </histogram> -<histogram name="Android.HistoryPage.RemoveSelected"> +<histogram name="Android.HistoryPage.RemoveSelected" expires_after="M78"> <owner>twellington@chromium.org</owner> <summary> The number of selected items the user removed from the native Android @@ -2347,7 +2349,7 @@ <histogram name="Android.MainActivity.ExplicitMainViewIntentDispatched.OnCreate" - enum="BooleanDispatched"> + enum="BooleanDispatched" expires_after="M78"> <owner>wnwen@chromium.org</owner> <summary> Whether VIEW intent sent explicitly to .Main activity was dispatched by @@ -2940,7 +2942,8 @@ </summary> </histogram> -<histogram name="Android.StrictMode.CheckGoogleSignedTime" units="ms"> +<histogram name="Android.StrictMode.CheckGoogleSignedTime" units="ms" + expires_after="M78"> <owner>estevenson@chromium.org</owner> <owner>wnwen@chromium.org</owner> <summary> @@ -4332,7 +4335,7 @@ </summary> </histogram> -<histogram name="Apps.AppShimErrorVersion"> +<histogram name="Apps.AppShimErrorVersion" expires_after="M78"> <owner>jackhou@chromium.org</owner> <summary> Counts which major milestone versions of app_mode_loader are sending @@ -4563,7 +4566,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.LockScreenAppUnloaded" - enum="LockScreenAppUnloadStatus"> + enum="LockScreenAppUnloadStatus" expires_after="M78"> <owner>tbarzic@chromium.org</owner> <summary> Reported when a note taking app is unloaded from the lock screen apps @@ -4595,7 +4598,8 @@ </summary> </histogram> -<histogram name="Apps.LockScreen.NoteTakingApp.ReloadCountOnAppTermination"> +<histogram name="Apps.LockScreen.NoteTakingApp.ReloadCountOnAppTermination" + expires_after="M78"> <owner>tbarzic@chromium.org</owner> <summary> Reported when a note taking app is terminated in the lock screen apps @@ -8524,7 +8528,7 @@ </summary> </histogram> -<histogram name="Autofill.CanLogUKM" enum="BooleanEnabled"> +<histogram name="Autofill.CanLogUKM" enum="BooleanEnabled" expires_after="M78"> <owner>dlkumar@google.com</owner> <owner>chrome-autofill@google.com</owner> <summary> @@ -8999,6 +9003,17 @@ <summary>Record how bubble is closed by different user interactions.</summary> </histogram> +<histogram name="Autofill.LocalCardMigrationDecision" + enum="AutofillLocalCardMigrationDecisionMetric" expires_after="2019-11-30"> + <owner>sujiezhu@google.com</owner> + <owner>siyua@chromium.org</owner> + <owner>jsaul@google.com</owner> + <summary> + Record the decisions made when determining if local card migration should be + offered. + </summary> +</histogram> + <histogram name="Autofill.LocalCardMigrationDialogActiveDuration" units="ms"> <owner>siyua@chromium.org</owner> <summary> @@ -10714,7 +10729,8 @@ </summary> </histogram> -<histogram name="BackgroundFetch.HasRequestsWithBody" enum="Boolean"> +<histogram name="BackgroundFetch.HasRequestsWithBody" enum="Boolean" + expires_after="M78"> <owner>nator@chromium.org</owner> <owner>rayankans@chromium.org</owner> <owner>peter@chromium.org</owner> @@ -10999,7 +11015,8 @@ </summary> </histogram> -<histogram name="BackgroundSync.NetworkObserver.HasPermission" enum="Boolean"> +<histogram name="BackgroundSync.NetworkObserver.HasPermission" enum="Boolean" + expires_after="M78"> <owner>iclelland@chromium.org</owner> <summary> Records whether the browser has sufficient permissions to create a @@ -11052,7 +11069,7 @@ </histogram> <histogram name="BackgroundSync.Registration.OneShot.IsDuplicate" - enum="BooleanRegistrationIsDuplicate"> + enum="BooleanRegistrationIsDuplicate" expires_after="M78"> <owner>iclelland@chromium.org</owner> <summary> Records whether a one-shot sync registration exactly duplicates an existing @@ -11692,7 +11709,7 @@ </histogram> <histogram base="true" name="Blink.Canvas.ToBlob.IdleTaskStatus" - enum="IdleTaskStatus"> + enum="IdleTaskStatus" expires_after="M78"> <owner>fserb@chromium.org</owner> <owner>davidqu@chromium.org</owner> <summary> @@ -13442,7 +13459,7 @@ </summary> </histogram> -<histogram name="BlinkGC.CommittedSize" units="MB"> +<histogram name="BlinkGC.CommittedSize" units="MB" expires_after="M78"> <owner>haraken@chromium.org</owner> <summary> The committed memory size in Blink GC. The value is reported when we see the @@ -13538,7 +13555,7 @@ <histogram name="BlinkGC.SlowIncrementalMarkingFinalize.IncrementalMarkingFinalize" - units="ms"> + units="ms" expires_after="M78"> <owner>oilpan-reviews@chromium.org</owner> <summary> Duration of time for incremental marking finalization. Only recorded when @@ -13566,7 +13583,7 @@ <histogram name="BlinkGC.SlowIncrementalMarkingFinalize.VisitCrossThreadPersistents" - units="ms"> + units="ms" expires_after="M78"> <owner>oilpan-reviews@chromium.org</owner> <summary> Duration of time taken to visit cross thread persistents. Only recorded when @@ -15159,7 +15176,7 @@ <summary>An open bubble was closed because the user accepted it.</summary> </histogram> -<histogram name="Bubbles.Close.Canceled" enum="BubbleType"> +<histogram name="Bubbles.Close.Canceled" enum="BubbleType" expires_after="M78"> <owner>hcarmona@chromium.org</owner> <summary> An open bubble was closed because the user didn't accept it. @@ -15188,7 +15205,7 @@ </summary> </histogram> -<histogram name="Bubbles.Close.Navigated" enum="BubbleType"> +<histogram name="Bubbles.Close.Navigated" enum="BubbleType" expires_after="M78"> <owner>hcarmona@chromium.org</owner> <summary> An open bubble was dismissed because the page was navigated. @@ -15416,7 +15433,7 @@ </histogram> <histogram name="CaptivePortal.Notification.Status" - enum="CaptivePortalNotificationStatus"> + enum="CaptivePortalNotificationStatus" expires_after="M78"> <owner>alemate@chromium.org</owner> <summary> Count of displayed and not displayed due to errors notifications about @@ -16722,7 +16739,7 @@ </histogram> <histogram name="ChromeOS.SAML.Scraping.VerificationResult" - enum="BooleanSuccess"> + enum="BooleanSuccess" expires_after="M78"> <owner>bartfab@chromium.org</owner> <summary> Whether one of the scraped passwords was successfully verified as the user's @@ -18708,7 +18725,8 @@ <summary>The default handler setting at profile open.</summary> </histogram> -<histogram name="ContentSettings.DefaultImagesSetting" enum="ContentSetting"> +<histogram name="ContentSettings.DefaultImagesSetting" enum="ContentSetting" + expires_after="M78"> <owner>toyoshim@chromium.org</owner> <summary>The default image setting at profile open.</summary> </histogram> @@ -18730,7 +18748,8 @@ </summary> </histogram> -<histogram name="ContentSettings.DefaultLocationSetting" enum="ContentSetting"> +<histogram name="ContentSettings.DefaultLocationSetting" enum="ContentSetting" + expires_after="M78"> <owner>toyoshim@chromium.org</owner> <summary>The default location setting at profile open.</summary> </histogram> @@ -19921,6 +19940,9 @@ </histogram> <histogram name="ContextualSuggestions.EnabledState" enum="BooleanEnabled"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>huayinz@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> @@ -19932,6 +19954,9 @@ <histogram name="ContextualSuggestions.Events" enum="ContextualSuggestions.Event"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>donnd@chromium.org</owner> <owner>fgorski@chromium.org</owner> <owner>twellington@chromium.org</owner> @@ -19943,6 +19968,9 @@ </histogram> <histogram name="ContextualSuggestions.FetchErrorCode" enum="NetErrorCodes"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>pnoland@chromium.org</owner> <summary> Android: The net::Error status code of contextual suggestion fetches. @@ -19950,8 +19978,10 @@ </summary> </histogram> -<histogram name="ContextualSuggestions.FetchLatencyMilliseconds" units="ms" - expires_after="M77"> +<histogram name="ContextualSuggestions.FetchLatencyMilliseconds" units="ms"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>pnoland@chromium.org</owner> <owner>fgorski@chromium.org</owner> <summary> @@ -19960,18 +19990,22 @@ </summary> </histogram> -<histogram name="ContextualSuggestions.FetchRequestProtoSizeKB" units="KB" - expires_after="M77"> +<histogram name="ContextualSuggestions.FetchRequestProtoSizeKB" units="KB"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>pnoland@chromium.org</owner> <summary> Android: The size of the serialized and base64-encoded proto sent to the server when fetching contextual suggestions. Recorded when a fetch is - initiated. </summary> </histogram> <histogram name="ContextualSuggestions.FetchResponseCode" enum="HttpResponseCode"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>pnoland@chromium.org</owner> <summary> Android: The http status code of contextual suggestion fetches. Recorded @@ -19979,8 +20013,10 @@ </summary> </histogram> -<histogram name="ContextualSuggestions.FetchResponseNetworkBytes" units="bytes" - expires_after="M77"> +<histogram name="ContextualSuggestions.FetchResponseNetworkBytes" units="bytes"> + <obsolete> + This feature was deprecated in M75 + </obsolete> <owner>pnoland@chromium.org</owner> <summary> Android: The number of bytes in the response received when a contextual @@ -19991,8 +20027,7 @@ <histogram name="ContextualSuggestions.FetchResponseSizeKB" units="KB" expires_after="2018-06-04"> <obsolete> - Removed 2018-06-01 in favor of a histogram that measures bytes received over - the network directly instead of the uncompressed KB. + This feature was deprecated in M74 </obsolete> <owner>pnoland@chromium.org</owner> <summary> @@ -20003,6 +20038,9 @@ <histogram name="ContextualSuggestions.PageViewClickLength" enum="ContextualSuggestions.ClickDuration"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -20015,8 +20053,10 @@ </summary> </histogram> -<histogram name="ContextualSuggestions.PageViewTime" units="ms" - expires_after="M77"> +<histogram name="ContextualSuggestions.PageViewTime" units="ms"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>fgorski@chromium.org</owner> <owner>wylieb@chromium.org</owner> <summary> @@ -20029,8 +20069,10 @@ </summary> </histogram> -<histogram name="ContextualSuggestions.Preference.State" enum="BooleanEnabled" - expires_after="M77"> +<histogram name="ContextualSuggestions.Preference.State" enum="BooleanEnabled"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>huayinz@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> @@ -20055,6 +20097,9 @@ <histogram name="ContextualSuggestions.SuggestionClickPosition.Cluster" units="index" expires_after="2019-05-30"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>twellington@chromium.org</owner> <owner>huayinz@chromium.org</owner> <summary> @@ -20065,6 +20110,9 @@ <histogram name="ContextualSuggestions.SuggestionClickPosition.Global" units="index" expires_after="2019-05-30"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>twellington@chromium.org</owner> <owner>huayinz@chromium.org</owner> <summary> @@ -21493,7 +21541,7 @@ </histogram> <histogram name="Cryptohome.DircryptoMigrationFailedOperationType" - enum="DircryptoMigrationFailedOperationType"> + enum="DircryptoMigrationFailedOperationType" expires_after="M78"> <owner>kinaba@chromium.org</owner> <summary> The type of file operation at which the user home directory migration from @@ -21503,7 +21551,7 @@ </histogram> <histogram name="Cryptohome.DircryptoMigrationFailedPathType" - enum="DircryptoMigrationFailedPathType"> + enum="DircryptoMigrationFailedPathType" expires_after="M78"> <owner>kinaba@chromium.org</owner> <summary> The category of the path where the user home directory migration from @@ -22568,7 +22616,7 @@ <histogram name="DataReductionProxy.DaysSinceSavingsCleared.NegativeSystemClock" - units="days"> + units="days" expires_after="M78"> <owner>tbansal@chromium.org</owner> <owner>bengr@chromium.org</owner> <summary> @@ -26767,7 +26815,7 @@ <summary>Wall time between starting and finishing DNS probe.</summary> </histogram> -<histogram name="DnsProbe.ProbeDuration2" units="ms"> +<histogram name="DnsProbe.ProbeDuration2" units="ms" expires_after="M78"> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary>Time ticks between starting and finishing DNS probe.</summary> @@ -28412,7 +28460,7 @@ </histogram> <histogram name="Download.MaliciousDownloadClassified" - enum="DownloadItem.DangerType"> + enum="DownloadItem.DangerType" expires_after="M78"> <owner>dtrainor@chromium.org</owner> <owner>felt@chromium.org</owner> <summary> @@ -28853,7 +28901,8 @@ </summary> </histogram> -<histogram base="true" name="Download.Service.Finish.FileSize" units="KB"> +<histogram base="true" name="Download.Service.Finish.FileSize" units="KB" + expires_after="M78"> <!-- Name completed by histogram_suffixes name="Download.Service.CompletionType" --> @@ -30547,7 +30596,7 @@ </histogram> <histogram name="Enterprise.EnrollmentAttestationBased" - enum="EnterpriseEnrollmentType"> + enum="EnterpriseEnrollmentType" expires_after="M78"> <owner>drcrash@chromium.org</owner> <summary> Events related to attestation-based enrollment (Zero-Touch) of Chrome OS @@ -30620,7 +30669,8 @@ </summary> </histogram> -<histogram name="Enterprise.EnrollmentRecovery" enum="EnterpriseEnrollmentType"> +<histogram name="Enterprise.EnrollmentRecovery" enum="EnterpriseEnrollmentType" + expires_after="M78"> <owner>tnagel@chromium.org</owner> <summary> Events related to Chrome OS enterprise enrollment recovery. Note that this @@ -31006,7 +31056,7 @@ <histogram name="Enterprise.UserPolicyChromeOS.InitialFetch.DelayClientRegister" - units="ms"> + units="ms" expires_after="M78"> <owner>mnissler@chromium.org</owner> <summary>Delay for registering the client with the policy server.</summary> </histogram> @@ -31384,7 +31434,8 @@ </summary> </histogram> -<histogram name="Event.ClickNotFiredDueToDomManipulation" enum="BooleanHit"> +<histogram name="Event.ClickNotFiredDueToDomManipulation" enum="BooleanHit" + expires_after="M78"> <owner>nzolghadr@chromium.org</owner> <summary> Whether click target was affected by DOM manipulation or not. @@ -32575,7 +32626,8 @@ </summary> </histogram> -<histogram name="Event.Latency.QueueingTime.KeyPressDefaultAllowed" units="ms"> +<histogram name="Event.Latency.QueueingTime.KeyPressDefaultAllowed" units="ms" + expires_after="M78"> <owner>tdresser@chromium.org</owner> <owner>input-dev@chromium.org</owner> <summary> @@ -33132,7 +33184,7 @@ <histogram name="Event.Latency.ScrollInertial.Touch.BrowserNotifiedToBeforeGpuSwap2" - units="microseconds"> + units="microseconds" expires_after="M78"> <owner>sahel@chromium.org</owner> <summary> Time between the browser receives the notification of a ScrollUpdate gesture @@ -33168,7 +33220,7 @@ <histogram name="Event.Latency.ScrollInertial.Touch.RendererSwapToBrowserNotified2" - units="microseconds"> + units="microseconds" expires_after="M78"> <owner>sahel@chromium.org</owner> <summary> Time between the renderer starts to swap a frame induced by a ScrollUpdate @@ -35484,7 +35536,8 @@ </summary> </histogram> -<histogram name="Extensions.ApiTabUpdateJavascript" enum="Boolean"> +<histogram name="Extensions.ApiTabUpdateJavascript" enum="Boolean" + expires_after="M78"> <owner>dbertoni@chromium.org</owner> <summary> Reports whether a tab was updated to a javascript:-scheme URL from the @@ -35826,7 +35879,7 @@ <histogram name="Extensions.BrowsingInstanceViolation.IsBackgroundSourceOrTarget" - enum="ExtensionViewTypeIsBackground"> + enum="ExtensionViewTypeIsBackground" expires_after="M78"> <owner>lukasza@chromium.org</owner> <summary> When an extension violates browsing instance boundaries, this metric records @@ -36397,7 +36450,7 @@ <histogram name="Extensions.DeclarativeWebRequest.WebViewRequestDeclarativeRules" - enum="BooleanDeclarativeRules"> + enum="BooleanDeclarativeRules" expires_after="M78"> <owner>karandeepb@chromium.org</owner> <summary> Whether a network request from a guest webview has any declarative web @@ -36776,7 +36829,7 @@ </summary> </histogram> -<histogram name="Extensions.ExtensionCacheCount"> +<histogram name="Extensions.ExtensionCacheCount" expires_after="M78"> <owner>achuith@chromium.org</owner> <summary> Number of cached extensions on disk. Reported on Chrome OS during user @@ -39853,7 +39906,7 @@ </histogram> <histogram name="FCMInvalidations.FailedSubscriptionsErrorCode" - enum="NetErrorCodes"> + enum="NetErrorCodes" expires_after="M78"> <owner>melandory@chromium.org</owner> <summary>Net error codes for failed subscription requests.</summary> </histogram> @@ -44198,7 +44251,8 @@ </summary> </histogram> -<histogram name="HIDDetection.TimesDialogShownPerOOBECompleted"> +<histogram name="HIDDetection.TimesDialogShownPerOOBECompleted" + expires_after="M78"> <owner>alemate@chromium.org</owner> <summary> Records number of times the dialog was shown by the time OOBE is completed. @@ -46349,7 +46403,7 @@ </summary> </histogram> -<histogram name="InputMethod.PkCommit.Index"> +<histogram name="InputMethod.PkCommit.Index" expires_after="M78"> <owner>shuchen@chromium.org</owner> <summary> The suggestion index (1-based) of the suggestion list item which user @@ -48850,7 +48904,7 @@ <histogram name="JSDialogs.FineTiming.TimeBetweenDialogClosedAndNextDialogCreated" - units="ms"> + units="ms" expires_after="M78"> <owner>joenotcharles@chromium.org</owner> <summary> Fine-grained (in msec) time between closing a Javascript dialog and opening @@ -48860,7 +48914,7 @@ <histogram name="JSDialogs.FineTiming.TimeBetweenDialogCreatedAndNextDialogCreated" - units="ms"> + units="ms" expires_after="M78"> <owner>joenotcharles@chromium.org</owner> <summary> Fine-grained (in msec) time between opening a Javascript dialog and opening @@ -48870,7 +48924,7 @@ <histogram name="JSDialogs.FineTiming.TimeBetweenDialogCreatedAndSameDialogClosed" - units="ms"> + units="ms" expires_after="M78"> <owner>joenotcharles@chromium.org</owner> <summary> Fine-grained (in msec) time between opening a Javascript dialog and closing @@ -49180,6 +49234,9 @@ </histogram> <histogram name="Launch.MashService" enum="MashService"> + <obsolete> + Deprecated 2019-05 -- removed as part of removing mash code + </obsolete> <owner>jamescook@chromium.org</owner> <summary> Records when a mojo ash UI service is started, for example the mojo app @@ -50388,7 +50445,8 @@ </summary> </histogram> -<histogram name="ManagedUsers.KidsManagementClassifyUrlFailureDelay" units="ms"> +<histogram name="ManagedUsers.KidsManagementClassifyUrlFailureDelay" units="ms" + expires_after="M78"> <owner>escordeiro@chromium.org</owner> <owner>unichrome-eng@google.com</owner> <summary> @@ -50399,7 +50457,8 @@ </summary> </histogram> -<histogram name="ManagedUsers.KidsManagementClassifyUrlSuccessDelay" units="ms"> +<histogram name="ManagedUsers.KidsManagementClassifyUrlSuccessDelay" units="ms" + expires_after="M78"> <owner>escordeiro@chromium.org</owner> <owner>unichrome-eng@google.com</owner> <summary> @@ -50411,7 +50470,7 @@ </histogram> <histogram name="ManagedUsers.KidsManagementUrlCheckerResponseStatus" - enum="KidsManagementURLCheckerResponseStatus"> + enum="KidsManagementURLCheckerResponseStatus" expires_after="M78"> <owner>escordeiro@chromium.org</owner> <owner>unichrome-eng@google.com</owner> <summary> @@ -52493,7 +52552,7 @@ </histogram> <histogram name="Media.CodecImage.ImageReaderGLOwner.WaitTimeForFrame" - units="ms"> + units="ms" expires_after="M78"> <owner>vikassoni@chromium.org</owner> <summary> Time spent waiting for a frame to become available in a Non Overlay @@ -52513,7 +52572,7 @@ </histogram> <histogram name="Media.CodecImage.SurfaceTextureGLOwner.WaitTimeForFrame" - units="ms"> + units="ms" expires_after="M78"> <owner>liberato@chromium.org</owner> <summary> Time spent waiting for a frame to become available in a Non Overlay @@ -53203,7 +53262,7 @@ <histogram name="Media.Engagement.SignificantPlayers.PlayerNotAdded.AfterFirstTime" - enum="InsignificantPlaybackReason"> + enum="InsignificantPlaybackReason" expires_after="M78"> <owner>beccahughes@chromium.org</owner> <owner>media-dev@chromium.org</owner> <summary> @@ -54999,7 +55058,8 @@ </summary> </histogram> -<histogram name="Media.VAVEA.EncoderFailure" enum="VAVEAEncoderFailure"> +<histogram name="Media.VAVEA.EncoderFailure" enum="VAVEAEncoderFailure" + expires_after="M78"> <owner>posciak@chromium.org</owner> <summary> Error codes reported by video encode using VA-API hardware video encoder. @@ -55501,7 +55561,7 @@ <histogram name="Media.VideoCaptureService.DurationFromLastConnectToClosingConnectionAfterCapture" - units="ms"> + units="ms" expires_after="M78"> <owner>chfremer@chromium.org</owner> <summary> Measures the duration from the time the Browser connected to the video @@ -55513,7 +55573,7 @@ <histogram name="Media.VideoCaptureService.DurationFromLastConnectToClosingConnectionAfterEnumerationOnly" - units="ms"> + units="ms" expires_after="M78"> <owner>chfremer@chromium.org</owner> <summary> Measures the duration from the time the Browser connected to the video @@ -55525,7 +55585,7 @@ <histogram name="Media.VideoCaptureService.DurationFromLastConnectToConnectionLost" - units="ms"> + units="ms" expires_after="M78"> <owner>chfremer@chromium.org</owner> <summary> Measures the duration from the time the Browser connected to the video @@ -55558,7 +55618,7 @@ <histogram name="Media.VideoCaptureService.DurationUntilReconnectAfterEnumerationOnly" - units="ms"> + units="ms" expires_after="M78"> <owner>chfremer@chromium.org</owner> <summary> Measures the duration from the time the Browser last closed or lost @@ -55804,7 +55864,7 @@ </histogram> <histogram name="Media.VTVDA.HardwareAccelerated" - enum="BooleanHardwareAccelerated"> + enum="BooleanHardwareAccelerated" expires_after="M78"> <owner>sandersd@chromium.org</owner> <summary> Whether a VTDecompressionSession is internally using hardware accelerated @@ -56249,7 +56309,7 @@ </histogram> <histogram name="MediaRouter.Provider.CreateRoute.Result.WiredDisplay" - enum="MediaRouteProviderResult"> + enum="MediaRouteProviderResult" expires_after="M78"> <owner>takumif@chromium.org</owner> <summary> Result of a request to the wired display MediaRouteProvider to create a @@ -56295,7 +56355,7 @@ </histogram> <histogram name="MediaRouter.Provider.TerminateRoute.Result.WiredDisplay" - enum="MediaRouteProviderResult"> + enum="MediaRouteProviderResult" expires_after="M78"> <owner>takumif@chromium.org</owner> <summary> Result of a request to the wired display MediaRouteProvider to terminate a @@ -62328,7 +62388,7 @@ <histogram name="Navigation.URLLoaderNetworkService.OnCompleteCertificateChainsSize" - units="KB"> + units="KB" expires_after="M78"> <owner>estark@chromium.org</owner> <summary> When the navigation URL loader receives an OnComplete message from the @@ -63814,7 +63874,7 @@ </histogram> <histogram name="Net.CertificateTransparency.CanInclusionCheckSCT" - enum="SCTCanBeChecked"> + enum="SCTCanBeChecked" expires_after="M78"> <owner>estark@chromium.org</owner> <owner>rsleevi@chromium.org</owner> <summary> @@ -63949,7 +64009,7 @@ </histogram> <histogram name="Net.CertificateTransparency.DnsQueryAuditProofError" - enum="NetErrorCodes"> + enum="NetErrorCodes" expires_after="M78"> <owner>robpercival@chromium.org</owner> <summary> Counts of specific error codes returned by LogDnsClient at the end of an @@ -63969,7 +64029,8 @@ </summary> </histogram> -<histogram name="Net.CertificateTransparency.DnsQueryDuration" units="ms"> +<histogram name="Net.CertificateTransparency.DnsQueryDuration" units="ms" + expires_after="M78"> <owner>robpercival@chromium.org</owner> <summary> The time taken attempting to obtain an inclusion proof from a Certificate @@ -63979,7 +64040,7 @@ </histogram> <histogram name="Net.CertificateTransparency.DnsQueryDuration.Success" - units="ms"> + units="ms" expires_after="M78"> <owner>robpercival@chromium.org</owner> <summary> The time taken to successfully obtain an inclusion proof from a Certificate @@ -63999,7 +64060,7 @@ </histogram> <histogram name="Net.CertificateTransparency.DnsQueryLeafIndexRcode" - enum="AsyncDNSRcode"> + enum="AsyncDNSRcode" expires_after="M78"> <owner>robpercival@chromium.org</owner> <summary> Counts of specific DNS response codes returned by LogDnsClient at the end of @@ -64069,7 +64130,7 @@ </histogram> <histogram name="Net.CertificateTransparency.InclusionCheckResult" - enum="CTLogEntryInclusionCheckResult"> + enum="CTLogEntryInclusionCheckResult" expires_after="M78"> <owner>estark@chromium.org</owner> <owner>rsleevi@chromium.org</owner> <summary> @@ -65927,7 +65988,7 @@ </histogram> <histogram name="Net.ErrorCodesForTLS13ExperimentMainFrame2" - enum="NetErrorCodes"> + enum="NetErrorCodes" expires_after="M78"> <owner>svaldez@chromium.org</owner> <summary> Positive net error codes that requests for pages end with, including net::OK @@ -67277,7 +67338,7 @@ <histogram name="Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess" - units="requests"> + units="requests" expires_after="M78"> <owner>yhirano@chromium.org</owner> <summary> The peak number of concurrent outstanding requests with keepalive specified @@ -67287,7 +67348,7 @@ <histogram name="Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess2" - units="requests"> + units="requests" expires_after="M78"> <owner>yhirano@chromium.org</owner> <summary> The peak number of concurrent outstanding requests with keepalive specified @@ -68900,7 +68961,7 @@ </histogram> <histogram name="Net.QuicSession.ActiveStreamsOnGoAwayAfterPathDegrading" - units="Streams"> + units="Streams" expires_after="M78"> <owner>renjietang@chromium.org</owner> <summary> The number of active streams when the quic session decides to go away on @@ -69210,7 +69271,7 @@ </histogram> <histogram name="Net.QuicSession.DrainingStreamsOnGoAwayAfterPathDegrading" - units="Streams"> + units="Streams" expires_after="M78"> <owner>renjietang@chromium.org</owner> <summary> The number of draining streams when the quic session decides to go away on @@ -69945,7 +70006,7 @@ </histogram> <histogram name="Net.QuicSession.UnexpectedOpenStreams" - enum="QuicSessionLocations"> + enum="QuicSessionLocations" expires_after="M78"> <owner>rch@chromium.org</owner> <summary> The location in quic_client_session.cc where there were unexpected open @@ -71388,7 +71449,8 @@ </summary> </histogram> -<histogram name="Net.SSL_Connection_Error_TLS13Experiment" enum="NetErrorCodes"> +<histogram name="Net.SSL_Connection_Error_TLS13Experiment" enum="NetErrorCodes" + expires_after="M78"> <owner>svaldez@chromium.org</owner> <summary> Counts of specific error codes returned when opening an SSL connection for @@ -73531,6 +73593,15 @@ </summary> </histogram> +<histogram name="Network.Cellular.Connection.Disconnections" + enum="NetworkCellularConnectionState"> + <owner>azeemarshad@chromium.org</owner> + <summary> + Tracks when cellular network is connected and when cellular network is + disconnected without explicit user action. + </summary> +</histogram> + <histogram name="Network.Cellular.Connection.TimeToConnected" units="ms"> <owner>azeemarshad@chromium.org</owner> <summary> @@ -73939,7 +74010,8 @@ </summary> </histogram> -<histogram name="Network.Shill.CorruptedProfile" enum="NetworkCorruptedProfile"> +<histogram name="Network.Shill.CorruptedProfile" enum="NetworkCorruptedProfile" + expires_after="M78"> <owner>benchan@chromium.org</owner> <summary> Chrome OS cellular network metric that tracks the number of corrupted @@ -74662,7 +74734,8 @@ </summary> </histogram> -<histogram name="Network.Shill.WiFi.ApDisconnectType" enum="WiFiStatusType"> +<histogram name="Network.Shill.WiFi.ApDisconnectType" enum="WiFiStatusType" + expires_after="M78"> <owner>kirtika@chromium.org</owner> <summary> Chrome OS network usage metric. Broad category of reason AP disconnected a @@ -76600,7 +76673,7 @@ <histogram name="NewTabPage.ContentSuggestions.UIUpdateSuccessNumberOfSuggestionsSeen" - units="suggestions"> + units="suggestions" expires_after="M78"> <owner>jkrcal@chromium.org</owner> <summary> Android: The number of content suggestions that have been seen by the user @@ -77283,7 +77356,7 @@ </summary> </histogram> -<histogram name="NewTabPage.Promos.ShownTime" units="ms"> +<histogram name="NewTabPage.Promos.ShownTime" units="ms" expires_after="M78"> <owner>kmilka@chromium.org</owner> <owner>ramyan@chromium.org</owner> <summary> @@ -80097,7 +80170,7 @@ <histogram name="OfflinePages.Background.EffectiveConnectionType.RemoveRequests" - enum="NQEEffectiveConnectionType"> + enum="NQEEffectiveConnectionType" expires_after="M78"> <owner>dougarnett@chromium.org</owner> <summary> Effective connection type when removing one or more background loads is @@ -80109,7 +80182,7 @@ <histogram name="OfflinePages.Background.EffectiveConnectionType.ResumeRequests" - enum="NQEEffectiveConnectionType"> + enum="NQEEffectiveConnectionType" expires_after="M78"> <owner>dougarnett@chromium.org</owner> <summary> Effective connection type when resuming one or more background loads is @@ -80158,7 +80231,8 @@ </histogram> <histogram - name="OfflinePages.Background.ImmediateStart.UnavailableRequestCount"> + name="OfflinePages.Background.ImmediateStart.UnavailableRequestCount" + expires_after="M78"> <owner>dougarnett@chromium.org</owner> <summary> Number of queued background load requests unavailable for processing when @@ -80268,7 +80342,8 @@ </histogram> <histogram - name="OfflinePages.Background.ScheduledStart.AvailableRequestCount.Svelte"> + name="OfflinePages.Background.ScheduledStart.AvailableRequestCount.Svelte" + expires_after="M78"> <owner>dougarnett@chromium.org</owner> <summary> Number of queued background load requests available for processing when @@ -80278,7 +80353,8 @@ </histogram> <histogram - name="OfflinePages.Background.ScheduledStart.UnavailableRequestCount"> + name="OfflinePages.Background.ScheduledStart.UnavailableRequestCount" + expires_after="M78"> <owner>dougarnett@chromium.org</owner> <summary> Number of queued background load requests unavailable for processing when @@ -80288,7 +80364,8 @@ </histogram> <histogram - name="OfflinePages.Background.ScheduledStart.UnavailableRequestCount.Svelte"> + name="OfflinePages.Background.ScheduledStart.UnavailableRequestCount.Svelte" + expires_after="M78"> <owner>dougarnett@chromium.org</owner> <summary> Number of queued background load requests unavailable for processing when @@ -80527,7 +80604,7 @@ </histogram> <histogram name="OfflinePages.ConsistencyCheck.Persistent.ExpiredEntryCount" - units="entries"> + units="entries" expires_after="M78"> <owner>dimich@chromium.org</owner> <summary> Number of DB entries (in persistent namespaces) that have been missing their @@ -80589,7 +80666,7 @@ <histogram name="OfflinePages.ConsistencyCheck.Temporary.PagesMissingArchiveFileCount" - units="pages"> + units="pages" expires_after="M78"> <owner>dimich@chromium.org</owner> <summary> Number of temporary offline pages without archive file when checking @@ -81777,7 +81854,7 @@ <histogram name="OfflinePages.WebsiteSettings.ConnectedWhenOpenOnlineButtonClicked" - enum="BooleanConnected"> + enum="BooleanConnected" expires_after="M78"> <owner>fgorski@chromium.org</owner> <summary> Indicates whether the browser was connected when Open online button was @@ -81927,6 +82004,31 @@ </summary> </histogram> +<histogram name="Omnibox.CharTypedToRepaintLatency.InsertToPresent" units="ms"> + <owner>asvitkine@chromium.org</owner> + <owner>mpearson@chromium.org</owner> + <owner>jdonnelly@chromium.org</owner> + <summary> + A refinement of Omnibox.CharTypedToRepaintLatency metric. It measures the + time between the first character insertion in a series that happen during a + frame, to the time the compositor reports the text was rendered on-screen. + Compositor-provided timestamps are used for this version of the metric, so + it is expected to be more accurate: the baseline CharTypedToRepaintLatency + uses now() from when the subsequent has-processed notification arrives back + on the UI thread, which may overestimate user-visible latency. + </summary> +</histogram> + +<histogram name="Omnibox.CharTypedToRepaintLatency.PaintToPresent" units="ms"> + <owner>asvitkine@chromium.org</owner> + <owner>mpearson@chromium.org</owner> + <owner>jdonnelly@chromium.org</owner> + <summary> + Records the time between when OnPaint() is called to the time the compositor + reports pixels were successfully drawn to the screen. + </summary> +</histogram> + <histogram name="Omnibox.CharTypedToRepaintLatency.ToPaint" units="ms"> <owner>asvitkine@chromium.org</owner> <owner>mpearson@chromium.org</owner> @@ -82214,7 +82316,7 @@ </summary> </histogram> -<histogram name="Omnibox.IsPopupOpen" enum="Boolean"> +<histogram name="Omnibox.IsPopupOpen" enum="Boolean" expires_after="M78"> <owner>mpearson@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary> @@ -82835,7 +82937,7 @@ <histogram name="Omnibox.SuggestionUsed.URL.Experimental.NavigationToFirstMeaningfulPaint" - units="ms"> + units="ms" expires_after="M78"> <owner>mpearson@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <summary> @@ -84575,7 +84677,7 @@ <histogram name="PageLoad.Clients.AMP.Experimental.PageTiming.InputToNavigation.Subframe" - units="ms"> + units="ms" expires_after="M78"> <owner>bmcquade@chromium.org</owner> <summary> The time from the user input that triggers the top-level navigation for an @@ -84587,7 +84689,7 @@ <histogram name="PageLoad.Clients.AMP.Experimental.PageTiming.MainFrameToSubFrameNavigationDelta.Subframe" - units="ms"> + units="ms" expires_after="M78"> <owner>bmcquade@chromium.org</owner> <summary> The time from the main frame navigation to the subsequent subframe @@ -84598,7 +84700,7 @@ <histogram name="PageLoad.Clients.AMP.Experimental.PageTiming.NavigationToInput.Subframe" - units="ms"> + units="ms" expires_after="M78"> <owner>bmcquade@chromium.org</owner> <summary> The time from navigation in the AMP frame to the user input that triggers @@ -84623,7 +84725,7 @@ <histogram name="PageLoad.Clients.AMP.InteractiveTiming.FirstInputDelay3.Subframe.FullNavigation" - units="ms"> + units="ms" expires_after="M78"> <owner>bmcquade@chromium.org</owner> <summary> Measures First Input Delay, the duration between the hardware timestamp and @@ -85051,7 +85153,7 @@ <histogram name="PageLoad.Clients.LoFi.Experimental.CompletedResources.Network.LoFi" - units="KB"> + units="KB" expires_after="M78"> <owner>bengr@chromium.org</owner> <owner>ryansturm@chromium.org</owner> <summary> @@ -86472,7 +86574,7 @@ <histogram name="PageLoad.Internal.PaintTiming.HadUserInputBeforeFirstMeaningfulPaint" - enum="HadUserInput"> + enum="HadUserInput" expires_after="M78"> <owner>ksakamoto@chromium.org</owner> <summary> Whether the user had any interaction on the page before @@ -86548,7 +86650,7 @@ <histogram name="PageLoad.Internal.Renderer.FirstMeaningfulPaintDetector.FirstMeaningfulPaintOrdering" - enum="FirstMeaningfulPaintOrdering"> + enum="FirstMeaningfulPaintOrdering" expires_after="M78"> <owner>ksakamoto@chromium.org</owner> <summary> Whether the two variants of First Meaningful Paint reported different @@ -86558,7 +86660,7 @@ <histogram name="PageLoad.Internal.Renderer.FirstMeaningfulPaintDetector.HadNetworkQuiet" - enum="NetworkQuietStatus"> + enum="NetworkQuietStatus" expires_after="M78"> <owner>ksakamoto@chromium.org</owner> <summary> Recorded when the page load reached network 0-quiet (no active network @@ -86796,7 +86898,7 @@ <histogram name="PageLoad.ParseTiming.ParseBlockedOnScriptExecutionFromDocumentWrite" - units="ms"> + units="ms" expires_after="M78"> <owner>bmcquade@chromium.org</owner> <owner>csharrison@chromium.org</owner> <summary> @@ -88151,7 +88253,7 @@ </summary> </histogram> -<histogram name="PasswordManager.DynamicFormChanges" expires_after="M75"> +<histogram name="PasswordManager.DynamicFormChanges" expires_after="M78"> <owner>battre@chromium.org</owner> <owner>dvadym@chromium.org</owner> <summary> @@ -88184,7 +88286,7 @@ <histogram name="PasswordManager.EmptyUsernames.FormWithoutUsernameFieldIsPasswordChangeForm" - enum="PasswordManagerEmptyUsernamePasswordChangeForm"> + enum="PasswordManagerEmptyUsernamePasswordChangeForm" expires_after="M78"> <owner>msramek@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -88969,7 +89071,7 @@ </histogram> <histogram name="PasswordManager.PrefilledUsernameFillOutcome" - enum="PrefilledUsernameFillOutcome"> + enum="PrefilledUsernameFillOutcome" expires_after="M78"> <owner>ioanap@chromium.org</owner> <summary> Records successful fills of prefilled username values known as placeholders @@ -89185,7 +89287,7 @@ <histogram name="PasswordManager.ShouldBlockPasswordForSameOriginButDifferentScheme" - enum="BooleanBlocked"> + enum="BooleanBlocked" expires_after="M78"> <owner>jdoerrie@chromium.org</owner> <summary> This metric is recorded every time Chrome detects a password form @@ -89298,6 +89400,15 @@ </summary> </histogram> +<histogram name="PasswordManager.StoreDecryptionResult" + enum="PasswordDecryptionResult" expires_after="2019-06-01"> + <owner>cfroussios@chromium.org</owner> + <owner>dvadym@chromium.org</owner> + <summary> + Describes the result of decrypting a password value from the LoginDatabase. + </summary> +</histogram> + <histogram name="PasswordManager.StorePasswordImportedFromCSVResult" enum="BooleanSuccess" expires_after="2017-09-20"> <obsolete> @@ -89658,7 +89769,8 @@ </summary> </histogram> -<histogram name="PasswordProtection.DomFeatureExtractionDuration" units="ms"> +<histogram name="PasswordProtection.DomFeatureExtractionDuration" units="ms" + expires_after="M78"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -91301,7 +91413,8 @@ </summary> </histogram> -<histogram name="Platform.CumulativeCpuTime" units="seconds"> +<histogram name="Platform.CumulativeCpuTime" units="seconds" + expires_after="M78"> <owner>semenzato@chromium.org</owner> <owner>bsimonnet@chromium.org</owner> <summary> @@ -99552,7 +99665,8 @@ </summary> </histogram> -<histogram name="PushMessaging.UnregistrationGCMResult" enum="GCMClientResult"> +<histogram name="PushMessaging.UnregistrationGCMResult" enum="GCMClientResult" + expires_after="M78"> <owner>peter@chromium.org</owner> <summary> When unregistering a legacy non-InstanceID push messaging subscription, this @@ -100966,7 +101080,7 @@ </histogram> <histogram name="Renderer4.GpuRasterizationSlowPathsWithNonAAPaint" - enum="BooleanHasSlowPathsWithNonAAPaint"> + enum="BooleanHasSlowPathsWithNonAAPaint" expires_after="M78"> <owner>ericrk@chromium.org</owner> <owner>enne@chromium.org</owner> <summary> @@ -105467,7 +105581,7 @@ </histogram> <histogram name="SafeBrowsing.V4LocalDatabaseManager.AreAllStoresAvailableNow" - enum="SafeBrowsingStoreAvailabilityResult"> + enum="SafeBrowsingStoreAvailabilityResult" expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -105729,7 +105843,7 @@ </histogram> <histogram name="SafeBrowsing.V4Store.IsStoreAvailable.ValidStore" - enum="BooleanAvailable"> + enum="BooleanAvailable" expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -107507,7 +107621,7 @@ <histogram name="SBClientDownload.DownloadFileWithoutDiskImageExtensionHasKolySignature" - enum="Boolean"> + enum="Boolean" expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -107895,7 +108009,8 @@ </summary> </histogram> -<histogram name="SBClientDownload.ZipTooBigToUnpack" enum="Boolean"> +<histogram name="SBClientDownload.ZipTooBigToUnpack" enum="Boolean" + expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -108281,7 +108396,8 @@ </summary> </histogram> -<histogram name="SBDownloadFeedback.Activations" enum="DownloadItem.DangerType"> +<histogram name="SBDownloadFeedback.Activations" enum="DownloadItem.DangerType" + expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <owner>mattm@chromium.org</owner> @@ -108311,7 +108427,8 @@ </summary> </histogram> -<histogram name="SBDownloadFeedback.EmptyFilePathFailure" enum="Boolean"> +<histogram name="SBDownloadFeedback.EmptyFilePathFailure" enum="Boolean" + expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -108331,7 +108448,8 @@ </summary> </histogram> -<histogram name="SBDownloadFeedback.SizeEligibleKB" units="KB"> +<histogram name="SBDownloadFeedback.SizeEligibleKB" units="KB" + expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <owner>mattm@chromium.org</owner> @@ -108362,7 +108480,7 @@ </histogram> <histogram name="SBDownloadFeedback.UploadRequestedByServer" - enum="DownloadUploadRequestedByServer"> + enum="DownloadUploadRequestedByServer" expires_after="M78"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -109755,7 +109873,8 @@ </summary> </histogram> -<histogram name="ScreenLocker.AuthenticationFailure" enum="UnlockType"> +<histogram name="ScreenLocker.AuthenticationFailure" enum="UnlockType" + expires_after="M78"> <owner>sammiequon@chromium.org</owner> <summary> What type of authentication was attempted when the user failed to unlock the @@ -109769,7 +109888,8 @@ <summary>The time spent for authentication in case of a failure.</summary> </histogram> -<histogram name="ScreenLocker.AuthenticationSuccess" enum="UnlockType"> +<histogram name="ScreenLocker.AuthenticationSuccess" enum="UnlockType" + expires_after="M78"> <owner>sammiequon@chromium.org</owner> <summary> What type of authentication was attempted when the user successfully @@ -111999,7 +112119,7 @@ <histogram name="Security.CertificateTransparency.MainFrameNavigationCompliance" - enum="CTComplianceStatus"> + enum="CTComplianceStatus" expires_after="M78"> <owner>estark@chromium.org</owner> <summary> The compliance of each main frame navigation's connection with the @@ -112530,7 +112650,8 @@ </summary> </histogram> -<histogram name="ServiceWorker.BackgroundFetchAbortEvent.Time" units="ms"> +<histogram name="ServiceWorker.BackgroundFetchAbortEvent.Time" units="ms" + expires_after="M78"> <owner>peter@chromium.org</owner> <summary> The time taken between dispatching a BackgroundFetchAbortEvent to a Service @@ -112571,7 +112692,8 @@ </summary> </histogram> -<histogram name="ServiceWorker.BackgroundFetchSuccessEvent.Time" units="ms"> +<histogram name="ServiceWorker.BackgroundFetchSuccessEvent.Time" units="ms" + expires_after="M78"> <owner>nator@chromium.org</owner> <owner>peter@chromium.org</owner> <owner>rayankans@chromium.org</owner> @@ -112604,7 +112726,7 @@ <histogram name="ServiceWorker.CacheStorageInstalledScript.CachedMetadataTotalSize" - units="bytes"> + units="bytes" expires_after="M78"> <owner>horo@chromium.org</owner> <summary> The total length of cached metadata of scripts which are stored to the @@ -113651,7 +113773,8 @@ </summary> </histogram> -<histogram name="ServiceWorker.ScriptCachedMetadataSize" units="bytes"> +<histogram name="ServiceWorker.ScriptCachedMetadataSize" units="bytes" + expires_after="M78"> <owner>horo@chromium.org</owner> <summary> The length of cached metadata of Service Worker scripts. Logged on each load @@ -113921,7 +114044,8 @@ <histogram name="ServiceWorker.StartWorker.InstalledScriptsSender.FinishedReason" - enum="ServiceWorkerInstalledScriptsManager.FinishedReason"> + enum="ServiceWorkerInstalledScriptsManager.FinishedReason" + expires_after="M78"> <owner>shimazu@chromium.org</owner> <summary> The result of sending installed scripts over @@ -116251,7 +116375,7 @@ </summary> </histogram> -<histogram name="Shutdown.end_session.time2"> +<histogram name="Shutdown.end_session.time2" expires_after="M78"> <owner>hashimoto@chromium.org</owner> <summary> Time for shutdown initiated by an end session (user logs off, shuts down or @@ -116625,7 +116749,8 @@ </summary> </histogram> -<histogram name="Signin.AndroidGetAccountIdsTime" units="ms"> +<histogram name="Signin.AndroidGetAccountIdsTime" units="ms" + expires_after="M78"> <owner>bsazonov@chromium.org</owner> <summary> The time it takes to retrieve Gaia ids for all accounts from GoogleAuthUtil. @@ -121946,7 +122071,7 @@ <histogram name="Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint" - units="ms"> + units="ms" expires_after="M78"> <owner>hans@chromium.org</owner> <summary> Time between RenderFrameHostImpl::Init and @@ -123132,7 +123257,7 @@ <histogram name="SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame" - units="microseconds"> + units="microseconds" expires_after="M78"> <owner>csharrison@chromium.org</owner> <summary> Records the total time the activation state navigation throttle within a @@ -123174,7 +123299,7 @@ <histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.MatchedRules" - units="resource loads"> + units="resource loads" expires_after="M78"> <owner>engedy@chromium.org</owner> <summary> Whenever a document load is finished in a main frame or subframe with @@ -123247,7 +123372,7 @@ <histogram name="SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalWallDuration" - units="microseconds"> + units="microseconds" expires_after="M78"> <owner>pkalinnikov@chromium.org</owner> <summary> Whenever a document load is finished in a main frame or subframe with @@ -123556,7 +123681,7 @@ <histogram name="SubresourceFilter.PageLoad.SubresourceEvaluation.TotalCPUDuration" - units="microseconds"> + units="microseconds" expires_after="M78"> <owner>pkalinnikov@chromium.org</owner> <summary> Whenever a page load is finished with subresource filtering activated, @@ -123570,7 +123695,7 @@ <histogram name="SubresourceFilter.PageLoad.SubresourceEvaluation.TotalWallDuration" - units="microseconds"> + units="microseconds" expires_after="M78"> <owner>pkalinnikov@chromium.org</owner> <summary> Whenever a page load is finished with subresource filtering activated, @@ -124609,7 +124734,7 @@ </summary> </histogram> -<histogram name="Sync.DeviceCount2"> +<histogram name="Sync.DeviceCount2" expires_after="M78"> <owner>mastiz@chromium.org</owner> <owner>jkrcal@chromium.org</owner> <summary> @@ -125967,7 +126092,8 @@ </summary> </histogram> -<histogram name="Sync.ResolveConflict" enum="SyncConflictResolutions"> +<histogram name="Sync.ResolveConflict" enum="SyncConflictResolutions" + expires_after="M78"> <owner>treib@chromium.org</owner> <owner>mastiz@chromium.org</owner> <summary> @@ -125977,7 +126103,7 @@ </histogram> <histogram name="Sync.ResolveSimpleConflict" - enum="SyncSimpleConflictResolutions"> + enum="SyncSimpleConflictResolutions" expires_after="M78"> <owner>zea@chromium.org</owner> <summary>Enumeration of types of simple conflict resolutions.</summary> </histogram> @@ -127857,7 +127983,7 @@ <histogram name="TabManager.Experimental.SessionRestore.CompressedPagesPerSecond" - units="pages/s"> + units="pages/s" expires_after="M78"> <owner>shaseley@chromium.org</owner> <owner>panicker@chromium.org</owner> <summary> @@ -127876,7 +128002,7 @@ <histogram name="TabManager.Experimental.SessionRestore.DecompressedPagesPerSecond" - units="pages/s"> + units="pages/s" expires_after="M78"> <owner>shaseley@chromium.org</owner> <owner>panicker@chromium.org</owner> <summary> @@ -127895,7 +128021,7 @@ <histogram name="TabManager.Experimental.SessionRestore.ForegroundTab.FirstContentfulPaint" - units="ms"> + units="ms" expires_after="M78"> <owner>shaseley@chromium.org</owner> <owner>panicker@chromium.org</owner> <summary> @@ -127917,7 +128043,7 @@ <histogram name="TabManager.Experimental.SessionRestore.ForegroundTab.FirstPaint" - units="ms"> + units="ms" expires_after="M78"> <owner>shaseley@chromium.org</owner> <owner>panicker@chromium.org</owner> <summary> @@ -127988,7 +128114,7 @@ <histogram name="TabManager.Experimental.SessionRestore.TabSwitchLoadTime.UntilTabIsLoaded" - units="ms"> + units="ms" expires_after="M78"> <owner>shaseley@chromium.org</owner> <owner>panicker@chromium.org</owner> <summary> @@ -128050,7 +128176,7 @@ <histogram name="TabManager.Heuristics.FromBackgroundedToFirstNonPersistentNotificationCreated" - units="ms"> + units="ms" expires_after="M78"> <owner>chrisha@chromium.org</owner> <owner>lpy@chromium.org</owner> <summary> @@ -129835,7 +129961,7 @@ </summary> </histogram> -<histogram name="Thumbnails.CopyFromSurfaceTime" units="ms"> +<histogram name="Thumbnails.CopyFromSurfaceTime" units="ms" expires_after="M78"> <owner>treib@chromium.org</owner> <summary> While taking a screenshot of the current tab for use as a thumbnail on the @@ -129863,7 +129989,7 @@ </summary> </histogram> -<histogram name="Thumbnails.ProcessBitmapTime" units="ms"> +<histogram name="Thumbnails.ProcessBitmapTime" units="ms" expires_after="M78"> <owner>treib@chromium.org</owner> <summary> While taking a screenshot of the current tab for use as a thumbnail on the @@ -130664,7 +130790,7 @@ </histogram> <histogram name="Translate.LanguageVerification" - enum="TranslateLanguageVerification"> + enum="TranslateLanguageVerification" expires_after="M78"> <owner>yyushkina@chromium.org</owner> <summary> For each page load, measures whether the provided HTML language (i.e. the @@ -138264,7 +138390,7 @@ <histogram name="WebCore.IndexedDB.TombstoneSweeper.DeletionCommitTime.Complete" - units="ms"> + units="ms" expires_after="M78"> <owner>dmurph@chromium.org</owner> <summary> Records the time it takes for the IndexedDB Tombstone Sweeper to commit @@ -138382,7 +138508,8 @@ </summary> </histogram> -<histogram name="WebCore.IndexedDB.Transaction.ReadOnly.TimeActive" units="ms"> +<histogram name="WebCore.IndexedDB.Transaction.ReadOnly.TimeActive" units="ms" + expires_after="M78"> <owner>dmurph@chromium.org</owner> <summary> The time it takes for an IndexedDB ReadOnly Transaction to commit, starting @@ -139945,7 +140072,8 @@ </summary> </histogram> -<histogram name="WebRTC.Audio.JitterBufferFullPerMinute" units="events/minute"> +<histogram name="WebRTC.Audio.JitterBufferFullPerMinute" units="events/minute" + expires_after="M78"> <owner>minyue@chromium.org</owner> <summary> Frequency that audio packets hits the capacity of WebRTC jitter buffer. A @@ -140090,7 +140218,8 @@ </summary> </histogram> -<histogram name="WebRTC.AudioInputSampleRate" enum="AudioSampleRate"> +<histogram name="WebRTC.AudioInputSampleRate" enum="AudioSampleRate" + expires_after="M78"> <owner>henrika@chromium.org</owner> <summary>Audio input sample rate for WebRTC (in Hz).</summary> </histogram> @@ -144872,7 +145001,11 @@ <suffix name="AssistantDetails" label="Showing cache patterns only for AssistantDetails."/> <suffix name="ContextualSuggestions" - label="Showing cache patterns only for ContextualSuggestions."/> + label="Showing cache patterns only for ContextualSuggestions."> + <obsolete> + This feature was deprecated in M74 + </obsolete> + </suffix> <suffix name="Feed" label="Showing cache patterns only for Feed."/> <suffix name="Internal" label="Showing cache patterns only for Internal."/> <suffix name="NewTabPageAnimatedLogo" @@ -145684,6 +145817,9 @@ </histogram_suffixes> <histogram_suffixes name="ContextualSuggestionsPageViewSource" separator="."> + <obsolete> + This feature was deprecated in M74 + </obsolete> <suffix name="ContextualSuggestions" label="For contextual suggestions navigations"/> <suffix name="Other" label="For non contextual suggestions navigations"/> @@ -148564,7 +148700,11 @@ label="In product help for contextual search for users who use web search."/> <suffix name="IPH_ContextualSuggestions" - label="In product help for contextual suggestions."/> + label="In product help for contextual suggestions."> + <obsolete> + This feature was deprecated in M74 + </obsolete> + </suffix> <suffix name="IPH_DataSaverDetail" label="In product help data saver detail."/> <suffix name="IPH_DataSaverMilestonePromo"
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 164a275..ba4d81a 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2199,6 +2199,9 @@ </event> <event name="ContextualSuggestions"> + <obsolete> + This feature was deprecated in M74 + </obsolete> <owner>donnd@chromium.org</owner> <owner>fgorski@chromium.org</owner> <owner>twellington@chromium.org</owner> @@ -5036,6 +5039,15 @@ distinguish two forms on the same site. </summary> </metric> + <metric name="DynamicFormChanges"> + <summary> + Records a bitmask of password form changes after the first time this form + is seen by Password Manager. Recorded once per a form when the form is + removed from DOM. Bit 0 - changes in number of fields, bit 1 - changes in + fields renderer ids, bit 2 - changes in autocomplete attributes, bit 3 - + changes in form control types. + </summary> + </metric> <metric name="Fill.FirstFillingResultInRenderer"> <summary> Records whether the PasswordAutofillAgent in the renderer manages to fill
diff --git a/tools/perf/page_sets/repeatable_synthesize_scroll_gesture_shared_state.py b/tools/perf/page_sets/repeatable_synthesize_scroll_gesture_shared_state.py deleted file mode 100644 index d97f7e0..0000000 --- a/tools/perf/page_sets/repeatable_synthesize_scroll_gesture_shared_state.py +++ /dev/null
@@ -1,17 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -import logging - -from telemetry.page import shared_page_state - - -class RepeatableSynthesizeScrollGestureSharedState( - shared_page_state.SharedPageState): - - def CanRunOnBrowser(self, browser_info, _): - if not browser_info.HasRepeatableSynthesizeScrollGesture(): - logging.warning('Browser does not support repeatable scroll gestures, ' - 'skipping test') - return False - return True
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 7b32abc..bd13b26 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -156,7 +156,7 @@ <item id="network_location_provider" hash_code="23472048" type="1" second_id="96590038" content_hash_code="41087976" os_list="linux,windows" semantics_fields="1" policy_fields="3,4" file_path="services/device/geolocation/network_location_provider.cc"/> <item id="network_location_request" hash_code="96590038" type="2" content_hash_code="80741011" os_list="linux,windows" semantics_fields="2,3,4,5" policy_fields="-1" file_path="services/device/geolocation/network_location_request.cc"/> <item id="network_time_component" hash_code="46188932" type="0" content_hash_code="28051857" os_list="linux,windows" file_path="components/network_time/network_time_tracker.cc"/> - <item id="ntp_contextual_suggestions_fetch" hash_code="95711309" type="0" content_hash_code="107035434" os_list="linux,windows" file_path="components/ntp_snippets/contextual/contextual_suggestions_fetch.cc"/> + <item id="ntp_contextual_suggestions_fetch" hash_code="95711309" type="0" deprecated="2019-04-18" content_hash_code="107035434" file_path=""/> <item id="ntp_custom_link_checker_request" hash_code="78408551" type="0" deprecated="2018-10-26" content_hash_code="13407730" file_path=""/> <item id="ntp_icon_source" hash_code="29197139" type="0" content_hash_code="16399294" os_list="linux,windows" file_path="chrome/browser/search/ntp_icon_source.cc"/> <item id="ntp_snippets_fetch" hash_code="15418154" type="0" content_hash_code="10078959" os_list="linux,windows" file_path="components/ntp_snippets/remote/json_request.cc"/>
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 8489012..07dd659 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -59,7 +59,6 @@ "mus/system_input_injector_mus.h", "mus/text_input_client_impl.h", "mus/topmost_window_tracker.h", - "mus/user_activity_forwarder.h", "mus/window_mus.h", "mus/window_port_mus.h", "mus/window_tree_client.h", @@ -131,7 +130,6 @@ "mus/system_input_injector_mus.cc", "mus/text_input_client_impl.cc", "mus/topmost_window_tracker.cc", - "mus/user_activity_forwarder.cc", "mus/window_port_mus.cc", "mus/window_tree_client.cc", "mus/window_tree_client_delegate.cc", @@ -394,7 +392,6 @@ "mus/focus_synchronizer_unittest.cc", "mus/input_method_mus_unittest.cc", "mus/property_converter_unittest.cc", - "mus/user_activity_forwarder_unittest.cc", "mus/window_port_mus_unittest.cc", "mus/window_tree_client_unittest.cc", "mus/window_tree_host_mus_unittest.cc",
diff --git a/ui/aura/mus/user_activity_forwarder.cc b/ui/aura/mus/user_activity_forwarder.cc deleted file mode 100644 index e3d56b2..0000000 --- a/ui/aura/mus/user_activity_forwarder.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/aura/mus/user_activity_forwarder.h" - -#include <cmath> -#include <cstdint> - -#include "ui/base/user_activity/user_activity_detector.h" - -namespace aura { - -UserActivityForwarder::UserActivityForwarder( - ws::mojom::UserActivityMonitorPtr monitor, - ui::UserActivityDetector* detector) - : monitor_(std::move(monitor)), binding_(this), detector_(detector) { - DCHECK(detector_); - - // Round UserActivityDetector's notification interval up to the nearest - // second (the granularity exposed by UserActivityMonitor). - const uint32_t kNotifyIntervalSec = static_cast<uint32_t>( - ceil(ui::UserActivityDetector::kNotifyIntervalMs / 1000.0)); - ws::mojom::UserActivityObserverPtr observer; - binding_.Bind(mojo::MakeRequest(&observer)); - monitor_->AddUserActivityObserver(kNotifyIntervalSec, std::move(observer)); -} - -UserActivityForwarder::~UserActivityForwarder() {} - -void UserActivityForwarder::OnUserActivity() { - detector_->HandleExternalUserActivity(); -} - -} // namespace aura
diff --git a/ui/aura/mus/user_activity_forwarder.h b/ui/aura/mus/user_activity_forwarder.h deleted file mode 100644 index 4823cc1..0000000 --- a/ui/aura/mus/user_activity_forwarder.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_AURA_MUS_USER_ACTIVITY_FORWARDER_H_ -#define UI_AURA_MUS_USER_ACTIVITY_FORWARDER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/ws/public/mojom/user_activity_monitor.mojom.h" -#include "ui/aura/aura_export.h" - -namespace ui { -class UserActivityDetector; -} - -namespace aura { - -// Helper class that receives reports of user activity from the mojo -// UserActivityMonitor interface (in the window server) and forwards them to -// ui::UserActivityDetector (usually in ash). -// TODO(derat): Make current ui::UserActivityObserver implementations (i.e. -// downstream of ui::UserActivityDetector) instead observe UserActivityMonitor -// directly: http://crbug.com/626899 -class AURA_EXPORT UserActivityForwarder - : public ws::mojom::UserActivityObserver { - public: - UserActivityForwarder(ws::mojom::UserActivityMonitorPtr monitor, - ui::UserActivityDetector* detector); - ~UserActivityForwarder() override; - - private: - // ws::mojom::UserActivityObserver: - void OnUserActivity() override; - - ws::mojom::UserActivityMonitorPtr monitor_; - mojo::Binding<ws::mojom::UserActivityObserver> binding_; - - ui::UserActivityDetector* detector_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(UserActivityForwarder); -}; - -} // namespace aura - -#endif // UI_AURA_MUS_USER_ACTIVITY_FORWARDER_H_
diff --git a/ui/aura/mus/user_activity_forwarder_unittest.cc b/ui/aura/mus/user_activity_forwarder_unittest.cc deleted file mode 100644 index 2f01215..0000000 --- a/ui/aura/mus/user_activity_forwarder_unittest.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/aura/mus/user_activity_forwarder.h" - -#include <memory> -#include <vector> - -#include "base/macros.h" -#include "base/time/time.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/ws/common/task_runner_test_base.h" -#include "services/ws/public/mojom/user_activity_monitor.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/user_activity/user_activity_detector.h" - -namespace { - -// Fake implementation of ws::mojom::UserActivityMonitor for testing that just -// supports tracking and notifying observers. -class FakeUserActivityMonitor : public ws::mojom::UserActivityMonitor { - public: - FakeUserActivityMonitor() : binding_(this) {} - ~FakeUserActivityMonitor() override {} - - ws::mojom::UserActivityMonitorPtr GetPtr() { - ws::mojom::UserActivityMonitorPtr ptr; - binding_.Bind(mojo::MakeRequest(&ptr)); - return ptr; - } - - // Notifies all observers about user activity. - // ws::TaskRunnerTestBase::RunUntilIdle() must be called after this method in - // order for observers to receive notifications. - void NotifyUserActivityObservers() { - for (auto& observer : activity_observers_) - observer->OnUserActivity(); - } - - // ws::mojom::UserActivityMonitor: - void AddUserActivityObserver( - uint32_t delay_between_notify_secs, - ws::mojom::UserActivityObserverPtr observer) override { - activity_observers_.push_back(std::move(observer)); - } - void AddUserIdleObserver(uint32_t idleness_in_minutes, - ws::mojom::UserIdleObserverPtr observer) override { - NOTREACHED() << "Unexpected AddUserIdleObserver call"; - } - - private: - mojo::Binding<ws::mojom::UserActivityMonitor> binding_; - std::vector<ws::mojom::UserActivityObserverPtr> activity_observers_; - - DISALLOW_COPY_AND_ASSIGN(FakeUserActivityMonitor); -}; - -} // namespace - -namespace aura { - -using UserActivityForwarderTest = ws::TaskRunnerTestBase; - -TEST_F(UserActivityForwarderTest, ForwardActivityToDetector) { - FakeUserActivityMonitor monitor; - ui::UserActivityDetector detector; - UserActivityForwarder forwarder(monitor.GetPtr(), &detector); - - // Run pending tasks so |monitor| receives |forwarder|'s registration. - RunUntilIdle(); - - base::TimeTicks now = - base::TimeTicks() + base::TimeDelta::FromMicroseconds(1000); - detector.set_now_for_test(now); - monitor.NotifyUserActivityObservers(); - RunUntilIdle(); - EXPECT_EQ(now, detector.last_activity_time()); - - now += base::TimeDelta::FromSeconds(10); - detector.set_now_for_test(now); - monitor.NotifyUserActivityObservers(); - RunUntilIdle(); - EXPECT_EQ(now, detector.last_activity_time()); -} - -} // namespace aura
diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc index 317563b..b6470d8 100644 --- a/ui/base/models/simple_menu_model.cc +++ b/ui/base/models/simple_menu_model.cc
@@ -171,6 +171,17 @@ AddSubMenu(command_id, l10n_util::GetStringUTF16(string_id), model); } +void SimpleMenuModel::AddSubMenuWithStringIdAndIcon( + int command_id, + int string_id, + MenuModel* model, + const gfx::ImageSkia& icon) { + Item item(command_id, TYPE_SUBMENU, l10n_util::GetStringUTF16(string_id)); + item.submenu = model; + item.icon = gfx::Image(icon); + AppendItem(std::move(item)); +} + void SimpleMenuModel::AddActionableSubMenu(int command_id, const base::string16& label, MenuModel* model) {
diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h index e034b81..895fd62 100644 --- a/ui/base/models/simple_menu_model.h +++ b/ui/base/models/simple_menu_model.h
@@ -108,6 +108,10 @@ const base::string16& label, MenuModel* model); void AddSubMenuWithStringId(int command_id, int string_id, MenuModel* model); + void AddSubMenuWithStringIdAndIcon(int command_id, + int string_id, + MenuModel* model, + const gfx::ImageSkia& icon); void AddActionableSubMenu(int command_id, const base::string16& label, MenuModel* model);
diff --git a/ui/chromeos/ime/candidate_window_view.cc b/ui/chromeos/ime/candidate_window_view.cc index 009b40b..b9e074a 100644 --- a/ui/chromeos/ime/candidate_window_view.cc +++ b/ui/chromeos/ime/candidate_window_view.cc
@@ -10,9 +10,6 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" -#include "mojo/public/cpp/bindings/type_converter.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/window_manager.mojom.h" #include "ui/base/ui_base_features.h" #include "ui/chromeos/ime/candidate_view.h" #include "ui/chromeos/ime/candidate_window_constants.h" @@ -409,18 +406,6 @@ return ui::DIALOG_BUTTON_NONE; } -void CandidateWindowView::OnBeforeBubbleWidgetInit( - views::Widget::InitParams* params, - views::Widget* widget) const { - using ws::mojom::WindowManager; - params->mus_properties[WindowManager::kContainerId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int32_t>(window_shell_id_)); - params->mus_properties[WindowManager::kDisplayId_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>( - display::Screen::GetScreen()->GetDisplayForNewWindows().id()); -} - void CandidateWindowView::ButtonPressed(views::Button* sender, const ui::Event& event) { for (size_t i = 0; i < candidate_views_.size(); ++i) {
diff --git a/ui/chromeos/ime/candidate_window_view.h b/ui/chromeos/ime/candidate_window_view.h index e45aa03..c1ec26d 100644 --- a/ui/chromeos/ime/candidate_window_view.h +++ b/ui/chromeos/ime/candidate_window_view.h
@@ -83,8 +83,6 @@ // views::BubbleDialogDelegateView: const char* GetClassName() const override; int GetDialogButtons() const override; - void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, - views::Widget* widget) const override; // Overridden from views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/ui/gfx/buffer_format_util.cc b/ui/gfx/buffer_format_util.cc index 22326d5..32840e44 100644 --- a/ui/gfx/buffer_format_util.cc +++ b/ui/gfx/buffer_format_util.cc
@@ -197,14 +197,14 @@ case BufferFormat::YVU_420: { static size_t offset_in_2x2_sub_sampling_sizes[] = {0, 4, 5}; DCHECK_LT(plane, base::size(offset_in_2x2_sub_sampling_sizes)); - return offset_in_2x2_sub_sampling_sizes[plane] * - (size.width() / 2 + size.height() / 2); + return offset_in_2x2_sub_sampling_sizes[plane] * (size.width() / 2) * + (size.height() / 2); } case gfx::BufferFormat::YUV_420_BIPLANAR: { static size_t offset_in_2x2_sub_sampling_sizes[] = {0, 4}; DCHECK_LT(plane, base::size(offset_in_2x2_sub_sampling_sizes)); - return offset_in_2x2_sub_sampling_sizes[plane] * - (size.width() / 2 + size.height() / 2); + return offset_in_2x2_sub_sampling_sizes[plane] * (size.width() / 2) * + (size.height() / 2); } } NOTREACHED();
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index 2382c57..f78aab4 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -4261,6 +4261,8 @@ // Ensure that the fallback fonts offered by GetFallbackFont() support glyphs // for different languages. +// TODO(https://crbug.com/743296): Implements Fallback fonts on Fuchsia. +#if !defined(OS_FUCHSIA) TEST_F(RenderTextTest, HarfBuzz_FallbackFontsSupportGlyphs) { // The word 'test' in different languages. static const wchar_t* kLanguageTests[] = { @@ -4281,7 +4283,13 @@ } } } +#endif // !defined(OS_FUCHSIA) + +// Ensure that the fallback fonts offered by GetFallbackFont() support glyphs +// for different languages. +// TODO(https://crbug.com/743296): Implements Fallback fonts on Fuchsia. +#if !defined(OS_FUCHSIA) TEST_F(RenderTextTest, HarfBuzz_MultiRunsSupportGlyphs) { static const wchar_t* kLanguageTests[] = { L"www.اختبار.com", @@ -4305,6 +4313,7 @@ } } } +#endif // !defined(OS_FUCHSIA) // Ensure that the width reported by RenderText is sufficient for drawing. Draws // to a canvas and checks if any pixel beyond the bounding rectangle is colored.
diff --git a/ui/gl/test/gl_image_test_support.cc b/ui/gl/test/gl_image_test_support.cc index c4a0840..257fde4 100644 --- a/ui/gl/test/gl_image_test_support.cc +++ b/ui/gl/test/gl_image_test_support.cc
@@ -74,6 +74,15 @@ } } return; + case gfx::BufferFormat::RGBA_4444: + DCHECK_EQ(0, plane); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + data[y * stride + x * 2 + 0] = (color[1] << 4) | (color[0] & 0xf); + data[y * stride + x * 2 + 1] = (color[3] << 4) | (color[2] & 0xf); + } + } + return; case gfx::BufferFormat::BGR_565: DCHECK_EQ(0, plane); for (int y = 0; y < height; ++y) { @@ -226,7 +235,6 @@ } return; } - case gfx::BufferFormat::RGBA_4444: case gfx::BufferFormat::UYVY_422: NOTREACHED() << gfx::BufferFormatToString(format); return;
diff --git a/ui/ozone/platform/scenic/sysmem_buffer_collection.cc b/ui/ozone/platform/scenic/sysmem_buffer_collection.cc index 5ac57bbe..a34f069 100644 --- a/ui/ozone/platform/scenic/sysmem_buffer_collection.cc +++ b/ui/ozone/platform/scenic/sysmem_buffer_collection.cc
@@ -315,8 +315,7 @@ uint32_t viable_memory_types = properties.memoryTypeBits & requirements.memoryTypeBits; - uint32_t memory_type = - base::bits::CountLeadingZeroBits32(viable_memory_types); + uint32_t memory_type = base::bits::CountTrailingZeroBits(viable_memory_types); VkImportMemoryBufferCollectionFUCHSIA buffer_collection_info = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA};
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc index 64a1451..8d2afbb 100644 --- a/ui/views/animation/ink_drop_host_view.cc +++ b/ui/views/animation/ink_drop_host_view.cc
@@ -49,8 +49,14 @@ } void InkDropHostView::AddInkDropLayer(ui::Layer* ink_drop_layer) { + old_paint_to_layer_ = layer() != nullptr; + if (!old_paint_to_layer_) + SetPaintToLayer(); + + layer()->SetFillsBoundsOpaquely(false); InstallInkDropMask(ink_drop_layer); - AddLayerBeneathView(ink_drop_layer); + layer()->Add(ink_drop_layer); + layer()->StackAtBottom(ink_drop_layer); } void InkDropHostView::RemoveInkDropLayer(ui::Layer* ink_drop_layer) { @@ -59,9 +65,11 @@ // would be wrong. if (destroying_) return; - RemoveLayerBeneathView(ink_drop_layer); + layer()->Remove(ink_drop_layer); // Layers safely handle destroying a mask layer before the masked layer. ink_drop_mask_.reset(); + if (!old_paint_to_layer_) + DestroyLayer(); } std::unique_ptr<InkDrop> InkDropHostView::CreateInkDrop() {
diff --git a/ui/views/animation/ink_drop_host_view.h b/ui/views/animation/ink_drop_host_view.h index 3087973..cb9ef74 100644 --- a/ui/views/animation/ink_drop_host_view.h +++ b/ui/views/animation/ink_drop_host_view.h
@@ -225,6 +225,10 @@ int ink_drop_small_corner_radius_ = 2; int ink_drop_large_corner_radius_ = 4; + // Determines whether the view was already painting to layer before adding ink + // drop layer. + bool old_paint_to_layer_ = false; + bool destroying_ = false; std::unique_ptr<views::InkDropMask> ink_drop_mask_;
diff --git a/ui/views/animation/ink_drop_impl.cc b/ui/views/animation/ink_drop_impl.cc index 4830ecc..2c8b6c5 100644 --- a/ui/views/animation/ink_drop_impl.cc +++ b/ui/views/animation/ink_drop_impl.cc
@@ -630,8 +630,7 @@ // |root_layer_| should fill the entire host because it affects the clipping // when a mask layer is applied to it. This will not affect clipping if no // mask layer is set. - root_layer_->SetBounds(gfx::Rect(new_size) + - root_layer_->bounds().OffsetFromOrigin()); + root_layer_->SetBounds(gfx::Rect(new_size)); const bool create_ink_drop_ripple = !!ink_drop_ripple_; InkDropState state = GetTargetInkDropState();
diff --git a/ui/views/controls/button/image_button_factory.cc b/ui/views/controls/button/image_button_factory.cc index e5f56eb..245b32f 100644 --- a/ui/views/controls/button/image_button_factory.cc +++ b/ui/views/controls/button/image_button_factory.cc
@@ -34,9 +34,10 @@ return button; } -ToggleImageButton* CreateVectorToggleImageButton(ButtonListener* listener) { - ToggleImageButton* button = new ToggleImageButton(listener); - ConfigureVectorImageButton(button); +std::unique_ptr<ToggleImageButton> CreateVectorToggleImageButton( + ButtonListener* listener) { + auto button = std::make_unique<ToggleImageButton>(listener); + ConfigureVectorImageButton(button.get()); return button; }
diff --git a/ui/views/controls/button/image_button_factory.h b/ui/views/controls/button/image_button_factory.h index 38abccf7..23d9a78 100644 --- a/ui/views/controls/button/image_button_factory.h +++ b/ui/views/controls/button/image_button_factory.h
@@ -27,7 +27,7 @@ // Creates a ToggleImageButton with an ink drop and a centered image in // preperation for applying a vector icon from SetImageFromVectorIcon and // SetToggledImageFromVectorIcon below. -VIEWS_EXPORT ToggleImageButton* CreateVectorToggleImageButton( +VIEWS_EXPORT std::unique_ptr<ToggleImageButton> CreateVectorToggleImageButton( ButtonListener* listener); // Sets images on |button| for STATE_NORMAL and STATE_DISABLED from the given
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index e558a17a..4462c920 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include <algorithm> #include <utility> #include "base/lazy_instance.h" @@ -60,6 +59,8 @@ SetTextInternal(text); AddChildView(ink_drop_container_); + ink_drop_container_->SetPaintToLayer(); + ink_drop_container_->layer()->SetFillsBoundsOpaquely(false); ink_drop_container_->SetVisible(false); AddChildView(image_); @@ -333,19 +334,6 @@ Button::GetAccessibleNodeData(node_data); } -void LabelButton::AddLayerBeneathView(ui::Layer* new_layer) { - image()->SetPaintToLayer(); - image()->layer()->SetFillsBoundsOpaquely(false); - ink_drop_container()->SetVisible(true); - ink_drop_container()->AddLayerBeneathView(new_layer); -} - -void LabelButton::RemoveLayerBeneathView(ui::Layer* old_layer) { - ink_drop_container()->RemoveLayerBeneathView(old_layer); - ink_drop_container()->SetVisible(false); - image()->DestroyLayer(); -} - ui::NativeTheme::Part LabelButton::GetThemePart() const { return ui::NativeTheme::kPushButton; } @@ -402,6 +390,19 @@ border_is_themed_border_ = true; } +void LabelButton::AddInkDropLayer(ui::Layer* ink_drop_layer) { + image()->SetPaintToLayer(); + image()->layer()->SetFillsBoundsOpaquely(false); + ink_drop_container_->AddInkDropLayer(ink_drop_layer); + InstallInkDropMask(ink_drop_layer); +} + +void LabelButton::RemoveInkDropLayer(ui::Layer* ink_drop_layer) { + image()->DestroyLayer(); + ResetInkDropMask(); + ink_drop_container_->RemoveInkDropLayer(ink_drop_layer); +} + gfx::Rect LabelButton::GetChildAreaBounds() { return GetLocalBounds(); }
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h index 82e9eb9..11f6c79 100644 --- a/ui/views/controls/button/label_button.h +++ b/ui/views/controls/button/label_button.h
@@ -96,9 +96,9 @@ void Layout() override; const char* GetClassName() const override; void EnableCanvasFlippingForRTLUI(bool flip) override; + void AddInkDropLayer(ui::Layer* ink_drop_layer) override; + void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - void AddLayerBeneathView(ui::Layer* new_layer) override; - void RemoveLayerBeneathView(ui::Layer* old_layer) override; // NativeThemeDelegate: ui::NativeTheme::Part GetThemePart() const override;
diff --git a/ui/views/view.cc b/ui/views/view.cc index 5e6b31e..dbd2360 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -141,9 +141,6 @@ for (ViewObserver& observer : observers_) observer.OnViewIsDeleting(this); - - for (ui::Layer* layer_beneath : layers_beneath_) - layer_beneath->RemoveObserver(this); } // Tree operations ------------------------------------------------------------- @@ -507,9 +504,6 @@ layer()->SetTransform(transform); layer()->ScheduleDraw(); } - - for (ui::Layer* layer_beneath : layers_beneath_) - layer_beneath->SetTransform(transform); } void View::SetPaintToLayer(ui::LayerType layer_type) { @@ -536,53 +530,6 @@ CreateOrDestroyLayer(); } -void View::AddLayerBeneathView(ui::Layer* new_layer) { - DCHECK(new_layer); - DCHECK(!base::ContainsValue(layers_beneath_, new_layer)) - << "Layer already added."; - - new_layer->AddObserver(this); - new_layer->SetVisible(visible()); - layers_beneath_.push_back(new_layer); - - // If painting to a layer already, ensure |new_layer| gets added and stacked - // correctly. If not, this will happen on layer creation. - if (layer()) { - ui::Layer* parent_layer = layer()->parent(); - if (parent_layer) - parent_layer->Add(new_layer); - new_layer->SetBounds(gfx::Rect(new_layer->size()) + - layer()->bounds().OffsetFromOrigin()); - if (parent()) - parent()->ReorderLayers(); - } - - CreateOrDestroyLayer(); - - layer()->SetFillsBoundsOpaquely(false); -} - -void View::RemoveLayerBeneathView(ui::Layer* old_layer) { - auto layer_pos = - std::find(layers_beneath_.begin(), layers_beneath_.end(), old_layer); - DCHECK(layer_pos != layers_beneath_.end()) - << "Attempted to remove a layer that was never added."; - layers_beneath_.erase(layer_pos); - old_layer->RemoveObserver(this); - - ui::Layer* parent_layer = layer()->parent(); - if (parent_layer) - parent_layer->Remove(old_layer); - - CreateOrDestroyLayer(); -} - -void View::LayerDestroyed(ui::Layer* layer) { - // Only layers added with |AddLayerBeneathView()| are observed so |layer| can - // safely be removed. - RemoveLayerBeneathView(layer); -} - std::unique_ptr<ui::Layer> View::RecreateLayer() { std::unique_ptr<ui::Layer> old_layer = LayerOwner::RecreateLayer(); Widget* widget = GetWidget(); @@ -1678,9 +1625,6 @@ if (layer() && parent_layer != layer()) { parent_layer->Add(layer()); - for (ui::Layer* layer_beneath : layers_beneath_) - parent_layer->Add(layer_beneath); - SetLayerBounds(size(), local_offset_data); } else { internal::ScopedChildrenLock lock(this); @@ -1698,24 +1642,16 @@ } void View::UpdateChildLayerVisibility(bool ancestor_visible) { - const bool layers_visible = ancestor_visible && visible_; if (layer()) { - layer()->SetVisible(layers_visible); - for (ui::Layer* layer_beneath : layers_beneath_) - layer_beneath->SetVisible(layers_visible); + layer()->SetVisible(ancestor_visible && visible_); } else { internal::ScopedChildrenLock lock(this); for (auto* child : children_) - child->UpdateChildLayerVisibility(layers_visible); + child->UpdateChildLayerVisibility(ancestor_visible && visible_); } } void View::DestroyLayerImpl(LayerChangeNotifyBehavior notify_parents) { - // Normally, adding layers beneath will trigger painting to a layer. It would - // leave this view in an inconsistent state if its layer were destroyed while - // layers beneath were still present. So, assume this doesn't happen. - DCHECK(layers_beneath_.empty()); - if (!layer()) return; @@ -1794,8 +1730,7 @@ } void View::CreateOrDestroyLayer() { - if (paint_to_layer_explicitly_set_ || paint_to_layer_for_transform_ || - !layers_beneath_.empty()) { + if (paint_to_layer_explicitly_set_ || paint_to_layer_for_transform_) { // If we need to paint to a layer, make sure we have one. if (!layer()) CreateLayer(ui::LAYER_TEXTURED); @@ -1835,8 +1770,6 @@ if (layer() && layer() != parent_layer) { DCHECK_EQ(parent_layer, layer()->parent()); parent_layer->StackAtBottom(layer()); - for (ui::Layer* layer_beneath : layers_beneath_) - parent_layer->StackAtBottom(layer_beneath); } else { // Iterate backwards through the children so that a child with a layer // which is further to the back is stacked above one which is further to @@ -2325,19 +2258,12 @@ layer()->GetCompositor()) { if (layer()->GetCompositor()->is_pixel_canvas()) { layer()->SetSubpixelPositionOffset(offset_data.GetSubpixelOffset()); - for (ui::Layer* layer_beneath : layers_beneath_) - layer_beneath->SetSubpixelPositionOffset( - offset_data.GetSubpixelOffset()); } else { ui::SnapLayerToPhysicalPixelBoundary(layer()->parent(), layer()); - for (ui::Layer* layer_beneath : layers_beneath_) - ui::SnapLayerToPhysicalPixelBoundary(layer()->parent(), layer_beneath); } } else { // Reset the offset. layer()->SetSubpixelPositionOffset(gfx::Vector2dF()); - for (ui::Layer* layer_beneath : layers_beneath_) - layer_beneath->SetSubpixelPositionOffset(gfx::Vector2dF()); } } @@ -2406,12 +2332,7 @@ void View::SetLayerBounds(const gfx::Size& size, const LayerOffsetData& offset_data) { - const gfx::Rect bounds = gfx::Rect(size) + offset_data.offset(); - layer()->SetBounds(bounds); - for (ui::Layer* layer_beneath : layers_beneath_) { - layer_beneath->SetBounds(gfx::Rect(layer_beneath->size()) + - bounds.OffsetFromOrigin()); - } + layer()->SetBounds(gfx::Rect(size) + offset_data.offset()); SnapLayerToPixelBoundary(offset_data); } @@ -2531,12 +2452,8 @@ void View::OrphanLayers() { if (layer()) { - ui::Layer* parent = layer()->parent(); - if (parent) { - parent->Remove(layer()); - for (ui::Layer* layer_beneath : layers_beneath_) - parent->Remove(layer_beneath); - } + if (layer()->parent()) + layer()->parent()->Remove(layer()); // The layer belonging to this View has already been orphaned. It is not // necessary to orphan the child layers. @@ -2549,15 +2466,9 @@ void View::ReparentLayer(const gfx::Vector2d& offset, ui::Layer* parent_layer) { layer()->SetBounds(GetLocalBounds() + offset); - for (ui::Layer* layer_beneath : layers_beneath_) - layer_beneath->SetBounds(gfx::Rect(layer_beneath->size()) + offset); - DCHECK_NE(layer(), parent_layer); - if (parent_layer) { + if (parent_layer) parent_layer->Add(layer()); - for (ui::Layer* layer_beneath : layers_beneath_) - parent_layer->Add(layer_beneath); - } layer()->SchedulePaint(GetLocalBounds()); MoveLayerToParent(layer(), LayerOffsetData(layer()->device_scale_factor())); }
diff --git a/ui/views/view.h b/ui/views/view.h index b6e25b5c..41aff91 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -33,7 +33,6 @@ #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/layer_delegate.h" -#include "ui/compositor/layer_observer.h" #include "ui/compositor/layer_owner.h" #include "ui/compositor/paint_cache.h" #include "ui/events/event.h" @@ -269,7 +268,6 @@ // END_METADATA() ///////////////////////////////////////////////////////////////////////////// class VIEWS_EXPORT View : public ui::LayerDelegate, - public ui::LayerObserver, public ui::LayerOwner, public ui::AcceleratorTarget, public ui::EventTarget, @@ -606,8 +604,6 @@ // Sets the transform to the supplied transform. void SetTransform(const gfx::Transform& transform); - // Accelerated painting ------------------------------------------------------ - // Sets whether this view paints to a layer. A view paints to a layer if // either of the following are true: // . the view has a non-identity transform. @@ -625,23 +621,6 @@ // for another reason. void DestroyLayer(); - // Add or remove layers below this view. This view does not take ownership of - // the layers. It is the caller's responsibility to keep track of this View's - // size and update their layer accordingly. - // - // In very rare cases, it may be necessary to override these. If any of this - // view's contents must be painted to the same layer as its parent, or can't - // handle being painted with transparency, overriding might be appropriate. - // One example is LabelButton, where the label must paint below any added - // layers for subpixel rendering reasons. Overrides should be made - // judiciously, and generally they should just forward the calls to a child - // view. They must be overridden together for correctness. - virtual void AddLayerBeneathView(ui::Layer* new_layer); - virtual void RemoveLayerBeneathView(ui::Layer* old_layer); - - // ui::LayerObserver: - void LayerDestroyed(ui::Layer* layer) override; - // Overridden from ui::LayerOwner: std::unique_ptr<ui::Layer> RecreateLayer() override; @@ -1983,11 +1962,6 @@ // Whether we are painting to a layer because of a non-identity transform. bool paint_to_layer_for_transform_ = false; - // Set of layers that should be painted beneath this View's layer. These - // layers are maintained as siblings of this View's layer and are stacked - // beneath. - std::vector<ui::Layer*> layers_beneath_; - // Accelerators -------------------------------------------------------------- // Focus manager accelerators registered on.
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 139df2a7..0d86fda3 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc
@@ -34,7 +34,6 @@ #include "ui/compositor/layer_animator.h" #include "ui/compositor/paint_context.h" #include "ui/compositor/test/draw_waiter_for_test.h" -#include "ui/compositor/test/test_layers.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/events/keycodes/keyboard_codes.h" @@ -4559,233 +4558,6 @@ EXPECT_EQ("0.00 0.00", ToString(v11->layer()->subpixel_position_offset())); } -TEST_F(ViewLayerTest, LayerBeneathTriggersPaintToLayer) { - View root; - root.SetPaintToLayer(); - - View* view = root.AddChildView(std::make_unique<View>()); - EXPECT_EQ(nullptr, view->layer()); - - ui::Layer layer1; - ui::Layer layer2; - view->AddLayerBeneathView(&layer1); - EXPECT_NE(nullptr, view->layer()); - view->AddLayerBeneathView(&layer2); - EXPECT_NE(nullptr, view->layer()); - - view->RemoveLayerBeneathView(&layer1); - EXPECT_NE(nullptr, view->layer()); - view->RemoveLayerBeneathView(&layer2); - EXPECT_EQ(nullptr, view->layer()); -} - -TEST_F(ViewLayerTest, LayerBeneathAddedToTree) { - View root; - root.SetPaintToLayer(); - - ui::Layer layer; - View* view = root.AddChildView(std::make_unique<View>()); - - view->AddLayerBeneathView(&layer); - ASSERT_NE(nullptr, view->layer()); - EXPECT_TRUE(view->layer()->parent()->Contains(&layer)); - - view->RemoveLayerBeneathView(&layer); - EXPECT_EQ(nullptr, layer.parent()); -} - -TEST_F(ViewLayerTest, LayerBeneathRemovedOnDestruction) { - View root; - root.SetPaintToLayer(); - - auto layer = std::make_unique<ui::Layer>(); - View* view = root.AddChildView(std::make_unique<View>()); - - // No assertions, just get coverage of deleting the layer while it is added. - view->AddLayerBeneathView(layer.get()); - layer.reset(); - root.RemoveChildView(view); - delete view; -} - -TEST_F(ViewLayerTest, LayerBeneathVisibilityUpdated) { - View root; - root.SetPaintToLayer(); - - ui::Layer layer; - - // Make a parent view that has no layer, and a child view that has a layer. - View* parent = root.AddChildView(std::make_unique<View>()); - View* child = parent->AddChildView(std::make_unique<View>()); - child->AddLayerBeneathView(&layer); - - EXPECT_EQ(nullptr, parent->layer()); - EXPECT_NE(nullptr, child->layer()); - - // Test setting the views' visbilities in various orders. - EXPECT_TRUE(layer.visible()); - child->SetVisible(false); - EXPECT_FALSE(layer.visible()); - child->SetVisible(true); - EXPECT_TRUE(layer.visible()); - - parent->SetVisible(false); - EXPECT_FALSE(layer.visible()); - parent->SetVisible(true); - EXPECT_TRUE(layer.visible()); - - parent->SetVisible(false); - EXPECT_FALSE(layer.visible()); - child->SetVisible(false); - EXPECT_FALSE(layer.visible()); - parent->SetVisible(true); - EXPECT_FALSE(layer.visible()); - child->SetVisible(true); - EXPECT_TRUE(layer.visible()); - - child->RemoveLayerBeneathView(&layer); - - // Now check the visibility upon adding. - child->SetVisible(false); - child->AddLayerBeneathView(&layer); - EXPECT_FALSE(layer.visible()); - child->SetVisible(true); - EXPECT_TRUE(layer.visible()); - - child->RemoveLayerBeneathView(&layer); -} - -TEST_F(ViewLayerTest, LayerBeneathHasCorrectBounds) { - View root; - root.SetBoundsRect(gfx::Rect(100, 100)); - root.SetPaintToLayer(); - - View* view = root.AddChildView(std::make_unique<View>()); - view->SetBoundsRect(gfx::Rect(25, 25, 50, 50)); - - // The layer's position will be changed, but its size should be respected. - ui::Layer layer; - layer.SetBounds(gfx::Rect(25, 25)); - - // First check when |view| is already painting to a layer. - view->SetPaintToLayer(); - view->AddLayerBeneathView(&layer); - EXPECT_NE(nullptr, layer.parent()); - EXPECT_EQ(gfx::Rect(25, 25, 25, 25), layer.bounds()); - - view->RemoveLayerBeneathView(&layer); - EXPECT_EQ(nullptr, layer.parent()); - layer.SetBounds(gfx::Rect(25, 25)); - - // Next check when |view| wasn't painting to a layer. - view->DestroyLayer(); - EXPECT_EQ(nullptr, view->layer()); - view->AddLayerBeneathView(&layer); - EXPECT_NE(nullptr, view->layer()); - EXPECT_NE(nullptr, layer.parent()); - EXPECT_EQ(gfx::Rect(25, 25, 25, 25), layer.bounds()); - - // Finally check that moving |view| also moves the layer. - view->SetBoundsRect(gfx::Rect(50, 50, 50, 50)); - EXPECT_EQ(gfx::Rect(50, 50, 25, 25), layer.bounds()); - - view->RemoveLayerBeneathView(&layer); -} - -TEST_F(ViewLayerTest, LayerBeneathTransformed) { - View root; - root.SetPaintToLayer(); - - ui::Layer layer; - View* view = root.AddChildView(std::make_unique<View>()); - view->SetPaintToLayer(); - view->AddLayerBeneathView(&layer); - EXPECT_TRUE(layer.transform().IsIdentity()); - - gfx::Transform transform; - transform.Rotate(90); - view->SetTransform(transform); - EXPECT_EQ(transform, layer.transform()); - view->SetTransform(gfx::Transform()); - EXPECT_TRUE(layer.transform().IsIdentity()); -} - -TEST_F(ViewLayerTest, LayerBeneathStackedCorrectly) { - using ui::test::ChildLayerNamesAsString; - - View root; - root.SetPaintToLayer(); - - ui::Layer layer; - layer.set_name("layer"); - - View* v1 = root.AddChildView(std::make_unique<View>()); - View* v2 = root.AddChildView(std::make_unique<View>()); - View* v3 = root.AddChildView(std::make_unique<View>()); - - // Check that |layer| is stacked correctly as we add more layers to the tree. - v2->AddLayerBeneathView(&layer); - v2->layer()->set_name("v2"); - EXPECT_EQ(ChildLayerNamesAsString(*root.layer()), "layer v2"); - v3->SetPaintToLayer(); - v3->layer()->set_name("v3"); - EXPECT_EQ(ChildLayerNamesAsString(*root.layer()), "layer v2 v3"); - v1->SetPaintToLayer(); - v1->layer()->set_name("v1"); - EXPECT_EQ(ChildLayerNamesAsString(*root.layer()), "v1 layer v2 v3"); - - v2->RemoveLayerBeneathView(&layer); -} - -TEST_F(ViewLayerTest, LayerBeneathOrphanedOnRemoval) { - View root; - root.SetPaintToLayer(); - - ui::Layer layer; - View* view = root.AddChildView(std::make_unique<View>()); - view->AddLayerBeneathView(&layer); - EXPECT_EQ(layer.parent(), root.layer()); - - // Ensure that the layer beneath is orphaned and re-parented appropriately. - root.RemoveChildView(view); - EXPECT_EQ(layer.parent(), nullptr); - root.AddChildView(view); - EXPECT_EQ(layer.parent(), root.layer()); - - view->RemoveLayerBeneathView(&layer); -} - -TEST_F(ViewLayerTest, LayerBeneathMovedWithView) { - using ui::test::ChildLayerNamesAsString; - - View root; - root.SetPaintToLayer(); - root.layer()->set_name("root"); - - ui::Layer layer; - layer.set_name("layer"); - - View* v1 = root.AddChildView(std::make_unique<View>()); - View* v2 = root.AddChildView(std::make_unique<View>()); - View* v3 = v1->AddChildView(std::make_unique<View>()); - - v1->SetPaintToLayer(); - v1->layer()->set_name("v1"); - v2->SetPaintToLayer(); - v2->layer()->set_name("v2"); - v3->SetPaintToLayer(); - v3->layer()->set_name("v3"); - - // Verify that |layer| is stacked correctly. - v3->AddLayerBeneathView(&layer); - EXPECT_EQ(ChildLayerNamesAsString(*v1->layer()), "layer v3"); - - // Move |v3| to under |v2| and check |layer|'s stacking. - v1->RemoveChildView(v3); - v2->AddChildView(std::unique_ptr<View>(v3)); - EXPECT_EQ(ChildLayerNamesAsString(*v2->layer()), "layer v3"); -} - namespace { class PaintLayerView : public View {
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index 8d97a5e..7fefa87 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h
@@ -303,6 +303,7 @@ bool wants_mouse_events_when_inactive = false; // A map of properties applied to windows when running in mus. + // TODO(crbug.com/958241): this is deprecated and will be removed shortly. std::map<std::string, std::vector<uint8_t>> mus_properties; };
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 7810976..86b64077 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -3017,15 +3017,17 @@ event.latency()->AddLatencyNumberWithTimestamp( ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, event_time, 1); - if (event_type == ui::ET_TOUCH_RELEASED) - id_generator_.ReleaseNumber(pointer_id); - // There are cases where the code handling the message destroys the // window, so use the weak ptr to check if destruction occurred or not. base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr()); delegate_->HandleTouchEvent(&event); if (ref) { + // Release the pointer id only when |HWNDMessageHandler| and |id_generator_| + // are not destroyed. + if (event_type == ui::ET_TOUCH_RELEASED) + id_generator_.ReleaseNumber(pointer_id); + // Mark touch released events handled. These will usually turn into tap // gestures, and doing this avoids propagating the event to other windows. if (delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN) {